initRD的启动流程分析
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的启动流程分析相关推荐
- Bootm启动流程分析
Bootm启动流程分析 如何引导内核 uboot启动命令 内核镜像介绍 内核启动前提 Bootm命令详解 Bootm命令格式 do_bootm do_bootm_subcommand images全局 ...
- 解析并符号 读取dll_Spring IOC容器之XmlBeanFactory启动流程分析和源码解析
一. 前言 Spring容器主要分为两类BeanFactory和ApplicationContext,后者是基于前者的功能扩展,也就是一个基础容器和一个高级容器的区别.本篇就以BeanFactory基 ...
- Zygote进程启动流程分析
文中的源代码版本为api23 Zygote进程启动流程分析 先说结论,zygote进程启动过程中主要做了下面这些事情: 启动DVM虚拟机 预加载部分资源,如一些通用类.通用资源.共享库等 启动syst ...
- c++builder启动了怎么停止_App 竟然是这样跑起来的 —— Android App/Activity 启动流程分析...
在我的上一篇文章: AJie:按下电源键后竟然发生了这一幕 -- Android 系统启动流程分析zhuanlan.zhihu.com 我们分析了系统在开机以后的一系列行为,其中最后一阶段 AMS( ...
- SpringBoot启动流程分析(四):IoC容器的初始化过程
SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...
- Exynos4412 Uboot 移植(二)—— Uboot 启动流程分析
uboot启动流程分析如下: 第一阶段: a -- 设置cpu工作模式为SVC模式 b -- 关闭中断,mmu,cache v -- 关看门狗 d -- 初始化内存,串口 e -- 设置栈 f -- ...
- bootloader启动流程分析
bootloader启动流程分析 1.Bootloader的概念和作用 Bootloader是嵌入式系统的引导加载程序,它是系统上电后运行的第一段程序.在完成对系统的初始化任务之后,它会将Flash中 ...
- MyBatis启动流程分析
目录 MyBatis简单介绍 启动流程分析 简单总结 附录 MyBatis内置别名转换 参考 MyBatis简单介绍 MyBatis是一个持久层框架,使用简单,学习成本较低.可以执行自己手写的SQL语 ...
- NameNode之启动流程分析
NameNode启动流程分析 public staticvoid main(Stringargv[]) throws Exception { if (DFSUtil.parseHelpArgument ...
最新文章
- 新警达尼亚尔·迪力木拉提的春运一天
- 微信小程序免费SSL证书https、TLS版本问题的解决方案
- 神经网络的输入对迭代次数的影响
- SAP Oracle EBS集成解决方案
- MYSQL主从同步故障一例及解决过程
- MySQL:为什么用limit时,offset很大会影响性能
- php 禁用外部实体,php – Doctrine 2 – 从实体外部禁用PrePersist
- atlas 力矩计算_Atlas Copco基本拧紧技术
- 2021年中青杯B题港珠澳大桥桥梁设计与安全策略数学建模全过程文档及程序
- vtp协议服务器配置,VTP协议
- 宝塔面板ftp空间连接失败解决方案汇总
- Vue打包出现Browserslist: caniuse-lite is outdated
- 【报告分享】 2020年中国汽车用户消费洞察白皮-懂车帝巨量算数(附下载)
- 微信免卸载降级安装方法
- Hexo-fluid主题添加51LA统计
- 考验直播平台搭建水平的十个性能指标
- 拾叁-关于R语言中括号的一些事,以及因子、向量转换的一些情
- 网络常用密码忘记破解方法
- 曾轶可16首原创歌词 小生整理完整版
- 基于asp.net高考志愿填报参考信息管理系统#毕业设计
热门文章
- 股票入门基础知识第88集:送红股和派现金哪个好?
- AJAX传值中文乱码
- SQL语句之聚合函数
- 【c++】因模板类导致的 LNK2019 错误:“ 无法解析的外部符号 ” 详解
- 搞懂性能指标专业术语,性能面试不再懵圈
- java exchange 数字证书认证_java处理加密文件---数字证书文件格式(cer和pfx)的区别 - 数安时代(GDCA)SSL证书官网...
- 关于贝叶斯概率(Bay概率(Bayes theory)
- 利用深度学习实现手绘数据可视化的生成
- 关于 batis.binding.BindingException: Invalid bound statement (not found) 解决方案
- c语言输出cad scr文件,屏幕保护程序文件scr关联被autocad修改为CAD脚本的恢复