Autor Thema: Speicherverwaltung  (Gelesen 57878 mal)

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #20 am: 09. June 2008, 20:16 »
Es gibt einen panic.
Out of Memory!
System is halting now.
Als ich mir von der Funktion, die die bitmap durchläuft, den Inhalt des jeweils aktuellen Eintrags hab ausgeben lassen, war der Wert immer 0xFFFFFFFF.
Ich verstehe nicht, warum das ausftritt, da ich ja die gesamte bitmap auf 0 gesetzt habe.

printf("\n\nphysical_bitmap_size = %d\nphysical_bitmap[1] = 0x%x\nphysical_bitmap = 0x%x\n", physical_bitmap_size, physical_bitmap[1], physical_bitmap);
    unsigned int i, j;
    for(i = 0; i < physical_bitmap_size; i++)
    {
        printf("physical_bitmap[%d] = 0x%x\n", i, physical_bitmap[i]);
        if(physical_bitmap[i] != 0xFFFFFFFF)
{
    printf("Something Free!\n");
    for(j = 0; j < 32; j++)
{
if(physical_bitmap[i] & BIT(j))
return( ((i * 32) + j) * PAGE_SIZE );
}
}
    }
Gesucht habe ich auf die Art und der hat halt durchnummeriert bis 131068 und hat als inhalt immer 0xFFFFFFFF ausgegeben.
« Letzte Änderung: 09. June 2008, 20:20 von ChristianF »

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #21 am: 09. June 2008, 20:20 »
Ist das ein Fehler in kmalloc? Ich mein 128kb ist schon einiges zum allozieren. Auf was greift den kmalloc zurück? Auf diese Bitmap? Das wäre nämlich schlecht, wenn sie noch nicht initialisiert ist.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #22 am: 09. June 2008, 20:22 »
Nun mein kmalloc sieht so aus:
unsigned int kmalloc_int(size_t size, unsigned int align, unsigned int *phys)
{
    if (align == 1 && (placement_address & 0xFFFFF000)) // If the address is not already page-aligned
    {
        // Align it.
        placement_address &= 0xFFFFF000;
        placement_address += 0x1000;
    }
    if (phys)
        *phys = placement_address;

    unsigned int tmp = placement_address;
    placement_address += size;
    return tmp;
}

Anmerkung: placement_address startet bei ab 0xC0000000.
Aus diesem Grund wird die Addresse mittels des Makros VIRT2PHYS umgewandelt (+0x40000000).

Einfach eine Variable, die immer ein bissel weiter geschubst wird  :wink:

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #23 am: 09. June 2008, 20:29 »
Ich versteh immernoch nicht woher der Panic kommt. Wird der von deinem OS angezeigt, wenn ja wo oder von qemu/bochs oder ...?

edit: Ist denn bei 0xC0000000 irgendwas sinnvolles gemappt?
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #24 am: 09. June 2008, 21:13 »
das sollte ja eigentlich gemacht werden.
Der reserviert eine Physische Page, um diese dann nach 0xC0000000 zu mappen.
Allerdings kommt er nicht bis dahin.

Der Reservierte Speicher, der auch durchsucht wird, hat nach dem memset den Wert 0xFFFFFFFF, überall.
 
Die Funktion (testweise find_free_frame) durchläuft das komplette Array und gibt, falls vorhanden, eine Addresse auf eine physische freie Speicheradresse zurück. Nun steht aber in allen einträgen der Bitmap 0xFFFFFFFF.
Dies wertet die funktion physical_alloc_page() so, dass der komplette RAM voll ist, und macht einen Aufruf der Funktion panic, mir dem Text "Out of Memory!".

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #25 am: 09. June 2008, 21:26 »
das sollte ja eigentlich gemacht werden.
Der reserviert eine Physische Page, um diese dann nach 0xC0000000 zu mappen.
in kmalloc hier:
physical_bitmap = (unsigned int*)VIRT2PHYS(kmalloc(physical_bitmap_size));
oder wo? Woher kommen den die physischen Pages für dieses kmalloc?

Zitat
Allerdings kommt er nicht bis dahin.
Bis wohin kommt er denn überhaupt...

