Initramfs 原理和实践
Linux系统启动时使用initramfs (initram file system), initramfs可以在启动早期提供一个用户态环境,借助它可以完成一些内核在启动阶段不易完成的工作。当然initramfs是可选的,Linux中的内核编译选项默认开启initrd。在下面的示例情况中你可能要考虑用initramfs。
- 加载模块,比如第三方driver
- 定制化启动过程 (比如打印welcome message等)
- 制作一个非常小的rescue shell
- 任何kernel不能做的,但在用户态可以做的 (比如执行某些命令)
一个initramfs至少要包含一个文件,文件名为/init。内核将这个文件执行起来的进程作为main init进程(pid 1)。当内核挂载initramfs后,文件系统的根分区还没有被mount, 这意味着你不能访问文件系统中的任何文件。如果你需要一个shell,必须把shell打包到initramfs中,如果你需要一个简单的工具,比如ls, 你也必须把它和它依赖的库或者模块打包到initramfs中。总之,initramfas是一个完全独立运行的体系。
另外initramfs打包的时候,要求打包成压缩的cpio档案。cpio档案可以嵌入到内核image中,也可以作为一个独立的文件在启动的过程中被GRUB load。
Linux的initramrd img
在/boot目录下的initrd.img-xxx (Ubuntu)或者initramfs-xxx.img (CentOS) 文件即为Linux用的initramfs文件。我们可以将其解压出来看看其目录结构,如下:
# ls -l /boot/ total 67408 -rw-r--r-- 1 root root 1240067 Jul 13 2016 abi-4.4.0-31-generic -rw-r--r-- 1 root root 1247269 Aug 15 2017 abi-4.4.0-93-generic -rw-r--r-- 1 root root 189566 Jul 13 2016 config-4.4.0-31-generic -rw-r--r-- 1 root root 190364 Aug 15 2017 config-4.4.0-93-generic drwxr-xr-x 5 root root 4096 Jul 4 17:23 grub -rw-r--r-- 1 root root 21977388 Aug 24 2017 initrd.img-4.4.0-31-generic -rw-r--r-- 1 root root 22440248 Aug 24 2017 initrd.img-4.4.0-93-generic -rw------- 1 root root 3879360 Jul 13 2016 System.map-4.4.0-31-generic -rw------- 1 root root 3899015 Aug 15 2017 System.map-4.4.0-93-generic -rw------- 1 root root 6937248 Jul 13 2016 vmlinuz-4.4.0-31-generic -rw------- 1 root root 7000752 Aug 15 2017 vmlinuz-4.4.0-93-generic # initrd的文件类型是gzip压缩文件 # file /boot/initrd.img-4.4.0-93-generic /boot/initrd.img-4.4.0-93-generic: gzip compressed data, from Unix, last modified: Thu Aug 24 20:51:59 2017 # cp /boot/initrd.img-4.4.0-93-generic . # 文件大小为22M # ls -lh initrd.img-4.4.0-93-generic -rw-r--r-- 1 root root 22M Jul 5 15:46 initrd.img-4.4.0-93-generic # 修改文件的后缀名,否则gzip工具无法识别 # mv initrd.img-4.4.0-93-generic initrd.img-4.4.0-93-generic.gz # 用gzip解压缩 # gzip -d initrd.img-4.4.0-93-generic.gz # 解压后的大小为57M # ls -lh initrd.img-4.4.0-93-generic -rw-r--r-- 1 root root 57M Jul 5 15:46 initrd.img-4.4.0-93-generic # 解压后的文件类型为cpio档案 # file initrd.img-4.4.0-93-generic initrd.img-4.4.0-93-generic: ASCII cpio archive (SVR4 with no CRC) # 将文件从cpio档案中copy出来 # cpio -idmv < initrd.img-4.4.0-93-generic . lib64 lib64/ld-linux-x86-64.so.2 ... lib/systemd lib/systemd/systemd-udevd 115997 blocks # 最终可以看到如下文件和目录结构,就是initramrd的结构 # ls bin conf etc init initrd.img-4.4.0-93-generic lib lib64 run sbin scripts
可以看到initramfs和跟分区文件系统的雏形很像,只是它的大小不大,少了很多工具和库。有些内核模块就在其中,比如:/lib/modules/4.4.0-93-generic/kernel/。
qemu中启动"Hello World" initramfs
在前文“在qemu环境中用gdb调试Linux内核”中,已经准备了一个Linux启动环境,但是缺少initramfs。我们可以做一个最简单的Hello World initramfs,来直观地理解initramfs。
Hello World的C程序如下,与普通的Hello World相比,加了一行while(1)。
#include <stdio.h>void main() {printf("Hello World\n");fflush(stdout);/* 让程序打印完后继续维持在用户态 */while(1); }
编译helloworld.c程序
# gcc -static -o helloworld -m32 helloworld.c
- -static: On systems that support dynamic linking, this prevents linking with the shared libraries. //不让gcc动态链接shared libraries
- -m32: Generate code for a 32-bit or 64-bit environment //在前文“在qemu环境中用gdb调试Linux内核”中Linux内核被编译成了32位架构,所以这里在gcc的选项中也编译成32位可执行程序
在64位机器上编译成32位程序,可能会报错如下:
In file included from /usr/include/stdio.h:27:0,
from helloworld.c:2:
/usr/include/features.h:374:25: fatal error: sys/cdefs.h: No such file or directory
# include <sys/cdefs.h>
^
compilation terminated.
解决方案是安装libc6-dev-i386包。
# apt-get install libc6-dev-i386
打包initramfs文件
# echo helloworld | cpio -o --format=newc > hwinitramfs
在qemu中启动编译好的内核,把hwinitramfs指定为initrd,在-append参数中将init指定为helloworld。
# qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd hwinitramfs -append "console=ttyS0 rdinit=helloworld" -nographic
系统能成功启动到输出"Hello World",并且在用户态停住。结合前文“在qemu环境中用gdb调试Linux内核”,可以看到qemu虚机中运行的Linux系统已经成功挂载了initramfs, 在console日志中也能看到“Unpacking initramfs...”。
参考
Custom Initramfs
GNU CPIO Manual
转载于:https://www.cnblogs.com/wipan/p/9269505.html
Initramfs 原理和实践相关推荐
- Atitit.java jna 调用c c++ dll的原理与实践 总结 v2 q27
Atitit.java jna 调用c c++ dll的原理与实践 总结 v2 q27 1. Jna简单介绍1 2. Jna范例halo owrld1 3. Jna概念2 3.1. (1)需 ...
- Atitit.软件兼容性原理与实践 v3 q326.docx
Atitit.软件兼容性原理与实践 v3 q326.docx 1. 架构兼容性1 2. Api兼容性1 2.1. 新api vs 修改旧的api1 3. Web方面的兼容性(js,html)1 3 ...
- 2018-2019-2 网络对抗技术 20165239Exp3 免杀原理与实践
2018-2019-2 网络对抗技术 20165239 Exp3 免杀原理与实践 win10 ip地址 192.168.18.1 fenix ip地址为 192.168.18.128 (1)杀软是如何 ...
- 20155222卢梓杰 实验三 免杀原理与实践
实验三 免杀原理与实践 1.正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil-evasion,自己利用shellcode编程等免杀工具或技巧 实验步骤如下 1.先对实验二中生 ...
- Webpack原理与实践
简单了解了几个常用的插件,一般适合用于任何类型的项目,不管是否使用了框架.webpack为每个工作环节都预留了合适的钩子,扩展时只需要找到合适的时机去做合适的事情. 写在前面 webpack插件机制的 ...
- 图解Spark原理及实践----大数据技术栈12
回顾:大数据平台技术栈 (ps:可点击查看),今天就来说说其中的Spark! 来自:ITPUB Spark 已经成为广告.报表以及推荐系统等大数据计算场景中首选系统,因效率高,易用以及通用性越来越得到 ...
- NLP汉语自然语言处理原理与实践
NLP汉语自然语言处理原理与实践 作者:郑捷 ISBN号:9787121307652 出版时间:2017-01-01 出版社:电子工业出版社
- 《新一代SDN——VMware NSX 网络原理与实践》——导读
** 前言 ** 当企业需要搭建一个"云"的时候,无论它是公有云还是私有云,其基础架构一定涉及网络.计算和存储这三大块.NIST对云计算的定义中,明确提出了云中资源需要实现&quo ...
- Docker容器的原理与实践(上)
本文来自网易云社区. 虚拟化 是一种资源管理技术,将计算机的各种资源予以抽象.转换后呈现出来, 打破实体结构间的不可切割的障碍,使用户可以比原本更好的方式来应用这些资源. Hypervisor 一种运 ...
- 2018-2019-2 网络对抗技术 20165301 Exp3 免杀原理与实践
2018-2019-2 网络对抗技术 20165301 Exp3 免杀原理与实践 实验内容 任务一:正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil-evasion,自己利用 ...
最新文章
- 【Go】Go基础(九):接口(Interfaces)与反射(reflection)
- TensorFlow object detection api------ssd_mobilenet使用
- IntelliJ Idea 快捷键列表
- Oracle to_char格式化函数
- PAT-乙级-1021. 个位数统计 (15)
- 2013\National _Java_A\3.埃及分数
- Oracle查询指定表里的触发器
- android——wifi系统架构
- jQuery10个重要问题梳理
- rust: 写CTP策略中的几个难点
- Springmvc源码分析之dispatcherServlet
- python中jieba库安装中出现pip库需要更新怎么办_python安装jieba库
- 单词发音网页 (文本处理 python)
- 【CTF】明御攻防实验室misc ningen
- IPSec在企业网络中的应用
- java中的private访问控制
- 用grldr启动ISO
- 梦想还是要有的,万一实现了呢?
- jaspersoft studio创建jasperreport模板 summary显示page header(页眉)
- 8.4.1 搭建自己的SSR