rk3188--3.initramfs_data.cpio的生成及使用

本文详细介绍了initramfs_data.cpio的生成过程,包括Makefile控制流程、gen_initramfs_list.sh脚本分析及gen_init_cpio使用,并阐述如何将其编译进内核。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. usr目录下initramfs_data.cpio的生成过程
1.1 Makefile中控制整个流程
在usr/Makefile中
cmd_initfs = (initramfs)o @ (ramfsargs) (ramfs-input)
(obj)/initramfsdata.cpio (suffix_y): (obj)/geninitcpio (deps_initramfs) klibcdirs
(Q) (initramfs) -l (ramfsinput)> (obj)/.initramfs_data.cpio.d //a.
$(call if_changed,initfs) //b.
a.这条命令展开
/bin/bash /rk/rk3188/kernel/scripts/gen_initramfs_list.sh -l -d > usr/.initramfs_data.cpio.d
作用: (没有什么实际的作用)
在文件usr/.initramfs_data.cpio.d中写入
deps_initramfs := /rk/rk3188/kernel/scripts/gen_initramfs_list.sh \
b. 就是执行cmd_initfs
/bin/bash /rk/rk3188/kernel/scripts/gen_initramfs_list.sh -o usr/initramfs_data.cpio -d
作用:
调用脚本 gen_initramfs_list.sh -o是生成的文件 -d是打印目录
1.2分析脚本gen_initramfs_list.sh
Makefile中的调用:
/bin/bash /rk/rk3188/kernel/scripts/gen_initramfs_list.sh -o usr/initramfs_data.cpio -d

!/bin/sh

set -e
default_initramfs() { //将默认的目录文件列表写入到临时的cpiolist中
cat <<-EOF >> ${output}
# This is a very simple, default initramfs

    dir /dev 0755 0 0
    nod /dev/console 0600 0 0 c 5 1
    dir /root 0700 0 0
    # file /kinit usr/kinit/kinit 0755 0 0
    # slink /init kinit 0755 0 0
EOF

}
arg=” 1case arg” in
“-o”) # generate compressed cpio image named 1shiftoutputfile= 1” //output_file= usr/initramfs_data.cpio
cpio_list=” (mktemp {TMPDIR:-/tmp}/cpiolist.XXXXXX)” //生成临时的cpiolist文件名
output= cpiolistecho output_file" | grep -q "\.cpio” && compr=”cat”  //如果output_file中有cpio字样  
        shift                                                   //compr=cat  
        ;;  
esac  
while [
# -gt 0 ]; do
arg=” 1shiftcase arg” in
“-d”) //生成默认initramfs的目录文件列表
default_list=”$arg”
default_initramfs
;;
esac
done

if [ ! -z outputfile];thenif[z {cpio_file} ]; then
cpio_tfile=” (mktemp {TMPDIR:-/tmp}/cpiofile.XXXXXX)” //生成临时的cpio文件名
#usr/gen_init_cpio /tmp/cpiolist.hWjXZa > /tmp/cpiofile.c6tWD2
usr/gen_init_cpio cpiolist> {cpio_tfile} //按照cpiolist的内容生成cpio文件
fi
rm cpiolistif[ {is_cpio_compressed}” = “compressed” ]; then
cat cpiotfile> {output_file} //不执行
else
#将临时的cpio文件,写入到正式的cpio文件中(usr/initramfs_data.cpio)
(cat cpiotfile| {compr} - > outputfile)||(rmf {output_file} ; false)
fi
[ -z {cpio_file} ] && rm{cpio_tfile}
fi
exit 0
梳理一下执行流程:
a. 生成默认的cpiolist
b. 按照默认的cipiolist中的内容,生成/tmp/cpiofile.c6tWD
c. 将这个/tmp/cpiofile.c6tWD复制成usr/initramfs_data.cpio
1.3分析gen_init_cpio
gen_int_cpio的调用过程:
usr/gen_init_cpio /tmp/cpiolist.hWjXZa > /tmp/cpiofile.c6tWD2
其中/tmp/cpiolist.hWjXZa的内容如下:

This is a very simple, default initramfs

dir /dev 0755 0 0
nod /dev/console 0600 0 0 c 5 1
dir /root 0700 0 0

file /kinit usr/kinit/kinit 0755 0 0

在内核源码的usr目录下有个gen_init_cpio.c,编译后会生成gen_init_cpio
int main (int argc, char *argv[])
{
FILE *cpio_list;
char line[LINE_SIZE];
char *args, *type;
int ec = 0;
int line_nr = 0;
const char *filename;

default_mtime = time(NULL);
... //省略解析参数部分,因为调用时只有一个参数filename
filename = argv[optind];
FILE* cpio_list = fopen(filename, "r");   //打开cpiolist
//进行cpiolist的解析
while (fgets(line, LINE_SIZE, cpio_list)) {  //每次读取一行
    int type_idx;
    size_t slen = strlen(line);
    line_nr++;

    if ('#' == *line)                     //跳过注释行
        continue;
    //分别解析出类型与文件
    type = strtok(line, " \t");            //每行中" \t"以前的字符串代表类型
    args = strtok(NULL, "\n");             //剩下的是文件
    //调用与type相同项的函数指针,进行打包
    for (type_idx = 0; file_handler_table[type_idx].type; type_idx++) {
        if (! strcmp(line, file_handler_table[type_idx].type))
           file_handler_table[type_idx].handler(args);    //打包过程就不多说了,
            break;           
    }        
}
if (ec == 0)
    cpio_trailer();        //最后加上trailer

}
rk3188–1.mkimage.sh及cpio打包过程分析:
http://blog.chinaunix.net/uid-26009923-id-4068594.html
二.将initramfs_data.cpio的编译进内核
2.1 initramfs_data.cpio的链接过程
在usr/initramfs_data.S中
//将initramfs_data.cpio放在.init.ramfs这个section中
.section .init.ramfs,”a”
__irf_start:
.incbin __stringify(INITRAMFS_IMAGE) //incbin将整个文件都包括进来
__irf_end:
//在init.ramfs.ramfs这个section中定义了size变量代表cpio文件的长度
.section .init.ramfs.info,”a”
.globl VMLINUX_SYMBOL(__initramfs_size)
VMLINUX_SYMBOL(__initramfs_size):

ifdef CONFIG_64BIT

.quad __irf_end - __irf_start

else

.long __irf_end - __irf_start       //没有64位支持就是个long

endif

注:上面的INITRAMFS_IMAGE是在usr/Makefile中定义,INITRAMFS_IMAGE=usr/initramfs_data.cpio
AFLAGS_initramfs_data.o += -DINITRAMFS_IMAGE=”usr/initramfs_data.cpio$(suffix_y)”
2.2 在内核的链接脚本中
在arch/arm/kernel/vmlinux.lds中定义了section .init.ramfs 和.init.ramfs.info
. = ALIGN(4); __initramfs_start = .; (.init.ramfs) . = ALIGN(8); (.init.ramfs.info)
这样就把initramfs_data.cpio链接进kernel了,
__initramfs_start是initramfs_data.cpio在内存中的首地址, __initramfs_size是initramfs_data.cpio的长度

四.initramfs_data.cpio在内核中解压缩

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值