Autor Thema: Paging  (Gelesen 33162 mal)

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #40 am: 08. January 2009, 19:49 »
Ich soll einfach die libc des gcc benutzen?
Dann muss ich doch gar kein malloc schreiben, oder?

Kann es sein, dass ich da was falsch verstehe?
Klärt mich mal bitte auf, wie das mit der libc und dem Kernel ist.
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #41 am: 08. January 2009, 22:28 »
Der gcc hat mit der libc nicht viel zu tun, außer dass man sie C-Programmen, die der gcc kompiliert, benutzen kann. Und nein, du sollst nicht die glibc nehmen. Die ist auf Linux ausgelegt und gilt nicht als besonders portabel.

Eine Binary - zum Beispiel deinen Kernel, aber auch deine Programme - erstellst du ja, indem du mehrere Objektdateien zusammenlinkst. Wenn du jetzt ein paar von diesen Objektdateien so geschrieben hast, daß du sie in jedes Programm reinlinken kannst, hast du eine Bibliothek geschrieben. Üblicherweise packt man dann die Objektdateien (*.o) in ein ar-Archive (*.a) zusammen und gibt dem Linker das zu den eigentlich Objektdateien des Programms dazu. Die Standardbibliothek, die solches Zeug wie malloc/free oder printf enthält, wird libc genannt. Um manche Funktionen implementieren zu können, ruft diese libc natürlich gelegentlich den Kernel auf, z.B. über einen Software-Interrupt - das ist dann ein Syscall.

Ist das so ungefähr der grobe Überblick, den du gesucht hast?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #42 am: 08. January 2009, 22:43 »
Ja, super.
Danke.
Das bringt Licht ins Dunkel.
Dann werde ich also erst mal die libc schreiben.
Kannst du mir jetzt noch sagen, was da so alles reinkommen sollte.
Ich dachte mir folgendes:
- Speichermethoden
- Printmethoden
- Filesystemmethoden

[Edit]
Wie binde ich das ganze denn dann ein?
Also wie bringe ich dem gcc bei, dass an dieser Stelle meine Includes sind?
Ganz normal über -Include... als Parameter?
« Letzte Änderung: 08. January 2009, 23:06 von rizor »
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #43 am: 08. January 2009, 23:29 »
Was da reingehört kann man dir genauer sagen als es dir lieb ist: Auf jeden Fall alle Funktionen, die der C-Standard vorschreibt. ;) Je nachdem, wie du weiter vorgehen willst, kannst du für alles weitere dann entweder deine eigenen Funktionen basteln oder einen vorhandenen Standard wie POSIX übernehmen.

Vorerst willst du vermutlich einen Teil von stdio.h (printf und Verwandte) und stdlib.h (malloc/free) implementieren. Stringfunktionen (string.h) kann man auch recht früh brauchen. Was sonst fehlt, merkst du ja nach und nach und implementierst dann halt die entsprechende Funktion. Die Linux-Manpages geben meistens recht brauchbare und trotzdem kompakte Informationen dazu, wie eine Funktion definiert ist (z.B. Verhalten im Fehlerfall und sowas), die du berücksichtigen solltest - je mehr du nach Standards arbeitest, um so leichter wird es später, Programme zu portieren.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #44 am: 26. February 2009, 13:55 »
Hallo,

ich habe ein Problem mit meiner Initialisierung des Pagings.
Ich habe meinen Code ein wenig umgeschrieben und habe nun ein Problem mit dem Mappen der Bitmap.

Die Bitmap wird laut Anzeige auf 0 gemappt.
Leider bekomme ich dabei einen panic, da das System angeblich versucht die Page zu remappen.
Ich weiß leider nicht woran das liegt, denn  die Ausgaben sagen mir, dass in dem Bereich nichts gemappt wird außer der Bitmap.

