转载:更换zImage中的initramfs

时间:2022-01-12 21:29:24

From: http://blog.csdn.net/linuxaxis/article/details/8769722

好吧,折腾了两三个星期,USB的问题没搞定,看来功夫还不到家,看了下efuse中有很多的位可以配置相关的参数,

也许智器在那里面做了很多的工作,使我一直都不能有所突破,这个问题暂时就放放吧,以后有时间再来研究研究。

其实话又说回来,国内的公司还是真垃圾,本身就是用开源的东西,不开源就算了,还搞这么多恶心的东西,真垃圾...

之前说的一起做这个事情的哥们也一直不见动静,看来只有自己来做了。这样的话,不得不修改策略,先用最少的

时间,最少的资源,最快的速度完成最主要的功能。干脆底层的驱动就用现成的kernel镜像了,把主要精力放在上层功能

的修改和定制上吧。如果要用原始的android源码,必须要能用x7的kernel启动android系统,这中间就有很多的问题需要

处理了,也就是清明三天+今天所有做的工作。

智器还是很恶心的,把andriod的ramdisk的原始目录静态编译到zImage中,这样就很难把这个initramfs剔除出来。

一开始想了很多的启动配置参数来修改启动的路径,能否绕过initramfs,从而从sd卡启动android系统,结果不行,主要

测试了如下的相关启动参数:

rdinit, 一开始发现这个参数感觉一阵惊喜,以为有所突破。将这个值设置为:rdinit=/init1,这样,如果在ramdisk中找不到

init1的话,就跳出ramdisk启动,走其他的路径,通过设置root=/dev/mmcblk1p2来修改root的路径,结果不行。同样,还有

其他的很多,如:rootfstype=ext4, rootdelay=5, noinitrd等等,结果都没有任何效果,于是就放弃了这条路。

于是就把更多的精力放在了如何把编译到zImage中的initramfs剔除出来,或者换成我从android源码里面编译出来的root.

结果,在苦思冥想了好几天,再加今天上班时候的灵感触发,和今天下班回家之后,老婆做的饭香熏陶下,终于成功了,小小

兴奋了一阵。流程如下:

1:从uImage中提取zImage

dd if=uImage of=zImage bs=64 skip=1

这步之后,就得到了没有uboot头得zImage镜像

2:从zImage中提取没有解压缩的头程序

先将zImage dump成十六进制的文本显示:

hexdump -C zImage > zImage.txt

在这个文本文件中,可以看到一个LZO的字符,这个是lzo压缩文件的头标识符。其实内核也就支持了那几种压缩格式,我也是

一个个的对出来的,没有什么好办法。

转载:更换zImage中的initramfs

只要从这个头开始,后面的数据就是linux Image用lzo压缩的数据。好提取从.lzo开始的部分

dd if=zImage of=Image.lzo bs=6212 skip=1

3: 得到Image

lzop -d Image.lzo -o Image

这个Image就是不包含解压的程序,原始的Linux编译的二进制结果

4:  找到image中的initramfs的起点和终点

这个可以看原始的linux编译出来的initramfs_data.cpio,把这个文件dump出来,可以看到cpio问题的头和结束的标识符。

转载:更换zImage中的initramfs

转载:更换zImage中的initramfs

kernel做出来的cpio文件头和尾标识,根据这两个特点,就能在image中直接找到哪个区间段是initramfs了。其实这是没有压缩的initramfs的特点,如果是压缩了的话,

就根据压缩格式所用问的标识符。智器之所以之前zImage用lzo格式的压缩,以及在这里的initramfs不用压缩,还有很多很多别的,一切的一切只是为了加快开机时间,

其实这块他们还是做了挺多工作的。

对于 这个文件提取,我用了下面两步,得到两个文件:

dd if=image bs=141392 of=new/head count=1
dd if=image of=new/end bs=472144 skip=1

head为initramfs之前的image镜像,end为initramfs之后的image镜像。

这里有点要补充的是:kernel的cpio文件的大小是512对齐的。

5:得到与原始zImage中initramfs等大小的ramdisk文件

根据第四点中相关的信息 得到原始zImage中的initramfs大小为:330752字节,

将android编译出来的root设置到Linux的INITRAMFS_SOURCE中,编译,将会生成一个initramfs_data.cpio文件,

我这里的到得这个文件大小为:292352字节,利用这个文件来制作一个与之前在zimage中的initramfs等大的initramfs:

dd if=/dev/zeor of=pad bs=512 count=75

cat initramfs_data.cpio > panda.ramdisk

cat pad >> panda.ramdisk

这样就得到了一个可以用的ramdisk了,

6:重新生成Image

cat head > new_image

cat panda.ramdisk >> new_image

cat end >> new_image

7: 制作u-Image

