diff options
Diffstat (limited to 'src/boot/bootsect.s')
-rw-r--r-- | src/boot/bootsect.s | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/src/boot/bootsect.s b/src/boot/bootsect.s new file mode 100644 index 0000000..94b1114 --- /dev/null +++ b/src/boot/bootsect.s | |||
@@ -0,0 +1,263 @@ | |||
1 | .code16 | ||
2 | # rewrite with AT&T syntax by falcon <wuzhangjin@gmail.com> at 081012 | ||
3 | # | ||
4 | # SYS_SIZE is the number of clicks (16 bytes) to be loaded. | ||
5 | # 0x3000 is 0x30000 bytes = 196kB, more than enough for current | ||
6 | # versions of linux | ||
7 | # | ||
8 | .equ SYSSIZE, 0x3000 | ||
9 | # | ||
10 | # bootsect.s (C) 1991 Linus Torvalds | ||
11 | # | ||
12 | # bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves | ||
13 | # iself out of the way to address 0x90000, and jumps there. | ||
14 | # | ||
15 | # It then loads 'setup' directly after itself (0x90200), and the system | ||
16 | # at 0x10000, using BIOS interrupts. | ||
17 | # | ||
18 | # NOTE! currently system is at most 8*65536 bytes long. This should be no | ||
19 | # problem, even in the future. I want to keep it simple. This 512 kB | ||
20 | # kernel size should be enough, especially as this doesn't contain the | ||
21 | # buffer cache as in minix | ||
22 | # | ||
23 | # The loader has been made as simple as possible, and continuos | ||
24 | # read errors will result in a unbreakable loop. Reboot by hand. It | ||
25 | # loads pretty fast by getting whole sectors at a time whenever possible. | ||
26 | |||
27 | .global _start, begtext, begdata, begbss, endtext, enddata, endbss | ||
28 | .text | ||
29 | begtext: | ||
30 | .data | ||
31 | begdata: | ||
32 | .bss | ||
33 | begbss: | ||
34 | .text | ||
35 | |||
36 | .equ SETUPLEN, 4 # nr of setup-sectors | ||
37 | .equ BOOTSEG, 0x07c0 # original address of boot-sector | ||
38 | .equ INITSEG, 0x9000 # we move boot here - out of the way | ||
39 | .equ SETUPSEG, 0x9020 # setup starts here | ||
40 | .equ SYSSEG, 0x1000 # system loaded at 0x10000 (65536). | ||
41 | .equ ENDSEG, SYSSEG + SYSSIZE # where to stop loading | ||
42 | |||
43 | # ROOT_DEV: 0x000 - same type of floppy as boot. | ||
44 | # 0x301 - first partition on first drive etc | ||
45 | .equ ROOT_DEV, 0x301 | ||
46 | ljmp $BOOTSEG, $_start | ||
47 | _start: | ||
48 | mov $BOOTSEG, %ax | ||
49 | mov %ax, %ds | ||
50 | mov $INITSEG, %ax | ||
51 | mov %ax, %es | ||
52 | mov $256, %cx | ||
53 | sub %si, %si | ||
54 | sub %di, %di | ||
55 | rep | ||
56 | movsw | ||
57 | ljmp $INITSEG, $go | ||
58 | go: mov %cs, %ax | ||
59 | mov %ax, %ds | ||
60 | mov %ax, %es | ||
61 | # put stack at 0x9ff00. | ||
62 | mov %ax, %ss | ||
63 | mov $0xFF00, %sp # arbitrary value >>512 | ||
64 | |||
65 | # load the setup-sectors directly after the bootblock. | ||
66 | # Note that 'es' is already set up. | ||
67 | |||
68 | load_setup: | ||
69 | mov $0x0000, %dx # drive 0, head 0 | ||
70 | mov $0x0002, %cx # sector 2, track 0 | ||
71 | mov $0x0200, %bx # address = 512, in INITSEG | ||
72 | .equ AX, 0x0200+SETUPLEN | ||
73 | mov $AX, %ax # service 2, nr of sectors | ||
74 | int $0x13 # read it | ||
75 | jnc ok_load_setup # ok - continue | ||
76 | mov $0x0000, %dx | ||
77 | mov $0x0000, %ax # reset the diskette | ||
78 | int $0x13 | ||
79 | jmp load_setup | ||
80 | |||
81 | ok_load_setup: | ||
82 | |||
83 | # Get disk drive parameters, specifically nr of sectors/track | ||
84 | |||
85 | mov $0x00, %dl | ||
86 | mov $0x0800, %ax # AH=8 is get drive parameters | ||
87 | int $0x13 | ||
88 | mov $0x00, %ch | ||
89 | #seg cs | ||
90 | mov %cx, %cs:sectors+0 # %cs means sectors is in %cs | ||
91 | mov $INITSEG, %ax | ||
92 | mov %ax, %es | ||
93 | |||
94 | # Print some inane message | ||
95 | |||
96 | mov $0x03, %ah # read cursor pos | ||
97 | xor %bh, %bh | ||
98 | int $0x10 | ||
99 | |||
100 | mov $24, %cx | ||
101 | mov $0x0007, %bx # page 0, attribute 7 (normal) | ||
102 | #lea msg1, %bp | ||
103 | mov $msg1, %bp | ||
104 | mov $0x1301, %ax # write string, move cursor | ||
105 | int $0x10 | ||
106 | |||
107 | # ok, we've written the message, now | ||
108 | # we want to load the system (at 0x10000) | ||
109 | |||
110 | mov $SYSSEG, %ax | ||
111 | mov %ax, %es # segment of 0x010000 | ||
112 | call read_it | ||
113 | call kill_motor | ||
114 | |||
115 | # After that we check which root-device to use. If the device is | ||
116 | # defined (#= 0), nothing is done and the given device is used. | ||
117 | # Otherwise, either /dev/PS0 (2,28) or /dev/at0 (2,8), depending | ||
118 | # on the number of sectors that the BIOS reports currently. | ||
119 | |||
120 | #seg cs | ||
121 | mov %cs:root_dev+0, %ax | ||
122 | cmp $0, %ax | ||
123 | jne root_defined | ||
124 | #seg cs | ||
125 | mov %cs:sectors+0, %bx | ||
126 | mov $0x0208, %ax # /dev/ps0 - 1.2Mb | ||
127 | cmp $15, %bx | ||
128 | je root_defined | ||
129 | mov $0x021c, %ax # /dev/PS0 - 1.44Mb | ||
130 | cmp $18, %bx | ||
131 | je root_defined | ||
132 | undef_root: | ||
133 | jmp undef_root | ||
134 | root_defined: | ||
135 | #seg cs | ||
136 | mov %ax, %cs:root_dev+0 | ||
137 | |||
138 | # after that (everyting loaded), we jump to | ||
139 | # the setup-routine loaded directly after | ||
140 | # the bootblock: | ||
141 | |||
142 | ljmp $SETUPSEG, $0 | ||
143 | |||
144 | # This routine loads the system at address 0x10000, making sure | ||
145 | # no 64kB boundaries are crossed. We try to load it as fast as | ||
146 | # possible, loading whole tracks whenever we can. | ||
147 | # | ||
148 | # in: es - starting address segment (normally 0x1000) | ||
149 | # | ||
150 | sread: .word 1+ SETUPLEN # sectors read of current track | ||
151 | head: .word 0 # current head | ||
152 | track: .word 0 # current track | ||
153 | |||
154 | read_it: | ||
155 | mov %es, %ax | ||
156 | test $0x0fff, %ax | ||
157 | die: jne die # es must be at 64kB boundary | ||
158 | xor %bx, %bx # bx is starting address within segment | ||
159 | rp_read: | ||
160 | mov %es, %ax | ||
161 | cmp $ENDSEG, %ax # have we loaded all yet? | ||
162 | jb ok1_read | ||
163 | ret | ||
164 | ok1_read: | ||
165 | #seg cs | ||
166 | mov %cs:sectors+0, %ax | ||
167 | sub sread, %ax | ||
168 | mov %ax, %cx | ||
169 | shl $9, %cx | ||
170 | add %bx, %cx | ||
171 | jnc ok2_read | ||
172 | je ok2_read | ||
173 | xor %ax, %ax | ||
174 | sub %bx, %ax | ||
175 | shr $9, %ax | ||
176 | ok2_read: | ||
177 | call read_track | ||
178 | mov %ax, %cx | ||
179 | add sread, %ax | ||
180 | #seg cs | ||
181 | cmp %cs:sectors+0, %ax | ||
182 | jne ok3_read | ||
183 | mov $1, %ax | ||
184 | sub head, %ax | ||
185 | jne ok4_read | ||
186 | incw track | ||
187 | ok4_read: | ||
188 | mov %ax, head | ||
189 | xor %ax, %ax | ||
190 | ok3_read: | ||
191 | mov %ax, sread | ||
192 | shl $9, %cx | ||
193 | add %cx, %bx | ||
194 | jnc rp_read | ||
195 | mov %es, %ax | ||
196 | add $0x1000, %ax | ||
197 | mov %ax, %es | ||
198 | xor %bx, %bx | ||
199 | jmp rp_read | ||
200 | |||
201 | read_track: | ||
202 | push %ax | ||
203 | push %bx | ||
204 | push %cx | ||
205 | push %dx | ||
206 | mov track, %dx | ||
207 | mov sread, %cx | ||
208 | inc %cx | ||
209 | mov %dl, %ch | ||
210 | mov head, %dx | ||
211 | mov %dl, %dh | ||
212 | mov $0, %dl | ||
213 | and $0x0100, %dx | ||
214 | mov $2, %ah | ||
215 | int $0x13 | ||
216 | jc bad_rt | ||
217 | pop %dx | ||
218 | pop %cx | ||
219 | pop %bx | ||
220 | pop %ax | ||
221 | ret | ||
222 | bad_rt: mov $0, %ax | ||
223 | mov $0, %dx | ||
224 | int $0x13 | ||
225 | pop %dx | ||
226 | pop %cx | ||
227 | pop %bx | ||
228 | pop %ax | ||
229 | jmp read_track | ||
230 | |||
231 | #/* | ||
232 | # * This procedure turns off the floppy drive motor, so | ||
233 | # * that we enter the kernel in a known state, and | ||
234 | # * don't have to worry about it later. | ||
235 | # */ | ||
236 | kill_motor: | ||
237 | push %dx | ||
238 | mov $0x3f2, %dx | ||
239 | mov $0, %al | ||
240 | outsb | ||
241 | pop %dx | ||
242 | ret | ||
243 | |||
244 | sectors: | ||
245 | .word 0 | ||
246 | |||
247 | msg1: | ||
248 | .byte 13,10 | ||
249 | .ascii "Loading system ..." | ||
250 | .byte 13,10,13,10 | ||
251 | |||
252 | .org 508 | ||
253 | root_dev: | ||
254 | .word ROOT_DEV | ||
255 | boot_flag: | ||
256 | .word 0xAA55 | ||
257 | |||
258 | .text | ||
259 | endtext: | ||
260 | .data | ||
261 | enddata: | ||
262 | .bss | ||
263 | endbss: | ||