首页 u-boot链接加载

u-boot链接加载

举报
开通vip

u-boot链接加载 U-boot链接加载 做了近两年 ARM下的驱动开发,常用的各个设备驱动基本都碰过,不过 Boot由于任务安排的缘故(公司一直有专人在做),一 直没有机会接触,从刚开始接触嵌入式的时候,就一直想弄清楚板子上电后,程序是怎么执行的,不过看了下公司 boot源码, 就很快放弃了,当时对汇编充满了畏惧,做了 1年多的驱动后,再看汇编感觉就没那边痛苦了,最近把 boot的资料整理下,把 我觉得 boot比较核心的部分,完整的看了一遍,现在做个记号。我把我觉得我之前比较困惑的难点整理出来,也许大家一起讨 论下,也...

u-boot链接加载
U-boot链接加载 做了近两年 ARM下的驱动开发,常用的各个设备驱动基本都碰过,不过 Boot由于任务安排的缘故(公司一直有专人在做),一 直没有机会接触,从刚开始接触嵌入式的时候,就一直想弄清楚板子上电后,程序是怎么执行的,不过看了下公司 boot源码, 就很快放弃了,当时对汇编充满了畏惧,做了 1年多的驱动后,再看汇编感觉就没那边痛苦了,最近把 boot的资料整理下,把 我觉得 boot比较核心的部分,完整的看了一遍,现在做个记号。我把我觉得我之前比较困惑的难点整理出来,也许大家一起讨 论下,也许和我一样的新手就可以少走些弯路。 BOOT的核心就是 relocate,目前见到的典型嵌入式系统,除了处理器,至少都有 ROM(norflash,nandflash)RAM(SDRAM), 一般把 Bootloader代码放在 norflash里面,而 nandflash因为本身硬件原因不能随机访问,一般只是用来放应用程序。在系 统加电或复位后,CPU通常由 CPU制造商预先安排上地址取指令。arm体系下一般都是 0x0地址取它的第一条指令,即 PC = 0开始。 和 boot紧密相关的个人觉得就是一下几点: 1.remap. remap比较简单,和MMU的功能可以看做是等价的,只是一般 remap地址估定为 0x0,网上有个帖子叫<>专门讲了它对 remap的理解,对 remap的作用是这样讲的: 当 ARM处理器上电或者 Reset之后,处理器 从 0x0取指。因此,必须保证系统上电时,0x0处有指令可以执行。所以,上电的时候,0x0地址处必定是 ROM或者 Flash (NOR)。但是,为了加快启动的速度,也方便可以更改异常向量 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf ,加快中断响应速度,往往把异常向量表映射到更快、更 宽(32bit/16bit)的 RAM中。但是异常向量表的开始地址是由 ARM架构决定的,必须位于 0x0处,因此,必须把 RAM映 射到 0x0。 文中提到了 ARM处理器 remap的三种情况,如下 1)如果处理器有专门的寄存器可以完成 Remap。那么 Remap是通过 Remap寄存器的相应 bit置 1完成的。 如 Atmel AT91xx 2)如果处理器没有专门的寄存器,但是memory的 bank控制寄存器可以用来配置 bank的起始地址,那么只要把 RAM的 起始地址编程为 0x0,也可以完成 remap。如 samsung s3c4510 . 3)如果上面两种机制都没有,那么 Remap就不要做了。因为处理器实现决定了 SDRAM对应的 bank地址是不能改变的。如 Samsung S3c2410. 不过我的看法有点稍微不一样,如果上面两种机制都没有,那么 Remap就不要做了,它给的典型例子是 Samsung S3c2410 , 2410虽然 sdram对应的 bank地址不能改变,但它有MMU功能,MMU可以起到 remap的作用,常用的最典型的应该是例 子 Samsung S3c44b0,它既没有mmu,SDRAM对应地址又没办法改变。顺便补充下除了 4510可以改变每个 bank的地 址,还有华邦的 w90P740(arm7),呵呵,我现在用的 U就是这款 U,可以把 bank的地址随意的设置。 2.relocate . relocate (地址重定位),个人觉得这个是 boot里面最麻烦也是最核心的部分,刚开始看 boot代码的时候,它简直是我的恶梦, 不知道大家分析 boot的源码 流程 快递问题件怎么处理流程河南自建厂房流程下载关于规范招聘需求审批流程制作流程表下载邮件下载流程设计 是否这样,也可能我大学不是计算机的,没学过编译原理(现在也没看过)对链接和加载一无所 知,有两个星期非常痛苦,就是不懂人家 boot里面的链接脚本为什么要那样写。网上关于 uboot的帖子很多,但对链接加载 这块,始终写的不详细,不知道是不是太过于基础了,高手都不愿意讲。最后自己找资料,发现其实一切痛苦的根源都是对链 接和加载不太清楚造成的,但个人感觉 boot除了初始化以外就是搬运程序,如何搬运?为什么要那样搬运都需要对硬件板的地 址分布很清楚,而这些都是链接决定的,所以非弄清楚不可! 1).我们为什么需要relocate ?经济方面,(nandflash和norflash 每兆价格相差悬殊),把boot代码放在norflash里面(为什 么不放在nandflash里面,因为nandflash读需要驱动支持,norflash可以直接访问),boot通常很小,只需要占用几十k的空 间,所以只需要很小的norflash芯片,这样很便宜,而应用程序通常很大,所以用价格低廉nandflash来储存。实际应用中, 通过执行boot程序,把nandflash里面代码和数据搬运到内存中来执行,这样比程序直接放在norflash里执行快。另外还有运 行速度方面的差别,程序在norflash里执行的速度远远小于在sdram中执行的速度,为了追求更高的速度,也需要relocate, 让程序在sdram里面执行 。 2).关于加载域(VMA)和运行域(LMA),杜春雷在它那本经典的<>一 关于书的成语关于读书的排比句社区图书漂流公约怎么写关于读书的小报汉书pdf 专门有一章来讲加载域和运行域 不一致的情况,但我当初接触了它的这些加载域和运行域后,看uboot的lds,uboot的lds没有设置LMA,只是设置了VMA,为 此我疑惑很久。直到耐心的看了那本链接器和加载器的书才豁然明白 ( http://bbs.chinaunix.net/viewthread.php?tid=817770),任何一个链接器和加载器的基本工作都非常简单: 将更抽象 的名字与更底层的名字绑定起来,好让程序员使用更抽象的名字编写代码。链接器的就是把源文件进行符号解析,把解析出来 的符号和地址的进行绑定,把全局变量、函数、标号等等这些符合和地址绑定起来。 3).boot上电后开始能够正确执行还有个很重要的原因,是要保证boot在系统加电或复位后最初执行的代码是跟地址无关的,(即 在代码搬运前所执行的代码是与地址无关),地址无关即地址无关代码生成的这个映象文件可以被放在内存中的任何一个地址上 运行。对于地址无关的代码,寻址是基于pc值的,在pc值上+/-一个偏移值,得到加载地址,如跳转指令B。当我们执行完代 码搬运,就需要跳到和地址相关的地方去执行,ldr pc,_start_armboot,执行这条程序相对偏编译加载指令,会让PC指向 _start_armboot地址上存放的地址中去,这时地址相关代码就开始运行了。因为在bin映象生成的时候(编译链接的时候), 就已经把 start_armboot 这个符号,和实际地址绑定在一起,当我们执行ldr pc,_start_armboot,程序就从ROM中跳到RAM 中执行了,但前提是我们进行了代码搬移,如果没有代码搬运而执行ldr pc,_start_armboot,相应的RAM中没有代码,程序 就马上飞掉了,所有我们在搬运之前不能执行地址相关代码,必须执行地址无关代码。 拿u-boot-1.1.4下的smdk2410来做例子,和smdk2410 board密切相关的就两个文件夹\board\smdk2410和 \cpu\arm920t,里面核心文件就u-boot.lds,config.mk,start.S。 ENTRY(_start) SECTIONS { . = 0x00000000;//从 0地址起始 . = ALIGN(4); .text : { cpu/arm920t/start.o (.text) *(.text) } . = ALIGN(4); .rodata : { *(.rodata) } . = ALIGN(4); .data : { *(.data) } . = ALIGN(4); .got : { *(.got) } . = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .; . = ALIGN(4); __bss_start = .;//为搬运代码提供的符号,来标明 bss段地址,方便 relocate .bss : { *(.bss) } _end = .; //定义整个 image的结束地址 } u-boot.lds 是链接脚本文件,我刚开始看这个链接脚本文件时,我疑惑很久,不明白 lds中 VMA= LMA(资料上很多链接脚本 包括我们公司项目里面自己写的 lds脚本是通过 AT命令设置过 LMA,这样看起来地址空间分配更清晰),而且整个 image 的 VMA按照 lds为基址为 0x0,而 2410芯片不能 remap,0x0地址是 ROM的区域,不是运行时 RAM的地址,我的理解是代 码段地址应该是指向该硬件板内存区域,设置 .text=TEXT_BASE 而不是 lds中的.text=0x0,这个疑点弄的我当时很郁闷, 想了很久也没想没有搞清楚 u-boot这样链接脚本都能让 boot跑起来,当我把编译出来的 bin烧到 norflash中,uboot居然 跑起来了,同时发现了一个问题,在 u-boot.map 中发现 .text 是从 config.mk 定义 TEXT_BASE =0x33f80000,而不 是 lds设置的 0x0,这又让我吃惊,没清楚是怎么会事,手上有介绍移植 uboot的资料,但都对 uboot链接这部分,写的不够 详细,知道是 config.mk文件搞的鬼,但把makefile文件看了几遍都没找不到是怎么回事(还是对makefile不熟啊!),最后 把编译 uboot的过程看了隐藏了个机关是 arm-linux-ld –Tu-boot-1.1.4\board\smdk2410\u-boot.lds –Ttext 0x33f80000 arm-linux-objcopy --gap-fill =0xff –O binary uboot ubtoot.bin 不知道 uboot 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 者为什么要在这里加一个–Ttext 而不是在 lds就设置?而很多移植 uboot的资料对 lds文件都有所描述, 但这个重要的细节似乎都漏掉了,不知道是不是因为太基础了,所以没有讲。 不过从最后生成的 bin上看 arm-linux-objcopy --gap-fill =0xff –O binary uboot ubtoot.bin没有对链接生成的 elf文件 进行重定位,因此它的运行地址是 config.mk 定义 TEXT_BASE为基地址,顺序按照 lds的顺序依次增加的,所以整个 uboot 最初运行的流程是 ◊ reset ◊_start ◊cpu_init_crit relocate 这个部分就是完成初始化,设 SVC32,关看门狗,关中断,设置时钟,初始化 SDRAM(为代码搬运到 SDRAM做准备),这些 都很简单 relocate: adr r0, _start ldr r1, _TEXT_BASE cmp r0, r1 beq stack_setup ldr r2, _armboot_start ldr r3, _bss_start sub r2, r3, r2 add r2, r0, r2 copy_loop: ldmia r0!, {r3-r10} stmia r1!, {r3-r10} cmp r0, r2 ble copy_loop 看了下网上的帖子,adr指令,网上很多人被这这个指令弄郁闷,我看杜春雷的<>P143讲,这个指 令是基于 PC或者寄存器的,读到是地址无关的,一般被编译器替换为 SUB r0, pc,#offset ,不要理解为读取符合表中_start 符号的地址(0x33f80000)。offset是在编译时就已经计算好的偏移量。接下来要用到链接时确定的符号地址了, _armboot_start(0x33f80000), _bss_start(0x33f97954)这些可以在 u-boot.map里面的看到, size of armboot =0x33f97954-0x33f80000 ,把_start:0x0 (norflsh)开始的 (.text)、(.data)代码和数据往 SDRAM里_TEXT_BASE 确定的地址(0x33f80000)搬运。s3c2410的 SDRAM基地址是 0x3000_0000,由于 uboot支持的这个 board SDRAM是 64M,(0x3000_0000---0x3400_0000),所以把 u-boot.bin搬运到内存的高端地址。然后跳到内存中执行,提高速度。 之后就 relocate RAM)◊ ldr pc, _start_armboot ( ROM◊ clear_bss ◊ stack_setup ◊ _start_armboot: .word start_armboot ( u-boot-1.1.4\lib_arm\board.c) stack_setup , clear_bss设置堆栈清 bss段,都是为进入 C语言做初始化准备,通过对 start_armboot链接后已经把 这个函数地址已经绑定在 RAM中,当执行完 ldr pc, label 指令,程序将从标号绑定地址开始执行,从而实现了从地址无关程 序到地址相关的转变,我们做代码搬移也是为了跳转做准备,如果没有搬移,直接访问地址相关,由于 RAM中都是随机值,一 跳转就马上飞了。当进入 start_armboot C函数,剩下的都没什么难度了。可以慢分析源码搞定。2410没有 remap寄存器, relocate时候要容易些,有 remap寄存器的芯片在 relocate时候进行 remap会让情况更复杂些。不过原理都差不多。在进 入 board.c后,uboot还做了一次代码搬运如下,大概如下图,不过分两种,一种是把宿主机传送的 image通过串口或者网 络传到内存开始执行,或者从 nandflash里把应用搬到内存开始执行,不过原理都差不多。 正好公司内部给我们做了板级初始化培训,把硬件板初始流程注意要点整理出来,和 boot这部分初始化对比,可以发现硬件板 初始化流程都差不多。比较头痛还是链接这部分,这方面的资料感觉太少了,没人可以指点,自己看这部分资料看的很痛苦。 ◊【CPU核相关初始化】 ◊【Watchdog初始化】 ◊【GPIO初始化】 ◊【系统时钟初始化】 ◊【内存初始化】 ◊【模式初始化】 ◊【中断向量初始化】 ◊【MMU初始化】 ◊【Cache初始化】 ◊【总线初始化】 ◊【语言相关初始化】 【设备相关初始化】 4.elf 格式和 bin格式 executable and linking format (ELF)重定位,可以参与程序的链接(创建一个程序)和程序的执行(运行一个程序),主要链接 和执行,但介绍 elf文件的资料很多,没时间仔细看,和实际密切的就是调试程序时候都用 elf格式调试,因为它包含了调试所 需的各种符号,固化的时候都是用的 bin格式,是可执行映象,用 objcopy 把 elf 转换成 bin ,不过网上介绍 bin格式的资 料很少,只是知道 bin程序,只要把 pc(程序指针)设置为 bin映象的入口地址,就可以正确执行, objcopy 可以对 elf 转 换成 bin再进行地址重定位,不过目前还没看见过这么干过,对于 elf和 bin这些理解的都不系统,资料也很少,工作中,集成 开发工具 IDE又把这些设置都给屏蔽起来,有没有那个强人能写一个文档,把这些都系统的讲清楚就好了! 顺便问下,论坛上上海的多不多,大家找工作都是在网上找的?有个MM拉我去上海,虽然对现在工作很满意,不过MM比工作更重 要,要我做选择,只有去上海了,不过在 51job上投了点简历,都石沉大海,按理说 2年也不短了,至少也会冒一个泡的,有没有上海 的能够指点下,你们在上海石怎么找相关工作的? 补充一个当时找资料看见对网上一个帖子,感觉写的很精辟的,关于地址无关的解释,网页地址被改成相当路径了,就没办法地址 粘贴出来,现在把原文粘贴出来. 关键词: 地址无关 术语 地址无关: 编译地址不等于运行地址. 地址相关: 编译地址等于运行地址. 常见的一些 Boot(如, U-Boot, VIVI)和 Linux Kernel代码开始的一段是位置无关的, 意思就是说运行地址与编译地址无关. 如, Kernel编译地址是 0xc0008000, 而运行地址是 0x30008000. 为什么? 为什么代码的编译地址和运行地址会不相等呢? 原因主要有以下几种: 1) 对于Boot, 用于存放Boot代码的存储器容量小于代 码量. 如, Boot片有 4K, 而代码通常有 50-60K. 这样, 通常会在前 4K代码里, 让 Boot把自己复制到 RAM, 再接着运行.这 里我们需要作出一个选择, 是让前面的代码与地址相关, 还是让后面的代码与地址相关呢? 显然我们会选择前面一段代码量小 的与地址无关. 2) 对于 Linux Kernel, 它是运行在虚拟地址空间的, 如 0xc0008000, 但在MMU打开之前, 通常这个地址是 不存在的, 也就是说在MMU打开之前, Kernel的代码必须是地址无关的. 怎么办? 对于位置无关的代码, 寻址是基于 pc值的, 在 pc值上+/-一个偏移值, 得到运行地址.以 ARM为例, 用 adr来寻址, adr的实 际上是一个宏指令, 在代码编译时, 会被编译器替换成对 pc的+/-运算 这里要注意, 对 pc的+/-运行显然是有一个地址范围的, 所以我们在上面选择代码量小的地址无关, 是很明智的. 而访问地址相关的代码, 只需要使用其它的寻址指令就行了. 但在这之前, 必须保证代码被放在正确的地址上, 所以通常都会 有一个复制代码的过程, 然后就是跳转到一个标号, 地址相关代码就开始运行了. 原文地址 http://blog.sina.com.cn/s/blog_4a9fb5cf01008d8u.html
本文档为【u-boot链接加载】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_306901
暂无简介~
格式:pdf
大小:127KB
软件:PDF阅读器
页数:5
分类:互联网
上传时间:2011-10-12
浏览量:24