Informationen vom RM in den PM übergeben?


  • Mod

    INT 12 - BIOS - GET MEMORY SIZE
    Return: AX = kilobytes of contiguous memory starting at absolute address 00000h
    Note: this call returns the contents of the word at 0040h:0013h; in PC and XT, this value is set from the switches on the motherboard

    Wie kann man diesen Wert nach dem Abfragen beim Umschalten vom RM in den PM am einfachsten übergeben? Ich benötige den physikalischen Speicher. Bisherige Routinen, die ich gefunden habe, geben falsche Werte aus.



  • Im Allgemeinen kannst du für die Übergabe Register nehmen, einen festen Speicherbereich reservieren, der beiden Programmen bekannt ist, oder die Werte geschickt auf den Stack legen, sodass sie als Parameter fungieren.

    Erhard Henkes schrieb:

    INT 12 - BIOS - GET MEMORY SIZE
    Return: AX = kilobytes of contiguous memory starting at absolute address 00000h
    Note: this call returns the contents of the word at 0040h:0013h; in PC and XT, this value is set from the switches on the motherboard

    1. Diese Information steht im Speicher an der linearen Adresse 0x00000413
    2. Das "contiguous" heißt "zusammenhängend". Das bedeutet, dass maximal 640KB zurückgegeben wird, denn bei 0x000a0000 ist bereits die erste Lücke. Also nützt dir dieser Wert nichts.

    Im Artikel auf wiki.osdev.org sind verschiedene Methoden beschrieben: http://wiki.osdev.org/Detecting_Memory_(x86)#Detecting_Upper_Memory


  • Mod

    Danke! Diesen Artikel hatte ich bisher übersehen. Das osdev.org wiki ist echt klasse.

    INT 0x15, EAX = 0xE820 ... available on all PCs built since 2002

    Sieht kompliziert aus.



  • Erhard Henkes schrieb:

    Sieht kompliziert aus.

    Ich kann dir mal meinen Code dafür raussuchen, der hat zweistufig gearbeitet: BIOS-Access im RM und die Aufbereitung der Liste im PM. Hat auch, zumindest unter Bochs, geklappt 🙂

    edit: Und funktioniert bisher nur bis 4GB RAM, müsste sich aber leicht ummünzen lassen. Die Daten werden an einem vordefinierten Platz im RAM gespeichert (bei RM->PM).



  • Es werden zwei Listen erstellt, eine Liste, die die freien Stücke enthält, die andere enthält die reservierten. Als "frei" gelten hier die Stücke mit Typ==1 (obwohl potentiell auch Typ3 & Typ4 nutzbar wären). Hab den Assembler-Code umgemodelt, dass auch >4GB gehen. Den C-Code, der die Stückchen dann an der Pagesize ausrichtet, überlappende Regionen zurechtschneidet und anschließend sortiert, poste ich jetzt nicht, weil er sehr davon abhängt, wie du den freien physischen Speicher verwaltest. Ich hab bei mir einfach 'ne Liste mit freien Elementen, du hast ja Bitmaps. Da kannst du ja erst alles als reserviert markieren und anschließend die freien Stückchen mit Alignment nach innen eintragen. Die Daten bekommst du jedenfalls so:

    struct MemChunk
    {
    	uint64 addr;
    	uint64 size;
    };
    
    MemChunk* const free_list = (MemChunk*)0x0500;
    MemChunk* const resv_list = (MemChunk*)0x0D00;
    
    MemChunk* list;
    for ( list=free_list; list->size; ++list )
        ...
    
    ; We store the RAM-info-lists at some free memory-place, see http://wiki.osdev.org/Memory_Map_(x86)
    ; There are two lists, each containing items of the form {addr:32, size:32}. This is, each entry
    ;   is a 2-tuple with each member being a 32-bit unsigned integer.
    ; The first list is located at 0x0500 and lists the chunks of free memory.
    ; The second list is located at 0x0D00 and lists the chunks of reserved memory.
    ;
    ; Doc: http://wiki.osdev.org/Detecting_Memory_(x86)#Getting_an_E820_Memory_Map
    ;      http://forum.osdev.org/viewtopic.php?f=1&t=18336&hilit=*E801*
    ;      http://www.ctyme.com/intr/rb-1741.htm#Table581
    
    GetRamChunks:
    	xor ebx, ebx
    
      .get_entry:
    	; Set up the BIOS-call
    	mov edi, .chunk_base
    	mov eax, 0xE820
    	mov edx, 0x534D4150
    	mov ecx, 24
    	int 0x15
    
    	; Carry-flag indicates "done" if eax is 534D4150h
    	jnc .continue_checking
    		cmp eax, 0x534D4150
    		jne .fail
    		jmp .done
    
      .continue_checking:
    	cmp eax, 0x534D4150
    	jne .fail
    
      .success:
    	; The entry may be useless for us (size==0)
    	cmp dword [.chunk_size], 0
    	jne .size_not_null
    	cmp dword [.chunk_size+4], 0
    	jne .size_not_null
    		jmp .continue
    
      .size_not_null:
    	cmp dword [.chunk_type], 1
    	jne .is_reserved_ram
    	.is_free_ram:
    		mov eax, .listfree
    		jmp .do_entry
    	.is_reserved_ram:
    		mov eax, .listresv
    	  .do_entry:
    		; Copy the 4 dwords to the list
    		cld
    		mov ecx, 4
    		mov esi, .chunk_base
    		mov edi, [eax]
    		rep movsd
    
    		add dword [eax], 16
    
      .continue:
    	test ebx, ebx   ; ebx=0 indicates end-of-list
    	jne .get_entry
    
      .done:
    	; Do a empty (0,0) entry in both lists as a terminator
    	xor eax, eax
    	mov ecx, 4
    	mov edi, [.listfree]
    	rep stosd
    	add dword [.listfree], 16
    
    	xor eax, eax
    	mov ecx, 4
    	mov edi, [.listresv]
    	rep stosd
    	add dword [.listresv], 16
    
    	; Check whether there were too many entries
    	cmp dword [.listfree], 0x500+2048
    	jge .fail
    	cmp dword [.listresv], 0x500+2048+2048
    	jge .fail
    
    	ret
    
      .fail:
    	mov al, 'A'
    	mov ah, 0x0E
    	int 0x10
    	hlt
    
      .listfree: dd 0x500
      .listresv: dd 0xD00
      .chunk_base: times 2 dd 0
      .chunk_size: times 2 dd 0
      .chunk_type: dd 0
      .chunk_extt: dd 0
    

  • Mod

    Hallo Badestrand,

    danke für die Unterstützung, finde ich klasse. Hier habe ich eine Umsetzung gefunden, die auch funktioniert: http://www.c-plusplus.net/forum/viewtopic-var-t-is-246159.html
    http://www.henkessoft.de/OS_Dev/OS_Dev3.htm#mozTocId584885



  • Dieser Thread wurde von Moderator/in Nobuo T aus dem Forum Assembler in das Forum Projekt: OS-Development verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


Anmelden zum Antworten