使用LOADADDR构建内核uImage

12

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

make uImage LOADADDR=0x80008000

您能帮忙理解这个的用途吗?我可以更改LOADADDR吗?LOADADDR的长度有任何限制吗?

2个回答

18

(我假设您使用的是ARM处理器,因为提到了U-Boot并且LOADADDR的值。)

请问你能帮忙理解这个的用途吗?

LOADADDR指定链接器放置内核镜像的地址。 (这在一些体系结构上是正确的(例如Blackfin),但对于ARM来说不是这样的。)

LOADADDR指定U-Boot放置内核镜像的地址,并由mkimage实用程序存储在U-Boot头中。通常,负载地址(用于放置在内存中)也是启动地址(用于执行)。请注意,uImage文件通常只是具有U-Boot包装器的(自解压缩的)zImage文件。

我可以更改LOADADDR吗?

可以,但根据(Vincent Sanders')Booting ARM Linux,这与ARM约定相反:

  • 尽管可以在内存中的任何位置放置zImage, 约定规定它会加载在物理RAM基址加上 0x8000(32K)的偏移量处。这留出空间给参数块 通常放置在偏移量0x100处,零页异常向量和页面 表。这个约定非常常见。

(您问题中提到的uImage可能只是具有U-Boot包装器的zImage,因此该引用适用。)

LOADADDR的长度是否有任何限制?

"长度"?如果您正在使用32位处理器,则此地址的长度将为32位。


补充说明

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

从(Russel King的)ARM Linux引导中,对该LOADADDR的限制如下:

内核应位于前128MiB的RAM中。建议将其加载在32MiB以上以避免在解压缩之前需要重新定位,这将使启动过程稍微快一些。

当引导原始(非zImage)内核时,限制更为严格。在这种情况下,内核必须加载到系统等于TEXT_OFFSET-PAGE_OFFSET的偏移处。

设备树、ATAGs或initramfs的预期位置可能会对此LOADADDR添加更多限制。


谢谢回复。是的,我正在使用基于ARM的板子。我没有理解“LOADADDR指定链接器将放置内核映像的地址”的含义,请问能否帮忙解释一下。据我所知,链接器将链接所有“.o”文件并创建vmlinux.o。我认为在构建uImage时,LOADADDR除了将相同的LOADDR值放置在uImage头中外,不会起到任何作用,请纠正我如果我错了。 - user3693586
1
LOADADDR是虚拟地址还是物理地址?如果我们将0x80008000视为物理地址(因为此时MMU未启用),那么0x80008000将指向一个超过2GB的物理地址。如果我们的设备有2GB RAM,它会如何处理? - user3693586
1
@user3693586 -- 这是一个物理内存地址,因为引导加载程序没有像你提到的那样启用MMU。通常物理RAM不会从地址零开始。我见过一些ARM SoC将RAM放在0x20000000或0x70000000处。显然,在您的板子上它从0x80000000开始。在ARM上,物理地址零通常具有内部引导ROM,而不是可读/可写RAM。请查阅SoC的数据手册或技术参考手册(TRM)以获取内存映射。 - sawdust
谢谢提供的信息,现在我对LOADADDR有了想法。 我使用hexdump检查了uImage头,并且可以看到loadaddr和entry point地址。在我的情况下,loadaddr和entry point地址是相同的。#hexdump uImage | head -2 0000000 0527 5619 5b20 01e4 bf55 da50 6000 a8d5 0000010 0080 0080 0080 0080 5f32 d5d4 0205 0002 - user3693586

0
将其用其他术语描述,内核编译可以生成不同的图像,压缩或非压缩(即XIP所需)。 LOADADDR 是内核的 entry_point,必须正确(与 u-boot 在 DDR 中加载的位置匹配)对于某些使用绝对长跳转进行编译的体系结构非常重要,但对于可以执行相对跳转的 ARM 则无关紧要。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接