XX教你玩 MiniPC (四) Mk908 bootloader行为分析

news/2024/10/30 19:30:01/

经历了沉寂郁闷的一天,终于一定程度上搞清楚了flashboot的启动行为。以下就说下自己做过的一些尝试吧,希望大家能从中吸取经验教训,少走弯路。

说到要分析一个软件的行为,我们通常都会从两个方面去考虑,这有点类似于做测试,白盒测试和黑盒测试。

要进行白盒测试,对应的就需要反编译flashboot,从它的代码中看到启动的过程。从上一篇的总结中,可以知道:flashboot在启动时经过了两次代码拷贝过程,在拷贝完毕后,转到地址0,继续执行。第一次拷贝时,把代码从0x60000310的位置拷贝到了0地址,大小为0x530;第二次拷贝时,把代码从0x60000840的位置拷贝到0x60080000的位置,大小为(0x6009b65c - 0x60080000)。通过分析,第一次拷贝的代码中包含了中断向量表,以及最基本的MMU,栈指针(SP)的初始化等操作,然后转到后面的0x60080000位置的代码中运行。

我们的反汇编操作也就是围绕着这两部分代码来进行的。

第一步,取出代码部分。第一次拷贝的位置位于0x60000310 ~ 0x60000840之间,它的目的地址是0。这里声明一下,linux下的指令一些是需要root账户权限的,如果你执行不通过,请su 到root账户,或者使用 sudo来操作,这在以后的篇幅中不再说明了。

# dd if=FlashBoot.bin of=FBPart1.bin bs=1 count=`echo "ibase=16;840-310"|bc` skip=`echo "ibase=16;310"|bc`

这样就得到第一部分的文件,类似的,取出第二部分代码部分。

# dd if=FlashBoot.bin of=FBPart2.bin bs=1 count=`echo "ibase=16;9B65C-80000"|bc`  skip=`echo "ibase=16;840"|bc`

注意了,bc 计算器只认识大写的16进制字母。

第二步,反汇编。反汇编的指令还是使用上一篇提到的objdump,但是这里又有一些不同,因为代码存放和运行的地址不同。FBPart1.bin运行于0地址,FBPart2.bin运行于0x60080000,所以为了理解方便,在反汇编时,使用参数--adjust-vma使其base地址发生偏移,便于查看。

# arm-linux-gnueabi-objdump  -b binary -marmv5 --adjust-vma=0x0 -D FBPart1.bin > FBPart1.asm

# arm-linux-gnueabi-objdump  -b binary -marmv5 --adjust-vma=0x60080000 -D FBPart2.bin > FBPart2.asm

第三步,利用汇编文件,形成C语言文件。现在就得到了两个汇编文件,这时的工作就是利用arm汇编指令以及CPU的寄存器地址,实现C语言。这个工作是非常繁琐的,需要掌握arm机器码的编码方式,arm gcc的链接过程,CPU的memory Map等等,所以还是在有时间的时候去做吧。

因为白盒反汇编的过程很漫长,所以只能通过黑盒的方式来从外围验证flashboot的功能。

从外设的角度讲,flashboot将围绕着 DDR,NAND flash,IDB flash,USB OTG,UART这个几个方面来操作。

从功能的角度讲,flashboot判断reset按键的状态,进而进入loader状态,或者直接启动kernel。在loader状态,负责 处理USB OTG的指令,包括烧写和读取等等。它还应该负责启动kernel失败后的处理。

那么以下,就通过实际的测试来验证我们预想的功能。

第一步,准备工具和原料。linux下,最好自己编译,否则出现一些问题,自己都不清楚。

工具:rkflashtool  下载地址:http://sourceforge.jp/projects/sfnet_rkflashtool/

参考文章:http://forum.xda-developers.com/showthread.php?t=1286305

原料:update_mk908_202j2203_overseas.img  注意是202j的,否则里面的内核在启动时,会发生错误。

下载地址:http://pan.baidu.com/s/1nFKAB

第二步,解包和烧写。当然可以先在windows用量产工具把升级包一次全部写入,这样我们就可以用减法的方法来验证预想。

进入loader模式的方法: 在进行试验前,先把MK908的调试串口接入主机,如果是USB转串口的线,则一般会在/dev/下产生

ttyUSBx的设备节点,如果是普通的串口,则使用ttySx就可以了。然后启动minicom或者其他串口软件。minicom第一次使用时,可以使用sudo minicom -s 来进行设置,设置方法就不多说了。

