U-Boot启动内核时的内存分配疑问(PetaLinux 2023.2)
当你通过JTAG将linux.bin.ub加载到0x80000000覆盖U-Boot原.text段(加载在0x80100000)却不影响后续执行,核心原因是U-Boot的重定位(Relocation)机制,具体细节如下:
U-Boot启动时的重定位操作
U-Boot启动流程分为两个阶段:早期阶段在加载地址(0x80100000)执行初始化硬件、设置内存控制器等基础操作;完成后会将自身完整镜像复制到DDR的高地址区域(通常靠近0xffff_ffff的位置,避开内核、设备树等后续加载区域),然后跳转到高地址的代码继续运行。此时原加载地址的.text段已经不再被使用,变成可复用的闲置内存。启动延迟阶段的内存状态
当你在U-Boot的4秒启动延迟期间暂停时,U-Boot已经完成重定位,所有正在运行的代码都位于高地址区域,0x80000000到0x80100000甚至原U-Boot.text段所在的0x80100000之后的内存,都处于无使用状态,完全可以被JTAG写入的内核镜像覆盖。JTAG加载的直接内存操作
JTAG是直接对物理DDR内存进行读写操作,绕过U-Boot的内存管理机制。只要目标内存区域没有被当前运行的U-Boot代码占用,就可以直接覆盖,而此时U-Boot的执行已经转移到高地址,所以不会产生冲突。bootm命令的执行独立性
执行bootm 0x80000000 0x82e00000 0x81e00000命令时,该命令的代码已经在重定位后的高地址区域运行,只需要读取指定地址的内核、根文件系统和设备树镜像,完成引导后就会交出控制权给内核,整个过程不需要再访问原U-Boot加载地址的内存。
内容的提问来源于stack exchange,提问作者bruin

