一万年太久,只争朝夕
分类: Android平台
2015-02-12 16:15:20
参考:http://www.ibm.com/developerworks/cn/linux/l-initrd.html
1、 initrd是什么?
Initrd英文含义是boot loader initialized RAM disk,即由bootloader初始化的内存盘。所谓内存盘的概念,即是指的处于内存中的文件系统。为什么这样说,在计算机概念术语里,看得见的磁盘,其实都是文件系统呈现给你的一种表象,隐藏在文件系统背后的那些磁盘目录是实实在在存在于外部的硬盘(PC)或者NAND/EMMC(手机)。而内存中存在的内存盘的概念,只能说是将内存仿成磁盘的形式,而非真正的磁盘。
简单来讲,initrd就是一个文件系统!
在ibm的技术文档中,展示了一个典型的initrd镜像所包含的内容:
drwxr-xr-x 10 root root 4096 May 7 02:48 .
drwxr-x--- 15 root root 4096 May 7 00:54 ..
drwxr-xr-x 2 root root 4096 May 7 02:48 bin
drwxr-xr-x 2 root root 4096 May 7 02:48 dev
drwxr-xr-x 4 root root 4096 May 7 02:48 etc
-rwxr-xr-x 1 root root 812 May 7 02:48 init
-rw-r--r-- 1 root root 1723392 May 7 02:45 initrd-2.6.14.2.img
drwxr-xr-x 2 root root 4096 May 7 02:48 lib
drwxr-xr-x 2 root root 4096 May 7 02:48 loopfs
drwxr-xr-x 2 root root 4096 May 7 02:48 proc
lrwxrwxrwx 1 root root 3 May 7 02:48 sbin -> bin
drwxr-xr-x 2 root root 4096 May 7 02:48 sys
drwxr-xr-x 2 root root 4096 May 7 02:48 sysroot
可以发现这个小型的文件系统包含了后续真正的根文件系统起来之后要运行的init。
所以手机启动之后,进入的根目录就在内存中。看得见的常见的/system、/cache、/data是磁盘文件系统,其他的都是存在于内存中的文件系统,在init.rc中,针对磁盘文件系统执行的是挂载的动作,而对于内存文件系统,则执行的是mkdir,典型的/sys、/dev、/proc都属于这个情况。
2、initrd用来干嘛的?
Initrd做了两件事:
1) 加载访问真正的根文件系统所需要的驱动模块
2) 加载真正的根文件系统。
所以,initrd也被称为临时根文件系统
这里需要说明一个问题,根文件系统归根结底也是存储在文件中的数据,那么加载数据就需要先加载存储设备的驱动,由于硬件架构不同,根文件系统可能存储在IDE、SCSI、USB等多种介质上,内核不会将这些驱动都编译进内核,所以采用了initrd来根据实际的硬件架构加载对应的存储设备驱动,从而读取真正的根文件系统数据。
3、一些重要的术语:
rootfs: 一个基于内存的文件系统,是linux在初始化时加载的第一个文件系统。
initramfs:内核镜像中附加一个cpio包,这个cpio包中包含了一个小型的文件系统,当内核启动时,内核将这个cpio包解开,并且将其中包含的文件系统释放到rootfs中,内核中的一部分初始化代码会放到这个文件系统中,作为用户层进程来执行。Linux 2.6.12内核的 initramfs还没有什么实质性的东西。
cpio-initrd: 前面已经定义过,指linux2.6内核使用的cpio格式的initrd。
image-initrd: 前面已经定义过,专指传统的文件镜像格式的initrd。
realfs: 用户最终使用的真正的文件系统。
cpio-initrd的处理流程在如下两个方面得到了简化:
1). cpio-initrd并没有使用额外的ramdisk,而是将其内容输入到rootfs中,其实rootfs本身也是一个基于内存的文件系统。这样就省掉了ramdisk的挂载、卸载等步骤。
2). cpio-initrd启动完/init进程,内核的任务就结束了,剩下的工作完全交给/init处理;而对于image-initrd,内核在执行完/linuxrc进程后,还要进行一些收尾工作,并且要负责执行真正的根文件系统的/sbin/init。
支持 "RAM disk" 和 "Initial RAM disk" 的配置:
CONFIG_BLK_DEV_RAM=y and CONFIG_BLK_DEV_INITRD=y)
这个设备是一个RAM disk,在kernel起来之前,已经被bootloader初始化了,kernel可以使用/dev/initrd的内容做一个二次系统开机
第一开机阶段,kernel启动,并根据/dev/initrd的内容挂载一个初始的根文件系统,第二阶段,其他的驱动或者模块从初始根设备的内容被加载。待这些模块加载之后,一个新的根文件系统(即normal根文件系统)从另外的设备挂载。
4、一些重要的文件
/dev/initrd:是一个只读的块设备,主设备号1,次设备号250.典型的,/dev/initrd是root.disk所有,权限0400(根用户权限可读)。可用以下命令创建设备节点:
mknod -m 400 /dev/initrd b 1 250
chown root:disk /dev/initrd
/dev/ram0:在内核初始化过程中,内核把 /dev/initrd 设备的内容解压缩并拷贝到 /dev/ram0 设备上,内核以可读写的方式把 /dev/ram0 设备挂载为原始的根文件系统,如果 /dev/ram0 被指定为真正的根文件系统,那么内核跳至最后一步正常启动,如果真正的根文件系统存在 /initrd 目录,那么 /dev/ram0 将从 / 移动到 /initrd。否则如果 /initrd 目录不存在, /dev/ram0 将被卸载。
linuxrc:image-initrd格式initrd镜像文件挂载之后,根目录下的核心文件。Cpio-initrd格式的initrd镜像的核心文件则是init。内核挂载 RAM 磁盘之后,它会查找 init 文件来执行。如果没有找到 init 文件,内核就会调用 linuxrc 文件作为自己的启动脚本。