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() 手続きも未掘です