uclinux很久前笔记10

【内核挂载根文件系统分析】

在init内核线程中:

static int init(void* unused)
{
       structfiles_struct *files;
       lock_kernel();
       do_basic_setup();
       prepare_namespace();  //准备命名空间
       free_initmem();
       unlock_kernel();
       files= current->files;
       if(unshare_files())
              panic("unshare");
       put_files_struct(files);
       if(open("/dev/console", O_RDWR, 0)< 0)
              printk("Warning:unable to open an initial console.\n");
……
}
void prepare_namespace(void)
{
       ……
       mount_root();    //挂载根文件系统
       ……
}
static void __init mount_root(void)
{
       ……
       devfs_make_root(root_device_name);
       create_dev("/dev/root",ROOT_DEV, root_device_name);
       ……
       mount_block_root("/dev/root",root_mountflags);
}
static void __init mount_block_root(char*name, int flags)
{
       ……
              printk("VFS: Cannot open root device \"%s\" or %s\n",
                     root_device_name, kdevname (ROOT_DEV));
              printk("Please append a correct \"root=\" boot option\n");
              panic("VFS:Unable to mount root fs on %s",
                     kdevname(ROOT_DEV));
       }
       panic("VFS:Unable to mount root fs on %s", kdevname(ROOT_DEV));
out:
       putname(fs_names);
       sys_chdir("/root");
       ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
       printk("VFS: Mounted root (%s filesystem)%s.\n",
              current->fs->pwdmnt->mnt_sb->s_type->name,
              (current->fs->pwdmnt->mnt_sb->s_flags& MS_RDONLY) ? " readonly" : "");
       /*44b0打印为:VFS: Mounted root (romfs filesystem) readonly.*/
}

注释:参数root_device_name是由启动参数传递过来的。

static int __init root_dev_setup(char*line)
{
       inti;
       charch;
       ROOT_DEV= name_to_kdev_t(line);
       memset(root_device_name, 0, sizeof root_device_name);
       if(strncmp (line, "/dev/", 5) == 0)line += 5;  //该函数得到的命令行为root=/dev/xxx
       for(i = 0; i < sizeof root_device_name - 1; ++i)
       {
           ch = line[i];
           if ( isspace (ch) || (ch == ',') || (ch =='\0') ) break;
           root_device_name[i]= ch;
       }
       return1;
}
__setup("root=",root_dev_setup);   //__setup为一个宏定义
 
#define __setup(str, fn)                                                   \
       staticchar __setup_str_##fn[] __initdata = str;                          \
       staticstruct kernel_param __setup_##fn __attribute__((unused)) __initsetup = {__setup_str_##fn, fn }
替换为:
#define __setup("root=", root_dev_setup)   \
       staticchar __setup_str_ root_dev_setup__initdata = "root="      \
       staticstruct kernel_param __setup_ root_dev_setup   __attribute__((unused)) __initsetup =
{__setup_str_root_dev_setup, root_dev_setup}
其中:
#define __initdata __attribute__ ((__section__ (".data.init")))
#define __initsetup __attribute__((unused,__section__ (".setup.init")))

在vmlinux.lds中:

              ……
              __tagtable_begin= .;
                     *(.taglist)
              __tagtable_end= .;
                     *(.data.init)
              .= ALIGN(16);
              __setup_start = .;
                     *(.setup.init)
              __setup_end = .;

kernel_param结构体为:

struct kernel_param {
       constchar *str;
       int(*setup_func)(char *);
};
static int __init checksetup(char*line)
{
       structkernel_param *p;
       p= &__setup_start;
       do{
              intn = strlen(p->str);
              if(!strncmp(line,p->str,n)) {
                     if(p->setup_func(line+n))
                            return1;
              }
              p++;
       }while (p < &__setup_end);
       return0;
}
static void __init parse_options(char*line)
{
       ……
       if(checksetup(line))  // start_kernel中调用了parse_options(command_line);
              continue;
       ……
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值