Könntest du mal sagen, was ausgeführt wird, was nicht, wer den Panic anzeigt, etc...? Ich komm nämlich momentan überhaupt nicht mit... :-P
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #26 am: 09. June 2008, 21:40 »
das löst zwar nicht dein problem aber
if (align == 1 && (placement_address & 0xFFFFF000)) // If the address is not already page-alignedsoll wohl eher
if (align == 1 && (placement_address & 0xFFF)) // If the address is not already page-alignedheißen
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #27 am: 09. June 2008, 21:52 »
mmhhh....
was ist denn falsch an der Zeile:
physical_bitmap = (unsigned int *)kmalloc(physical_bitmap_size);
Ich verstehe das nicht so ganz.
 
Gruß Christian

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #28 am: 09. June 2008, 21:56 »
Fangen wir mal ganz von vorne an: Wie weit wird denn initialise_physical_memory_manager(...) ausgeführt bzw. was wird nicht mehr ausgeführt bzw. wo hängt er in einer Endlosschleife?
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #29 am: 09. June 2008, 22:08 »
was ist denn falsch an der Zeile:
physical_bitmap = (unsigned int *)kmalloc(physical_bitmap_size);
Henne-Ei und so. Ein vernueftiges kmalloc braucht selbstverstaendlich eine initialisierte physische Speicherverwaltung. Ansonsten kann ja der reservierte Speicher nicht als belegt markiert werden.

Edit: Aber mit deiner Fakeimplementierung ist das natuerlich nicht dein aktuelles Problem. Nur ein zukuenftiges.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #30 am: 09. June 2008, 22:13 »
Meine Vermutung wäre schon oben gewesen, dass du in kmalloc auf die page bitmap zugreifst, die du durch das kmalloc erst allozieren (und danach erst initialisieren) willst.

edit: Der von dir angegebene Code ist übrigens nicht kmalloc sondern kmalloc_int... Das erscheint mir irgendwie was anderes zu sein...

edit2: taljeth bemerkte in #lost noch, dass deine Adresse für physical_bitmap sehr komisch ist und nicht wirklich zu den von dir prophezeiten 0xC0000000 + X passt. Zumindest sagtest du, dass kmalloc, sowas allozieren sollte...

edit3: Wenn du Lust hast kannst du mir auch mal ein (Floppy/CD-)Image + Sourcecode schicken, dann schau ich mir das an... Am liebsten natürlich mit (funktionierenden) Makefiles, damit ich auch ein bisschen was frickeln. kann.
« Letzte Änderung: 09. June 2008, 22:22 von bluecode »
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #31 am: 09. June 2008, 22:40 »
Also folgendes kmalloc ist nur eine zusatz Funktion. in dieser Funktion wird kmalloc_int so aufgerufen:
return(kmalloc_int(size, 0, 0));
Des Weiteren habe ich kmalloc jetzt so umgestellt, dass physikalische Adressen zurückgegeben werden.
unsigned int placement_address = (unsigned int)&end+0x40000000;
initialise_physical_memory_manager(...) wird komplett ausgeführt.
Er endet dann in einer endlos schleife, wenn nach einer freien physischen Page gesucht wird.
Wie zuvor auch schon gesagt, komischer weise ist die bitmap gefüllt mit dem Wert 0xFFFFFFFF anstatt 0.
 
Ich habe das OS in ein Archiv gelegt und auf meinem Server abgelegt. Wäre schön, wenn du irgendwann die Zeit findest, dir das mal anzuschaun.
http://87.230.87.9/ftp/christian/DeutschOS.tar.gz
 
Gruß Christian

 
PS: Wenn du dir den Code anschaust, dann kannst du den ganzen inhalt der Datei mm/paging.c ignorieren, bis auf die Funktion initialise_paging(...).
Hier soll eine freie Page gefunden und reserviert werden, mittels physical_alloc_page(), was dann aber in einem Out of Memory endet.

