|
|
1.1 ! root 1: # ! 2: # device-independent boot block ! 3: # uses the rom device driver ! 4: # reads an already-de-headered, small file with predetermined name ! 5: # into the beginning of memory ! 6: # and executes it ! 7: # ! 8: ! 9: .set HIADDR,0x70000 # high address at which we run ! 10: ! 11: .set REGMASK,0x6e # registers to save for second boot ! 12: .set SR1,0 # offsets in save area ! 13: .set SR3,2*4 ! 14: .set DRIVER,4*4 # where device driver addr gets saved ! 15: ! 16: .set BSIZE, 512 # size of a disk block ! 17: .set ISIZE, 64 # size of an i-node ! 18: .set INOPB, BSIZE/ISIZE ! 19: .set ROOTINO, 2 # i-number of the root ! 20: .set ILBLK, 2 # first block of i-list ! 21: .set NDIREC, 10 # number of direct blocks ! 22: .set I_ADDR, 12 # offset to addresses in inode ! 23: .set DIRSIZ, 14 # chars in filename ! 24: ! 25: .set TXCS,34 # console device csr ! 26: .set TXDB,35 # console device data buffer ! 27: .set TRDY_B,7 # bit number of ready bit in TXCS ! 28: ! 29: # ! 30: # main code ! 31: # relocate ourselves to high memory ! 32: # read the root directory, and search it for ! 33: # the desired file ! 34: # read that file in ! 35: # ! 36: ! 37: beg: ! 38: nop;nop;nop;nop # space required by dec bootstrap ! 39: nop;nop;nop;nop ! 40: nop;nop;nop;nop ! 41: start: ! 42: movl $HIADDR,sp # set up new stack ! 43: pushr $REGMASK # save important boot registers ! 44: movl sp,r11 # remember where they are ! 45: movc3 $end,beg,*$HIADDR # copy us up ! 46: jmp *$HIADDR + strel # and jump up there ! 47: strel: ! 48: # ! 49: # get the root i-node ! 50: # ! 51: movl $ROOTINO,r0 ! 52: bsbb iget ! 53: #### check is directory? ! 54: subl2 $NDIREC*4,sp # make room for block pointers ! 55: movl sp,r10 ! 56: bsbw addrcpy ! 57: ! 58: # ! 59: # search the root directory ! 60: # ! 61: ! 62: clrl r12 # init block pointer ! 63: dirblk: ! 64: movl r12,r0 ! 65: clrl r5 # use beginning of mem as buffer ! 66: bsbw lread ! 67: blbs r0,dirgot ! 68: movab notfound,r0 ! 69: bsbw putstr ! 70: direof: brb direof ! 71: ! 72: notfound: .asciz "no boot\r\n" ! 73: ! 74: dirgot: ! 75: clrl r9 ! 76: dirent: ! 77: cmpl r9,$FSBSIZE # done with this block? ! 78: blss dirok # no ! 79: incl r12 # yes, get next one ! 80: brb dirblk ! 81: dirok: ! 82: tstw (r9) # empty entry? ! 83: beql dirno # yes, skip it ! 84: cmpc3 $DIRSIZ,2(r9),bootname # desired name? ! 85: beql diryes # yep ! 86: dirno: ! 87: addl2 $DIRSIZ+2,r9 ! 88: brb dirent ! 89: ! 90: # ! 91: # found the file ! 92: # fetch its i-node and read it in ! 93: # ! 94: ! 95: diryes: ! 96: movzwl (r9),r0 # i-number ! 97: bsbb iget ! 98: ##### check i-node? ! 99: bsbb addrcpy ! 100: clrl r12 ! 101: rdloop: ! 102: movl r12,r0 ! 103: mull3 $FSBSIZE,r12,r5 ! 104: bsbb lread ! 105: blbc r0,done ! 106: incl r12 ! 107: brb rdloop ! 108: ! 109: # ! 110: # read it in ! 111: # reset registers and start it ! 112: # ! 113: ! 114: done: ! 115: movl r11,sp ! 116: popr $REGMASK ! 117: movl r5,r11 # put boot flags in stupid bky place ! 118: movzbl $DEVNUM,r10 # more berkeley bullshit - 7 == uda50 ! 119: jmp *$2 # skip register mask & start it ! 120: ! 121: # ! 122: # fetch an i-node ! 123: # r0 has the i-number ! 124: # on exit, r0 points to the i-node in core ! 125: # address 0 is used as a buffer ! 126: # ! 127: ! 128: iget: ! 129: decl r0 # i-numbers are 1 based ! 130: clrl r1 # make a quadword ! 131: ediv $INOPB,r0,r8,-(sp) # r8 == block; (sp) == offset ! 132: addl2 $ILBLK*FSBSIZE/BSIZE,r8 ! 133: clrl r5 # into address 0 ! 134: bsbb bread ! 135: mull3 (sp)+,$ISIZE,r0 # point to i-node ! 136: rsb ! 137: ! 138: # ! 139: # copy/convert block numbers ! 140: # out of an i-node ! 141: # r10 points to where we want them ! 142: # r0 points to the i-node ! 143: # for now, only the direct blocks ! 144: # ! 145: # r0 is destroyed ! 146: # ! 147: ! 148: addrcpy: ! 149: movl r10,r1 # make a volatile copy ! 150: clrl r2 # counter ! 151: addl2 $I_ADDR,r0 # point to addresses ! 152: ad0: ! 153: movw (r0)+,(r1)+ ! 154: movb (r0)+,(r1)+ ! 155: clrb (r1)+ ! 156: aoblss $NDIREC,r2,ad0 ! 157: rsb ! 158: ! 159: # ! 160: # read a (filesystem) block from a file ! 161: # (filesystem) block number in r0 ! 162: # buffer address in r5 ! 163: # r10 points to the addresses ! 164: # returns status in r0: ! 165: # low bit set if read a block ! 166: # clear if error or block doesn't exist ! 167: # ! 168: ! 169: lread: ! 170: cmpl r0,$NDIREC ! 171: blss lr0 ! 172: lerr: ! 173: clrl r0 ! 174: rsb ! 175: lr0: ! 176: movl (r10)[r0],r8 ! 177: beql lerr ! 178: mull3 $FSBSIZE/BSIZE,r8,-(sp) # fs block to disk block ! 179: pushl $FSBSIZE/BSIZE # count of disk blocks within fs block ! 180: lrlp: ! 181: movl 4(sp),r8 ! 182: bsbb bread ! 183: addl2 $BSIZE,r5 ! 184: incl 4(sp) ! 185: sobgtr (sp),lrlp ! 186: addl2 $8,sp ! 187: rsb ! 188: ! 189: # ! 190: # read a block from the disk ! 191: # using the rom subroutine ! 192: # block number in r8; ! 193: # buffer address in r5 ! 194: # no return if it failed ! 195: # ! 196: ! 197: bread: ! 198: movq SR1(r11),r1 # device address stuff ! 199: movl SR3(r11),r3 # unit number ! 200: pushl r5 # duplicate address for driver routine ! 201: jsb *DRIVER(r11) # and call driver ! 202: blbc r0,berr ! 203: movl (sp)+,r5 # fixup stack ! 204: rsb ! 205: ! 206: berr: ! 207: movab diskerr,r0 ! 208: bsbb putstr ! 209: berr0: brb berr0 ! 210: ! 211: diskerr: .asciz "disk error\r\n" ! 212: ! 213: # ! 214: # print a null-terminated string on the console ! 215: # string address in r0 ! 216: # ! 217: ! 218: putstr: ! 219: movb (r0)+,r1 ! 220: bneq ps0 ! 221: rsb ! 222: ps0: ! 223: mfpr $TXCS,r2 ! 224: bbc $TRDY_B,r2,ps0 ! 225: mtpr r1,$TXDB ! 226: brb putstr ! 227: ! 228: # ! 229: # miscellaneous stuff ! 230: # ! 231: ! 232: bootname: ! 233: .byte 'b,'o,'o,'t,0,0,0,0,0,0,0,0,0,0 ! 234: ! 235: end:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.