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
浙公网安备 33010602011771号