3.3.3 进程1在根设备上加载根文件系统(5)
2.将根设备中的根i节点挂在super_block[8]中根设备超级块上
回到mount_root(?)函数中,调用iget(?)函数,从虚拟盘上读取根i节点。根i节点的意义在于,通过它可以到文件系统中任何指定的i节点,也就是能找到任何指定的文件。
执行代码如下:
- //代码路径:fs/super.c:
- void mount_root(void)
- {
- …
- if (!(p=read_super(ROOT_DEV)))
- panic("Unable to mount root");
- if (!(mi=iget(ROOT_DEV,ROOT_INO)))
- panic("Unable to read root i-node");
- …
- }
进入iget(?)函数后,操作系统从i节点表inode_table[32]中申请一个空闲的i节点位置(inode_table[32]是操作系统用来控制同时打开不同文件的最大数)。此时应该是首个i节点。对这个i节点进行初始化设置,其中包括该i节点对应的设备号、该i节点的节点号……
图3-42中给出了根目录i节点在内核i节点表中的位置。
![](https://i-blog.csdnimg.cn/blog_migrate/7820b58309838cd6d17abbd70c01b23f.jpeg)
对应代码如下:
- //代码路径:fs/inode.c:
- struct m_inode * iget(int dev,int nr)
- {
- struct m_inode * inode, * empty;
-
- if (!dev)
- panic("iget with dev==0");
- empty= get_empty_inode(); //从inode_table[32]中申请一个空闲的i节点
- inode= inode_table;
- while (inode < NR_INODE?+?inode_table){ //查找与参数相同的inode
- if (inode->i_dev != dev || inode->i_num != nr) {
- inode++;
- continue;
- }
- wait_on_inode(inode); //等待解锁
- if (inode->i_dev != dev || inode->i_num != nr){ //如等待期间发生
- inode= inode_table; //变化,继续查找
- continue;
- }
- inode->i_count++;
- if (inode->i_mount) {
- int i;
-
- for (i= 0;i<NR_SUPER;i++) //如是mount点,则查找对应的超级块
- if (super_block[i].s_imount==inode)
- break;
- if (i >= NR_SUPER) {
- printk("Mounted inode hasn't got sb\n");
- if (empty)
- iput(empty);
- return inode;
- }
- iput(inode);
- dev= super_block[i].s_dev; //从超级块中获取设备号
- nr= ROOT_INO; // ROOT_INO为1,根i节点号
- inode= inode_table;
- continue;
- }
- if (empty)
- iput(empty);
- return inode;
- }
- if (!empty)
- return (NULL);
- inode=empty;
- inode->i_dev= dev; //初始化
- inode->i_num= nr;
- read_inode(inode); //从虚拟盘上读出根i节点
- return inode;
- }