I'm using the code from osdev wiki to read e820 output as follows:
Code: Select all
[BITS 16]
e820_start:
mov di, 0
xor ebx, ebx ; ebx must be 0 to start
xor bp, bp ; keep an entry count in bp
mov edx, 0x0534D4150 ; Place "SMAP" into edx
mov eax, 0xe820
mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
mov ecx, 24 ; ask for 24 bytes
int 0x15
jc short .failed ; carry set on first call means "unsupported function"
mov edx, 0x0534D4150 ; Some BIOSes apparently trash this register?
cmp eax, edx ; on success, eax must have been reset to "SMAP"
jne short .failed
test ebx, ebx ; ebx = 0 implies list is only 1 entry long (worthless)
je short .failed
jmp short .jmpin
.e820lp:
mov eax, 0xe820 ; eax, ecx get trashed on every int 0x15 call
mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
mov ecx, 24 ; ask for 24 bytes again
int 0x15
jc short .e820f ; carry set means "end of list already reached"
mov edx, 0x0534D4150 ; repair potentially trashed register
.jmpin:
jcxz .skipent ; skip any 0 length entries
cmp cl, 20 ; got a 24 byte ACPI 3.X response?
jbe short .notext
test byte [es:di + 20], 1 ; if so: is the "ignore this data" bit clear?
je short .skipent
.notext:
mov ecx, [es:di + 8] ; get lower uint32_t of memory region length
or ecx, [es:di + 12] ; "or" it with upper uint32_t to test for zero
jz .skipent ; if length uint64_t is 0, skip entry
inc bp ; got a good entry: ++count, move to next storage spot
add di, 24
.skipent:
test ebx, ebx ; if ebx resets to 0, list is complete
jne short .e820lp
.e820f:
xor eax,eax
mov ax,bp
push eax
xor eax,eax
mov eax, es
shl eax, 4
add eax, 0
push eax ; i will use the address in this register later in 32bit mode to access the list.
clc ; there is "jc" on end of list to this point, so the carry must be cleared
jmp 0:(r16_tail_start-r16_header_start + 0x7e00)
.failed:
stc ; "function unsupported" error exit
ret
e820_end:
(read as base, limit, type)
Code: Select all
0000000000009F400 00000000000A0000 0002
000000000000CE000 00000000000D0000 0002
000000000000DC000 0000000000100000 0002
00000000000100000 00000000BFEE0000 0001
000000000BFEE0000 00000000BFEFF000 0003
000000000BFEFF000 00000000BFF00000 0004
000000000BFF00000 00000000C0000000 0001
000000000F0000000 00000000F8000000 0002
000000000FEC00000 00000000FEC10000 0002
000000000FEE00000 00000000FEE01000 0002
000000000FFFE0000 0000000100000000 0002
00000000100000000 0000000140000000 0001
i tried to a live ubuntu cd and used it's print of e820 (from dmesg) and of course i got correct results (with base of memory accesible)
the final test i did was to run my exact code in kvm and again got correct results:
Code: Select all
00000000000000000 000000000009FC00 0001
0000000000009FC00 00000000000A0000 0002
000000000000F0000 0000000000100000 0002
00000000000100000 00000000BFFE0000 0001
000000000BFFE0000 00000000C0000000 0002
000000000FEFFC000 00000000FF000000 0002
000000000FFFC0000 0000000100000000 0002
00000000100000000 0000000140000000 0001