-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathboot.asm
195 lines (157 loc) · 3.41 KB
/
boot.asm
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
;; since we will into real mode,BIOS can not be used any more
xor ax, ax
mov ss, ax
;; 0. set up GDT
mov ax, 0
mov ds, ax
mov bx, 0x7c00 + 2048
;; item 0, must be zero
mov dword [bx + 0], 0x00
mov dword [bx + 4], 0x00
;; item 1 we make it to be zero
mov dword [bx + 8], 0x00
mov dword [bx + 12], 0x00
;; item 2, 0-4G, code
mov dword [bx + 16], 0x0000ffff
mov dword [bx + 20], 0x00cf9a00
;; item 3, 0-4G, data
mov dword [bx + 24], 0x0000ffff
mov dword [bx + 28], 0x00cf9200
;; init gdt reg
mov word [gdt_size + 0x7c00], 31
mov eax, [gdt_size + 0x7c00]
lgdt [gdt_size + 0x7c00]
;; 1. to readl mode
;; open A20
in al, 0x92
or al, 000_0010B
out 0x92, al
;; disable interrupt
cli
;; set PE
mov eax, cr0
or eax, 1
mov cr0, eax
;; jmp to read mode
jmp dword 0x010:flush+0x7c00
[bits 32]
flush:
;; 2. to load kernel
mov cx, 0x18
mov ds, cx
mov ss, cx
mov es, cx
mov esp, 0x10000 + 0x1000
mov ecx, 1024
mov ebx, 0x100000
mov eax, 2049
read_kernel:
push ebx ;buffer address
push 0x0
push 16 ;8kb a time
push eax ;start sector_number
call _read_sectors_lba24
pop edx
pop edx
pop edx
pop edx
add eax, 16
add ebx, 512 * 2 * 8
dec ecx
jnz read_kernel
;; jmp to kernel
jmp [kernel_address + 0x7c00]
check_ready:
mov dx, 0x1f7
in al, dx
test al, 0x40
jz check_ready
ret
check_read_complete:
mov dx, 0x1f7
in al, dx
test al, 0x08
jz check_ready
ret
pio_delay:
nop
nop
nop
nop
ret
;;
;; read sectors to buffer
;; void
;; read_sectors_lba24 (
;; int sector_number,
;; int sector_count,
;; int driver,
;; int buffer);
;;
;; parameters:
;; sector_number: the start sector to read
;; sector_count: the count of sectors to read
;; driver: 0: 1st desk, 1: 2nd desk
;; buffer: the address of buffer
;;
_read_sectors_lba24:
push ebp
mov ebp, esp
push eax
push ebx
push ecx
push edx
push edi
call check_ready
mov dx, 0x1f2
mov eax, dword [ebp+12]
out dx, al ; sector count
call pio_delay
mov dx, 0x1f3
mov eax, dword [ebp+8]
out dx, al ; 0~7 bit
call pio_delay
mov dx, 0x1f4
mov eax, dword [ebp+8]
shr eax, 8 ; 8~15 bit
out dx, al
call pio_delay
mov dx, 0x1f5
mov eax, dword [ebp+8]
shr eax, 16 ; 16~23 bit
out dx, al
call pio_delay
mov ebx, dword [ebp+16]
and ebx, 1
shl bl, 4
mov al, 0xe0 ; 5~7: 111, 4: driver, 0~3: 24~27 bit
or al, bl
mov ebx, dword [ebp+8]
shr ebx, 24 ; 24~27 bit
and bl, 0x0f
or al, bl
mov dx, 0x1f6
out dx, al
mov dx, 0x1f7
mov al, 0x20 ; read until succeed
out dx, al
call check_read_complete
mov ecx, 256 * 16
mov dx, 0x1f0
mov ebx, dword [ebp + 20]
readw:
in ax, dx
mov [ebx], ax
add ebx, 2
loop readw
pop edi
pop edx
pop ecx
pop ebx
pop eax
pop ebp
ret
;; gdt_infor----------------------------------------------------------
gdt_size dw 0
gdt_base dd 0x00007c00 + 2048
kernel_address dd 0x000100000