initramfs 関連整理
ちょっと整理できてない事に気づいたので。
startup
最初らへんは略して start_kernel() あたりから。様々な初期化を行なった後に、いっちゃんケツで rest_init() 手続きを呼び出します。
/* Do the rest non-__init'ed, we're now alive */ rest_init(); }
で、rest_init() 手続きの先頭でカーネルスレッドを生成。
static void noinline rest_init(void) __releases(kernel_lock) { kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);
これが将来的に pid が 1 の init になる。んですがこの時点ではまだカーネルスレッドな状態。プロセスは生成されているが、その後、schedule() 手続きが呼ばれないとスケジュールされないとの事。
init
で、カーネルスレッドとして kick される init() 手続きは init/main.c のいっちゃんケツにて定義。initramfs.c にて定義されている populate_rootfs() 手続きが呼び出されるのは init() で定義されている以下な手続き経由となります。
do_basic_setup();
ここからどうやって populate_rootfs() が呼ばれるかは年末のエントリにて書いてるので略。そしてここからどうやって rootfs にイメージが展開されるかは未着手の課題ッス。
その後
init() なカーネルスレッドから populate_rootfs() が呼ばれて rootfs が展開された後、以下あたりを経由して initramfs の中の init が起動されるはず。
if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) printk(KERN_WARNING "Warning: unable to open an initial console.\n"); (void) sys_dup(0); (void) sys_dup(0); if (ramdisk_execute_command) { run_init_process(ramdisk_execute_command); printk(KERN_WARNING "Failed to execute %s\n", ramdisk_execute_command); }
0, 1, 2 なファイルディスクリプタを準備した後に ramdisk_execute_command が NULL でなければ (initrd 経由な起動であれば NULL ではあり得ない)、run_init_process() 手続きを呼び出している。
その run_init_process() 手続きの定義は以下の通りで
static void run_init_process(char *init_filename) { argv_init[0] = init_filename; kernel_execve(init_filename, argv_init, envp_init); }
exec してるという事はここから戻ってくることは無いはず。おおよそざっくりな流れがこれです、って言って構わないのかな。
# ちなみに kernel_execve() 手続きも未掘です