44;; Para bios boot primero real mode a protected mode. Uefi saltea esta parte, ya
55;; bootea en 64.
66;;
7- ;; https://wiki.osdev.org/Detecting_Memory_(x86)#BIOS_Function:_INT_0x15,_EAX_=_0xE820
7+ ;; https://wiki.osdev.org/Detecting_Memory_(x86)#BIOS_Function:_INT_0x15,_EAX_=_
8+ ;; 0xE820
89;; https://wiki.osdev.org/Detecting_Memory_(x86)#Getting_an_E820_Memory_Map
910;;==============================================================================
1011
@@ -36,12 +37,16 @@ start16:
3637
3738
3839;;==============================================================================
39- ;;e820 | builds memmap
40+ ;;e820 | build memmap
41+ ;;==============================================================================
4042;; Arguments:
4143;; -- {es:di} = destination buffer for 24 byte entries.
4244;; Returns:
4345;; -- bp = entry count
4446;;
47+ ;; https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/15_System_Address_Map_Interface
48+ ;; s/int-15h-e820h---query-system-address-map.html
49+ ;;
4550;; trashes all registers except esi
4651;; Creates memory map at 0x6000.
4752;; and the records are:
@@ -53,48 +58,52 @@ start16:
5358;;==============================================================================
5459
5560e820:
56- mov edi , 0x00006000 ;; Addrr to place memmap.
61+ mov edi , 0x00006000 ;; Addrr to place memmap.
5762 xor ebx , ebx
58- xor bp , bp ;; Entry count.
59- mov edx , 0x0534D4150 ;; SMAP.
63+ xor bp , bp ;; Entry count.
64+
6065 mov eax , 0xe820
61- mov dword [ es : di + 20 ], 1 ;; force a valid ACPI 3.X entry
62- mov ecx , 24 ; ask for 24 bytes
66+ mov dword [ es : di + 20 ], 1 ;; Buffer Pointer.
67+ ;; force a valid ACPI 3.X entry
68+ mov ecx , 24 ;; Buffer Size [bytes].
69+ mov edx , 0x0534D4150 ;; Signature = "SMAP".
6370 int 0x15
64- jc nomemmap ; carry set on first call means "unsupported function"
65- mov edx , 0x0534D4150 ; Some BIOSes apparently trash this register?
71+
72+ jc .nomemmap ;; Error condition if CF = 1.
73+ mov edx , 0x0534D4150 ;; Need to reset. According wiki.osdev.org: some BIO
74+ ;; Ses apparently trash this register.
6675 cmp eax , edx ; on success, eax must have been reset to "SMAP"
67- jne nomemmap
76+ jne . nomemmap
6877 test ebx , ebx ; ebx = 0 implies list is only 1 entry long (worthless)
69- je nomemmap
70- jmp jmpin
71- e820lp :
78+ je . nomemmap
79+ jmp . jmpin
80+ . loop :
7281 mov eax , 0xe820 ; eax, ecx get trashed on every int 0x15 call
7382 mov [ es : di + 20 ], dword 1 ; force a valid ACPI 3.X entry
7483 mov ecx , 24 ; ask for 24 bytes again
7584 int 0x15
76- jc memmapend ; carry set means "end of list already reached"
85+ jc . memmapend ; carry set means "end of list already reached"
7786 mov edx , 0x0534D4150 ; repair potentially trashed register
78- jmpin:
79- jcxz skipent ; skip any 0 length entries
87+ . jmpin:
88+ jcxz . skipent ; skip any 0 length entries
8089 cmp cl , 20 ; got a 24 byte ACPI 3.X response?
81- jbe notext
90+ jbe . notext
8291 test byte [ es : di + 20 ], 1 ; if so: is the "ignore this data" bit clear?
83- je skipent
84- notext:
92+ je . skipent
93+ . notext:
8594 mov ecx , [ es : di + 8 ] ; get lower dword of memory region length
8695 test ecx , ecx ; is the qword == 0?
87- jne goodent
96+ jne . goodent
8897 mov ecx , [ es : di + 12 ] ; get upper dword of memory region length
89- jecxz skipent ; if length qword is 0, skip entry
90- goodent:
98+ jecxz . skipent ; if length qword is 0, skip entry
99+ . goodent:
91100 inc bp ; got a good entry: ++count, move to next storage spot
92101 add di , 32 ; Pad to 32 bytes for each record
93- skipent:
102+ . skipent:
94103 test ebx , ebx ; if ebx resets to 0, list is complete
95- jne e820lp
96- nomemmap:
97- memmapend:
104+ jne . loop
105+ . nomemmap:
106+ . memmapend:
98107 xor eax , eax ; Create a blank record for termination (32 bytes)
99108 mov ecx , 8
100109 rep stosd
0 commit comments