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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
macro bios_a20_enable {
mov ax, 0x2401
int 0x15
}
macro bios_vga_write_mode_3 {
mov ax, 0x03
int 0x10
}
; assumes dl = drive number
macro bios_disk_read dst*, cyl*, head*, sector*, count*, err_label* {
local read_disk
assert 0 <= cyl & cyl <= 1023
assert 0 <= head & head <= 15
assert 1 <= sector & sector <= 17
assert 1 <= count & count <= 128
; try to read disk up to 3 times
mov di, 3
read_disk:
; ah = 0x02, al = number of sectors to read
mov ax, (0x0200 or count)
; es:bx = pointer to destination buffer
if dst = 0
xor bx, bx
else
mov bx, dst
end if
; ch = track/cylinder number, cl = sector number
mov cx, ((cyl and 0xff) shl 8) or ((cyl and 0x300) shl 6) or sector
; dh = head number
if head = 0
xor dh, dh
else
mov dh, head
end if
int 0x13
jc .error
cmp ax, count
jne .error
jmp .exit
.error:
dec di
jz err_label
; reset disk on error
xor ah, ah
stc
int 0x13
jc err_label
jmp read_disk
.exit:
}
macro bios_e820_mmap mmap*, err_label* {
local e820, e820_entry
e820:
virtual at di
label e820_entry
.base dq ?
.length dq ?
.type dd ?
.ext_attr dd ?
.sizeof = $ - e820_entry
end virtual
mov di, mmap + 8
xor ebx, ebx
xor bp, bp
mov edx, 0x0534d4150
mov eax, 0xe820
mov byte [.ext_attr], 0x01
mov ecx, .sizeof
int 0x15
jc err_label
mov edx, 0x0534d4150
cmp eax, edx
jne err_label
test ebx, ebx
jz err_label
jmp @f
.e820_loop:
mov ax, 0xe820
mov byte [.ext_attr], 0x01
mov ecx, .sizeof
int 0x15
jc err_label
mov edx, 0x0534d4150
@@:
jcxz .skip_entry
; ACPI < 3.0
cmp cl, (.sizeof-4)
jbe .not_ext
; ignore data flag
test byte [.ext_attr], 0x01
jz .skip_entry
.not_ext:
mov ecx, dword [.length]
or ecx, dword [.length + 4]
jz .skip_entry
inc bp
add di, .sizeof
.skip_entry:
test ebx, ebx
jnz .e820_loop
; store e820 mmap entry count at beginning
mov [mmap], bp
}
|