zoukankan      html  css  js  c++  java
  • 转载:更换zImage中的initramfs

    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压缩文件的头标识符。其实内核也就支持了那几种压缩格式,我也是

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

    只要从这个头开始,后面的数据就是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问题的头和结束的标识符。

    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

    [plain] view plaincopy
     
      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.   
      9.   
      10.  vmlinux.lds  
      11.   
      12. <pre name="code" class="plain"><pre name="code" class="html">  __con_initcall_start = .; *(.con_initcall.init) __con_initcall_end = .;  
      13.   __security_initcall_start = .; *(.security_initcall.init) __security_initcall_end = .;  
      14.   . = ALIGN(4); <span style="color:#FF0000;">__initramfs_start</span> = .; *(.init.ramfs) . = ALIGN(8); *(.init.ramfs.info)  
      15.   __init_begin = _stext;  
      16.   *(.init.data) *(.meminit.data) *(.init.rodata) *(.meminit.rodata) . = ALIGN(32); __dtb_start = .; *(.dtb.init.rodata) __dtb_end = .;  
      17. </pre><br>  
      18. <pre></pre>  
      19. initramfs.c<br>  
      20. <br>  
      21. static int __init populate_rootfs(void)<br>  
      22. {<br>  
      23.     char *err = unpack_to_rootfs(<span style="color:#FF0000">__initramfs_start</span>, __initramfs_size);<br>  
      24.     if (err)<br>  
      25.         panic(err);    /* Failed to decompress INTERNAL initramfs */<br>  
      26.     if (initrd_start) {<br>  
      27. #ifdef CONFIG_BLK_DEV_RAM<br>  
      28.         int fd;<br>  
      29.         printk(KERN_INFO "Trying to unpack rootfs image as initramfs... ");<br>  
      30.         err = unpack_to_rootfs((char *)initrd_start,<br>  
      31.             initrd_end - initrd_start);<br>  
      32.         if (!err) {<br>  
      33.             free_initrd();<br>  
      34.             return 0;<br>  
      35.         } else {<br>  
      36.             clean_rootfs();<br>  
      37.             unpack_to_rootfs(__initramfs_start, __initramfs_size);<br>  
      38.         }<br>  
      39.         printk(KERN_INFO "rootfs image is not initramfs (%s)"<br>  
      40.                 "; looks like an initrd ", err);<br>  
      41.         fd = sys_open((const char __user __force *) "/initrd.image",<br>  
      42.                   O_WRONLY|O_CREAT, 0700);<br>  
      43.         if (fd >= 0) {<br>  
      44.             sys_write(fd, (char *)initrd_start,<br>  
      45.                     initrd_end - initrd_start);<br>  
      46.             sys_close(fd);<br>  
      47.             free_initrd();<br>  
      48.         }<br>  
      49. #else<br>  
      50.         printk(KERN_INFO "Unpacking initramfs... ");<br>  
      51.         err = unpack_to_rootfs((char *)initrd_start,<br>  
      52.             initrd_end - initrd_start);<br>  
      53.         if (err)<br>  
      54.             printk(KERN_EMERG "Initramfs unpacking failed: %s ", err);<br>  
      55.         free_initrd();<br>  
      56. #endif<br>  
      57.     }<br>  
      58. <br>  
      59. <br>  
      60.    
      61. <pre></pre>  
      62. <p></p>  
      63.   
      64. </pre>  
  • 相关阅读:
    Hash表的查找-C语言
    二叉排序树-C语言
    线性表的查找算法-C语言
    拓扑排序和关键路径
    图结构的创建与遍历-C语言
    MySQL数据库基本脚本命令
    哈夫曼树编码-C语言
    协程简述
    Python多线程编程-Threading库
    Python多进程编程-multiprocessing库
  • 原文地址:https://www.cnblogs.com/super119/p/3230652.html
Copyright © 2011-2022 走看看