Die Methoden sehen wie folgt aus:
void map_init(phys_t paddr , virt_t vaddr , size_t size){
size_t i , offset , overflow = 0;
uint32_t phys;
page_table_t table;

offset = ((uint32_t)vaddr >> PAGING_SHIFT_TABLE) % PAGING_TABLE_SIZE;

if(size > PAGING_TABLE_SIZE - offset){
if(kernel_dir[(uint32_t)vaddr >> PAGING_SHIFT_DIRECTORY + 1] == EMPTY)
create_table(kernel_dir , (uint32_t)vaddr >> PAGING_SHIFT_DIRECTORY + 1);

table = (page_table_t)((uint32_t)kernel_dir[(uint32_t)vaddr >> PAGING_SHIFT_DIRECTORY + 1] & PAGING_REMOVEFLAGS);

overflow = size - PAGING_TABLE_SIZE + offset;

for(i = 0; i < overflow; i++){
phys = (uint32_t)paddr + PAGING_TABLE_SIZE - offset + i * PAGING_PAGESIZE;

if(table[i] & PAGING_INUSE)
panic("Tried to map a mapped page");

table[i] = phys | PAGING_KERNEL;
}
}

if(kernel_dir[(uint32_t)vaddr >> PAGING_SHIFT_DIRECTORY] == EMPTY)
create_table(kernel_dir , (uint32_t)vaddr >> PAGING_SHIFT_DIRECTORY);

table = (page_table_t)(kernel_dir[(uint32_t)vaddr >> PAGING_SHIFT_DIRECTORY] & PAGING_REMOVEFLAGS);
for(i = 0; i < size - overflow; i++){
phys = (uint32_t)paddr + i * PAGING_PAGESIZE;

if(table[i + offset] & PAGING_INUSE)
panic("Tried to map a mapped page");

table[i + offset] = phys | PAGING_KERNEL;
}
puts("from %p to %p\n" , vaddr , (vaddr + size * PAGING_PAGESIZE));
}

und die Methode, die die Tabellen erstellt:

void create_table(directory_table_t directory , size_t dir_offset){
page_table_t table;

table = (page_table_t)palloc(PAGING_TABLE_SIZE * sizeof(page_table_t) / PAGING_PAGESIZE);

if(table == EMPTY)
//TODO call swapping
panic("Not enough physical memory");

memset(table , EMPTY , PAGING_TABLE_SIZE);

if(dir_offset >= PAGING_KERNEL_DIR_SIZE)
directory[dir_offset] = (uint32_t)table | PAGING_USER;
else
directory[dir_offset] = (uint32_t)table | PAGING_KERNEL;
}

Der Aufruf sieht wie folgt aus:
kernel_dir = (directory_table_t)palloc(PAGING_KERNEL_DIR_SIZE * sizeof(directory_table_t) / PAGING_PAGESIZE);
memset(kernel_dir , EMPTY , PAGING_KERNEL_DIR_SIZE);

//map the kernel
size = ((uint32_t)kernel_end - (uint32_t)kernel_start) / PAGING_PAGESIZE;
puts("\tMapped the kernel ");
map_init(kernel_start , kernel_mem_start , size);

//map the txt-video-memory
size = 80 * 25 * 2 / PAGING_PAGESIZE + 1;
puts("\tMapped the video-memory ");
map_init((phys_t)0xB8000 , (virt_t)0xB8000 , size);

//map the kernel_directory
puts("\tMapped the kernel-directory ");
map_init(kernel_dir , kernel_dir , 1);

//map the bitmap
size = bitmap_size / PAGING_PAGESIZE;
puts("\tMapped the bitmap ");
map_init(bitmap_entry, bitmap_entry , size);

PAGING_KERNEL setzt das Present, Readwrite und den Kernel-Flag in use

Vllt findet ihr den Fehler
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #45 am: 26. February 2009, 15:46 »
Mittlerweile habe ich herausgefunden woran es liegt.
Ich finde nur nicht den Fehler im Code.
Es steht an dem Eintrag 0 in der Tabelle bereits ein Eintrag (Adresse der Tabelle).
Ich weiß leider nicht warum
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #46 am: 03. March 2009, 22:16 »
Ich habe mal wieder ein wenig versucht den Fehler zu debuggen.
Nun weiß ich, dass der Fehler mit dem falschen Eintrag an der ersten Stelle einer Tabelle nur bei der ersten Tabelle auftritt.
Alle anderen stimmen überein.
Woran kann das liegen.
Der Fehler ist für mich völlig unlogisch.
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #47 am: 05. March 2009, 21:26 »
Ich habe mal versucht die Bitmap an eine andere Stelle zu mappen.
Das hat leider auch nicht funktioniert (bekomme einen triple fault).
Woran kann es liegen, dass das Problem allgemein mit der Bitmap besteht?

