Linux 内核引导错误:保留 fdt 内存区域失败

问题描述 投票:0回答:1

我正在使用 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 ]---

正如我所说,无法追踪内核恐慌,因为它不是确定性的:它不会在每次执行时发生,而是在不同的配置下发生。

您认为引导错误可能与内核崩溃有关吗?你知道如何纠正引导错误吗?

memory linux-kernel embedded-linux xilinx u-boot
1个回答
0
投票

该错误消息是在 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 内核的影响为零。

你知道如何纠正引导错误吗?

要么忽略它,要么尝试使用内存较低的区域。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.