OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Mar 29, 2024 9:00 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Possible problem in reading e820 output
PostPosted: Mon Jan 22, 2018 3:32 am 
Offline

Joined: Wed Feb 01, 2017 6:48 am
Posts: 10
hi,
I'm using the code from osdev wiki to read e820 output as follows:
Code:
[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:


and when using it in vmware i get the following output:
(read as base, limit, type)
Code:
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


which is kind of weird, since it does not report the base of memory as usable.
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:
00000000000000000 000000000009FC00 0001
0000000000009FC00 00000000000A0000 0002
000000000000F0000 0000000000100000 0002
00000000000100000 00000000BFFE0000 0001
000000000BFFE0000 00000000C0000000 0002
000000000FEFFC000 00000000FF000000 0002
000000000FFFC0000 0000000100000000 0002
00000000100000000 0000000140000000 0001


is there anything i'm missing in regards to how vmware handles those calls ?


Top
 Profile  
 
 Post subject: Re: Possible problem in reading e820 output
PostPosted: Mon Jan 22, 2018 6:49 am 
Offline
Member
Member
User avatar

Joined: Sun Jan 13, 2013 6:24 pm
Posts: 90
Location: Grande Prairie AB
ES:DI = Destination, so ES needs to be set before you start routine. All I did to your code was add

Code:
         mov      ax, 800h
         mov      es, ax

before e820_start: and it returned a map in BOCHs the same as this code does.

Code:
; Read E820 map into a temporary buffer just above boot sector @ 7E0:0

         mov       ax, BOOT_SEG + 32   ; So MSB of EAX is nullified
         mov      es, ax
         mov      ds, ax            ; So segment overrides are not required

         xor      di, di            ; ES:DI = Pointer to base address of map
         mov      bx, di            ; Initial continuation value
         mov      edx, 'PAMS'         ; Function signature
         push   edx

   ; Top of loop to read first or next map entry

ReadNext:   inc      byte [MAP_ENTR]      ; Bump number of map entries = 0 first iteration.
   .skip:   mov      cl, 48            ; Let function call know how big entry can be.
         mov      ax, 0xe820         ; System Service function number.
         int      SYS_SERVICE

   ; Assert the possible error and termination conditions

         jc      .done            ; CY = 1 can happen in all cases
         cmp      bl, 1            ; Is this the first entry
         jb      .done            ; If zero, no more entries
         ja      .J0               ; Next code only needs happen on first iteration

      ; This need only happen on first iteration

         pop      edx
         sub      eax, edx         ; Does BIOS even support this function
         jz      .J0 - 3
         dec      byte [MAP_ENTR]      ; Bump value back to -1
         jmp      .done

         mov      [MAP_SIZE], cl      ; Save actual size of entry returned by function.

   .J0:   jcxz   .skip            ; Ignore any null length entries
         cmp      cl, 20
         jbe      .J1

         test   byte [di + 20], 1   ; Ignore ACPI entries
         jz      .skip

      ; Test 64 bit value representing length for zero

   .J1:   mov      eax, [di + 8]      ; Get low order DWORD of length
         or      eax, [di + 12]      ; Determine if QWORD value is zero
         jz      .skip

      ; Bump ES:DI pointer to next entry

         add      di, cx
         jmp      ReadNext

   .done:   or      di, di            ; Was a map even created


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 330 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group