我正在使用 Xilinx zcu706 开发板。我已经开发了 Linux 内核,但是当它启动时,我在保留设备树中定义的内存时遇到错误:ERROR: reserving fdt memory region failed (addr=38000000 size=8000000)
这是我的设备树,我从 Xilinx 教程中复制了它:
/include/ "system-conf.dtsi"
/ {
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
reserved: buffer@0x38000000 {
compatible = "shared-dma-pool";
no-map;
reg = <0x38000000 0x08000000>;
};
};
reserved-driver@0x38000000 {
compatible = "ingeniars,gpu4sat-memory";
memory-region = <&reserved>;
};
};
这是错误发生前启动时发生的情况:
Hit any key to stop autoboot: 0
JTAG: Trying to boot script at 0x3000000
## Executing script at 03000000
## Booting kernel from Legacy Image at 00200000 ...
Image Name: Linux-5.4.0-xilinx-v2020.2
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 4325984 Bytes = 4.1 MiB
Load Address: 00200000
Entry Point: 00200000
Verifying Checksum ... OK
## Loading init Ramdisk from Legacy Image at 04000000 ...
Image Name: petalinux-image-minimal-zynq-gen
Image Type: ARM Linux RAMDisk Image (uncompressed)
Data Size: 7885622 Bytes = 7.5 MiB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
## Flattened Device Tree blob at 00100000
Booting using the fdt blob at 0x100000
Loading Kernel Image
Loading Ramdisk to 1f87a000, end 1ffff336 ... OK
ERROR: reserving fdt memory region failed (addr=38000000 size=8000000)
Loading Device Tree to 1f872000, end 1f879ce8 ... OK
Starting kernel ...
错误之后,启动似乎正确结束,我可以使用我开发的应用程序,但最终我得到一个内核恐慌,我认为这可能与错误保留内存有关。
这是内核恐慌堆栈跟踪:
Unable to handle kernel NULL pointer dereference at virtual address 000009b4
pgd = 330888c5
[000009b4] *pgd=00000000
Internal error: Oops - BUG: 5 [#1] PREEMPT SMP ARM
Modules linked in: krnl_gpu4sat_memory(O) krnl_gpu_sat(O) uio_pdrv_genirq
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G O 5.4.0-xilinx-v2020.2 #1
Hardware name: Xilinx Zynq Platform
PC is at update_rq_clock+0x0/0xe8
LR is at dequeue_task+0x20/0x40
pc : [<c013acfc>] lr : [<c013ae44>] psr: 400f0193
sp : c0b01d90 ip : 00000000 fp : c0b01da4
r10: 00000000 r9 : c0b03df4 r8 : 800f0193
r7 : ee57d104 r6 : 00000400 r5 : c0a3f180 r4 : ef7f5180
r3 : 0bea0be9 r2 : c0a3f180 r1 : ef7f5180 r0 : 00000400
Flags: nZcv IRQs off FIQs on Mode SVC_32 ISA ARM Segment none
Control: 18c5387d Table: 2e4ec04a DAC: 00000051
Process swapper/0 (pid: 0, stack limit = 0x23873ec4)
Stack: (0xc0b01d90 to 0xc0b02000)
1d80: ee57cc80 ee57cc80 00000000 ee57d104
1da0: c0b01db4 c0140f48 ef7f5180 ee57cc80 c0b01dcc c013b74c ee57cc80 ef7f5180
1dc0: 00000000 ee57d104 c0b01dfc c013c318 ee487f20 c0b03c48 ef7f3600 ef7f3640
1de0: ef7f3600 ef7f3600 ee487f20 00000000 35cca1c4 000000a7 00000001 c016d768
1e00: ef7f3640 c016dbf0 35cca1c4 000000a7 ffffffff c016d748 c0b00000 ef7f3600
1e20: 200f0193 00000011 ffffffff 7fffffff 000000a7 000000a7 000000a7 c016e528
1e40: 200f0193 0000000f 00000003 c016e3ac 69871980 35cca1c4 000000a7 35cc9c0c
1e60: 000000a3 00000001 c0b040d4 00000011 ef015ec0 f8f01100 c0b00000 000000a7
1e80: 000000a7 c010dcfc ef008900 c015db40 00000000 00000000 ef006600 00000001
1ea0: f8f01100 c0158d90 00000000 c015933c c0b01ee0 f8f00100 c0b040cc c0b17b3c
1ec0: f8f01100 c033ec18 c052bcd0 600f0013 ffffffff c0b01f14 3768e24e c0101a8c
1ee0: 00000000 000000a7 2edb6000 ef7f5180 c0b2d5ac 00000000 ef7f4578 00000000
1f00: 3768e24e 376d9005 000000a7 000000a7 fffffff5 c0b01f30 c052bcac c052bcd0
1f20: 600f0013 ffffffff 00000051 00000000 c0b01f83 00000000 0004c5d8 00000000
1f40: ee9aef00 c0548278 00000000 ef7f4578 c0b2d5ac 00000000 c0b03c68 00000001
1f60: c0b01f80 c0b03ca8 00000000 c052bea8 ef7f4578 c0b2d5ac c0b00000 c01400ec
1f80: 017f5180 c0b03c48 00000000 000000cf 00000001 c0b36440 00000000 c0b36440
1fa0: 00000001 c0a2da40 00000000 c0140278 c0b36494 c0a00cb8 ffffffff ffffffff
1fc0: 00000000 c0a00578 00000000 c0a2da40 d337e4a0 c0b03c48 c0a00330 00000051
1fe0: 10c0387d 00000000 1f872000 413fc090 18c5387d 00000000 00000000 00000000
[<c013acfc>] (update_rq_clock) from [<c0140f48>] (update_overutilized_status.part.0+0x20/0x3c)
[<c0140f48>] (update_overutilized_status.part.0) from [<c013b74c>] (ttwu_do_activate+0x38/0x50)
Code: eaffffe4 e24bd014 e8bd88f0 c0801b38 (e59035b4)
---[ end trace 3e666a7ba6e33cb7 ]---
Kernel panic - not syncing: Fatal exception in interrupt
CPU1: stopping
CPU: 1 PID: 0 Comm: swapper/1 Tainted: G D O 5.4.0-xilinx-v2020.2 #1
Hardware name: Xilinx Zynq Platform
[<c010e37c>] (unwind_backtrace) from [<c010a124>] (show_stack+0x10/0x14)
[<c010a124>] (show_stack) from [<c06a24e8>] (dump_stack+0xb4/0xd0)
[<c06a24e8>] (dump_stack) from [<c010c964>] (ipi_cpu_stop+0x3c/0x98)
[<c010c964>] (ipi_cpu_stop) from [<c010d1b0>] (handle_IPI+0x64/0x80)
[<c010d1b0>] (handle_IPI) from [<c033ec44>] (gic_handle_irq+0x84/0x90)
[<c033ec44>] (gic_handle_irq) from [<c0101a8c>] (__irq_svc+0x6c/0xa8)
Exception stack(0xef085f20 to 0xef085f68)
5f20: 00000000 000000a7 2edc5000 ef804180 c0b2d5ac 00000001 ef803578 00000000
5f40: 3ae0ed5b 4689c05e 000000a7 000000a7 fffffff5 ef085f70 c052bcac c052bcd0
5f60: 60010013 ffffffff
[<c0101a8c>] (__irq_svc) from [<c052bcd0>] (cpuidle_enter_state+0xec/0x288)
[<c052bcd0>] (cpuidle_enter_state) from [<c052bea8>] (cpuidle_enter+0x28/0x38)
[<c052bea8>] (cpuidle_enter) from [<c01400ec>] (do_idle+0x230/0x258)
[<c01400ec>] (do_idle) from [<c0140278>] (cpu_startup_entry+0x18/0x1c)
[<c0140278>] (cpu_startup_entry) from [<0010242c>] (0x10242c)
---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---
正如我所说,无法追踪内核恐慌,因为它不是确定性的:它不会在每次执行时发生,而是在不同的配置下发生。
您认为引导错误可能与内核崩溃有关吗?你知道如何纠正引导错误吗?
该错误消息是在 Linux 内核开始执行之前由 U-Boot 输出的。请注意,
Starting kernel ...
消息在此错误消息之后。
U-Boot 正在处理保留的内存列表,以确保其放置 DT blob 和(可选)initramfs 存档或 initrd 映像不与这些规范冲突。这在 boot/image-fdt.c:
的评论中有记录 * Adding the memreserve regions prevents u-boot from using them to store the
* initrd or the fdt blob.
虽然这是一条“错误”消息,但当它来自 U-Boot 而不是 Linux 内核时,可能会忽略此消息。生成此消息的 U-Boot 例程来自 boot/image-fdt.c:
static void boot_fdt_reserve_region(struct lmb *lmb, uint64_t addr,
uint64_t size, enum lmb_flags flags)
{
long ret;
ret = lmb_reserve_flags(lmb, addr, size, flags);
if (ret >= 0) {
debug(" reserving fdt memory region: addr=%llx size=%llx flags=%x\n",
(unsigned long long)addr,
(unsigned long long)size, flags);
} else {
puts("ERROR: reserving fdt memory region failed ");
printf("(addr=%llx size=%llx flags=%x)\n",
(unsigned long long)addr,
(unsigned long long)size, flags);
}
}
请注意,在尝试为内存块/区域设置保留标志后,成功或失败只会显示消息。由于此例程的类型为
void
,因此不会传回任何返回码,并且错误条件会被 U-Boot 丢弃。
错误之后,启动似乎正确结束,我可以使用我开发的应用程序,但最终我得到一个内核恐慌,我认为这可能与错误保留内存有关。
...
正如我所说,无法追踪内核恐慌,因为它不是确定性的:它不会在每次执行时发生,而是在不同的配置下发生。
您需要查看内核启动日志和 /proc/iomem 以验证指定的内存区域是否已正确保留。你的“想法”可能是不正确的。根据我(数十年)的经验,随机恐慌和故障通常是由故障硬件引起的。 (但要小心;不要成为总是指责硬件的软件人!)
您认为引导错误可能与内核崩溃有关吗?
不,U-Boot 消息与内核崩溃无关。
U-Boot 报告的“错误”可能表示与在高端内存中执行的 U-Boot 的(重定位)映像发生冲突。这种(临时)冲突对 Linux 内核的影响为零。
你知道如何纠正引导错误吗?
要么忽略它,要么尝试使用内存较低的区域。