|
|
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.