方法1.断电,用曲别针插入指示灯对面的小孔,按住reset键,USBcable 插入OTG接口,注意不是power接口。

方法2. 如果已经进入android系统了,那么在minicom中就有shell环境了。在shell中输入:

# su切换到root

# reboot  重启,在重启前,按住reset键,重启后就进入loader模式了。

验证进入loader模式的方法:

1. 在minicom中会有显示

2. 使用 lsusb 命令,会发现多了一个无名的设备,ivendr:iproduct == 2207:310B

以下实验都在loader模式下进行。

实验一:删除kernel分区,再启动。关于分区地址我们可以从解包后的parameter文件中cmdline中获得。

CMDLINE:console=ttyFIQ0 androidboot.console=ttyFIQ0 init=/init initrd=0x62000000,0x00800000 mtdparts=rk29xxnand:0x00002000@0x00002000(misc),0x00006000@0x00004000(kernel),0x00008000@0x0000A000(boot),0x00010000@0x00012000(recovery),0x00020000@0x00022000(backup),0x00040000@0x00042000(cache),0x00400000@0x00082000(userdata),0x00002000@0x00482000(kpanic),0x00100000@0x00484000(system),-@0x00584000(user)

# rkflashtool e 0x4000 0x6000  擦除

# rkflashtool  b重启

现象:系统可以正常启动

结论:kernel分区错误不影响系统启动。flashboot在启动时,可以检测到kernel分区的错误,进而跳过kernel分区,启动boot分区。

实验二:增加kernel分区内容。从网上下载了做好了的kernel image。http://www.zhetenger.com/node/56 这篇文章中的“MK908直接启动ubuntu系统内核”。使用winhex工具,能看到这个内核是经过rkcrc附加了校验信息的内核镜像。

# rkflashtool w 0x4000 0x6000 < kernel.img

# rkflashtool  b重启

现象系统启动到android

结论:即使kernel分区被写入了正确的内核镜像,flashboot也不会理会kernel。这说明kernel分区在这里只是一个摆设,没有实际作用。

实验三:删除boot分区。

# rkflashtool e 0xa000 0x8000  擦除

# rkflashtool  b 重启

现象:系统无法启动,重启到recovery模式,recovery模式下,修复了boot分区

结论:boot分区的缺失会使android无法启动,但flashboot会在boot分区启动失败时进入recovery模式,利用recovery模式修复系统。

实验四:删除boot分区,删除recovery分区

# rkflashtool e 0xa000 0x8000  擦除

# rkflashtool e 0x12000 0x10000  擦除

# rkflashtool  b 重启

现象:android系统无法启动,recovery模式无法进入,使用backup分区进行修复

结论:当recovery分区也缺失时,flashboot会利用backup分区的内容,对boot分区,misc分区,recovery分区进行修复。

实验五:删除boot,recovery,backup分区

# rkflashtool e 0xa000 0x8000  擦除

# rkflashtool e 0x12000 0x10000  擦除

#rkflashtool e 0x22000 0x20000  擦除

# rkflashtool  b 重启

现象:系统无法启动,flashboot停留在loader模式

结论:当所有以上的分区都缺失后 flashboot无能为力了,停在了loader模式下

通过以上实验,可以知道实际启动的内核在boot分区下。

在linux kernel启动过程中,bootloader给kernel传递的参数非常重要,很多参数都存在于parameter文件中,所以需要测试一下parameter参数对kernel启动的影响。注意:parameter文件修改后,需要使用rkcrc 进行Magic和校验的添加,否则flashboot无法检索到parameter。

下面是更细节的测试。

实验六:修改parameter参数,分析对启动的影响

a. 修改MACHINE_ID 字段为 008

启动正常

b.修改MAGIC 字段为0x5041524C

启动正常

c.修改ATAG字段

启动正常

d.修改CHECK_MASK字段

启动正常

e.修改KERNEL_IMG字段

启动正常

f.修改MACHINE字段

启动失败

g.修改CMDLINE

在启动的log中,能够发现内核的cmdline也发生改变

通过以上的实验,可以知道,parameter文件中的一些参数在启动android时是不起作用的,可能是在直接启动kernel时(目前的这个flashboot不支持)使用的。真正启动时使用的是MACHINE字段和CMDLINE字段。

MACHINE字段为bootloader启动kernel时传递的第二个参数,必须与内核中的machine id相同,否则无法启动内核。这一点可以参考uboot对linux 内核的启动。kernel端的machine id存放于 arch/arm/tools/mach-types文件中。

