xv6.pdf

ホットスプリング(温泉)にスプリング(春)が来る。
 スプリング(活力)を得てスプリング(跳躍)しよう。
                      ルー大柴の弟子

とまあ、英語のスプリングには色々な意味が込められているそうな。でも、スプリングには もう一つ意味がある。

車に乗れば4000から5000個に及ぶスプリングを使う事になるし、パソコンを使えば、古いパソコンにハードディスが搭載されてて、読み出しヘッドを微妙に浮かせるためにスプリングが使われている。

ハードディスと言えば、 HDD用バネで価格カルテル談合 日本発条とTDK 課徴金11億円なんてのが記憶にあるな。ここに出て来る日本発条って、略称がNHKなのね。と思ってたら、天下のNHKに遠慮してか、 NHKニッパツって、呼んでくださいって言ってるみたい。 まあ、どうでもいいけど。

オイラーのパソコンは、HDDじゃなくてSSDだから関係ねぇと考えるのは甘い。キーボード大好き人間は、キーを叩く度にばねにお世話になってるぞ。GUIな人はマウスでカチカチするけど、それを下支えしてるのは、勿論ばね。

パソコンなんて使わんと言う新人類でも、部屋の明かりぐらいは点けるでしょ。電源スイッチにもばねが内蔵されてるよ。電源コンセントの中にもばねは入ってる。もう逃れませんな。 あんたの体の筋肉もばねと言えばばねだもんね。

ああ、ばねの日本語語源は、跳ねるから来てるそうですよ。(なまるとばねになる)もう、逃れませんです。

『ばね基礎のきそ』なんて本からの受け売り。そもそものきっかけは、コイルばねの材料って、 ピアノ線だよな。あんな硬い線を丸めてスプリングに出来るなって素朴な疑問が沸いたから、手にした次第。

熱を加えて柔らかくしてから加工。後は焼き入れ、やきなましで、望む特性を出すとか。 熱を加えるって言っても、300度ぐらいの冷間処理の場合もあれば、900度ぐらいの熱間形成と 大きく分けて2種類あるとか。

竹細工とか木工細工でも、熱を加えて柔らかくして行うってのがセオリーみたいだから、共通事項なのね。

そう言えば、昔はよく見たばね測り、最近見かけないな。体重計も圧力センサーが主流だもんな。圧力センサーは、スマホにも埋め込まれているな。この圧力センサーを使って、スマホ体重計って出来ないかな。お相撲さんの体重も楽々測れます、なんていうスマホが出たら、みんな飛びつくと思うんだけど、どうでっしゃろ。>あぷるさん。

xv6.pdf

この間から、マサチューセッツ工科大学(MIT)のOS製作学習キット xv6に取り組んでいる。キットに付属の取り扱い説明書(README)には、色々な所からソースを 貰ってきたのでその謝辞とクレジット、それから簡単な動かし方しか書いてない。細かい事は 授業で説明するからね、って方針なのかな?

極東の島国に住むオイラーは自習を余儀なくされる。で、つらつらとMakefileを眺めていたんだ。多分有益な楽しみ方が書いてあると思ってね。で、見つけたのがこれ。

# make a printout
FILES = $(shell grep -v '^\#' runoff.list)
PRINT = runoff.list runoff.spec README toc.hdr toc.ftr $(FILES)

xv6.pdf: $(PRINT)
        ./runoff
        ls -l xv6.pdf

print: xv6.pdf

printoutを作るって何ざんしょ? 雰囲気からして、ソースリストをまとめてPDFにしてくれそうだな。解説書はネットに既に公開されてるから、2つ合わせて自前の自習書にしてくださいって魂胆だろうな。ならば、やってみるか。素直にdebian9を使う事にする。

deb9:xv6-public$ make print
./runoff
This script takes a minute to run. Be patient.
assuming that sheet 1 is a left page.  double-check!
mp.c does not start on a left page [7200]
./runoff: 222: ./runoff: mpage: not found
fatal: Not a git repository (or any parent up to mount point /tmp)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
ugly font!
ls -l xv6.pdf
-rw-r--r-- 1 sakae sakae 2217 Feb 27 14:54 xv6.pdf

