/var/log/messages

2009-01-14

[] でびあんの initrd

_CentOS で試す_を改題。しかもそろそろ pukiwiki なひらメソドに移行した方が良さげ、って思いつつ。

scripts/functions

先頭部分の手続き。

log_success_msg()
{
	_log_msg "Success: $@"
}

log_failure_msg()
{
	_log_msg "Failure: $@"
}

log_warning_msg()
{
	_log_msg "Warning: $@"
}

については、$quiet が "y" でなければ _log_msg 手続きに渡した文字列が echo されます。echo だけ、とゆーあたりが若干微妙ですが仕方ないのか他に手があるのかは不明。

次。

log_begin_msg()
{
	if [ -x /sbin/usplash_write ]; then
		/sbin/usplash_write "TEXT $@"
	fi
	_log_msg "Begin: $@ ..."
}

log_end_msg()
{
	if [ -x /sbin/usplash_write ]; then
		/sbin/usplash_write "SUCCESS ok"
	fi
	_log_msg "Done."
	update_progress
}

/sbin/usplash_write というソレが実行可能であれば出力している。usplash_write については別途。ちなみに log_end_msg 手続きのいっちゃんケツで呼び出されている update_progress 手続きですが、意味を図りかねております。

update_progress()
{
	[ -d /dev/.initramfs ] || return

となってて init の中で log_end_msg 手続きが最初に呼び出される前に

mkdir /dev/.initramfs

されているんで上記以降の命令は実行されないはず、と見てるんですがダウトでしょうか。

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