Ich habe leider überhaupt keine Idee.
Wenn ich mir das recht überlege, dürfte es an sich ja nicht an der Bitmap liegen, denn ich greife momentan nicht mehr auf die Bitmap zu und wenn ich die nicht mitmappe, dann funktioniert alles einwandfrei.
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

tarrox

  • Beiträge: 12
    • Profil anzeigen
Gespeichert
« Antwort #48 am: 06. March 2009, 14:48 »
Wenn du weißt wo der Fehler auftrit, würde ich versuchen ihn zu finden. Daher ich würde schaun wann der erste Eintrag in der ersten Tabelle gesetzt wird. Dies musst du kannst du machen indem du nach jedem Schritt in dem der Speicher geändert wird schaust, ob sich der Wert geändert hat. Anstrangend aber meist nicht anders machbar.

PS: Ist Paging schon aktiviert oder machst du das erst jetzt.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #49 am: 06. March 2009, 16:27 »
Paging ist nicht aktiviert.
Das Problem ist, dass ich mir die Adressen ausgeben lasse, die in die Einträge geschrieben werden.
Dort sehe ich definitiv, dass es keinen Eintrag gibt (außer den der Bitmap).
Sobald die Bitmap eingetragen werden soll, ist alles hinüber.
Keine Ahnung wieso.

Nein, Paging ist noch nicht aktiviert
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

tarrox

  • Beiträge: 12
    • Profil anzeigen
Gespeichert
« Antwort #50 am: 06. March 2009, 18:48 »
Stürzt es in der Funktion ab ader dannach?
Wenn es in der Funktion abstürzt, musst du suchen wo es Abstürzt, also die genaue Zeile. Ansonaten muss man woanders schaun, je nachdem wo es abstürtzt^^.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #51 am: 06. March 2009, 19:59 »
Ich habe es eben einmal gedebugged und dabei ist mir auufgefallen, dass er mir zweimal den gleichen Speicherbereich bekomme.
Das wundert mich, denn die physikalische Speicherverwaltung habe ich getestet.
Da ist mir kein Fehler aufgefallen.

Hier ist mal der Code, vllt fällt euch auf, wo der Fehler liegen kann:

phys_t palloc(size_t size){
lock_spin(mem_lock);
phys_t block = find_free(0 , bitmap_size , size);

if(block)
mark_res(block , size);
unlock_spin(mem_lock);

return block;
}

phys_t find_free(size_t lowest , size_t highest , size_t size){
size_t i , k;
size_t found_blocks = 0;
phys_t block;

for(i = lowest; i < highest; i++){
// these blocks are full
if(!bitmap_entry[i]){
found_blocks = 0;
continue;
}

if(bitmap_entry[i] == ~0x0){
if(found_blocks == 0)
block = (phys_t)(i * BLOCKS_PER_STDSIZE * BITMAP_SIZE);
found_blocks += BLOCKS_PER_STDSIZE;
}
else{
for(k = 0; k < BLOCKS_PER_STDSIZE; k++){
if(bitmap_entry[i] & (1 << k)){
if(found_blocks == 0)
block = (phys_t)((i * BLOCKS_PER_STDSIZE + k) * BITMAP_SIZE);
found_blocks++;

if(found_blocks > size)
break;
}
else
found_blocks = 0;
}
}

if(found_blocks > size)
return block;
}

return NULL;
}

void mark_res(phys_t addr , size_t num){
size_t i , index , d_block;

for(i = 0; i < num; i++){
d_block = (size_t)addr + i * BITMAP_SIZE;
index = d_block / BITMAP_SIZE / BLOCKS_PER_STDSIZE;
bitmap_entry[index] &= ~(1 << ((d_block / BITMAP_SIZE) & (BLOCKS_PER_STDSIZE - 1)));
}
}

