Post

从设备中获取内核固件的一些方法

在安卓中,公开内核源码是必备的事情,但是有的公司却只更新一次,做不到像谷歌一样,每天更新! 导致kernel和上层建筑物不匹配。当然,OEM厂商是有权力不开源。感谢Nanda Oktavera的固件拆分笔记。本文由我重新编写!!

​ 如果你编译内核刷入手机后bootloop,卡米或者刷内核后进fastboot,相机错误,没声音,触摸坏了等各种异常情况。当然,解开设备树也可用于屏幕超频。用此排除原因,除了git bisect操作,不妨看看是否是设备树文件太老了。更新内核设备树很可能是解决问题的办法!

问题例子: 调试时屏幕id与内核不符 设备三星屏幕不工作


device tree compiler使用简要

dtb反编译为dts Device tree compiler可以用来编译或反编译

由dts构建dtb: dtc -I dts -O dtb -o <devicetree name>.dtb <devicetree name>.dts

由dtb构建dts: dtc -I dtb -O dts -o <devicetree name>.dts <devicetree name>.dtb

这样我们就可以得到设备的设备树文件啦!

其实在调用dtc --help可观看教程


实战提取设备树文件:

设备树是描述硬件的数据结构,通过编写dts文件,不同CPU架构的设备都可以跑Linux kernel

1.克隆libufdt工具,用于解开dtbo镜像

git clone https://android.googlesource.com/platform/system/libufdt

2.安装python2

sudo apt install Python2

我就看看不进去 ls ~/libuft/utils/src 我不仅要看看,还要进去 cd ~/libuft/utils/src

3.拆镜像

1
python2 mkdtboimg.py dump dtbo.img -b device

然后生成了好多好多后缀名是数字的device文件,这些就是dtb文件。

通过device tree compiler转换文件内容是数制的设备文件,使人可读。

4.转换格式

1
dtc -I dtb -O dts -o device.dts device.0

gah0@儿童电脑 ~/mkdtimg/utils/src >$ ls dtsi/ device.0 device.1 …..device.51 device.dts

这里出现后缀名为数字的文件,和你内核存放设备树目录下的Makefile文件里的写入需要编译的设备树文件,数量是一样的。

有一些OEM为了保护该产品的集成产品(例如指纹)安全,他们有权力不进行开源,把一些调用指纹寄存器指令的方法写入已固化数制文件中。可以尝试使用开源软件csplitb分解数制固件。


使用csplitb进行内核固件提取

例子:设备指纹硬件寄存器读取错误

1.准备

解压缩的内核二进制文件(用于unpackbootimg获取Image.gz和提取Image文件Image.gz) 引用的旧固件二进制文件(您可以在内核的输出目录中获取它或转换ihex文件) csplitb用于读取二进制

2.查找

xxd 用于查找二进制文件值。

xxd <Original-Firmware> | head -n1

$: xxd goodix_gt9886_fw_f2.bin | head -n $: 0001 58fa acc0 4e4f 525f 4731 0000 0a39 ..X…NOR_G1….9

3.获取正确的固件内容

要获得实际固件的正确内容,我们需要找出原始固件的确切大小。

stat -c %s <Original-Firmware>

$: stat -c %s goodix_gt9886_fw_f2.bin $: 88320

请记住这个“0001 58fa”,他是文件开头初始量,还有文件大小88320

4.查找魔法数字

xxd <Kernel-Image> | grep '0001 58fa'

$: xxd Image | grep ‘0001 58fa $: 01341250: 3900 0000 0000 0000 0001 58fa a7f9 9……X…NO…

5.拆分

从内核拆分固件,因为我们发现内核映像实际上包含了我们需要的固件

csplitb --prefix dumped-fw- --suffix .bin --number 4 000158fa <Kernel-Image>

$: csplitb –prefix dumped-fw- –suffix .bin –number 4 000158fa Image 结果将保存名字dumped-fw-0000.bin

6.转储

然后让它用dd转储它。

$ dd if=dumped-fw-0000.bin of=<New-Firmware-Name.bin> bs=<Size-Of-Original-Firmware> count=1

$: dd if =dumped-fw-0000.bin of=new_goodix_gt9886_fw_f2.bin bs88320 count=1 $: 88320 bytes(88kB,86KiB)copied, 00000003514s ,250mb/s

将新固件“new_goodix_gt9886_fw_f2.bin”转换为Intel Hex文件,将它封装在内核中 我们可以使用avr-objcopy。avr-objcopy 用于二进制blob到ihex的转换。

avr-objcopy -I binary -O ihex <New-Firmware.bin> <New-Firmware.ihex>

$: avr-objcopy -I binary -O ihex new_goodix_gt9886_fw_f2.bin new_goodix_gt9886_fw_f2.ihex

This post is licensed under CC BY 4.0 by the author.