博客首页 注册 建议与交流 排行榜 加入友情链接
推荐 投诉 搜索: 帮助

gliethttp

2005年07月毕业于桂林电子工业学院普通本科生的工作笔记--我们chinese人要学的东西还有很多很多,所以兄弟们可都要加油啊...... 欢迎访问~ luther.gliethttp Regards
  gliethttp.cublog.cn

关于作者
姓名:飞镖 luther
职业:摸索中
年龄:1982
邮箱:luther.ge@163.com
位置:北京朝阳区安贞西里2区
个性介绍:

0>需要能打,但更需要能挨;
  能打如卫青,能挨如李广.
1>UNIX is basically a simple 
  operating system, but you 
  have to be a genius to 
  understand the simplicity.
2>人以铜为镜,可以正衣冠;以
  史为镜,可以知兴亡;以人为
  镜,可以明得失
3>1只笼子养着两只公鸡,打鸣那
  是一个比一个响
4>要是甘蔗两端一样甜,那谁还
  会辛辛苦苦抢着吃后边那一节
5>审问、慎思、明辨、力行、
  观其人
6>宦海浮沉,世事难测;
  朝中熙熙,多为利来;
  宫中攘攘,多为利往。
7>桃花坞里桃花庵,
  桃花庵下桃花仙; 
  桃花仙人种桃树,
  又摘桃花换酒钱。
  ......
  别人笑我太疯癫,
  我笑他人看不穿; 
  不见五陵豪杰墓,
  无花无酒锄作田。哈哈哈哈哈
8>贵有恒,何必三更起五更勤;
  最无益,只怕一日曝十日寒
9>君不密,则失臣;
  臣不密,则失身;
  几事不密,则成害!
10>汉武帝的人生4目标:
  修身、齐家、治国、平天下

|| << >> ||
我的分类


浅析linux2.6.24内核initrd传递给rootfs进行系统加载流程

浅析linux2.6.24内核initrd传递给rootfs进行系统加载流程

1.解析有loader传递过来的initrd参数
start_kernel()->
setup_arch()->
parse_tags()->
使用下面这个函数进行解析:
static int __init parse_tag_initrd(const struct tag *tag)
{
    printk(KERN_WARNING "ATAG_INITRD is deprecated; "
        "please update your bootloader.\n");
    phys_initrd_start = __virt_to_phys(tag->u.initrd.start);
    phys_initrd_size = tag->u.initrd.size;
    return 0;
}
__tagtable(ATAG_INITRD, parse_tag_initrd);

2.进一步初始化initrd_start变量
start_kernel()->
setup_arch()->
paging_init()->
bootmem_init()->
bootmem_init_node()->
在该函数中使用下面2个语句将物理地址转为虚拟地址
#ifdef CONFIG_BLK_DEV_INITRD
    ...
    initrd_start = __phys_to_virt(phys_initrd_start);
    initrd_end = initrd_start + phys_initrd_size;
    ...
#endif
3.建立rootfs文件系统,并mount到根目录
start_kernel()->
vfs_caches_init()->
mnt_init()->
init_rootfs()->位于fs/ramfs/inode.c中,调用register_filesystem(&rootfs_fs_type);注册rootfs
接下来
init_mount_tree()函数将调用mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);将rootfs挂在到/根目录下
然后使用如下两个函数,将后边建立线程的根目录指向rootfs,
set_fs_pwd(current->fs, ns->root, ns->root->mnt_root);
set_fs_root(current->fs, ns->root, ns->root->mnt_root);
4.将initrd(的ramdisk加载到rootfs
start_kernel()->
rest_init()->
kernel_init()->内核线程
do_basic_setup()->
do_initcalls()->调用所有arch/arm/kernel/vmlinux.lds.S中定义的INITCALLS模块,比如:使用module_init内建到zImage中的所有驱动模块

#define pure_initcall(fn)        __define_initcall("0",fn,0)
#define core_initcall(fn)        __define_initcall("1",fn,1)
#define core_initcall_sync(fn)        __define_initcall("1s",fn,1s)
#define postcore_initcall(fn)        __define_initcall("2",fn,2)
#define postcore_initcall_sync(fn)    __define_initcall("2s",fn,2s)
#define arch_initcall(fn)        __define_initcall("3",fn,3)
#define arch_initcall_sync(fn)        __define_initcall("3s",fn,3s)
#define subsys_initcall(fn)        __define_initcall("4",fn,4)
#define subsys_initcall_sync(fn)    __define_initcall("4s",fn,4s)
#define fs_initcall(fn)            __define_initcall("5",fn,5)
#define fs_initcall_sync(fn)        __define_initcall("5s",fn,5s)
#define rootfs_initcall(fn)        __define_initcall("rootfs",fn,rootfs)
#define device_initcall(fn)        __define_initcall("6",fn,6)
#define device_initcall_sync(fn)    __define_initcall("6s",fn,6s)
#define late_initcall(fn)        __define_initcall("7",fn,7)
#define late_initcall_sync(fn)        __define_initcall("7s",fn,7s)

上面我们关心的是rootfs_initcall定义,
在init/initramfs.c中具体实现如下:
rootfs_initcall(populate_rootfs);
populate_rootfs()会调用下面这个函数将initrd的内容释放到rootfs文件系统下
unpack_to_rootfs((char *)initrd_start,initrd_end - initrd_start, 0);
这样initrd的ramdisk的内容全部释放到了rootfs文件系统中,所以ramdisk下的所有目录结构将全部被克隆到rootfs文件系统下,具体unpack_to_rootfs函数的实现流程,以后有时间再研究(gliethttp_20080514)

发表于: 2008-05-14,修改于: 2008-05-14 18:38,已浏览888次,有评论0条 推荐 投诉


网友评论
 发表评论