分类: LINUX
2010-03-08 16:23:54
关于initramfs
initramfs概述
initramfs与initrd类似,也是初始化好了且存在于ram中的,可以压缩也可以不压缩。但是目前initramfs只支持cpio包格式,它会被populate_rootfs()->unpack_to_rootfs(&__initramfs_ start, &__initramfs_end - &__initramfs_start, 0)函数(解压缩、)解析、安装。
initramfs与initrd的区别
1)Linux内核只认cpio格式的initramfs文件包(因为unpack_to_rootfs只能解析cpio格式文件),非cpio格式的initramfs文件包将被系统抛弃,而initrd可以是cpio包也可以是传统的印象(image)文件,实际使用中initrd都是传统印象文件。
2)initramfs在编译内核的同时被编译并与内核连接成一个文件,它被链接到地址__initramfs_star处,与内核同时被bootloader加载到ram中,而initrd是另外单独编译生成的,是一个独立的文件,它由bootloader单独加载到ram中内核空间外的地址,比如加载的地址为addr(是物理地址而非虚拟地址),大小为8MB,那么只要在命令行中加入“initrd=addr,
3)initramfs被解析处理后其原始的cpio包(压缩或非压缩)所占的空间(&__initramfs_start~&__initramfs_end)是作为系统的一部分一直保留在系统中,不会被释放掉,而对于initrd的印象(image)文件,如果没有在命令行中设置“keepinitrd”命令,即keep_initrd全局变量等于0,那么initrd印象文件被处理后其原始文件(压缩或非压缩)所占的空间(initrd_start~initrd_end)将被释放掉。
4)initramfs可以独立于ram disk单独存在,而要支持initrd必须首先支持ramdisk,即要配置CONFIG_BLK_DEV_INITRD选项首先必须配置CONFIG_BLK_DEV_RAM,因为initrd image实际就是初始化好了的ram disk印象文件,最后都要解析、写入到ram disk设备/dev/ram或/dev/ram0中。
initramfs相关全局变量
__initramfs_start
char数据类型,&__initramfs_start就是initramfs的cpio包起始虚拟地址。
__initramfs_end
char数据类型,&__initramfs_end就是initramfs的cpio包结束虚拟地址。
initramfs被编译链接的位置
initramfs被链接到&__initramfs_start虚拟地址处,属于.init.ramfs区,&__initramfs_start和&__initramfs_end在链接文件arch/arm/kernel/vmlinux.lds.S中定义如下:
__initramfs_start = .;
usr/built-in.o(.init.ramfs);所以initramfs文件实际就是usr目录下的built-in.o文件
__initramfs_end = .;
.init.ramfs在Linux2.6.10/usr/initramfs_data.S中定义,编译内核时会先编译Linux2.6.10\usr\gen_init_cpio.c生成应用程序gen_init_cpio;然后用gen_init_cpio生成Linux2.6.10\usr\ initramfs_data.cpio(.gz),它就是保存在&__initramfs_start与&__initramfs_end之间的.init.ramfs;可以通过修改Linux2.6.10\usr\Makefile文件将来使得编译链接时是否压缩initramfs。
initramfs文件的生成过程
1)cpio包格式二进制initramfs文件是由gen_init_cpio命令生成的,gen_init_cpio应用程序是由Linux
gen_init_cpio命令格式:
# ./gen_init_cpio
Usage:
./gen_init_cpio
# a comment ;注释行;
file
dir
nod
# Last modified: 1206050528
dir /dev 0755 0 0
nod /dev/console 0600 0
dir /root 0700 0 0
dir //lost+found 700 0 0
dir //bin 755 0 0
file //bin/addgroup /home/whh/tmp/bin/addgroup 777 0 0
file //bin/adduser /home/whh/tmp/bin/adduser 777 0 0
2)
方法一:根据上述
方法二:写一个脚本文件一次性为指定目录下的每个文件/目录/节点生成一行描述符,并将它们全部写入一个指定的
# . ./gen_initramfs_list.sh
将把生成的所有文件、目录、节点的描述行写入文件my_cpio_list中。如果命令行中没有指定
dir /dev 0755 0 0
nod /dev/console 0600 0
dir /root 0700 0 0
3)配置并编译initramf
将要作为initramfs的目录放在某个目录下,如“/home/my_root/”目录。或者将已经写好的
将内核配置文件myconfig中的
CONFIG_INITRAMFS_SOURCE=""
改成
CONFIG_INITRAMFS_SOURCE="/home/my_root"
或者
CONFIG_INITRAMFS_SOURCE="/home/my_list"
执行
# make myconfig
# make
或者将上面两步改成如下形式并执行:
# make menuconfig
在逐级弹出的
“Block devices”->“Source directory or cpio_list”
子菜单下输入:
/home/my_root
或者
/home/my_list
然后执行
# make
4)Linux
Linux
5)从arm中编译出的内核印象文件Image、编译连接文件vmlinux.lds.S、cpio格式initramfs二进制压缩文件initramfs_data.cpio.gz、编译连接符号文件System.map对照看,事实上链接到&__initramfs_start位置的就是initramfs_data.cpio.gz文件。