minix3

世間の児童と学生さん達は、待ちに待った夏休みが始まった。8月一杯の休みで、ゆとり教育 なんですねぇ。おいらの頃は、7月末からお盆までの3週間ぐらいだったような。。 宿題がたっぷり出て、休みの終わり頃は大変だったよな。

夏休みと言えば、朝6時30分から始まる、ラジオ体操に出て、皆勤するとご褒美を貰える なんてのがあったなあ。懐かしい。そーだ、あの頃にトリップして、ラジオ体操でもやって みるかな、なんて事を寝る前に思いついた。

ラジオ体操と言えば、今じゃ、第一から第四までもあるご時勢だけど、軽く ラジオ体操第一・二 をやってみた。時間にして6分ぐらいかな。

でも、翌朝、肩が痛いのなんの。女房には、あんた年だからと、笑われる、笑われる。 そこでまた、ふっと思い出した。中国へ行った時(台湾だったかも)、朝公園を散歩してたら、 どこからもとなく、人々が集まってきて、太極拳を始めた事を。あれなら、動作がゆるいから 大丈夫かな。ビデオを探してみよーと。色々あるな。 これがいいかな? でも、とっても長くて、 途中でバテそうだな。

こう暑いと、昼はじっとシエスタ(昼寝)をするに限るな。こんな極楽はなかなか、有るもんじゃ ありませんよ。

minix

ずっとFreeBSDのソースを追っているんだけど、変態CPUのおかげでさっぱり読みたい所が 読めていない。もっとやさしいのはないかと思って本棚をみたよ。そしたら、約20年前に 読んで投げ出していた、"MINIXオペレーティングシステム"なんてのが目に飛び込んできた。 監修が、坂本 文 さんとは懐かしい。この方が書いた、楽しいUNIX なんて本を一生懸命に 読んだっけ(と、遠い目)

このMINIX本、巻末にソースが付いているんだけど、ソースはやっぱりマシンの上で読みたい。 ネットで探したら、世界の百科事典に説明が出てた。 minixとは?を読むと、今はVer3に進化してるらしい。 そして、参考を辿って行ったら、 MINIXが今VMware Playerでよみがえる!なんてのに行き着いた。 これはもう、入れてみる鹿。

総本山へ行って、ISO.gzを落としてきた。やけに大きい サイズなのは、コンパニオンさんも同梱してるから? 入れてみれば分かるよね。

Install minix3 on VMWarePlayer3

OSのカテゴリーは、LinuxでもないしFreeBSDでもないし、1秒悩んで、その他のその他を 選択。HDDは勘で4Gもあれば十分と判断。メモリーは、太っ腹で512Mを指定。CDからbootしたら rootでloginして、setupを実行。後は言われるままにした。一応入ったら、VMWareに、 インストールを完了しましただと報告しといて、再起動。

次はコンパニオンアプリを入れる。コマンドは、packman。貧乏性なおいらは、みんな要りかつ ソースもねを選んだ。待つ事、1時間ぐらいかな。全部入った、けど、肝心なopensshが CDには収録されてなかったんで、もう一度packmanを起動して、ネットからopensshだけを 追加インストール。これが終わったら再起動。何かすると再起動って、どこかの某OSみたい だけど、暑さで頭が回らないので勘弁ね。

DHCPでVMwareからIPを貰えるように設定しておいたので、OSが上がってくると(ウブンツの 高速bootなんかより、ずっと高速で起動するぞ)、sshでlogin出来る体制になっている。 早速、PuTTYからloginしてみた。

# uname -a
Minix aaa.bbb.ccc.ddd 3 1.7 i686
# df
Filesystem      Size (kB)       Free       Used    % Files%   Mounted on
/dev/c0d0p0s0       65536      57804       7732  12%     2%   /
/dev/c0d0p0s2     3316388    1377216    1939172  59%    11%   /usr
/dev/c0d0p0s1      811008     798184      12824   2%     1%   /home
/dev/c0d2p2        614400      89352     525048  86%    25%   /mnt

