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のすなわちシステムのルートファイルシステムとなります。
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);


最終更新 2015/02/22 19:41:01 - north
(2015/02/22 19:41:01 作成)


検索

アクセス数
3575126
最近のコメント
コアダンプファイル - sakaia
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
Adsense
広告情報が設定されていません。