file-type

理解bootloader与Linux中的位置无关代码(PIC)

5星 · 超过95%的资源 | 下载需积分: 50 | 85KB | 更新于2024-11-20 | 11 浏览量 | 14 下载量 举报 收藏
download 立即下载
"该文主要探讨了bootloader与Linux系统中的位置无关代码(Position Independent Code,简称PIC),并以u-boot和vivi两个bootloader为例进行了深入分析。文章首先介绍了加载域与运行域的概念,解释了为何需要这两个概念,并通过norflash到RAM的代码执行例子进行说明。此外,文章还讨论了链接地址的重要性以及相对跳转指令如何实现位置无关性。" 文章的核心知识点包括: 1. **加载域与运行域**:加载域是指代码在存储介质(如norflash)中的地址,而运行域则是代码实际执行时的内存地址(如RAM)。这种分离是因为某些代码需要在不同的地方运行,比如从非易失性存储加载到RAM中执行。 2. **链接地址与位置无关代码(PIC)**:链接地址是链接器分配给代码、变量和函数的实际地址。位置无关代码(PIC)是指不依赖于绝对地址的代码,它使用相对寻址而非绝对寻址,使得代码可以在内存中的任何位置正确执行。PIC的关键在于能够适应不同的加载和运行地址。 3. **汇编指令的相对跳转**:汇编指令如b、bl进行相对地址跳转,而不是绝对地址。例如,b main指令实际上是计算main标签相对于当前指令的偏移量,而不是main的绝对地址,这使得包含这些指令的代码段可以在不同位置运行。 4. **u-boot中的PIC应用**:在u-boot的start.S文件中,可以看到使用了位置无关的代码设计,如全局符号_start和相对指令ldrp,这些设计确保了u-boot在不同地址加载时仍能正常启动。 5. ** PIC的重要性**:对于可移植性和内存管理,特别是在动态链接和共享库的情况下,使用位置无关代码是必要的。在嵌入式系统中,如u-boot和vivi这样的bootloader,为了能在多种硬件配置下工作,通常需要实现位置无关。 6. **PIC的限制**:尽管PIC提供了灵活性,但使用绝对寻址指令会使代码变得位置有关。因此,在编写需要位置无关性的代码时,应避免使用绝对寻址。 7. **特定平台考虑**:文中提到分析基于mini2440的板子及配套代码,这意味着其他平台或代码可能有不同的实现方式和考虑。 8. **vivi部分的分析**:虽然未提供vivi的具体代码,但可以推断文章会进一步分析vivi如何实现位置无关代码,以及与u-boot在处理PIC方面的异同。 这篇文章不仅讲解了位置无关代码的基本原理,还通过具体的bootloader实例展示了其在实际系统中的应用。理解这些概念对于开发和调试嵌入式系统,尤其是Linux系统的引导过程至关重要。

相关推荐

filetype

ENTRY(stext) ARM_BE8(setend be ) @ ensure we are in BE8 mode THUMB( adr r9, BSYM(1f) ) @ Kernel is always entered in ARM. THUMB( bx r9 ) @ If this is a Thumb-2 kernel, THUMB( .thumb ) @ switch to Thumb now. THUMB(1: ) #ifdef CONFIG_ARM_VIRT_EXT bl __hyp_stub_install #endif @ ensure svc mode and all interrupts masked safe_svcmode_maskall r9 mrc p15, 0, r9, c0, c0 @ get processor id bl __lookup_processor_type @ r5=procinfo r9=cpuid movs r10, r5 @ invalid processor (r5=0)? THUMB( it eq ) @ force fixup-able long branch encoding beq __error_p @ yes, error 'p' #ifdef CONFIG_ARM_LPAE mrc p15, 0, r3, c0, c1, 4 @ read ID_MMFR0 and r3, r3, #0xf @ extract VMSA support cmp r3, #5 @ long-descriptor translation table format? THUMB( it lo ) @ force fixup-able long branch encoding blo __error_lpae @ only classic page table format #endif #ifndef CONFIG_XIP_KERNEL adr r3, 2f ldmia r3, {r4, r8} sub r4, r3, r4 @ (PHYS_OFFSET - PAGE_OFFSET) add r8, r8, r4 @ PHYS_OFFSET #else ldr r8, =PLAT_PHYS_OFFSET @ always constant in this case #endif /* * r1 = machine no, r2 = atags or dtb, * r8 = phys_offset, r9 = cpuid, r10 = procinfo */ bl __vet_atags #ifdef CONFIG_SMP_ON_UP bl __fixup_smp #endif #ifdef CONFIG_ARM_PATCH_PHYS_VIRT bl __fixup_pv_table #endif bl __create_page_tables /* * The following calls CPU specific code in a position independent * manner. See arch/arm/mm/proc-*.S for details. r10 = base of * xxx_proc_info structure selected by __lookup_processor_type * above. On return, the CPU will be ready for the MMU to be * turned on, and r0 will hold the CPU control register value. */ ldr r13, =__mmap_switched @ address to jump to after @ mmu has been enabled adr lr, BSYM(1f) @ return (PIC) address mov r8, r4 @ set TTBR1 to swapper_pg_dir ldr r12, [r10, #PROCINFO_INITFUNC] add r12, r12, r10 ret r12 1: b __enable_mmu ENDPROC(stext)

philipyu
  • 粉丝: 3
上传资源 快速赚钱