TMM官方镜像 改host 修改img镜像 | 您所在的位置:网站首页 › 修改img镜像文件内容命令 › TMM官方镜像 改host 修改img镜像 |
曾经遇到过这样的一个问题:有一位同事误操作把windows下编辑过的一个文件覆盖了ubuntu下android 源码下的同样的文件,造成某个apk在运行的时候出错。由于不同版本更新做了好多的改动,调查了许久查不出缘由,查看repo-git历史修改信息也没看出任何相关的改动。终于在万分无助之际相处了一个办法:把旧机器上的system.img 跟boot.img 抽出来,烧录到新的板子上,来缩小问题原因的范畴。终于一步一步地定位到原因,最终把问题解决。 这是一个真实得经历,抽离系统分区镜像解决问题。于是在日后的工作中加深研究:怎样使用这种方法来修改系统镜像。实际上,市面上一下平板方案商的客制化软件修改image的原理也是这样来的。掌握这种方法,在工作中有时候可以给予我们很大的帮助。 首先是把img从系统分区里面抽离出来:(以boot.img为例) dd if=/dev/block/mmcblk0p1 of=/data/boot.img 之所以是partition1 ,是因为在烧录flash镜像的时候把boot.img烧录到了partition1,mmcblk0p1 是分区的名字,这个名字是在android 的devices下定义的,详细情况可以具体了解。实际上我们会发现,dd 出来的boot.img 比系统编译出来的boot.img 大小要大。这是因为我们dd的时候把整个partition1 都dd出来了,不单单是boot.img本身。 接下来我们把抽离出来的boot.img 放到ubuntu下面去解压。使用split_bootimg.pl脚本: ./split_bootimg.pl boot.img
于是我们解压出来了三个文件: boot.img-dt.img boot.img-kernel boot.img-ramdisk.gz 1、 boot.img-dt.img 这是linux kernel 3.x以后加入的dts后多出来的文件,也是android4.x之后,在boot.img里面所具备的文件。在这里,这个文件是由split_bootimg.pl 脚本生成的。可以不用太在意。 2、 boot.img-kernel,kernel的镜像文件,不是我们关注的重点。 3、 boot.img-ramdisk.gz,这是我们需要修改的文件,ramdisk 。顾名思义,内存当作硬盘使用。实际上,android为了加快对一些只读文件的访问速度,于是加入了ramdisk。每次机器启动后,cpu就会把ramdisk.img的内容加载到内存当中,这也是问什么我们在android下修改init.rc 等文件是不能够生效的。重启之后又恢复原样。 在解压的过程中,我们会发现,把内核的command line打印出来的,下文会详细说到,command line在这里怎样使用。其中command line 是在mk文件里面定义的。或者是由uboot传参进来。 接下来我们要把ramdisk解压出来,使用命令: ./split_bootimg.pl boot.img
解压完毕后,我们可以使用ls命令查看,原理ramdisk里面的内容跟我们实际在android启动后,串口命令行ls命令看到的内容十分相像。事实上,android启动后,根目录下的内容很多都是由加载ramdisk得到的。说到这里,我们也会清楚,问什么称之为ramdisk了。 做到这一步,我们就可以安装我们所想的去修改里面的内容。如,我把init.rc 里面默认设置的 setprop service.adb.tcp.port 5555 改为 setpropservice.adb.tcp.port 6666. 修改完毕后,压缩ramdisk,使用命令: ./mkbootfs ./ramdisk | gzip >ramdisk-new.gz mkbootfs是android源码包编译的时候生成的制作工具,路径是:out/host/linux-x86/bin/ 压缩完ramdisk-new.gz后,我们就可以重新压缩boot.img ,实际上,我们压缩boot.img 的过程跟android源码编译时压缩boot.img 的过程无异。在这里,我们可以参考android源码是怎样做的。 看到build/core/tasks/factory_ramdisk.mk 里面: 87 $(INSTALLED_FACTORY_RAMDISK_TARGET) : $(MKBOOTIMG) $(TARGET_RAMDISK_KERNEL) $(INSTALLED_FACTORY_RAMDISK_FS) 88 $(call pretty,"Target factory ram disk img format: $@") 89 $(MKBOOTIMG) --kernel $(TARGET_RAMDISK_KERNEL) --ramdisk $(INSTALLED_FACTORY_RAMDISK_FS) \ 90 --base $(BOARD_KERNEL_BASE) $(BOARD_MKBOOTIMG_ARGS) $(RAMDISK_CMDLINE) --output $@语法上不解释。首先我们关注几个变量: 1、 BOARD_KERNEL_BASE 这是kernel镜像的基地址,机器启动后,cpu会到这个地方需找kernel的img文件,如果这个地址错了,那么机器也就启动不了了。于是我们查找是否有BOARD_KERNEL_BASE的定义,在device下的mk文件: BOARD_KERNEL_BASE := 0x10800000于是在 –base参数后面,我们跟着基地址0x10800000 ,具体平台有所差异。 2、 RAMDISK_CMDLINE 我们还是看到build/core/tasks/factory_ramdisk.mk文件里面,对RAMDISK_CMDLINE的引用: 82 ifneq (,$(BOARD_KERNEL_CMDLINE_FACTORY_BOOT)) 83 RAMDISK_CMDLINE := --cmdline "$(BOARD_KERNEL_CMDLINE_FACTORY_BOOT)" 84 else 85 RAMDISK_CMDLINE := 86 endif而BOARD_KERNEL_CMDLINE_FACTORY_BOOT 没有被定义,所以RAMDISK_CMDLINE为空,可以不用理会。 3、 BOARD_MKBOOTIMG_ARGS 此字符串也没被定义,所以不需要理会。 接下来我们使用mkbootimg来压缩,同样的,此工具也是android源码包编译的时候生成的压缩boot.img 的工具,路径是:out/host/linux-x86/bin/ 可以直接执行这个工具来查看其用法,./ mkbootimg ,会打印出用法: error: no output filename specified usage: mkbootimg --kernel --ramdisk [ --second ] [ --cmdline ] [ --board ] [ --base ] [ --pagesize ] -o|--output接下来,我们的思路就很清晰了,执行命令: ./mkbootimg --base 0x10800000 --kernelboot.img-kernel --ramdisk ramdisk-new.gz -o newboot.img 生成的newboot.img 就是我们修改过后生成的新的boot.img 。 把newboot.img 拷贝到u盘,插上u盘启动机器。串口命令行使用命令: dd if=/mnt/udisk/boot.img of=/dev/block/mmcblk0p1 然后系统更新完毕。重启,在串口命令行输入: getprop service.adb.tcp.port 就可以看到,默认端口被改为了 6666 。
|
CopyRight 2018-2019 实验室设备网 版权所有 |