1、根文件系统存放在flash中,设备启动过程中会耗时比较久时间。这是因为从flash中读取rootfs的数据操作比较耗时,同时读取存放在rootfs中的*.so,*.ko等文件也比较耗时。这都是由flash本身的读写属性决定的。对于一些需要快速启动的设备,flash的读写速率无法满足,因此可以考虑挂载到内存中的rootfs,即ramdisk。

2、使用ramdisk需要内核的支持,需要打开CONFIG_BLK_DEV_INITRD宏

3、initramfs初始化流程图如下图所示,主要分成两部分。
3.1、挂载rootfs(“/”),vfs_caches_init分支
3.2、制作rootfs,rest_init分支

4、建立rootfs

struct vfsmount *
vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
{......root = mount_fs(type, flags, name, data);......
}
EXPORT_SYMBOL_GPL(vfs_kern_mount);

根据vfs_kern_mount函数传入的name="rootfs",最终会执行rootfs_mount完成根文件系统建立。

static struct file_system_type rootfs_fs_type = {.name      = "rootfs",.mount        = rootfs_mount,.kill_sb    = kill_litter_super,
};

5、制作根文件系统
5.1、如何从__initcall6_start到populate_rootfs
device_initcall(populate_rootfs);
populate_rootfs函数通过device_initcall宏,装载到特定的section中(.initcall6.init)

#define device_initcall(fn)      __define_initcall(fn, 6)
#define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id)
#define ___define_initcall(fn, id, __sec) \static initcall_t __initcall_##fn##id __used \__attribute__((__section__(#__sec ".init"))) = fn;

即device_initcall函数__initcall_populate_rootfs6存放在.initcall6.init的section中
通过//include/asm-generic/vmlinux.lds.h 链接脚本文件,发现

当执行__initcall6_start函数时,就是执行存放在.initcall6.init这个section的数据,即__initcall_populate_rootfs6函数

5.2、制作rootfs

static int __init populate_rootfs(void)
{char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size);......if (initrd_start) {......printk(KERN_INFO "Unpacking initramfs...\n");err = unpack_to_rootfs((char *)initrd_start,initrd_end - initrd_start);if (err)printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err);free_initrd();/** Try loading default modules from initramfs.  This gives* us a chance to load before device_initcalls.*/load_default_modules();}return 0;
}

5.2.1、先unpcak_to_rootfs的[__initramfs_start, __initramfs_start+__initramfs_size]数据
通过//include/asm-generic/vmlinux.lds.h 链接脚本文件,发现

其中定义了.init.ramfs和.init.ramfs.info两个section
通过//usr/initramfs_data.S文件发现,__initramfs_size大小由initramfs_data.o确定

其中INITRAMFS_IMAGE在//usr/Makefile文件中定义

initramfs加载后一般不会使用

5.2.2、后unpack_to_rootfs的[initrd_start, initrd_end]数据
其中initrd_end和initrd_start通过cmdline传入,并且数据在uboot阶段已经从flash的rootfs分区解压后搬迁到initrd_start地址。

5.2.2.1、flash镜像中rootfs的制作
rootfs通过cpio命令制作生成*.cpio的文件,根据压缩方式完成压缩(build\images.mk脚本中)

#lzo压缩方式,rootfs.bin是rootfs_initramfs.cpio经过lzo压缩后的文件
lzop -x rootfs.bin
#将cpio文件转换成目录格式,ls查看具体的目录内容
cpio -idmv < rootfs_initramfs.cpio 

5.2.2.2、内存中rootfs的制作

static char * __init unpack_to_rootfs(char *buf, unsigned len)
{......while (!message && len) {loff_t saved_offset = this_header;if (*buf == '0' && !(this_header & 3)) {state = Start;written = write_buffer(buf, len);......}......this_header = 0;decompress = decompress_method(buf, len, &compress_name);if (decompress) {res = decompress(buf, len, NULL, flush_buffer, NULL,&my_inptr, error);if (res)error("decompressor failed");} ......}
}

当前buf中的数据已经完成解压,直接通过write_buffer函数制作;不通过具体的压缩方式decompress后flush_buffer实现
write_buffer中通过以下函数解析buf数据,完成根文件系统的制作

static __initdata int (*actions[])(void) = {[Start]         = do_start,[Collect]       = do_collect,[GotHeader]       = do_header,[SkipIt]       = do_skip,[GotName]        = do_name,[CopyFile]       = do_copy,[GotSymlink] = do_symlink,[Reset]           = do_reset,
};

6、运行跟文件系统中的应用程序

//kernel_init函数内,执行ramdisk_execute_command应用程序,其中ramdisk_execute_command从cmdline中传入
if (ramdisk_execute_command) {if (!run_init_process(ramdisk_execute_command))return 0;pr_err("Failed to execute %s\n", ramdisk_execute_command);
}