Edit:
Das System stürzt erst ab, wenn ich Paging aktiviere.
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #52 am: 06. March 2009, 20:27 »
Ich habe den Fehler gefunden....
Das Problem lag daran, dass ich bei palloc 0 Seiten anfordere....
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #53 am: 06. March 2009, 22:15 »
Habe mal noch eine Frage.
Bin gerade dabei, den Code zu testen und dabei fällt mir auf, dass wenn ich eine Page suche, damit ich die dann mappen kann, dass ich einen Pagefault bekomme.
Der gdb meldet auch, dass er auf die Seite nicht zugreifen kann.
Die Tabelle ist gemappt.
Das ist kein Problem.

Der code, der den Fehler auslöst:
table[k] == EMPTY

Die Tabelle wurde ordentlich aus der Directory kopiert.
Wieso kann ich nicht darauf zugreifen?
An sich müsste in diesem Eintrag eine 0 stehen.
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #54 am: 07. March 2009, 22:06 »
Ich habe eben gesehen, dass an dieser Stelle schon ein Eintrag stehen sollte.
Das ist die erste Tabelle, in der auch der Kernel liegt.
Wie kann es dann sein, dass ich beim Zugriff einen Pagefault bekomme.
An sich müsste ich die einzelnen Tabellen nicht mitmappen, oder?
Falls doch, wie kann man das machen?
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #55 am: 07. March 2009, 23:01 »
Speicher auf den du zugreifst, muss gemappt sein, egal was da drin steht.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

tarrox

  • Beiträge: 12
    • Profil anzeigen
Gespeichert
« Antwort #56 am: 07. March 2009, 23:06 »
Am einfachsten ist es den 1023 Direktory Eintrag, selbst auf die Directory zu zeigen. Dadurch ist jeder ist jede Tabelle automatisch gemappt, wenn du sie in den Direktory reinschreibst.
//Alle Page-Tabels sind nun ab der Position 0xFFC00000 zu finden, und muss nicht extra gemappt werden.
kernel_dir[1023]=(kernel_dir|0x3);
addresse = 0xFFC00000+(i*0x1000);//gib die Addresse des i-ten Tabelle aus, um sie zu bearbeiten.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #57 am: 07. March 2009, 23:09 »
Wie kann ich das Mapping ansonsten machen?
Also wie mappe ich jede einzelne Tabelle?
An sich mappe ich die Directory ja selbst in der Directory.
Also muss ich nach der Erstellung der Tabelle die Tabelle selbst noch einmal mappen?
Das wirkt für mich wie eine endlose Rekursion.

Edit:
@tarrox:
ich habe die Directory 1:1 gemappt.
« Letzte Änderung: 07. March 2009, 23:38 von rizor »
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #58 am: 08. March 2009, 01:39 »
Ich finde es ein wenig ineffektiv, dass wenn ich meine Tabelle in die Directory eintrage, dass ich diese Tabellen und Pages einzeln mappen muss, damit ich auf sie zugreifen kann.
Muss das echt so gemacht werden?
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #59 am: 08. March 2009, 12:02 »
Wie tarrox schon angemerkt hat, kannst du im PD das PD selbst als PT eintragen. Ich hatte das erst nicht erwähnt, weil es am Anfang ein etwas verwirrender Hack ist. Wenn du das machst, hast du alle Page Tables hintereinander weg gemappt. Die Adressen der PTs stehen ja alle im PD drin, ganz normal. Wenn du jetzt das PD auch noch als PT benutzt, wird der Inhalt nicht mehr als Page-Table-Adressen interpretiert, die zum weiteren Auflösen der Adresse benutzt werden, sondern als die Adresse der Pages, die die Page Tables enthalten, selbst. Damit hast du alle im PD vorhandenen PTs gemappt.

Mal dir das am besten einfach mal auf ein Blatt Papier auf, wenn es dich verwirrt.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

 

Einloggen