ホスト名がIPアドレス(意味なく伏字)になってるのは大胆だなあ。普通はホストアドレス と任意の文字列を組み合わせると思うのだけど。DISKの使いっぷりも余裕があって宜しい ですな。

# ps ef
  F S UID   PID  PPID  PGRP     SZ         RECV TTY  TIME CMD
  2 W   0  (-4)     0     0      0                ? 12:05 idle
  2 W   0  (-3)     0     0      0                ?  0:00 clock
  2 W   0  (-2)     0     0      0                ?  0:00 system
  2 W   0  (-1)     0     0      0                ?  0:00 kernel
  0 R   0     5     4   214      0                ?  0:01 pm
 10 W   0     7     4     0      0          ANY   ?  7:58 vfs
 10 W   0     4     1     0      0          ANY   ?  0:00 rs
 10 W   0     8     4     0      0          ANY   ?  0:00 memory
 10 W   0     9     4     0      0          ANY   ?  0:00 log
 10 W   0    10     4     0      0          ANY   ?  1:54 tty
 10 W   0     3     4     0      0          ANY   ?  0:00 ds
 10 W   0    12     4     0      0          ANY   ?  0:02 vm
 10 W   0    13     4     0      0          ANY   ?  1:46 pfs
 10 W   0     6     4     0      0          ANY   ?  0:00 sched
 10 S   0     1     0     1      0    (wait) pm   ?  0:00 init
200 W   0    14     4     0      0                ?  0:00 log
 10 W   0    17     4     0      0          ANY   ?  0:00 pci
 10 W   0    19     4     0      0          ANY   ?  0:00 floppy
 10 W   0    22     4     0      0          ANY   ?  0:00 at_wini
 10 W   0    24     4     0      0          ANY   ?  0:00 at_wini
 10 W   0    32     4     0      0          ANY   ?  3:04 mfs
 10 W   0    37     4     0      0          ANY   ?  0:00 is
 10 W   0    52     4     0      0          ANY   ?  0:00 mfs
 10 W   0    58     4     0      0          ANY   ?  0:00 mfs
 10 W   0    65     4     0      0          ANY   ?  0:01 random
 10 W   0    80     4     0      0          ANY   ?  0:02 lance
 10 W   0    83     4     0      0          ANY   ?  0:00 inet
 10 W   0    86     4     0      0          ANY   ?  0:00 printer
 10 W   0    89     4     0      0          ANY   ?  0:00 ipc
 10 W   0   301   151   151      0           pm  p0  0:00 ps
 10 S   0    92     1     1      0 (select) vfs   ?  0:00 update
 10 S   0    94     1     1      0   (pause) pm   ?  0:00 cron
 10 S   0    98     1    98      0 (select) vfs   ?  0:00 syslogd
 10 S   0   101     1     1      0 (select) vfs   ?  0:00 dhcpd
 10 S   0   103     1     1      0 (select) vfs   ?  0:00 nonamed
 10 S   2   112     1   112      0 (select) vfs   ?  0:00 exim
 10 S   0   121     1   121      0 (select) vfs   ?  0:00 sshd
 10 S   0   123     1   123      0    (tty) vfs  c1  0:00 getty
 10 S   0   124     1   124      0    (tty) vfs  c2  0:00 getty
 10 S   0   125     1   125      0    (tty) vfs  c3  0:00 getty
 10 S   0   148     1   148      0    (tty) vfs  co  0:00 getty
 10 S   0   149   121   149      0 (select) vfs   ?  0:02 sshd
 10 S   0   151   149   151      0    (wait) pm  p0  0:00 sh

PIDがマイナスになってるのが目新しいな。こういうのは、普通のUnixでは見られない。 MINIX本を拾い読みした所、マイナスが付いてるのが、本当のカーネルプロセスで、他の ものは、カーネル外(いわゆるユーザープロセス)のプロセスって事だな。小さい事は いい事だ、が実践されてます。後面白いのが、RECVって項目。メッセージのやり取りで 仕事が進んで行くっていう設計になってるので、こんな項目を出してるんですね。