*EDIT*
Die Funktionen sind teilweise angelehnt an die von LOST, allerdings selbstgeschrieben.
Des Weiteren muss ich den Paging kram nochmals überarbeiten, wenn die physikalische Speicherverwaltung funktioniert.
« Letzte Änderung: 10. June 2008, 07:55 von ChristianF »

FreakyPenguin

  • Administrator
  • Beiträge: 301
    • Profil anzeigen
    • toni.famkaufmann.info
Gespeichert
« Antwort #32 am: 10. June 2008, 08:02 »
Hm also bei mir tut der Code einfach so nicht. Mit dem ganzem Segment-Gefummel verrutscht da die Adresse der Multiboot-Struktur. Die müsste dann halt auch irgendwo angepasst werden.

Aber das mit der ganzen Segmentierung finde ich ziemlich mühsam und Fehleranfällig, da du da während der ganzen Initialisierung immer die richtigen Adressen umbiegen musst. (Ich hab das auch erst nach einem Hinweis von bluecode gesehen, warum das überhaupt funktioniert) Ich würde dir empfehlen in der start.s ein einfaches PD zu erstellen, das den Kernel sowohl 1:1 als auch auf den 3. GB mappt. So musst du dann nur noch dort am Anfang kurz auf die Adressen achten.

Ah und nochwas, ich glaube im Kernel wäre ein -Werror keine schlechte Idee, denn die Warnungen sind oft nicht nur Dekoration. ;-)

Mir fehlt leider grad die Zeit um noch weiter zu suchem, aber wenn das Problem heute Abend noch nicht gelöst ist, kann ichs mir nochmal anschauen.

Edit:
Abgesehen natürlich von der Zeile "if(physical_bitmap & BIT(j))" in find_free_page, die meiner Meinung nach eher "if(!(physical_bitmap & BIT(j)))" sein sollte.
« Letzte Änderung: 10. June 2008, 08:06 von FreakyPenguin »

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #33 am: 10. June 2008, 08:20 »
Dieser Post wurde unter enormen Zwang auf mich von FreakyPenguin erstellt. Er fordert, dass ich auf den Edit seines letzten Posts explizit hinweise.
Bitte helft mir, er wird, falls ich seine Forderungen nicht erfülle bei meinem OS-Projekt mithelfen. :-o
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #34 am: 10. June 2008, 09:14 »
Da habe ich das wohl vergessen.  :cry:
In meinem alten Code war das so drinne, habe allerdings den Unterschied gestern nicht gesehen  :roll:
 
Gruß Christian

*EDIT*
Hm also bei mir tut der Code einfach so nicht. Mit dem ganzem Segment-Gefummel verrutscht da die Adresse der Multiboot-Struktur.
Bei mir hat das Funktioniert, wollte das aber eh schon seit längerer Zeit ändern  :-D
Bin grad dabei eine neue start.s zu erstellen ...
 
*EDIT2*
Mmmhhh....
wie setze ich nur Paging mit nasm auf...  :roll:
« Letzte Änderung: 10. June 2008, 09:23 von ChristianF »

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #35 am: 10. June 2008, 10:13 »
Mir ist gerade eben noch ein weiterer Fehler aufgefallen.
Und zwar hier:
physical_bitmap_size = (num_pages / 32) * 4;
Das stimmt allerdings so nicht, oder gibt es 128 Bit Variablen (16 Byte) ???
Ich kenne nur 8 Byte große Variablen, also 64 Bit (long long int, C99 Standard).
physical_bitmap_size = num_pages / 32;
Ich weiß nur nicht warum ich das dahin geschrieben habe...
wahrscheinlich, weil ich vorher folgendes da stehen hatte:
physical_bitmap_size = num_pages / ( 8 * 4 );
« Letzte Änderung: 10. June 2008, 10:19 von ChristianF »

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #36 am: 10. June 2008, 13:06 »
physical_bitmap_size = (num_pages / 32) * 4;Das stimmt allerdings so nicht, oder gibt es 128 Bit Variablen (16 Byte) ???
Das stimmt so schon, du willst doch 32bit integer allozieren, deswegen teilst du durch 32 (für eine page ein bit) und multiplizierst anschließend mit 4 (also der Größe deines Datentyps). Es wird zwar damit nach unten gerundet (was nicht unbedingt richtig ist), aber was solls.

