|
|
1.1 root 1: ////////
2: /
3: / Master Boot Block
4: /
5: / To be installed in first block of hard disk drives.
6: / Supports 4 logical partitions per drive, with the
7: / info layout specified by /usr/include/sys/fdisk.h.
8: /
9: / Will execute the keyboard selected or active partition.
10: / Keyboard chars 0-3 will select partitions 0, 1, 2, or 3 on 1st drive.
11: / Keyboard chars 4-7 will select partitions 0, 1, 2, or 3 on 2nd drive.
12: / In the event of an empty partition, a read error, or
13: / invalid partition signature, prompts for new partition.
14: /
15: / Partition parameters can be modified by fdisk(8).
16: /
17: / Author: Allan Cornish, INETCO Systems Ltd, April 23 1985
18: /
19: / $Log: /newbits/conf/boot/RCS/mboot.s,v $
20: / Revision 1.1 91/05/29 08:30:28 bin
21: / Initial revision
22: /
23: / Revision 1.1 88/03/24 16:44:18 src
24: / Initial revision
25: /
26: / 86/12/11 Allan Cornish /usr/src/sys/i8086/boot/mboot.s
27: / Diagnostic messages modified.
28: /
29: / 86/12/03 Allan Cornish /usr/src/sys/i8086/boot/mboot.s
30: / Extended to support booting on either hard disk.
31: /
32: ////////
33:
34: ////////
35: /
36: / Offsets within partition structure to data fields.
37: /
38: ///////
39: P_BOOT = 0
40: P_BHD = 1
41: P_BSEC = 2
42: P_BCYL = 3
43: P_SYS = 4
44: P_EHD = 5
45: P_ESEC = 6
46: P_ECYL = 7
47: P_BASE = 8
48: P_SIZE = 12
49:
50: ////////
51: /
52: / Magic constants.
53: /
54: ////////
55:
56: VIDEO = 0x10 / video swi
57: DISK = 0x13 / disk io swi
58: KEYBD = 0x16 / keyboard swi
59: READ1 = 0x0201 / read 1 sector
60: BOOTLC = 0x7C00 / boot location
61: RBOOTLC = 0x0600 / relocated boot location
62: JMPF = 0xEA / jump far, direct
63:
64: ////////
65: /
66: / Master boot block startup code.
67: /
68: / Action: Setup segmentation registers.
69: / Generate a 'INETCO Systems' message on console.
70: / Copy boot block to new location.
71: / Transfer control to relocated boot block.
72: /
73: ////////
74:
75: cli
76: sub ax, ax
77: mov es, ax
78: mov ds, ax
79: mov ss, ax
80: mov sp, $BOOTLC
81: sti
82: cld
83:
84: mov si, $m_hello+BOOTLC
85: call puts
86:
87: mov si, sp
88: mov di, $RBOOTLC
89: mov cx, $512
90: rep
91: movsb
92:
93: .byte JMPF
94: .word entry+RBOOTLC
95: .word 0
96:
97: ////////
98: /
99: / entry
100: /
101: / Action: If input character is available from keyboard,
102: / transfer control to partition selection routine.
103: / Otherwise, transfer control to partition scan routine.
104: /
105: ////////
106:
107: entry: movb ah, $1 / entry:
108: int KEYBD / if ( iskey() )
109: jne select / goto select;
110: call scan / scan();
111: incb m_drvnum+RBOOTLC / drvnum++;
112: call scan / scan();
113: jmp resel / goto resel;
114:
115: ////////
116: /
117: / warn
118: /
119: / Input: SI = null terminated error message.
120: /
121: / Action: Output error message.
122: / Tranfer control to partition reselection routine.
123: /
124: ////////
125:
126: warn: / warn:
127: mov sp, $BOOTLC /
128: call puts / puts( s );
129: // jmp resel / goto resel;
130:
131: ////////
132: /
133: / resel
134: /
135: / Action: Prompt for user input of partition #.
136: / Wait until keyboard data is available.
137: / Transfer control to partition selection routine.
138: /
139: ////////
140:
141: resel: / resel:
142: mov si, $m_select+RBOOTLC / puts("Select partn ... ? ");
143: call puts /
144: /
145: 0: movb ah, $1 / while (! iskey() )
146: int KEYBD / ;
147: je 0b /
148: /
149: call crnl / puts("\r\n");
150: // jmp select / goto select;
151:
152: ////////
153: /
154: / select
155: /
156: / Action: Read character from keyboard.
157: / Use chars 0..3 as index into partition table.
158: / Select drive and partition.
159: / Initiate read of selected drive's master boot block.
160: /
161: ////////
162:
163: select: / select:
164: movb ah, $0 / ch = nextkey();
165: int KEYBD /
166: /
167: movb m_partnum+RBOOTLC, al / partnum = ch;
168: movb m_drvnum+RBOOTLC, $'1 / drvnum = '1';
169: /
170: subb al, $'0 / if ( (ch -= '0') < 0 )
171: jl resel / goto resel;
172: cmpb al, $7 / if (ch > 7)
173: jg resel / goto resel;
174: /
175: cmpb al, $4 / if ( ch < 4 )
176: sbbb m_drvnum+RBOOTLC, $0 / drvnum--;
177: /
178: andb al, $~4 / ch &= ~4;
179: /
180: cbw / pp = &partitions[ch];
181: movb cl, $4 /
182: shl ax, cl /
183: add ax, $partitions+RBOOTLC /
184: mov di, ax /
185: /
186: call rdinfo / rdinfo();
187: /
188: // jmp rdboot / goto rdboot;
189:
190: ////////
191: /
192: / rdboot - read partition boot block
193: /
194: / Action: Validate partition table.
195: / Ensure booting partition exists.
196: / Read the partition boot block into memory.
197: /
198: ////////
199:
200: rdboot: / rdboot:
201: mov si, $m_partn+RBOOTLC /
202: call puts / puts("Partition #n");
203: /
204: mov si, $m_empty+RBOOTLC / if (pp->p_size == 0) {
205: mov ax, P_SIZE(di) / s = " is empty\n";
206: or ax, P_SIZE+2(di) / goto warn;
207: je warn / }
208: /
209: movb al, m_drvnum+RBOOTLC / pp->p_boot = drvnum-'0' + 0x80;
210: addb al, $0x80-0x30 /
211: movb P_BOOT(di), al /
212: /
213: mov cx, P_BSEC(di) / p_bsec -> cl, p_bcyl -> ch
214: mov dx, P_BOOT(di) / p_boot -> dl, p_bhd -> dh
215: call rdblock / rdblock();
216: /
217: // jmp exec / goto exec;
218:
219: ////////
220: /
221: / exec()
222: /
223: / Action: Validate partition boot block at BOOTLC.
224: / If valid, transfer control to partition boot block.
225: /
226: ////////
227:
228: exec: call crnl / puts("\r\n");
229: /
230: mov bx, sp /
231: mov cx, P_BSEC(di) /
232: mov dx, P_BOOT(di) /
233: mov si, di /
234: mov bp, di /
235: jmp BOOTLC-RBOOTLC / jump relative to new boot block
236:
237: ////////
238: /
239: / scan
240: / Action: Read partition table from current drive.
241: / Scan partition table for active partition.
242: / If found, transfer control to rdboot routine.
243: / Otherwise, allow partition reselection.
244: /
245: ////////
246:
247: scan: / scan:
248: call rdinfo / rdinfo();
249: /
250: mov di, $partitions+RBOOTLC / pp = &partitions[0];
251: mov cx, $4 / n = 4;
252: /
253: 0: testb P_BOOT(di), $0x80 / do { if (pp->b_boot & 0x80)
254: jne rdboot / goto rdboot;
255: add di, $0x10 / pp++;
256: incb m_partnum+RBOOTLC / partnum++;
257: loop 0b / } while (--n != 0);
258: /
259: ret / return;
260:
261: ////////
262: /
263: / rdblock - read disk block
264: /
265: / Input: CX/DX = sector/drive information
266: /
267: / Action: Read block from disk.
268: / Reset drive and report error on read failure.
269: / Report error if block lacks boot signature.
270: /
271: ////////
272:
273: rdblock: / rdblock:
274: mov ax, $READ1 /
275: mov bx, $BOOTLC /
276: int DISK / READ FROM DISK
277: /
278: jc rderr / if ( read ok ) {
279: cmp BOOTLC+510, $0xAA55 / if ( bad signature ) {
280: mov si, $m_missing+RBOOTLC / s = "has no..";
281: jne warn2 / goto warn;
282: ret / }
283: / return;
284: / }
285: /
286: rderr: sub ax, ax / RESET HARD DISK
287: int DISK /
288: mov si, $m_rderr+RBOOTLC / s = " can't be read\n";
289: warn2: jmp warn / goto warn;
290:
291: ////////
292: /
293: / rdinfo - read partition information
294: /
295: / Action: Read master boot block from current drive.
296: / Extract partition table.
297: /
298: ////////
299:
300: rdinfo: / rdinfo:
301: mov si, $m_drive+RBOOTLC / puts( "Drive X " );
302: call puts /
303: /
304: mov cx, $1 / 1st sector
305: mov dx, $0x0080-0x30 / drive
306: addb dl, m_drvnum+RBOOTLC /
307: call rdblock / read master boot block
308: /
309: push di /
310: mov si, $partitions+BOOTLC / copy partition table
311: mov di, $partitions+RBOOTLC /
312: mov cx, $64 /
313: rep /
314: movsb /
315: pop di /
316: /
317: mov si, $m_invalid+RBOOTLC /
318: mov bx, $partitions+RBOOTLC / pp = &partitions[0];
319: movb al, P_BOOT+0x00(bx) / ch = pp[0].p_boot;
320: orb al, P_BOOT+0x10(bx) / for ( n=1; n < 4; ++n )
321: orb al, P_BOOT+0x20(bx) / ch |= pp[n].p_boot;
322: orb al, P_BOOT+0x30(bx) /
323: andb al, $0x7F / if ( ch & 0x7F )
324: jne warn2 / goto warn;
325: /
326: // call crnl / puts("\r\n");
327: // ret / return;
328:
329: ////////
330: /
331: / crnl - print carriage return followed by line feed.
332: /
333: ////////
334:
335: crnl:
336: mov si, $m_crnl+RBOOTLC / puts("\r\n");
337: // call puts /
338: // ret / return;
339: /
340: lodsb /
341:
342: ////////
343: /
344: / puts( s )
345: / char * s;
346: /
347: / Input: SI = null terminated character string to output.
348: /
349: / Output: DI, SP, and segment registers are preserved.
350: / All others may be destroyed.
351: /
352: ////////
353:
354: 0: movb ah, $14
355: mov bx, $7
356: push si
357: push di
358: int VIDEO
359: pop di
360: pop si
361:
362: puts: / puts(s)
363: lodsb / {
364: orb al, al / while ( ch = *s++ )
365: jne 0b / putc( ch );
366: ret / }
367:
368: ////////
369: /
370: / Text messages.
371: /
372: ////////
373:
374: m_hello: .ascii "Mark Williams "
375: m_crnl: .ascii "\r\n\000"
376:
377: m_drive: .ascii "Drive "
378: m_drvnum: .ascii "0 \000"
379:
380: m_partn: .ascii "Partition "
381: m_partnum: .ascii "0 \000"
382:
383: m_select: .ascii "Select partition [0-7]\000"
384: m_invalid: .ascii "has bad partition table\r\n\n\000"
385: m_empty: .ascii "is empty\r\n\n\000"
386: m_missing: .ascii "has no operating system\r\n\n\000"
387: m_rderr: .ascii "can't be read\r\n\n\000"
388:
389: .blkb 6 / filler
390: partitions: .blkb 64 / partition tables
391: .word 0xAA55 / master boot signature
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.