Annotation of researchv10no/sys/boot/bb/bblock.s, revision 1.1

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: # buffering:
        !             9: # the ROM driver will only write into the bottom 64K of memory
        !            10: # to make things simple, we always read to a fixed place,
        !            11: # then copy to the desired place.
        !            12: # if we would have read to the fixed place,
        !            13: # we copy to a safe buffer, and copy back when we're all done.
        !            14: # the same subterfuge is needed to avoid overwriting the in-RAM copy
        !            15: # of the boot ROMs, where our device driver lives,
        !            16: # so we use the memory just below the ROM copy for the buffer
        !            17: #
        !            18:        .set    BSIZE,512       # size of a disk block, according to rom driver
        !            19:        .set    BSHIFT,9
        !            20:        .set    BUFADDR,0xfa00-BSIZE    # where to read stuff
        !            21:        .set    BUFSIZE,1024+BSIZE      # sizeof(buffer) + sizeof(roms)
        !            22: 
        !            23:        .set    NAMELEN,14      # number of chars in name; one element for now
        !            24:        .set    HIADDR,0x70000  # high address at which we run
        !            25: 
        !            26:        .set    REGMASK,0xef    # registers to save for second boot
        !            27:        .set    SVSIZE,7*4
        !            28:        .set    SADR,0          # r0 -- overwritten with start addr
        !            29:        .set    SR1,(1*4)       # offsets in save area
        !            30:        .set    SR3,(3*4)
        !            31:        .set    SFLGS,(4*4)     # boot flags -- r5
        !            32:        .set    DRIVER,(5*4)    # where device driver addr gets saved -- r6
        !            33: 
        !            34:        .set    A_MAGIC,0       # offset in exec hdr: magic number
        !            35:        .set    A_TEXT,4        # text size
        !            36:        .set    A_DATA,8        # data size
        !            37:        .set    A_ENTRY,20      # start address
        !            38: 
        !            39:        .set    ISIZE,64        # size of an i-node
        !            40:        .set    ISHIFT,6        # same as a shift
        !            41:        .set    INOPB,BSIZE/ISIZE
        !            42:        .set    ROOTINO,2       # i-number of the root
        !            43:        .set    ILBLK,2         # first block of i-list
        !            44:        .set    NDIREC,10       # number of direct blocks
        !            45:        .set    NINDIR,256      # number of (interesting) indirect blocks
        !            46:        .set    NINDBLK,NDIREC+NINDIR
        !            47: 
        !            48: #
        !            49: # MAXBLK is the max number of blocks to read;
        !            50: # must be the lesser of NINDBLK (number of blocks available)
        !            51: # and (HIADDR-NINDBLK*4-some slop)/FSBSIZE (space available without overwriting us)
        !            52: #
        !            53:        .set    MAXBLK,(HIADDR-NINDBLK*4-FSBSIZE)/FSBSIZE
        !            54:        .set    I_ADDR,12       # offset to addresses in inode
        !            55:        .set    DIRSIZ,14       # chars in filename
        !            56: 
        !            57:        .set    PGSIZE,1024     # ld's idea of page size -- for 0410 a.out
        !            58:        .set    PGSHIFT,10
        !            59: 
        !            60:        .set    RXCS,32         # console rcv csr
        !            61:        .set    RXDB,33         # console rcv data buffer
        !            62:        .set    RRDY_B,7        # bit number of ready bit in RXCS
        !            63:        .set    TXCS,34         # console xmt csr
        !            64:        .set    TXDB,35         # console xmt data buffer
        !            65:        .set    TRDY_B,7        # bit number of ready bit in TXCS
        !            66: 
        !            67: #
        !            68: # main code
        !            69: # relocate ourselves to high memory
        !            70: # read the root directory, and search it for
        !            71: # the desired file
        !            72: # read that file in
        !            73: #
        !            74: # start must be at addr 0xc
        !            75: #
        !            76: 
        !            77: beg:
        !            78:        brb start;brb start     # 0, 2 valid start addresses
        !            79: hiaddr:        .long   HIADDR
        !            80: .set didsave,hiaddr+3          # a byte which is 0 when we start
        !            81: bufaddr: .long BUFADDR         # handy constant reference
        !            82: start:
        !            83:        movl    hiaddr,sp       # set up new stack
        !            84:        pushr   $REGMASK        # save important boot registers
        !            85:        movl    sp,r11          # remember where they are
        !            86:        movc3   $end,beg,SVSIZE(sp)     # copy us up
        !            87:        jmp     strel+SVSIZE(sp)
        !            88: 
        !            89: bootname:
        !            90:        .byte   'u,'n,'i,'x,0,0,0,0,0,0,0,0,0,0
        !            91: 
        !            92: 
        !            93: #
        !            94: # print a character on the console from r1
        !            95: #
        !            96: 
        !            97: putc:
        !            98:        mfpr    $TXCS,r2
        !            99:        bbc     $TRDY_B,r2,putc
        !           100:        mtpr    r1,$TXDB
        !           101:        rsb
        !           102: 
        !           103: #
        !           104: # jump here after relocation
        !           105: #
        !           106: 
        !           107: strel:
        !           108:        blbs    SFLGS(r11),stask        # boot flag 1 == prompt for filename
        !           109:        movab   bootname,r0
        !           110: 0:     movzbl  (r0)+,r1
        !           111:        beql    prnl
        !           112:        bsbb    putc
        !           113:        brb     0b
        !           114: 
        !           115: stask:
        !           116:        movl    r11,sp          # in case we loop back
        !           117: 
        !           118: #
        !           119: # read a string from the console into bootname
        !           120: # terminated by newline
        !           121: #
        !           122: 
        !           123: getpr:
        !           124:        movzbl  $'*,r1          # prompt
        !           125:        bsbb    putc
        !           126: 
        !           127: getname:
        !           128:        movab   bootname,r3
        !           129:        movzbl  $NAMELEN-1,r0
        !           130: 0:     mfpr    $RXCS,r1
        !           131:        bbc     $RRDY_B,r1,0b
        !           132:        mfpr    $RXDB,r1
        !           133:        bicb2   $0200,r1
        !           134:        bsbb    putc
        !           135:        cmpb    $015,r1
        !           136:        beql    8f
        !           137:        cmpb    $040,r1         # ignore control chars; thanks, nautilus
        !           138:        bgtr    0b
        !           139:        decl    r0
        !           140:        blss    0b
        !           141:        movb    r1,(r3)+
        !           142:        brb     0b
        !           143: 8:     clrb    (r3)+
        !           144:        sobgtr  r0,8b
        !           145: prnl:  movzbl  $015,r1
        !           146:        bsbb    putc
        !           147:        movzbl  $012,r1
        !           148:        bsbb    putc    # and return
        !           149: 2:
        !           150: #
        !           151: # get the root i-node
        !           152: #
        !           153:        movl    $ROOTINO,r0
        !           154:        bsbb    iget
        !           155: #### check is directory?
        !           156:        movab   -NINDBLK*4(sp),sp
        !           157:        movl    sp,r10
        !           158:        bsbb    addrcpy
        !           159: #
        !           160: # search the root directory
        !           161: #
        !           162: 
        !           163:        clrl    r12                     # init block pointer
        !           164: dirblk:
        !           165:        clrl    r5                      # use beginning of mem as buffer
        !           166:        bsbw    lread
        !           167:        bneq    stask                   # eof, try another file
        !           168:        clrl    r9
        !           169: 0:
        !           170:        movzwl  (r9)+,r0                # empty entry?
        !           171:        beql    2f                      # yes, skip it
        !           172:        clrl    r1
        !           173: 1:     cmpb    (r9)[r1],bootname[r1]   # MicroVAX II doesn't have cmpc
        !           174:        bneq    2f
        !           175:        aoblss  $DIRSIZ,r1,1b
        !           176:        brb     diryes                  # the name we want
        !           177: 
        !           178: 2:     acbw    $FSBSIZE-1,$DIRSIZ,r9,0b
        !           179:        incl    r12                     # get next block
        !           180:        brb     dirblk
        !           181: 
        !           182: berr:  brb     stask
        !           183: 
        !           184: #
        !           185: # subroutines placed here, out of sequence, to save space
        !           186: #
        !           187: # copy/convert block numbers
        !           188: # out of an i-node
        !           189: # r10 points to where we want them
        !           190: # r0 points to the i-node
        !           191: # for now, only the direct blocks
        !           192: #
        !           193: # r0 is destroyed
        !           194: #
        !           195: 
        !           196: addrcpy:
        !           197:        movl    r10,r1                  # make a volatile copy
        !           198:        addl2   $I_ADDR,r0              # point to addresses
        !           199:        clrl    r2
        !           200: 0:
        !           201:        movw    (r0)+,(r1)+
        !           202:        movzbw  (r0)+,(r1)+
        !           203:        aoblss  $NDIREC+1,r2,0b
        !           204:        rsb
        !           205: 
        !           206: #
        !           207: # fetch an i-node
        !           208: # r0 has the i-number
        !           209: # on exit, r0 points to the i-node in core
        !           210: # address 0 is used as a buffer
        !           211: #
        !           212: 
        !           213: iget:
        !           214:        decl    r0                      # i-numbers are 1 based
        !           215:        clrl    r1                      # make a quadword
        !           216:        ediv    $INOPB,r0,r8,-(sp)      # r8 == block; (sp) == offset
        !           217:        addl2   $ILBLK*FSBSIZE/BSIZE,r8
        !           218:        clrl    r5                      # into address 0
        !           219:        bsbb    bread
        !           220:        ashl    $ISHIFT,(sp)+,r0        # point to i-node
        !           221:        rsb
        !           222: 
        !           223: #
        !           224: # read a BSIZE block from the disk
        !           225: # using the rom subroutine
        !           226: # block number in r8;
        !           227: # buffer address in r5
        !           228: # no return if it failed
        !           229: #
        !           230: # hack: if we would read atop the boot roms, don't;
        !           231: # read into a safe place instead, and remember
        !           232: # for the purposes of the hack, it's assumed that
        !           233: # reads are aligned in memory conveniently
        !           234: #
        !           235: 
        !           236: bread:
        !           237:        subl3   bufaddr,r5,r0
        !           238:        blss    0f
        !           239:        cmpl    r0,$BUFSIZE
        !           240:        bgeq    0f
        !           241:         movab  savedata,r5
        !           242:         addl2  r0,r5
        !           243:         movb   $1,didsave
        !           244: 0:
        !           245:        pushl   r5              # save real addr
        !           246:        movl    bufaddr,r5      # get buffer loc
        !           247:        movq    SR1(r11),r1     # device address stuff
        !           248:        movl    SR3(r11),r3     # unit number
        !           249:        pushl   r5              # duplicate address for driver routine
        !           250:        jsb     *DRIVER(r11)    # and call driver
        !           251:        blbc    r0,berr         # disk error, start over
        !           252:        tstl    (sp)+           # fixup stack
        !           253:        movc3   $BSIZE,*bufaddr,*(sp)+  # copy data to final resting place
        !           254:        rsb
        !           255: 
        !           256: #
        !           257: # back to the main path:
        !           258: # found the file
        !           259: # fetch its i-node and read it in
        !           260: # i-number left in r0 for us
        !           261: #
        !           262: 
        !           263: diryes:
        !           264:        bsbb    iget
        !           265: ##### check i-node?
        !           266:        bsbb    addrcpy
        !           267: #
        !           268: # indirect blocks
        !           269: # only the first 1024 bytes of the first indirect block examined
        !           270: #
        !           271:        mull3   NDIREC*4(r10),$FSBSIZE/BSIZE,r12 # pick up one indirect block
        !           272:        beql    noind
        !           273:        movl    r12,r8
        !           274:        moval   NDIREC*4(r10),r5
        !           275:        bsbb    bread
        !           276:        addl3   r12,$1,r8               # 2 sectors == 256 indirections
        !           277:        moval   NDIREC*4+BSIZE(r10),r5
        !           278:        bsbb    bread
        !           279: noind:
        !           280:        clrl    r5
        !           281:        clrl    r12
        !           282: rdloop:
        !           283:        ashl    $FSSHIFT,r12,r5
        !           284:        bsbb    lread
        !           285:        bneq    eof
        !           286:        incl    r12
        !           287:        brb     rdloop
        !           288: #
        !           289: # whole file read in
        !           290: # check for a.out header and relocate
        !           291: #
        !           292: eof:
        !           293:        blbc    didsave,1f
        !           294:         movc3  $BUFSIZE,savedata,*bufaddr
        !           295: 1:     clrl    r12
        !           296:        movq    A_TEXT(r12),r7  # r7 = text size; r8 = data size
        !           297:        movl    A_ENTRY(r12),SADR(r11)  # starting address
        !           298: 2:     casel   A_MAGIC(r12),$0407,$1
        !           299: 0:     .word   m0407-0b
        !           300:        .word   m0410-0b
        !           301:        clrl    SADR(r11)       # no a.out, start at the top
        !           302:        brb     done
        !           303: m0407:
        !           304:        addl2   r8,r7           # text = text + data; no data
        !           305:        clrl    r8
        !           306: #
        !           307: # do copies by longword: simpler and smaller than movc3,
        !           308: # which would need to loop anyway
        !           309: # longword not quadword because ld rounds sizes to long
        !           310: #
        !           311: # really should beql after the second div, else when there's no data
        !           312: # we copy one extra word to a nonsense place.
        !           313: # too bad; we can't spare the code space
        !           314: #
        !           315: m0410:
        !           316:        clrl    r0
        !           317:        movzbl  $32,r1
        !           318:        addl3   r7,r8,r2
        !           319:        divl2   $4,r2
        !           320: 1:     movl    (r1)+,(r0)+     # copy down over a.out header
        !           321:        sobgtr  r2,1b
        !           322: #
        !           323: # assertion: r0 == t + d
        !           324: #
        !           325:        extzv   $0,$PGSHIFT,r7,r1       # r1 = t & pagemask
        !           326:        beql    3f              # no offset, no work
        !           327:        subw3   r1,$PGSIZE,r1
        !           328:        addl3   r1,r0,r1        # r1 = (t + d) + alignment offset
        !           329:        divl3   $4,r8,r2
        !           330: 2:     movl    -(r0),-(r1)     # copy data to start at page boundary
        !           331:        sobgtr  r2,2b
        !           332: 3:
        !           333: #
        !           334: # reset registers and start
        !           335: #
        !           336: 
        !           337: done:
        !           338:        movl    r11,sp
        !           339:        popr    $REGMASK
        !           340:        movl    r5,r11          # put boot flags in stupid bky place
        !           341:        jmp     2(r0)           # skip register mask & start it
        !           342: 
        !           343: #
        !           344: # read a (filesystem) block from a file
        !           345: # (filesystem) block number in r12
        !           346: # buffer address in r5
        !           347: # r10 points to the addresses
        !           348: # returns status in psw:
        !           349: # zero flag set if read a block
        !           350: # clear if error or block doesn't exist
        !           351: #
        !           352: 
        !           353: lread:
        !           354:        cmpw    r12,$MAXBLK
        !           355:        blss    0f
        !           356: lerr:
        !           357:        bicpsw  $4              # clear zero flag
        !           358:        rsb
        !           359: 0:
        !           360:        movl    (r10)[r12],r8
        !           361:        beql    lerr
        !           362:        pushl   $FSBSIZE/BSIZE  # count of disk blocks within fs block
        !           363:        mull3   $FSBSIZE/BSIZE,r8,-(sp) # fs block to disk block
        !           364: 1:
        !           365:        movl    (sp),r8
        !           366:        movl    r5,r6           # safe place
        !           367:        bsbw    bread
        !           368:        movab   BSIZE(r6),r5
        !           369:        incl    (sp)
        !           370:        sobgtr  4(sp),1b
        !           371:        clrq    (sp)+           # addl2 $8,sp; set zero bit
        !           372:        rsb
        !           373: #
        !           374: # last address that needs saving
        !           375: #
        !           376:        .globl end
        !           377: end:
        !           378: 
        !           379: #
        !           380: # put uninitialized (not 0) data here
        !           381: #
        !           382:        .align  2
        !           383: savedata:
        !           384: #      .space  ROMSIZE

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.