Zitat
Ich kenne nur 8 Byte große Variablen, also 64 Bit (long long int, C99 Standard).
Der C Standard gibt keine feste Größe für die Datentypen an, sondern nur eine Mindestgröße. Gcc stellt iirc als Erweiterung sogar einen 128bit Integerdatentyp zur Verfügung, wie der heißt weiß ich nicht auswendig, wenns dich interessiert muss halt ins Manual schauen.
Was allerdings dein 128bit Datentyp mit dem Code oben zu tun haben soll versteh ich nicht. :wink:
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #37 am: 10. June 2008, 13:08 »
wie setze ich nur Paging mit nasm auf...  :roll:
Gibt doch genug Beispielcode dazu :roll: (zB. meinen beiden OS, siehe Signatur, beides higher half und beidesmal wird das in assemblercode initialisiert)
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #38 am: 10. June 2008, 17:25 »
Mmmmhhh....
Ich habe den Fehler gefunden  :lol:

Ich habe mal das Makro VIRT2PHYS entfernt und siehe da, es geht!
*freu*
 
Jetzt kommt auch das was ich erwartet habe, und zwar ein neustart beim initialisieren des Pagings.
 
Kampfesgrüße Christian

*EDIT*
auch folgendes habe ich geändert:
unsigned int placement_address = (unsigned int)&end+0x40000000;zu folgendem:
unsigned int placement_address = (unsigned int)&end;
« Letzte Änderung: 10. June 2008, 17:28 von ChristianF »

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #39 am: 10. June 2008, 19:24 »
Mal ne kurze Frage:
Mein Linker Script sah vorher so aus:
OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
SECTIONS
{
. = 0x100000;

.setup :
{
*(.setup)
}

. += 0xC0000000;

.text : AT(ADDR(.text) - 0xC0000000)
{
*(.text)
}

.data ALIGN (4096) : AT(ADDR(.data) - 0xC0000000)
{
*(.data)
*(.rodata*)
}

.bss ALIGN (4096) : AT(ADDR(.bss) - 0xC0000000)
{
*(COMMON*)
*(.bss*)
}
}

Nun wollte ich fragen, ob das auch so geht:
OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
phys = 0x00100000;
virt = 0xC0100000;
SECTIONS
{
    . = virt;
    .text virt : AT(phys)
    {
        code = .;
        *(.text)
        *(.rodata)
        . = ALIGN(4096);
    }
    .data : AT(phys + (data - code))
    {
        data = .;
        *(.data)
        . = ALIGN(4096);
    }
    .bss : AT(phys + (bss - code))
    {
        bss = .;
        *(.bss)
        . = ALIGN(4096);
    }
    end = .; _end = .; __end = .;
}

Ich habe mir halt gedacht, wenn ich jetzt schon die start.s überarbeite, kann ich auch mein linker script überarbeiten.
Die untere Version ist eine abgeänderte von Brans Kernel Development Tutorial. Die wurde ersetzt, als ich daraus einen HigherHalf kernel gemacht habe.  :evil:


*EDIT*
wie setze ich nur Paging mit nasm auf...  :roll:
Gibt doch genug Beispielcode dazu :roll: (zB. meinen beiden OS, siehe Signatur, beides higher half und beidesmal wird das in assemblercode initialisiert)
Nun ja, das Problem ist, dass die AT & T Syntax, oder wie auch immer mich immer verwirrt, weshalb dein Code mit nichts bringt.

Ich habe in mein Linkerscript jetzt noch die Einträge __kernel_start__ und __kernel_end__ eingefügt.
Alles was ich jetzt machen muss ist doch von Adresse 0, bzw. __kernel_start__ bis __kernel_end__ in einer loop durchzulaufen und die Adresse in die Page Table (0xC0000000 >> 22) schreiben, falls der Kernel kleiner als 4 MB ist, oder?
Wenn ich doch nur etwas besser Assembler könnte ...
Wie mach ich das jetzt?  :-D
« Letzte Änderung: 10. June 2008, 20:06 von ChristianF »

 

Einloggen