1 .code16 2 3#define SMAP 0x534d4150 4#define E820_BIOS_MAX 128 5 6get_memory_map: 7 8.Lmeme820: 9 xorl %ebx, %ebx # continuation counter 10 movw $bootsym(bios_e820map), %di # point into the whitelist 11 # so we can have the bios 12 # directly write into it. 13 141: movl $0x0000e820, %eax # e820, upper word zeroed 15 movl $SMAP,%edx # ascii 'SMAP' 16 movl $20,%ecx # size of the e820rec 17 pushw %ds # data record. 18 popw %es 19 int $0x15 20 jc .Lmem88 21 22 cmpl $SMAP,%eax # check the return is `SMAP' 23 jne .Lmem88 24 25 incw bootsym(bios_e820nr) 26 cmpw $E820_BIOS_MAX, bootsym(bios_e820nr) # up to this many entries 27 jae .Lmem88 28 29 movw %di,%ax 30 addw $20,%ax 31 movw %ax,%di 32 testl %ebx,%ebx # check to see if 33 jnz 1b # %ebx is set to EOF 34 35.Lmem88: 36 movb $0x88, %ah 37 int $0x15 38 movw %ax,bootsym(highmem_kb) 39 40.Lmeme801: 41 stc # fix to work around buggy 42 xorw %cx,%cx # BIOSes which don't clear/set 43 xorw %dx,%dx # carry on pass/error of 44 # e801h memory size call 45 # or merely pass cx,dx though 46 # without changing them. 47 movw $0xe801, %ax 48 int $0x15 49 jc .Lint12 50 51 testw %cx, %cx # Kludge to handle BIOSes 52 jnz 1f # which report their extended 53 testw %dx, %dx # memory in AX/BX rather than 54 jnz 1f # CX/DX. The spec I have read 55 movw %ax, %cx # seems to indicate AX/BX 56 movw %bx, %dx # are more reasonable anyway... 571: movzwl %dx, %edx 58 shll $6,%edx # and go from 64k to 1k chunks 59 movzwl %cx, %ecx 60 addl %ecx, %edx # add in lower memory 61 movl %edx,bootsym(highmem_kb) # store extended memory size 62 63.Lint12: 64 int $0x12 65 movw %ax,bootsym(lowmem_kb) 66 67 ret 68 69 .align 4 70GLOBAL(bios_e820map) 71 .fill E820_BIOS_MAX*20,1,0 72GLOBAL(bios_e820nr) 73 .long 0 74GLOBAL(lowmem_kb) 75 .long 0 76GLOBAL(highmem_kb) 77 .long 0 78