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);