1. 在《linux0.12--11.minix文件系统中文件读取流程》中还有一个问题就是root结点是怎么来的?
init-->setup((void *) &drive_info);
在kernel/blk_drv/hd.c中
-
int sys_setup(void * BIOS)
-
{
-
static int callable = 1;
-
int i,drive;
-
unsigned char cmos_disks;
-
struct partition *p;
-
struct buffer_head * bh;
-
-
if (!callable)
-
return -1;
-
callable = 0;
-
//获取硬盘的总体信息
-
for (drive=0 ; drive<2 ; drive++) {
-
hd_info[drive].cyl = *(unsigned short *) BIOS;
-
hd_info[drive].head = *(unsigned char *) (2+BIOS);
-
hd_info[drive].wpcom = *(unsigned short *) (5+BIOS);
-
hd_info[drive].ctl = *(unsigned char *) (8+BIOS);
-
hd_info[drive].lzone = *(unsigned short *) (12+BIOS);
-
hd_info[drive].sect = *(unsigned char *) (14+BIOS);
-
BIOS += 16;
-
}
-
if (hd_info[1].cyl)
-
NR_HD=2;
-
else
-
NR_HD=1;
-
//由硬盘的总体信息,计算整个硬盘的总扇区数,并设置start_sect=0
-
for (i=0 ; i<NR_HD ; i++) {
-
hd[i*5].start_sect = 0;
-
hd[i*5].nr_sects = hd_info[i].head*
-
hd_info[i].sect*hd_info[i].cyl;
-
}
-
-
if ((cmos_disks = CMOS_READ(0x12)) & 0xf0)
-
if (cmos_disks & 0x0f)
-
NR_HD = 2;
-
else
-
NR_HD = 1;
-
else
-
NR_HD = 0;
-
for (i = NR_HD ; i < 2 ; i++) {
-
hd[i*5].start_sect = 0;
-
hd[i*5].nr_sects = 0;
-
}
-
for (drive=0 ; drive<NR_HD ; drive++) {
-
if (!(bh = bread(0x300 + drive*5,0))) { //读取MBR
-
printk("Unable to read partition table of drive %d\n\r",
-
drive);
-
panic("");
-
}
-
if (bh->b_data[510] != 0x55 || (unsigned char) //判断MBR中是否含有引导标志
-
bh->b_data[511] != 0xAA) {
-
printk("Bad partition table on drive %d\n\r",drive);
-
panic("");
-
}
-
p = 0x1BE + (void *)bh->b_data;
-
//读取每个分区的起始
-
for (i=1;i<5;i++,p++) {
-
hd[i+5*drive].start_sect = p->start_sect;
-
hd[i+5*drive].nr_sects = p->nr_sects;
-
}
-
brelse(bh);
-
}
-
for (i=0 ; i<5*MAX_HD ; i++)
-
hd_sizes[i] = hd[i].nr_sects>>1 ;
-
blk_size[MAJOR_NR] = hd_sizes;
-
if (NR_HD)
-
printk("Partition table%s ok.\n\r",(NR_HD>1)?"s":"");
-
rd_load();
-
init_swapping();
-
mount_root(); //有了每个分区的起始信息之后就可以挂载根文件系统,因为根文件系统也是在某一个分区中的
-
return (0);
-
}
挂载根文件系统-->在fs/super.c中
不要把挂载想象的很神秘,其实挂载文件系统就是获得root的inode
-
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");
-
for(i=0;i<NR_FILE;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))) //读取super block,从而确定imap与zmap的block块数
-
panic("Unable to mount root"); //为读取root的inode作准备
-
if (!(mi=iget(ROOT_DEV,ROOT_INO))) //获取root的inode
-
panic("Unable to read root i-node");
-
mi->i_count += 3 ; /* it is logically used 4 times, not 1 */
-
p->s_isup = p->s_imount = mi;
-
current->pwd = mi; //开始时将pwd=root
-
current->root = mi; //获取root的inode
-
free=0;
-
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);
-
}
在fs/super.c中
-
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;
-
}
在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 = inode_table;
-
while (inode < NR_INODE+inode_table) {
-
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++)
-
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;
-
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);
-
return inode;
-
}
在fs/inode.c中
-
static void read_inode(struct m_inode * inode)
-
{
-
struct super_block * sb;
-
struct buffer_head * bh;
-
int block;
-
-
lock_inode(inode);
-
//从super_block数组中找到与inode->i_dev相同的super_block
-
if (!(sb=get_super(inode->i_dev)))
-
panic("trying to read inode without dev");
-
//要知道具体的inode在分区的第几个block中,根据minix文件系统的性质,前面是1_boot 1_super n_imap n_zmap,
-
//具体的inode就是在接下来的inode区。 是在inode区的哪一个block里面呢?
-
//因为inode的大小是固定的32个BYTE,INODES_PER_BLOCK=1024/32,
-
//所以第10个inode是在(10-1)/32=0个block里面, 第35个inode是在(35-1)/32=1个block里面
-
block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks + (inode->i_num-1)/INODES_PER_BLOCK; //找到这个block
-
if (!(bh=bread(inode->i_dev,block)))
-
panic("unable to read i-node block");
-
*(struct d_inode *)inode =
-
((struct d_inode *)bh->b_data)
-
[(inode->i_num-1)%INODES_PER_BLOCK]; //根据inode在这个block中的偏移就可以找出这个具体的inode的位置
-
brelse(bh);
-
if (S_ISBLK(inode->i_mode)) {
-
int i = inode->i_zone[0];
-
if (blk_size[MAJOR(i)])
-
inode->i_size = 1024*blk_size[MAJOR(i)][MINOR(i)];
-
else
-
inode->i_size = 0x7fffffff;
-
}
-
unlock_inode(inode);
-
}
3. 挂载根文件系统
看起来很高大上,说白了其实就是读取root的inode
阅读(1560) | 评论(0) | 转发(0) |