IMD 1.17: 17/11/2010 7:08:54 /usr/sys/sys (file system - process manager) (systems sources)  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ÅÙÔÁ×@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@åÖÓñÃÄÃÂ×Ö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@æÈÄÙñ@ÄÁãÁ@@@@@@@@@@@@@@@ðøð@ðñððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ðñððñ@ÄÄÙñ@ÄÁãÁðù@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñð@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁññ@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñò@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñó@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñô@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñõ@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñö@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñ÷@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñø@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñù@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁòð@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁòñ@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁòò@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁòó@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁòô@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁòõ@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁòö@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ åååå î\íìëêéèçæåäãâáàßÞÝÜÛÚÙØ×ÖÕÔÓÒÑÐÏÎÍÌËÊÉÈÇÆÅÄÃÂÁÀ¿¾½¼»º¹¸·¶µ´³²±°¯®­¬«ª©¨§¦¥¤£¢¡ Ÿž�œ›š™˜—–•”“DCBA@?Œ‹+  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXY¶‘tŽQ`2Q`2¤‘G+wQ\2Q\2¶�˜klmnQV2QV2¤� defghijQR2QR2Z[\]^_`abcdel*CQ¹1ÿÿ¶�abcQP2QP2¤�Ø\]^_`QM2QM2¶�0 UVWXYZ[QJ2QJ2¤�MNOPQRSTQF2QF2ÿÁÀ áQc2Qc2¶�à HIJKLQC2QC2¤�' BCDEFGQ?2Q?2¶�€ ;<=>?@AQ;2Q;2¤�H3456789:Q82Q82¶�ô+,-./012Q42Q42¶‘°%Q12Q12¤‘[Q-2Q-2¶�ü Q)2Q)2¤�Î     Q%2Q%2¶�ðQ#2Q#2¤‘ÃÿQ 2Q 2¶�óôõöQ2Q2¤� íîïðñòQ2Q2¶�ìQ2Q2í�BëQ2Qd2¶�?êQ2Q2¶�?éQ2Q2¶�úèQ2Q2¶�à âãäåæçQ2Q2¤�� ÚÛÜÝÞßàQ 2Q 2 ¤‘ÒQ 2Q 2¶�8ÇÈÉQ2Q2¤�BÄÅÆQ2Q2ÿ�ÃQ2Q2¤�ºÁÂQ2Q2¶‘„¹Q2Q2¶�è­®¯°Qý1Qý1¤�C ¦§¨©ª«¬Qû1Qû1¶�¤¥Qù1Qù1¤�H¢£Q÷1Q÷1¤‘çšQõ1Qõ1¶�È �Ž��‘Qò1Qò1¶�0‹ŒQð1Qð1¤�q‡ˆ‰ŠQï1Qï1¶�¬…†Qí1Qí1¤��‚ƒ„Qì1Qì1¤�¦ {|}~€Qê1Qê1¶�Ô uvwxyzQé1Qé1¤�ðmnopqrstQç1Qç1¶�ähijklQå1Qå1¤�À`abcdefgQã1Qã1¤‘s'SQà1Qà1¤�IJQÝ1QÝ1¶�ÈEFGHQÛ1QÛ1¤�Ü ?@ABCDlClC¶‘Ü=QØ1QØ1¤‘!+QÕ1QÕ1¶�€ !"QÑ1QÑ1¤‘QÏ1QÏ1 sually because of an IO error. */ iinit() { register *cp, *bp; bp = bread(rootdev, 1); cp = getblk(NODEV); if(u.u_error) >s_nfree; bcopy(fp->s_free, ip, 100); fp->s_nfree = 0; bwrite(bp); fp->s_flock = 0; wakeup(&fp->s_flock); } fp->s_fr panic(); bcopy(bp->b_addr, cp->b_addr, 256); brelse(bp); mount[0].m_bufp = cp; mount[0].m_dev = rootdev; cp = cp->b_addr; ee[fp->s_nfree++] = bno; fp->s_fmod = 1; } /* * Check that a block number is in the * range between the I list and the size  cp->s_flock = 0; cp->s_ilock = 0; cp->s_ronly = 0; time[0] = cp->s_time[0]; time[1] = cp->s_time[1]; } /* * alloc will ob * of the device. * This is used mainly to check that a * garbage file system has not been mounted. * * bad block on dev x/ytain the next available * free disk block from the free list of * the specified device. * The super block has up to 100 remem -- not in range */ badblock(afp, abn, dev) { register struct filsys *fp; register char *bn; fp = afp; bn = abn; if (bn <bered * free blocks; the last of these is read to * obtain 100 more . . . * * no space on dev x/y -- when * the free list i fp->s_isize+2 || bn >= fp->s_fsize) { panic(); return(1); } return(0); } /* * Allocate an unused I node * on the specis exhausted. */ alloc(dev) { int bno; register *bp, *ip, *fp; fp = getfs(dev); while(fp->s_flock) sleep(&fp->s_flock, PIfied device. * Used with file creation. * The algorithm keeps up to * 100 spare I nodes in the * super block. When this runs...ealloc.cdalloc.ocbio.cbbio.oaclock.c`clock.oNOD); do { if(fp->s_nfree <= 0) goto nospace; bno = fp->s_free[--fp->s_nfree]; if(bno == 0) goto nospace; } while _conf.c^emul.s]fio.c\fio.o[iget.cZiget.oYlow.sXmain.c(badblock(fp, bno, dev)); if(fp->s_nfree <= 0) { fp->s_flock++; bp = bread(dev, bno); ip = bp->b_addr; fp->s_nfree = *iWmain.oVmalloc.cUmalloc.oTmch.oSmch.sRmem.cQmem.oPnami.cp++; bcopy(ip, fp->s_free, 100); brelse(bp); fp->s_flock = 0; wakeup(&fp->s_flock); } bp = getblk(dev, bno); clrbuf(bOnami.oNobiocMpartab.cLpartab.oKprfcJprfoIqxeml.sHrdwri.cp); fp->s_fmod = 1; return(bp); nospace: fp->s_nfree = 0; u.u_error = ENOSPC; return(NULL); } /* * place the specified d# #include "../param.h" #include "../systm.h" #include "../filsys.h" #include "../conf.h" #include "../buf.h" #include "../inodeisk block * back on the free list of the * specified device. */ free(dev, bno) { register *fp, *bp, *ip; fp = getfs(dev); .h" #include "../user.h" /* * iinit is called once (from main) * very early in initialization. * It reads the root's super b while(fp->s_flock) sleep(&fp->s_flock, PINOD); if (badblock(fp, bno, dev)) return; if(fp->s_nfree <= 0) { fp->s_nfree =lock * and initializes the current date * from the last modified date. * * panic: iinit -- cannot read the super * block. U 1; fp->s_free[0] = 0; } if(fp->s_nfree >= 100) { fp->s_flock++; bp = getblk(dev, bno); ip = bp->b_addr; *ip++ = fp- k some more. */ iput(ip); goto loop; } fp->s_ilock++; ino = 0; for(i=0; is_isize; i++) { bp = bread(dev, i+2);unt * check failed. At this point, all * the counts are zeroed which will * almost certainly lead to "no space" * diagnostic ip = bp->b_addr; for(j=0; j<256; j=+16) { ino++; if(ip[j] != 0) continue; for(k=0; ks_inode[fp->s_ninode++] = ino; if(fp->s_ninode >= 100) brer *n1, *n2; for(p = &mount[0]; p < &mount[NMOUNT]; p++) if(p->m_bufp != NULL && p->m_dev == dev) { p = p->m_bufp->b_addr; ak; cont:; } brelse(bp); if(fp->s_ninode >= 100) break; } fp->s_ilock = 0; wakeup(&fp->s_ilock); if (fp->s_ninode n1 = p->s_nfree; n2 = p->s_ninode; if(n1 > 100 || n2 > 100) { p->s_nfree = 0; p->s_ninode = 0; } return(p); } p > 0) goto loop; u.u_error = ENOSPC; return(NULL); } /* * Free the specified I node * on the specified device. * The alganic(); } /* * update is the internal name of * 'sync'. It goes through the disk * queues to initiate sandbagged IO; * goesorithm stores up * to 100 I nodes in the super * block and throws away any more. */ ifree(dev, ino) { register *fp; fp = g through the I nodes to write * modified nodes; and it goes through * the mount table to initiate modified * super blocks. */ update() { register struct inode *ip; register struct mount *mp; register *bp; if(updlock) return; updlock++; for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) if(mp->m_bufp != NULL) { ip = mp->m_bufp->b_addr; if(ip->s_fmod==0 || ip->s_ilock!=0 || ip->s_flock!=0 || ip->s_ronly!=0) continue; bp = getblk(mp->m_dev, 1); ip->s_fmod = 0; ip->s_time[0]  out, * a linear search through the * I list is instituted to pick * up 100 more. */ ialloc(dev) { register *fp, *bp, *ip;  int i, j, k, ino; fp = getfs(dev); while(fp->s_ilock) sleep(&fp->s_ilock, PINOD); loop: if(fp->s_ninode > 0) { ino = fpetfs(dev); if(fp->s_ilock) return; if(fp->s_ninode >= 100) return; fp->s_inode[fp->s_ninode++] = ino; fp->s_fmod = 1; } ->s_inode[--fp->s_ninode]; ip = iget(dev, ino); if (ip==NULL) return(NULL); if(ip->i_mode == 0) { for(bp = &ip->i_mo /* * getfs maps a device number into * a pointer to the incore super * block. * The algorithm is a linear * search throughde; bp < &ip->i_addr[8];) *bp++ = 0; fp->s_fmod = 1; return(ip); } /* * Inode was allocated after all. * Loo the mount table. * A consistency check of the * in core free-block and i-node * counts. * * bad count on dev x/y -- the co ]; ip++) if((ip->i_flag&ILOCK) == 0) { ip->i_flag =| ILOCK; iupdat(ip); prele(ip); } updlock = 0; bflush(NODEV); II)¹ØÈ} (Ø8)i¹ØØ(”Hw üÿÎæôÿß Ö Îÿÿß ÷‹÷ ØÿÎ&æß –%Îß 7¾ÿ÷¸ÿ¶ÿ4Š˜4Š™4Š›7œ ÿ7žœÿw–ÿw ’ÿæ )¹ù)¹ØNß œÎ¦ÿ¦Îe˜ß Ö ò‹˜õò Iò €À €`5øÿ?Nføÿ¦ß ì–%À éò !²Š˜Nøÿfß Ö òÎd¦Îeæß ˜)È–%ß 2Š˜ŽÎe˜ß Nøÿfß Ö ß ò•šwÖþ2 ÷•ÿ ÷w ÄþNß œÎ¦ÿ&Îe˜ß Ö ô‹˜õNf&ß ì–%À XX(;ô ô4 ô%d#´Š˜Nfß Ö ÂÎd¦&Îeß –%4 Îß 4Š˜Îe˜ß À ´ apô•šwþw þi¹)¹xDCÀeÀ ‡-‚÷ ôýÀwìý üw äýÆåNß œÎ¦ÿ&Îe™ß Ö ô‹™õ*ô ÎÎÀ a5ÐòÿNòÿfß Ö  ƒÃexù)¹ÙÙxØII €ÀeÀ ú‡ô•š€wtýò íŽß ô ÎÓ´Š™5 òÿ5 øÿKNøÿÎefß Ö Â5 öÿµ òÿ@öÿÀ €`È %5 ôÿAôÿWpq-AôÿxX8HXÙX)_canonb _swapmap _rootdir _lbolt _time _tout Wpq-òÿµ ôÿõ%2ôÿêÎÀ ´ ÎapòÿÐô%dÎõeöÿõ%öÿÌÎß ô%dε øÿ5#øÿ²4Š™Îe™ß ô Ξ÷•Õü‚w ˜üNß œ_callout _mount _mpid _runrun _curpri _rootdev _swapdev _updlock _regloc _bdevsw _nblkdevô‹™ô%dÎ ÎÀ ´ ÎapÐô•šwdüw `üÄô L-ÎÃ%d‡Â%d†4 4 ÎÄeÄ%á‚÷ üwüw ü÷  _cdevsw _nchrdev _buf X_bfreeli _inode Ü_u &_iinit"~iinitcpbpcsvüN· üÃó *Àô‹š#ô‹™ ô‹˜ô‹›Îæß Ö 4ŠšôÈûœôÄûžÎ¦&ß –%Žß ÃeÃ%΂Ä̵ÌÕ _bread _getblk L2(_panic _bcopy _brelse cret _alloc"j~allocjbp= time[0]; ip->s_time[1] = time[1]; bcopy(ip, bp->b_addr, 256); bwrite(bp); } for(ip = &inode[0]; ip < &inode[NINODEß ß ÄeÄ%Üð‚7 xûÎÿÿß wlû¹¹ÈØiùy¹y /proc.h" /* * This is the set of buffers proper, whose heads * were declared in buf.h. There can exist buffer * headers notlag&B_DELWRI)==0) geterror(rbp); } /* * Release the buffer, marking it so that if it is grabbed * for another purpose it wi pointing here that are used purely * as arguments to the I/O routines to describe * I/O to be done-- e.g. swbuf, just below, ll be written out before being * given up (e.g. when writing a partial block where it is * assumed that another write for the fpipdevbnoøÿ_getfs"œL4ŒL20001|_sleep L8’L9*_badblocfor * swapping. */ char buffers[NBUF][512]; struct buf swbuf; /* * The following several routines allocate and free * buffe"ìL10_wakeup _clrbuf L3&_free"8~free8bpfpipdevbnors with various side effects. In general the * arguments to an allocate routine are a device and * a block number, and the vaL12XL20003HL11èL14‚L15Ð_bwrite ~badblocìbnfpabnlue is a pointer to * to the buffer header; the buffer is marked "busy" * so that no on else can touch it. If the block was afpdevL10000L17L16_ialloc"~iallocbpfpipi* already in core, no I/O need be done; if it is * already busy, the process waits until it becomes free. * The following routøÿjöÿkôÿdevinoòÿL19<L20005,L21˜L20011D_iget L23ŒL200ines allocate a buffer: * getblk * bread * Eventually the buffer must be released, possibly with the * side effect of writin18hL18ˆL20009lL25vL20007t_iput L27BL20017¬L20015ÈL32"L20013Üg it out, by using one of * bwrite * bdwrite * bawrite * brelse */ /* * Read in (if necessary) the block and return a bufL35üL310L28H_ifree"d~ifreedfpdevinoL37˜~getfsœpfer pointer. */ bread(dev, blkno) { register struct buf *rbp; rbp = getblk(dev, blkno); if (rbp->b_flags&B_DONE) return(rdevn1n2L20020¤L41ØL10002ÌL43ÔL38æ_update"ê~updateêbpbp); rbp->b_flags =| B_READ; rbp->b_wcount = -256; (*bdevsw[dev.d_major].d_strategy)(rbp); iowait(rbp); return(rbp); } /* ipmpL44�L20022üL47VL20024dL51z_iupdat _prele _bflush  * Write the buffer, waiting for completion. * Then release the buffer. */ bwrite(bp) struct buf *bp; { register struct buf *rbp; register flag; rbp = bp; flag = rbp->b_flags; rbp->b_flags =& ~(B_READ | B_DONE | B_ERROR | B_DELWRI); rbp->b_wcount # /* */ #include "../param.h" #include "../user.h" #include "../buf.h" #include "../conf.h" #include "../systm.h" #include "..= -256; (*bdevsw[rbp->b_dev.d_major].d_strategy)(rbp); if ((flag&B_ASYNC) == 0) { iowait(rbp); brelse(rbp); } else if ((f /* * Assign a buffer for the given block. If the appropriate * block is already associated, return it; otherwise search * foB_BUSY | B_RELOC; bp->b_back->b_forw = bp->b_forw; bp->b_forw->b_back = bp->b_back; bp->b_forw = dp->b_forw; bp->b_back = dpr the oldest non-busy buffer and reassign it. * When a 512-byte area is wanted for some random reason * (e.g. during exec, for; dp->b_forw->b_back = bp; dp->b_forw = bp; bp->b_dev = dev; bp->b_blkno = blkno; return(bp); } /* * Wait for I/O complet the user arglist) getblk can be called * with device NODEV to avoid unwanted associativity. */ getblk(dev, blkno) { registerion on the buffer; return errors * to the user. */ iowait(bp) struct buf *bp; { register struct buf *rbp; rbp = bp; spl6() struct buf *bp; register struct devtab *dp; if(dev.d_major >= nblkdev) panic(); loop: if (dev < 0) dp = &bfreelist; while ((rbp->b_flags&B_DONE)==0) sleep(rbp, PRIBIO); spl0(); geterror(rbp); } /* * Unlink a buffer from the available l; else { dp = bdevsw[dev.d_major].d_tab; if(dp == NULL) panic(); for (bp=dp->b_forw; bp != dp; bp = bp->b_forw) { iist and mark it busy. * (internal interface) */ notavail(bp) struct buf *bp; { register struct buf *rbp; register int sps; same block will soon follow). */ bdwrite(bp) struct buf *bp; { register struct buf *rbp; rbp = bp; rbp->b_flags =| B_DELWRIf (bp->b_blkno!=blkno || bp->b_dev!=dev) continue; spl6(); if (bp->b_flags&B_BUSY) { bp->b_flags =| B_WANTED;  | B_DONE; brelse(rbp); } /* * Release the buffer, start I/O on it, but don't wait for completion. */ bawrite(bp) struct bufsleep(bp, PRIBIO); spl0(); goto loop; } spl0(); notavail(bp); return(bp); } } spl6(); if (bfreelist.av_ *bp; { register struct buf *rbp; rbp = bp; rbp->b_flags =| B_ASYNC; bwrite(rbp); } /* * release the buffer, with no I/O forw == &bfreelist) { bfreelist.b_flags =| B_WANTED; sleep(&bfreelist, PRIBIO); spl0(); goto loop; } spl0(); notavailimplied. */ brelse(bp) struct buf *bp; { register struct buf *rbp, **backp; register int sps; rbp = bp; if (rbp->b_flags&B#$%&'()*,-./01234_WANTED) wakeup(rbp); if (bfreelist.b_flags&B_WANTED) { bfreelist.b_flags =& ~B_WANTED; wakeup(&bfreelist); } if (rbp->b_flags&B_ERROR) rbp->b_dev.d_minor = -1; /* no assoc. on error */ backp = &bfreelist.av_back; #ifdef QX sps = getps(); #endif #ifndef QX sps = PS->integ; #endif spl6(); rbp->b_flags =& ~(B_WANTED|B_BUSY|B_ASYNC); (*backp)->av_forw = rbp; rbp->av_back = *backp; *backp = rbp; rbp->av_forw = &bfreelist; #ifdef QX putps(sps); #endif #ifndef QX PS->integ = sps; #endif } (bp = bfreelist.av_forw); if (bp->b_flags & B_DELWRI) { bp->b_flags =| B_ASYNC; bwrite(bp); goto loop; } bp->b_flags =   register *p; register c; p = bp->b_addr; c = 256; do *p++ = 0; while (--c); } /* * Initialize the buffer I/O system br; #endif #ifndef VSWAP swbuf.b_blkno = SWPLO + rp->p_pid*SWPSIZ; #endif swbuf.b_addr = &u; /* 64 b/block */ (*bdevsw[swapdevy freeing * all buffers and setting all device buffer lists to empty. */ binit() { register struct buf *bp; register struct >>8].d_strategy)(&swbuf); spl6(); while((swbuf.b_flags&B_DONE)==0) idle(); spl0(); if(rdflg == B_READ) { p1 = TOPUSR; devtab *dp; register int i; struct bdevsw *bdp; bfreelist.b_forw = bfreelist.b_back = bfreelist.av_forw = bfreelist.av_p2 = (pp->p_size<<6) + TOPSYS - (USIZE<<6); if(p2 <= p1) while(p1 >= USTACK->integ.intp) *--p1 = *--p2; #ifdef VSWAP back = &bfreelist; for (i=0; ib_dev = -1; bp->b_addr = buffers[i]; bp->b_back = &bfreelmfree(swapmap,(pp->p_size + 7)/8,pp->p_addr); #endif } swbuf.b_flags =& ~(B_BUSY|B_WANTED); return(swbuf.b_flags&B_ERROR); } ist; bp->b_forw = bfreelist.b_forw; bfreelist.b_forw->b_back = bp; bfreelist.b_forw = bp; bp->b_flags = B_BUSY; brelse /* * make sure all write-behind blocks * on dev (or NODEV for all) * are flushed out. * (from umount and update) */ bflush(bp); } i = 0; for (bdp = bdevsw; bdp->d_open; bdp++) { dp = bdp->d_tab; if(dp) { dp->b_forw = dp; dp->b_back = dp;(dev) { register struct buf *bp; loop: spl6(); for (bp = bfreelist.av_forw; bp != &bfreelist; bp = bp->av_forw) { if (bp-> } i++; } nblkdev = i; } /* * swap I/O */ #define USTACK (TOPSYS-12) struct { int *intp;}; struct {char *chrp;}; swapb_flags&B_DELWRI && (dev == NODEV||dev==bp->b_dev)) { bp->b_flags =| B_ASYNC; notavail(bp); bwrite(bp); goto loop; (rp, rdflg) struct proc *rp; { register *pp, *p1, *p2; pp = rp; if(rdflg == B_WRITE) { p1 = USTACK->integ; p2 = TOPSYS + } } spl0(); } /* * Pick up the device's error number and pass it to the user; * if there is an error but the number is 0 s rbp = bp; #ifdef QX sps = getps(); #endif #ifndef QX sps = PS->integ; #endif spl6(); rbp->av_back->av_forw = rbp->av_forw;  (u.u_dsize<<6) + (p1.integ&077); if(p2 <= p1) { pp->p_size = u.u_dsize + USIZE + ((TOPUSR>>6)&01777) - ((p1.integ>> rbp->av_forw->av_back = rbp->av_back; rbp->b_flags =| B_BUSY; #ifdef QX putps(sps); #endif #ifndef QX PS->integ = sps; #endi6)&01777); while(p1.chrp < TOPUSR) *p2++ = *p1++; } else pp->p_size = SWPSIZ<<3; #ifdef VSWAP pp->p_addr = mallocf } /* * Mark I/O complete on a buffer, release it if I/O is asynchronous, * and wake up anyone waiting for it. */ iodone(bp(swapmap,(pp->p_size+7)/8); if(pp->p_addr == NULL) panic(); #endif } #ifdef DEBUG printf("Swap (%d) id %d size %d addr ) struct buf *bp; { register struct buf *rbp; rbp = bp; rbp->b_flags =| B_DONE; if (rbp->b_flags&B_ASYNC) brelse(rbp); e%d\n", rdflg, pp->p_pid, (((pp->p_size+7)& ~07)<<5) >> 7, pp->p_addr); #endif spl6(); swbuf.b_flags = B_BUSY | rdflg; swbuflse { rbp->b_flags =& ~B_WANTED; wakeup(rbp); } } /* * Zero the core associated with a buffer. */ clrbuf(bp) int *bp; { .b_dev = swapdev; swbuf.b_wcount = -(((pp->p_size+7)&~07)<<5); /* 32 words per block */ #ifdef VSWAP swbuf.b_blkno = pp->p_add  .u_error = EIO; } )é)é¸))(¸(éù()éIy(ù())(ÈÙ8yùâw üÿNfß Ö Ì5wàÿÌUôÿ &@�tø Ö ß ìw ºÿDÌEôÿ &� tø Ö Ã5ß Ù)Ù)ß ¶Ã5ß Âwvÿw rÿDÌUß ¶w`ÿw \ÿDÌUß BwJÿw FÿDÌ5@ß ÷5@0ÿ÷E@(ÿÎß Ì5ô•ÿÿ ÃéùÈÙ)ééù)é÷ ÿ÷ ÿÌEHÀ0ô ôŽß wæþw âþ@�À-Úþ÷ ÔþÃ÷ Êþ÷%Êþ:÷U@¼þÎÎÿæß Ö ÷ ªþõ é@�t÷ ’þĸ)é)é())))x()))Ä Þt-t- ÷ vþÌ5ÌU@ÎÎÿ&Ø÷ `þß <wTþà÷ JþÄLþß <Ì5ÌUß BÂ̈00ô8I)é ôÀ03t tÌw îýD÷ æýÎÎÿ&ß Ö Ì5÷÷ Îýß ÂwÄýw ÀýD÷ ¸ý÷ ²ý00ÌUÎß w�ýˆøyù‰9‰‰‰‰ˆ98w ŒýDÌUÌ5ß ¶ÌE@ß whýw dý@à Â~wPýw Lýæ À7Jý7Dý7>ý78ý �WpDÄeôÿÿ €t Àe4ôù)‰Ùˆx‰‰)éô ýÀý07þüÌß ¶‚ Â%Û õøÿ @øÿóó‚ õeøÿý øÿð·¼üw¸üw ´üDõ 6Ãô_ÀvýtÁÁEÀÿ@`Âe`ù)(Ù)é )_u &_buf X_bfreeli _bdevsw ‡À\ýÀe�ÁWtúÿÁEü@à4Ã%àƒÒûôÀetýÿæß Ö 4ô ÷ >ü÷ :ü@ÀU7.ü÷*ü2üÀeÀEt 7ü7 _nblkdev _cdevsw _nchrdev _canonb _swapmap _rootdir _lbolt _time _tout _callout _mouü÷üæÀþûtøÿtø Ö ÷ ìû÷ æû÷5àûú÷ Úûõ%Ãà—tÂe\ †£ß ô_ü†Àetýÿ&æß –%÷EH’ûÀnt _mpid _runrun _curpri _rootdev _swapdev _updlock _regloc _proc „_buffers _swbuf et a generalized * code. Actually the latter is always true because devices * don't yet return specific errors. */ geterror(ŽûÀEûÿw†ûw ‚ûõ%ÿÿ5- ÌUß <ß B÷ \ûÄ^ûÌ5èÄ%ø÷ Bûw>ûw :ûDÌ57�aû÷•Yûwûéabp) struct buf *abp; { register struct buf *bp; bp = abp; if (bp->b_flags&B_ERROR) if ((u.u_error = bp->b_error)==0) u)8é8)é   if((ps&0340) != 0) goto out; /* * callout */ spl5(); if(callout[0].c_time <= 0) { p1 = &callout[0]; while(p1->c__bread"~breaddevblknorbpcsv _getblk"L2 L20000cret _iowait"_bwrite"B~bwriteBbpflagrbpL4z_brelse"¶L3†_geterro"Â_bdwrite"Š~bdwhL55FL54LL20016D_mfree _bflush"z~bflushzbpdevL58 L20018€L100riteŠbprbp_bawrite" ~bawrite bprbp~brelse¶bpbackprbp00�L61°L59´L20020ª~geterroÂbpabpL63ÞspsL10Ê_wakeup L11àL12ì_getps _spl6 _putps ~getblkbpdpdevblknoL15V_panic L20002.L172L23²L20005L_sleep _spl0 L18nL19rL21¬L22œ_notavai"<L20006¦L24Ò~iowaitbprbpL26(# #include "../param.h" #include "../systm.h" #include "../user.h" #include "../proc.h" /* * clock is called straight from * L20008~notavai<bprbpsps_iodone"p~iodonepbprbpL30ŠL29the real time clock interrupt. * * Functions: * reprime clock * implement callouts * maintain user/system times * maintain”_clrbuf"˜~clrbuf˜bpcpL35¨_binit"°~binit°bpdpi date * profile * tout wakeup (sys sleep) * lightning bolt wakeup (every 4 sec) * alarm clock signals * jab the scheduler bdpøÿL20010ÌL40:L20012 L432_swap"H~swapHrppprdflg*/ clock(dev, sp, r1, nps, r0, pc, ps) char *pc; { register struct callo *p1, *p2; register struct proc *pp; int a; #ifdefp1p2L45ÂL46–L47ŒL49œ_malloc L51L20014_idle L53 QX #ifndef SA /* * update graphics screen */ lkint(); #endif #endif /* * restart clock */ #ifndef QX *lks = 0115;56789:;<> #endif /* * callouts * if none, just return * else update first non-zero time */ if(callout[0].c_func == 0) goto out; p2 = &callout[0]; while(p2->c_time<=0 && p2->c_func!=0) p2++; p2->c_time--; /* * if ps is high, just return */  has the effect of * updating all entries. */ timeout(fun, arg, tim) { register struct callo *p1, *p2; register t; int s; ¨y_canonb _swapmap _rootdir _lbolt _time t = tim; #ifdef QX s = getps(); #endif #ifndef QX s = PS->integ; #endif p1 = &callout[0]; spl7(); while(p1->c_func != 0 && _tout _callout _mount _mpid _runrun _curpri _rootdev _swapdev _updlock _regloc _up1->c_time <= t) { t =- p1->c_time; p1++; } p1->c_time =- t; p2 = p1; while(p2->c_func != 0) p2++; while(p2 >= p1) {  &_proc „_clock"~clockpcsppsppaøÿdevnps r1 (p2+1)->c_time = p2->c_time; (p2+1)->c_func = p2->c_func; (p2+1)->c_arg = p2->c_arg; p2--; } p1->c_time = t; p1->c_fur0 p1p2csv _lkint L2tL3 L20001L4$_spl5 func != 0 && p1->c_time <= 0) { (*p1->c_func)(p1->c_arg); p1++; } p2 = &callout[0]; while(p2->c_func = p1->c_func) {nc = fun; p1->c_arg = arg; #ifdef QX putps(s); #endif #ifndef QX PS->integ = s; #endif }  p2->c_time = p1->c_time; p2->c_arg = p1->c_arg; p1++; p2++; } } /* * lightning bolt time-out * and time of day */ out: if(pc > TOPSYS) u.u_utime++; else u.u_stime++; pp = u.u_procp; if(++lbolt >= HZ) { if((ps&0340) != 0)  return; if((time[1]&03)==0) wakeup(&lbolt); lbolt =- HZ; if(++time[1] == 0) ++time[0]; spl1(); if(time[1]==toš„w üÿæ ÷ öÿ÷ öÿ2Ãó ÃeË ùË õ5à#÷ Îÿ÷ ÊÿÄ Ì &ü Ö Äeô ôà 3ÄeÃe3ut[1] && time[0]==tout[0]) wakeup(tout); #ifdef QX if((time[1]&07) == 0) { #endif #ifndef QX if((time[1]&01) == 0) { #endôõ%`†· Š· †Â²ÿ· rÿ÷%<lÿHõ5àD÷5^ÿÎß ÷å<Lÿ· Jÿ· Bÿ÷ >ÿ÷-<ÿ:ÿ÷-2ÿ0ÿÎß ÂÊ‹ò  ò ò if runrun++; } for(pp = &proc[0]; pp < &proc[NPROC]; pp++) if (pp->p_stat) { if(pp->p_clktim) if(--pp->p_clktim Î¦ß Ö ÂeÂ%„ë‚õ%` †@Àe 7üÿ÷ âþÀ ÷ ÚþwÖþw Òþæ B÷ Èþ5øÿÄ÷ ¼þŒ ãÄeô øŒàÃeó û óó== 0) psignal(pp, SIGCLK); } if(pc > TOPSYS) { u.u_ar0 = &r0; if(issig()) psig(); } } } /* * timeout is  óÃå!ôƒŒttNøÿß wfþéùihIihcalled to arrange that * fun(arg) is called in tim/HZ seconds. * An entry is sorted into the callout * structure. The time inhùùù99I8è9II YIYIX each structure * entry is the number of HZ's more * than the previous entry. * In this way, decrementing the * first entry èHùYiyéh)  # #include "../param.h" /* */ int (*bdevsw[])() { #ifdef QX &nulldev, &nulldev, &qxstrategy, &qxtab, #endif #ifdef SA &nul11/10 / / / This program is designed to allow the use / of the PDP 11/40 instruction set on the PDP 11/10 / in an environmldev, &nulldev, &sastrategy, &satab, #endif #ifndef QX &nulldev, &nulldev, &rkstrategy, &rktab, /* &nulldev, &tcclose, &tcstraent which handles traps in the / same manner as the UNIX operating system. / This program returns the same results / and tegy, &tctab, */ /* &tmopen, &tmclose, &tmstrategy, &tmtab, */ #endif 0, }; int (*cdevsw[])() { &klopen, &klclose, &klread,condition codes that the internal DEC / instruction does on the PDP 11/40. This allows / programs which run under UNIX on a &klwrite, &klsgtty, &nulldev, &nulldev, &mmread, &mmwrite, &nodev, /* &lpopen, &lpclose, &nodev, &lpwrite, &nodev, */ 0, };n 11/40 to / be run on an 11/10 with a UNIX-like system. / The functions implimented are listed below: / multiply (MUL) / d ivide (DIV) / arithmetic shift (ASH) / arithmetic shift combined (ASHC) / exclusive OR (XOR) / subtract one and branch (SOB) / / / / / Upon entry to this program the stack is assumed / to look as follows: / / < bottom portion of stack > / UPS -- user's program status word at time of trap / UPC -- user's program counter at time of trap / UR0 -- user's r0 at time of trap / ---L6PL20003>L7VL8lL20005\L10‚L11†L1&L13®_wakeup L14¾_spl1 L15ÚL20007ÞL18þ_psignal _issig _psig cret _timeout"*~timeout*arg.globl nofault,emtrap,trapem rti = 2 PS = 177776 / / trapem: mov *$PS,-4(sp) / trap type mov r0,-(sp) tst -(sp) mov r1,-(ssøÿtfuntimp1p2_getps _spl7 L25PL20009Fp) mov $12.,-(sp) add sp,*sp mov 4(sp),-(sp) bic $!17,*sp jsr pc,trapems tst (sp)+ mov (sp)+,r0 / return stack pointer mL26VL27`L20011\L29|L20013h_putps ov (sp)+,r1 tst (sp)+ add $6,sp cmp sp,r0 blos 0f sub $6,sp sub $6,r0 mov (sp)+,(r0)+ mov (sp)+,(r0)+ mov -12.(sp),(r0) / copy in PS word mov r0,sp sub $4,sp br 1f 0: mov -14.(sp),-2(sp) / copy in PS word mov -(sp),-(r0) mov -(sp),-(r0) mov -(sp),-(r0) mov r0,sp 1: mov (sp)+,r0 rti / return from emulation / / / / / EXTENDED INSTRUCTION SET EMULATOR FOR PDP  / This causes the stack to look as follows: / / < bottom portion of stack > / UPS / UPC / UR0 / --- / UR1 / USP / DEV / RPC /  to be performed mov (sp),r4 bic $170777,r4 swab r4 jmp *fcntbl(r4) fcntbl: smul / multiply sdiv / divide sash / arithmetUR5 : user's r5 <--- register 5 points here / UR4 : user's r4 / UR3 : user's r3 / UR2 : user's r2 / nfaddr : used to hold olic shift sashc / arithmetic shift combined sxor / exclusive OR errrtn / unimplimented errrtn / unimplimented ssob / subtracd nofault address / PCFLG : used to hold value to increment UPC by / DSTN : used to hold address of destination field / MODMAP t one and branch / / / / this routine performs the multiply function / smul: jsr pc,getsrc / set up flags for proper sign manag: used to hold interim condition codes / INST: used to hold instruction being emulated <--- stack pointer / < top of stack > / /ement mov r0,r1 bge 1f neg r1 inc r3 1: clr r0 tst r2 bge 1f neg r2 dec r3 1: / set counter for 17 cycles mov $21,-(sp / / / UPC =16 UPS =20 MODMAP =2 INST =0 DSTN =4 PCFLG =6 nfaddr =10 / / / .text / / .globl csv, cret / / / emul2.o = . / trapKLMNOPQRTUVWXYZ[\]^_ems: jsr r5,csv sub $12,sp / set up to catch traps which occur during emululation mov nofault,nfaddr(sp) mov $errrtn,nofault / find instruction which caused trap mov UPC(r5),r0 mov UPS(r5),UPS-12.(r5) / put PS in safe place mov -(r0),(sp) / is it one to be emululated? cmp (sp),$070000 / 170000 for 40 testing / 070000 for 10 use bgt 1f / bhis for 40 testing / bgt for 10 use mov (sp),r0 bic $77,r0 cmp r0,$6700 beq ssxt jmp errrtn ssxt: jsr pc,getsrc bis $4,(r4) /set z-bit clr *DSTN(s) 2: / use shift and add algorithm clc ror r0 ror r1 bcc 1f add r2,r0 1: dec (sp) bne 2b / were signs the same? cmp r3,(p) bit $10,UPS-12.(r5) / n-bit on? beq 0f dec *DSTN(sp) bic $4,(r4) /clear z-bit 0: mov $4,r2 jmp setcc 1: / / / / / thissp)+ beq 1f / no, negate the product neg r0 neg r1 sbc r0 1: / was product greater than 15 bits long? tst r1 bpl 1f cmp $ -- not used by this program / UR1 -- user's r1 / USP -- user's stack pointer / DEV -- trap type / RPC -- return address to routine gets the even-odd register pair / specified in the instruction and moves / them into r0 and r1 / / find register nu trap routine / < top of stack > / / / / / After it is determined that the trap is an illegal / instruction trap ( DEV = 1 )mber = n mov (sp),r4 bic $177077,r4 asl r4 asl r4 swab r4 / move register(n) into r0 movb regs(r4),r3 add r5,r3 mov (r3), a register save routine / is used which saves the other user registers and / allocates temporary space for variables. / ,r0 / move register(n ORed with 1) into r1 bis $1,r4 movb regs(r4),r3 add r5,r3 mov (r3),r1 / / / find out which function is -1,r0 bne 2f br 3f 1: tst r0 beq 3f 2: / if so, set the C bit bis $1,*r4 3: / was the register odd? bit $100,(sp) beq 1f beq div37 neg r0 jmp div26 div29: neg r0 div37: mov r1,r3 neg r1 com r3 jmi div26 clr *r4 tst r1 beq 2f bpl 1f bis $/ if so, move product to r0 mov r1,r0 1: / set up flags and quit mov $1,r3 mov $17,r2 jmp strreg / / / / / this routine perf10,*r4 br div42 2: bis $4,*r4 1: bis $2,*r4 div42: / exit procedure mov (sp)+,r5 mov r0,r3 mov r1,r0 mov r3,r1 mov $1,r3orms the division function / the algorithm used is taken directly / from the DEC microcode flow in order / to make all con mov $-17,r2 jmp strreg / / / / / this routine performs the arithmetic shift function / sash: jsr pc,getsrc br 1f / / / / / dition codes and results / agree in all cases. / sdiv: / if an odd register instruction, error bit (sp),$100 beq 1f jmp errthis routine performs the arithmetic shift combined function / sashc: jsr pc,getsrc inc r3 1: / get shift distance bic $17770rtn 1: jsr pc,getsrc mov r5,-(sp) mov r1,r5 / is divisor 0? tst r2 bne div5 / if so, quit bis $7,*r4 br div12 div5: / is 0,r2 bit $40,r2 beq 1f bis $177700,r2 2: / right shift tst r3 beq 3f / for ashc asr r0 ror r1 br 4f 3: / for ash asr r0dividend negative? tst r0 bge div16 / yes bis $17,*r4 neg r0 clr r1 sub r5,r1 sbc r0 bpl div16 div12: / error exit bis  4: bic $1,*r4 bcc 5f bis $1,*r4 5: inc r2 bne 2b br 9f 1: / left shift tst r2 beq 9f 1: tst r3 beq 3f / for ashc asl$2,*r4 mov (sp)+,r5 mov $17,r2 jmp setcc div16: / first step of algorithm mov r2,r3 neg r3 clc rol r1 rol r0 tst r2 bm r1 rol r0 br 4f 3: / for ash asl r0 4: bvc 2f bis $2,*r4 2: bic $1,*r4 bcc 5f bis $1,*r4 5: dec r2 bgt 1b 9: tst r3 i 1f add r3,r0 br 2f 1: add r2,r0 2: adc r1 bic $1,*r4 / test for overflow condition bit $1,r1 beq 1f tst r0 jne div12  bne 7f / for ash mov r0,r1 br 8f 7: bit $100,(sp) beq 8f / for ashc mov r1,r0 8: / exit mov $17,r2 jmp strreg / / / / /  clr r5 tst r2 bge 3f inc r5 3: bit $10,*r4 beq 3f inc r5 3: ror r5 jcc div12 1: / if no overflow, interate algorithm 15this routine performs the exclusive OR function / using A xor B = A and NOT B or B and NOT A / sxor: jsr pc,getsrc mov r0,r1 times mov $17,-(sp) div19: clc rol r1 rol r0 clr r5 tst r2 bpl 1f inc r5 1: bit $2,r1 beq 1f inc r5 1: ror r5 bcc  bic r2,r0 / A AND NOT B bic r1,r2 / B AND NOT A bis r0,r2 / A XOR B mov r2,*DSTN(sp) bvc 1f bis $2,*r4 1: mov r2,r0 clr1f add r3,r0 br 2f 1: add r2,r0 2: adc r1 dec (sp) bne div19 / branch to appropriate cleanup and condition code routines  r1 mov $16,r2 jmp setnz / / / / / this routine performs the subtract one and / branch function / ( untested ) / ssob: movcmp r2,(sp)+ bgt 1f bit $1,r1 beq div31 bne div33 1: bit $1,r1 bne div23 div27: add r2,r0 div23: bit $10,*r4 bne div29  (sp),r2 bic $177700,r2 / subtract 1 dec r0 beq 1f / modify PC asl r2 sub r2,UPC(r5) 1: /exit clr r3 clr r2 jmp strreg /div26: clr *r4 tst r1 beq 2f bpl 1f bis $10,*r4 br 1f 2: bis $4,*r4 1: jmp div42 div31: sub r2,r0 div33: bit $10,*r4  / / / / this routine performs the decoding and / fetching of the source operand and / places it in register 2 / getsrc:  n mov (sp),r4 bic $177077,r4 asl r4 asl r4 swab r4 / single (r0) or double (r0-r1) register store tst r3 beq 1f /store r1file[rf]; if(fp != NULL) return(fp); bad: u.u_error = EBADF; return(NULL); } /* * Internal form of close. * Decrement re in r(n ORed with 1) mov r4,r3 bis $1,r3 movb regs(r3),r3 add r5,r3 mov r1,(r3) 1: / store r0 in r(n) movb regs(r4),r3 adference count on * file structure and call closei * on last closef. * Also make sure the pipe protocol * does not constipated r5,r3 mov r0,(r3) / branch to next routine by flag tst r2 bge setnz neg r2 br setcc / / / / / this routine cause a return. */ closef(fp) int *fp; { register *rfp, *ip; rfp = fp; if(rfp->f_count <= 1) closei(rfp->f_inode, rfp->f_flag&FWRITE); mov INST+2(sp),r4 mov r4,r3 bic $177770,r4 / register bic $177707,r3 / mode asr r3 asr r3 clr PCFLG+2(sp) / if PC addressi to the regular / trap handler if an error is found so a normal / illegal instruction trap can be signalled / errrtn: mov nng cmp r4,$7 bne 1f mov $2,PCFLG+2(sp) / then modes 1,4 and 5 are errors cmp r3,$2 jeq errrtn cmp r3,$10 jeq errrtn cmp faddr(sp),nofault sub $6,r5 mov r5,sp mov (sp)+,r2 mov (sp)+,r3 mov (sp)+,r4 mov (sp)+,r5 add $6,sp mov (sp)+,r1 tst (sr3,$12 jeq errrtn 1: asr r3 bic $1,r3 movb regs(r4),r4 add r5,r4 jmp *mods(r3) mods: 0f / modes 0,1 1f / 2,3 2f /p)+ mov (sp)+,r0 jmp emtrap / / / / / this routine sets the condition codes for / the n and z bits / setnz: tst r0 bgt set 4,5 3f / 6,7 0: / contents of register mov r4,r2 br 4f 1: / autoincrementing mov (r4),r2 add $2,(r4) br 4f 2:cc blt 1f tst r1 bne setcc bis $4,MODMAP(sp) br setcc 1: bis $10,MODMAP(sp) / / / / / this routine sets the proper conditi / autodecrementing sub $2,(r4) mov (r4),r2 br 4f 3: / indexed mov (r4),r2 mov UPC(r5),r3 add $2,UPC(r5) add PCFLG+2(sp),on codes / in the user's PS and jumps to cret which / cleans up the stack and causes the / return to the user / setcc: br2 add (r3),r2 4: / address of location in r2 / is mode indirect? bit $10,INST+2(sp) beq 5f / if so, new address to r2 mov (ic r2,UPS-12.(r5) com r2 bic r2,MODMAP(sp) bis MODMAP(sp),UPS-12.(r5) mov nfaddr(sp),nofault jmp cret / / / / r2),r2 5: / effective address to DSTN mov r2,DSTN+2(sp) / contents to r2 mov (r2),r2 clr r3 mov $MODMAP+2,r4 add sp,r4 clr *r4 rts pc / / / / / this table contains the offset in bytes of the / user's registers in the stack based at r5 / .data r# #include "../param.h" #include "../user.h" #include "../filsys.h" #include "../file.h" #include "../conf.h" #include "../inodeegs: .byte 14 / r0 .byte 10 / r1 .byte -6 / r2 .byte -4 / r3 .byte -2 / r4 .byte 0 / r5 .byte 6 / r6 .byte 16 / r7 .t.h" #include "../reg.h" /* * Convert a user supplied * file descriptor into a pointer * to a file structure. * Only task isext / / / / / this routine stores the results of the operation / into the proper registers / strreg: / find register number =  to check range * of the descriptor. */ getf(f) { register *fp, rf; rf = f; if(rf<0 || rf>=NOFILE) goto bad; fp = u.u_o switch(rip->i_mode&IFMT) { case IFCHR: if(maj >= nchrdev) goto bad; (*cdevsw[maj].d_open)(dev, rw); break; case IFBcture. * Initialize the descriptor * to point at the file structure. * * no file -- if there are no available * file strucLK: if(maj >= nblkdev) goto bad; (*bdevsw[maj].d_open)(dev, rw); } return; bad: u.u_error = ENXIO; } /* * Check modtures. */ falloc() { register struct file *fp; register i; if ((i = ufalloc()) < 0) return(NULL); for (fp = &file[0]; fpe permission on inode pointer. * Mode is READ, WRITE or EXEC. * In the case of WRITE, the * read-only status of the file * s < &file[NFILE]; fp++) if (fp->f_count==0) { u.u_ofile[i] = fp; fp->f_count++; fp->f_offset[0] = 0; fp->f_offset[1ystem is checked. * Also in WRITE, prototype text * segments cannot be written. * The mode is shifted to select * the owner/] = 0; return(fp); } u.u_error = ENFILE; return(NULL); } group/other fields. * The super user is granted all * permissions. */ access(aip, mode) int *aip; { register *ip, m; ip = aip; m = mode; if(m == IWRITE) { if(getfs(ip->i_dev)->s_ronly != 0) { u.u_error = EROFS; return(1); } } if(u.u_uid rfp->f_count--; } /* * Decrement reference count on an * inode due to the removal of a * referencing file structure. * On  == 0) return(0); if(u.u_uid != ip->i_uid) { m =>> 6; } if((ip->i_mode&m) != 0) return(0); bad: u.u_error = EACCES; the last closei, switchout * to the close entry point of special * device handler. * Note that the handler gets called * on return(1); } /* * Look up a pathname and test if * the resultant inode is owned by the * current user. * If not, try for suevery open and only on the last * close. */ closei(ip, rw) int *ip; { register *rip; register dev, maj; rip = ip; dev = rper-user. * If permission is granted, * return inode pointer. */ owner() { register struct inode *ip; if ((ip = namei(0)) ip->i_addr[0]; maj = rip->i_addr[0].d_major; if(rip->i_count <= 1) switch(rip->i_mode&IFMT) { case IFCHR: (*cdevsw[maj].d== NULL) return(NULL); if(u.u_uid == ip->i_uid) return(ip); if (suser()) return(ip); iput(ip); return(NULL); } /* * _close)(dev, rw); break; case IFBLK: (*bdevsw[maj].d_close)(dev, rw); } iput(rip); } /* * openi called to allow handleTest if the current user is the * super user. */ suser() { if(u.u_uid == 0) return(1); u.u_error = EPERM; return(0); } r * of special files to initialize and * validate before actual IO. * Called on all sorts of opens * and also on mount. */ /* * Allocate a user file descriptor. */ ufalloc() { register i; for (i=0; ii_addr[0]; maj = rip->i_addr[0].d_major; u.u_ar0[R0] = i; return(i); } u.u_error = EMFILE; return(-1); } /* * Allocate a user file descriptor * and a file stru À 0ª´Š4 4 wøýÄô‹îÄeÄ%�ø‚÷•þã `€œ’ `ÖÉù É"Þ~fallocÞfpiL37L20020êL36L20017îL20019 ùÉHHù(ÉYH(9 ùÉÈ ùÉX HùÉ ù É# #include "../param.h" #include "../systm.h" #include "../user.h" #include "../inode.h" #include "../filsys.h" #include "../con ù Éù f.h" #include "../buf.h" /* * Look up an inode by device,inumber. * If it is in core (in the inode structure), * honor the l_u &_file �_bdevsw _nblkdev _cdevsw _nchrdev _inode Ü_getf"~getffpocking protocol. * If it is not in core, read it in from the * specified device. * If the inode is mounted on, perform * therffcsv L2 L1cret _closef"*~closef*fpiprfp indicated indirection. * In all cases, a pointer to a locked * inode structure is returned. * * panic: no imt -- if the mouL5J_closei"RL10001$L10002(L10€L11œL7’~closeiRiprwmajnted file * system is not in the mount table. * "cannot happen" */ iget(dev, ino) { register struct inode *p; register *ip2devripL10003xL20000�_iput _openi"®L100050L100064L15ÖL17; int *ip1; register struct mount *ip; loop: ip = NULL; for(p = &inode[0]; p < &inode[NINODE]; p++) { if(dev==p->i_dev &&$\w üÿC Ã%ÀÀ ªwàÿ÷•  ùw ÒÿDô£ “ÎEýÿ&ß RÖ ôŠw®ÿw ªÿD�ô£ÀEÿŸL12~openi®iprwmajdevripL10007ÎL16L20001þL20003Á$7° þyfæ�Wp ù –%ß wdÿfæ€tø ñw NÿD�ÀEÿŸÁ07f þyÂ-&ÿfæ�Wp ù fî_access"~accessipmodemaipL19>_getfs L20008\L20007:L200æ€tø –%Â-úþó÷•)ÿwîþw êþDCÃ%€ ß ð‹›÷•ÿþ ÷‹öþû7­ îþ×túÿô0ò÷• ÛþÀwœþw ˜þ ß 05:L18`L22P_owner"d~ownerdip_namei L26xL20013ŽL20010tL25�  7­ ºþú÷ À öß wlþw hþ÷‹œþÀwZþ÷•‹þ ùw Lþ À ð ª?Rÿw6þ„ Ä%ò÷•_þÀÿÿôw þ÷ Êÿ À_suser"”~suser”L30¦L29¢_ufalloc"°~ufalloc°iL20015¶L34ÊL31Æ_falloc i_flag&IMOUNT) != 0) { for(ip = &mount[0]; ip < &mount[NMOUNT]; ip++) if(ip->m_inodp == p) { dev = ip->m_dev;  { *ip1++ = time[0]; *ip1++ = time[1]; } bwrite(bp); } } /* * Free all the disk blocks associated * with the speciino = ROOTINO; goto loop; } panic(); } p->i_count++; p->i_flag =| ILOCK; return(p); } if(ip==NULL &fied inode structure. * The blocks of the file are removed * in reverse order. This FILO * algorithm will tend to maintain *& p->i_count==0) ip = p; } if((p=ip) == NULL) { u.u_error = ENFILE; return(NULL); } p->i_dev = dev; p->i_number = in a contiguous free list much longer * than FIFO. */ itrunc(ip) int *ip; { register *rp, *bp, *cp; int *dp, *ep; rp = ip; o; p->i_flag = ILOCK; p->i_count++; ip = bread(dev, ldiv(ino+31,16)); /* * Check I/O errors */ if (ip->b_flags&B_ERROR)if((rp->i_mode&(IFCHR&IFBLK)) != 0) return; for(ip = &rp->i_addr[7]; ip >= &rp->i_addr[0]; ip--) if(*ip) { if((rp->i_mode& { brelse(ip); iput(p); return(NULL); } ip1 = ip->b_addr + 32*lrem(ino+31, 16); ip2 = &p->i_mode; while(ip2 < &p->i_adILARG) != 0) { bp = bread(rp->i_dev, *ip); for(cp = bp->b_addr+510; cp >= bp->b_addr; cp--) if(*cp) free(rp->i_dev,dr[8]) *ip2++ = *ip1++; brelse(ip); return(p); } /* * Decrement reference count of * an inode structure. * On the last r *cp); brelse(bp); } free(rp->i_dev, *ip); *ip = 0; } rp->i_mode =& ~ILARG; rp->i_size0 = 0; rp->i_size1 = 0; rp->eference, * write the inode out and if necessary, * truncate and deallocate the file. */ iput(p) struct inode *p; { registeri_flag =| IUPD; } /* * Make a new file. */ maknode(mode) { register *ip; ip = ialloc(u.u_pdir->i_dev); if (ip==NULL) re *rp; rp = p; if(rp->i_count == 1) { rp->i_flag =| ILOCK; if(rp->i_nlink <= 0) { itrunc(rp); rp->i_mode = 0; ifrturn(NULL); ip->i_flag =| IUPD; ip->i_mode = mode|IALLOC; ip->i_nlink = 1; ip->i_uid = u.u_uid; wdir(ip); return(ip); } /ee(rp->i_dev, rp->i_number); } iupdat(rp); prele(rp); rp->i_flag = 0; rp->i_number = 0; } rp->i_count--; prele(rp);* * Write a directory entry with * parameters left as side effects * to a call to namei. */ wdir(ip) int *ip; { register ch } /* * Check accessed and update flags on * an inode structure. * If either is on, update the inode * with the correspondiar *cp1, *cp2; u.u_dent.u_ino = ip->i_number; cp1 = &u.u_dent.u_name[0]; for(cp2 = &u.u_dbuf[0]; cp2 < &u.u_dbuf[DIRSIZ];) ng dates * set to the argument tm. */ iupdat(p) int *p; { register *ip1, *ip2, *rp; int *bp, i; rp = p; if((rp->i_flag&IU *cp1++ = *cp2++; u.u_count = DIRSIZ+2; u.u_base = &u.u_dent; writei(u.u_pdir); iput(u.u_pdir); } prele(ip) int *ip; { regPD) != 0) { if(getfs(rp->i_dev)->s_ronly) return; i = rp->i_number+31; bp = bread(rp->i_dev, ldiv(i,16)); ip1 = bp->bister *rp; rp = ip; rp->i_flag =& ~ILOCK; if(rp->i_flag&IWANT) { rp->i_flag =& ~IWANT; wakeup(rp); } }  ino==p->i_number) { if((p->i_flag&ILOCK) != 0) { p->i_flag =| IWANT; sleep(p, PINOD); goto loop; } if((p->_addr + 32*lrem(i, 16); ip2 = &rp->i_mode; while(ip2 < &rp->i_addr[8]) *ip1++ = *ip2++; ip1 =+ 2; if(rp->i_flag&IUPD) È(ÈÙùù/ low core / parameters to be set to include various drivers / as well as eis and dump capability. eis = 1 dump = 0 rk = 0 rpÙùùùøøøùøùù¨ùÙù = 0 qx = 1 qxeml = 1 sa = 0 hp = 0 tc = 0 tm = 0 lp = 0 fltvect = 0 dl = 0 halt = 0 reset = 5 br4 = 200 br5 = 240 br6 = 300 bB@w üÿæ ÌÕΦÿ&ß Ö µõ Ä5-"5-̵ä̵ Â2!åÂeÂ%ø‚÷ ¢ÿ´ŠÌÕ÷•ÇÿøÙ_canonb _swapmap _rootdir _lbolt _time _tout _callout _mount _mpid  wŠÿ ô‹ÄeÄ%ÜÏ‚„íttÌ•´ŠÎfÎeß Ö fß Ö Ê5Žß ß ÌÎfÎeß Ö t€l_runrun _curpri _rootdev _swapdev _updlock _regloc _u &_inode Ü_bdevsw _nblkdev _cdevsw5øÿÃeSøÿõeøÿÀeÀ ö‡Žß ¦w âþDô£ÌÕô‹ ß 4 &ß Ö ß jß " Š4 ôŠß "w–þw ’þÆå _nchrdev _buf X_bfreeli _iget"~igetipip2ip1øÿpdevinoBʵAŽß ð‹›:€Àe5öÿÎföÿß Ö ¦ß Ö 5øÿÎföÿß Ö tAøÿ@lƒÃeÔ€ÀeÀ ú‡ÄeʵÔcsv L2$L20001_sleep L20013L20005*L6vL8^L20003J_panic þÔ þNøÿß wþýw úýÆåDô5 EÀe50ý *ô5N&ß Ö ÂÂeþ Ê Ž&ß Ö ÂåÂ,óƒÎß N&L20011fL1rL20007jL20008pcret L5‚_ldiv _bread L15Ø_brelse _iputß Ö = õåÀe@-ʆôE4Š 4 ÌÕw\ýw XýÀ¼ýß  wBýÌÕ@ÀU€4ô•ô�`ý ß äëw ý@7"_lrem L16L20010þ~iputrppL19\L20J_itrunc"_ifree _iupfýÄZÃHÔ”Ã%Vü‚÷8ý÷X0ýÎVýß ÎNýß wÞüw ÚüDÌÅ̵ÌÅß w¾üù(dat"j_prele""~iupdatjbpøÿip1ip2rpiöÿpL21þ_getfs xx‰ùÙL23ÚL20015ØL25ö_bwrite ~itruncbpcpdpøÿepöÿiprpø(H(ùL26 L27‚L20019"L29|L31jL32^L20017JL34Z_free _maknode"¤~makØÙùˆønode¤ipmode_ialloc L37¾L36º_wdir"ä~wdiräipcp1cp2HIIÈÙùL20021ú_writei ~prele"iprpL41>_wakeup  ////////////////////////////////////////////// .globl call, trap .globl _clock kwlp: jsr r0,call; _clock .if qxeml .globl _emlint emlou: jsr r0,call; _emlint; .endif .if lp .globl _lpint lpou: jsr r0,call; _lpint .endif .if rk .globl _rkintr rkio: # #include "../param.h" #include "../user.h" #include "../systm.h" #include "../proc.h" #include "../inode.h" #define CLOCK1 01jsr r0,call; _rkintr .endif .if rp .globl _rpintr rpio: jsr r0,call; _rpintr .endif .if qx .globl _qxintr qxio: jsr r0,call;77546 #define CLOCK2 0172540 /* * Icode is the octal bootstrap * program executed in user mode * to bring up the system. * _qxintr .endif .if sa .globl _saintr saio: jsr r0,call; _saintr .endif .if hp .globl _hpintr hpio: jsr r0,call; _hpintr .en/ int icode[] { 0104413, /* sys exec; init; initp */ TOPSYS+014, TOPSYS+010, 0000777, /* br . */ TOPSYS+014, /* initp: initdif .if tc .globl _tcintr tcio: jsr r0,call; _tcintr .endif .if tm .globl _tmintr tmio: jsr r0,call; _tmintr .endif .globl ; 0 */ 0000000, 0062457, /* init: */ 0061564, 0064457, 0064556, 0000164, }; /* * Initialization code. * Cr7 = 340 . = 0^. br 1f 4 / trap vectors trap; br7+0 / bus error .if eis trap; br7+1 / illegal instruction .endif .if eis_klrint klin: jsr r0,call; _klrint .globl _klxint klou: jsr r0,call; _klxint / save registers and dump memory _panic: _du-1 .globl trapem trapem; br7+1 / emulate illegal instruction .endif trap; br7+2 / bpt-trace trap trap; br7+3 / iot trap mp: .if dump reset mov r0,*$4 mov $6,r0 mov r1,(r0)+ mov r2,(r0)+ mov r3,(r0)+ mov r4,(r0)+ mov r5,(r0)+ mov sp,(r0)+ rtrap; br7+4 / power fail trap; br7+5 / emulator trap trap; br7+6 / system entry . = 040^. .globl start, _dump, _panic 1: jkda = 177412 rkcs = 177404 1: tstb *$rkcs bge 1b mov $rkda+2,r1 mov $[396.\<4]+8.,-(r1) clr -(r1) mov $-28.*1024.,-(r1) mmp start jmp _dump . = 060^. klin; br5 klou; br5 . = 100^. kwlp; br6 kwlp; br6 .if qxeml . = 164^. emlou; br6 .endif ov $3,-(r1) 1: tstb (r1) bge 1b jmp *$173010 .endif .if dump-1 halt br . .endif .if rk .globl _rkaddr _rkaddr: mov r2,-(.if lp . = 200^. lpou; br4 .endif .if tc . = 214^. tcio; br6 .endif .if rk . = 220^. rkio; br5 .endif .if tm . = 224^. tmsp) mov $dvtab,r2 mov 4(sp),r0 bic $!7,r0 swab r0 asl r0 mov 6(sp),r1 0: sub (r2),r1 bmi 1f add 2(r2),r0 br 0b 1: addio; br5 .endif .if qx . = 250^. qxio; br5 .endif .if rp . = 254^. rpio; br5 .endif .if hp . = 254^. hpio; br5 .endif / f (r2),r1 cmp (r2)+,(r2)+ cmp r2,$dvtab+12. blo 0b asl r0 asl r0 asl r0 asl r0 bis r1,r0 mov (sp)+,r2 rts pc dvtab: 1loating vectors go here .if fltvect . = 300^. .endif .if dl klin; br5+1 klou; br5+1 .endif .if sa . = 360^. saio; br5 saio200. 100. 120. 10. 12. 1. .endif ; br5+1 / error interrupt thru 364 .endif ////////////////////////////////////////////////////// / interface code to C //////// lag =| SLOAD; u.u_procp = &proc[0]; /* * set up 'known' i-nodes */ /* *lks = 0115; */ cinit(); binit(); iinit(); rootdir = iget(rootdev, ROOTINO); rootdir->i_flag =& ~ILOCK; u.u_cdir = iget(rootdev, ROOTINO); u.u_cdir->i_flag =& ~ILOCK; /* * make init process */ copyout(icode, TOPSYS, sizeof icode); /* * Return goes to loc. 0 of user init * code just c# /* */ /* * Structure of the coremap and swapmap * arrays. Consists of non-zero count * and base address of that many * copied out. */ } ontiguous units. * (The coremap unit is 64 bytes, * the swapmap unit is 512 bytes) * The addresses are increasing and * the list is terminated with the * first zero count. */ struct map { char *m_size; char *m_addr; }; /* * Allocate size units from the given * map. Return the base of the allocated * space. * Algorithm is first fit. */ malloc(mp, size) struct map *mp; { register int a; register struct map *bp; for (bp = mp; bp->m_size; bp++) { if (bp->m_size >= size) { a = bp->m_addr; ~tw üÿ7 øÿÎTæšæß –%÷•àÿ÷ÕÛÿ÷÷ Ðÿ÷ Ìÿ÷ ÈÿÎæÀÿß Ö 7¶ÿÿŰÿÎæ¨ÿß Ö 7äÿÿÅÞÿÎæ` bp->m_addr =+ size; if ((bp->m_size =- size) == 0) do { bp++; (bp-1)->m_addr = bp->m_addr; } while ((bp-alled from mch.s as * soon as a stack * has been established. * Functions: * find which clock is configured * hand craft 0tæ~ß –%w‚ÿ ‰ ``ÿ `/etc/inityé(ˆ   ™©¹ÉÈ99ÉÈh process * call all initialization routines * fork - process 0 to schedule * - process 1 execute bootstrap * * panic: Øé_u &_canonb _swapmap _rootdir _lbolt _time  no clock -- neither clock responds * loop at loc 6 in user mode -- /etc/init * cannot be executed. */ main() { extern schar_tout _callout _mount _mpid _runrun _curpri _rootdev _swapdev _updlock _regloc _proc; register i, *p; updlock = 0; /* * determine clock */ #ifndef QX if(fuword(lks = CLOCK1) == -1) lks = CLOCK2; #end „_inode Ü_icode#~_main"~mainipcsv _mfree _cinit _binit _iinif #ifdef VSWAP mfree(swapmap, NSWAP, SWPLO); #endif /* * set up system process */ proc[0].p_stat = SRUN; proc[0].p_fit _iget _copyout cret  { register struct map *bp; register int t; register int a; a = aa; for (bp = mp; bp->m_addr<=a && bp->m_size!=0; bp++); ieeDbpmpsizeataaL11ZL20003RL12`L14œf (bp>mp && (bp-1)->m_addr+(bp-1)->m_size == a) { (bp-1)->m_size =+ size; if (a+size == bp->m_addr) { (bp-1)->m_size =+ bL10ØL16ˆL19¸L24¾p->m_size; while (bp->m_size) { bp++; (bp-1)->m_addr = bp->m_addr; (bp-1)->m_size = bp->m_size; } } } else { if (a+size == bp->m_addr && bp->m_size) { bp->m_addr =- size; bp->m_size =+ size; } else if (size) do { t = bp->mzÄö�üÿ÷ r7Îfæ æ�ÎEà�æ�f�fÎe ¦ÎEàÿ—- `‡�Æ`fffffffØ æ�ÎUà�÷‹žÿæ�ÎEà�÷ �ÿ_addr; bp->m_addr = a; a = t; t = bp->m_size; bp->m_size = size; bp++; } while (size = t); } } òØ Ö �—-` ‡Áå ‘‘‘‘‘Áå F�Ö €�æ�¦æ�ÎUàÎE@�B€”ÀEÿ±Ñ   Â5 ‰øÿÉe ÂEÊÿ·ÿ‚�‡1 Àÿÿ‚�‡€�æ�¦ææ�ÎUàÎE@�B Ââþ·Üþ ± Â5 ÃÊþ÷Äþòøÿ �±‰ ƒ‚�‡Àƒ‚�‡�ÁE÷ Bv ÀÀEÿ‡�ÁE÷ (&v ¶�Ž�€÷ 4 ‡�÷ ‡æ�æ�ÎUà�æ¾÷ò¸@�€÷ ‡æ�æ�ÎUà�æ˜÷ò’ ·Œ�‡·„�Ö Àÿÿ‡÷ ‚~·n‚ ‡€¦æ`&€� ‚ ‚ ÷2J‡·D‚Àÿÿ‡æ�æ�ÎEà��‡æ�ÎUà��€�Pæ�ÎEà�Iæ�ÎUà�Ühw üÿCK-‚ÄsmKíË ÃeóþÿóüÿøwÈÿÃeË å øw ¸ÿBDÌ Äe´ ù†D-†þÿmüÿ€ �€æ�ÎEà�Iæ�ÎEà�‡æ�ÎU ÎEÀ�‡æ�ÎUàÎE@�‡æ�ÎUàÎE �‡æ�ÎUà�‡€°mH ‡€�€í�í€  ÿÿW þ ‚Àtmüÿ€@m-*4cüÿÌ &Äe4þÿ4üÿö€@m-Ì tíLmõ  ´ÂLÄeõów$ÿiþ‡W ‡Á@‡À  `ü‡÷þ[èX÷ äüÆ€& æ` �6r‡ �6r@‡�@A6v@‡@…&æ¦È ADCBF…‡À�‡Ùi6�‡ÿ˜Ùé1)->m_size = bp->m_size); return(a); } } return(0); } /* * Free the previously allocated space aa * of size units intoÙ_malloc"~mallocbpmpsize the specified map. * Sort aa into map and combine on * one or both ends if possible. */ mfree(mp, size, aa) struct map *mp; acsv L2<L20001 L48L62L9"L14cret _mfree"D~mfr / machine language assist / non-UNIX instructions halt = 0 wait = 1 rti = 2 reset = 5 / flag to enable LSI PS r/w instructionsut .globl _getc, _putc .globl _cfreelist _getc: mov 2(sp),r1 .if lsi mfps -(sp) .endif .if lsi-1 mov PS,-(sp) .endif mov r99: mfps, mtps lsi = 1 .if lsi mtps = 106400^tst mfps = 106700^tst .endif .globl trap, call, emtrap .globl _trap trap: .if lsi m9999fps -4(sp) .endif .if lsi-1 mov PS,-4(sp) .endif tst nofault bne 1f emtrap: jsr r0,call1; _trap / no return 1: mov nofault,(sp) rti .globl _runrun, _swtch call1: tst -(sp) .if lsi mfps -(sp) bic $340,(sp) mtps (sp)+ .endif .if lsi-1 bic $340,PS .endif br 1f call: .if lsi mfps -(sp) .endif .if lsi-1 mov PS,-(sp) .endif 1: mov r1,-(sp) mov sp,r1 /get stack pointer at trap mov r1,-(sp) add $10.,(sp) mov 4(sp),-(sp) bic $!37,(sp) / trap type cmp 10.(sp),$_u+[usize*64.] blo 1f / trap fro)m system mov 2(sp),r1 / trap from user, get user stack mov $_u+[usize*64.],sp mov -(r1),-(sp) / copy user stack to system stahaltrtiresetlsimtps �mfps À�trap"call""emtrap" _trap PSck mov -(r1),-(sp) mov -(r1),-(sp) mov -(r1),-(sp) mov -(r1),-(sp) mov -(r1),-(sp) mov -(r1),-(sp) jsr pc,*(r0)+ 2: .if lþÿnofault$zcall1_runrun _swtch _u!\usize_getc"œ_putc"ú_cfreeli _fubyte"`si mfps -(sp) bis $340,(sp) mtps (sp)+ .endif .if lsi-1 bis $340,PS .endif tstb _runrun beq 2f .if lsi mfps -(sp) bic $3_subyte"z_fuibyte"`_suibyte"z_fuword"¤_suword"Æ_fuiword"¤_suiword"Ægword®pwordÔfuword¨err40,(sp) mtps (sp)+ .endif .if lsi-1 bic $340,PS .endif jsr pc,_swtch br 2b 1: jsr pc,*(r0)+ 2: tst (sp)+ mov (sp)+,r1 / nòsuwordÎ_copyin"_copyout"copsu_idle">_savu"N_retu"h_spl0"‚_spl1"Œ_spl4"š_splew user stack pointer cmp 6(sp),$_u+[usize*64.] blo 1f / return from system trap sub $10.,r1 / begin. of system stack to be c5"š_spl6"¨_spl7"¶_dpadd"À_dpcmp"Îstart"_end _edata _main _ldiv"(_lrem"4opied to user stack mov (sp)+,(r1)+ / copy system stack to user stack mov (sp)+,(r1)+ mov (sp)+,(r1)+ mov (sp)+,(r1)+ mov (_lshift"Bcsv"Rcret"^_getps"l_putps"p_haltins"vsp)+,(r1)+ sub $10.,r1 mov r1,sp / switch to user stack 1: mov (sp)+,r1 tst (sp)+ mov (sp)+,r0 rti / Character list get/p ov (sp)+,r3 mov (sp)+,r2 .if lsi mtps (sp)+ .endif .if lsi-1 mov (sp)+,PS .endif rts pc 9: mov pc,r0 mov (sp)+,r3 mov (spsp)+,PS .endif rts pc err: mov (sp)+,nofault .if lsi mtps (sp)+ .endif .if lsi-1 mov (sp)+,PS .endif tst (sp)+ mov $-1,r0)+,r2 .if lsi mtps (sp)+ .endif .if lsi-1 mov (sp)+,PS .endif rts pc .globl _fubyte, _subyte .globl _fuibyte, _suibyte .glob rts pc .globl _copyin, _copyout _copyin: _copyout: jsr pc,copsu 1: mov (r0)+,(r1)+ sob r2,1b 2: mov (sp)+,nofault mov (sl _fuword, _suword .globl _fuiword, _suiword _fuibyte: _fubyte: mov 2(sp),r1 bic $1,r1 jsr pc,gword cmp r1,2(sp) beq 1f swp)+,r2 clr r0 rts pc copsu: mov (sp)+,r0 mov r2,-(sp) mov nofault,-(sp) mov r0,-(sp) mov 10(sp),r0 mov 12(sp),r1 mov 1ab r0 1: bic $!377,r0 rts pc _suibyte: _subyte: mov 2(sp),r1 bic $1,r1 jsr pc,gword mov r0,-(sp) cmp r1,4(sp) beq 1f m4(sp),r2 asr r2 mov $1f,nofault rts pc 1: mov (sp)+,nofault mov (sp)+,r2 mov $-1,r0 rts pc .globl _idle _idle: .if lsi 2,-(sp) .if lsi mfps -(sp) bis $340,(sp) bic $100,(sp) mtps (sp)+ / spl 5 .endif .if lsi-1 bis $340,PS bic $100,PS .endifovb 6(sp),1(sp) br 2f 1: movb 6(sp),(sp) 2: mov (sp)+,r0 jsr pc,pword clr r0 rts pc _fuiword: _fuword: mov 2(sp),r1 fuwo mov 2(r1),r2 / first ptr beq 9f / empty movb (r2)+,r0 / character bic $!377,r0 mov r2,2(r1) dec (r1)+ / count bne 1f rd: jsr pc,gword rts pc gword: .if lsi mfps -(sp) mfps -(sp) bis $340,(sp) mtps (sp)+ .endif .if lsi-1 mov PS,-(sp) bisclr (r1)+ clr (r1)+ / last block br 2f 1: bit $7,r2 bne 3f mov -10(r2),(r1) / next block add $2,(r1) 2: dec r2 bic $7,r $340,PS .endif mov nofault,-(sp) mov $err,nofault mov (r1),r0 br 1f _suiword: _suword: mov 2(sp),r1 mov 4(sp),r0 suword:2 mov _cfreelist,(r2) mov r2,_cfreelist 3: mov (sp)+,r2 .if lsi mtps (sp)+ .endif .if lsi-1 mov (sp)+,PS .endif rts pc 9:  jsr pc,pword rts pc pword: .if lsi mfps -(sp) mfps -(sp) bis $340,(sp) mtps (sp)+ .endif .if lsi-1 mov PS,-(sp) bis $3 clr 4(r1) mov $-1,r0 mov (sp)+,r2 .if lsi mtps (sp)+ .endif .if lsi-1 mov (sp)+,PS .endif rts pc _putc: mov 2(sp),r0 mo40,PS .endif mov nofault,-(sp) mov $err,nofault mov r0,(r1) 1: mov (sp)+,nofault .if lsi mtps (sp)+ .endif .if lsi-1 mov (v 4(sp),r1 .if lsi mfps -(sp) .endif .if lsi-1 mov PS,-(sp) .endif mov r2,-(sp) mov r3,-(sp) .if lsi mfps -(sp) bis $340,(’“”•–—˜™›œ�žŸ ¡sp) bic $100,(sp) mtps (sp)+ / spl 5 .endif .if lsi-1 bis $340,PS bic $100,PS .endif mov 4(r1),r2 / last ptr bne 1f mov _cfreelist,r2 beq 9f mov (r2),_cfreelist clr (r2)+ mov r2,2(r1) / first ptr br 2f 1: bit $7,r2 bne 2f mov _cfreelist,r3  beq 9f mov (r3),_cfreelist mov r3,-10(r2) mov r3,r2 clr (r2)+ 2: movb r0,(r2)+ mov r2,4(r1) inc (r1) / count clr r0 m mtps (sp)+ .endif .if lsi-1 bic $340,PS .endif rts pc _spl1: .if lsi mfps -(sp) bis $40,(sp) bic $300,(sp) mtps (sp)+ .en -(r1),r2 mov r5,sp mov (sp)+,r5 rts pc .if lsi .globl _getps _getps: mfps r0 rts pc .globl _putps _putps: mtps 2(sp) dif .if lsi-1 bis $40,PS bic $300,PS .endif rts pc _spl4: _spl5: .if lsi mfps -(sp) bis $340,(sp) bic $100,(sp) mtps (sp)rts pc .endif / halt instruction / used with "halt" system call / for bringing system down gracefully .globl _haltins _haltins:+ .endif .if lsi-1 bis $340,PS bic $100,PS .endif rts pc _spl6: .if lsi mfps -(sp) bis $340,(sp) bic $40,(sp) mtps (sp)+  halt br . / hang .globl _u _u = 56000 usize = 16. PS = 177776 .bss .globl nofault nofault:.=.+2 .endif .if lsi-1 bis $340,PS bic $40,PS .endif rts pc _spl7: .if lsi mfps -(sp) bis $340,(sp) mtps (sp)+ .endif .if lsi-1  bis $340,PS .endif rts pc .globl _dpadd _dpadd: mov 2(sp),r0 add 4(sp),2(r0) adc (r0) rts pc .globl _dpcmp _dpcmp: mov 2(sp),r0 mov 4(sp),r1 sub 6(sp),r0 sub 8(sp),r1 sbc r0 bge 1f cmp r0,$-1 bne 2f cmp r1,$-512. bhi 3f 2: mov $-512.,r0 # /* */ /* * Memory special file * minor device 0 is physical memory * minor device 1 is kernel memory * minor device 2 is rts pc 1: bne 2f cmp r1,$512. blo 3f 2: mov $512.,r1 3: mov r1,r0 rts pc .globl start, _end, _edata, _main start: / cle EOF/RATHOLE */ #include "../param.h" #include "../user.h" #include "../conf.h" mmread(dev) { register c; if(dev.d_minor = mfps -(sp) mfps -(sp) bic $340,(sp) mtps (sp)+ .endif .if lsi-1 mov PS,-(sp) bic $340,PS .endif wait .if lsi mtps (sp)+ ar bss and user block mov $_edata,r0 1: clr (r0)+ cmp r0,$_u+[usize*64.] blo 1b / set up stack pointer mov r0,sp / and .endif .if lsi-1 mov (sp)+,PS .endif rts pc .globl _savu, _retu _savu: .if lsi mfps -(sp) bis $340,(sp) mtps (sp)+ .endif pointer to system stack mov $_u-2,_u / set up previous mode and call main / on return, enter user mode at 060000 jsr pc,_m.if lsi-1 bis $340,PS .endif mov (sp)+,r1 mov (sp),r0 mov sp,(r0)+ mov r5,(r0)+ .if lsi mfps -(sp) bic $340,(sp) mtps (sain mov $_u+[usize*64.]+8192.,sp / set stack at first 4K of user space clr -(sp) mov $_u+[usize*64.],-(sp) rti .globl _ldivp)+ .endif .if lsi-1 bic $340,PS .endif jmp (r1) _retu: .if lsi mfps -(sp) bis $340,(sp) mtps (sp)+ .endif .if lsi-1 bis  _ldiv: clr r0 mov 2(sp),r1 div 4(sp),r0 rts pc .globl _lrem _lrem: clr r0 mov 2(sp),r1 div 4(sp),r0 mov r1,r0 rts pc $340,PS .endif mov (sp)+,r1 mov (sp),r0 mov (r0)+,sp mov (r0)+,r5 .if lsi mfps -(sp) bic $340,(sp) mtps (sp)+ .endif .if  .globl _lshift _lshift: mov 2(sp),r1 mov (r1)+,r0 mov (r1),r1 ashc 4(sp),r0 mov r1,r0 rts pc .globl csv csv: mov r5,r0 lsi-1 bic $340,PS .endif jmp (r1) .globl _spl0, _spl1, _spl4, _spl5, _spl6, _spl7 _spl0: .if lsi mfps -(sp) bic $340,(sp)  mov sp,r5 mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) jsr pc,(r0) .globl cret cret: mov r5,r1 mov -(r1),r4 mov -(r1),r3 mov ted * 2 if name is to be deleted */ namei(flag) { register struct inode *dp; register c; register char *cp; int eo, *bp;  /* * If name starts with '/' start from * root; otherwise start from current dir. */ dp = u.u_cdir; if((c=uchar()) == '/') dp = rootdir; iget(dp->i_dev, dp->i_number); while(c == '/') c = uchar(); if(c == '\0' && flag != 0) { u.u_error =p w üÿõ¥ Î4ß ÷‹ß À ówÖÿw Òÿõ¥Ä7 7aüÿæBß Ö w®ÿ÷ ªÿú÷‹Ùÿ÷æÞÿÎ ß Ö ñ ENOENT; goto out; } cloop: /* * Here dp contains pointer * to last component matched. */ if(u.u_error) goto out;™ È Øé™ Héi x_u &_bde if(c == '\0') return(dp); /* * If there is another component, * dp must be a directory and * must have x permission.vsw _nblkdev _cdevsw _nchrdev _mmread"~mmreadcdevcsv L1&L4  */ if((dp->i_mode&IFMT) != IFDIR) { u.u_error = ENOTDIR; goto out; } if(access(dp, IEXEC)) goto out; /* * Gathe_fuibyte _passc cret _mmwrite"*~mmwrite*cdevL7R_dpadd L5N_cpassr up name into * users' dir buffer. */ cp = &u.u_dbuf[0]; while(c!='/' && c!='\0' && u.u_error==0) { if(cp < &u.u_dbuf[ _suibyte DIRSIZ]) *cp++ = c; c = uchar(); } while(cp < &u.u_dbuf[DIRSIZ]) *cp++ = '\0'; while(c == '/') c = uchar(); if(u.u_error) goto out; /* * Set up to search a directory. */ u.u_offset[1] = 0; u.u_offset[0] = 0; eo = 0; u.u_count = ldiv(dp->i_size1, DIRSIZ+2); bp = NULL; eloop: /* * If at the end of the directory, * the search failed. Report what * i= 2) return; do { c = fuibyte(u.u_offset[1]); } while(u.u_error==0 && passc(c)>=0); } mmwrite(dev) { register c; if(dev.d_minor == 2) { c = u.u_count; u.u_count = 0; u.u_base =+ c; dpadd(u.u_offset, c); return; } for(;;) { if ((c=cp# #include "../param.h" #include "../inode.h" #include "../user.h" #include "../systm.h" #include "../buf.h" /* * Convert a paass())<0 || u.u_error!=0) break; suibyte(u.u_offset[1]-1, c); } } thname into a pointer to * an inode. Note that the inode is locked. * * flag = 0 if name is sought * 1 if name is to be crea s appropriate as per flag. */ if(u.u_count == 0) { if(bp != NULL) brelse(bp); if(flag==1 && c=='\0') { if(access(dp, IWRITE)) goto out; u.u_pdir = dp; if(eo) u.u_offset[1] = eo-DIRSIZ-2; else dp->i_flag =| IUPD; return(NULL); } u.u_error = ENOENT; goto out; } /* * If offset is on a block boundary, * read the next directory block. * Release previous if it exists. */ if((u.u_offset[1]&0777) == 0) { if(bp != NULL) brelse(bp); bp = bread(dp->i_dev, N<w üÿÆåÄ:÷ Ã%/Ääÿ&ß Ö ÷ úÃ%/úà õ  ÷•ïÿ÷•çÿß _÷‹×ÿ÷à _þÀE bmap(dp, ldiv(u.u_offset[1], 512))); } /* * Note first empty directory slot * in eo for possible creat. * String compaÿŸÀ%@éÎ@&ß Ö À äÂH à ÷‹¡ÿ Â%VƒÒ�÷ †Ã%/ðŠÂ%Vü‚÷ nÃ%/ú÷‹oÿÃ7 vÿ7 pÿ5 øÿÎ& ß Ö 7Xÿ5 öÿ÷ Pÿre the directory entry * and the current component. * If they do not match, go back to eloop. */ bcopy(bp->b_addr+(u.u_o$õ öÿNöÿß õ%�à ›Î€&ß Ö À š7Hÿõ øÿ@øÿÀeðÿ7ÿ‘ÌÕŽ÷5ÿÿõ öÿNöÿß Îæìþß Ö &ß Ö &ß ffset[1]&0777), &u.u_dent, (DIRSIZ+2)/2); u.u_offset[1] =+ DIRSIZ+2; u.u_count--; if(u.u_dent.u_ino == 0) { if(eo == 0) Ö 5öÿÎæX@öÿ&À¸þÀEþ`ß –%÷e¦þ÷ žþ÷ ²þõ øÿŸõ’þøÿ›ÂHÀZÀåH€`ˆ¢’‚ Â%Võ‚õ öÿNöÿß õ%à ΀&eo = u.u_offset[1]; goto eloop; } for(cp = &u.u_dbuf[0]; cp < &u.u_dbuf[DIRSIZ]; cp++) if(*cp != cp[u.u_dent.u_name - u.u_ß Ö À _Pwüý5öÿß ÎDþföÿß Ö _\_Vw ÒýÎ$þ· þß Ä%ÿÿ÷•jïýw²ý¹Idbuf]) goto eloop; /* * Here a component matched in a directory. * If there is more pathname, go back to * cloop, othèX˜erwise return. */ if(bp != NULL) brelse(bp); if(flag==2 && c=='\0') { if(access(dp, IWRITE)) goto out; return(dp);X˜ } bp = dp->i_dev; iput(dp); dp = iget(bp, u.u_dent.u_ino); if(dp == NULL) return(NULL); goto cloop; out: iput(dp); rX˜¨¸eturn(NULL); } /* * Return the next character from the * user string pointed at by dirp. */ uchar() { register c; c = fuX˜ Xèbyte(u.u_dirp++); if(c == -1) u.u_error = EFAULT; return(c); } ¹8 _inode Ü_u &_canonb _swapmap _rootdir _lbolt _time  de effects. In general the * arguments to an allocate routine are a device and * a block number, and the value is a pointer t(rbp); } /* * Release the buffer, start I/O on it, but don't wait for completion. */ bawrite(bp) struct buf *bp; { register o * to the buffer header; the buffer is marked "busy" * so that no on else can touch it. If the block was * already in core,struct buf *rbp; rbp = bp; rbp->b_flags =| B_ASYNC; bwrite(rbp); } /* * release the buffer, with no I/O implied. */ brels no I/O need be done; if it is * already busy, the process waits until it becomes free. * The following routines allocate a bue(bp) struct buf *bp; { register struct buf *rbp, **backp; register int sps; rbp = bp; if (rbp->b_flags&B_WANTED) wakeup(_tout _callout _mount _mpid _runrun _curpri _rootdev _swapdev _updlock _regloc _bufffer: * getblk * bread * Eventually the buffer must be released, possibly with the * side effect of writing it out, by using X_bfreeli _namei"~nameiflagdpcpeoøÿbpöÿccsv _uch one of * bwrite * bdwrite * bawrite * brelse */ /* * Read in (if necessary) the block and return a buffer pointer. */ bar"*L2_iget L32L20001,L7\L20010BL6PL20014J_iput L20015Vread(dev, blkno) { register struct buf *rbp; rbp = getblk(dev, blkno); if (rbp->b_flags&B_DONE) return(rbp); rbp->b_flagsL1L20003þ_access L10¦L20005ŽL13°L12 L20007®L15¾L20009¸_ldiv =| B_READ; rbp->b_wcount = -256; (*bdevsw[dev.d_major].d_strategy)(rbp); iowait(rbp); return(rbp); } /* * Write the buffe L17ìL18:L19_brelse L214L23xL24P_bmap _bread _bcopy L25r, waiting for completion. * Then release the buffer. */ bwrite(bp) struct buf *bp; { register struct buf *rbp; register fla¶L20012ºL30ÞL31cret ~uchar*c_fubyte L34Hg; rbp = bp; flag = rbp->b_flags; rbp->b_flags =& ~(B_READ | B_DONE | B_ERROR | B_DELWRI); rbp->b_wcount = -256; (*bdevsw[# /* */ #include "param.h" #include "user.h" #include "buf.h" #include "conf.h" #include "systm.h" #include "proc.h" /* * Thrbp->b_dev.d_major].d_strategy)(rbp); if ((flag&B_ASYNC) == 0) { iowait(rbp); brelse(rbp); } else if ((flag&B_DELWRI)==0) is is the set of buffers proper, whose heads * were declared in buf.h. There can exist buffer * headers not pointing here tha geterror(rbp); } /* * Release the buffer, marking it so that if it is grabbed * for another purpose it will be written out t are used purely * as arguments to the I/O routines to describe * I/O to be done-- e.g. swbuf, just below, for * swapping. before being * given up (e.g. when writing a partial block where it is * assumed that another write for the same block will so*/ char buffers[NBUF][512]; struct buf swbuf; /* * The following several routines allocate and free * buffers with various sion follow). */ bdwrite(bp) struct buf *bp; { register struct buf *rbp; rbp = bp; rbp->b_flags =| B_DELWRI | B_DONE; brelse  &bfreelist; else { dp = bdevsw[dev.d_major].d_tab; if(dp == NULL) panic(); for (bp=dp->b_forw; bp != dp; bp = bp->b_favailable list and mark it busy. * (internal interface) */ notavail(bp) struct buf *bp; { register struct buf *rbp; registerorw) { if (bp->b_blkno!=blkno || bp->b_dev!=dev) continue; spl6(); if (bp->b_flags&B_BUSY) { bp->b_flags =| B_W int sps; rbp = bp; sps = PS->integ; spl6(); rbp->av_back->av_forw = rbp->av_forw; rbp->av_forw->av_back = rbp->av_back; ANTED; sleep(bp, PRIBIO); spl0(); goto loop; } spl0(); notavail(bp); return(bp); } } spl6(); if (bfrbp->b_flags =| B_BUSY; PS->integ = sps; } /* * Mark I/O complete on a buffer, release it if I/O is asynchronous, * and wakereelist.av_forw == &bfreelist) { bfreelist.b_flags =| B_WANTED; sleep(&bfreelist, PRIBIO); spl0(); goto loop; } spl0() up anyone waiting for it. */ iodone(bp) struct buf *bp; { register struct buf *rbp; rbp = bp; rbp->b_flags =| B_DONE; if ; notavail(bp = bfreelist.av_forw); if (bp->b_flags & B_DELWRI) { bp->b_flags =| B_ASYNC; bwrite(bp); goto loop; } bp-(rbp->b_flags&B_ASYNC) brelse(rbp); else { rbp->b_flags =& ~B_WANTED; wakeup(rbp); } } /* * Zero the core associated w±²³´µ¶·¸º»¼½¾¿Àith a buffer. */ clrbuf(bp) int *bp; { register *p; register c; p = bp->b_addr; c = 256; do *p++ = 0; while (--c); } rbp); if (bfreelist.b_flags&B_WANTED) { bfreelist.b_flags =& ~B_WANTED; wakeup(&bfreelist); } if (rbp->b_flags&B_ERROR)  rbp->b_dev.d_minor = -1; /* no assoc. on error */ backp = &bfreelist.av_back; sps = PS->integ; spl6(); rbp->b_flags =& ~(B_WANTED|B_BUSY|B_ASYNC); (*backp)->av_forw = rbp; rbp->av_back = *backp; *backp = rbp; rbp->av_forw = &bfreelist; PS->integ = sps; } /* * Assign a buffer for the given block. If the appropriate * block is already associated, return it; otherwise s>b_flags = B_BUSY | B_RELOC; bp->b_back->b_forw = bp->b_forw; bp->b_forw->b_back = bp->b_back; bp->b_forw = dp->b_forw; bp->earch * for the oldest non-busy buffer and reassign it. * When a 512-byte area is wanted for some random reason * (e.g. durinb_back = dp; dp->b_forw->b_back = bp; dp->b_forw = bp; bp->b_dev = dev; bp->b_blkno = blkno; return(bp); } /* * Wait for g exec, for the user arglist) getblk can be called * with device NODEV to avoid unwanted associativity. */ getblk(dev, blkno) I/O completion on the buffer; return errors * to the user. */ iowait(bp) struct buf *bp; { register struct buf *rbp; rbp = { register struct buf *bp; register struct devtab *dp; if(dev.d_major >= nblkdev) panic(); loop: if (dev < 0) dp =bp; spl6(); while ((rbp->b_flags&B_DONE)==0) sleep(rbp, PRIBIO); spl0(); geterror(rbp); } /* * Unlink a buffer from the  w = bp; bp->b_flags = B_BUSY; brelse(bp); } i = 0; for (bdp = bdevsw; bdp->d_open; bdp++) { dp = bdp->d_tab; if(dp) { dp->b_forw = dp; dp->b_back = dp; } i++; } nblkdev = i; } /* * swap I/O */ swap(rp, rdflg) struct proc *rp; { r/* */ char partab[] { 0001,0201,0201,0001,0201,0001,0001,0201, 0202,0004,0003,0205,0005,0206,0201,0001, 0201,0001,0001,0201egister int *fp; fp = &swbuf.b_flags; spl6(); *fp = B_BUSY | rdflg; swbuf.b_dev = swapdev; swbuf.b_wcount = - SWPSIZ*256; ,0001,0201,0201,0001, 0001,0201,0201,0001,0201,0001,0001,0201, 0200,0000,0000,0200,0000,0200,0200,0000, 0000,0200,0200,0000,0/* 32 w/block */ swbuf.b_blkno = SWPLO+rp->p_pid*SWPSIZ; swbuf.b_addr = &u; /* 64 b/block */ (*bdevsw[swapdev>>8].d_strategy)200,0000,0000,0200, 0000,0200,0200,0000,0200,0000,0000,0200, 0200,0000,0000,0200,0000,0200,0200,0000, 0200,0000,0000,0200,000(&swbuf); spl6(); while((*fp&B_DONE)==0) idle(); spl0(); *fp =& ~(B_BUSY|B_WANTED); return(*fp&B_ERROR); } /* * make su0,0200,0200,0000, 0000,0200,0200,0000,0200,0000,0000,0200, 0000,0200,0200,0000,0200,0000,0000,0200, 0200,0000,0000,0200,0000,re all write-behind blocks * on dev (or NODEV for all) * are flushed out. * (from umount and update) */ bflush(dev) { regis0200,0200,0000, 0000,0200,0200,0000,0200,0000,0000,0200, 0200,0000,0000,0200,0000,0200,0200,0000, 0200,0000,0000,0200,0000,02ter struct buf *bp; loop: spl6(); for (bp = bfreelist.av_forw; bp != &bfreelist; bp = bp->av_forw) { if (bp->b_flags&B_DELW00,0200,0000, 0000,0200,0200,0000,0200,0000,0000,0201 }; RI && (dev == NODEV||dev==bp->b_dev)) { bp->b_flags =| B_ASYNC; notavail(bp); bwrite(bp); goto loop; } } spl0(); } /* * Pick up the device's error number and pass it to the user; * if there is an error but the number is 0 set a generaliz/* * Initialize the buffer I/O system by freeing * all buffers and setting all device buffer lists to empty. */ binit() { reed * code. Actually the latter is always true because devices * don't yet return specific errors. */ geterror(abp) struct bugister struct buf *bp; register struct devtab *dp; register int i; struct bdevsw *bdp; bfreelist.b_forw = bfreelist.b_back f *abp; { register struct buf *bp; bp = abp; if (bp->b_flags&B_ERROR) if ((u.u_error = bp->b_error)==0) u.u_error = EIO= bfreelist.av_forw = bfreelist.av_back = &bfreelist; for (i=0; ib_dev = -1; bp->b_a; } ddr = buffers[i]; bp->b_back = &bfreelist; bp->b_forw = bfreelist.b_forw; bfreelist.b_forw->b_back = bp; bfreelist.b_for €€€€€€€� putchar(0177); putchar(0177); } putchar(0); KL->xsr = s; } _partab#(w üÿCÃe 1Žß ´@µ ’Â%%óBŸµ Â%dÂ%lÂ%o Â%oÎÎ æß vÖ Â%sÄŽß ´•ûÃe# /* */ /* * Address and structure of the * KL-11 console device registers. */ #define KL 0177560 struct { int rsr; inÒwŠÿw †ÿNfß Ö N&ß vÖ Nfß Ö Îe0ß ´wLÿw HÿDß5€tÿüÄ Ãtÿ tÿvÿÄ% Î ß ´Îß ´Îß t rbr; int xsr; int xbr; }; /* * Scaled down version of C Library printf. * Only %s %l %d (==%l) %o are recognized. * Used ´ ß ´ßtÿwÿ)to print diagnostic information * directly on console tty. * Since it is not interrupt driven, * all system activities are prù)Hhù)etty much * suspended. * Printf should not be used for chit-chat. */ printf(fmt,x1,x2,x3,x4,x5,x6,x7,x8,x9,xa,xb,xc) char fmtù_printf"~printfxaxbxccsadxfmtx1[]; { register char *s; register *adx, c; adx = &x1; loop: while((c = *fmt++) != '%') { if(c == '\0') return; putchax2x3 x4 x5x6x7x8x9csv L3r(c); } c = *fmt++; if(c == 'd' || c == 'l' || c == 'o') printn(*adx, c=='o'? 8: 10); if(c == 's') { s = *adx; while(cL20001 L1r_putchar"´L10000@L5XL10001LL10002P_printn"vL6lL7hL20003 = *s++) putchar(c); } adx++; goto loop; } /* * Print an unsigned integer in base b. */ printn(n, b) { register a; ibcret ~printnvabn_ldiv L10˜_lrem ~putchar´rccf(a = ldiv(n, b)) printn(a, b); putchar(lrem(n, b) + '0'); } /* * Print a character on console. * Attempts to save and ressL12¼L11üL14òtore device * status. * If the switches are 0, all * printing is inhibited. */ putchar(c) { register rc, s; rc = c; whil€ ����‚…†���������€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€e((KL->xsr&0200) == 0) ; if(rc == 0) return; s = KL->xsr; KL->xsr = 0; KL->xbr = rc; if(rc == '\n') { putchar('\r');  play (page buffer) /to ascii spaces, set the cursor to be on column 0, line 23, /blank all graphics zones, and unblank the charatlput / \\ cmpb r0, $lf / \\ beq ctlput / \\ accept only cmpb r0, $bs / // ,,, beq ctlput / // ccter page. / /whenever the page buffer is referenced, "snow" will /be generated on the screen unless all such data transfers /ampb r0, $ff / // bne emldun /// ctlput: com r0 /neg byte in buf flags control character br put / --common char. buffer bufre synchronous with the line clock (start the vertical retrace). /the peak data rate from the emulator hardware is throttled by /a hardware delay of 500us for the interrupt thru vector 64. /thus, the driver buffer of 34. bytes covers the peak data /that ca ////////////////////////////////////// /// terak terminal emulator driver /// ////////////////////////////////////// / This n be received in 16.6 ms. however, since and /transfer blocks of spaces (80. and 1920. resp.), one entire /line clock Terak terminal emulator driver was borrowed from the / corresponding DEC RT-11 source (MACRO-11). / Slightly modified to backspaevent is dedicated to the or . /timing is critical: the lkint portion of driver, which runs as /a co-routine with emlice upon char. / Apologies for the assembly code. / addresses vtbase = 160000 esr = 177564 edb = 177566 vir = 177742 vcr = nt, must finish data transfer in < 1.2 ms. / .globl _emlint, _lkint _emlint: /vector from 164/166...data in edb cmp putpt177744 / control, status bits gbenbl = 200 belbit = 4000 syncbit = 4000 / ascii char. codes bel = 7 bs = 10 lf = 12 ff = 14 crr, (pc)+ /at end of buffer ??? endptr: bufend /must be relocate by ***boot*** blos emlsus /suspend by leaving data in edb mo = 15 space = 40 crs = 177 /emulator handler to accept characters from the hrdwr emulator /data buffer and place them into the v r0, -(sp) mov r1, -(sp) movb *$edb, r0 /get the byte bicb $!177, r0 ble emldun /ignore null and 200 + cmpb r0, $space page buffer in a manner /similar to a glass teletype. a cursor is displayed as ascii /code 177 (normally a solid block) placed iblo chrtst /test for specials cmpb r0, $177 /also, 177 is reserved for cursor beq emldun put: mov (pc)+, r1 /pick up buffernto the page buffer. / /driver will always clear bit 7 (selects page buf) and set bit 1 /(unblank lower character display zone)  pointer putptr: emlbuf - 1 /must be relocated by ***boot*** movb r0, (r1) /put character into buffer clrb -(r1) /maintain of the vcr, with each /character printed, only ascii codes 40 thru 176 are displayed. /ascii code 177 is reserved for driver to delimiter mov r1,putptr /put back pointer emldun: mov (sp)+, r1 mov (sp)+, r0 emlsus: rts pc / by not reading edb, done bit display the cursor. /all control codes are ignored except: , , and . /a will clear the entire character diis left * 0 chrtst: cmpb r0, $bel / b e l l ??? bne 1f inc belflg /turn on the beeper br emldun 1: cmpb r0, $cr /\\ beq c! ÊËÌÍÎÏÐÑÓÔÕÖרÙ$-1*200-120, r1 /next line, column zero 5: movb r0, (r1)+ /clear out new line movb r0, (r1)+ /the quadruple movb movb r0, (r1)+ /results in a transfer movb r0, (r1)+ /rate increase of 35% sob r2, 5b /and ()+ is 10% faster than -() bit $37*200, r1 /at line zero yet ??? bne 1b clr *$vir /reset index mov $vtbase+5600, r1 /reset cursor br xcskip /toss out ff compress buffer xlf: mov r0, -(sp) /set up for gear mov $25.*400, r0 /save-a-word mov *$vir, r2 /set vir image clrb r2 /always remor right now, all char zone off!!! mov (pc)+, r1 /pick up cursor address cursor: vtbase+5600 /address of page buffer movb (pc)ve scan lines add $400, r2 /bump index...scroll cmp r2, r0 /cmp w $25.*400...wrap around??? blo 1f /no clr r2 /yes 1: end: .byte 0 /\\ 16.666 ms - (1.08 (refresh)) .byte 0,0,0,0,0 .byte 0,0,0,0,0 .byte 0,0,0,0,0 .byte 0,0,0,0,0 .byte 0,0,0,+, (r1) /restore old contents * cursor oldcrs: space cmpb r2, $!lf /first = lf ? beq xlf cmpb r2, $!ff /or a ff ?? beq xff0,0 .byte 0,0,0,0,0 .byte 0 .byte 0 /// (max rate thru edb) => 33. req'd emlbuf: .byte !ff /initial form feed in buffer  xxfr: mov $80., r2 /figure the 80.'s-complement sub r1, r2 /out of column number bic $!177, r2 /=bytes to end of line xfr:_lkint: mov r0, -(sp) /line clock interrupt mov r1, -(sp) /rons as co-routine with mov r2, -(sp) /emlint clock service mov tstb -(r0) /end of buffer ??? bgt 2f /not end of buf, nor cntl char if gt 0 cmpb (r0), $!bs /bs? bne 4f /no cmp $80., $vcr, r1 /save-a-word bic $belbit, *r1 /clear bell bit asl (pc)+ /beep-in-progress ??? belflg: 0 beq 1f bis $belbit, *r1 r2 /at column 0? beq xfr /yes...next movb $space, -(r1) /blank out old char., dec. cursor pos. br xxfr /next 4: cmpb (r /set bell bit 1: mov (pc)+, r0 /point to start of buffer bufhdr: emlbuf /must be relocated by ***boot*** movb (r0)+, r2 /0), $!cr /cr? bne xcntrl /no br xcr /yes 2: movb (r0),(r1)+ /into the buffer with it sob r2, xfr /count bytes to end of anything to xfr ??? jeq done /buffer's empty! / note the use of "jeq"..."jump if equal". / Unix assembler feature...muline movb $!lf, (r0)+ /put a lf into buffer xcr: bic $177, r1 /move cursor to column zero br xxfr xff: mov $7, (sp) /when vcst change if porting bit $syncbit, *$esr /is clock latency o.k.??? jeq done /0-> too late !!! mov *r1, -(sp) /put copy of r is restored..... / ...blank all graphics zones, display all character zones mov r0, -(sp) /use r0 to hold a blank mov $spacvcr into stack bic $gbenbl+1, (sp) /turn off generator buffer inc (sp) /turn on at least bottom zone bic $gbenbl+7, *r1 /foe, r0 /(georgia overdrive for ff loop) mov $vtbase+6200+120, r1 /-> end of 26th line 1: mov $20., r2 /count 80. columns add " , r1 xcskip: mov (sp)+, r0 cmpb -(r0), -(r0) /skip first byte (lf/ff) /fall into xcntrl xcntrl: movb (r1), oldcrs /save old co== 0) return; if((ip->i_mode&IFMT) == IFCHR) { (*cdevsw[ip->i_addr[0].d_major].d_read)(ip->i_addr[0]); return; } do { ntents movb $crs, (r1) /light up the cursot mov (sp)+, *$vcr /restore vcr...unblank display mov r1, cursor /save cursor loc lbn = bn = lshift(u.u_offset, -9); on = u.u_offset[1] & 0777; n = min(512-on, u.u_count); if((ip->i_mode&IFMT) != IFBLK)ation mov bufhdr, r2 /point to buf cmpb (r0)+, (r2)+ /include this byte 1: movb -(r0), -(r2) /compress this buffer bne 1b  { dn = dpcmp(ip->i_size0&0377, ip->i_size1, u.u_offset[0], u.u_offset[1]); if(dn <= 0) return; n = min(n, dn);/note...when done, (r0)=0 mov r2, putptr tstb *$esr /is there data in edb ??? bmi done /done bit = 1 says empty bisb (r0), if ((bn = bmap(ip, lbn)) == 0) return; dn = ip->i_dev; } else dn = ip->i_addr[0]; bp = bread(dn, bn); iomove *$edb /read-modify-write the edb..... / .....will cause fresh interrupt thru 164 done: mov (sp)+, r2 mov (sp)+, r1 mov (sp(bp, on, n, B_READ); brelse(bp); } while(u.u_error==0 && u.u_count!=0); } /* * Write the file corresponding to * the inode)+, r0 rts pc  pointed at by the argument. * The actual write arguments are found * in the variables: * u_base core address for source * u_offset byte offset in file * u_count number of bytes to write */ writei(aip) struct inode *aip; { int *bp; int n, on; register dn, bn; register struct inode *ip; ip = aip; ip->i_flag =| IUPD; if((ip->i_mode&IFMT) == IFCHR) { (*cdevsw[ip->i_amov r2, *$vir /load the new index!!! asl r1 /adjust cursor to byte split bic $377*400, r1 /remove line bits bis r2, r1 /set to index add $23.*400, r1 /always set cursor on line 23 cmp r1, r0 /wrap around??? blo 3f sub r0, r1 /adjust 3: asr r1 # #include "../param.h" #include "../inode.h" #include "../user.h" #include "../buf.h" #include "../conf.h" #include "../systm.h bis $vtbase, r1 /the new cursor !!! mov r1, -(sp) /preserve cursor bic $177, r1 /set to column zero mov $20., r2 /count " /* * Read the file corresponding to * the inode pointed at by the argument. * The actual read arguments are found * in theighty columns mov $space, r0 /stuff spaces 5: movb r0, (r1)+ /clear out new line movb r0, (r1)+ /the quadruple movb movb e variables: * u_base core address for destination * u_offset byte offset in file * u_count number of bytes to read */ rear0, (r1)+ /results in a transfer movb r0, (r1)+ /rate increase of 35% sob r2, 5b /and ()+ is 10% faster than -() mov (sp)+di(aip) struct inode *aip; { int *bp; int lbn, bn, on; register dn, n; register struct inode *ip; ip = aip; if(u.u_count # turn; dn = ip->i_dev; } else dn = ip->i_addr[0]; if(n == 512) bp = getblk(dn, bn); else bp = bread(dn, bn); isc(*cp++) < 0) return; } omove(bp, on, n, B_WRITE); if(u.u_error != 0) brelse(bp); else if ((u.u_offset[1]&0777)==0) bawrite(bp); else bdwriGrdwri.oFshlib1EshlowcoreDshrshsBshs2Asig.c@sig.ote(bp); if(dpcmp(ip->i_size0&0377, ip->i_size1, u.u_offset[0], u.u_offset[1]) < 0 && (ip->i_mode&(IFBLK&IFCHR)) == 0) ?slp.c>slp.o=subr.c<subr.o;sys1.c:sys1.i9sys1.o8sys2.c{ ip->i_size0 = u.u_offset[0]; ip->i_size1 = u.u_offset[1]; } ip->i_flag =| IUPD; } while(u.u_error==0 && u.u_count!=7sys2.o6sys3.c5sys3.o4sys4.c3sys4.o2sysent.c1sysent.o0trap.c0); } /* * Return the logical maximum * of the 2 arguments. */ max(a, b) char *a, *b; { if(a > b) return(a); return(b);/trap.o.tty.c-tty.oCrun } /* * Return the logical minimum * of the 2 arguments. */ min(a, b) char *a, *b; { if(a < b) return(a); return(b); } °w üÿÆåB÷ 0_€ÀEÿŸÀ% ¦�œWp ù Ö dÎ÷ÿæBß Ö 5ôÿ5öÿÀòÿÀEþ5òÿÎâÿæNíòÿß ^Ö € /* * Move 'an' bytes at byte location * &bp->b_addr[o] to/from (flag) the * user/kernel area starting at u.base. * Update ÀEÿŸÀ%`#ÎÄÿæ¾ÿ¦ €œ &ÎEÿß Æe1æß ^Ö Nöÿ¦ß Ö 5ôÿ"„„Nôÿ&ß Ö 5øÿÎæfòÿføÿß xÆeNøÿall the arguments by the number * of bytes moved. * * There are 2 algorithms, * if source address, dest address and count *ß ÷‹?ÿ÷ Bÿœwüþw øþÆåBÊÕ€ÀEÿŸÀ% ¦�œWp ù Ö _@÷ ÿ_@Î÷ÿæBß Ö ÀîþÀEþ5ôÿÎÞþæNíôÿß ^Ö  are all even in a user copy, * then the machine language copyin/copyout * is called. * If not, its done byte-by-byte with *5öÿ€ÀEÿŸÀ%` Î¦ß Ö X„„õ%öÿÎ&ß Î&ß Ö 5øÿ föÿfôÿføÿß xÆe÷‹cþNøÿß ÷5ÿ^þNøÿß  cpass and passc. */ iomove(bp, o, an, flag) struct buf *bp; { register char *cp; register int n, t; n = an; cp = bp->b_adNøÿß ÎFþæ@þ¦ €œ &ÎEÿß ÆeÀ ò5 ò�þ òþ ÊÕ÷‹ÿý÷ þ�w¼ýw ¸ýu-†@w¨ý@ûw žýu-ƒ@wdr + o; if(((n | cp | u.u_base)&01)==0) { if (flag==B_WRITE) cp = copyin(u.u_base, cp, n); else cp = copyout(cp, u.u_Žý@ûw „ýC@DmÀQÀ]ªýÀ5#õ Î&æ–ýß ÎæŠý&ß –%÷•jqýw6ý÷`pýÎæBß Ö ÷àbýóõ Àà À ì÷ ddr[0].d_major].d_write)(ip->i_addr[0]); return; } if (u.u_count == 0) return; do { bn = lshift(u.u_offset, -9); on base, n); if (cp) { u.u_error = EFAULT; return; } u.u_base =+ n; dpadd(u.u_offset, n); u.u_count =- n; return;= u.u_offset[1] & 0777; n = min(512-on, u.u_count); if((ip->i_mode&IFMT) != IFBLK) { if ((bn = bmap(ip, bn)) == 0) re } if (flag==B_WRITE) { while(n--) { if ((t = cpass()) < 0) return; *cp++ = t; } } else while (n--) if(pas$ L15¬_getblk L20001´L17àL18úL19ò_bawrite _bdwrite L210_max"D~maxýè”�öÀà À â•ß À öÛhHDabL23XL22T~min^abL25rL24n~iomovexanxˆ¨bpflag cpnotL27àL28®_copyin L20003ºÈÙhH_copyout L30ÊL26Æ_dpadd L35úL32æ_cpass _passc ˆØ¨È(8xÙÙÙ¨ÈÙøcc -c -O *.c mv conf.o ../conf.o as emul.s; mv a.out emul.o ar r ../lib1 alloc.o iget.o rdwri.o slp.o subr.o trap.o sig.o ar r )8_inode Ü_u &_buf X_bfreeli _bdevsw _nblkdev _cdevsw../lib1 clock.o sysent.o fio.o malloc.o nami.o sys1.o sys2.o sys3.o sys4.o ar r ../lib1 bio.o mem.o tty.o partab.o emul.o  _nchrdev _canonb _swapmap _rootdir _lbolt _time _tout _callout _mount _mpid _runrun _curpri _rootdev _swapdev _updlock _regloc _readi"~readibnôÿbpøÿdniponòÿnaiplbnöÿcsv L1L58_lshift _min"^L6as low.s;mv a.out ../low.o cc -c -O conf.c;mv conf.o ../conf.o Â_dpcmp _bmap L7Æ_bread _iomove"x_brelse cret _writei"~writeibnbpøÿdniponôÿnöÿaipL98L8@L12BL13–L14š% sual sequence is: * if(issig()) * psig(); */ psig() { register n, p; register *rp; rp = u.u_procp; n = rp->p_sig; rp->p_sig = 0; if((p=u.u_signal[n]) != 0) { u.u_error = 0; if(n != SIGINS) u.u_signal[n] = 0; n = u.u_ar0[R6] - 4; suword(n+2, u.u_ar0[RPS]); suword(n, u.u_ar0[R7]); u.u_ar0[R6] = n; u.u_ar0[R7] = p; return; } switch(n) { case SIGQIT: # #include "../param.h" #include "../systm.h" #include "../user.h" #include "../proc.h" #include "../inode.h" #include "../reg.hcase SIGINS: case SIGTRC: case SIGIOT: case SIGEMT: case SIGFPT: case SIGBUS: case SIGSEG: case SIGSYS: u.u_arg[0] = n;as low.s;mv a.out ../low.o cc -c -O conf.c;mv conf.o ../conf.o " /* * Structure to access an array of integers. */ struct { int inta[]; }; /* * Send the specified signal to * all processes with 'pgrp' as * process group. * Called by tty.c for quits and * interrupts. */ signal(apgrp, sig) { register struct proc *p; int pgrp; if ((pgrp = apgrp)==0) return; for(p = &proc[0]; p < &proc[NPROC]; p++) if(p->p_pgrp == pgrp) psignal(p, sig); } /* * Send the specified signal to * the specified process. */ psignal(p, sig) int *p; char *sig; { register if $1x != x goto link cc -c -O *.c echo Done compiling... mv conf.o ../conf.o as low.s;mv a.out ../low.o as mch.s;mv a.out mch.o*rp; if(sig >= NSIG) return; rp = p; if(rp->p_sig != SIGKIL) rp->p_sig = sig; if(rp->p_stat == SSLEEP && rp->p_pri>0)  as qxeml.s; mv a.out ../qxeml.o echo Done assembling... : link echo Begin linking sys... ld -a -x -r *.o mv a.out syso echo Don setrun(rp); } /* * Returns true if the current * process has a signal to process. * This is asked at least once * each time linking sys... ar r ../lib1 syso echo Done archiving... rm syso e a process enters the * system. * A signal does not do anything * directly to a process; it sets * a flag that asks the process to * do something to itself. */ issig() { register n; register struct proc *p; p = u.u_procp; if(n = p->p_sig) { icc -O -c main.c bio.c sys1.c f((u.u_signal[n]&1) == 0) return(n); } return(0); } /* * Perform the action specified by * the current signal. * The u& rror==0); } _signal"~signalpgrpøÿpsigapgrpcsv L10L20001L4&_psignal"4cret ~psignal4rppsigL6dL7R_setrun _issig"h~issighnpL10ˆL9„_psig"ŒL10001²L25L15~psigŒrpnpL13öL14¸_suword L12*_core"._exit ~core.ipsL28²`w üÿæ uøÿÄt-øÿN&ß 4Ö ÄeÄ%„ñ‚wÌÿw Èÿõ%ƒDô¥ t�Ì¥ô‹ß w˜ÿw ”ÿÃÌÿÆ_namei L29ZL20005¦_maknode _access L32š_itrunc _writei _iput L10002¬L27Äœ À ð5âwxÿ üw pÿ¨ÿ„œ2ŠÀ â(7Š�ÿÄ%À 0 âÀZúÿÄeüÿ&Îeß Ö À>&ß Ö À.0úÿÀ&¨ðÀå ‚À x²7¼ÿ÷ À Äe€ÀúÿtQ7¢ÿ÷ ÖþwÒþw Îþ7Šÿ÷ÆÿÎß  ÷‹ëþ,릧 &΀æß Ö À ó5` if(core()) n =+ 0200; } u.u_arg[0] = (u.u_ar0[R0]<<8) | n; exit(); } /* * Create a core image on the file "core" * I÷­ÄþÀþÎß 7 ¾þ7 ¼þ÷°þ÷„¬þÎß Îß ÷‹“þ wTþÀûcore‰f you are looking for protection glitches, * there are probably a wealth of them here * when this occurs to a suid command. *Ù‰HÙ‰ùøÙ‰ùø * It writes USIZE block of the * user.h area followed by the entire * data+stack segments. */ core() { register s, *ip; ùøùXùXùùùùu.u_error = 0; u.u_dirp = "core"; ip = namei(1); if(ip == NULL) { if(u.u_error) return(0); ip = maknode(0666); if (iù‰Ù‰ùùØùùù8ùùøùùHXùp==NULL) return(0); } if(!access(ip, IWRITE) && (ip->i_mode&IFMT) == 0 && u.u_uid == u.u_ruid) { itrunc(ip); u.Ù_canonb _swapmap _rootdir _lbolt _time _tout _callout _mouu_offset[0] = 0; u.u_offset[1] = 0; u.u_base = &u; u.u_count = (USIZE+UCORE)*64; writei(ip); } iput(ip); return(u.u_ent _mpid _runrun _curpri _rootdev _swapdev _updlock _regloc _u &_proc „_inode Ü' if pri>0 signals will be processed. * Callers of this routine must be prepared for * premature return, and check that the reasC; if(runrun && swapflag == 0) { do { rp++; if(rp >= &proc[NPROC]) rp = &proc[0]; if(rp->p_stat==SRUN) { p =on for * sleeping has gone away. */ sleep(chan, pri) { register *rp, s; #ifdef QX s = getps(); #endif #ifndef QX s = PS->i rp; n = rp->p_pri; runrun = 0; break; } } while(--i); } else { if(rp->p_stat == SRUN) { p = rp; n = rnteg; #endif rp = u.u_procp; spl6(); rp->p_stat = SSLEEP; rp->p_wchan = chan; rp->p_pri = pri; spl0(); if(pri > 0) { ifp->p_pri; } } /* * If no process is runnable, idle. */ if(p == NULL) { p = rp; idle(); goto loop; } curpri = n;(issig()) goto psig; swtch(); if(issig()) goto psig; } else swtch(); #ifdef QX putps(s); #endif #ifndef QX PS->in n = rp = p; /* if(hp > &hbuf[36]) hp = hbuf; *hp++ = n; *hp++ = u.u_procp; *hp++ = time[1]; */ if(n != u.u_procp && swateg = s; #endif return; /* * If priority was low (>0) and * there has been a signal, * execute non-local goto to * thpflag == 0) { /* * Save stack of current user and * and use system stack. */ swapflag++; savu(u.u_ssav); retu(u.u_re qsav location. * (see trap1/trap.c) */ psig: rp->p_stat = SRUN; retu(u.u_qsav); } /* * Wake up all processes sleeping sav); u.u_procp->p_flag =& ~SLOAD; if(u.u_procp->p_stat != SZOMB) swap(u.u_procp, B_WRITE); swap(rp, B_READ); rp->p_fon chan. */ wakeup(chan) { register struct proc *p; register c, i; c = chan; p = &proc[0]; i = NPROC; do { if(p->p_wchlag =| SLOAD; retu(u.u_ssav); swapflag--; } /* * The value returned here has many subtle implications. * See the newpran == c) { setrun(p); } p++; } while(--i); } /* * Set the process running; * arrange for it to be swapped in if necesoc comments. */ return(1); } /* * Create a new process-- the internal version of * sys fork. * It returns 1 in the new prsary. */ setrun(p) { register struct proc *rp; rp = p; rp->p_wchan = 0; rp->p_stat = SRUN; if(rp->p_pri < 0) rp->p_pri ocess. * How this happens is rather hard to understand. * The essential fact is that the new process is created * in such a w= PSLEP; if(rp->p_pri < curpri) runrun++; } /* * This routine is called to reschedule the CPU. * if the calling process isay that appears to have started executing * in the same call to newproc as the parent; * but in fact the code that runs is tha# #include "../param.h" #include "../proc.h" #include "../user.h" #include "../systm.h" #include "../file.h" #include "../inode. not in RUN state, * arrangements for it to restart must have * been made elsewhere, usually by calling via sleep. */ /* inth" #include "../buf.h" /* * Give up the processor till a wakeup occurs * on chan, at which time the process * enters the sch hbuf[40]; int *hp hbuf; */ int swapflag; swtch() { static struct proc *p; register i, n; register struct proc *rp; if(p =eduling queue at priority pri. * The most important effect of pri is that when * pri<=0 a signal cannot disturb the sleep; * = NULL) p = &proc[0]; loop: rp = p; p = NULL; n = 128; /* * Search for highest-priority runnable process */ i = NPRO( t of swtch. * The subtle implication of the returned value of swtch * (see above) is that this is the value that newproc's * nt * of the new process so that when it is actually * created (by copying) it will look right. */ rpp = p; u.u_procp = caller in the new process sees. */ newproc() { int a1, a2; struct proc *p, *up; register struct proc *rpp; register *rip, nrpp; rip = up; rip->p_stat = SIDL; savu(u.u_ssav); swap(rpp, B_WRITE); /* swap out child */ rpp->p_flag =| SSWAP; rip->p_s; p = NULL; /* * First, just locate a slot for a process * and copy the useful info from this process into it. * The patat = SRUN; u.u_procp = rip; return(0); /* return to parent */ } nic "cannot happen" because fork has already * checked for the existence of a slot. */ retry: if(++mpid >= NPROC) mpid = 1; for(rpp = &proc[0]; rpp < &proc[NPROC]; rpp++) { if(rpp->p_stat == NULL && p==NULL) p = rpp; if (rpp->p_pid==mpid)  goto retry; } if ((rpp = p)==NULL) panic(); /* * make proc entry for new proc */ rip = u.u_procp; up = rip; rpp->T8w üÿ÷ øÿÄ.÷ îÿÌ•tt�÷ Úÿõ ÷ ÐÿÀ ÷ v÷ ÄÿÀ Ì•ÎÚß w°ÿ÷ ZÎß øw  ÿCÄÂô ÷øùúûüýþß ‚Äe‰~w~ÿw zÿD4 Ì•ô‹ô•Zô­^ÿ·ŠVÿwRÿw Nÿ÷ ž÷–Â’7 ŽÃ€Ä÷‹.ÿ÷ (ÿÂeÂ%„‚ÂÊ¥·bƒœ7Šÿ Ä ìÊ¥·Hƒœ÷ @·:÷ âþÏ÷�ÜþÂ,ƒÃ-ÿ)÷ Ìþ&· ÆþÎÞß Îß ÀîþðÃÿ¥äþ æÜþß Ö Î¦ß Ö òÓÎÞß ÷ ~þÀwvþw rþÆå5 ôÿ· fþ÷%`þ÷XþÄÌ‹õ ôÿ5ôÿô-Bþ êÄeÄ%„ð‚Dôÿ÷ *þÃbþõòÿÌ•ô“ôœôôœôþ ô êĴŠÃ%Èù‚À,þ°ŠDôÿ7þCòÿË•ÎÞß  &ß Ö ôÕË•÷îý w¬ý¹ÉÙp_stat = SRUN; rpp->p_flag = SLOAD; rpp->p_uid = rip->p_uid; rpp->p_pgrp = rip->p_pgrp; rpp->p_nice = rip->p_nice; rpp->p_pé  Hix¹i¹id = mpid; rpp->p_ppid = rip->p_pid; /* * make duplicate entries * where needed */ for(rip = &u.u_ofile[0]; rip < &u.ɹi¹¹i¹u_ofile[NOFILE];) if((rpp = *rip++) != NULL) rpp->f_count++; u.u_cdir->i_count++; /* * Partially simulate the environmeIÉiihHˆˆHii¹©)  bdwrite(bp); } else brelse(bp); return(nb); } /* * Pass back c to the user at his location u_base; * update u_base, u_count, and u_offset. Return -1 * on the last character of the user's read. * u_base is in the user address space unless u_s# #include "../param.h" #include "../conf.h" #include "../inode.h" #include "../user.h" #include "../buf.h" #include "../systm.hegflg is set. */ passc(c) char c; { if(subyte(u.u_base, c) < 0) { u.u_error = EFAULT; return(-1); } u.u_count--; if(++©©©y©" /* * Bmap defines the structure of file system storage * by returning the physical block number on a device given the * inhˆi_proc „_u &_canonb _swapmap _rootdir _lbolt ode and the logical block number in a file. */ bmap(ip, bn) struct inode *ip; int bn; { register *bp, *bap, nb; int *nbp, d,_time _tout _callout _mount _mpid _runrun _curpri _rootdev _swapdev _updlock _regloc i; d = ip->i_dev; if(bn & 0174000) { u.u_error = EFBIG; return(0); } if((ip->i_mode&ILARG) == 0) { /* * small f _file �_inode Ü_buf X_bfreeli _sleep"~sleepchanrpspricsvile algorithm */ if((bn & ~7) != 0) { /* * convert small to large */ if ((bp = alloc(d)) == NULL) retu _getps _spl6 _spl0 L2P_issig L3@_swtch"®L4T_retu L1Lrn(NULL); bap = bp->b_addr; for(i=0; i<8; i++) { *bap++ = ip->i_addr[i]; ip->i_addr[i] = 0; } ip->i_addr[0] cret _putps _wakeup"\~wakeup\chancipL8lL9x_setrun= bp->b_blkno; bdwrite(bp); ip->i_mode =| ILARG; goto large; } nb = ip->i_addr[bn]; if(nb == 0 && (bp = alloc(d))"‚~setrun‚rppL11žL10ª_swapfla ~swtch®L14Trpin != NULL) { bdwrite(bp); nb = bp->b_blkno; ip->i_addr[bn] = nb; ip->i_flag =| IUPD; } return(nb); } /* * lapTL16¾L17L20ÚL21èL18üL23L25 _idle L26‚rge file algorithm */ large: i = bn>>8; if((nb=ip->i_addr[i]) == 0) { ip->i_flag =| IUPD; if ((bp = alloc(d)) == NU_savu L27f_swap _newproc"Š~newprocŠupòÿnpôÿa1øÿa2öÿrppLL) return(NULL); ip->i_addr[i] = bp->b_blkno; } else bp = bread(d, nb); bap = bp->b_addr; /* * normal indirect fetripL29–L30¨L20001¬L34ºL35Ö_panic L20003L36ch */ i = bn & 0377; if((nb=bap[i]) == 0 && (nbp = alloc(d)) != NULL) { nb = nbp->b_blkno; bap[i] = nb; bdwrite(nbp);* *a, *b, c; a = from; b = to; c = count; do *b++ = *a++; while(--c); } d _runrun _curpri _rootdev _swapdev _updlock _regloc _bmap"~bmapbnbpnbipdöÿiôÿbapnbpøÿcsv L2"L20005¶L9ŒL4¼_alloc L20004J_bdwrite L11 L12úL1¸cret L10öL13_bread L14Àw üÿÆå@5öÿõ5ø÷•J@ð5/õ5øÿCNöÿß :5 ôÿ@ôÿÀ @m@ôÿÀ @m0 µ ôÿõ%ôÿ^_brelse _passc"f~passcfc_subyte L17ŠL20006„L16¤L18˜_cpass"¨ì@0ß @ðU@tøÿ5ôÿÀ @m4ýÕNöÿß " wDÿ@À @mNöÿß ß @À @m°~cpass¨cL20ÀL20009²L19äL20011¸_fubyte L22Ú_nodev"è~nodevè_nulldevýÕ€ß@ôÿÀ @m0Žföÿß Ö @ÀEÿ5ôÿÀ À`Nöÿß 5øÿ@ôÿÀ À`ˆNøÿß ß Ìß Èw –þ@�"ö~nulldevö_bcopy"þ~bcopyþtofromabccountL28u.u_offset[1] == 0) u.u_offset[0]++; u.u_base++; return(u.u_count == 0? -1: 0); } /* * Pick up and return the next charactæÊþß Ö À ÷•j³þÀÿÿ ÷ ²þ· ²þ· ªþ· ¢þ÷  þñ wXþw Tþ÷ �þÀÿÿ÷•jyþùÎzþß ö÷ pþ· pþ· hþ· `þÀEÿwþw þ÷•er from the user's * write call at location u_base; * update u_base, u_count, and u_offset. Return -1 * when u_count is exhaEþw þw þwþw þýDCB‚~wêýYhusted. u_base is in the user's * address space unless u_segflg is set. */ cpass() { register c; if(u.u_count == 0) returˆhÉhn(-1); if((c=fubyte(u.u_base)) < 0) { u.u_error = EFAULT; return(-1); } u.u_count--; if(++u.u_offset[1] == 0) u.u_offsˆøhˆet[0]++; u.u_base++; return(c&0377); } /* * Routine which sets a user error; placed in * illegal entries in the bdevsw and ˆYXYYYYYYÉYYYYYYcdevsw tables. */ nodev() { u.u_error = ENODEV; } /* * Null routine; placed in insignificant entries * in the bdevsw and cYÉYÉÉÉ_bdevsw _nblkdev _cdevsw _nchrdev _inode Ü_udevsw tables. */ nulldev() { } /* * copy count words from from to to. */ bcopy(from, to, count) int *from, *to; { register  &_buf X_bfreeli _canonb _swapmap _rootdir _lbolt _time _tout _callout _mount _mpi+ |(IEXEC>>6))) == 0) { u.u_error = EACCES; goto bad; } /* * pack up arguments into * allocated disk buffer */ cp = = ip->i_uid; } /* * clear sigs, regs and return */ c = ip; for(ip = &u.u_signal[0]; ip < &u.u_signal[NSIG]; ip++)  bp->b_addr; na = 0; nc = 0; while(ap = fuword(u.u_arg[1])) { na++; if(ap == -1) goto bad; u.u_arg[1] =+ 2; for(;;if((*ip & 1) == 0) *ip = 0; for(cp = ®loc[0]; cp < ®loc[6];) u.u_ar0[*cp++] = 0; u.u_ar0[R7] = TOPSYS; for(ip = &u) { c = fubyte(ap++); if(c == -1) goto bad; *cp++ = c; nc++; if(nc > 510) { u.u_error = E2BIG; goto b.u_fsav[0]; ip < &u.u_fsav[25];) *ip++ = 0; ip = c; bad: iput(ip); brelse(bp); } /* * exit system call: * pass back calad; } if(c == 0) break; } } if((nc&1) != 0) { *cp++ = 0; nc++; } /* * read in first 8 bytes * of file fler's r0 */ rexit() { u.u_arg[0] = u.u_ar0[R0] << 8; exit(); } /* * Release resources. * Save u. area for parent to look or segment * sizes: * w0 = 407 * w1 = text size * w2 = data size * w3 = bss size */ u.u_base = &u.u_arg[0]; u.u_cat. * Enter zombie state. * Wake up parent and init processes, * and dispose of children. */ exit() { register int *q, a; ount = 8; u.u_offset[1] = 0; u.u_offset[0] = 0; readi(ip); if(u.u_error) goto bad; if(u.u_arg[0] == 0407) { u.u_arg[2] register struct proc *p; p = u.u_procp; p->p_clktim = 0; for(q = &u.u_signal[0]; q < &u.u_signal[NSIG];) *q++ = 1; for(q =+ u.u_arg[1]; } else { u.u_error = ENOEXEC; goto bad; } /* * find text and data sizes * try them out for possible = &u.u_ofile[0]; q < &u.u_ofile[NOFILE]; q++) if(a = *q) { *q = NULL; closef(a); } iput(u.u_cdir); #ifdef VSWAP a =  * exceed of max sizes */ ds = ((u.u_arg[2]+u.u_arg[3]+63)>>6) & 01777; if(ds + SSIZE > UCORE) goto bad; /* * allocatmalloc(swapmap, 1); if (a == NULL) panic(); p = getblk(swapdev, a); #endif #ifndef VSWAP p = getblk(swapdev, p->p_pid*SWPSIe and clear core * at this point, committed * to the new image */ cp = TOPSYS; while(cp < TOPUSR) *cp++ = 0; /* *Z + SWPLO); #endif bcopy(&u, p->b_addr, 256); bwrite(p); q = u.u_procp; #ifdef VSWAP q->p_addr = a; #endif q->p_stat = SZOM# #include "../param.h" #include "../systm.h" #include "../user.h" #include "../proc.h" #include "../buf.h" #include "../reg.h"  read in data segment */ u.u_base = TOPSYS; u.u_offset[1] = 020; u.u_count = u.u_arg[2]; u.u_dsize = ds; readi(ip); /*#include "../inode.h" /* * exec system call. */ exec() { int ap, na, nc, *bp; int ds; register c, *ip; register char *cp * initialize stack segment */ u.u_ssize = SSIZE; cp = bp->b_addr; ap = TOPUSR - nc - na*2 - 4; u.u_ar0[R6] = ap; suwo; /* * pick up file names * and check various modes * for execute permission */ ip = namei(0); if(ip == NULL) retrd(ap, na); c = TOPUSR - nc; while(na--) { suword(ap=+2, c); do subyte(c++, *cp); while(*cp++); } suword(ap+2, -1);urn; bp = getblk(NODEV); if(access(ip, IEXEC)) goto bad; if((ip->i_mode & IFMT) != 0 || (ip->i_mode & (IEXEC|(IEXEC>>3) /* * set SUID/SGID protections */ if(ip->i_mode&ISUID) if(u.u_uid != 0) { u.u_uid = ip->i_uid; u.u_procp->p_uid, C]; p++) if(q->p_pid == p->p_ppid) { p->p_ppid = 0; } runrun++; swtch(); /* no return */ } q->p_ppid = 0; goto T); goto loop; } u.u_error = ECHILD; } /* * fork system call. */ fork() { register struct proc *p1, *p2; p1 = u.u_procloop; } /* * Wait system call. * Search for a terminated (zombie) child, * finally lay it to rest, and collect its status. p; for(p2 = &proc[0]; p2 < &proc[NPROC]; p2++) if(p2->p_stat == NULL) goto found; u.u_error = EAGAIN; goto out; found: * Look also for stopped (traced) children, * and pass back status from them. */ wait() { register f, *bp; register struct pr if(newproc()) { u.u_ar0[R0] = p1->p_pid; u.u_cstime[0] = 0; u.u_cstime[1] = 0; u.u_stime = 0; u.u_cutime[0] = 0; u.oc *p; f = 0; loop: for(p = &proc[0]; p < &proc[NPROC]; p++) if(p->p_ppid == u.u_procp->p_pid) { f++; if(p->p_stat == Su_cutime[1] = 0; u.u_utime = 0; return; } u.u_ar0[R0] = p2->p_pid; out: u.u_ar0[R7] =+ 2; } /* * break system call. *ZOMB) { u.u_ar0[R0] = p->p_pid; #ifdef VSWAP bp = bread(swapdev, f = p->p_addr); mfree(swapmap, 1, f); #endif #ifndef V -- bad planning: "break" is a dirty word in C. */ sbreak() { register a, n, d; /* * set n to new data size * set d to new-old * set n to new total size */ n = (((u.u_arg[0]-TOPSYS+63)>>6) & 01777); if(n < 0) n = 0; d = n - u.u_dsize; n =+ USIZE+u.u_ssize; if(n > UCORE) { u.u_error = E2BIG; return; } u.u_dsize =+ d; }  struct { char lobyte; char hibyte; }; struct { int integ; }; SWAP bp = bread(swapdev, p->p_pid*SWPSIZ + SWPLO); #endif p->p_stat = NULL; p->p_pid = 0; p->p_ppid = 0; p->p_sig char canonb[ 256 ]; int swapmap[ 26 ]; int *rootdir; int lbolt; int time[2]; int tout[2]; struc = 0; p->p_pgrp = 0; p->p_flag = 0; p = bp->b_addr; u.u_cstime[0] =+ p->u_cstime[0]; dpadd(u.u_cstime, p->u_cstimt callo { int c_time; int c_arg; int (*c_func)(); } callout[ 4 ]; struct mount { int m_dev; int *m_bufp; int *e[1]); dpadd(u.u_cstime, p->u_stime); u.u_cutime[0] =+ p->u_cutime[0]; dpadd(u.u_cutime, p->u_cutime[1]); dpadd(u.u_m_inodp; } mount[ 4 ]; int mpid; char runrun; char curpri; int rootdev; int swapdev; int updlock; char regloB; loop: for(p = &proc[0]; p < &proc[NPROC]; p++) if(q->p_ppid == p->p_pid) { wakeup(p); for(p = &proc[0]; p < &proc[NPROcutime, p->u_utime); u.u_ar0[R1] = p->u_arg[0]; brelse(bp); return; } } if(f) { runrun++; sleep(u.u_procp, PWAI- actf; struct buf *d_actl; }; struct buf bfreelist; struct inode { char i_flag; char i_coun; do subyte(c++, *cp); while(*cp++); } suword(ap+2, -1); if(ip->i_mode& 04000 ) if(u.u_uid != 0) { u.u_ut; int i_dev; int i_number; int i_mode; char i_nlink; char i_uid; char i_gid; char i_size0; char *i_size1; iid = ip->i_uid; u.u_procp->p_uid = ip->i_uid; } c = ip; for(ip = &u.u_signal[0]; ip < &u.u_signal[ 20 ]; ip++) ic[]; struct user { int u_rsav[2]; int u_fsav[25]; char u_segflg; char u_error; char u_uid; char u_gint i_addr[8]; } inode[ 50 ]; exec() { int ap, na, nc, *bp; int ds; register c, *ip; register chad; char u_ruid; char u_rgid; int u_procp; char *u_base; char *u_count; char *u_offset[2]; int *u_cdir; r *cp; ip = namei(0); if(ip == 0 ) return; bp = getblk( (-1) ); if(access(ip, 0100 )) goto bad; if((ip->i_ char u_dbuf[ 14 ]; char *u_dirp; struct { int u_ino; char u_name[ 14 ]; } u_dent; int *u_pdir; int u_uimode & 060000 ) != 0 || (ip->i_mode & ( 0100 |( 0100 >>3)|( 0100 >>6))) == 0) { u.u_error = 13 ; goto bad; } sa[16]; int u_uisd[16]; int u_ofile[ 15 ]; int u_arg[5]; int u_tsize; int u_dsize; int u_ssize; int u_sep cp = bp->b_addr; na = 0; nc = 0; while(ap = fuword(u.u_arg[1])) { na++; if(ap == -1) goto bad; u.u_arg[1] =+ ; int u_qsav[2]; int u_ssav[2]; int u_signal[ 20 ]; int u_utime; int u_stime; int u_cutime[2]; int u_csti2; for(;;) { c = fubyte(ap++); if(c == -1) goto bad; *cp++ = c; nc++; if(nc > 510) { u.u_error = 7 ; me[2]; int *u_ar0; int u_prof[4]; char u_intflg; int u_ttyp; int u_ttyd; } u;  goto bad; } if(c == 0) break; } } if((nc&1) != 0) { *cp++ = 0; nc++; } u.u_base = &u.u_arg[0 struct proc { char p_stat; char p_flag; char p_pri; char p_sig; char p_uid; char p_time; char p_cpu;]; u.u_count = 8; u.u_offset[1] = 0; u.u_offset[0] = 0; readi(ip); if(u.u_error) goto bad; if(u.u_arg[0] == 0407) { u. char p_nice; int p_pgrp; int p_pid; int p_ppid; int p_wchan; int p_addr; int p_clktim; int p_size; } pru_arg[2] =+ u.u_arg[1]; } else { u.u_error = 8 ; goto bad; } ds = ((u.u_arg[2]+u.u_arg[3]+63)>>6) & 01777; if(oc[ 13 ]; struct buf { int b_flags; struct buf *b_forw; struct buf *b_back; struct buf *av_forw; ds + 20 > (16*32) ) goto bad; cp = 12*2048 ; while(cp < 28*2048 ) *cp++ = 0; u.u_base = 12*204 struct buf *av_back; int b_dev; int b_wcount; char *b_addr; char *b_blkno; char b_error; char *b_resid; } 8 ; u.u_offset[1] = 020; u.u_count = u.u_arg[2]; u.u_dsize = ds; readi(ip); u.u_ssize = 20 ; cp = bp->b_addr; abuf[ 4 ]; struct devtab { char d_active; char d_errcnt; struct buf *b_forw; struct buf *b_back; struct buf *d_p = 28*2048 - nc - na*2 - 4; u.u_ar0[ (-3) ] = ap; suword(ap, na); c = 28*2048 - nc; while(na--) { suword(ap=+2, c).  { *q = 0 ; closef(a); } iput(u.u_cdir); mfree(swapmap, p->p_size, p->p_addr); a = malloc(swapmap, 1); if (a ==  return; } u.u_ar0[ (0) ] = p2->p_pid; out: u.u_ar0[ (1) ] =+ 2; } sbreak() { register a, n, d; n = (((u.u 0 ) panic(); p = getblk(swapdev, a); bcopy(&u, p->b_addr, 256); bwrite(p); q = u.u_procp; q->p_addr = a; q->p_sta_arg[0]- 12*2048 +63)>>6) & 01777); if(n < 0) n = 0; d = n - u.u_dsize; n =+ 16 +u.u_ssize; if(n > (16*32) ) { u.t = 5 ; loop: for(p = &proc[0]; p < &proc[ 13 ]; p++) if(q->p_ppid == p->p_pid) { wakeup(p); for(p = &proc[0]; p <u_error = 7 ; return; } u.u_dsize =+ d; }  &proc[ 13 ]; p++) if(q->p_pid == p->p_ppid) { p->p_ppid = 0; } runrun++; swtch(); } q->p_ppid = 0; goto loop; } wait() { register f, *bp; register struct proc *p; f = 0; loop: for(p = &proc[0]; p < &proc[ 13 ]; p++) f((*ip & 1) == 0) *ip = 0; for(cp = ®loc[0]; cp < ®loc[6];) u.u_ar0[*cp++] = 0; u.u_ar0[ (1) ] = 12*2048 ; for(if(p->p_ppid == u.u_procp->p_pid) { f++; if(p->p_stat == 5 ) { u.u_ar0[ (0) ] = p->p_pid; bp = bread(swapdev, f ip = &u.u_fsav[0]; ip < &u.u_fsav[25];) *ip++ = 0; ip = c; bad: iput(ip); brelse(bp); } rexit() { u.u_arg[0] = u.u_= p->p_addr); mfree(swapmap, 1, f); p->p_stat = 0 ; p->p_pid = 0; p->p_ppid = 0; p->p_sig = 0; p->p_pgrp !"#$&'()* = 0; p->p_flag = 0; p = bp->b_addr; u.u_cstime[0] =+ p->u_cstime[0]; dpadd(u.u_cstime, p->u_cstime[1]); dpadd(u.u_cstime, p->u_stime); u.u_cutime[0] =+ p->u_cutime[0]; dpadd(u.u_cutime, p->u_cutime[1]); dpadd(u.u_cutime, p->u_utime); u.u_ar0[ (-2) ] = p->u_arg[0]; brelse(bp); return; } } if(f) { runrun++; sleep(u.u_procp, 40 ); goto loop; } u.u_error = 10 ; } fork() { register struct proc *p1, *p2; p1 = u.u_procp; for(p2 = &proc[0]; p2 < &proc[ 13 ar0[ (0) ] << 8; exit(); } exit() { register int *q, a; register struct proc *p; p = u.u_procp; p->p_clktim = 0;  ]; p2++) if(p2->p_stat == 0 ) goto found; u.u_error = 11 ; goto out; found: if(newproc()) { u.u_ar0[ (0) ] = p for(q = &u.u_signal[0]; q < &u.u_signal[ 20 ];) *q++ = 1; for(q = &u.u_ofile[0]; q < &u.u_ofile[ 15 ]; q++) if(a = *q)1->p_pid; u.u_cstime[0] = 0; u.u_cstime[1] = 0; u.u_stime = 0; u.u_cutime[0] = 0; u.u_cutime[1] = 0; u.u_utime = 0; / Êý2 ÄâÔÄ% û‚Ī Îß ÄeÄ%Èõ‚Τýß Îæß Ö ÷ DýÎæ>ýß Ö Î¦æß –%Žß ÄVýôÌ•ÂùùùùùùùùùÙéùùùùùÙ_canonb´, Žß ´, 2 ÂeÂ%„õ‚·Šâü÷ ÞüÂeÂ%„ã‚4 Þw Êü ÂÀüü°, P„ Ê¥L¿ Àý„æ üß Ö ææ _swapmap _rootdir _lbolt _time _tout _callout _mount _mpid _runrun _curpri _rooß –% Š2 2 2Š2 2ŠÂ·lzýŽæß Ö Ž æß Ö ·lTýŽæß Ö Ž æß Ö À<ý°ÈüÿÎß ÂeÂ%„tdev _swapdev _updlock _regloc _u &_proc „_buf X_bfreeli _inode Ü_exec"~exec¥‚Ä ·ŠüÎ(æ:üß Ö —÷• 'üwìûw èûÄ üÃË‹ ÃeÃ%„ù‚÷• ü÷ ÆûÀ ? Òü7 Êü7 Èü7 ¼ü7 ºü7 ¸ü7 ®ü ÿ ²üÀÁªü1`naöÿapøÿncôÿbpòÿdsðÿipcpccsv _namei L1wŒûw ˆûÃLüÃe? ×túÿÃEüà  ÂÂí@üÀ>üÀe`Ã%÷•�û·`$üwLûéø(N_getblk _access L2@L10000FL3PL4ªL20009bL6v_fubyte L8¦_fuwùù˜ùù¸ord L9Æ_readi L10,L12"L136_suword L14ÀL20001œL18®_subyte øùùùùØùùùùùùùùL19üL20003L23 L20005L200076_iput _brelse cret _rexit"R~rexitR_exitùùùùØùùX"j~exitjaqpL20011zL20013ˆL35”_closef _malloc L37¼_pan´|w üÿÆå  ß _NÎÿÿß 5òÿÎ@æß Ö À _@ó5`ó5I÷• ëÿ_@@òÿ5 öÿ5 ôÿ$µ öÿÀ%ÿÿ_@ùùùøøèùèùøø÷eTNøÿµ øÿß Ä%ÿÿ_@‘µ ôÿõ%þôÿ÷••ÿ_@Ä æÎß 5øÿÕõ5ôÿе ôÿ÷Èrÿ÷nÿ7 nÿ7 hÿÎß ÷‹Sÿ_@÷%Øÿ¸ÈÙéùùÙéùøøøˆøù¸˜¹÷mÔÿÔÿÀÐÿÀmÎÿÀe?túÿÀEü5ðÿÀeÀ%_@Â`Â%àƒŠû÷•ÿ_@÷`ÿ÷ÿ÷†ÿøþwðÿ†ÿÎß ÷|ÿ@òÿÀà@íôÿAöÿÁ ÉøÈØù™Ié@àÀeüÿ5øÿÀ˜ÿpøÿúÿNöÿføÿß Ö ÄàDíôÿõeøÿføÿß Ö €’&„ ß Ö Ò‹÷@öÿõ öÿÀ èÎÿÿføÿÎeß Ö ó5 ÷‹Nþ÷œ ùùÉØèùøøøøùFþÀFþðœ ÄÃâË5 ÃeÃ% ÷‚€”À Àmöþ Â%ø‚Àêþð`à Ã%6ü‚Îß Nòÿß w®ýw ªýÀ¼þt7fþ÷ w–ýw ’ýÂøøøøùÈ™ù(ùÙéùù©0 L54 _sleep _fork"~forkp1p2L20021 L596L60d_newproc L61lse open1(ip, FWRITE, 1); } /* * common code for open and creat. * Check permissions, allocate an open file structure, * a^L55p_sbreak"t~sbreaktadnL63ŽL64¬L62°nd call the device open routine if any. */ open1(ip, mode, trf) int *ip; { register struct file *fp; register *rip, m; int i; rip = ip; m = mode; if(trf != 2) { if(m&FREAD) access(rip, IREAD); if(m&FWRITE) { access(rip, IWRITE); if((rip->i_mode&IFMT) == IFDIR) u.u_error = EISDIR; } } if(u.u_error) goto out; if(trf) itrunc(rip); prele(rip); if ((f# #include "../param.h" #include "../systm.h" #include "../user.h" #include "../reg.h" #include "../file.h" #include "../inode.hp = falloc()) == NULL) goto out; fp->f_flag = m&(FREAD|FWRITE); fp->f_inode = rip; i = u.u_ar0[R0]; openi(rip, m&FWRITE); " /* * read system call */ read() { rdwr(FREAD); } /* * write system call */ write() { rdwr(FWRITE); } /* * common cod if(u.u_error == 0) return; u.u_ofile[i] = NULL; fp->f_count--; out: iput(rip); } /* * close system call */ close() { e for read and write calls: * check permissions, set base, count, and offset, * and switch out to readi, writei, or pipe code.register *fp; fp = getf(u.u_ar0[R0]); if(fp == NULL) return; u.u_ofile[u.u_ar0[R0]] = NULL; closef(fp); } /* * seek sys */ rdwr(mode) { register *fp, m; m = mode; fp = getf(u.u_ar0[R0]); if(fp == NULL) return; if((fp->f_flag&m) == 0) { tem call */ seek() { int n[2]; register *fp, t; fp = getf(u.u_ar0[R0]); if(fp == NULL) return; if(fp->f_flag&FPIPE) { u.u_error = EBADF; return; } u.u_base = u.u_arg[0]; u.u_count = u.u_arg[1]; u.u_offset[1] = fp->f_offset[1]; u.u_offset[0 u.u_error = ESPIPE; return; } t = u.u_arg[1]; if(t > 2) { n[1] = u.u_arg[0]<<9; n[0] = u.u_arg[0]>>7; if(t == 3) ] = fp->f_offset[0]; if(m==FREAD) readi(fp->f_inode); else writei(fp->f_inode); dpadd(fp->f_offset, u.u_arg[1]-u.u_count);n[0] =& 0777; } else { n[1] = u.u_arg[0]; n[0] = 0; if(t!=0 && n[1]<0) n[0] = -1; } switch(t) { case 1: case 4:  u.u_ar0[R0] = u.u_arg[1]-u.u_count; } /* * open system call */ open() { register *ip; ip = namei(0); if(ip == NULL) r n[0] =+ fp->f_offset[0]; dpadd(n, fp->f_offset[1]); break; default: n[0] =+ fp->f_inode->i_size0&0377; dpadd(n, fp->fic _bcopy _bwrite L38îL20017òL41"_wakeup L20015L45_swtch _wait"2eturn; u.u_arg[1]++; open1(ip, u.u_arg[1], 0); } /* * creat system call */ creat() { register *ip; ip = namei(1); if(ip~wait2bpfpL488L20019<L51è_bread _mfree _dpadd L47 == NULL) { if(u.u_error) return; ip = maknode(u.u_arg[1]&07777); if (ip==NULL) return; open1(ip, FWRITE, 2); } e1 ð |w üÿÎß wðÿw ìÿÎß wàÿw ÜÿCÎêß .̰÷• ùÿ(÷„øÿ÷€ôÿ7òÿ7êÿÃ%ß ß Iˆù ùùˆùHùùHù_inode->i_size1); case 0: case 3: ; } fp->f_offset[1] = n[1]; fp->f_offset[0] = n[0]; } /* * link system call */ linkÎVÎíÈÿ&Îeß Ö ÀBÀí´ÿ?†wlÿw hÿ ß  · $ æ&ß ø–%wHÿw DÿÎß ÷‹kÿÎøÿÎEðß  ÎÎæ&ß () { register *ip, *xp; ip = namei(0); if(ip == NULL) return; if(ip->i_nlink >= 127) { u.u_error = EMLINK; goto out; ø–%wÿw ÿæ CBõ%Â5Îæß Ö Â5΀æß Ö ÀÀEÿŸÀ%@÷•ñþ÷‹íþ'õ Îß Îß ÷ žþ€ÀEüÿ �ô } if((ip->i_mode&IFMT)==IFDIR && !suser()) goto out; /* * unlock to avoid possibly hanging the namei */ ip->i_flag =& õ ÿøÿŽÎEýÿæß Ö ÷‹­þ @øÿÀ 0 ªôŠÎß w\þw XþÎjÿß À^ÿÀ 0 ªß w8þw 4þÆåÎBÿß D̵÷•Oþ=ÃÜþÃ%~ILOCK; u.u_dirp = u.u_arg[1]; xp = namei(1); if(xp != NULL) { u.u_error = EEXIST; iput(xp); } if(u.u_error) goto outÀÐþt 5øÿÀÄþtùÿ5öÿÃ%õEþöÿ õªþøÿ5 öÿà õ øÿõÿÿöÿÀ ‚À xð5möÿfÎeöÿß Ö tøÿtöÿw˜ýœ ; if(u.u_pdir->i_dev != ip->i_dev) { iput(u.u_pdir); u.u_error = EXDEV; goto out; } wdir(ip); ip->i_nlink++; ip->i_flÀEÿ5`öÿ åw zý ß >ô¥÷•™ý3ÀEÿŸÀ%@÷ NýÀ (ÌÅ÷ þ–ýÎß ÷•eýÎß ÷‹[ýÀ†ý0-ß ag =| IUPD; out: iput(ip); } /* * mknod system call */ mknod() { register *ip; if(suser()) { ip = namei(1); if(ip !=÷•Aýß ´ŠÌÕß wðüw ìü÷ èüÀ Îß ÷• ý ÷‹ý Î�ýß ô†ýß w®üw ªüÆå÷ ¢üõžüöÿõšüøÿΨýf NULL) { u.u_error = EEXIST; goto out; } } if(u.u_error) return; ip = maknode(u.u_arg[1]); if (ip==NULL) return;Îeöÿß Ö Î„üæ~üføÿföÿß ÆeÀ ÷ füwbüÎ`üæZüæXüæRüß ÆeÀ Nøÿföÿæ<üæ6üß ÆeÀ wöÿ$üwøÿ üÎZæß Ä ip->i_addr[0] = u.u_arg[2]; out: iput(ip); } /* * sleep system call * not to be confused with the sleep internal routine.XBhXBIiIiIùØùùùùùùù8ù */ sslep() { char *d[2]; spl7(); d[0] = time[0]; d[1] = time[1]; dpadd(d, u.u_ar0[R0]); while(dpcmp(d[0], d[1], time[0ùHùùùiIˆùùiIˆùù], time[1]) > 0) { if(dpcmp(tout[0], tout[1], time[0], time[1]) <= 0 || dpcmp(tout[0], tout[1], d[0], d[1]) > 0) { touiIÈÈùùøùt[0] = d[0]; tout[1] = d[1]; } sleep(tout, PSLEP); } spl0(); } (ùøHiIùØùø˜iIùØùùùùùHi2 k"ÈL10001ðL25XL28BL29h~seekÈfpnöÿtL19dL20ê 0) return; u.u_ofile[i] = fp; fp->f_count++; } /* * the mount system call. */ smount() { int d; register *ip; registeL21L234L20007L_link"‚~link‚ipxpL32 L33 L34L10002r struct mount *mp, *smp; d = getmdev(); if(u.u_error) return; u.u_dirp = u.u_arg[1]; ip = namei(0); if(ip == NULL) re¶_suser L35ØL36ø_wdir _mknod"~mknodipL380L40HL37N_sslturn; if(ip->i_count!=1 || (ip->i_mode&(IFBLK&IFCHR))!=0) goto out; smp = NULL; for(mp = &mount[0]; mp < &mount[NMOUNT]; mpep"R~sslepRdöÿ_spl7 L20008x_dpcmp L20010ž_spl0 L10003ÖL44â_sleep ++) { if(mp->m_bufp != NULL) { if(d == mp->m_dev) goto out; } else if(smp == NULL) smp = mp; } if(smp == NULL)8HiI ˆùùùùHiIÙIIùHIIøiIIYYøYYøYYXH# #include "../param.h" #include "../systm.h" #include "../reg.h" #include "../buf.h" #include "../filsys.h" #include "../user.h_canonb _swapmap _rootdir _lbolt _time _tout _callout _mount _mpid _runrun _cur" #include "../inode.h" #include "../file.h" #include "../conf.h" /* * the fstat system call. */ fstat() { register *fp; fpri _rootdev _swapdev _updlock _regloc _u &_file �_inode Ü_read"~readcsv p = getf(u.u_ar0[R0]); if(fp == NULL) return; stat1(fp->f_inode, u.u_arg[0]); } /* * the stat system call. */ stat() { r_rdwr" cret _write"~write~rdwr fpmodem_getf L3�L4egister ip; ip = namei(0); if(ip == NULL) return; stat1(ip, u.u_arg[1]); iput(ip); } /* * The basic routine for fstat a@L5h_readi L6p_writei _dpadd _open"”~open”ip_namei L7´_opend stat: * get the inode and pass appropriate parts back. */ stat1(ip, ub) int *ip; { register i, *bp, *cp; iupdat(ip); bpn1"ø_creat"¸~creat¸ipL9äL8ô_maknode L20003è~open1øfpip = bread(ip->i_dev, ldiv(ip->i_number+31, 16)); cp = bp->b_addr + 32*lrem(ip->i_number+31, 16) + 24; ip = &(ip->i_dev); for(imodeiøÿmriptrfL12FL13 _access L16šL17X_itrunc=0; i<14; i++) { suword(ub, *ip++); ub =+ 2; } for(i=0; i<4; i++) { suword(ub, *cp++); ub =+ 2; } brelse(bp); } /*  _prele _falloc _openi L11 _iput _close"¤~close¤fpL18Ä_closef _see * the dup system call. */ dup() { register i, *fp; fp = getf(u.u_ar0[R0]); if(fp == NULL) return; if ((i = ufalloc()) <3 d==ip->i_dev) { u.u_error = EBUSY; return; } ip = mp->m_inodp; ip->i_flag =& ~IMOUNT; iput(ip); ip = mp->m_bufp; mp8ù¹È™ù¹->m_bufp = NULL; brelse(ip); } /* * Common code for mount and umount. * Check that the user's argument is a reasonable * th8xXùxè8ˆing on which to mount, and return the device number if so. */ getmdev() { register d, *ip; ip = namei(0); if(ip == NULL) ˜8¨¹ xxreturn; if((ip->i_mode&IFMT) != IFBLK) u.u_error = ENOTBLK; d = ip->i_addr[0]; if(ip->i_addr[0].d_major >= nblkdev) u.u_e((X8ù¹8YXrror = ENXIO; iput(ip); return(d); } ù_canonb _swapmap _rootdir _lbolt _time _tout _callout _mount _mpid _runrun _curpri _rootdev _swapdev _updlock _regloc _buf X_bfreeli _u &_inode Ü_file �_bdevsw º\w üÿÎß Î´&ß FÖ wÞÿw Úÿ ß  Ζ&ß FÖ ß wºÿw ¶ÿNß Î@&Îeß Ö @&_nblkdev _cdevsw _nchrdev _fstat"~fstatfpcsv _getf L1_stat1"Fcret goto out; mp = bread(d, 1); if(u.u_error) { brelse(mp); goto out1; } smp->m_inodp = ip; smp->m_dev = d; smp->m_bufpß Ö Î@&Îeß Ö —tÂlÂe@Àe5 Nõefß Ö õe„ Ä%ï Žfß Ö õe„ Ä%óÎß  = getblk(NODEV); bcopy(mp->b_addr, smp->m_bufp->b_addr, 256); smp = smp->m_bufp->b_addr; smp->s_ilock = 0; smp->s_flock = 0w ÿw ÿÎß  ÷ øþÀ 𪳊wäþw àþæ ÷ R5øÿ÷‹ ÿ÷–ÿ ÿ ß ô£ ô5   Ãó  õ"øÿ ÷•Ñþß w�þ; smp->s_ronly = u.u_arg[2] & 1; brelse(mp); ip->i_flag =| IMOUNT; prele(ip); return; out: u.u_error = EBUSY; out1: iput ÂÃeÃ%ê‚ îÎføÿß Ö ÷‹ŸþÎß â2JøÿÎÿÿß 2΀&æß –%€2Š™2Š˜ÀìþÀEþÿ2�›Îß ÌÕ(ip); } /* * the umount system call. */ sumount() { int d; register struct inode *ip; register struct mount *mp; update(ß ¹w þæ ÷ üý÷ p5øÿ÷‹'þ1Ãó õ"øÿ ÃeÃ%õ‚÷•þ Äô 5-øÿ÷•ëýÄeÄ%Üð‚ÄÌÅß Ä3 ); d = getmdev(); if(u.u_error) return; for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) if(mp->m_bufp!=NULL && d==mp->m_deß wˆýw „ý ß ÀÀEÿŸÀ%`÷•�ýÄÀœÀ-Zý÷•‰ýÎß wFý¹Èù¹8v) goto found; u.u_error = EINVAL; return; found: for(ip = &inode[0]; ip < &inode[NINODE]; ip++) if(ip->i_number!=0 && Xù¹ÈØèø4 _getmdev"xL11lL12`L20005TL16pL15vL20fL19¢_getblk _bcopy _pre: iput(pp); } chdir() { register *ip; ip = namei(0); if(ip == NULL) return; if((ip->i_mode&IFMT) != IFDIR) { u.u_errole _sumount"ú~sumountúipmpdøÿ_update L21tL20007L24"L254r = ENOTDIR; bad: iput(ip); return; } if(access(ip, IEXEC)) goto bad; iput(u.u_cdir); u.u_cdir = ip; prele(ip); } cL200098L28N~getmdevxipdL30¶L31šL32®hmod() { register *ip; if ((ip = owner()) == NULL) return; ip->i_mode =& ~07777; ip->i_mode =| u.u_arg[1]&07777; ip->i_f# /* * Everything in this file is a routine implementing a system call. */ #include "../param.h" #include "../user.h" #includlag =| IUPD; iput(ip); } chown() { register *ip; if (!suser() || (ip = owner()) == NULL) return; ip->i_uid = u.u_arg[1].e "../reg.h" #include "../inode.h" #include "../systm.h" #include "../proc.h" getswit() { u.u_ar0[R0] = 0177300; } gtime() {lobyte; ip->i_gid = u.u_arg[1].hibyte; ip->i_flag =| IUPD; iput(ip); } ssig() { register a; a = u.u_arg[0]; if(a<=0 || a u.u_ar0[R0] = time[0]; u.u_ar0[R1] = time[1]; } stime() { if(suser()) { time[0] = u.u_ar0[R0]; time[1] = u.u_ar0[R1];>=NSIG || a==SIGKIL) { u.u_error = EINVAL; return; } u.u_ar0[R0] = u.u_signal[a]; u.u_signal[a] = u.u_arg[1]; if(u.u_pro wakeup(tout); } } setuid() { register uid; uid = u.u_ar0[R0].lobyte; if(u.u_ruid == uid.lobyte || suser()) { u.u_uid cp->p_sig == a) u.u_procp->p_sig = 0; } kill() { register struct proc *p, *q; register a; int f; f = 0; a = u.u_ar0[R0]= uid; u.u_procp->p_uid = uid; u.u_ruid = uid; } } getuid() { u.u_ar0[R0].lobyte = u.u_ruid; u.u_ar0[R0].hibyte = u.u_u; q = u.u_procp; for(p = &proc[0]; p < &proc[NPROC]; p++) { if(p == q) continue; if(a != 0 && p->p_pid != a) continuid; } getpid() { u.u_ar0[R0] = u.u_procp->p_pid; } sync() { update(); } nice() { register n; n = u.u_ar0[R0]; if(n > 2e; if(a == 0 && (p->p_pgrp != q->p_pgrp || p <= &proc[1])) continue; if(u.u_uid != 0 && u.u_uid != p->p_uid) continue;0) n = 20; if(n < 0 && !suser()) n = 0; u.u_procp->p_nice = n; } /* * Unlink system call. * panic: unlink -- "cannot ha f++; psignal(p, u.u_arg[0]); } if(f == 0) u.u_error = ESRCH; } times() { register *p; for(p = &u.u_utime; p < &u.u _stat""~stat"ip_namei L2B_iput ~stat1Fbpcpipubppen" */ unlink() { register *ip, *pp; pp = namei(2); if(pp == NULL) return; prele(pp); ip = iget(pp->i_dev, u.u_dent.ui_iupdat _ldiv _bread _lrem L20001¬_suword L20003Ð_brelse _dup"ô_ino); if(ip == NULL) goto out1; if((ip->i_mode&IFMT)==IFDIR && !suser()) goto out; u.u_offset[1] =- DIRSIZ+2; u.u_base ~dupôfpiL10_ufalloc _smount"~smountipmpdøÿsmp= &u.u_dent; u.u_count = DIRSIZ+2; u.u_dent.u_ino = 0; writei(pp); ip->i_nlink--; ip->i_flag =| IUPD; out: iput(ip); out15 _utime+6;) { suword(u.u_arg[0], *p++); u.u_arg[0] =+ 2; } } /* * alarm clock signal */ alarm() { register c, *p; p = 7‘Æÿwˆÿw „ÿÿ�ºÿ”À�ð�®ÿwpÿw lÿÀ¤ÿ? xw^ÿw Zÿ÷ VÿwRÿw NÿÄ`Ä%ÄÄ ÷ 8ÿÀ  Àjÿ0‘w&ÿw "ÿÎß /Îß u.u_procp; c = p->p_clktim; p->p_clktim = u.u_ar0[R0]; u.u_ar0[R0] = c; } /* * indefinite wait. * no one should wakeup(&u)Îdÿæß Ö  ÀEÿŸÀ%@÷ ìþÀ ÷å&ÿ÷Xÿ÷ÿ7 *ÿÎß ôŠÌÕß Îß w´þw °þ ß ÀEÿŸÀ%@÷•Éþ */ pause() { for(;;) sleep(&u, PSLEP); } /* * Implement the halt system call; bring down the system gracefully. * mgß Î@&ß Ö À ôμþß 7´þß wdþw `þ÷ \þôEÿÀÿÀEð4PÌÕß w8þw 4þ÷ 0þÀ ÷ (þ ô�êþ ô�åþ ÌÕß s 1/80 */ halt() { register struct proc *p, *procs; register done; extern wakeup(); if (!suser()) return; /* caller mustw þw þÄÊþÄ%Ä% ÷•%þÀ ?âøþÀ ð¤þâÀþœ!Àþ0ŠwÀýw ¼ýæ 5 øÿÂÈþÃêýÄÄ  ´  ô, be super user */ spl7(); /* wait for update completion */ for (;;) { if (updlock==0) break; idle(); } updlocÄ%†÷‹¾ý7­¶ýµ øÿÎ<þ&ß Ö ÄeÄ%„Ü‚õ øÿ÷•�ýwRýw NýÄ æ þß Ö ÷eþÄ%ô‚w.ýw *ýÃbýÄó4þ?.þwýw ýk++; procs = u.u_procp; for (p= &proc[0]; p<&proc[NPROC]; p++) if (p!=procs) psignal(p,SIGKIL); spl0(); u.u_ar0[R0] = 2; ÎZæß Ö øw üü÷ øüÀ C÷ ðü÷ êü÷ æüû· àüÃýÄÄ Î &ß Ö ÄeÄ%„ó‚÷ ºüÿÊý÷ °ü ÄÌ‹ “×  Á@0‚  do { /* wait for everything done */ sslep(); done = 0; for (p= &proc[0]; p<&proc[NPROC]; p++) if (p->p_stat!=NULL &ÄeÄ%„î‚ÿ–ýÂ%ã7 vü÷ rü÷ nüwjüI YIi iYI© i ixÈYI & p->p_stat&SZOMB==0) done++; u.u_ar0[R0] = 1; } while(done > 1); updlock = 0; update(); /* printf("\7"); printf("Halted© YI YI YI‰YI © Yþ[–IŸßºDbinžßÄü5ÄeÎn & I(H X©  ˜¨¨YI(tþ€nÚ_â_º_Ê_ ¨ ¨ HYIY ¨YI©Yú_(Y ¨YI   YI  È YI ( YI –ôw üÿÿÀþ wòÿw îÿÿêÿþÀúðâÿüÿwÚÿw Öÿ÷ ÒÿÀ ÷àÈÿÀÚ7üÿÀÿÎß w²ÿw ®ÿÄŸÀ7¡àÿ÷  ÿÀ 7‘ÐÿÀÐÿ0‘ YI¨I©Iùù Èy ™6 p_pause"ì~pauseìL34ð_sleep _halt"~haltdonepprocsL36ullsys, /* 30 = smdate; inoperative */ 1, &stty, /* 31 = stty */ 1, >ty, /* 32 = gtty */ 2, &nosys, /* 33 = access ’_spl7 L37L20005_idle L20007(L418_spl0 L45L_sslep L20009V*/ 0, &nice, /* 34 = nice */ 0, &sslep, /* 35 = sleep */ 0, &sync, /* 36 = sync */ 1, &kill, /* 37 = kill */ 0, &geL48pL10006fL10007j_haltins tswit, /* 38 = switch */ 0, &nosys, /* 39 = x */ 0, &nosys, /* 40 = x */ 0, &dup, /* 41 = dup */ 0, &nosys, /* 42  ù‰éY_u &_inode Ü_canonb _swapmap _rootdir _lbolt _time _tout _callout _mount _mpid _runrun _curpri _rootdev _swapdev _updlock _reg# /* * This table is the switch used to transfer * to the appropriate routine for processing a system call. * Each row contailoc _proc „_getswit"~getswitcsv cret _gtime"~gtime_stime"&~stime&_suser ns the number of arguments expected * and a pointer to the routine. */ int sysent[] { 0, &nullsys, /* 0 = indir */ 0, &reL3J_wakeup _setuid"N~setuidNuidL10000dL5t_getuid"x~getuidx_getpid"�~getpidxit, /* 1 = exit */ 0, &fork, /* 2 = fork */ 2, &read, /* 3 = read */ 2, &write, /* 4 = write */ 2, &open, /* �_sync"¢~sync¢_update _nice"®~nice®nL11ÀL12Î_unlink"Ú~unlinkÚip 5 = open */ 0, &close, /* 6 = close */ 0, &wait, /* 7 = wait */ 2, &creat, /* 8 = creat */ 2, &link, /* 9 = linpp_namei L13H_prele _iget L14BL10001L15<_writei _iput k */ 1, &unlink, /* 10 = unlink */ 2, &exec, /* 11 = exec */ 1, &chdir, /* 12 = chdir */ 0, >ime, /* 13 = time */ _chdir"L~chdirLipL16˜L17vL18n_access _chmod"œ~chmodœip_owner 3, &mknod, /* 14 = mknod */ 2, &chmod, /* 15 = chmod */ 2, &chown, /* 16 = chown */ 1, &sbreak, /* 17 = break */ 2, L19Ä_chown"È~chownÈipL20ò_ssig"ö~ssigöaL10002 L22L21 &stat, /* 18 = stat */ 2, &seek, /* 19 = seek */ 0, &getpid, /* 20 = getpid */ 3, &smount, /* 21 = mount */ 1, &sum<_kill"@~kill@aføÿpqL20001VL27”L10003dL10004vount, /* 22 = umount */ 0, &setuid, /* 23 = setuid */ 0, &getuid, /* 24 = getuid */ 0, &stime, /* 25 = stime */ 3, &L10005„_psignal L24ª_times"®~times®pL20003¶_suword _alarm"Ò~alarmÒcnullsys, /* 26 = ptrace */ 0, &alarm, /* 27 = alarm */ 1, &fstat, /* 28 = fstat */ 0, &pause, /* 29 = pause */ 1, &n7 # #include "../param.h" #include "../systm.h" #include "../user.h" #include "../proc.h" #include "../reg.h" #define EBIT 1 /* øuser error bit in PS: C-bit */ #define SETD 0170011 /* SETD instruction */ #define SYS 0104400 /* sys (trap) instruction */ #define USER 020 /* user-mode flag added to dev */ /* * structure of the system entry table (sysent.c) */ struct sysent { int(8HXhxˆ˜¨¸ÈØèø(8HXhxˆ˜¨¸ count; /* argument count */ int (*call)(); /* name of handler */ } sysent[64]; /* * Offsets of the user's registers relativÈØèø(8HXhxˆe to * the saved r0. See reg.h */ char regloc[9] { R0, R1, R2, R3, R4, R5, R6, R7, RPS }; /* * Called from l40.s or l45.s w˜_sysent#_nullsys _rexit _fork _read _write _open _close _wait _crehen a processor trap occurs. * The arguments are the words saved on the system stack * by the hardware and software during the= pipe */ 1, ×, /* 43 = times */ 4, &nosys, /* 44 = prof */ 0, &nosys, /* 45 = tiu */ 0, &nullsys, /* 46 = setgat _link _unlink _exec _chdir _gtime _mknod _chmod _chown _sbreak _stat id */ 0, &nullsys, /* 47 = getgid */ 2, &ssig, /* 48 = sig */ 0, &nosys, /* 49 = x */ 0, &nosys, /* 50 = x */ 0, &n_seek _getpid _smount _sumount _setuid _getuid _stime _alarm _fstat _pause _sttyosys, /* 51 = x */ 0, &nosys, /* 52 = x */ 0, &nosys, /* 53 = x */ 0, &nosys, /* 54 = x */ 0, &nosys, /* 55 = x */ _gtty _nosys _nice _sslep _sync _kill _getswit _dup _times _ssig _hal 0, &nosys, /* 56 = x */ 0, &nosys, /* 57 = x */ 0, &nosys, /* 58 = x */ 0, &nosys, /* 59 = x */ 0, &nosys, /* 60t  = x */ 0, &nosys, /* 61 = x */ 0, &halt, /* 62 = halt */ /* * never change the entry for sys. call 63...the system depends on it * being set to "&nosys". See "trap.c" */ 0, &nosys /* 63 = nosys */ }; 8 ; case 0+USER: /* bus error */ i = SIGBUS; break; /* * If illegal instructions are not * being caught and the offendt * clearing u_intflg; if it's still set, trap * marks an error which means that a system * call (like read on a typewriter) ing instruction * is a SETD, the trap is ignored. * This is because C produces a SETD at * the beginning of every program got interrupted * by a signal. */ trap1(f) int (*f)(); { u.u_intflg = 1; savu(u.u_qsav); (*f)(); u.u_intflg = 0; } /* *which * will trap on CPUs without 11/45 FPU. */ case 1+USER: /* illegal instruction */ if(fuiword(pc-2) == SETD && u.u_si nonexistent system call-- set fatal error code. */ nosys() { u.u_error = 100; } /* * Ignored system call */ nullsys() { } gnal[SIGINS] == 0) goto out; i = SIGINS; break; case 2+USER: /* bpt or trace */ i = SIGTRC; break; case 3+USER: /* iot */ i = SIGIOT; break; case 5+USER: /* emt */ i = SIGEMT; break; case 6+USER: /* sys call */ u.u_error = 0;  ps =& ~EBIT; callp = &sysent[fuiword(pc-2)&077]; if (callp == sysent) { /* indirect */ a = fuiword(pc); pc =+ 2; iš$w üÿõ%`†õU@Àe 7ú@Àå ‚À x¤÷ ÌÿÄ æþÿß Ö ÷ ¸ÿÀ ÷ °ÿw¬ÿNÎeþÿß À% ð÷ €ìÄ = fuword(a); if ((i & ~077) != SYS) i = 077; /* illegal */ callp = &sysent[i&077]; for(i=0; icount; i++) ãÄàÄÝÄÚ7НÿõENÎeþÿß ÂEÀÿ—tÂeÂ%)Nß õeÎß ÀE?À%‰Ä?ÂEÀÿ—tÂe „"ÃeÎ u.u_arg[i] = fuword(a =+ 2); } else { for(i=0; icount; i++) { u.u_arg[i] = fuiword(pc); pc =+ 2; } ß Á 1È„ ó Nß Á 1Èõe„ „"ò÷¤ÿ0ÿŽß f÷‹îÿ÷•ýþ÷¥d÷þ÷‹ñþ_DõUÀ�áþ5 _DÄ _8w –þ÷•°ÿ} u.u_dirp = u.u_arg[0]; trap1(callp->call); if(u.u_intflg) u.u_error = EINTR; if(u.u_error < 100) { if(u.u_error)ÎÚß ý 7Š ÿw|þw xþ÷•d©þwnþw jþwfþþ÷øùúý4Trx0~„iù‰ù trap processing. * Their order is dictated by the hardware and the details * of C's calling sequence. They are peculiar in th { ps =| EBIT; r0 = u.u_error; } goto out; } i = SIGSYS; break; } psignal(u.u_procp, i); out: if(issig()at * this call is not 'by value' and changed user registers * get copied back on return. * dev is the kind of trap that occur) psig(); } /* * Call the system-entry routine f (out of the * sysent table). This is a subroutine for trap, and * not in-red. */ trap(dev, sp, r1, nps, r0, pc, ps) char *pc; { register i, a; register struct sysent *callp; if(pc > TOPSYS) dev line, because if a signal occurs * during processing, an (abnormal) return is simulated from * the last caller to savu(qsav); =| USER; u.u_ar0 = &r0; switch(dev) { /* * Trap not expected. * Usually a kernel mode bus error. */ default: dump()if this took place * inside of trap, it wouldn't have a chance to clean up. * * If this occurs, the return takes place withou9 VVVºßþ€nÚ_â_º_Ê_ë÷- é‡÷-ü,†÷å ô÷ ªÿ�Ä¥ ú÷e âÎBtä‘ÀU€2Ä¥$8÷ t�Ä¥0+Ä¥9(‘ÀeÐÿÀ-®‘À Àm¢7 ÿ”÷ �ÄŸŠ· †Ä‹®7 ~ÜIîú_(Y÷ 2�Ä¥\Ö÷ &�Ä¥ ÌÀ w€ Ä¥$÷vRÞ‘ÀE€ÿów X æ ÷ d÷%\÷ ` ÀR· N’Ä ÷BÄ w4 ÷%4÷ 6 ÎfÎeøÿ& ß Ìq–%À% ß .qõ¥ øÿ÷ ÷ þ@�øÿÝw à õeu-ÎVt@’&ß æmÖ À îNfß ndÖ w¶ üw   æ 5 øÿDD-BŸÁÖr7R þy µ øÿÄeîõ øÿú·Šr÷õ øÿôŸ5øÿÎß –bËfß $eÖ 33 õ%&øÿÂòUaN&Îeß .dÖ 3À õ øÿNfß $eÖ ·Šüwü w ê  DD-0ŸÁîr7¶  þyƒ Äeïà ûà ùÎß –bÊfß ¤eÖ 2N&Îe (Y?Y Y$9…4Y Y(Y(Y _ 8(YàYš  ÿ ÿ(Y…pÿN_Ø9b9(Y€Ib_¤ * ²;¼€I t_Òl_n_À € ¼ûHYîU„_T=€@ |_|ß $eÖ 22 €wŒ Nfß ¤eÖ öw j Æå5 êÿ@È¥)õUêÿ5 øÿ5 öÿ5 ðÿ5 îÿ5 ôÿ5 òÿDD-_¼fŸ5ìÿÁs7  þyõ HYîU–_*?îUHYû¼|à–I´_Ò¨_ _ |}¨Ä 0 A€I–IÊ_–!–I€I–IV¼A–I€IÖ_ü'¼A4vâ_24Ú\A4vî_ä3Ö'€z4vˆz²ß´²ßªßæzˆz(oòÿ õ øÿ·ŠÀe5øÿµ òÿÄeÝõ òÿú5öÿ÷ÄeD-ü¥>õUêÿÄåõ òÿåÄeD-·Š¼ÄåÎZtŸ&ß æmÖ À ·Š õ%< ð€&Ð 6÷ ß .q‰w öÄß Þp„ Ä%ùÎß ænÄ%ß Þp÷ ð7¼ÄÎ æ°& ß Br–%7¤ÀÀe04�vÄ îBÃÑs÷Þsìÿõ ðÿ·ŠŽ5ðÿÄõ îÿ·Š~5îÿ¼õ òÿ¹@ôÿÀ µ ôÿ@m°õ øÿ!õ ôÿ·ŠPÎß –bËNöÿføÿß ndÖ 3sêÿsðÿsîÿÀˆ÷ ´7�–À5ÿ÷ástÃäs÷•ÿÿ~õ%47 ^ú¥-ú•-€ð¥cõ%·P€ð¥t÷> ß Þp ¦ß ®qÖ w õ ôÿ·Š@ôÿÀ µ ôÿ@m NôÿÎeß –bË5 òÿu-ôÿòÿØ@òÿÀ À`AòÿÁ Amp µ òÿîw ¶ BÂe „ “üÀ�&ý Ö �÷w¢ w Žß tmÎñsß Dmú¥-·ŠÎæß doÖ Îæß doÖ €Àe7Ä@À 7¼÷ ºÎ´ß tm÷ h7�¶÷ òw ¦÷zž÷vzš÷4vŽ÷� Î^tfß æmÖ À ÷•€@w~ w l @ÀE€ÿwn w \ Æåõ A@Àå :‚À xs@ Îbtæß nÖ À Îhtæß nÖ À .@zŠ7Š”7ŠŽÃ|÷ RË¥ ù÷€zt÷H{p÷‹p÷‹l ÷ Ž ÷‹bÎPæzß .dÖ ÷‹LÎÿsß DmŽß ²gw:w (ÿ ÷e÷ Ì�‘ð  ß ÌnÀ Îktß Dm÷%æ Χtß tm ÀÔ ðÐ ÷eÈ ÷ Æ wÚ΀tß ÌnÀ øÎ…tßΡtæß nÖ À Úηtæß nÖ À ÷ öâÎ rÁ ÁeŽrA! þy ‘÷ ˜�Ä (Ä¥ ·Šî7‘æwê‘ÀU€?�Ì· Èê?‘· ¾ 7‘ÄÎt‘&ß æmÖ À È?Š¢· žá7‘¤÷ N�Î t‘¼tæß nÖ À ÷ x À�† ß ÞpNÎe æÂtß únÖ ÎÍt¹Îätæß nÖ À ÷ @ À�N ß ÞpNÎe æëtß únÖ Î÷t�Îuæß nÖ À  þ[–I»ßùºDbinºßdbin&ß æmÖ À â?‘|· xïw xÄv@À 7`l÷-jf†Îtß tm·Š`÷ – wZw H÷‹JÄ�D7Š@‘`÷å.÷ àÿ�Ä¥ ú÷eÎ4tß Dm·Š: frß tmõ5€øÿΤuß tmà δuß Dm5!Nß ¼nwl ß ¼n»w Rw\w JwTf…w≶u†wT …‡f…@)‰†w>…‡f…wannot execute wait:try again : cannot open: cannot create/dev/null/etc/globglob: cannot execute /usr/bin/: not found¸w´÷ < æðæo‰ºuwf…‰†w7 …‡f…‰…‡w Êw w wÊÅö õô w¼f…AW †@wHÁ fT{/bin/shNo shell! : too large : -- Core dumped ‰7v ‰0‰+‰(v ‰‰ß Ö –%ÆewŠÿ‰‰ºß‰‰Þßæÿÿß &nÖ ›Îuæß nÖ À “@5öÿ5 øÿõ5öÿ÷ ì5øÿõ%ÿÿøÿÎu_hõ øÿ%õ5öÿ Nß Þp@ß Þpõ5@öÿNøÿß ªmÎ u1T{7< À5Á Á Áe¼ow(‰Àu ‡À5€…‡À& Ö wx&À’ L&ÀŒ H&À† D&À€ @&Àz <&Àt 8&Àn 4&Àh 0&Àß tmõ5öÿ_BhNføÿµ@ð  ß Þp @&ß ®qÖ 5øÿ @ß tmÎ"uß Dm÷ V@ð =õ5öÿÎ@&ß ®qÖ 5øÿb ,&À\ (&ÀV $&ÀP &ÀJ &ÀD &À> &À8 &À2 &À, &À& &À f¦æ&È „ƒ‚�€f…$‰…‡f… Î& føÿß îq–%ζ@&ß ôpÖ 5øÿ @ß tmÎ0uß Dm÷ êÎß ÞpNøÿß ænNøÿß Þpõ5öÿ ß ÞpNß ænNß Þp@ ‰¦BR‚…‡f…w,‰Æu…‡f…w‰Êu†w| …‡f…÷ |&‰†Ö wbÖ }…‡f…@‰†wF …‡f…wÒwß Þpõ5öÿÎß Þp@ß ænNß Þp@ß Þpõ5 öÿ@ð  õ5öÿ  ß Þp æ@uß ®qÖ õ5 öÿ÷‹4  æß doÖ  æÎ‰Îu†w&…‡@…&æ¦æ HADCBF…‡f…@‰f…‰…‡fA… w,üÿ‚Àw"|Àe"w"rÀew"h@lw"`ß doÖ ý%@@öÿÀEßÿ4Pß ²g÷ þÀ�ê ß Þp7ŠÜ Î~gfß XgÖ ÷‹Ê @ðJuNÎe@&ß únÖ ÎTuß tm÷ °ÎAlÁeæw¬S &@Àtùÿ`Áe€Ø€ …‡f…w0w,‰æu†wl…‡f…@ww‰ìu†wJ…‡f…@wøw¢gfß XgÖ ?Š| N@& ß ÖlÖ Ãf Âjuƒ ‹”ý@ “”þNæF Îeß ÖlÖ Næ4 ß ÖlÖ @ ß tmÎtuß Dm÷ 8@5öÿô‰òu†w( …‡f…@wÚwÖ‰øu†w…‡7 ÀÿÿF…‡€�6rw* ‡€�6r@‡s%s,s1sEsTs]sfsys€sŠs—sζæ\ß ôpÖ ß Þp æJß ®qÖ 5òÿÎæ8ß ®qÖ 5ôÿÎ*ß ¤p@@öÿÀE›ÿÀU4PNÎeòÿf&ß ²g–%@@öÿÀE–ÿÀU4P§s®sµs¼sÃsÊs–ržrªr¶r$  )' pböabFbpbFbbFbFbFbpböaFbFbFbFb &(); ¬d¬d–d d¬dšd()^|lHePeTeTeNfÎeòÿ&ß ²g–%_Bh@ÀEßÿ5öÿ@t]öÿß ²g@t]öÿß ²g_Bhw 8DÎe fß únÖ ÷%Tÿ‹ ô Je()<>lþe"fLf.f¤fÔgiök–l.__pf0HangupQuitIllegal instructionTrace/BPT trapIOT trapEMT trapFloating exceptionKilled ô€uÎe&ß únÖ Îˆuß tm÷ ÷%   ß tmΓuß Dm÷ îwÜw ÊNß tmΟuß tm÷ ® Î& & ß îq–%÷ ¾w¬w šD•Bus errorMemory faultBad system callSig 14Sig 15Sig 16Sig 17Sig 18Sig 19/usr/adm/sha% # /usr/adm/shb: cannot opensß ŽmÌ‹úw’w €ÎfÎeæß r–%wvw dÎ f& ß Br–%ß ªmÎ f& ß Tr–%Îe0ß Žmw:w (DÌ‹•@-úÀwyntax error '" ;&<>()|^ "'Command line overflow Too many argsToo many characters;& <>([?*chdircdchdir: bad directory üw DCÔ¢Ó‹üÀwþ üw èæ õ ?Î(vß ’pÎ(vß |pNÎeøÿß ¾pÄ%ÿÿ.CøÿÃE€ÿÀÀ ð frD-ß ªmΡuß tmÀÀ /usrchdir: "/usr" bad directoryshiftshift: no args synclogin/bin/loginlogin: cannot execute newgrp/bin/newgrpnewgrp: c; 4vˆ÷ ´7�–À5ÿ÷ástÃäs÷•ÿÿ~õ%47 ^ú¥-ú•-€ð¥cõ%·P€ð¥t÷> ß Þp ¦ß ®qÖ ˆz4vŽß tmÎñsß Dmú¥-·ŠÎæß doÖ Îæß doÖ €Àe7Ä@À 7¼÷ ºÎ´ß tm÷ h7�¶÷ òw ¦÷zž÷vzš÷4vŽ÷Úß¶azŠ7Š”7ŠŽÃ|÷ RË¥ ù÷€zt÷H{p÷‹p÷‹l ÷ Ž ÷‹bÎPæzß .dÖ ÷‹LÎÿsß DmŽß ²gw:w (ÿ ÷e÷ Ì�‘°ßLn¨ßªß€z4vˆzÆßÆß6iuzÊ߀z7vˆzÚß¼lˆzddzú߀z7vÿÿæßâa€zúßäsÿÿòßfaás`úßþßÿÿ- rÁ ÁeŽrA! þy ‘÷ ˜�Ä (Ä¥ ·Šî7‘æwê‘ÀU€?�Ì· Èê?‘· ¾ 7‘ÄÎt‘&ß æmÖ À È?Š¢· žá7‘¤÷ N�Î t‘þ[€I»ßùºDbin4vdbin&ß æmÖ À â?‘|· xïw xÄv@À 7`l÷-jf†Îtß tm·Š`÷ – wZw H÷‹JÄ�D7Š@‘`÷å.÷ àÿ�Ä¥ ú÷eÎ4tß Dm·Š00001üßás9vz zvz–zH{ÿlWŒåls VVV4vþ€nÚ_â_´_¼_ Jîú_(Y (Y?Y Y$9…4Y Y(Y(Y _ 8(YàYš  ÿ ÿ(Y…pÿN_Ø9b9(Y€Ib_¤ * ²;¼€I t_Òl_n_À € ¼HYîU¼|HYîU†_ª ¼|HYîU–_J?îUû¼|à–I´_Ò¨_ _ |}¨ < AàI¢ \îI€IÈ_�¼îI4vÖ_È'€I("A4vâ_24Ú\"A4vî_ä3ô&€z4vˆz¢ß´ ßLnæÊp ð€&Ð 6÷ ß .q‰w öÄß Þp„ Ä%ùÎß ænÄ%ß Þp÷ ð7¼ÄÎ æ°& ß Br–%7¤ÀÀe04�vÄ îBÃÑs÷Þs< ß $eÖ 22 €wŒ Nfß ¤eÖ öw j Æå5 êÿ@È¥)õUêÿ5 øÿ5 öÿ5 ðÿ5 îÿ5 ôÿ5 òÿDD-_¼fŸ5ìÿÁs7  þyõ ζæ\ß ôpÖ ß Þp æJß ®qÖ 5òÿÎæ8ß ®qÖ 5ôÿÎ*ß ¤p@@öÿÀE›ÿÀU4PNÎeòÿf&ß ²g–%@@öÿÀE–ÿÀU4Pòÿ õ øÿ·ŠÀe5øÿµ òÿÄeÝõ òÿú5öÿ÷ÄeD-ü¥>õUêÿÄåõ òÿåÄeD-·Š¼ÄåÎZtŸ&ß æmÖ À ·Š õ%<NfÎeòÿ&ß ²g–%_Bh@ÀEßÿ5öÿ@t]öÿß ²g@t]öÿß ²g_Bhw 8DÎe fß únÖ ÷%Tÿ‹ ô ìÿõ ðÿ·ŠŽ5ðÿÄõ îÿ·Š~5îÿ¼õ òÿ¹@ôÿÀ µ ôÿ@m°õ øÿ!õ ôÿ·ŠPÎß –bËNöÿføÿß ndÖ 3sêÿsðÿsîÿÀ ô€uÎe&ß únÖ Îˆuß tm÷ ÷%   ß tmΓuß Dm÷ îwÜw ÊNß tmΟuß tm÷ ® Î& & ß îq–%÷ ¾w¬w šD•w õ ôÿ·Š@ôÿÀ µ ôÿ@m NôÿÎeß –bË5 òÿu-ôÿòÿØ@òÿÀ À`AòÿÁ Amp µ òÿîw ¶ BÂe „ “üÀ�&ý Ö �÷w¢ w ß ŽmÌ‹úw’w €ÎfÎeæß r–%wvw dÎ f& ß Br–%ß ªmÎ f& ß Tr–%Îe0ß Žmw:w (DÌ‹•@-úÀw� Î^tfß æmÖ À ÷•€@w~ w l @ÀE€ÿwn w \ Æåõ A@Àå :‚À xs@ Îbtæß nÖ À Îhtæß nÖ À .@ üw DCÔ¢Ó‹üÀwþ üw èæ õ ?Î(vß ’pÎ(vß |pNÎeøÿß ¾pÄ%ÿÿ.CøÿÃE€ÿÀÀ ð frD-ß ªmΡuß tmÀÀ ð  ß ÌnÀ Îktß Dm÷%æ Χtß tm ÀÔ ðÐ ÷eÈ ÷ Æ wÚ΀tß ÌnÀ øÎ…tßΡtæß nÖ À Úηtæß nÖ À ÷ öâÎfrß tmõ5€øÿΤuß tmà δuß Dm5!Nß ¼nwl ß ¼n»w Rw\w JwTf…w≶u†wT …‡f…@)‰†w>…‡f…w¼tæß nÖ À ÷ x À�† ß ÞpNÎe æÂtß únÖ ÎÍt¹Îätæß nÖ À ÷ @ À�N ß ÞpNÎe æëtß únÖ Î÷t�Îuæß nÖ À  ¸w´÷ < æðæo‰ºuwf…‰†w7 …‡f…‰…‡w Êw w wÊÅö õô w¼f…AW †@wHÁ fT{æÿÿß &nÖ ›Îuæß nÖ À “@5öÿ5 øÿõ5öÿ÷ ì5øÿõ%ÿÿøÿÎu_hõ øÿ%õ5öÿ Nß Þp@ß Þpõ5@öÿNøÿß ªmÎ u1T{7< À5Á Á Áe¼ow(‰Àu ‡À5€…‡À& Ö wx&À’ L&ÀŒ H&À† D&À€ @&Àz <&Àt 8&Àn 4&Àh 0&Àë÷- é‡÷-ü,†÷å ô÷ ªÿ�Ä¥ ú÷e âÎBtä‘ÀU€2Ä¥$8÷ t�Ä¥0+Ä¥9(‘ÀeÐÿÀ-®‘À Àm¢7 ÿ”÷ �ÄŸŠ· †Ä‹®7 ~ß tmõ5öÿ_BhNføÿµ@ð  ß Þp @&ß ®qÖ 5øÿ @ß tmÎ"uß Dm÷ V@ð =õ5öÿÎ@&ß ®qÖ 5øÿ÷ 2�Ä¥\Ö÷ &�Ä¥ ÌÀ w€ Ä¥$÷vRÞ‘ÀE€ÿów X æ ÷ d÷%\÷ ` ÀR· N’Ä ÷BÄ w4 ÷%4÷ 6 ÎfÎe Î& føÿß îq–%ζ@&ß ôpÖ 5øÿ @ß tmÎ0uß Dm÷ êÎß ÞpNøÿß ænNøÿß Þpõ5öÿ ß ÞpNß ænNß Þp@øÿ& ß Ìq–%À% ß .qõ¥ øÿ÷ ÷ þ@�øÿÝw à õeu-ÎVt@’&ß æmÖ À îNfß ndÖ w¶ üw   æ 5 øÿDD-ß Þpõ5öÿÎß Þp@ß ænNß Þp@ß Þpõ5 öÿ@ð  õ5öÿ  ß Þp æ@uß ®qÖ õ5 öÿ÷‹4  æß doÖ  æBŸÁÖr7R þy µ øÿÄeîõ øÿú·Šr÷õ øÿôŸ5øÿÎß –bËfß $eÖ 33 õ%&øÿÂòUaN&Îeß .dÖ 3ß doÖ ý%@@öÿÀEßÿ4Pß ²g÷ þÀ�ê ß Þp7ŠÜ Î~gfß XgÖ ÷‹Ê @ðJuNÎe@&ß únÖ ÎTuß tm÷ °ÎÀ õ øÿNfß $eÖ ·Šüwü w ê  DD-0ŸÁîr7¶  þyƒ Äeïà ûà ùÎß –bÊfß ¤eÖ 2N&Îe¢gfß XgÖ ?Š| N@& ß ÖlÖ Ãf Âjuƒ ‹”ý@ “”þNæF Îeß ÖlÖ Næ4 ß ÖlÖ @ ß tmÎtuß Dm÷ 8@5öÿ= ΉÎu†w&…‡@…&æ¦æ HADCBF…‡f…@‰f…‰…‡fA… w,üÿ‚Àw"|Àe"w"rÀew"h@lw"`AlÁeæw¬S &@Àtùÿ`Áe€Ø€ …‡f…w0w,‰æu†wl…‡f…@ww‰ìu†wJ…‡f…@wøwô‰òu†w( …‡f…@wÚwÖ‰øu†w…‡7 ÀÿÿF…‡€�6rw* ‡€�6r@‡s%s,s1sEsTs]sfsys€sŠs—s§s®sµs¼sÃsÊs–ržrªr¶r$  )' pböabFbpbFbbFbFbFbpböaFbFbFbFb &(); ¬d¬d–d d¬dšd()^|lHePeTeTeJe()<>lþe"fLf.f¤fÔgiök–l.__pf0HangupQuitIllegal instructionTrace/BPT trapIOT trapEMT trapFloating exceptionKilledBus errorMemory faultBad system callSig 14Sig 15Sig 16Sig 17Sig 18Sig 19/usr/adm/sha% # /usr/adm/shb: cannot opens4vyntax error '" ;&<>()|^ "'Command line overflow Too many argsToo many characters;& <>([?*chdircdchdir: bad directoryˆz4v/usrchdir: "/usr" bad directoryshiftshift: no args synclogin/bin/loginlogin: cannot execute newgrp/bin/newgrpnewgrp: cÚß¶aannot execute wait:try again : cannot open: cannot create/dev/null/etc/globglob: cannot execute /usr/bin/: not found°ßLn¨ßªß€z4vˆzÆßiˆzzÊ߀z7vˆzÚß¼lˆzddzú߀z7vÿÿæßâa€zúßäsÿÿòßfaás`úßþßÿÿ-/bin/shNo shell! : too large : -- Core dumped ‰7v ‰0‰+‰(v ‰‰ß Ö –%ÆewŠÿ‰‰ºß‰‰Þß900001üßás9vz zvz–zH{ÿlvŒîls ø¨ 9ø 9b ,&À\ (&ÀV $&ÀP &ÀJ &ÀD &À> &À8 &À2 &À, &À& &À f¦æ&È „ƒ‚�€f…$‰…‡f… ‰¦BR‚…‡f…w,‰Æu…‡f…w‰Êu†w| …‡f…÷ |&‰†Ö wbÖ }…‡f…@‰†wF …‡f…wÒw> 5 L8 L20001 _sleep _flushtt"t_spl0 _cinit"4~cinit4cpccpcdp¹è É 99L11TL20003HL14hL20005b~flushttttpatpspsL18|_getc L20øŠ_wakeup _getps L22²_putps _canon"Ê~canonÊbpbp1øÿtpcatp_canonb _swapmap _rootdir _lbolt _time _tout L25ôL20007ÚL27èL24äL28þL29pL20009_putc L39’L31_callout _mount _mpid _runrun _curpri _rootdev _swapdev _updlock _regloc _u &_partabL32hL33DL344L10000ZL38fL30„_ttyinpu"ž~ttyinpužtpcatp _proc „_inode Ü_file �_bdevsw _nblkdev _cdevsw _nchrdev _maptab#z_cfree _cfreeli _ttyt_flagsacL42ÂL43öL10001ÔL10002àL10003ä_signal L20011îL41rL45open"~ttyopenpptpdevatpcsv L2(cret _gtty"8~gtty8L10004.L46H_ttyoutp"vL49l_ttstart"*L10007úL64¾L62ÀL66BL68J†‡ˆ‰Š‹Œ���‘’L73ŽL76ÚL78è~ttyoutpvtpcolpcrtpctypeøÿacL10005šL50ÖL51ÀL54¨L55öL56L57ÌL58æL61L69~L71Š_max L74ºL79_ttrstrt"~ttrstrttpatp~ttstart*addrtpcatpL85DL84�L87x_timeout _ttread"”~ttread”tpatpL89ÎL91upvpvôÿ_sgtty"¸L3|_suword _stty"€~stty€up_fuword ~sgtty´_passc _ttwrite"Ò~ttwriteÒtpcatpL94L93*L20015äL96L200¸fpipv_getf L5øL6â_wflusht"ü~wflushtütpatp_spl13ê_cpass _ttystty".~ttystty.avtpvatpL99XL98T? åååååååååååååååååååååååååå@ ååååååååååååååååååååååååååA ååååååååååååååååååååååååååB ååååååååååååååååååååååååååC ååååååååååååååååååååååååååD ååååååååååååååååååååååååååE ååååååååååååååååååååååååååF ååååååååååååååååååååååååååG ååååååååååååååååååååååååååH ååååååååååååååååååååååååååI ååååååååååååååååååååååååååJ ååååååååååååååååååååååååååK ååååååååååååååååååååååååååL åååååååååååååååååååååååååå