Linux kernel 使用LOADADDR构建内核uImage

Linux kernel 使用LOADADDR构建内核uImage,linux-kernel,embedded-linux,u-boot,Linux Kernel,Embedded Linux,U Boot,在构建内核时,我将LOADADDR命名为“0x80008000”: 你能帮我弄明白这有什么用吗?我可以更改LOADADDR吗?LOADADDR的长度是否有任何限制?(我假设您使用的是ARM,因为您提到了U-Boot和LOADADDR的值。) 你能帮我弄明白这有什么用吗 LOADADDR指定链接器将在其中定位内核映像的地址。(对于一些体系结构(例如Blackfin),这是正确的,但对于ARM则不然 LOADADDR指定内核映像将通过U-Boot定位的地址,并由mkimage实用程序存储在U-Boo

在构建内核时,我将LOADADDR命名为“0x80008000”:

你能帮我弄明白这有什么用吗?我可以更改LOADADDR吗?LOADADDR的长度是否有任何限制?

(我假设您使用的是ARM,因为您提到了U-Boot和LOADADDR的值。)

你能帮我弄明白这有什么用吗

LOADADDR指定链接器将在其中定位内核映像的地址。(对于一些体系结构(例如Blackfin),这是正确的,但对于ARM则不然

LOADADDR指定内核映像将通过U-Boot定位的地址,并由mkimage实用程序存储在U-Boot头中。通常,加载地址(用于放置在内存中)也是开始地址(用于执行)。请注意,uImage文件通常只是(自解压、压缩)文件使用U-Boot包装器的zImage文件

我能换一下LOADADDR吗

是的,但根据(文森特·桑德斯)的说法,这将违反ARM公约:

  • 尽管能够将zImage放在内存中的任何位置, 按照惯例,它是在物理RAM plus的基础上加载的 偏移量0x8000(32K)。这为参数块留出了空间 通常放置在偏移量0x100处,零页面异常向量和页面 这种惯例非常普遍
(您问题中提到的uImage可能只是一个带有U-Boot包装的zImage,因此引用确实适用。)

LOADADDR的长度有限制吗

“长度”?如果使用32位处理器,则此地址的长度为32位


附录

arch/arm/boot/Makefile仅使用LOADADDR从zImage构建uImage

根据(Russel King's),此LOADADDR上的约束条件为:

内核应该放在RAM的第一个128MiB中。建议这样做 将其加载到32MiB以上,以避免需要重新定位 在解压缩之前,这将使引导过程稍微 更快

当引导原始(非zImage)内核时,约束更加严格。 在这种情况下,内核必须以一个偏移量加载到系统中 到文本偏移-页面偏移


设备树、ATAGs或initramfs的预期位置可以在此LOADADDR上添加更多约束。

感谢您的回复。是的,我使用的是基于ARM的board。我没有得到“LOADADDR指定链接器将定位内核映像的地址。”,请提供帮助。据我所知,链接器将链接所有“.o”并创建vmlinux.o。我认为LOADADDR在构建uImage时不会放置任何角色,而只是将相同的(LOADDR值)放置在uImage头中,请更正它是否工作。LOADADDR是虚拟的还是物理的?如果我们将0x80008000视为物理地址(因为此时未启用MMU)然后0x80008000将指向一个大于2GB的物理地址。如果我们的设备中有2GB的RAM,那么它将如何处理?@user3693586——这是一个物理内存地址,因为引导加载程序没有像您提到的那样启用MMU。通常,物理RAM不会从地址零开始。我见过RAM位于0x2000的ARM SOC0000或0x7000000。显然,在您的电路板上,它从0x8000000开始。物理地址0通常在ARM上有一个内部启动ROM,而不是读/写RAM。请参阅数据表或技术参考手册(TRM)您的SoC的内存映射。感谢您提供的信息,现在我了解了LOADADDR。我使用hexdump检查了uImage标头,可以看到LOADADDR和入口点地址。在我的情况下,LOADADDR和入口点地址都是相同的。#hexdumpuImage |水头-20000005275619 5b20 01e4 bf55 da50 6000 A8D50 0000010 0080 0080 0080 0080 5f32 d5d4 0205 0002
make uImage LOADADDR=0x80008000