git repositoryって、.gitの中に詰まってる巨大な履歴かな。だったらそれは削除してるんで無視するとして、汚いフォントも我慢しよう。でもrunoffってスクリプトの中で使ってるmpageって何者? 探してみる。

deb9:xv6-public$ apt-file search bin/mpage
deb9:xv6-public$ sudo apt install mpage
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package mpage is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

E: Package 'mpage' has no installation candidate

そんな物はdebianには無いとな。一体どんな使われ方をしてるの? runoffを覗いてみるか。

# format the whole thing
(
        ../pr.pl README
        ../pr.pl -h "table of contents" toc
        # pr -t -2 t.defs | ../pr.pl -h "definitions" | pad
        pr -t -l50 -2 refs | ../pr.pl -h "cross-references" | pad
        # pr.pl -h "definitions" -2 t.defs | pad
        # pr.pl -h "cross-references" -2 refs | pad
        for i in $files
        do
                ../pr.pl -h "xv6/$i" $i
        done
) | mpage -m50t50b -o -bLetter -T -t -2 -FCourier -L60 >all.ps

ps2pdf allf.ps ../xv6.pdf

ざっと眺めると、fmtって言う作業dirを作り、その中に印刷すべきファイル類をコピー。パあるの助けを借りて定義だとかを抽出。それらを元に上のスクリプト片でpsファイルを作る。 最後にそれをpdfに変換してるとな。mpageはその重要な部分を占めているんだな。

mpage

debianに無いのはちょっと腑に落ちないけど、ここで足踏みしてもしょうがないので、OpenBSDに有るか調べてみる。

$ cat /usr/ports/print/mpage/pkg/DESCR
Mpage reads plain text files or PostScript documents and prints them on a
PostScript printer with the text reduced in size so that several pages
appear on one sheet of paper.  This is useful for viewing large printouts
on a small amount of paper.

プレインファイルをPSファイルに変換すると同時に、紙の節約のため、縮小印刷もするんだな。

COMMENT=        print multiple pages per sheet on PostScript printer

MASTER_SITES=   http://www.mesa.nl/pub/mpage/ \
                ftp://ftp.mesa.nl/pub/mpage/ \
                ftp://ftp.mesa.nl/pub/mpage/old/

ソースの在処が分かった。こういう時はportsの情報は有り難いな。 早速入れて、走らせてみた。

$ gmake xv6.pdf
./runoff
This script takes a minute to run. Be patient.
assuming that sheet 1 is a left page.  double-check!
mp.c does not start on a left page [7200]
%%Pages: (atend)
%%Pages: 100
fatal: Not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
ugly font!
ls -l xv6.pdf
-rw-r--r--  1 sakae  wheel  171834 Feb 27 16:12 xv6.pdf

成果

debianにもmpageを入れてあげたよ。縮小印刷する時に便利だからね。上記の設定だと、 1枚の用紙に左右50行づつ印刷される。mpage自体は、デフォで4ページをまとめて1枚にし、 印刷するという、若者仕様になってた。

# basic headers         # system calls          67 pipe.c
01 types.h              32 traps.h
01 param.h              32 vectors.pl           # string operations
02 memlayout.h          33 trapasm.S            69 string.c
02 defs.h               33 trap.c
04 x86.h                35 syscall.h            # low-level hardware
06 asm.h                35 syscall.c            70 mp.h
07 mmu.h                37 sysproc.c            72 mp.c
09 elf.h                                        73 lapic.c
                        # file system           76 ioapic.c
# entering xv6          38 buf.h                77 kbd.h
10 entry.S              39 sleeplock.h          78 kbd.c
11 entryother.S         39 fcntl.h              79 console.c
12 main.c               40 stat.h               83 uart.c
                        40 fs.h
