记录自己学习android系统启动以及 recovery过程(1)----------kernel
kernel阶段,代码比较复杂,才看懂基本流程。。。。。
在kernel阶段,会根据传递进来的参数,进行初始化并挂载root
1. uboot->kernel的参数解析模式
解析tag函数流程: start_kernel->setup_arch->parse_tags
以initrc举例,在uboot中,配置函数为:
static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end)
{
/* an ATAG_INITRD node tells the kernel where the compressed
* ramdisk can be found. ATAG_RDIMG is a better name, actually.
*/
params->hdr.tag = ATAG_INITRD2;
params->hdr.size = tag_size (tag_initrd);
params->u.initrd.start = initrd_start;
params->u.initrd.size = initrd_end - initrd_start;
params = tag_next (params);
}
在kernel中,存在相应的解析函数:
static int __init parse_tag_initrd2(const struct tag *tag)
{
phys_initrd_start = tag->u.initrd.start;
phys_initrd_size = tag->u.initrd.size;
return 0;
}
__tagtable(ATAG_INITRD2, parse_tag_initrd2);
可以看到,这两个函数都使用到了相同的宏ATAG_INITRD2,在kernel中,__tagtable标志使得ATAG_INITRD2, parse_tag_initrd2被注册进了一个结构体tagtable,并在解析tag时,通过比较相应的宏是否一致,调用注册的函数进行解析
在上述函数中:phys_initrd_start,phys_initrd_size是被初始化为0的,因此,当传进来的tag中,不含有ATAG_INITRD2时,这两个变量均等于0。
2. 初始化rootfs文件系统
初始化rootfs文件系统流程:start_kernel->vfs_caches_init->mnt_init
mnt_init函数如下:
void __init mnt_init(void)
{
......
init_rwsem(&namespace_sem);
......
err = sysfs_init();
......
fs_kobj = kobject_create_and_add("fs", NULL);
......
init_rootfs(); /*注册rootfs文件系统*/
init_mount_tree(); /*这步执行结束后,文件系统中存在目录‘/’,以后的文件系统,会挂载在这个目录下*/
}
init_rootfs:
int __init init_rootfs(void)
{
int err;
err = bdi_init(&ramfs_backing_dev_info);
if (err)
return err;
err = register_filesystem(&rootfs_fs_type); /*rootfs 结构体*/
if (err)
bdi_destroy(&ramfs_backing_dev_info);
return err;
}
rootfs结构体:
static struct file_system_typ