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