# ls /etc
X11                inet.conf             passwd            shadow
aliases            init.d                profile           sip
binary_sizes       keymap                protocols         syslog.conf
binary_sizes.big   make.conf             rc                system.conf
binary_sizes.xxl   mk                    rc.cd             termcap
fonts              motd                  rc.daemons.dist   ttytab
fstab              motd.install          rs.inet           utmp
group              mtab                  rs.single         version
hostname.file      packages-i386-3.1.7   services
# ls /usr/local/etc/rc.d
exim   postgres   sshd

etcの下はすっきりしてますなあ。これじゃ、某雑誌が時々特集する、/etcの中のファイルの 役割なんてのは、minixについては必要無いな。catで片っ端から開いてみれば、役割が想像 出来るよ。コンパニオンから入れたやつで、ダエモンになって欲しいやつは、/usr/local/etc/rc.dの 中に、上げ下げスクリプトを置いておくのね。FreeBSDみたいだな。

xdmを起動したら、アムステルダムの運河と自転車の写真がアクセントとして出てきた。 これぞオランダ。昔ドイツに駐留してた時、汽車を乗り継いでアムステルダムまで遊びに 行ったっけ。そして飾り窓を見学したり、風車を見学にも行ったな。フィンランド方面は 縁がないけど、アムステルダムとは懇意なのね。

嗚呼、xdmの画面なんて 何年ぶりに見るのだろうか?懐かしいぞ。そして、Xの設定なんて何もしてないのに、twmの 懐かしいのが、画面一杯に広がってきた。emacsは、21.4が入っていたけど、残念ながら ターミナルモードでしか動かんかった。よって、Xはもう封印する。

どんなソフトが入ってるの?

いろいろ入れたんで、どんなのが入ってるか、確認してみる。その前にずっとrootで作業は まずいよね。アカウントを作るのも少々かったるいので、デフォで入っている、タンネンバウム 教授(何故かバウムクーヘンを思い出したぞ)のアカウントを盗用させてもらった。 (passwd ast だけで済んじゃうから楽です!)

perlもpythonもluaも入っていたけど、東洋の秘宝 rubyは入っていなかった。ちょいと入れようか。 と、始めたのはいいんだけど、minix由来の cc では、しょっぱなからエラーになって しまい、箸にも棒にもかからない。しょうがないので、gccを使う事にした。

  :
gcc -g -O2    -DRUBY_EXPORT -I. -I.    -c dmyext.c
ar rcu libruby-static.a array.o  bignum.o  class.o  compar.o  dir.o  dln.o  enum.o  enumerator.o  error.o  eval.o  file.o  gc.o  hash.o  inits.o  io.o  marshal.o  math.o  numeric.o  object.o  pack.o  parse.o  process.o  prec.o  random.o  range.o  re.o  regex.o  ruby.o  signal.o  sprintf.o  st.o  string.o  struct.o  time.o  util.o  variable.o  version.o  fileblocks.o finite.o acosh.o erf.o dmyext.o
gcc -g -O2    -DRUBY_EXPORT -I. -I.    -c main.c
gcc -g -O2    -DRUBY_EXPORT -L.   main.o  libruby-static.a -lm   -o miniruby
/usr/gnu/bin/gld:libruby-static.a: file format not recognized; treating as linker script
/usr/gnu/bin/gld:libruby-static.a:1: parse error
collect2: ld returned 1 exit status
*** Error code 1

でも、見事にエラーだわさ。珍しい落ち方だ事。これはきっと、arがお気に召さないんだな。 しょうがないので、gnu由来の /usr/gnu/i386-pc-minix/bin/ar を使うようにしたら、上記 のエラーは回避出来た。けど、今度は少し進んだ所で、BFDが無いなんていうエラーが発生。 画して、東洋の秘宝は諦める事にしました。

minix3 には、ccと、コンパニオンとしてやってきたgccがあるので、ちと比べてみます。 お手軽に、ハローワールドです。

$ cc test.c
$ ls -l a.out
-rwxr-xr-x 1 ast  other  21208 Jul 21 14:48 a.out
$ file a.out
a.out: MINIX-PC 32-bit executable, sep I&D not stripped
$ strip a.out
$ ls -l a.out
-rwxr-xr-x 1 ast  other  19336 Jul 21 14:50 a.out

