linux-0.11调试教程,mkfs.c源代码分析(2)

第二个任务是建立根目录。由make_root_inode()函数完成。在make_root_inode()函数运行之前如果命令中加入了-c选项,会运行check_blocks()函数检查坏块,并把坏块对应的逻辑块位图块中对应的位置1。因为我们的系统是在bochs中运行,硬盘对应的是一个img文件,不是实体硬盘,所以不会有坏块。也没有必要加-c选项。


根目录对应的数据是:

#define ROOT_INO_STRING "\001\000"

static char root_block[BLOCK_SIZE] =
ROOT_INO_STRING ".\0\0\0\0\0\0\0\0\0\0\0\0\0"
ROOT_INO_STRING "..\0\0\0\0\0\0\0\0\0\0\0\0"

根目录文件有两个目录项,每个目录项16字节,前两个字节既前面的紫色的表示目录对应的i节点号既1,后14个字节是文件名,这里是"."既当前目录,".."既当前目录的目录。


#define ROOT_INO 1

#define mark_inode(x) (setbit(inode_map,(x)))
#define unmark_inode(x) (clrbit(inode_map,(x)))

ROOT_INO表示的是根目录对应的节点号既1。

mark_inode(ROOT_INO);会把i节点位图块中的第1位置为1。第0位在setup_tables()函数中开始的:

    memset(inode_map,0xff,sizeof(inode_map));

就设置为1了。后来的

    for (i = ROOT_INO ; i<INODES ; i++)
        unmark_inode(i);

因为ROOT_INO为1,所以第0位没有被重置为0。

void make_root_inode(void) {
    struct d_inode * inode = &Inode[ROOT_INO];

    mark_inode(ROOT_INO);
    inode->i_zone[0] = get_free_block();
    inode->i_nlinks = 2;
    inode->i_time = time(NULL);
    if (badblocks)
        inode->i_size = 48;
    else
        inode->i_size = 32;
    inode->i_mode = S_IFDIR + 0755;
    write_block(inode->i_zone[0],root_block);

}


write_block()函数把buffer指向的字符串的内容写到块号为blk的块中。

void write_block(int blk, char * buffer)
{
    if (blk*BLOCK_SIZE != lseek(DEV, blk*BLOCK_SIZE, SEEK_SET))
        die("seek failed in write_block");
    if (BLOCK_SIZE != write(DEV, buffer, BLOCK_SIZE))
        die("write failed in write_block");
}


get_free_block()函数分析:get_free_block()函数在数据区从前往后寻找第一个未被使用的块。

make_root_inode()函数第一次调用get_free_block()函数时used_good_blocks等于0。所以

  if (used_good_blocks)
        blk = good_blocks_table[used_good_blocks-1]+1;
    else
        blk = FIRSTZONE;

执行的是else语句既blk = FIRSTZONE;。


   while (blk < ZONES && zone_in_use(blk))
        blk++;

的作用是检测块号为blk的块是否已经被使用既是否被置位。

good_blocks_table[0]等于FIRSTZONE既第一个数据块的块号。以后都是make_bad_inode()函数中调用的。


int get_free_block(void)
{
    int blk;

    if (used_good_blocks+1 >= MAX_GOOD_BLOCKS)
        die("too many bad blocks");
    if (used_good_blocks)
        blk = good_blocks_table[used_good_blocks-1]+1;
    else
        blk = FIRSTZONE;
   while (blk < ZONES && zone_in_use(blk))
        blk++;

     if (blk >= ZONES)
        die("not enough good blocks");
    good_blocks_table[used_good_blocks] = blk;
    used_good_blocks++;
    return blk;
}


你可能感兴趣的:(linux-0.11调试教程,mkfs.c源代码分析(2))