Wie kann man Speicherkapazitäten ermitteln?



  • Diese Frage betrifft Arbeitsspeicher als auch Festplattendaten.
    Für die Speicherverwaltung des Arbeitsspeichers ist es sinnvoll, wie groß RAM ist. Von den Festplatten möchte ich auch gerne eine Funktion schreiben, welche die Anzahl der Sektoren, Zylinder und Köpfe mir zur Verfügung stellt.
    Immerhin ist das BIOS in der Lage, automatisch diese >Daten zu ermitteln, so müßte doch über einige BIOS-Funktionen diese Daten doch gewinnen. Leider weiß ich nicht, welche Funktionen es sind. Vielleicht gibt es auch Portadressen, welche diese Daten liefern.





  • In PrettyOS kannst Du das in Funktion anschauen.



  • Lieber Herr Henkes,
    Da ich wieder in die Systemprogrammierung einsteige und mich mit den für mich neueren Intelprozessoren wie 80368->80586 etc. auseinandersetze, vielleicht auch mit den 64 Bit-Prozessoren ähnlicher Bauart, habe ich erst einmal viel Stoff, um mich wieder da einzuarbeiten. Gleichzeitig sammle ich Erfahrungen mit meinen selbst geschriebenen Betriebssystem, welches mein eigenes Verständnis wiederspiegelt.

    Sie haben zwar schöne Beiträge hierzu geschrieben, die ich bei mir unter Linux getestet habe, die jedoch nicht gleich auf Anhieb funktionierten. Irgendwann hatte ich ihre Ausführungen zum Laufen gebracht, da bei Compilern und Linkern inzwischen andere Parameter erwartet werden. Nun schreibe ich ebenso eine Art Log-Buch wie sie es getan hatten. Doch mit den Werkzeugen, die man unter Linux gewöhnlich verwendet mit speziellen Optionen, als auch mit Linux-ähnlichen Werkzeugen für Windows unter Cygwin, um die Sache einheitlicher zu gestalten, so daß Windows-Benutzer unmittelbar auch diese Unix-Werkzeuge wie nasm, ld, dd, gcc, cat, bochs, make, hexedit, usw. benutzen können. Ich teste dann beides sowohl unter Linux als auch unter Windows aus.

    Doch zurück zu meiner eigentlichen Frage, um Speichergrenzen festzustellen, erwähnten sie, daß ich unter PrettyOS unter Funktionen nachschauen sollte. Ich weiß noch nicht wie ich hierbei vorgehen sollte, da ich annehme, daß der Sourcecode bestimmt schon einiges an Größe erreicht hat und die Suche wohl schwieriger wird.

    Sollte ich PrettyOS mir runterladen und mir den Sourcecode anschauen oder gibt es hierzu weitere Logbücher dazu? Ich bin bestrebt, nicht abzuschreiben, sondern mein Verständnis auf diesen Gebiet zu vertiefen, weswegen ich eigene Wege gehe und auch hierbei bereits neue Erkenntnisse gemacht habe, die etwas von ihren Erfahrungen abweichen. Man könnte sich hier auch austauschen, weswegen ich vielleicht in naher Zukunft, sofern ich alles verstanden habe, in das Projekt PrettyOs mit einsteigen kann, um meinen eigenen Senf dazu zu geben. Auf diese Weise können wir zusammen die Erkenntnisse in einen Pool zusammentragen. Ich gehe davon aus, daß dieses Forum jenen Zweck dient.

    Mit freundlichen Grüßen
    Wolfgang Ciossek



  • Tobiking2: Sehr vielen Dank!



  • Sollte ich PrettyOS mir runterladen und mir den Sourcecode anschauen oder gibt es hierzu weitere Logbücher dazu?

    Man kann es auch im SVN betrachten: https://sourceforge.net/p/prettyos/code/HEAD/tree/trunk/Source/
    Hier würde ich starten: https://sourceforge.net/p/prettyos/code/HEAD/tree/trunk/Source/kernel/ckernel.c
    Dort sieht man gut, in welcher Reihenfolge wir die einzelnen Module laden.

    In z. 175 findet man auch "showMemorySize".
    Dieses wird in z. 127/128 gesetzt:

    int64_t memsize = paging_install(mb_struct->mmap, mb_struct->mmapLength);
    ipc_setInt("PrettyOS/RAM", &memsize, IPC_SIZE);
    

    in .../paging.c findest Du:

    uint32_t ram_available = physMemInit(memoryMapBegin, memoryMapLength);
    

    und

    static uint32_t physMemInit(memoryMapEntry_t* memoryMapBegin, size_t memoryMapLength)
    {
        memoryMapEntry_t* memoryMapEnd = (memoryMapEntry_t*)((char*)memoryMapBegin + memoryMapLength);
      #ifdef _PAGING_DIAGNOSIS_
        textColor(HEADLINE);
        printf("\nMemory map (%X -> %X):", memoryMapBegin, memoryMapEnd);
        textColor(TEXT);
      #endif
    
        // Prepare the memory map entries, since we work with max 4 GB only. The last entry in the entry-array has size 0.
        for (memoryMapEntry_t* entry = memoryMapBegin; entry < memoryMapEnd; entry = (memoryMapEntry_t*)((char*)entry + entry->mysize + 4))
        {
          #ifdef _PAGING_DIAGNOSIS_
            printf("\n  %Xh -> %Xh %u (%u Bytes)", (uint32_t)entry->base, (uint32_t)(entry->base + entry->size), entry->type, (uint32_t)entry->size); // Print the memory map
          #endif
    
            // We will completely ignore memory above 4 GB or with size of 0, move following entries backward by one then
            if (entry->base < FOUR_GB && entry->size != 0)
            {
                // Eventually reduce the size so the the block doesn't exceed 4 GB
                if (entry->base + entry->size >= FOUR_GB)
                {
                    entry->size = FOUR_GB - entry->base;
                }
    
                if (entry->type == 1)
                    MAX_DWORDS = max(MAX_DWORDS, (entry->base+entry->size)/PAGESIZE/32); // Calculate required size of bittables
            }
        }
    
        // Check that 6 MiB-12 MiB is free for use
        if (!isMemoryMapAvailable(memoryMapBegin, memoryMapEnd, PLACEMENT_BEGIN, IDMAP*PAGE_COUNT*PAGESIZE))
        {
            printfe("The memory between 6 MiB and 12 MiB is not free for use. OS halted!\n");
            cli();
            hlt();
        }
    
        // We store our data here, initialize all bits to "reserved"
        phys_reservationTable = malloc(MAX_DWORDS * 4, 0, "phys_reservationTable");
        memset(phys_reservationTable, 0xFF, MAX_DWORDS * 4);
        phys_blockingTable = malloc(MAX_DWORDS * 4, 0, "phys_blockingTable");
    
        // Set the bitmap bits according to the memory map now. "type==1" means "free".
        for (const memoryMapEntry_t* entry = memoryMapBegin; entry < memoryMapEnd; entry = (memoryMapEntry_t*)((char*)entry + entry->mysize + 4))
        {
            if (entry->type == 1 && entry->base < FOUR_GB) // Set bits to "free"
            {
                physSetBits(entry->base, entry->base+entry->size, false);
            }
        }
    
        // Find the number of dwords we can use, skipping the last, "reserved"-only ones
        uint32_t dwordCount = 0;
    
        for (uint32_t i=0; i<MAX_DWORDS; i++)
        {
            if (phys_reservationTable[i] != 0xFFFFFFFF)
            {
                dwordCount = i + 1;
            }
        }
    
        // Reserve first 12 MiB
        physSetBits(0x00000000, PLACEMENT_END-1, true);
    
        // Reserve the region of the kernel code
        if ((uintptr_t)&_kernel_end >= PLACEMENT_END)
            physSetBits((uint32_t)&_kernel_beg, (uint32_t)&_kernel_end, true);
    
      #ifdef _DIAGNOSIS_
        printf("Highest available RAM: %Xh\n", dwordCount * 32 * PAGESIZE);
      #endif
    
        // Return the amount of memory available (or rather the highest address)
        return (dwordCount * 32 * PAGESIZE);
    }
    

    Das Tutorial ist inzwischen bezüglich Tools überholt. Das ist richtig. Ich wollte aber damals unbedingt, dass man auch ohne Linux, also an einem Windows-Rechner, entwickeln kann.

    Du kannst gerne deine Hinweise im Forum hier zusammenfassen (vlt. eigener Thread). dann könnte man darauf seitens des Tutorials verweisen. Anfängern würde das vielleicht helfen, wobei es inzwischen viel gute Tutorials an anderen Stellen gibt. Das war 2009 nicht so.