相关代码:sys_setup()函数调用mount_root()函数,mount_root()函数又调用read_super()函数。
struct super_block {
unsigned short s_ninodes; 4e20
unsigned short s_nzones; ea60
unsigned short s_imap_blocks; 0003
unsigned short s_zmap_blocks; 0008
unsigned short s_firstdatazone; 027e
unsigned short s_log_zone_size; 0000
unsigned long s_max_size; 10081c00
unsigned short s_magic; 137f
/* These are only in memory */
struct buffer_head * s_imap[8]; 0x0001faa0 0x0001fac4 0x0001fae8
struct buffer_head * s_zmap[8]; 0x0001fb0c 0x0001fb30 0x0001fb54
0x0001fb78 0x0001fb9c 0x0001fbc0 0x0001fbe4
0x0001fc08
unsigned short s_dev; 0301
struct m_inode * s_isup; 0x00019294
struct m_inode * s_imount; 0x00019294
unsigned long s_time;
struct task_struct * s_wait;
unsigned char s_lock;
unsigned char s_rd_only;
unsigned char s_dirt;
};
上图是表示的buffer_head结构:
struct buffer_head {
char * b_data; /* pointer to data block (1024 bytes) */
unsigned long b_blocknr; /* block number */
unsigned short b_dev; /* device (0 = free) */
unsigned char b_uptodate;
unsigned char b_dirt; /* 0-clean,1-dirty */
unsigned char b_count; /* users using this block */
unsigned char b_lock; /* 0 - ok, 1 -locked */
struct task_struct * b_wait;
struct buffer_head * b_prev;
struct buffer_head * b_next;
struct buffer_head * b_prev_free;
struct buffer_head * b_next_free;
};
unsigned short s_imap_blocks; 0003
i节点位图块占3块,块号是0002,0003,0004
逻辑块位图块占8块,块号是。。。
s_firstdatazone表示第一个逻辑块的块号,应该等于0块,1块既超级块,和i节点位图的块数既s_imap_blocks和逻辑块位图的块数既s_zmap_blocks和i节点所占的块数。
i节点所占的块数既i节点的个数s_ninodes乘i节点的大小既32字节除每个块的大小既1024。
unsigned short s_firstdatazone; 0x027e
unsigned short s_ninodes; 4e20
unsigned short s_imap_blocks; 0003
unsigned short s_zmap_blocks; 0008
((0x4e20*32)/1024+8+3+2)=625+13=638=0x27e
int sys_setup(void * BIOS)
{
......
mount_root();
return (0);
}
int sys_mount(char * dev_name, char * dir_name, int rw_flag)
{
struct m_inode * dev_i, * dir_i;
struct super_block * sb;
int dev;
if (!(dev_i=namei(dev_name)))
return -ENOENT;
dev = dev_i->i_zone[0];
if (!S_ISBLK(dev_i->i_mode)) {
iput(dev_i);
return -EPERM;
}
iput(dev_i);
if (!(dir_i=namei(dir_name)))
return -ENOENT;
if (dir_i->i_count != 1 || dir_i->i_num == ROOT_INO) {
iput(dir_i);
return -EBUSY;
}
if (!S_ISDIR(dir_i->i_mode)) {
iput(dir_i);
return -EPERM;
}
if (!(sb=read_super(dev))) {
iput(dir_i);
return -EBUSY;
}
if (sb->s_imount) {
iput(dir_i);
return -EBUSY;
}
if (dir_i->i_mount) {
iput(dir_i);
return -EPERM;
}
sb->s_imount=dir_i;
dir_i->i_mount=1;
dir_i->i_dirt=1; /* NOTE! we don't iput(dir_i) */
return 0; /* we do that in umount */
}
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);
if (s->s_magic != SUPER_MAGIC) {
s->s_dev = 0;
free_super(s);
return NULL;
}
for (i=0;i<I_MAP_SLOTS;i++)
s->s_imap[i] = NULL;
for (i=0;i<Z_MAP_SLOTS;i++)
s->s_zmap[i] = NULL;
block=2;
for (i=0 ; i < s->s_imap_blocks ; i++)
if (s->s_imap[i]=bread(dev,block))
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<I_MAP_SLOTS;i++)
brelse(s->s_imap[i]);
for(i=0;i<Z_MAP_SLOTS;i++)
brelse(s->s_zmap[i]);
s->s_dev=0;
free_super(s);
return NULL;
}
s->s_imap[0]->b_data[0] |= 1;
s->s_zmap[0]->b_data[0] |= 1;
free_super(s);
return s;
}