initRD的启动流程分析相关推荐

  1. Bootm启动流程分析

    Bootm启动流程分析 如何引导内核 uboot启动命令 内核镜像介绍 内核启动前提 Bootm命令详解 Bootm命令格式 do_bootm do_bootm_subcommand images全局 ...

  2. 解析并符号 读取dll_Spring IOC容器之XmlBeanFactory启动流程分析和源码解析

    一. 前言 Spring容器主要分为两类BeanFactory和ApplicationContext,后者是基于前者的功能扩展,也就是一个基础容器和一个高级容器的区别.本篇就以BeanFactory基 ...

  3. Zygote进程启动流程分析

    文中的源代码版本为api23 Zygote进程启动流程分析 先说结论,zygote进程启动过程中主要做了下面这些事情: 启动DVM虚拟机 预加载部分资源,如一些通用类.通用资源.共享库等 启动syst ...

  4. c++builder启动了怎么停止_App 竟然是这样跑起来的 —— Android App/Activity 启动流程分析...

    在我的上一篇文章: AJie:按下电源键后竟然发生了这一幕 -- Android 系统启动流程分析​zhuanlan.zhihu.com 我们分析了系统在开机以后的一系列行为,其中最后一阶段 AMS( ...

  5. SpringBoot启动流程分析(四):IoC容器的初始化过程

    SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...

  6. Exynos4412 Uboot 移植(二)—— Uboot 启动流程分析

    uboot启动流程分析如下: 第一阶段: a -- 设置cpu工作模式为SVC模式 b -- 关闭中断,mmu,cache v -- 关看门狗 d -- 初始化内存,串口 e -- 设置栈 f -- ...

  7. bootloader启动流程分析

    bootloader启动流程分析 1.Bootloader的概念和作用 Bootloader是嵌入式系统的引导加载程序,它是系统上电后运行的第一段程序.在完成对系统的初始化任务之后,它会将Flash中 ...

  8. MyBatis启动流程分析

    目录 MyBatis简单介绍 启动流程分析 简单总结 附录 MyBatis内置别名转换 参考 MyBatis简单介绍 MyBatis是一个持久层框架,使用简单,学习成本较低.可以执行自己手写的SQL语 ...

  9. NameNode之启动流程分析

    NameNode启动流程分析 public staticvoid main(Stringargv[]) throws Exception { if (DFSUtil.parseHelpArgument ...

最新文章

  1. 新警达尼亚尔·迪力木拉提的春运一天
  2. 微信小程序免费SSL证书https、TLS版本问题的解决方案
  3. 神经网络的输入对迭代次数的影响
  4. SAP Oracle EBS集成解决方案
  5. MYSQL主从同步故障一例及解决过程
  6. MySQL:为什么用limit时,offset很大会影响性能
  7. php 禁用外部实体,php – Doctrine 2 – 从实体外部禁用PrePersist
  8. atlas 力矩计算_Atlas Copco基本拧紧技术
  9. 2021年中青杯B题港珠澳大桥桥梁设计与安全策略数学建模全过程文档及程序
  10. vtp协议服务器配置,VTP协议
  11. 宝塔面板ftp空间连接失败解决方案汇总
  12. Vue打包出现Browserslist: caniuse-lite is outdated
  13. 【报告分享】 2020年中国汽车用户消费洞察白皮-懂车帝巨量算数(附下载)
  14. 微信免卸载降级安装方法
  15. Hexo-fluid主题添加51LA统计
  16. 考验直播平台搭建水平的十个性能指标
  17. 拾叁-关于R语言中括号的一些事,以及因子、向量转换的一些情
  18. 网络常用密码忘记破解方法
  19. 曾轶可16首原创歌词 小生整理完整版
  20. 基于asp.net高考志愿填报参考信息管理系统#毕业设计

热门文章

  1. 股票入门基础知识第88集:送红股和派现金哪个好?
  2. AJAX传值中文乱码
  3. SQL语句之聚合函数
  4. 【c++】因模板类导致的 LNK2019 错误:“ 无法解析的外部符号 ” 详解
  5. 搞懂性能指标专业术语,性能面试不再懵圈
  6. java exchange 数字证书认证_java处理加密文件---数字证书文件格式(cer和pfx)的区别 - 数安时代(GDCA)SSL证书官网...
  7. 关于贝叶斯概率(Bay概率(Bayes theory)
  8. 利用深度学习实现手绘数据可视化的生成
  9. 关于 batis.binding.BindingException: Invalid bound statement (not found) 解决方案
  10. c语言输出cad scr文件,屏幕保护程序文件scr关联被autocad修改为CAD脚本的恢复