uboot启动时遇到设备树头校验错误
Posted
技术标签:
【中文标题】uboot启动时遇到设备树头校验错误【英文标题】:The device tree header verification error was encountered during uboot startup 【发布时间】:2021-12-27 06:33:21 【问题描述】:我在使用 orangepi3 时遇到问题。
我有一张正常情况下可以使用的图片,
但偶尔会出现以下问题。 一旦出现这个问题,此时烧录的镜像就不能再使用了,只能复制烧录的镜像
uboot启动时报以下错误。
Hit any key to stop autoboot: 0
no mmc device at slot 0
mmc2(part 0) is current device
2512 bytes read in 5 ms (490.2 KiB/s)
## Executing script at 43100000
U-boot loaded from SD
Boot script loaded from mmc
** Bad device mmc 0 **
** File not found /boot/dtb/sunxi/sun50i-h6-orangepi3.dtb **
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
8247895 bytes read in 404 ms (19.5 MiB/s)
19425352 bytes read in 945 ms (19.6 MiB/s)
但我确定这个文件是存在的; 因为当这个错误存在的时候,我进入uboot,打印设备树。可以正常打印,但是执行命令boot还是会报这个错误。
然后我检查了文件系统,发现该文件存在于路径中 .
查了uboot源码,在函数fdt_check_header中发现了这个错误
int fdt_check_header(const void *fdt)
if (fdt_magic(fdt) == FDT_MAGIC)
/* Complete tree */
if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
return -FDT_ERR_BADVERSION;
if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
return -FDT_ERR_BADVERSION;
else if (fdt_magic(fdt) == FDT_SW_MAGIC)
/* Unfinished sequential-write blob */
if (fdt_size_dt_struct(fdt) == 0)
return -FDT_ERR_BADSTATE;
else
return -FDT_ERR_BADMAGIC;
return 0;
但是在uboot中init_sequence_f exereserve_fdt也有设备树头的校验,校验通过。 但是在uboot autoboot_command run_command_list cmd_list中checked device tree header发生错误,导致无法正确进入内核。
进入FDT前_check_我在header函数前加了一个打印函数
在输入函数 fdt_check_header() 之前,我在 reserve_fdt() 中添加如下打印
静态 int reserve_fdt(void)
/*
* If the device tree is sitting immediate above our image then we
* must relocate it. If it is embedded in the data section, then it
* will be relocated with other data.
*/
if (gd->fdt_blob)
pr_msg("reserve_fdt fdt_check_headeris %d\n",fdt_magic(gd->fdt_blob));
if(fdt_check_header(gd->fdt_blob) != 0)
pr_msg("fdt header check error\n");
return -1;
//reserve memory for expand dtb ,because cmd_fdt will update the base dtb
gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);
fdt_set_totalsize((void*)gd->fdt_blob,gd->fdt_size);
gd->start_addr_sp -= gd->fdt_size * 2;
gd->new_fdt = map_sysmem(gd->start_addr_sp, gd->fdt_size);
debug("Reserving %lu Bytes for FDT at: %08lx\n",
gd->fdt_size, gd->start_addr_sp);
return 0;
并且在函数 fdt_valid() 中也添加;
static int fdt_valid(struct fdt_header **blobp)
const void *blob = *blobp;
int err;
if (blob == NULL)
printf ("The address of the fdt is invalid (NULL).\n");
return 0;
printf("fdt_valid fdt_check_header is %d\n",fdt_magic(blob));
err = fdt_check_header(blob);
if (err == 0)
return 1; /* valid */
if (err < 0)
printf("libfdt fdt_check_header(): %s", fdt_strerror(err));
/*
* Be more informative on bad version.
*/
if (err == -FDT_ERR_BADVERSION)
if (fdt_version(blob) <
FDT_FIRST_SUPPORTED_VERSION)
printf (" - too old, fdt %d < %d",
fdt_version(blob),
FDT_FIRST_SUPPORTED_VERSION);
if (fdt_last_comp_version(blob) >
FDT_LAST_SUPPORTED_VERSION)
printf (" - too new, fdt %d > %d",
fdt_version(blob),
FDT_LAST_SUPPORTED_VERSION);
printf("\n");
*blobp = NULL;
return 0;
return 1;
那么,当错误发生时,日志如下:
U-Boot 2014.07-orangepi (Oct 29 2021 - 09:07:58) Xunlong Software
[1.947]uboot commit : b65841975dcb31f64a2c69344f60db12b98791ae
[1.947]secure enable bit: 0
[1.947]normal mode: with secure monitor
I2C: ready
[1.949]pmbus: ready
[1.949][ARISC] :arisc initialize
[1.975][ARISC] :arisc para ok
[SCP] :sunxi-arisc driver begin startup 2
[SCP] :arisc version: []
[SCP] :sunxi-arisc driver v1.10 is starting
[1.987][ARISC] :sunxi-arisc driver startup succeeded
[1.989]PMU: AXP806
[1.989]PMU: AXP806 found
[1.989]bat_vol=0, ratio=0
[1.989]set pc_bias(1) bias:1800
[1.989]set pg_bias(5) bias:1800
[1.989]set power on vol to default
[1.989]dcdca_vol = 1000, onoff=1
[1.993]aldo2_vol = 3300, onoff=1
[1.998]bldo3_vol = 1800, onoff=1
[2.002]cldo2_vol = 3300, onoff=1
[2.006]cldo3_vol = 3300, onoff=1
[2.010]find power_sply to end
[2.010]cant find pll setting(1320M) from pll table,use default(408M)
[2.012]PMU: cpux 408 Mhz,AXI=204 Mhz
[2.013]PLL6=600 Mhz,AHB1=200 Mhz, APB1=100Mhz MBus=400Mhz
[2.017]DRAM: 1 GiB
[2.019]reserve_fdt fdt_check_headeris -804389139
[2.026]fdt addr: 0x79ccb0e0
[2.026]gd->fdt_size: 0x1a6c0
[2.030]Relocation Offset is: 34e03000
[2.095]gic: sec monitor mode
[2.095]line:180 func:check_ir_boot_recovery start
[2.095]ir boot recovery not used
[2.095][key recovery] no use
[2.096][box standby] read rtc = 0x0
[2.096][box standby] start_type = 0x1
[2.096][box standby] to kernel
[2.096]workmode = 0,storage type = 2
[2.098]MMC: 2
SUNXI SD/MMC: 2
[mmc]: [0-60|61]
[mmc]: [0-51|52]
[mmc]: [7-48|42]
[mmc]: [0-11|12] [26-29|4] [34-50|17]
[mmc]: [0-48|49] [54-56|3] [58-63|6]
[mmc]: [0-26|27] [54-63|10]
[mmc]: [0-58|59]
[mmc]: [6-51|46] [53-58|6]
[mmc]: [1-7|7] [9-56|48]
[mmc]: [1-26|26]
Normal
[6.618]MMC: 2
SUNXI SD/MMC: 2, SUNXI SD/MMC: 2
[6.624]sunxi flash init ok
[6.624]hdmi hdcp not enable!
Using default environment
[6.625]inter uboot shell
Hit any key to stop autoboot: 0
no mmc device at slot 0
mmc2(part 0) is current device
2512 bytes read in 5 ms (490.2 KiB/s)
## Executing script at 43100000
U-boot loaded from SD
Boot script loaded from mmc
** Bad device mmc 0 **
**** File not found /boot/dtb/sunxi/sun50i-h6-orangepi3.dtb **
fdt_valid fdt_check_header is -1271711085
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
fdt_valid fdt_check_header is -1271711085
libfdt fdt_check_header(): FDT_ERR_BADMAGIC**
8247895 bytes read in 404 ms (19.5 MiB/s)
19425352 bytes read in 945 ms (19.6 MiB/s)
## Booting kernel from Legacy Image at 41000000 ...
Image Name:
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 19425288 Bytes = 18.5 MiB
Load Address: 41000000
Entry Point: 41000000
Verifying Checksum ... OK
## Loading init Ramdisk from Legacy Image at 43300000 ...
Image Name: uInitrd
Image Type: ARM Linux RAMDisk Image (gzip compressed)
Data Size: 8247831 Bytes = 7.9 MiB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
Loading Kernel Image ... OK
reserving fdt memory region: addr=40020000 size=800
reserving fdt memory region: addr=48000000 size=1000000
reserving fdt memory region: addr=48100000 size=4000
reserving fdt memory region: addr=48104000 size=1000
reserving fdt memory region: addr=48105000 size=1000
reserving fdt memory region: addr=79ccb0e0 size=18f20
Loading Ramdisk to 49822000, end 49fffa17 ... OK
Using Device Tree in place at 44000000, end 4401d6bf
[8.736]disp_ioctl, display not init yet
[8.736]disp_ioctl, display not init yet
Starting kernel ...
INFO: BL3-1: Next image address = 0x41000000
INFO: BL3-1: Next image spsr = 0x3c5
WARNING: Unimplemented Standard Service Call: 0xc0000026
和编号 fdt_check_headeris -804389139 id normol;
这是为什么呢? 为什么前面验证还是正确,后面却出错了?
你遇到过这个问题吗?或者你能给我一些建议吗?谢谢!
【问题讨论】:
【参考方案1】:每次重启时报告日志是否相同?
如果相同,则硬件存储中的 DTB 没问题。
您应该担心两个fdt_magic
函数调用之间的内存覆盖。
【讨论】:
大部分情况下,镜像可以正常启动。只是偶尔找不到设备树文件。但是一旦出现这个问题,镜像就不能再正常使用了,必须重新烧录 出现问题时第一次检查fdt头没问题,但是第二次检查失败。我认为应该是内存中的数据被更改了。 感谢您的提醒。我再看一遍代码。【参考方案2】:您在 2014.07
上,它既缺少对现代 ext4 文件系统映像的支持,也缺少对安装现代 ext4 文件系统映像的警告/拒绝,这些映像具有默认启用的功能,显示诸如“文件我知道存在,我可以在 Linux 中看到它,但没有找到”。请升级到当前的 U-Boot。
【讨论】:
以上是关于uboot启动时遇到设备树头校验错误的主要内容,如果未能解决你的问题,请参考以下文章