理解Linux的加载地址对于U-Boot过程很重要

13

我正在尝试理解嵌入式Linux的原理,但是无法弄清楚u-boot输出中的地址。

例如,我有一块基于i.MX6四核处理器的UDOO开发板,我从U-Boot获取了以下输出:

U-Boot 2013.10-rc3 (Jan 20 2014 - 13:33:34)

CPU:   Freescale i.MX6Q rev1.2 at 792 MHz
Reset cause: POR
Board: UDOO
DRAM:  1 GiB
MMC:   FSL_SDHC: 0
No panel detected: default to LDB-WVGA
Display: LDB-WVGA (800x480)
In:    serial
Out:   serial
Err:   serial
Net:   using phy at 6
FEC [PRIME]
Warning: FEC MAC addresses don't match:
Address in SROM is         00:c0:08:88:a5:e6
Address in environment is  00:c0:08:88:9c:ce

Hit any key to stop autoboot:  0 
Booting from mmc ...
4788388 bytes read in 303 ms (15.1 MiB/s)
## Booting kernel from Legacy Image at 12000000 ...
   Image Name:   Linux-3.0.35
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    4788324 Bytes = 4.6 MiB
   Load Address: 10008000
   Entry Point:  10008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK

Starting kernel ...

我不理解加载地址0x10008000的价值。根据该特定处理器的文档,在地址区域0x10000000-0xffffffff映射了主存储器。但是0x8000偏移量是什么?我无法找到这个值的原因。
我也不理解地址0x12000000,内核镜像是从那里加载的。是否有SD卡的映射内存区域?
请给我一些关于这些地址的解释或更好的是一些关于此主题的参考资源。我的目标是学习如何将U-boot和Linux内核移植到其他开发板上。
谢谢!

1
内核引导要求在Documentation/arm/Booting中有记录。我记不清楚TEXT_OFFSET为什么是必须的,但它确实是必须的。 - Notlikethat
1
典型的情况是将RAM的起始地址设置为0x8000,因为'ATAGS'存储在最低地址处。从Freescale下载iMX6参考手册,所有地址都会在前几章中列出。 - artless noise
2
我也不理解0x12000000地址,这是内核映像加载的地方。U-Boot使用变量loadaddr来存储该值。它是一个在上部内存中相当任意的值,但仍然远低于U-Boot执行的位置。当从非易失性存储器(例如NAND或SD卡)读取或从网络加载内核uImage或zImage文件时,该地址是内核uImage或zImage在主存储器中暂时存储的位置。 uImage或zImage的这个loadaddr必须与实际内核的“加载地址” 0x10008000不同,以允许内核映像的解压缩。 - sawdust
1
“SD卡是否有映射内存区域?”-- 不是的。可以使用读取SD卡的命令(例如fatload mmc 0:1 0x12000000 uImage),其唯一输出结果为“4788388字节在303毫秒内读取(15.1 MiB/s)”。您需要获取printenv命令的输出,以充分揭示和理解自动引导在您的板子上的工作方式。关键的环境变量是bootcmd - sawdust
@sawdust 在这种情况下不需要对0x10008000进行解压以允许内核镜像的解压缩。当u-boot将控制权转移到内核时,内核将执行至少两个操作。1)如果需要,解压自身;2)重新定位自身。在OP的情况下,当u-boot将控制权转移到内核时,不会执行解压缩,但会执行重新定位。内核将自身重新定位/复制到RAM(硬件地址)的起始位置。 - sessyargc.jp
显示剩余5条评论
2个回答

14

如果您检查u-boot的环境变量,您会发现内核映像是通过类似于fatload的命令从引导设备复制到RAM位置(这里是12000000)。

现在,这不是LOADADDRESS。您在编译内核时将LOADADDRESS提供给命令行,该地址大多数情况下位于处理器物理地址空间中RAM开头的32K偏移处。

您的RAM被映射到10000000,而内核LOADADDRESS10008000(32K偏移)。bootm命令将内核映像从12000000解压缩到10008000地址,然后调用kernel入口点


好的,我会添加0x12000000和0x80008000,这两个地址都必须在物理DDR地址空间中。因此,0x12000000只是存储内核的初步位置,在从u-boot解压缩之前,将未压缩的二进制文件放入0x80008000,同时还必须将其设置为内核构建中的load_addr。 - Angelo Dureghello

1
请查看include/configs文件夹。它包含所有板定义。 i.MX uboot include/configs 要将uboot移植到另一个端口,请基于非常相似的板进行修改。

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