Chinaunix首页 | 论坛 | 博客
  • 博客访问: 622171
  • 博文数量: 168
  • 博客积分: 1053
  • 博客等级: 少尉
  • 技术积分: 1187
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-30 17:20
个人简介

公众号【嵌入式er笔记】持续记录和分享C/C++、Linux、ARM、Android、IoT等技术相关知识,以及职场、生活经验和感悟。

文章分类

全部博文(168)

分类: 嵌入式

2014-10-11 21:04:47

原文地址:关于initramfs 作者:hpuwangbo

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,8M”命令系统就可以找到initrd(当然通过适当修改Linux的目录架构、makefile文件和相关代码,以上两种情况都是可以相通的)。

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应用程序是由Linux2.6.10/gen_init_cpio.c文件编译而来,gen_init_cpio命令格式和用法说明如下。

gen_init_cpio命令格式:

# ./gen_init_cpio

Usage:

    ./gen_init_cpio

文件格式:

# a comment ;注释行;

file            ;描述initramfs中的一个文件

dir                        ;描述initramfs中的一个目录

nod ;描述initramfs中的一个节点

文件每一行各字段说明:

      :该文件/目录/节点在initramfs中的名字,包含绝对路径

  :该文件/目录/节点在当前开发主机上的位置

      :该文件/目录/节点的模式字

       :该文件/目录/节点的用户id,0表示root用户

       :该文件/目录/节点的组id,0表示root组

  :该设备节点对应设备的类型,b表示块设备,c表示字符设备

       :设备节点对应设备的主设备号

       :设备节点对应设备的次设备号

文件示例:

# Last modified: 1206050528

 

dir /dev 0755 0 0

nod /dev/console 0600 0 0 c 5 1

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)文件生成方式

方法一:根据上述文件格式说明自行编写。

方法二:写一个脚本文件一次性为指定目录下的每个文件/目录/节点生成一行描述符,并将它们全部写入一个指定的文件中。在Linux2.6.10原始目录下的scripts\gen_initramfs_list.sh就是这样的脚本文件。它的使用方法如下:

# . ./gen_initramfs_list.sh 或<目录> >

将把生成的所有文件、目录、节点的描述行写入文件my_cpio_list中。如果命令行中没有指定和<目录>,那么gen_initramfs_list.sh会自行生成一个最简单的initramfs_list文件,如下所示:

dir /dev 0755 0 0

nod /dev/console 0600 0 0 c 5 1

dir /root 0700 0 0

3)配置并编译initramf

将要作为initramfs的目录放在某个目录下,如“/home/my_root/”目录。或者将已经写好的文件放在某个目录下,如“/home/my_list”。

将内核配置文件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)Linux2.6.10中cpio包格式二进制initramfs文件实际产生流程

Linux2.6.10中cpio包格式二进制initramfs文件实际产生过程是:第一步,gen_initramfs_list.s为指定目录“/home/my_root”或文件“/home/my_list”在Linux2.6.10/usr目录下生成真正的文件initramfs_list;第二步,gen_init_cpio按照initramfs_list文件描述将对应的目录/home/my_root生成二进制cpio包initramfs_data.cpio;第三步,gzip将initramfs_data.cpio压缩成initramfs_data.cpio.gz;第四步,ld -m elf_i386 --format binary --oformat elf32-i386 -r -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o生成initramfs_data.o;第五步,ld -m elf_i386  -r -o built-in.o initramfs_data.o最后生成built-in.o。

5)从arm中编译出的内核印象文件Image、编译连接文件vmlinux.lds.S、cpio格式initramfs二进制压缩文件initramfs_data.cpio.gz、编译连接符号文件System.map对照看,事实上链接到&__initramfs_start位置的就是initramfs_data.cpio.gz文件。

阅读(2039) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~