2011/10/16

[bb]kernelのブートから切り替わるところを見ていこう

kernelのブートは、うまくいく。
nfsもうまくいく。
exportしている/lib/modulesにkernelバージョンをあわせたものを置くとエラーが出なくなったので、nfsマウントしたファイルを読みに行っている。

nfsマウントしたファイルをアクセスしに行っているのは、たぶんユーザランド側だと思うのだけど、確信がない。
調べてみよう。


INIT: version 2.86 booting

これは、どっちが出しているのだろう?
Androidやってたときには出なかったので、たぶんユーザランドだ。
kernel起動すると最初に起動するのは、bootargsで指定したinitプロセスだ。
今回のbootargsはこうなっている。

Kernel command line: mem=99M console=ttyS2,115200n8 noinitrd ip=192.168.0.22::192.168.0.1:255.255.255.0 root=/dev/nfs nfsroot=192.168.0.2:/home/xxx/Qt/nfs,nfsvers=3,nolock,rsize=1024,wsize=1024 rootfstype=nfs mpurate=600 omapfb.rotate=1 omapfb.vrfb=y vram=10M omapfb.vram=0:10M omapdss.def_disp=dvi omapfb.mode=dvi:720x480MR-16@60

長いな・・・まあ仕方あるまい。
ともかく、initは指定していない。
指定していない場合なにが起動するかは・・・kernelのソースを見ないとわからん。
とは限らないが、そこから見ていこう。

kernelのほどほどの最初は、init/main.cにあるstart_kernel()だろう。
「ほどほど」というのは、一番最初はブートとかkernelの解凍とかになってしまうけど、そこら辺はあまり知らないからだ。
armの場合、arch/arm/kernel/head-common.Sからstart_kernelは呼ばれているようだ。


丹念に追っていけばいいのだが、めんどうなので端折ろう。
ソースを眺めていると、init_post()の中に/sbin/initなんかを起動させそうな箇所がある。
これは、start_kernel()の一番最後にあるrest_init()からkernel_init()を別スレッドとして起動することで呼び出されるようだ。

PSP環境の/を見ると、linuxrcというファイルがあるのでgrepすると、do_mounts_initrc.cの中にある。
これもたどっていくと、kernel_init()で呼び出されているが、順序としてはinit_post()より前だ。

つまり、/linuxrcを先に実行して、/sbin/initのようなinitプロセスを実行させるのだろう。
initは、

  1. /sbin/init
  2. /etc/init
  3. /bin/init
  4. /bin/sh

という順で探しに行き、たぶんどれか1つ実行できれば終わりだ。
なければkernel panicする。
PSP環境には/sbin/initがあるので、これが動くのだろう。


では、linuxrcと/sbin/initを見ていこう。

PSPとして入手できたファイルの中には、linuxrcもinitもバイナリしかない。
linuxrcはbusyboxで、initはinit.sysvinitだ。
init.sysvinitはbusyboxではない。うーむ。
出所がわからないので、initもbusyboxのを見てみよう。

 

busyboxでは、initのことしか出てこない。
linuxrcは、initのオプションでinitrdを有効にすることでできる。

initrdって「initialize RAM disk」の略だろうか。
よくよくkernel_init()を見ると、linuxrcが実行されるのはRAM diskで実行させたときだけのような気がする。
となると、/sbin/initだけ気にすればよいか。

えーい、めんどうなので、busyboxを自分でビルドして差し替えてみよう。

VFS: Mounted root (nfs filesystem) on device 0:12.
Freeing init memory: 168K
Warning: unable to open an initial console.
Kernel panic - not syncing: No init found.  Try passing init= option to kernel.

これは・・・4つのinitのうちどれかを実行しようとしたけど、どれもだめだったときのpanicではないか。
ファイルはあるし、アクセス権もroot.rootにあわせたんだけどなぁ。

「unable to open…」は、kernelが/dev/consoleをオープンできなかったときに出している。
PSPで使われていた/devを持ってくると出なくなった。
もしかするとファイルシステムが見えていないのでは、と思ったが、そういうわけではなさそうだ。

しかしinitの実行はできていない。
PSPのinit.sysvinitをコピーしてもだめだったので、initの問題ではなさそうだ。
では、PSP環境の/sbin/initを削ってみると・・・シェルが起動した。
ってことは、やはりPSP環境版はちゃんと動くんだ。


そういえば、PSP環境版で固まると思ったのも「Starting thttpd」で止まってしまうからというだけだ。
rc5.dからhttpdを取り除くといいのかと思ったが、そうではないようだ。
たぶん、httpdは動いているが、その次のomap-demoが動かずに固まっているか、動いているけどディスプレイに表示されていないかだろう。

整理できなくなってきたので、一旦筆を置こう。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。