UNIX V6コードリーディング・メモ
UNIX V6のコードをまじめに読み始めようかと。 去年から『はじめてのOSコードリーディング』をぽつぽつと読んで、UNIX V6のソースの理解をし始めてはいるが、やはり全体像を知るにはまだまだ道のりは遠い。 動かしながら読めるのが一番ベストなのだが、まあとりあえずはソースコードの構成から、改めて眺めてみようと。
ただ読んでも面白くないので、Shell遊びしながらデータをとってみる。
ソース構成:
├── buf.h ├── conf │ ├── data.s │ ├── m40.s │ ├── m45.s │ ├── mkconf.c │ ├── sysfix │ └── sysfix.c ├── conf.h ├── dmr │ ├── bio.c │ ├── cat.c │ ├── dc.c │ ├── dh.c │ ├── dhdm.c │ ├── dhfdm.c │ ├── dn.c │ ├── dp.c │ ├── hp.c │ ├── hs.c │ ├── ht.c │ ├── kl.c │ ├── lp.c │ ├── mem.c │ ├── partab.c │ ├── pc.c │ ├── rf.c │ ├── rk.c │ ├── rp.c │ ├── sys.c │ ├── tc.c │ ├── tm.c │ ├── tty.c │ ├── vs.c │ └── vt.c ├── file.h ├── filsys.h ├── ino.h ├── inode.h ├── ken │ ├── alloc.c │ ├── clock.c │ ├── fio.c │ ├── iget.c │ ├── main.c │ ├── malloc.c │ ├── nami.c │ ├── pipe.c │ ├── prf.c │ ├── rdwri.c │ ├── sig.c │ ├── slp.c │ ├── subr.c │ ├── sys1.c │ ├── sys2.c │ ├── sys3.c │ ├── sys4.c │ ├── sysent.c │ ├── text.c │ └── trap.c ├── param.h ├── proc.h ├── reg.h ├── run ├── seg.h ├── systm.h ├── text.h ├── tty.h └── user.h
行数とかはさておき、各ファイルの定義関数の一覧を得てみる。
$ for i in `find . -name "*.c"` ;do A=`grep "^[a-z]*(.*)" $i`; echo $i":"$A ;done
出力:
./conf/mkconf.c:main() puke(s, a) input() equal(a, b) getchar() ./conf/sysfix.c:main(argc, argv) getrel(r) ./dmr/bio.c:bread(dev, blkno) breada(adev, blkno, rablkno) bwrite(bp) bdwrite(bp) bawrite(bp) brelse(bp) incore(adev, blkno) getblk(dev, blkno) iowait(bp) notavail(bp) iodone(bp) clrbuf(bp) binit() devstart(bp, devloc, devblk, hbcom) rhstart(bp, devloc, devblk, abae) mapalloc(abp) mapfree(bp) swap(blkno, coreaddr, count, rdflg) bflush(dev) physio(strat, abp, dev, rw) geterror(abp) ./dmr/cat.c:ctopen(dev) ctclose() ctwrite(dev) catintr() ./dmr/dc.c:dcopen(dev, flag) dcclose(dev) dcread(dev) dcwrite(dev) dcxint(dev) dcrint(dev) dcsgtty(dev, av) ./dmr/dh.c:dhopen(dev, flag) dhclose(dev) dhread(dev) dhwrite(dev) dhrint() dhsgtty(dev, av) dhparam(atp) dhxint() dhstart(atp) ・・・
関数の数がよくわからないので、')' を数えて関数の数とする。
$ for i in `find . -name "*.c"` ;do FN=`grep "^[a-z]*(.*)" $i`; NF=`echo $FN | awk -F\) 'NF>0 {print NF-1}'`; echo $i": "$FN": "$NF ;done
結果:
./conf/mkconf.c: main() puke(s, a) input() equal(a, b) getchar(): 5 ./conf/sysfix.c: main(argc, argv) getrel(r): 2 ./dmr/bio.c: bread(dev, blkno) breada(adev, blkno, rablkno) bwrite(bp) bdwrite(bp) bawrite(bp) brelse(bp) incore(adev, blkno) getblk(dev, blkno) iowait(bp) notavail(bp) iodone(bp) clrbuf(bp) binit() devstart(bp, devloc, devblk, hbcom) rhstart(bp, devloc, devblk, abae) mapalloc(abp) mapfree(bp) swap(blkno, coreaddr, count, rdflg) bflush(dev) physio(strat, abp, dev, rw) geterror(abp): 21 ./dmr/cat.c: ctopen(dev) ctclose() ctwrite(dev) catintr(): 4 ./dmr/dc.c: dcopen(dev, flag) dcclose(dev) dcread(dev) dcwrite(dev) dcxint(dev) dcrint(dev) dcsgtty(dev, av): 7 ./dmr/dh.c: dhopen(dev, flag) dhclose(dev) dhread(dev) dhwrite(dev) dhrint() dhsgtty(dev, av) dhparam(atp) dhxint() dhstart(atp): 9 ./dmr/dhdm.c: dmopen(dev) dmclose(dev) dmint(): 3 ./dmr/dhfdm.c: dmopen(dev) dmclose(dev): 2 ・・・
さらに、この結果に対して、 定義関数の数字を奇麗に出してみる。
$ for i in `find . -name "*.c"` ;do FN=`grep "^[a-z]*(.*)" $i`; NF=`echo $FN | awk -F\) 'NF>0 {print NF-1}'`; echo $i": "$FN": "$NF ;done | awk -F: '{printf("%3d\t%s\n",$3,$1)}'
結果:
5 ./conf/mkconf.c 2 ./conf/sysfix.c 21 ./dmr/bio.c 4 ./dmr/cat.c 7 ./dmr/dc.c 9 ./dmr/dh.c 3 ./dmr/dhdm.c 2 ./dmr/dhfdm.c 4 ./dmr/dn.c 10 ./dmr/dp.c 7 ./dmr/hp.c 5 ./dmr/hs.c 9 ./dmr/ht.c 7 ./dmr/kl.c 7 ./dmr/lp.c ・・・
関数名に数字[0-9]を入れるのを忘れてた、ということで以下修正版:
$ for i in `find . -name "*.c"` ;do FN=`grep "^[a-z0-9]*(.*)" $i`; NF=`echo $FN | awk -F\) 'NF>0 {print NF-1}'`; echo $i": "$FN": "$NF ;done | awk -F: '{printf("%3d\t%s\n",$3,$1)}'
まあ、細かいこと言うとアセンブラソースの中の定義関数は入ってないし、 行の先頭以外で定義した関数(あるかどうか知らないが)は関知してない。
※うーむ、はてなって長い行のソースコードは折り返して表示してくれないんだな。
(追記)以下のサイトのCSS使ったら、折り返してくれた。 preタグ内のコードをボックス枠内で折り返すcss | DAICHIFIVE blog
以上。