如何分析基于linux0.11文件系统中的根文件系统挂载原理
发表于:2025-02-08 作者:千家信息网编辑
千家信息网最后更新 2025年02月08日,如何分析基于linux0.11文件系统中的根文件系统挂载原理,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。看完文件系统的
千家信息网最后更新 2025年02月08日如何分析基于linux0.11文件系统中的根文件系统挂载原理
如何分析基于linux0.11文件系统中的根文件系统挂载原理,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
看完文件系统的基础数据结构。我们接着解析的根文件系统的挂载,因为这是文件系统被使用的起点。根文件系统的挂载是在操作系统初始化的时候进行的。对应的函数是mount_root。
// 系统初始化时挂载根文件系统
void mount_root(void)
{
int i,free;
struct super_block * p;
struct m_inode * mi;
if (32 != sizeof (struct d_inode))
panic("bad i-node size");
// 初始化file结构体列表,struct file file_table[NR_FILE];
for(i=0;i
file_table[i].f_count=0;
// 如果根文件系统是软盘提示插入软盘
if (MAJOR(ROOT_DEV) == 2) {
printk("Insert root floppy and press ENTER");
wait_for_keypress();
}
// 初始化超级块列表
for(p = &super_block[0] ; p < &super_block[NR_SUPER] ; p++) {
p->s_dev = 0;
p->s_lock = 0;
p->s_wait = NULL;
}
// 读取某个设备(硬盘分区)中的超级块,即根文件系统的超级块
if (!(p=read_super(ROOT_DEV)))
panic("Unable to mount root");
// 获取根文件系统的第一个inode节点,里面存的是根目录的数据
if (!(mi=iget(ROOT_DEV,ROOT_INO)))
panic("Unable to read root i-node");
// mi在下面四个地方有赋值,iget里面的get_empty_inode函数已经设置i_count=1,所以这里加三就行
mi->i_count += 3 ; /* NOTE! it is logically used 4 times, not 1 */
// 超级块挂载到了mi对应的inode节点,p->s_isup设置根文件系统的根节点
p->s_isup = p->s_imount = mi;
// 设置当前进程的根文件目录和当前工作目录
current->pwd = mi;
current->root = mi;
free=0;
// 文件系统的逻辑数据块和inode数量
i=p->s_nzones;
while (-- i >= 0)
if (!set_bit(i&8191,p->s_zmap[i>>13]->b_data))
free++;
printk("%d/%d free blocks\n\r",free,p->s_nzones);
free=0;
i=p->s_ninodes+1;
while (-- i >= 0)
if (!set_bit(i&8191,p->s_imap[i>>13]->b_data))
free++;
printk("%d/%d free inodes\n\r",free,p->s_ninodes);
}
从代码中我们可以知道,该函数的主要工作是读取硬盘的超级块内容,然后申请一个inode节点作为根文件系统的根节点。最后把inode设置成当前进程的根节点。这时候的当前进程是操作系统的初始化进程。后续进程是从该进程fork出来的。所以根节点都是一样的。
下面看一下读取超级块的实现。主要逻辑是申请一个表示超级块的结构体,然后把超级块从硬盘读取进来,进行字段的初始化和处理。
// 读取dev对应的超级块
static struct super_block * read_super(int dev)
{
struct super_block * s;
struct buffer_head * bh;
int i,block;
if (!dev)
return NULL;
check_disk_change(dev);
// 在超级块表中则直接返回
if (s = get_super(dev))
return s;
// 找一个可用于存储超级块的空项
for (s = 0+super_block ;; s++) {
if (s >= NR_SUPER+super_block)
return NULL;
if (!s->s_dev)
break;
}
s->s_dev = dev;
s->s_isup = NULL;
s->s_imount = NULL;
s->s_time = 0;
s->s_rd_only = 0;
s->s_dirt = 0;
// 加锁,避免其他进程使用超级块里的数据,这时候还没读进来
lock_super(s);
// 把设备的第一块读进来,即超级块的内容
if (!(bh = bread(dev,1))) {
// 释放
s->s_dev=0;
free_super(s);
return NULL;
}
*((struct d_super_block *) s) =
*((struct d_super_block *) bh->b_data);
brelse(bh);
// 不是超级块则rollback
if (s->s_magic != SUPER_MAGIC) {
s->s_dev = 0;
free_super(s);
return NULL;
}
for (i=0;i
s->s_imap[i] = NULL;
for (i=0;i
s->s_zmap[i] = NULL;
block=2;
// 读inode和块位图信息,s_imap_blocks块表示inode位图,读进来
for (i=0 ; i < s->s_imap_blocks ; i++)
if (s->s_imap[i]=bread(dev,block)) // s_imap_blocks > 8时会溢出
block++;
else
break;
for (i=0 ; i < s->s_zmap_blocks ; i++)
if (s->s_zmap[i]=bread(dev,block))
block++;
else
break;
// 没全读成功全部释放
if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) {
for(i=0;i
brelse(s->s_imap[i]);
for(i=0;i
brelse(s->s_zmap[i]);
s->s_dev=0;
free_super(s);
return NULL;
}
// 第一个不能使用,置第一个为已使用,因为找空闲块的时候,返回0表示失败。所以第0块可用的话会有二义性
s->s_imap[0]->b_data[0] |= 1;
s->s_zmap[0]->b_data[0] |= 1;
free_super(s);
return s;
}
至此,根文件系统就加载完成了。后续的对文件系统的使用都是基于这个根文件系统的根节点的。
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。
系统
文件
节点
进程
数据
内容
函数
硬盘
结构
操作系统
位图
时候
目录
设备
软盘
逻辑
工作
帮助
原理
分析
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
石家庄网络技术师
惠州惠城DNS服务器地址
玫瑰花园软件开发系统
网络技术俗称
网络安全全面总结报告
服务器机柜散架
广安软件开发成交价
陕西惠中惠网络技术有限公司
共享服务器运维
被计入诚信数据库的后果
视爵网络技术 运营总监
软件开发国企待遇
正式服部落大服务器排名
从事危害网络安全 罚款
程序设计的数据库
网络安全是哪个专业的
棋牌平台软件开发流程
皇氏集团软件开发
网络安全竞赛上机题目
管家婆打开需要输入服务器名称
企业部门网络安全责任书
flash访问数据库
我的世界拔刀剑服务器多少钱
如何打免流服务器
直通车软件开发靠谱吗
电子政务中数据库的作用
珠海软件开发机构
服务器管理员密码更改
原神服务器安全机制
思想政治教育 网络安全