CMDLINE字段将以param中atag的形式传递给内核,即上图的第三个参数。实际上,这个参数是个内存地址,对应于parameter文件中的ATAG字段。内核在启动时,从该地址取得bootloader传递过来的参数,其中就包括了cmdline。这部分代码位于arch/arm/kernel/setup.c 中的setup_arch 函数。

通过以上的实验,我们大致验证了开始时的预想。

新增的结论:

使用当前的flashboot无法实现从kernel分区的直接启动

当前的flashboot优先启动boot分区,并在boot分区失效情况下,通过其他方式实现修复

当前flashboot 条件下,只有parameter文件中的MACHINE和CMDLINE字段影响内核启动

最终的结论:

当前flashboot 条件下,要想实现启动定制的内核,只能依赖于修改boot分区。为了改变内核启动时的某些特性,可以通过修改过parameter文件中的CMDLINE来实现。

明白了以上的结论,下一步我们就可以通过修改boot分区内容来实现我们定制系统的启动。


下一篇将仔细说一下rockchip公司的bootimg吧。


http://www.ppmy.cn/news/242775.html

相关文章

XX教你玩 MiniPC (二)MK908升级包分析

前一篇已经讲完了怎么debug MK908的硬件&#xff0c;关键点是引出了调试用串口&#xff0c;这在后续的分析过程中起到很大作用。 这一篇&#xff0c;将脱离MK908的硬件&#xff0c;从MK908的升级包的角度来看出厂时&#xff0c;MK908的启动和工作方式。 先发布一下&#xff0…

【车机协同slam】miniPC、Nano、T265、UWB linktrack P-B

目录 0、前言0.1 软硬件0.2 实现步骤 一、装系统、换源、装ROS1.1 装系统、换源2.1 装ROS 二、T2652.1 ubuntu 安装 T265 SDK&#xff08;已测18、20、Nano&#xff09;&#xff1a;2.2 ubuntu 安装 T265 ROS包&#xff08;已测18、20、nano&#xff09;&#xff1a; 三、UWB &…

Android 实现单击鼠标右键返回功能

实现单击鼠标右键返回功能modified: frameworks/native/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.cppdiff --git a/frameworks/native/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.cpp b/frameworks/native/…

python 第三章 基础语句

系列文章目录 第一章 初识python 第二章 变量 文章目录 3.1 输出格式化输出格式化符号格式化字符串扩展f-格式化字符串转义字符结束符 3.2 输入3.3 数据类型转换转换数据类型的函数 3.4 PyCharm交互式开发3.5 运算符运算符的分类算数运算符赋值运算符复合赋值运算符比较运算符逻…

STL(结)

STL&#xff08;结&#xff09; map存储结构基本操作equal_range遍历方式 插入 multimapsetunordered_mapmap和无序map的异同mapunordered_map map 存储结构 map容器的底层存储是一个红黑树&#xff0c;遍历方式都是按照中序遍历的方式进行的。 int main() {std::map<int…

使用Graalvm+Swing搓了个原生桌面应用的轮子:文件差异对比工具,附轮子源码

文章目录 1、DFDiff介绍2、软件架构3、安装教程3.1、编译为jar包运行3.2、编译为原生应用运行 4、运行效果图5、项目源码地址 1、DFDiff介绍 当前已实现的功能比较两个文件夹内的文件差异&#xff0c;已支持文件差异对比。 2、软件架构 软件架构说明 开发环境是在OpenJDK17&…

华为5g鸿蒙麒麟,华为5G手机渲染图曝光,鸿蒙+麒麟985+5G基带,参考价格很良心...

众所周知&#xff0c;曾经偌大的中国手机市场一直以来都呈现着苹果三星两家独大的局面&#xff0c;即便在当时像波导和金立等老牌手机厂商&#xff0c;在市场上也有着一定的地位&#xff0c;但就产品竞争性而言&#xff0c;却往往没有那些海外品牌更具有说服力。时至今日随着国…

鸿蒙os 芯片制程,鸿蒙OS首秀+5nm工艺芯片华为Mate40,华为Mate30处境悲惨价格骤降...

原标题&#xff1a;鸿蒙OS首秀5nm工艺芯片华为Mate40&#xff0c;华为Mate30处境悲惨价格骤降 鸿蒙OS首秀5nm工艺芯片华为Mate40&#xff0c;华为Mate30处境悲惨价格骤降 华为Mate40可谓是亮点多多&#xff0c;其将首发台积电5nm工艺打造的麒麟1020处理器&#xff0c;相比前代麒…