# locks                 41 file.h               # user-level
15 spinlock.h           42 ide.c                84 initcode.S
15 spinlock.c           44 bio.c                84 usys.S
                        46 sleeplock.c          85 init.c
# processes             47 log.c                85 sh.c
17 vm.c                 49 fs.c
23 proc.h               58 file.c               # bootloader
24 proc.c               60 sysfile.c            91 bootasm.S
30 swtch.S              66 exec.c               92 bootmain.c
31 kalloc.c
                        # pipes

1枚目の左側にREADMEが表示され、その右側にtocと称する、関係者一同のファイルが列挙されてる。ファイル名の左側の数字は、そのファイルの掲載ページ。ユーザーランドの関係者のうち 大事なアプリが登場してる。

PHYSTOP 0203
    0203 1234 1812 1826 1827
    3168

続いてこんなクロスレファレンスが付いてくる。PHYSTOPって定義は、203行目で行われてるよ。この定義は、203,1234,18126,1827,3168行目から参照されてるよ。 そして最後は、各ファイルの内容が4桁の通し番号付きで、92頁に渡って掲載されてる。

これはもう、ASCIIから出版されてる unix v6の解説本そっくりのしかけだ。 (時代の流れかASCII出版が無くなってた。ソースコードのPDFが見つかった。今ならxv6用の日本語解説書はじめてのOSコードリーディングが良いだろう) 勿論、解説の 部分は、上であげた解説書に譲る事になる。これだけあれば、パソコンが無くても、リストと 解説書を元に、いつでもどこでも、OSの勉強が出来るよ。

ああ、オイラーはこの資料をOS関係のものとはとらえていないけどね。オイラーの捉え方は、 糞石の特権機構をどう操っているかの実例と思ってる。

電源入れてBIOSが走り、リアルモードを脱出してプロテクトモードへと成長させる、石の歴史を そのままなぞる、進化。そして、まだ詳しくみてないけど、石へ割り込みをかけて、実行の流れを無理やりに変えちゃう方法。まあ、おかげで糞石嫌いという抵抗感は大分低下したよ。

パソコンが有るなら

折角ここまでやってきて、リストを紙に出すってのが資源の無駄と思ってる。ならばPDFを眺めるなり、行番号で検索するとか、関数名等で検索するとか考えられるな。uv6の本の時はそうしていたけど、煩雑過ぎる。

今なら、etag作って、TagJumpで一発だな。(PHYSTOPでjumpすれば、memlayout.hへ一直線に飛んで行く)じゃ、参照はどうする? そんなの、emacsの中からgrep一発。

grep --color -nH -e PHYSTOP *.[chS]
kalloc.c:64:  if((uint)v % PGSIZE || v < end || V2P(v) >= PHYSTOP)
main.c:35:  kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers()
memlayout.h:4:#define PHYSTOP 0xE000000           // Top physical memory
vm.c:95://   data..KERNBASE+PHYSTOP: mapped to V2P(data)..PHYSTOP,
vm.c:100:// between V2P(end) and the end of physical memory (PHYSTOP)
vm.c:101:// (directly addressable from end..P2V(PHYSTOP)).
vm.c:113: { (void*)data,     V2P(data),     PHYSTOP,   PTE_W}, // kern data+memory
vm.c:127:  if (P2V(PHYSTOP) > (void*)DEVSPACE)
vm.c:128:    panic("PHYSTOP too high");

M-x grep すると、画面が割れて、上記のように出て来るんで、その画面にカーソルを移してから、n,pとかすれば、検索結果の近傍が動的に表示される。これ、なかなか便利。

組版

egrepした結果と、クロスレファレンスで出て来る結果が微妙に違う。クロスレファレンスの方は、コメントに表われているものがカットされてるよ。芸が細かいなあ。

芸が細かいと言えば、pdfを作る時に出てた、mp.c does not start on a left pageもそうだ。mp.cは、左側のページから始まるべきという、組版の主張。そのために、runoff.specって ファイルをわざわざあつらえて、チェックしてるよ。この警告を消すには、left指定をright指定に変えればよい。そうすると、無駄なブランクページが追加されて辻褄を合わせてくれる。 (オイラーも暇な事をやってるな)