mkimage -A arm -O linux -T kernel -C none -a 0x80008000 -e 0x80008000 -n linux-2.6.13 -d new_image u_image

这样,就可以通过uboot将u_image拷贝到内存中,再通过bootm来启动。其实,new_image也可以直接启动了,只是uboot的

参数无法传递了。

地址的选择:这时用的地址已经不是平时做uImage的地址了,这个地址是一个绝对地址,不在需要做任何拷贝动作,CPU直接跳转

到这个地址直接执行内核代码,不需要搬移,不需要解压。这个地址可以在arch/arm/mach-oma2/Makefile.boot中找到。对于我们

从SD卡拷贝到内存中的地址选择可以是任意的。

之前遇到一个比较想当然的错误,以为把initramfs从image中去掉,就可以直接当成一个没有编译进initramfs那样直接可以启动

的镜像,结果却是在启动的时候没有任何反应,今天研究了下相关的代码才有所领悟:

initrafs_data.S

    1. .section <span style="color:#FF0000;">.init.ramfs</span>,"a"
    2. __irf_start:
    3. .incbin __stringify(INITRAMFS_IMAGE)
    4. __irf_end:
    5. .section .<span style="color:#FF0000;">init.ramfs.info</span>,"a"
    6. .globl VMLINUX_SYMBOL(__initramfs_size)
    7. VMLINUX_SYMBOL(__initramfs_size):
    8. vmlinux.lds
    9. <pre name="code" class="plain"><pre name="code" class="html">  __con_initcall_start = .; *(.con_initcall.init) __con_initcall_end = .;
    10. __security_initcall_start = .; *(.security_initcall.init) __security_initcall_end = .;
    11. . = ALIGN(4); <span style="color:#FF0000;">__initramfs_start</span> = .; *(.init.ramfs) . = ALIGN(8); *(.init.ramfs.info)
    12. __init_begin = _stext;
    13. *(.init.data) *(.meminit.data) *(.init.rodata) *(.meminit.rodata) . = ALIGN(32); __dtb_start = .; *(.dtb.init.rodata) __dtb_end = .;
    14. </pre><br>
    15. <pre></pre>
    16. initramfs.c<br>
    17. <br>
    18. static int __init populate_rootfs(void)<br>
    19. {<br>
    20. char *err = unpack_to_rootfs(<span style="color:#FF0000">__initramfs_start</span>, __initramfs_size);<br>
    21. if (err)<br>
    22. panic(err);    /* Failed to decompress INTERNAL initramfs */<br>
    23. if (initrd_start) {<br>
    24. #ifdef CONFIG_BLK_DEV_RAM<br>
    25. int fd;<br>
    26. printk(KERN_INFO "Trying to unpack rootfs image as initramfs...\n");<br>
    27. err = unpack_to_rootfs((char *)initrd_start,<br>
    28. initrd_end - initrd_start);<br>
    29. if (!err) {<br>
    30. free_initrd();<br>
    31. return 0;<br>
    32. } else {<br>
    33. clean_rootfs();<br>
    34. unpack_to_rootfs(__initramfs_start, __initramfs_size);<br>
    35. }<br>
    36. printk(KERN_INFO "rootfs image is not initramfs (%s)"<br>
    37. "; looks like an initrd\n", err);<br>
    38. fd = sys_open((const char __user __force *) "/initrd.image",<br>
    39. O_WRONLY|O_CREAT, 0700);<br>
    40. if (fd >= 0) {<br>
    41. sys_write(fd, (char *)initrd_start,<br>
    42. initrd_end - initrd_start);<br>
    43. sys_close(fd);<br>
    44. free_initrd();<br>
    45. }<br>
    46. #else<br>
    47. printk(KERN_INFO "Unpacking initramfs...\n");<br>
    48. err = unpack_to_rootfs((char *)initrd_start,<br>
    49. initrd_end - initrd_start);<br>
    50. if (err)<br>
    51. printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err);<br>
    52. free_initrd();<br>
    53. #endif<br>
    54. }<br>
    55. <br>
    56. <br>
    57. <pre></pre>
    58. <p></p>
    59. </pre>

