linux加载文件系统

内核实在是很复杂, 这里从start_kernel开始。

/* kernel/init/main.c */
/* __init 宏告诉编译器这个函数或者变量是用来初始化的,
 *   编译器会把带有__init的代码放到一个特殊的内存区域,
 *  当初始化结束的时候就会释放,以获得更多空间.
 *  __weak 可以将一个函数声明为weak, 当没有其他同名函数声明时调用weak,
 *   有其他同名函数时调用其他同名函数.
 */
void __init __weak smp_setup_processor_id(void)
{

}

/* kernel/init/main.c */
asmlinkage void __init start_kernel(void)
{
  /* 一看是个空函数,略过..... 如果略过就错了。 */
   * 这是属于多CPU的范畴,当只有一个CPU的时候这个函数就什么都不做,所以就把它定义为空,
   * 但是如果有多个CPU的时候那么它就返回在启动的时候的那个CPU的号,而这个函数在配置了多CPU的时候
   * 是有定义的,而不是空,所以就这样来处理了.
  smp_setup_processor_id();

  ...

  /* 输出Linux版本信息 */
  printk(KERN_NOTICE "%s", linux_banner);  
  /* 设置与体系结构相关的环境 */
  setup_arch(&command_line);
  /* 使用"arch/alpha/kernel/entry.S"中的入口点设置系统自陷入口 */
  trap_init();

  /* 等等等....... 一系列初始化*/

  /* 初始化vfs */
  vfs_caches_init(totalram_pages); 
/* Do the rest non-__init'ed, we're now alive */
rest_init(); }

vfs初始化

/* kernel/fs/dcache.c */
void __init vfs_caches_init(unsigned long mempages)
{
  dcache_init();
  inode_init();
  files_init(mempages);
  mnt_init();             //mnt初始化
  bdev_cache_init();
  chrdev_init();
}

/* kernel/fs/namespace.c */
void __init mnt_init(void)
{
  err = sysfs_init();
  init_rootfs();         //初始化rootfs文件系统
  init_mount_tree();     //初始化加载树
}

/* fs/ramfs/inode.c */
static struct file_system_type rootfs_fs_type = {
    .name       = "rootfs",
    .get_sb     = rootfs_get_sb,
    .kill_sb    = kill_litter_super,
};

int __init init_rootfs(void)
{
  err = bdi_init(&ramfs_backing_dev_info);
  
  err = register_filesystem(&rootfs_fs_type);
}

//fs/filesystem.c
int register_filesystem(struct file_system_type * fs)
{
    int res = 0;
    struct file_system_type ** p;

    BUG_ON(strchr(fs->name, '.'));
    if (fs->next)
        return -EBUSY;
    INIT_LIST_HEAD(&fs->fs_supers);
    write_lock(&file_systems_lock);
    p = find_filesystem(fs->name, strlen(fs->name));//查找到文件系统加载位置
    if (*p)
        res = -EBUSY;
    else
        *p = fs;
    write_unlock(&file_systems_lock);
    return res;
}

下面部分调用文件系统的init

/* init/main.c */
static noinline void __init_refok rest_init(void)
    __releases(kernel_lock)
{
  kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
}

static int __init kernel_init(void * unused)
{
  if (!ramdisk_execute_command)
      ramdisk_execute_command = "/init";

  init_post();
}

static noinline int init_post(void)
    __releases(kernel_lock)
{
  /*
   * We try each of these until one succeeds.
   */
  if (execute_command) {
    run_init_process(execute_command);
  }
  run_init_process("/sbin/init");
  run_init_process("/etc/init");
  run_init_process("/bin/init");
  run_init_process("/bin/sh");
}

参考:

VFS

http://www.cppblog.com/bujiwu/archive/2010/07/04/119301.html

start_kernel()

http://blog.csdn.net/pottichu/article/details/4261228

RAMFS

http://hi.baidu.com/deep_pro/blog/item/220df2dddac6e3d28d1029dd.html