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