summaryrefslogtreecommitdiffstats
path: root/src/boot/bootsect.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/boot/bootsect.s')
-rw-r--r--src/boot/bootsect.s263
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
58go: 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
68load_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
81ok_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
132undef_root:
133 jmp undef_root
134root_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#
150sread: .word 1+ SETUPLEN # sectors read of current track
151head: .word 0 # current head
152track: .word 0 # current track
153
154read_it:
155 mov %es, %ax
156 test $0x0fff, %ax
157die: jne die # es must be at 64kB boundary
158 xor %bx, %bx # bx is starting address within segment
159rp_read:
160 mov %es, %ax
161 cmp $ENDSEG, %ax # have we loaded all yet?
162 jb ok1_read
163 ret
164ok1_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
176ok2_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
187ok4_read:
188 mov %ax, head
189 xor %ax, %ax
190ok3_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
201read_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
222bad_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# */
236kill_motor:
237 push %dx
238 mov $0x3f2, %dx
239 mov $0, %al
240 outsb
241 pop %dx
242 ret
243
244sectors:
245 .word 0
246
247msg1:
248 .byte 13,10
249 .ascii "Loading system ..."
250 .byte 13,10,13,10
251
252 .org 508
253root_dev:
254 .word ROOT_DEV
255boot_flag:
256 .word 0xAA55
257
258 .text
259 endtext:
260 .data
261 enddata:
262 .bss
263 endbss: