Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2117267
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: LINUX

2016-10-10 14:11:30

1. 在《linux0.12--11.minix文件系统中文件读取流程》中还有一个问题就是root结点是怎么来的?
init-->setup((void *) &drive_info);


在kernel/blk_drv/hd.c中
  1. int sys_setup(void * BIOS)
  2. {
  3.     static int callable = 1;
  4.     int i,drive;
  5.     unsigned char cmos_disks;
  6.     struct partition *p;
  7.     struct buffer_head * bh;

  8.     if (!callable)
  9.         return -1;
  10.     callable = 0;
  11. //获取硬盘的总体信息
  12.     for (drive=0 ; drive<2 ; drive++) {
  13.         hd_info[drive].cyl = *(unsigned short *) BIOS;
  14.         hd_info[drive].head = *(unsigned char *) (2+BIOS);
  15.         hd_info[drive].wpcom = *(unsigned short *) (5+BIOS);
  16.         hd_info[drive].ctl = *(unsigned char *) (8+BIOS);
  17.         hd_info[drive].lzone = *(unsigned short *) (12+BIOS);
  18.         hd_info[drive].sect = *(unsigned char *) (14+BIOS);
  19.         BIOS += 16;
  20.     }
  21.     if (hd_info[1].cyl)
  22.         NR_HD=2;
  23.     else
  24.         NR_HD=1;
  25. //由硬盘的总体信息,计算整个硬盘的总扇区数,并设置start_sect=0
  26.     for (i=0 ; i<NR_HD ; i++) {
  27.         hd[i*5].start_sect = 0;
  28.         hd[i*5].nr_sects = hd_info[i].head*
  29.                 hd_info[i].sect*hd_info[i].cyl;
  30.     }

  31.     if ((cmos_disks = CMOS_READ(0x12)) & 0xf0)
  32.         if (cmos_disks & 0x0f)
  33.             NR_HD = 2;
  34.         else
  35.             NR_HD = 1;
  36.     else
  37.         NR_HD = 0;
  38.     for (i = NR_HD ; i < 2 ; i++) {
  39.         hd[i*5].start_sect = 0;
  40.         hd[i*5].nr_sects = 0;
  41.     }
  42.     for (drive=0 ; drive<NR_HD ; drive++) {
  43.         if (!(bh = bread(0x300 + drive*5,0))) {    //读取MBR
  44.             printk("Unable to read partition table of drive %d\n\r",
  45.                 drive);
  46.             panic("");
  47.         }
  48.         if (bh->b_data[510] != 0x55 || (unsigned char)   //判断MBR中是否含有引导标志
  49.          bh->b_data[511] != 0xAA) {
  50.             printk("Bad partition table on drive %d\n\r",drive);
  51.             panic("");
  52.         }
  53.         p = 0x1BE + (void *)bh->b_data;
  54. //读取每个分区的起始
  55.         for (i=1;i<5;i++,p++) {
  56.             hd[i+5*drive].start_sect = p->start_sect;
  57.             hd[i+5*drive].nr_sects = p->nr_sects;
  58.         }
  59.         brelse(bh);
  60.     }
  61.     for (i=0 ; i<5*MAX_HD ; i++)
  62.         hd_sizes[i] = hd[i].nr_sects>>1 ;
  63.     blk_size[MAJOR_NR] = hd_sizes;
  64.     if (NR_HD)
  65.         printk("Partition table%s ok.\n\r",(NR_HD>1)?"s":"");
  66.     rd_load();
  67.     init_swapping();
  68.     mount_root();         //有了每个分区的起始信息之后就可以挂载根文件系统,因为根文件系统也是在某一个分区中的
  69.     return (0);
  70. }


挂载根文件系统-->在fs/super.c中
不要把挂载想象的很神秘,其实挂载文件系统就是获得root的inode
  1. void mount_root(void)
  2. {
  3.     int i,free;
  4.     struct super_block * p;
  5.     struct m_inode * mi;

  6.     if (32 != sizeof (struct d_inode))
  7.         panic("bad i-node size");
  8.     for(i=0;i<NR_FILE;i++)
  9.         file_table[i].f_count=0;
  10.     if (MAJOR(ROOT_DEV) == 2) {
  11.         printk("Insert root floppy and press ENTER");
  12.         wait_for_keypress();
  13.     }
  14.     for(p = &super_block[0] ; p < &super_block[NR_SUPER] ; p++) {
  15.         p->s_dev = 0;
  16.         p->s_lock = 0;
  17.         p->s_wait = NULL;
  18.     }
  19.     if (!(p=read_super(ROOT_DEV)))                   //读取super block,从而确定imap与zmap的block块数
  20.         panic("Unable to mount root");               //为读取root的inode作准备 
  21.     if (!(mi=iget(ROOT_DEV,ROOT_INO)))                //获取root的inode
  22.         panic("Unable to read root i-node");
  23.     mi->i_count += 3 ;    /* it is logically used 4 times, not 1 */
  24.     p->s_isup = p->s_imount = mi;
  25.     current->pwd = mi;                 //开始时将pwd=root
  26.     current->root = mi;                //获取root的inode
  27.     free=0;
  28.     i=p->s_nzones;
  29.     while (-- i >= 0)
  30.         if (!set_bit(i&8191,p->s_zmap[i>>13]->b_data))
  31.             free++;
  32.     printk("%d/%d free blocks\n\r",free,p->s_nzones);
  33.     free=0;
  34.     i=p->s_ninodes+1;
  35.     while (-- i >= 0)
  36.         if (!set_bit(i&8191,p->s_imap[i>>13]->b_data))
  37.             free++;
  38.     printk("%d/%d free inodes\n\r",free,p->s_ninodes);
  39. }

在fs/super.c中
  1. static struct super_block * read_super(int dev)
  2. {
  3.     struct super_block * s;
  4.     struct buffer_head * bh;
  5.     int i,block;

  6.     if (!dev)
  7.         return NULL;
  8.     check_disk_change(dev);
  9.     if (s = get_super(dev))
  10.         return s;
  11.     for (s = 0+super_block ;; s++) {
  12.         if (s >= NR_SUPER+super_block)
  13.             return NULL;
  14.         if (!s->s_dev)
  15.             break;
  16.     }
  17.     s->s_dev = dev;
  18.     s->s_isup = NULL;
  19.     s->s_imount = NULL;
  20.     s->s_time = 0;
  21.     s->s_rd_only = 0;
  22.     s->s_dirt = 0;
  23.     lock_super(s);
  24.     if (!(bh = bread(dev,1))) {
  25.         s->s_dev=0;
  26.         free_super(s);
  27.         return NULL;
  28.     }
  29.     *((struct d_super_block *) s) =
  30.         *((struct d_super_block *) bh->b_data);
  31.     brelse(bh);
  32.     if (s->s_magic != SUPER_MAGIC) {
  33.         s->s_dev = 0;
  34.         free_super(s);
  35.         return NULL;
  36.     }
  37.     for (i=0;i<I_MAP_SLOTS;i++)
  38.         s->s_imap[i] = NULL;
  39.     for (i=0;i<Z_MAP_SLOTS;i++)
  40.         s->s_zmap[i] = NULL;
  41.     block=2;
  42.     for (i=0 ; i < s->s_imap_blocks ; i++)
  43.         if (s->s_imap[i]=bread(dev,block))
  44.             block++;
  45.         else
  46.             break;
  47.     for (i=0 ; i < s->s_zmap_blocks ; i++)
  48.         if (s->s_zmap[i]=bread(dev,block))
  49.             block++;
  50.         else
  51.             break;
  52.     if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) {
  53.         for(i=0;i<I_MAP_SLOTS;i++)
  54.             brelse(s->s_imap[i]);
  55.         for(i=0;i<Z_MAP_SLOTS;i++)
  56.             brelse(s->s_zmap[i]);
  57.         s->s_dev=0;
  58.         free_super(s);
  59.         return NULL;
  60.     }
  61.     s->s_imap[0]->b_data[0] |= 1;
  62.     s->s_zmap[0]->b_data[0] |= 1;
  63.     free_super(s);
  64.     return s;
  65. }

在fs/inode.c中
  1. struct m_inode * iget(int dev,int nr)
  2. {
  3.     struct m_inode * inode, * empty;

  4.     if (!dev)
  5.         panic("iget with dev==0");
  6.     empty = get_empty_inode();
  7.     inode = inode_table;
  8.     while (inode < NR_INODE+inode_table) {
  9.         if (inode->i_dev != dev || inode->i_num != nr) {
  10.             inode++;
  11.             continue;
  12.         }
  13.         wait_on_inode(inode);
  14.         if (inode->i_dev != dev || inode->i_num != nr) {
  15.             inode = inode_table;
  16.             continue;
  17.         }
  18.         inode->i_count++;
  19.         if (inode->i_mount) {
  20.             int i;

  21.             for (i = 0 ; i<NR_SUPER ; i++)
  22.                 if (super_block[i].s_imount==inode)
  23.                     break;
  24.             if (i >= NR_SUPER) {
  25.                 printk("Mounted inode hasn't got sb\n");
  26.                 if (empty)
  27.                     iput(empty);
  28.                 return inode;
  29.             }
  30.             iput(inode);
  31.             dev = super_block[i].s_dev;
  32.             nr = ROOT_INO;
  33.             inode = inode_table;
  34.             continue;
  35.         }
  36.         if (empty)
  37.             iput(empty);
  38.         return inode;
  39.     }
  40.     if (!empty)
  41.         return (NULL);
  42.     inode=empty;
  43.     inode->i_dev = dev;
  44.     inode->i_num = nr;
  45.     read_inode(inode);
  46.     return inode;
  47. }


在fs/inode.c中
  1. static void read_inode(struct m_inode * inode)
  2. {
  3.     struct super_block * sb;
  4.     struct buffer_head * bh;
  5.     int block;

  6.     lock_inode(inode);
  7. //从super_block数组中找到与inode->i_dev相同的super_block
  8.     if (!(sb=get_super(inode->i_dev)))
  9.         panic("trying to read inode without dev");
  10. //要知道具体的inode在分区的第几个block中,根据minix文件系统的性质,前面是1_boot 1_super n_imap n_zmap,
  11. //具体的inode就是在接下来的inode区。 是在inode区的哪一个block里面呢?
  12. //因为inode的大小是固定的32个BYTE,INODES_PER_BLOCK=1024/32,
  13. //所以第10个inode是在(10-1)/32=0个block里面, 第35个inode是在(35-1)/32=1个block里面
  14.     block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks + (inode->i_num-1)/INODES_PER_BLOCK;   //找到这个block
  15.     if (!(bh=bread(inode->i_dev,block)))
  16.         panic("unable to read i-node block");
  17.     *(struct d_inode *)inode =
  18.         ((struct d_inode *)bh->b_data)
  19.             [(inode->i_num-1)%INODES_PER_BLOCK];                //根据inode在这个block中的偏移就可以找出这个具体的inode的位置
  20.     brelse(bh);
  21.     if (S_ISBLK(inode->i_mode)) {
  22.         int i = inode->i_zone[0];
  23.         if (blk_size[MAJOR(i)])
  24.             inode->i_size = 1024*blk_size[MAJOR(i)][MINOR(i)];
  25.         else
  26.             inode->i_size = 0x7fffffff;
  27.     }
  28.     unlock_inode(inode);
  29. }
3. 挂载根文件系统
看起来很高大上,说白了其实就是读取root的inode


阅读(1521) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~