bootloader与linux中位置无关代码(PIC)的分析理解
### bootloader与Linux中位置无关代码(PIC)的分析理解 #### 一、基本概念解析 在深入探讨位置无关代码(Position Independent Code, PIC)之前,我们需要先了解几个基础概念: 1. **加载域与运行域**: - 加载域(Load Address):指的是代码在存储器中的实际存放地址。 - 运行域(Execution Address):指的是代码在执行过程中所处的实际地址。 - 在某些情况下,代码的加载域与运行域可能会不一致。例如,代码最初可能被存储在NOR Flash中,但在运行时会被复制到RAM中。 2. **链接地址**: - 链接地址是链接器为程序中的变量名、函数名等分配的地址。它是编译器和链接器用来确保程序能够正确访问这些标识符的一种机制。 3. **绝对地址与相对地址**: - 绝对地址是指代码或数据的具体内存地址。 - 相对地址是指相对于当前指令或位置的偏移量。在程序执行过程中,这种偏移量是相对于指令当前位置计算出来的。 #### 二、位置无关代码(PIC)简介 位置无关代码是一种特殊的编程技术,使得代码可以在不同的内存位置上运行而不影响其功能。在嵌入式系统中,这一点尤为重要,因为内存资源通常有限,且代码可能需要在不同的地址空间中运行。 1. **PIC的重要性**: - 提高代码的灵活性和可重用性。 - 允许代码在不同的内存位置运行,有助于优化内存使用。 2. **如何实现PIC**: - 使用相对地址而非绝对地址。 - 避免直接引用特定内存地址,转而使用寄存器或其他间接方式来访问内存。 - 在链接时或运行时进行必要的地址调整。 #### 三、U-Boot 中的 PIC 实现 接下来,我们将通过分析 U-Boot 的启动代码来进一步理解位置无关代码的实现。 ##### 代码片段分析 以下是从 `u-boot-1.1.2\cpu\arm920t\start.S` 文件中截取的部分相关代码: ```assembly 1 .globl _start 2 _start: 3 b reset 4 ldr pc, _undefined_instruction 5 ldr pc, _software_interrupt 6 ldr pc, _irq 7 ldr pc, _fiq 8 9 reset: 10 mrs r0,cpsr 11 bic r0,r0,#0x1f 12 orr r0,r0,#0xd3 13 bl cpu_init_crit 14 15 relocate: /* relocate U-Boot to RAM */ 16 adr r0, _start /* r0 <- current position of code */ 17 ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ 18 cmp r0, r1 /* don't reloc during debug */ 19 beq stack_setup 20 ldr r2, _armboot_start 21 ldr r3, _bss_start 22 sub r2, r3, r2 /* r2 <- size of armboot */ 23 add r2, r0, r2 /* r2 <- source end address */ 24 25 copy_loop: 26 ldmia r0!, {r3-r10} /* copy from source address [r0] */ 27 stmia r1!, {r3-r10} /* copy to target address [r1] */ 28 cmp r0, r2 /* until source end address [r2] */ 29 ble copy_loop 30 31 /* Set up the stack */ 32 stack_setup: 33 ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ 34 sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ 35 sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ ``` 1. **_start**: - `_start` 是 U-Boot 的入口点,它通过跳转到 `reset` 函数开始初始化过程。 2. **relocate: /* relocate U-Boot to RAM */**: - 此段代码用于将 U-Boot 从其初始加载位置(通常是 Flash 存储器)复制到 RAM 中,并重新定位所有相关的地址。 - `adr r0, _start`:获取 `_start` 的地址,即当前代码的位置。 - `ldr r1, _TEXT_BASE`:加载 `_TEXT_BASE` 的值,该值表示 U-Boot 是否在 Flash 或 RAM 中运行。 - `cmp r0, r1` 和 `beq stack_setup`:如果 U-Boot 已经在 RAM 中运行,则跳过重定位步骤并继续进行栈设置。 - 接下来的指令将 U-Boot 的代码段从 Flash 复制到 RAM,并更新相应的地址。 3. **stack_setup: /* Set up the stack */**: - 完成 U-Boot 的重定位后,设置了栈指针。栈设置对于后续的函数调用至关重要,确保有足够的空间用于函数调用时的局部变量和返回地址。 #### 四、VIVI 中的 PIC 实现 虽然题目描述中提到了 VIVI,但给定的部分内容中并未涉及 VIVI 的具体代码示例。然而,VIVI 作为一个流行的嵌入式 Linux 引导加载程序,在其实现中也广泛应用了位置无关代码的技术。 1. **VIVI 中的 PIC 实现策略**: - VIVI 采用类似的方法来实现位置无关代码,主要是在引导加载阶段通过重定位表来调整代码和数据的地址。 - 使用相对地址代替绝对地址,确保代码可以在不同的内存位置上运行。 2. **VIVI 的重定位过程**: - VIVI 在启动时也会检查其加载位置,并根据需要进行重定位。 - 通常情况下,VIVI 会将自己从 Flash 中复制到 RAM 中,并更新所有相关的地址信息,以便于在 RAM 中高效地运行。 #### 五、结论 通过对 U-Boot 和 VIVI 的分析,我们可以看出位置无关代码(PIC)在嵌入式系统中的重要性和实用性。通过使用相对地址、重定位表等技术手段,可以使代码更加灵活,提高系统的整体性能和可靠性。在未来的设计和开发中,位置无关代码的应用将会越来越广泛。
- dragon1dragon22013-01-23解释的挺详细的,学习了。
- 粉丝: 3
- 资源: 12
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 5G建设和AI技术推动下,中证5G通信ETF的投资价值探讨
- Python项目之淘宝模拟登录.zip
- 课程设计项目:python+QT实现的小型编译器.zip
- (源码)基于AVR ATmega644的智能卡AES解密系统.zip
- (源码)基于C++插件框架的计算与打印系统.zip
- (源码)基于Spring Boot和Vue的苍穹外卖管理系统.zip
- (源码)基于wxWidgets库的QMiniIDE游戏开发环境管理系统.zip
- 通过C++实现原型模式(Prototype Pattern).rar
- 学习记录111111111111111111111111
- 通过java实现原型模式(Prototype Pattern).rar