Last active
February 15, 2024 20:52
-
-
Save Andrej123456789/72a874e0e8629ecec5ddf6e54cdbe2bf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; use the INT 0x15, eax= 0xE820 BIOS function to get a memory map | |
; note: initially di is 0, be sure to set it to a value so that the BIOS code will not be overwritten. | |
; The consequence of overwriting the BIOS code will lead to problems like getting stuck in `int 0x15` | |
; inputs: es:di -> destination buffer for 24 byte entries | |
; outputs: bp = entry count, trashes all registers except esi | |
mmap_ent equ 0x8000 ; the number of entries will be stored at 0x8000 | |
global _do_e820 | |
_do_e820: | |
mov di, 0x8004 ; Set di to 0x8004. Otherwise this code will get stuck in `int 0x15` after some entries are fetched | |
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 | |
mov [_segment], es | |
mov [_offset], di | |
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: | |
mov [mmap_ent], bp ; store the entry count | |
mov [_entry_count], bp | |
; mov [_segment], es | |
; mov [_offset], di | |
clc ; there is "jc" on end of list to this point, so the carry must be cleared | |
ret | |
.failed: | |
stc ; "function unsupported" error exit | |
ret | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment