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