折角なので、組版スクリプトの中で、どうやってクロスレファレンスを作っているか、観察しておく。

# make reference list
for i in `awk '{print $2}' defs | sort -f | uniq`
do
        defs=`egrep '^[0-9]+ '$i'( |$)' defs | awk '{print $1}'`
        echo $i $defs >>s.defs
        uses=`egrep -h '([^a-zA-Z_0-9])'$i'($|[^a-zA-Z_0-9])' alltext | awk '{print $1}'`
        if [ "x$defs" != "x$uses" ]; then
                echo $i $defs
                echo $uses |fmt -29 | sed 's/^/    /'
#       else
#               echo $i defined but not used >&2
        fi
done
) >refs

fmtで印字幅を29文字以内に収めて、冒頭に数文字の空白を入れると、ああなるのか。ちょっと した組版の技だな。

$ echo 111 222 333 444 555 666 777 888 999 | fmt -10 | sed 's/^/   /'
   111 222
   333 444
   555 666
   777 888
   999
$ echo 111 222 333 444 555 666 777 888 999 | fmt -13 | sed 's/^/   /'
   111 222 333
   444 555 666
   777 888 999
$ wc *
   13112   95801  527176 all.ps
   13112   95801  527176 allf.ps
    9200   22314  158012 alltext
     574    1368    8573 defs
    1195    4110   24862 refs
     537    1111    7177 s.defs
     574    1148    7399 t.defs
      45     278    1689 toc
      55     165     988 tocdata
   38404  222096 1263052 total

これはpdfを作るための、各種作業ファイル。この他に *.[chS] があるけど、コピーされる 段階で、行頭に通し番号が振られている。

%!PS-Adobe-2.0
%%DocumentFonts: Courier Times-Bold
%%Title: <stdin> (mpage)
%%Creator: mpage 2.5.7 June 2017
%%CreationDate: Wed Feb 28 16:38:49 2018
%%Orientation: Landscape
%%DocumentMedia: Letter 612 792
%%BoundingBox: 18 50 594 742
%%Pages: (atend)
%%EndComments

これ、all.psの冒頭部分。汚いFontの代表として、Courierが採用されてる。オイラーに取って 綺麗、汚いフォントを論じる前に、大事な要件が有る。Oと0がきちんと視認出来るか? lと1が 間違わずに見分けられるかだ。

最近は、Oと0の区別がコンテキストで大体把握出来るようになった。(って、言ってもgccのコマンドオプション中に出て来る、-O0 ぐらいだけどね。)でも、後者はいかんともしがたいな。それから、よく間違えるのが、,と.だ。間違ると、人工衛星が墜落して、うん十億円の損失になるぞ。後は、;と:かな。まあ、こちらは焦っていなければ、文脈で判断付くけど。

prを日本語で

prなんてコマンド何をやってくれるか知らない。素のmanは英語だ。日本語したい。 んな訳で、(少々古くてもいいから)日本語でmanを読みたい。この希望はきっとかなえられるでしょう。

deb9:man1$ apt-cache search manpages | grep ja
manpages-ja - Japanese version of the manual pages (for users)
manpages-ja-dev - Japanese version of the manual pages (for developers)
deb9:man1$ sudo dpkg-reconfigure locales
deb9:man1$ locale -a
C
C.UTF-8
POSIX
en_US.utf8
ja_JP.utf8
deb9:man1$ LANG=ja_JP.utf-8
deb9:man1$ man pr

原稿は有ったので入れてあげる。日本語表示を出来るようにロケールを追加。日本語モードにする。(常に日本語だと、文字化けしちゃうシーンが有るので、通常は、帝国言語です。そしてmanする。

昔のFreeBSDはきちんと日本語のmanが読めたんだけど、メンテナの方が引退されてしまったようで、今は見る影もない。段々と過疎っていくなあ。