跳到主要内容

[TOC]

调试手段

本章节主要介绍一些U-Boot阶段常用的调试手段,包括使用命令、脚本、配置选项、开机打印等等。

DEBUG

功能:让全局debug()打印生效。

可在各平台的 rkxxx_common.h 中增加宏定义进行使能:

#define DEBUG

Initcall

功能:打印启动流程。

U-Boot 的启动实质是一系列initcall调用,把initcall_run_list()函数内的 debug() 改成 printf()。例:

U-Boot 2017.09-01725-g03b8d3b-dirty (Jul 06 2018 - 10:08:27 +0800)

initcall: 0000000000214388
initcall: 0000000000214724
Model: Rockchip RK3399 Evaluation Board
initcall: 0000000000214300
DRAM: initcall: 0000000000203f68
initcall: 0000000000214410 // 结合反汇编找出地址对应的函数
initcall: 00000000002140dc
....
3.8 GiB
initcall: 00000000002143b8
....
Relocation Offset is: f5c03000
initcall: 00000000f5e176bc
initcall: 00000000002146a4 (relocated to 00000000f5e176a4)
initcall: 0000000000214668 (relocated to 00000000f5e17668)

...

io命令

功能:读写内存。

// 读操作
md - memory display
Usage: md [.b, .w, .l, .q] address [# of objects]

// 写操作
mw - memory write (fill)
Usage: mw [.b, .w, .l, .q] address value [count]

读操作。范例:显示 0x76000000 地址开始的连续 0x10 个数据。

=> md.l 0x76000000 0x10
76000000: fffffffe ffffffff ffffffff ffffffff ................
76000010: ffffffdf ffffffff feffffff ffffffff ................
76000020: ffffffff ffffffff ffffffff ffffffff ................
76000030: ffffffff ffffffff ffffffff ffffffff ................

写操作。范例:对 0x76000000 地址赋值为 0x1234;

=> mw.l 0x76000000 0xffff1234 // 高16位有mask
=> md.l 0x76000000 0x10 // 回读
76000000: ffff1234 ffffffff ffffffff ffffffff ................
76000010: ffffffdf ffffffff feffffff ffffffff ................
76000020: ffffffff ffffffff ffffffff ffffffff ................
76000030: ffffffff ffffffff ffffffff ffffffff ................

iomem命令

功能:读内存。比md命令更灵活,通过自动解析DTS节点获取基地址信息。

=> iomem
iomem - Show iomem data by device compatible

Usage:
// @<compatible>:节点的compatible部分关键词匹配
iomem <compatible> <start offset> <end offset>
eg: iomem -grf 0x0 0x200

范例:RK3228 读取 GRF 里 0x00 ~ 0x20 的数据:

// 这里为了和"rockchip, rk3288-pmugrf" 区分开,所以用"-grf"作为关键词
=> iomem -grf 0x0 0x20
rockchip,rk3228-grf:
11000000: 00000000 00000000 00004000 00002000
11000010: 00000000 00005028 0000a5a5 0000aaaa
11000020: 00009955

i2c命令

功能:i2c设备读写。

=> i2c
i2c - I2C sub-system

Usage:
i2c dev [dev] - show or set current I2C bus
i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device
i2c mw chip address[.0, .1, .2] value [count] ‐ write to I2C device (fill)
......

读操作。范例:

=> i2c dev 0                     // 切到i2c0(指定一次即可)
Setting bus to 0

=> i2c md 0x1b 0x2e 0x20 // i2c设备地址为1b(7位地址),读取0x2e开始的连续0x20个寄存器值
002e: 11 0f 00 00 11 0f 00 00 01 00 00 00 09 00 00 0c ................
003e: 00 0a 0a 0c 0c 0c 00 07 07 0a 00 0c 0c 00 00 00 ................

写操作。范例:

=> i2c dev 0                     // 切到i2c0(指定一次即可)
Setting bus to 0

=> i2c mw 0x1b 0x2e 0x10 // i2c设备地址为1b(7位地址),对0x2e寄存器赋值为0x10
=> i2c md 0x1b 0x2e 0x20 // 回读
002e: 10 0f 00 00 11 0f 00 00 01 00 00 00 09 00 00 0c ................
003e: 00 0a 0a 0c 0c 0c 00 07 07 0a 00 0c 0c 00 00 00 ................

gpio命令

功能:pin脚输入输出读写

=> gpio
gpio - query and control gpio pins

Usage:
gpio <input|set|clear|toggle> <pin>
- input/set/clear/toggle the specified pin
gpio status [-a] [<bank> | <pin>] - show [all/claimed] GPIOs

查看pin脚状态:如RV1126

=> gpio status -a
Bank A:
A0: input: 0 [ ]
A1: output: 1 [ ]
A2: input: 1 [ ]
...
A29: unused: 1 [ ]
A30: unknown
A31: unused: 0 [ ]
...
D6: input: 0 [ ]
D7: output: 1 [x] vcc18-lcd-n.gpio
...
D31: input: 0 [ ]

Bank E:
E0: input: 0 [ ]
E1: input: 0 [ ]

pin输入:

=> gpio input A7

pin输出INACTIVE:

=> gpio clear A7

pin输出ACTIVE:

=> gpio set A7

pin状态切换:如A7: input: 0 改为 A7: output: 1

=> gpio toggle A7

fdt命令

功能:打印DTB内容。

=> fdt
fdt - flattened device tree utility commands

Usage:
fdt addr [-c] <addr> [<length>] - Set the [control] fdt location to <addr>
fdt print <path> [<prop>] - Recursive print starting at <path>
fdt list <path> [<prop>] - Print one level starting at <path>
......
NOTE: Dereference aliases by omitting the leading '/', e.g. fdt print ethernet0.

其中如下两条组合命令一起使用,可以把 device-tree 完整 dump 出来:

=> fdt addr $fdt_addr_r   // 指定fdt地址
=> fdt print // 把fdt内容全部打印出来

mmc命令

功能:MMC 设备读写、切换。

MMC 设备查看:

=> mmc info
Device: dwmmc@ff0f0000 // 设备节点
Manufacturer ID: 15
OEM: 100
Name: 8GME4
Timing Interface: High Speed // 速度模式
Tran Speed: 52000000 // 当前速度
Rd Block Len: 512
MMC version 5.1
High Capacity: Yes
Capacity: 7.3 GiB // 存储容量
Bus Width: 8-bit // 总线宽度
Erase Group Size: 512 KiB
HC WP Group Size: 8 MiB
User Capacity: 7.3 GiB WRREL
Boot Capacity: 4 MiB ENH
RPMB Capacity: 512 KiB ENH

MMC 设备切换:

=> mmc dev 0                            // 切换到eMMC
=> mmc dev 1 // 切换到sd卡

MMC 设备读写:

mmc read addr blk# cnt
mmc write addr blk# cnt
mmc erase blk# cnt
例:
=> mmc read 0x70000000 0 1 // 读取MMC设备第一个block,大小为1 sector的数据到内存0x70000000
=> mmc write 0x70000000 0 1 // 把内存0x70000000起1 sector的数据写到存储第一个block起位置
=> mmc erase 0 1 // 擦除存储第一个block起1 sector数据

如果 MMC 设备读写异常,可以通过以下简单步骤快速定位:

把 drivers/mmc/dw_mmc.c 内的 debug() 改为 printf() 后重新编译烧写。查看 MMC 设备的打印信息:

  • 如果最后的打印为 Sending CMD0,请检查硬件供电、管脚连接;检查软件 IOMUX 是否被其他 IP 切走;
  • 如果最后打印为 Sending CMD8,安全软件部分请配置 MMC 设备允许访问安全存储;
  • 如果初始化命令都已通过,最后打印为 Sending CMD18,请检查 MMC 硬件供电、靠近 MMC 供电端的电容是否足够(可以更换大电容)、软件可以降低时钟频率、切换 MMC 设备的速度模式。

时间戳

功能:给U-Boot 打印信息增加时间戳(相对时间)。

CONFIG_BOOTSTAGE_PRINTF_TIMESTAMP

范例:

[    0.259266] U-Boot 2017.09-01739-g856f373-dirty (Jul 10 2018 - 20:26:05 +0800)
[ 0.260596] Model: Rockchip RK3399 Evaluation Board
[ 0.261332] DRAM: 3.8 GiB
Relocation Offset is: f5bfd000
Using default environment

[ 0.354038] dwmmc@fe320000: 1, sdhci@fe330000: 0
[ 0.521125] Card did not respond to voltage select!
[ 0.521188] mmc_init: -95, time 9
[ 0.671451] switch to partitions #0, OK
[ 0.671500] mmc0(part 0) is current device
[ 0.675507] boot mode: None
[ 0.683738] DTB: rk-kernel.dtb
[ 0.706940] Using kernel dtb
......

时间戳仅是把当前系统timer的时间打印出来,而不是从0开始计时。所以时间戳打印的仅仅是相对时间,而不是绝对时间。

dm tree

功能:查看所有 device-driver 之间的绑定、probe状态。

=> dm tree

Class Probed Driver Name
----------------------------------------------------------
root [ + ] root_driver root_driver
syscon [ ] rk322x_syscon |-- syscon@11000000
serial [ + ] ns16550_serial |-- serial@11030000 *
clk [ + ] clk_rk322x |-- clock-controller@110e0000
sysreset [ ] rockchip_sysreset | |-- sysreset
reset [ ] rockchip_reset | `-- reset
mmc [ + ] rockchip_rk3288_dw_mshc |-- dwmmc@30020000 *
blk [ + ] mmc_blk | `-- dwmmc@30020000.blk *
ram [ ] rockchip_rk322x_dmc |-- dmc@11200000
serial [ + ] ns16550_serial |-- serial@11020000
i2c [ + ] i2c_rockchip |-- i2c@11050000
......

打印含义:

  • 列出所有已经完成 bind的 device-driver
  • 列出所有 uclass-device-driver 之间的隶属关系
  • [ + ] 表示当前 driver 已经完成 probe
  • * 表示当前device-driver来自于U-Boot的DTB,否则来在kernel DTB

dm uclass

功能:查看某类uclass下的所有设备。

=> dm uclass

uclass 0: root
- * root_driver @ 7be54c88, seq 0, (req -1)

uclass 11: adc
- * saradc@ff100000 @ 7be56220, seq 0, (req -1)
......
uclass 40: backlight
- * backlight @ 7be81178, seq 0, (req -1)

uclass 77: key
- rockchip-key @ 7be811f0
......

stacktrace.sh

利用调用栈回溯机制分析abort、dump_stack()的现场。请参考RK架构章节。

系统卡死

功能:打印当前CPU的现场和调用栈,适用于系统卡死时使用。串口会每隔 5s dump 出和abort时类似的信息。

CONFIG_ROCKCHIP_DEBUGGER

获取到调用栈信息后再使用stacktrace脚本转换。请参考RK架构章节。

CRC 校验

功能:校验RK格式的固件完整性。

RK 格式的镜像头包含了整个镜像的CRC32,打开如下宏可以用CRC32验证固件的完整性。

CONFIG_ROCKCHIP_CRC

范例:

=Booting Rockchip format image=
kernel image CRC32 verify... okay. // kernel 校验成功(如果失败则打印“fail!”)
boot image CRC32 verify... okay. // boot 校验成功(如果失败则打印“fail!”)
kernel @ 0x02080000 (0x01249808)
ramdisk @ 0x0a200000 (0x001e6650)
# Flattened Device Tree blob at 01f00000
Booting using the fdt blob at 0x1f00000
'reserved-memory' secure-memory@20000000: addr=20000000 size=10000000
Loading Ramdisk to 08019000, end 081ff650 ... OK
Loading Device Tree to 0000000008003000, end 0000000008018c97 ... OK
Adding bank: start=0x00200000, size=0x08200000
Adding bank: start=0x0a200000, size=0xede00000

Starting kernel ...

HASH校验

功能:校验Android格式的固件完整性。

ANDROID_BOOT_IMAGE_HASH

启用该配置后,加载Android格式的固件时会校验固件的完整性。

因为一些历史原因,如果上述配置无法正确校验固件,请同时打开如下配置试试:

HASH_ROCKCHIP_LEGACY

修改DDR容量

开机时DDR初始化代码会把DDR容量传递给U-Boot,U-Boot会去除一些安全内存后再传递给内核。用户可以在U-Boot阶段修改传递给内核的DDR容量。

传递范例:

......
// 传递给内核的可用内存块(已去除安全内存块)。
Adding bank: 0x00200000 - 0x08400000 (size: 0x08200000)
Adding bank: 0x0a200000 - 0x40000000 (size: 0x35e00000)
Total: 895.411 ms

Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0

代码位置:

./arch/arm/mach-rockchip/param.c

修改位置:

struct memblock *param_parse_ddr_mem(int *out_count)
{
......

// 这里就是ddr传递给U-Boot的容量信息。
// 因为可能出现不连续的地址,所以会分块传递,分别指明各个内存块的起始地址和大小。
// PS: 一般情况下都是连续内存,不会需要分块。
for (i = 0, n = 0; i < count; i++, n++) {
// 比如2GB容量(连续地址),则:count=1, base = 0,size = 0x80000000。
// 用户调试时可以在这里按需修改。
base = t->u.ddr_mem.bank[i];
size = t->u.ddr_mem.bank[i + count];

/* 0~4GB */
if (base < SZ_4GB) {
mem[n].base = base;
mem[n].size = ddr_mem_get_usable_size(base, size);
if (base + size > SZ_4GB) {
n++;
mem[n].base_u64 = SZ_4GB;
mem[n].size_u64 = base + size - SZ_4GB;
}
} else {
/* 4GB+ */
mem[n].base_u64 = base;
mem[n].size_u64 = size;
}

assert(n < count + MEM_RESV_COUNT);
}
......
}

跳转信息

功能:确认固件版本和流程。某些情况下,开机信息也可以帮助用户定位一些死机问题。

  1. trust 跑完后就卡死

trust 跑完后就卡死的可能性:固件打包或者烧写有问题,导致 trust 跳转到错误的 U-Boot 启动地址。此时用户可以通过 trust 开机打印的 U-Boot 启动地址来确认。

64 位平台 U-Boot 启动地址一般是偏移 0x200000(DRAM 起始地址是 0x0):

NOTICE:  BL31: v1.3(debug):d98d16e
NOTICE: BL31: Built : 15:03:07, May 10 2018
NOTICE: BL31: Rockchip release version: v1.1
INFO: GICv3 with legacy support detected. ARM GICV3 driver initialized in EL3
INFO: Using opteed sec cpu_context!
INFO: boot cpu mask: 0
INFO: plat_rockchip_pmu_init(1151): pd status 3e
INFO: BL31: Initializing runtime services
INFO: BL31: Initializing BL32
INFO: BL31: Preparing for EL3 exit to normal world
INFO: Entry point address = 0x200000 // U-Boot地址
INFO: SPSR = 0x3c9

32 位平台 U-Boot 启动地址一般是偏移 0x0(DRAM 起始地址是 0x60000000):

INF [0x0] TEE-CORE:init_primary_helper:378: Release version: 1.9
INF [0x0] TEE-CORE:init_primary_helper:379: Next entry point address: 0x60000000 // U-Boot地址
INF [0x0] TEE-CORE:init_teecore:83: teecore inits done
  1. U-Boot 版本回溯:

通过 U-Boot 开机信息可回溯编译版本。如下对应提交点是 commit: b34f08b。

U-Boot 2017.09-01730-gb34f08b (Jul 06 2018 - 17:47:52 +0800)

开机信息中出现"dirty",说明编译时有本地改动没有提交进仓库,编译点不干净。

U-Boot 2017.09-01730-gb34f08b-dirty (Jul 06 2018 - 17:35:04 +0800)

启动信息

用户通过U-Boot开机信息可获知当前U-Boot的流程和各外设的状态,方便快速定位异常。

目前U-Boot支持三种固件类型引导:Android格式 > RK格式 > DISTRO格式。RK发布的SDK主要是前两种固件格式,DISTRO一般是开源用户会使用。

说明:如果用户的代码不够新,有些打印可能看不到,这不影响用户对于U-Boot开机信息的整体了解。

17.1 Android固件

// U-Boot第一行打印,包含了commit版本、编译时间等信息
// 注意: 这里只是U-Boot"相对早"的第一行正规打印,而不是U-Boot能做出的最早打印
// 打开debug信息,可以看到更早的调试打印
U-Boot 2017.09-03033-g81b79f7-dirty (Jul 04 2019 - 15:04:00 +0800)

// U-Boot dts的“model"字段内容,通过这个信息可以知道我们使用了U-Boot哪份dts
Model: Rockchip RK3399 Evaluation Board
// 启用了preloader-serial功能,即沿用前级loader的串口配置,当前使用UART2作为打印口
PreSerial: 2
// 板子的总内存容量是2GB
DRAM: 2 GiB
// 当前版本支持了sysmem内存卡管理机制
Sysmem: init
// U-Boot会把自己的代码进行自搬移,从当前ddr靠前的位置搬到靠后的位置(详见U-Boot开发文档启动流程)
// 自搬移后的代码起始地址是0x7dbe2000, 这个信息在反汇编调试时可能有用到
Relocation Offset is: 7dbe2000
// ENV默认保存在ddr里。如果是选择保存在eMMC、Nand等存储介质里,则不会有这个打印
Using default environment

// 当前的存储介质是mmc0,即eMMC(如果是sd卡,则为mmc1)
dwmmc@fe320000: 1, sdhci@fe330000: 0
// 存储介质类型是通过atags,由前级miniloader传参告知U-Boot
Bootdev(atags): mmc 0
// 当前的eMMC的工作在HS400模式,时钟频率是150M
MMC0: HS400, 150Mhz
// 当前采用GPT分区表(如果是RK parameter分区表,则打印:RKPARM)
PartType: EFI
// 当前是recovery模式
// kernel里执行的"reboot xxx"命令,最终也是由这个打印来体现
boot mode: recovery
// Kernel DTB来自于recovery.img,其正常被加载
Load FDT from recovery part
DTB: rk-kernel.dtb
HASH: OK(c)

// ==> 注意:自此之后,U-Boot已经切到kernel dtb,后续所有外设驱动都使用kernel dtb的信息!!

// DTBO执行成功
ANDROID: fdt overlay OK
// I2C的速度,这个是U-Boot开机速度的影响因素之一,尤其对于DCDC和LDO非常多的PMIC,如果I2C速度慢,
// 那么对开机速度有一定影响。如果用户关心开机速度,可以关注这个信息
I2c speed: 400000Hz
// 当前PMIC是RK818
// on值对应ON_SOURCE寄存器,表明了当前这次PMIC上电的原因
// off值对应OFF_SOURCE寄存器,表明前一次关机或掉电的原因
// on和off信息,对于系统出现异常重启或关机等情况时,这是个有价值的信息
PMIC: RK818 (on=0x20 off=0x40)
// 各路可调压regulator的当前电压值,一般是DCDC且对应的是RK平台的arm、logic、center等电压
// 在出现系统启动异常、开机不稳定等问题时,这是个有价值的信息vdd_center 900000 uV
vdd_cpu_l 900000 uV
vdd_log 900000 uV
// Kernel dts的“model"字段内容,通过这个信息可以知道我们使用了Kernel的哪份dts
Model: Rockchip RK3399 Excavator Board edp avb (Android)
enter Recovery mode!
// 显示驱动的相关信息
Rockchip UBOOT DRM driver version: v1.0.1
Using display timing dts
Detailed mode clock 200000 kHz, flags[a]
H: 1536 1548 1564 1612
V: 2048 2056 2060 2068
bus_format: 100e
// clk-tree信息,具体含义请参考U-Boot开发文档的CLK章节
CLK: (uboot. arml: enter 816000 KHz, init 816000 KHz, kernel 0N/A)
CLK: (uboot. armb: enter 24000 KHz, init 24000 KHz, kernel 0N/A)
aplll 816000 KHz
apllb 24000 KHz
dpll 800000 KHz
cpll 200000 KHz
gpll 800000 KHz
npll 600000 KHz
vpll 24000 KHz
aclk_perihp 133333 KHz
hclk_perihp 66666 KHz
pclk_perihp 33333 KHz
aclk_perilp0 266666 KHz
hclk_perilp0 88888 KHz
pclk_perilp0 44444 KHz
hclk_perilp1 100000 KHz
pclk_perilp1 50000 KHz
// GMAC驱动使能
Net: eth0: ethernet@fe300000
// 开机长按ctrl+c,可在如下打印之后进入U-Boot命令行模式
Hit key to stop autoboot('CTRL+C'): 0
// 再一次知道当前是recovery模式
ANDROID: reboot reason: "recovery"
// vboot=0表示没有启用secureboot;当前是AVB固件,所以会走AVB的常规校验流程
Vboot=0, AVB images, AVB verify
// 设备是否unlock
read_is_device_unlocked() ops returned that device is UNLOCKED
// 原生的U-Boot默认是把整个boot.img/recovery.img加载起来,然后再把ramdisk、fdt、kernel再进行
// 一次搬移(称为relocation),搬到用户预定的地址上,这样是比较耗时的,尤其当ramdisk非常大的时候。
// RK平台做了修改,一次性直接从存储上把ramdisk、fdt、kernel搬到预定的内存地址。
// 有如下打印则说明启用了这种一次性搬移的操作,更省时间
Fdt Ramdisk skip relocation

// 加载Android格式的固件,把kernel加载到0x00280000,fdt加载到0x8300000
// 假如是LZ4压缩内核,这里可能打印:
// Booting LZ4 kernel at 0x00680000(Uncompress to 0x00280000) with fdt at 0x8300000...
Booting IMAGE kernel at 0x00280000 with fdt at 0x8300000...

// 忽略,可不关心
## Booting Android Image at 0x0027f800 ...
// kernel和ramdisk的加载地址以及大小
Kernel load addr 0x00280000 size 19081 KiB
RAM disk load addr 0x0a200000 size 9627 KiB
// fdt的加载地址
## Flattened Device Tree blob at 08300000
Booting using the fdt blob at 0x8300000
// 忽略,可不关心
XIP Kernel Image ... OK
// 这里仅仅是打印kernel dts指定的reserved-memory,可作为出内核启动出问题时的一个分析信息
'reserved-memory' secure-memory@20000000: addr=20000000 size=10000000
// fdt的起始和结束地址
Using Device Tree in place at 0000000008300000, end 000000000831c6f7
// 传递给内核,告知内核可使用的内存空间范围(ATF、optee等空间已经被除去)
Adding bank: 0x00200000 - 0x08400000 (size: 0x08200000)
Adding bank: 0x0a200000 - 0x80000000 (size: 0x75e00000)
// U-Boot阶段开机耗时
Total: 367.128 ms

// 由U-Boot打印,这个打印之后,U-Boot会完成一些ARM架构相关(比如:清cache、关中断、
// cpu状态切换等)和U-Boot的dm设备注销等清零工作,出问题的概率极低。
// 完成上述工作后就跳到kernel,因此也可以理解为,出现这个打印就是到了内核阶段。
Starting kernel ...

// kernel阶段的打印信息
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Initializing cgroup subsys cpuset
[ 0.000000] Initializing cgroup subsys cpu
[ 0.000000] Initializing cgroup subsys cpuacct
[ 0.000000] Initializing cgroup subsys schedtune
[ 0.000000] Linux version 4.4.167 (hgc@ubuntu) (gcc version 6.3.1 20170404 (Linaro
GCC 6.3-2017.05) ) #83 SMP PREEMPT Thu Mar 21 09:31:08 CST 2019
[ 0.000000] Boot CPU: AArch64 Processor [410fd034]
[ 0.000000] earlycon: Early serial console at MMIO32 0xff1a0000 (options '')
[ 0.000000] bootconsole [uart0] enabled
[ 0.000000] Reserved memory: failed to reserve memory for node 'stb-
devinfo@00000000': base 0x0000000000000000, size 0 MiB
[ 0.000000] cma: Reserved 16 MiB at 0x000000007f000000
......

RK固件

U-Boot 2017.09-03352-gb1265b5 (Jul 12 2019 - 09:57:24 +0800)

Model: Rockchip RK3399 Evaluation Board
PreSerial: 2
DRAM: 2 GiB
Sysmem: init
Relocation Offset is: 7dbe2000
Using default environment
......

Hit key to stop autoboot('CTRL+C'): 0
ANDROID: reboot reason: "recovery"
// 因为是RK格式的固件,所以不可能是AVB格式
Not AVB images, AVB skip
// 因为是RK格式的固件,所以这里会提示加载android格式固件失败
// 因为目前启动优先级是:android格式 > RK格式 > distro格式
** Invalid Android Image header **
Android image load failed
Android boot failed, error -1.
// 当前是recovery模式
boot mode: recovery
// 启动RK格式的固件,加载ramdis、kernel、fdt
=Booting Rockchip format image=
fdt @ 0x08300000 (0x00012dd0)
kernel @ 0x00280000 (0x0119e008)
ramdisk @ 0x0a200000 (0x00754540)

// 下面基本类同android格式固件的启动信息
Fdt Ramdisk skip relocation
## Flattened Device Tree blob at 08300000
Booting using the fdt blob at 0x8300000
Using Device Tree in place at 0000000008300000, end 0000000008315dcf
Adding bank: 0x00200000 - 0x08400000 (size: 0x08200000)
Adding bank: 0x0a200000 - 0x80000000 (size: 0x75e00000)
Total: 508.11 ms

Starting kernel ...

[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Initializing cgroup subsys cpuset
[ 0.000000] Initializing cgroup subsys cpu
......

Didstro固件

U-Boot 2017.09-03352-gb1265b5 (Jul 12 2019 - 09:57:24 +0800)

Model: Rockchip RK3399 Evaluation Board
PreSerial: 2
DRAM: 2 GiB
Sysmem: init
Relocation Offset is: 7dbe2000
Using default environment

......

// 找到mmc0,即eMMCswitch to partitions #0, OK
mmc0(part 0) is current device
// 查找eMMC存储上第6个分区的固件(GPT分区表里,6对应的是boot.img分区,GPT里用"-bootable"属性指明)
Scanning mmc 0:6...
// 找到了配置文件extlinux.conf
Found /extlinux/extlinux.conf
Retrieving file: /extlinux/extlinux.conf

// 加载kernel
205 bytes read in 82 ms (2 KiB/s)
1: rockchip-kernel-4.4
Retrieving file: /Image
13484040 bytes read in 1833 ms (7 MiB/s)

// 打包时指定的cmdline信息
append: earlycon=uart8250,mmio32,0xff1a0000 console=ttyS2,1500000n8 rw
root=/dev/mmcblk0p7 rootwait rootfstype=ext4 init=/sbin/init

// 加载fdt
Retrieving file: /rk3399.dtb
61714 bytes read in 54 ms (1.1 MiB/s)

// ==> 如果打包时没有ramdisk,就不会有ramdisk信息打印; 否则这里也会有打印

## Flattened Device Tree blob at 01f00000
Booting using the fdt blob at 0x1f00000
Loading Device Tree to 000000007df14000, end 000000007df26111 ... OK

Starting kernel ...

[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Initializing cgroup subsys cpuset
[ 0.000000] Initializing cgroup subsys cpu
......

无有效固件

U-Boot 2017.09-03352-gb1265b5 (Jul 12 2019 - 09:57:24 +0800)

Model: Rockchip RK3399 Evaluation Board
PreSerial: 2
DRAM: 2 GiB
Sysmem: init
Relocation Offset is: 7dbe2000
Using default environment

......

// 找到mmc0,即eMMC
找不到固件的开机信息
switch to partitions #0, OK
mmc0(part 0) is current device
// 查找eMMC存储上第6个分区的固件(GPT分区表里,6对应的是boot.img分区,GPT里用"-bootable"属性指明)
Scanning mmc 0:6...
// 找到了配置文件extlinux.conf
Found /extlinux/extlinux.conf
Retrieving file: /extlinux/extlinux.conf

// 加载kernel
205 bytes read in 82 ms (2 KiB/s)
1: rockchip-kernel-4.4
Retrieving file: /Image
13484040 bytes read in 1833 ms (7 MiB/s)

// 打包时指定的cmdline信息
append: earlycon=uart8250,mmio32,0xff1a0000 console=ttyS2,1500000n8 rw
root=/dev/mmcblk0p7 rootwait rootfstype=ext4 init=/sbin/init

// 加载fdt
Retrieving file: /rk3399.dtb
61714 bytes read in 54 ms (1.1 MiB/s)

// ==> 如果打包时没有ramdisk,就不会有ramdisk信息打印; 否则这里也会有打印

## Flattened Device Tree blob at 01f00000
Booting using the fdt blob at 0x1f00000
Loading Device Tree to 000000007df14000, end 000000007df26111 ... OK

Starting kernel ...

[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Initializing cgroup subsys cpuset
[ 0.000000] Initializing cgroup subsys cpu
......
U-Boot 2017.09-03352-gb1265b5 (Jul 12 2019 - 09:57:24 +0800)

Model: Rockchip RK3399 Evaluation Board
PreSerial: 2
DRAM: 2 GiB
Sysmem: init
Relocation Offset is: 7dbe2000
Using default environment

......

Net: eth0: ethernet@fe300000
Hit key to stop autoboot('CTRL+C'): 0 ANDROID: reboot reason: "recovery"
// 不是Android格式固件
Not AVB images, AVB skip
** Invalid Android Image header **
Android image load failed
Android boot failed, error -1.
boot mode: recovery

// 不是RK格式固件
=Booting Rockchip format image=
kernel: invalid image tag(0x45435352)
boot_rockchip_image kernel part read error

// 不是DISTRO格式固件。后面所有的打印都来在distro加载命令,因为distro命令会试图从mmc、nand、net、
// usb等所有我们预先定义的设备(详见rockchip-common.h中的宏定义:BOOT_TARGET_DEVICES)中去寻
// 找distro固件,即逐一扫描进行查找
switch to partitions #0, OK
mmc0(part 0) is current device
Failed to mount ext2 filesystem...
** Unrecognized filesystem type **
starting USB...
USB0: Register 2000140 NbrPorts 2
Starting the controller
USB XHCI 1.10
USB1: Register 2000140 NbrPorts 2
Starting the controller
USB XHCI 1.10
USB2: USB EHCI 1.00
USB3: USB OHCI 1.0
USB4: USB EHCI 1.00
USB5: USB OHCI 1.0
scanning bus 0 for devices... 1 USB Device(s) found
scanning bus 1 for devices... 1 USB Device(s) found
scanning bus 2 for devices... 1 USB Device(s) found
scanning bus 3 for devices... 1 USB Device(s) found
scanning bus 4 for devices... 1 USB Device(s) found
scanning bus 5 for devices... 1 USB Device(s) found
scanning usb for storage devices... 0 Storage Device(s) found

Device 0: unknown device
ethernet@fe300000 Waiting for PHY auto negotiation to complete......... TIMEOUT !
Could not initialize PHY ethernet@fe300000
missing environment variable: pxeuuid
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/01-7a-1d-33-50-3d-a1
ethernet@fe300000 Waiting for PHY auto negotiation to complete..
......

// 最终distro命令对所有可能的存储介质都扫描后也找不到固件,就停在U-Boot命令行模式
=>