123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- /* https://github.com/cirosantilli/x86-bare-metal-examples#bios-detect-memory */
- #include "common.h"
- BEGIN
- CLEAR
- STAGE2
- mov $output, %di
- call do_e820
- /* Debug aid. */
- PRINT_WORD_HEX <%bp>
- PRINT_NEWLINE
- mov %bp, %ax
- mov $0, %dx
- /* Each entry is 24 bytes wide. */
- mov $24, %cx
- mul %cx
- PRINT_BYTES $output, <%ax>
- hlt
- /* This was copy pasted from:
- * http://wiki.osdev.org/Detecting_Memory_%28x86%29#Getting_an_E820_Memory_Map
- *
- * use the INT 0x15, eax= 0xE820 BIOS function to get a memory map
- * inputs: es:di -> destination buffer for 24 byte entries
- * outputs: bp = entry count, trashes all registers except esi
- */
- do_e820:
- xorl %ebx,%ebx # ebx must be 0 to start
- xorw %bp,%bp # keep an entry count in bp
- movl $0x0534D4150,%edx # Place "SMAP" into edx
- movl $0xe820,%eax
- movl $1, %es:20(%di)
- movl $24,%ecx # ask for 24 bytes
- int $0x15
- jc do_e820.failed # carry set on first call means "unsupported function"
- movl $0x0534D4150,%edx # Some BIOSes apparently trash this register?
- cmpl %edx,%eax # on success, eax must have been reset to "SMAP"
- jne do_e820.failed
- testl %ebx,%ebx # ebx = 0 implies list is only 1 entry long (worthless)
- je do_e820.failed
- jmp do_e820.jmpin
- do_e820.e820lp:
- movl $0xe820,%eax # eax, ecx get trashed on every int 0x15 call
- movl $1, %es:20(%di)
- movl $24,%ecx # ask for 24 bytes again
- int $0x15
- jc do_e820.e820f # carry set means "end of list already reached"
- movl $0x0534D4150,%edx # repair potentially trashed register
- do_e820.jmpin:
- jcxz do_e820.skipent # skip any 0 length entries
- cmpb $20,%cl # got a 24 byte ACPI 3.X response?
- jbe do_e820.notext
- testb $1, %es:29(%di)
- je do_e820.skipent
- do_e820.notext:
- mov %ecx, %es:8(%di)
- or %ecx, %es:12(%di)
- jz do_e820.skipent # if length uint64_t is 0, skip entry
- incw %bp # got a good entry: ++count, move to next storage spot
- addw $24,%di
- do_e820.skipent:
- testl %ebx,%ebx # if ebx resets to 0, list is complete
- jne do_e820.e820lp
- do_e820.e820f:
- #movw %bp,mmap_ent # store the entry count
- clc # there is "jc" on end of list to this point, so the carry must be cleared
- ret
- do_e820.failed:
- stc # "function unsupported" error exit
- ret
- output:
|