转载:更换zImage中的initramfs的更多相关文章

  1. 转载:WinForm中播放声音的三种方法

    转载:WinForm中播放声音的三种方法 金刚 winForm 播放声音 本文是转载的文章.原文出处:http://blog.csdn.net/jijunwu/article/details/4753 ...

  2. 转载:C&num;中事件和委托的编译代码

    接上文转载:C#中事件的由来,这时候,我们注释掉编译错误的行,然后重新进行编译,再借助Reflactor来对 event的声明语句做一探究,看看为什么会发生这样的错误: public event Gr ...

  3. 转载:C&num;中事件的由来

    原文地址 http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-in-CSharp.aspx 感谢博主分享! 我们继续思考转 ...

  4. &lbrack;转载&rsqb;解析WINDOWS中的DLL文件---经典DLL解读

    [转载]解析WINDOWS中的DLL文件---经典DLL解读 在Windows世界中,有无数块活动的大陆,它们都有一个共同的名字——动态链接库.现在就走进这些神奇的活动大陆,找出它们隐藏已久的秘密吧! ...

  5. 【转载】 Sqlserver中通过Select Into语句快速单表备份

    在Sqlserver数据库中,备份数据的方式有很多种,可以使用整个数据库备份,也可使用导出包含数据和架构的脚本文件的方式来进行单表或多表数据的备份,其实还有一种Select Into的方式可以快速备份 ...

  6. 【转载】C&num;中自定义Sort的排序规则IComparable接口

    C#中的List集合在排序的时候,如果不使用Lambda表达式进行排序的话,一般调用Sort()方法进行排序,如果希望Sort()方法排序后的结果跟我们预想的效果一致或者按照我们自定义的规则排序,则需 ...

  7. 【转载】 Sqlserver中DateAdd&lpar;&rpar;函数

    在Sqlserver数据库中,DATEADD() 函数在日期中添加或减去指定的时间间隔.例如计算当前时间往后一天的时刻以及往前1天的时刻时间即可使用DateAdd()函数来操作,DateAdd()函数 ...

  8. 【转载】 C&num;中全角转半角以及半角转全角

    半角指的是一个字符占用一个标准字符的位置.全角指一个字符占用两个标准字符位置的状态.在C#中,我们可以通过程序的方法,将相应的半角字符串信息转换为全角类型,也可以实现全角转半角功能. 相应封装好的方法 ...

  9. 转载:java中Thread&period;sleep&lpar;&rpar;函数使用

    点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更新中~ 正式篇: Java多线程(一) 什么是线程 Java多线程(二)关于多线程的CPU密集型和IO密集型这件事 Java多线程(三)如何 ...

随机推荐

  1. HDU 3584 Cube --三维树状数组

    题意:给一个三维数组n*n*n,初始都为0,每次有两个操作: 1. 翻转(x1,y1,z1) -> (x2,y2,z2) 0. 查询A[x][y][z] (A为该数组) 解法:树状数组维护操作次 ...

  2. LED流水灯(二)

    记住看汇编的时候是红在上面 黑色在下面 startup.s 程序 ; MDK跑马灯实验; PRESERVE8               // 字节对齐关键词 ,汇编有8位对齐的要求,要添加 AREA ...

  3. for循环语句示例应用

    age = 22 #优化前 ''' for i in range(10): guess_num = int(input('input your guess num:')) if guess_num = ...

  4. Vsftpd -- 验证方式

    vsftpd程序提供的FTP服务可选认证方式,分别为匿名访问.本地用户和虚拟用户: 匿名访问:任何人无需验证口令即可登入FTP服务端. 本地用户:使用FTP服务器中的用户.密码信息. 虚拟用户:创建独 ...

  5. 19个心得 明明白白说Linux下的负载均衡

    [51CTO.com独家特稿]前言:作为一名Linux/unix系统工程师,这几年一直在涉及到对外项目,经手过许多小中型网站的架构,F5.LVS及Nginx接触的都比较多,我想一种比较通俗易懂的语气跟 ...

  6. JS的作用域浅谈

    作为前端小白,总是对JS的作用域有点迷糊,这里稍微研究了一下分享出来,希望和我一样的小白可以学的一点 首先是一个经典的例子: var a=0,b=0; for (var i = 0; i < 1 ...

  7. &lbrack;HAOI2018&rsqb;苹果树

    嘟嘟嘟 这种计数大题就留给南方的计数神仙们做吧-- 刚开始我一直想枚举点,考虑新加一个点在根节点的左右子树,以及左右子树大小怎么分配,但是这样太难计算新的点带来的贡献了. 后来lba又提示我枚举边,考 ...

  8. Linux命令(1)——xargs命令

    1.功能: xargs能够将stdin中以空格或换行符进行分隔的数据.形成以空格分隔的參数(arguments),传递给其它命令.由于以空格作为分隔符,所以有一些文件名称或者其它意义的名词内含有空格的 ...

  9. Windows开机出现提示&OpenCurlyDoubleQuote;nwsvc&period;exe”错误怎么办

    开机时出现错误提示: Microsoft Visual C++ Runtime Library Runtime Error! Program: C:\Windows\system32\nwsvc.ex ...

  10. 【bzoj4036】&lbrack;HAOI2015&rsqb;按位或 fmt&plus;期望

    Description 刚开始你有一个数字0,每一秒钟你会随机选择一个[0,2^n-1]的数字,与你手上的数字进行或(c++,c的|,pascal 的or)操作.选择数字i的概率是p[i].保证0&l ...