crt0.s 分析

本文详细解析了U-Boot的启动过程,包括初始化阶段、内存重定位、BSS段清零、LED初始化及board_init_r函数调用等关键步骤,并介绍了不同配置下堆栈空间的设置方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ENTRY(_main)

/*
 * Set up initial C runtime environment and call board_init_f(0).
 */

#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
ldr sp, =(CONFIG_SPL_STACK)
#else
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
#endif
bic sp, sp, #7/* 8-byte alignment for ABI compliance */
sub sp, sp, #GD_SIZE/* allocate one GD above SP */
bic sp, sp, #7/* 8-byte alignment for ABI compliance */
mov r9, sp/* GD is above SP */
mov r0, #0
    /* 以上代码都是为board_init_f函数准备堆栈空间和gd空间,都在iram中 */
bl board_init_f /*  */
    /* 此时gd空间被初始化了 */
#if ! defined(CONFIG_SPL_BUILD)

/*
 * Set up intermediate environment (new sp and gd) and call
 * relocate_code(addr_moni). Trick here is that we'll return
 * 'here' but relocated.
 */
    /* 初始化sp堆栈 *//* 为relcate, 等函数装备运行环境。 */
ldr sp, [r9, #GD_START_ADDR_SP]/* sp = gd->start_addr_sp */
bic sp, sp, #7/* 8-byte alignment for ABI compliance */
    /* [r9, #GD_BD]就是gd->bd, r9保存的是gd */
ldr r9, [r9, #GD_BD]/* r9 = gd->bd */
sub r9, r9, #GD_SIZE/* new GD is below bd */


adr lr, here    
ldr r0, [r9, #GD_RELOC_OFF]/* r0 = gd->reloc_off */
add lr, lr, r0  /* here加 gd->reloc_off,就是要返回的地址(代码重定位后执行)*/
ldr r0, [r9, #GD_RELOCADDR]/* r0 = gd->relocaddr */
b relocate_code /* 把自己从*(nand)拷贝到dram,返回后here是拷贝到dram中的here。 */
    /* 在此之前的代码都是在iram中执行的。 */
here:
    /* 此后代码在dram中执行了 */
/* Set up final (full) environment */
bl c_runtime_cpu_setup/* we still call old routine here */
ldr r0, =__bss_start/* this is auto-relocated! */
ldr r1, =__bss_end/* this is auto-relocated! */

mov r2, #0x00000000/* prepare zero to clear BSS */

clbss_l:cmp r0, r1/* while not at end of BSS */
strlo r2, [r0]/* clear 32-bit BSS word */
addlo r0, r0, #4/* move to next */
blo clbss_l

bl coloured_LED_init
bl red_led_on

/* call board_init_r(gd_t *id, ulong dest_addr) */
mov     r0, r9                  /* gd_t */
ldr r1, [r9, #GD_RELOCADDR]/* dest_addr */
/* call board_init_r */
ldr pc, =board_init_r/* this is auto-relocated! */

/* we should not return here. */
#endif


ENDPROC(_main)
<think>好的,用户现在遇到了一个问题,他在编译Android NDK项目时发现NDK里面没有crt1.o文件,而他的系统中有其他路径下存在这个文件。他想知道是否可以使用现有的这些文件。 首先,我需要回顾一下之前的对话。用户之前遇到了链接错误,提示找不到crt1.o等文件,虽然确认sysroot正确,但问题依然存在。现在通过find命令发现NDK目录下确实没有这些文件,而系统其他位置有。 接下来,我需要分析为什么NDK里没有这些文件。可能的原因包括NDK版本问题、安装不完整,或者用户配置的路径不正确。另外,用户可能混淆了不同工具链的文件,比如RV1126/RV1109的Linux工具链和Android NDK的工具链,这两者针对的平台不同,一个是Linux嵌入式系统,另一个是Android,所以库文件不兼容。 用户的问题核心在于是否可以使用系统中现有的crt1.o文件。这时候需要告诉他,直接使用非NDK提供的crt文件会导致兼容性问题,因为不同工具链的C运行时库针对的目标系统不同,混用可能导致链接错误或运行时崩溃。 然后,我需要给出解决方案。首先建议检查NDK安装是否正确,确保路径配置正确,特别是sysroot和--target参数是否正确指定了目标架构和API级别。如果确认配置正确,但NDK确实缺少这些文件,可能需要重新下载或验证NDK的完整性。 另外,用户提到使用的是NDK r18b,这个版本可能较旧,可以考虑升级到较新的NDK版本,因为新版本可能修复了此类问题,或者提供更好的工具链支持。同时,建议用户使用NDK提供的标准编译脚本或make_standalone_toolchain.py生成独立的工具链,避免手动配置路径带来的错误。 如果用户确实需要使用现有的非NDK提供的crt文件,需要指导他如何正确配置链接器的路径,但必须强调这可能带来的风险,并建议仅在明确知道兼容性的情况下使用。 最后,确认用户是否需要进一步的帮助,比如检查具体的编译命令,或者验证NDK安装的完整性,以及如何正确设置环境变量和编译参数。</think>根据您提供的搜索结果,这个问题的根源在于Android NDK工具链与本地系统工具链的架构不匹配。让我们逐步分析解决方案: 1. **架构差异分析**: - 您找到的crt1.o文件属于不同的工具链: - `/home/chang/rv1126...` 开头的路径:这是Rockchip RV1126/RV1109的**Linux嵌入式工具链** - `/usr/arm-linux-gnueabihf...`:这是Ubuntu系统的**ARM Linux桌面工具链** - Android NDK需要的是**Android Bionic C库**的启动文件,与上述两者二进制不兼容 2. **NDK r18b正确路径验证**: 在标准NDK r18b中,crt文件应位于: ```bash # ARMv7架构示例 ${NDK}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/arm-linux-androideabi/21/crt1.o # 检查路径是否存在 ls /opt/android-ndk-r18b/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/arm-linux-androideabi ``` 3. **临时解决方案(不推荐长期使用)**: 如果必须使用现有文件,可以通过符号链接创建应急方案: ```bash sudo mkdir -p /opt/android-ndk-r18b/sysroot/usr/lib/arm-linux-androideabi/21/ sudo ln -s /usr/arm-linux-gnueabihf/lib/crt1.o /opt/android-ndk-r18b/sysroot/usr/lib/arm-linux-androideabi/21/ ``` ⚠️ 注意:这可能导致运行时崩溃,仅适用于编译测试 4. **推荐的标准修复方案**: ```bash # 清理旧配置 rm -rf /home/chang/dev/mpp/mpp_build # 重新配置时指定完整工具链参数 ./configure \ --cross-prefix=arm-linux-androideabi- \ --sysroot=/opt/android-ndk-r18b/sysroot \ --extra-cflags="-I/opt/android-ndk-r18b/sysroot/usr/include -march=armv7-a" \ --extra-ldflags="-L/opt/android-ndk-r18b/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/9.0.9/lib/linux/arm/" ``` 5. **NDK版本升级建议**: ```bash # 下载新版NDK (示例使用r25b) wget https://dl.google.com/android/repository/android-ndk-r25b-linux.zip unzip android-ndk-r25b-linux.zip -d /opt/ # 验证新NDK路径 find /opt/android-ndk-r25b -name crt1.o # 预期输出类似: # /opt/android-ndk-r25b/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/26/crt1.o ``` 6. **交叉编译验证测试**: ```bash # 创建测试文件 test.c echo -e '#include <stdio.h>\nint main(){printf("NDK test\\n");return 0;}' > test.c # 使用NDK工具链编译 /opt/android-ndk-r18b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang \ --target=armv7-none-linux-androideabi21 \ -pie -fPIE \ -o test test.c # 验证二进制格式 file test # 正确输出应包含:ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV) ``` 如果仍然存在问题,建议检查以下配置: ```bash # 查看环境变量污染 env | grep -E 'CROSS|TOOLCHAIN' # 确认库搜索路径 echo | clang -E -Wp,-v - 2>&1 | grep /usr/include ``` 最终建议优先考虑升级NDK版本,旧版r18b(2018年发布)对现代Android系统的兼容性支持已不足,新版NDK能更好地处理工具链路径问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值