今度は、gnu系です。勿論、stripもgnu系です。

$ gcc test.c
$ ls -l a.out
-rwxr-xr-x  1 ast other 51486 Jul 21 14:52 a.out
$ strip a.out
$ ls -l a.out
-rwxr-xr-x  1 ast other 13064 Jul 21 14:53 a.out
$ file a.out
a.out: MINIX-PC 32-bit executable, NSYM, comm I&D stripped

ふむふむ、同じバイナリーでも、ドチラでコンパイルされたか分かるんだ。それなら、コンパニオン として入ってるのは、どちら系が多いのか、ちょいと調べてむる。

$ cd /usr/local/bin/
$ file perl
perl: MINIX-PC 32-bit executable, sep I&D not stripped
$ file zsh
zsh: MINIX-PC 32-bit executable, NSYM, comm I&D stripped
$ ls|wc
    428     428    3430
$ bash
[ast@aaa bin]$ for f in *
> do
> file $f
> done | grep NSYM | wc
    164    1471   10606
$ echo '100 * 164 / 428' | bc
38

幸いな事にbcが入っていたので、gnu率を計算してみたら、38%でした。資料によると、ccが お勧めのようであります。

折角なので、fileコマンドがどうなっているかソースに当たってみる。ソースの在り処は、 /usr/src/commands/file/ の中という所。教育的な配慮がしてあるなあ。なんたって、核 以外は、commandsなんですから。そういう配慮は、/sbin や /usr/sbin以下にもあって、ここに サーバー類とかドライバー類とかダエモンの類がまとめてある。詳しくは、man hier かな。

/* file - report on file type.          Author: Andy Tanenbaum */
/* Magic number detection changed to look-up table 08-Jan-91 - ajm */
 :
struct info {
  int execflag;                 /* 1 == ack executable, 2 == gnu executable,
                                 * 3 == core */
  unsigned char magic[4];       /* First four bytes of the magic number */
  unsigned char mask[4];        /* Mask to apply when matching */
  char *description;            /* What it means */
} table[] = {
  0x00, 0x1f, 0x9d, 0x8d, 0x00,         0xff, 0xff, 0xff, 0x00,
        "13-bit compressed file",
   :
  0x02, 0x0b, 0x01, 0x00, 0x00,         0xff, 0xff, 0xff, 0xff,
        "MINIX-PC 32-bit gnu executable combined I & D space",
  0x02, 0x00, 0x00, 0x0b, 0x01,         0xff, 0xff, 0xff, 0xff,
        "MINIX-68k gnu executable",
  0x03, 0x82, 0x12, 0xC4, 0xC0,         0xff, 0xff, 0xff, 0xff,
        "core file",
};

"Hello world!"を卒業した人は、こういう実用的なソースをどんどん読むべきですね。 教育用に変なテクニックを使ってないし、速読するにはうってつけと思います。

minixに特有な事

minix3になって、仮想記憶がサポートされたそうだけど、残念ながらまだ、swapがサポート されていない。メモリーが一杯になったら、そこで新しいアプリは起動出来なくなる。 普通のUnixだと、使ってなさそうなメモリーを追い出して、空きを作りそこへ新しいアプリを (強引に)押し込んじゃうんだけどね。

従って、minixでは、アプリが使うエリアを最小限にしておく必要がある。何を削ればいいかは 、アプリを作った人しか分からない。プログラムとデータは少なくするって言っても無理な 相談なので、スタックエリアを切り詰める(あるいは増やす)命令が用意されている。

$ size a.out
   text    data     bss    stack   memory
  14160    5144     144   131072   150520  a.out
$ chmem -520 a.out
a.out: Stack+malloc area changed from 131072 to 130552 bytes.
$ size a.out
   text    data     bss    stack   memory
  14160    5144     144   130552   150000  a.out

上記は、初期状態で、スタックが131072あったものを、chmemで多少削ってみたものだ。 スタックなんてそんなに使わないと分かっていれば、大胆に削っていい。どこまで削れるかは アプリ次第だ。