prepare_namespace
saved_root_nameはブート引数のroot=で設定され、それがフラッシュメモリデバイスのmtd/ubiなら、そのデバイスをrootfsの/rootにマウントします。
それ以外ならname_to_dev_t()でデバイス番号(メジャー番号/マイナ番号)を取得、ないし、すべてのドライバがインストールされるまで取得を試みます。
initrd_load()はinitrdが、cpioでなくブロックデバイスイメージの場合で、 rootfsにinitrdを展開するpopulate_rootfs()で、ブロックデバイスイメージなら、そのイメージをrootfsに/initrd.imageを作成しこのファイルにイメージが書き込まれます。これは/initrd.imageを/dev/ramに書き込む事でブロックデバイスとして取り扱いを可能とします。
ルートファイルシステムイメージのブロックデバイスを、rootfsの/rootにマウントすればOKです。ただしfdをルートファイルシステムとする場合、(fdによるブートのケース等)、ブート引数のload_ramdisk=のrd_doloadが0でないなら、fdイメージをrd_load_disk()で/dev/ram0に転送し、/dev/ram0をルートファイルといたします。この時ブート引数のrompt_ramdisk=が0でないなら、"root floppy disk to be loaded into RAM disk"とメッセージが表示されます。
mount_root()でROOT_DEVのブロックデバイスを/rootにマウントし、プロセス0のカレントディレクトリを/rootにし、カレントディレクトリを/として再マウント後、プロセス0のルートディレクトリをカレントディレクトリ(/root)とすることで、/rootをプロセス0のすなわちシステムのルートファイルシステムとなります。
execute_commandが設定されていないと、/sbin/init /etc/init /bin/init /bin/shと順に起動され、そうでなければパニックとなりブートに失敗します。また、initrdでもブロックデバイスイメージの場合はこの流れに準じることになります。
rootfsの/rootや/devは、.initcallrootfs.initセクションに配置されたdefault_rootfs()で作成されています。
それ以外ならname_to_dev_t()でデバイス番号(メジャー番号/マイナ番号)を取得、ないし、すべてのドライバがインストールされるまで取得を試みます。
initrd_load()はinitrdが、cpioでなくブロックデバイスイメージの場合で、 rootfsにinitrdを展開するpopulate_rootfs()で、ブロックデバイスイメージなら、そのイメージをrootfsに/initrd.imageを作成しこのファイルにイメージが書き込まれます。これは/initrd.imageを/dev/ramに書き込む事でブロックデバイスとして取り扱いを可能とします。
ルートファイルシステムイメージのブロックデバイスを、rootfsの/rootにマウントすればOKです。ただしfdをルートファイルシステムとする場合、(fdによるブートのケース等)、ブート引数のload_ramdisk=のrd_doloadが0でないなら、fdイメージをrd_load_disk()で/dev/ram0に転送し、/dev/ram0をルートファイルといたします。この時ブート引数のrompt_ramdisk=が0でないなら、"root floppy disk to be loaded into RAM disk"とメッセージが表示されます。
mount_root()でROOT_DEVのブロックデバイスを/rootにマウントし、プロセス0のカレントディレクトリを/rootにし、カレントディレクトリを/として再マウント後、プロセス0のルートディレクトリをカレントディレクトリ(/root)とすることで、/rootをプロセス0のすなわちシステムのルートファイルシステムとなります。
void __init prepare_namespace(void)
{
int is_floppy;
if (root_delay) {
printk(KERN_INFO "Waiting %dsec before mounting root device...\n",
root_delay);
ssleep(root_delay);
}
wait_for_device_probe();
md_run_setup();
if (saved_root_name[0]) {
root_device_name = saved_root_name;
if (!strncmp(root_device_name, "mtd", 3) ||
!strncmp(root_device_name, "ubi", 3)) {
mount_block_root(root_device_name, root_mountflags);
goto out;
}
ROOT_DEV = name_to_dev_t(root_device_name);
if (strncmp(root_device_name, "/dev/", 5) == 0)
root_device_name += 5;
}
if (initrd_load())
goto out;
if ((ROOT_DEV == 0) && root_wait) {
printk(KERN_INFO "Waiting for root device %s...\n",
saved_root_name);
while (driver_probe_done() != 0 ||
(ROOT_DEV = name_to_dev_t(saved_root_name)) == 0)
msleep(100);
async_synchronize_full();
}
is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
if (is_floppy && rd_doload && rd_load_disk(0))
ROOT_DEV = Root_RAM0;
mount_root();
out:
devtmpfs_mount("dev");
sys_mount(".", "/", NULL, MS_MOVE, NULL);
sys_chroot((const char __user __force *)".");
}
mount_root()でROOT_DEVのブロックデバイスを、/rootにマウントします。ROOT_DEVがfdでrd_doload==2の場合、fdイメージを/dev/ram1に再度複写します。prepare_namespace()で/dev/ram0に複写済です。これはルートファイルシステムを2毎のfdで構築する場合(たぶん)です。この時ROOT_DEVはRoot_RAM1で2枚目のfdとなり、初期ユーザプロセスとなるinitは2枚目に構築されている必要があります。1枚目の/dev/ram0はinitからmountすることで参照する物と思われます。
void __init mount_root(void)
{
#ifdef CONFIG_ROOT_NFS
if (ROOT_DEV == Root_NFS) {
if (mount_nfs_root())
return;
printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
ROOT_DEV = Root_FD0;
}
#endif
#ifdef CONFIG_BLK_DEV_FD
if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
if (rd_doload==2) {
if (rd_load_disk(1)) {
ROOT_DEV = Root_RAM1;
root_device_name = NULL;
}
} else
change_floppy("root floppy");
}
#endif
#ifdef CONFIG_BLOCK
create_dev("/dev/root", ROOT_DEV);
mount_block_root("/dev/root", root_mountflags);
#endif
}
prepare_namespace()でブロックデバイスをルートファイルシステムとすると、ブートパラメータのinit=で設定されるコマンドが (execute_commandに設定)初期プロセスとなります。cpioのinitrdではrdinit=で設定されるramdisk_execute_commandが初期プロセスとなり、rdinit=が設定されていないと、デフォルトでramdisk_execute_command=/initとなりますが、execute_commandはNULLのままです。execute_commandが設定されていないと、/sbin/init /etc/init /bin/init /bin/shと順に起動され、そうでなければパニックとなりブートに失敗します。また、initrdでもブロックデバイスイメージの場合はこの流れに準じることになります。
rootfsの/rootや/devは、.initcallrootfs.initセクションに配置されたdefault_rootfs()で作成されています。
static int __init default_rootfs(void)
{
int err;
err = sys_mkdir((const char __user __force *) "/dev", 0755);
if (err < 0)
goto out;
err = sys_mknod((const char __user __force *) "/dev/console",
S_IFCHR | S_IRUSR | S_IWUSR,
new_encode_dev(MKDEV(5, 1)));
if (err < 0)
goto out;
err = sys_mkdir((const char __user __force *) "/root", 0700);
if (err < 0)
goto out;
return 0;
out:
printk(KERN_WARNING "Failed to create a rootfs\n");
return err;
}
rootfs_initcall(default_rootfs);





