linux0.11 mount_root函数疑问分析

Posted 学习记录

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux0.11 mount_root函数疑问分析相关的知识,希望对你有一定的参考价值。

在阅读Linux0.11代码中,mount_root函数在统计i节点时有加1操作,对此一直不理解,既然s_ninodes表示i节点的数量当然包含了0节点,因此此处个人认为不用加1,修改代码后,内核运行正常

 

void mount_root(void)

    int i,free;
    struct super_block * p;
    struct m_inode * mi;

    /*
     * 磁盘上的i节点必须为32个字节
     */
    if (32 != sizeof(struct d_inode))
        panic("bad i-node size");
    
    /*
     * 初始化文件表数组
     */
    for(i = 0; i < NR_FILE; i++)
        file_table[i].f_count=0;

    /*
     * 如果是软盘,提示用户插入文件系统软盘并输入Enter
     */
    if (MAJOR(ROOT_DEV) == 2) 
        printk("Insert root floppy and press ENTER");
        wait_for_keypress();
    

    /*
     * 初始化超级块数组,一共8项
     */
    for(p = &super_block[0]; p < &super_block[NR_SUPER]; p++) 
        p->s_dev = 0;
        p->s_lock = 0;
        p->s_wait = NULL;
    

    /*
     * 从根文件系统上读取超级块,如果失败则panic
     * p是super_block超级块
     */
    if (!(p = read_super(ROOT_DEV)))
        panic("Unable to mount root");
    
    /*
     * 从设备上获取根i节点
     */
    if (!(mi = iget(ROOT_DEV, ROOT_INO)))
        panic("Unable to read root i-node");
    /*
     * 从逻辑上讲,该i节点引用增加了4次
     * 下面分析
     */
    mi->i_count += 4 ;    /* NOTE! it is logically used 4 times, not 1 */
    /*
     * i节点安装到超级块中,引用+1
     */
    p->s_isup = p->s_imount = mi;
    /*
     * 引用+1
     */
    current->pwd = mi;
    /*
     * 引用+1
     */
    current->root = mi;
    free=0;
    /*
     * 统计该设备上的空闲块数,先让i等于该设备总的逻辑块数
     * s_nzones表示总逻辑块数
     * s_zmap逻辑块位图缓冲块指针数组,8个块
     * s_ninodes表示节点数
     * s_imap节点位图缓冲块指针数组,8个块
     * 为什么是8191呢?
     * 因为一个高速缓冲区是1024个字节,共8192位
     * i&8191算的是在高速缓冲区的偏移,而i>>13是使用哪个高速缓存作为索引
     * 下面inodes是一样的道理
     * 每一个bit代表一个块,一共8192*8个bit,一个块1K
     * minix文件系统一共可管理8192*8*1K = 64M
     * minix文件系统最大64M
     * inode代表一个文件或者文件夹
     */
    i = p->s_nzones;
    while (--i >= 0)
        if (!test_bit(i&8191, p->s_zmap[i>>13]->b_data))
            free++;
    printk("%s %d/%d free blocks\\n\\r", __func__, free, p->s_nzones);
    /*
     * 重置free,计算inode
     * s_ninodes为什么要加1???不明白,书上和网上的很多资料说是要把0节点统计进去
     * 但是我觉得不合理,既然s_ninodes表示i节点的数量当然包含了0节点
     * 根据我查的一些资料http://ohm.hgesser.de/sp-ss2012/Intro-MinixFS.pdf
     * s_ninodes表示inodes的数量Number of inodes, 因此此处个人觉得不用加1
     * 我进行了如下的修改,内核正常运行
     * 详见 https://github.com/sudochen/linux-0.11.paging
     */
    free=0;
#if 0
    i = p->s_ninodes + 1;
#else
    i = p->s_ninodes;
#endif
    while (--i >= 0)
        if (!test_bit(i&8191,p->s_imap[i>>13]->b_data))
            free++;
    printk("%s %d/%d free inodes\\n\\r", __func__, free, p->s_ninodes);
    printk("%s %d is firstdatazone\\n\\r", __func__, p->s_firstdatazone);

 

以上是关于linux0.11 mount_root函数疑问分析的主要内容,如果未能解决你的问题,请参考以下文章

Linux0.11 内核体系结构

Linux0.11内核--内存管理之1.初始化

Linux 0.11启动过程分析

Linux0.11内核源码——内核态进程切换的改进

Linux0.11内核--进程调度分析之1.初始化

Linux0.11内核--加载可执行二进制文件之3.exec