在mnt_init-->init_mount_tree:
分爲3部分來分析這個函數:
1、mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);這個是安裝操作的核心;
1.2、mnt = vfs_kern_mount(type, flags, name, data);
1.2.2、error = type->get_sb(type, flags, name, data, mnt);調用rootfs的get_sb方法rootfs_get_sb來獲取超級塊:
set_anon_super獲得一個未使用的次設備號dev,然後用主設備號0和次設備號dev設置s的s_dev字段
1.2.2.2、調用rootfs的fill_super(ramfs_fill_super)來分配索引節點對象和對應的目錄項對象,並填充超級塊字段值。這裏會建立rootfs的“/”目錄項對象和索引節點對象。
sb->s_root = root; 這個root就是“/”目錄項對象。
1.2.2.3、將mnt的mnt_sb指向剛建的super_block超級塊對象,將mnt的mnt_root指向sb的s_root對象("/"的目錄項對象)
1.2.3、
mnt->mnt_mountpoint = mnt->mnt_root; 安裝樹的根的目錄項和安裝點的目錄項都指向前面的root(rootfs的"/"目錄項對象)
mnt->mnt_parent = mnt; 將我們mount的文件系統指向自己。比如在/mnt/a下是mount了一塊ext2的磁盤,在/mnt/a/b下又mount omfs文件系統,那麼這裏的parent就可 以指明這個關係。
2、ns = create_mnt_ns(mnt);
新建一個私有的命名空間(mnt_namespace),並添加root fs:
mnt->mnt_ns = new_ns;
new_ns->root = mnt;
list_add(&new_ns->list, &new_ns->root->mnt_list);
3、
root.mnt = ns->root;
root.dentry = ns->root->mnt_root;
set_fs_pwd(current->fs, &root);
set_fs_root(current->fs, &root);
將進程0的根目錄和當前工作目錄設備爲根文件系統。
到目前我們看得rootfs都是基於內存的數據,要真正安裝根文件系統,就要安裝實際的文件系統。我們以磁盤的文件系統爲例。
在系統初始化的最後部分:
start_kernel-->rest_init-->kernel_init-->prepare_namespace
1、把root_device_name變量設置爲從啓動參數"root"中獲取的設備文件名。同樣把ROOT_DEV變量設置爲同一設備文件的主設備號和次設備號。
實際上代碼中會優先將root_device_name和mtd ubi做對比,如果有這樣的flash設備,就從flash上建立文件系統。
2、還是以磁盤說明,調用mount_root函數:
2.1、調用sys_mknod在rootfs初始根文件系統中創建設備文件/dev/root,其主次設備號與ROOT_DEV中的一樣。
2.2、分配一個緩衝區並用文件系統類型名鏈表填充它。該鏈表通過啓動參數"rootfstype"傳送給內核,也可以通過file_systems爲頭的單向鏈表中獲取元素建立。
2.3、掃描上面建立的鏈表,對每一種文件系統鬥調用sys_mount在根目錄上安裝給定的文件系統類型。但是由於每種文件系統都有自己的magic,在get_sb時候會從
物理設備的特定位置讀到magic,這個magic實在mkfs的時候寫入物理設備的。因爲magic的存在,所以大多數文件系統不可用,只有一個例外,就是用根設備上實際 使用過的文件系統的函數來填充超級塊的那個調用,該文件系統安裝在rootfs文件系統的/root目錄。
3、
sys_mount(".", "/", NULL, MS_MOVE, NULL);
sys_chroot(".");
移動rootfs文件系統目錄上的已安裝文件系統的安裝點。
注意的是:rootfs文件系統沒有卸載,只是隱藏在基於磁盤(磁盤或flash這種存儲介質)的根文件系統下了。
舉個例子說明:
在pc的ubuntu下,
lrwxrwxrwx 1 root root 4 2012-04-03 14:46 /dev/root -> sda7
sda7是安裝ubuntu的盤
df -TH結果如下:
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda7 ext4 27G 24G 1011M 97% /
none devtmpfs 494M 716K 493M 1% /dev
none tmpfs 500M 1.3M 499M 1% /dev/shm
none tmpfs 500M 384K 500M 1% /var/run
none tmpfs 500M 0 500M 0% /var/lock
看到的是ext4文件系統是在/dev/sda7這個磁盤上的,但它作爲實際的根文件系統,mount在"/"上了。
因爲是雙系統,還可以看到:
/dev/sda5 fuseblk 156G 141G 15G 91% /media/DATAPART
win下的磁盤都被linux掛在/media目錄下了。
到這裏,"/"終於出現了!