1: MAJOR = 10. / major # from bdevsw[] 2: 3: / RP04/05/06 bootstrap. 4: / 5: / 1995/05/31 - The unit number needs to go in bits 3-5 of bootdev 6: / because the partition number now goes into bits 0-2. 7: / 8: / disk boot program to load and transfer 9: / to a unix entry. 10: / for use with 1 KB byte blocks, CLSIZE is 2. 11: / NDIRIN is the number of direct inode addresses (currently 4) 12: / assembled size must be <= 512; if > 494, the 16-byte a.out header 13: / must be removed 14: 15: / options: none. all options of reading an alternate name or echoing to 16: / the keyboard had to be removed to make room for the 17: / code which understands the new directory structure on disc 18: 19: / 930124 Fixed major bug that made booting impossible. 20: / Lasse Ylitalo & Johnny Billquist 21: 22: / constants: 23: CLSIZE = 2. / physical disk blocks per logical block 24: CLSHFT = 1. / shift to multiply by CLSIZE 25: BSIZE = 512.*CLSIZE / logical block size 26: INOSIZ = 64. / size of inode in bytes 27: NDIRIN = 4. / number of direct inode addresses 28: ADDROFF = 12. / offset of first address in inode 29: INOPB = BSIZE\/INOSIZ / inodes per logical block 30: INOFF = 31. / inode offset = (INOPB * (SUPERB+1)) - 1 31: PBSHFT = -4 / shift to divide by inodes per block 32: WC = -256.*CLSIZE / word count 33: 34: / The boot options and device are placed in the last SZFLAGS bytes 35: / at the end of core by the kernel for autobooting. 36: ENDCORE= 160000 / end of core, mem. management off 37: SZFLAGS= 6 / size of boot flags 38: BOOTOPTS= 2 / location of options, bytes below ENDCORE 39: BOOTDEV= 4 40: CHECKWORD= 6 41: 42: .. = ENDCORE-512.-SZFLAGS / save room for boot flags 43: 44: / entry is made by jsr pc,*$0 45: / so return can be rts pc 46: 47: / establish sp, copy 48: / program up to end of core. 49: 50: nop / These two lines must be present or DEC 51: br start / boot ROMs will refuse to run boot block! 52: start: 53: mov r0,unit 54: mov r1,csr 55: mov $..,sp 56: mov sp,r1 57: clr r0 58: 1: 59: mov (r0)+,(r1)+ 60: cmp r1,$end 61: blo 1b 62: jmp *$2f 63: 64: / On error, restart from here. 65: restart: 66: clr r0 67: / clear core to make things clean 68: 2: 69: clr (r0)+ 70: cmp r0,sp 71: blo 2b 72: 73: / initialize hp 74: mov csr,r1 75: mov unit,hpcs2(r1) 76: mov $preset+go,hpcs1(r1) 77: mov $fmt22,hpof(r1) 78: 79: mov $bootnm, r1 80: mov $2,r0 / ROOTINO 81: jsr pc,iget 82: clr r2 / offset 83: again: 84: jsr pc,readdir 85: beq restart / error - restart 86: mov 4(r0),r4 / dp->d_namlen 87: cmp r4,$bootlen / if (bootlen == dp->d_namlen) 88: bne again / nope, go try next entry 89: mov r0,r3 90: add $6,r3 / r3 = dp->d_name 91: mov r1,r5 / r5 = filename 92: 9: 93: cmpb (r3)+,(r5)+ 94: bne again / no match - go read next entry 95: sob r4,9b 96: mov (r0),r0 / r0 = dp->d_ino 97: jsr pc,iget / fetch boot's inode 98: br loadfile / 'boot'- go read it 99: 100: / get the inode specified in r0 101: iget: 102: add $INOFF,r0 103: mov r0,r5 104: ash $PBSHFT,r0 105: bic $!7777,r0 106: mov r0,dno 107: clr r0 108: jsr pc,rblk 109: bic $!17,r5 110: mov $INOSIZ,r0 111: mul r0,r5 112: add $buf,r5 113: mov $inod,r4 114: 1: 115: movb (r5)+,(r4)+ 116: sob r0,1b 117: rts pc 118: 119: readdir: 120: bit $BSIZE-1,r2 121: bne 1f 122: jsr pc,rmblk / read mapped block (bno) 123: br err / end of file branch 124: clr r2 / start at beginning of buf 125: 1: 126: mov $buf,r0 127: add r2,r0 / dp = buf+offset 128: add buf+2(r2),r2 / dp += dp->d_reclen 129: tst (r0) / dp->d_ino == 0? 130: beq readdir / yes - go look at next 131: rts pc / return with r0 = &dp->d_ino 132: err: 133: clr r0 / return with 134: rts pc / dp = NULL 135: 136: loadfile: 137: clr bno / start at block 0 of inode in 'inod' 138: / read file into core until 139: / a mapping error, (no disk address) 140: clr r1 141: 1: 142: jsr pc,rmblk 143: br 1f 144: mov $buf,r2 145: 2: 146: mov (r2)+,(r1)+ 147: cmp r2,$buf+BSIZE 148: blo 2b 149: br 1b 150: / relocate core around 151: / assembler header 152: 1: 153: clr r0 154: cmp (r0),$407 155: bne 2f 156: 1: 157: mov 20(r0),(r0)+ 158: cmp r0,sp 159: blo 1b 160: / enter program and 161: / restart if return 162: 2: 163: mov ENDCORE-BOOTOPTS, r4 164: mov unit,r3 165: ash $3,r3 / unit # in bits 3-5, partition # is 0 166: bis $MAJOR\<8.,r3 167: mov ENDCORE-CHECKWORD, r2 168: mov csr,r1 169: jsr pc,*$0 170: br restart 171: 172: / read a mapped block 173: / offset in file is in bno. 174: / skip if success, no skip if fail 175: / the algorithm only handles a single 176: / indirect block. that means that 177: / files longer than NDIRIN+256 blocks (260kb) cannot 178: / be loaded. 179: rmblk: 180: add $2,(sp) 181: mov bno,r0 182: cmp r0,$NDIRIN 183: blt 1f 184: mov $NDIRIN,r0 185: 1: 186: ash $2,r0 187: mov addr+2(r0),dno 188: mov addr(r0),r0 189: bne 1f 190: tst dno 191: beq 2f 192: 1: 193: jsr pc,rblk 194: mov bno,r0 195: inc bno 196: sub $NDIRIN,r0 197: blt 1f 198: ash $2,r0 199: mov buf+2(r0),dno 200: mov buf(r0),r0 201: bne rblk 202: tst dno 203: bne rblk 204: 2: 205: sub $2,(sp) 206: 1: 207: rts pc 208: 209: read = 70 210: preset = 20 211: go = 1 212: fmt22 = 10000 213: 214: hpcs1 = 0 215: hpda = hpcs1+6 216: hpcs2 = hpcs1+10 217: hpds = hpcs1+12 218: hpof = hpcs1+32 219: hpca = hpcs1+34 220: 221: / rp0456 disk driver. 222: / low order address in dno, 223: / high order in r0. 224: rblk: 225: mov r1,-(sp) 226: mov dno,r1 227: .if CLSIZE-1 228: ashc $CLSHFT,r0 / multiply by CLSIZE 229: .endif 230: div $22.*19.,r0 231: mov csr,r3 232: mov r0,hpca(r3) 233: clr r0 234: div $22.,r0 235: swab r0 236: bis r1,r0 237: add $hpcs2,r3 / 930124 LY&JB 238: mov unit,(r3) 239: mov r0,-(r3) 240: mov $buf,-(r3) 241: mov $WC,-(r3) 242: mov $read+go,-(r3) 243: 1: 244: tstb (r3) 245: bge 1b 246: mov (sp)+,r1 247: rts pc 248: 249: bootnm: <boot\0\0> 250: bootlen = 4 / strlen(bootnm) 251: unit: 0 252: csr: 0 253: end: 254: 255: inod = ..-512.-BSIZE / room for inod, buf, stack 256: addr = inod+ADDROFF / first address in inod 257: buf = inod+INOSIZ 258: bno = buf+BSIZE 259: dno = bno+2