首页 uboot代码剖析

uboot代码剖析

举报
开通vip

uboot代码剖析Uboot 代码剖析                                     黄雪莉 代码重定位 编译器在编译一段程序链接过程中,要对所有目标文件进行重定位,建立符号引用规则,同时为变量,函数等分配地址。程序执行时,把代码加载到链接时指定的地址空间,以保证程序在执行过程中对变量,函数等符号的正确引用,是程序正常运行。 但是在操作系统中,一个进程通常从硬盘等二级存储设备拷贝到内存中去执行,这两者的地址是不同的,因此操作系统要对这个进程进行重定位,才能正确运行该进程。 位置不相关代码: 在设计系统引导程...

uboot代码剖析
Uboot 代码剖析                                     黄雪莉 代码重定位 编译器在编译一段程序链接过程中,要对所有目标文件进行重定位,建立符号引用规则,同时为变量,函数等分配地址。程序执行时,把代码加载到链接时指定的地址空间,以保证程序在执行过程中对变量,函数等符号的正确引用,是程序正常运行。 但是在操作系统中,一个进程通常从硬盘等二级存储设备拷贝到内存中去执行,这两者的地址是不同的,因此操作系统要对这个进程进行重定位,才能正确运行该进程。 位置不相关代码: 在 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 系统引导程序如bootloader时,一般为了提高速度,需要将bootloader从ROM拷贝到RAM中去执行,这两者的地址也不同。如果这些代码即使不在链接时指定的地址空间也能正确运行,这就是位置无关代码(position independent code)。PIC的特点是,它被加载到任意地址空间都可以正确的执行。其原理是PIC对常量和函数入口地址的操作都是基于PC+偏移量的寻址方式。即使程序被移动,但是PC也变化了,而偏移量是不变的,所以程序仍然可以找到正确的入口地址或者常量。 位置代码无关在U-boot中的实现: U-Boot中用GOT 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf (Global Offset Table 全局偏移量表)实现PIC代码位置无关,总的来讲,U-Boot依靠维护GOT表来实现,在GOT表中存放一些全局label的表项,这些表项 记录 混凝土 养护记录下载土方回填监理旁站记录免费下载集备记录下载集备记录下载集备记录下载 重要的地址; 运行在Flash时,GOT表中存放的是编译时全局label的值(地址);当U-Boot运行时检测RAM大小进行代码搬运之后, 利用代码搬运前后产生的地址偏移对(相对偏移)GOT表中的各个表项值进行更新,使其记录RAM中的相应的地址。 这样代码运行时不会出现代码/变量地址出错的问题。 主要代码剖析 1.关于GOT的主要宏定义(include/ppc_asm.tmpl) #define START_GOT \ //定义 .got2段,GOT起始地址为 当前地址+0x8000 .section ".got2","aw"; \ .LCTOC1 = .+32768 #define END_GOT \ //got2段结束,text开始 .text //通过GET_GOT获得.got2段的起始地址 #define GET_GOT \ bl 1f ; \ .text 2 ; \ 0: .long .LCTOC1-1f ; \ .text ; \ 1: mflr r14 ; \ //r14存放的是标签1的地址 lwz r0,0b-1b(r14) ; \ //r0=0b-1b+1b=0b add r14,r0,r14 ;//r14= 0b+1b=.LCTOC1-1f +1f=.LCTOC1 //.L_NAME为相对于.got2的偏移, //NAME为 表项NAME的存储地址 // GOT_ENTRY的真正作用是将编译时全局lable (NAME)的值存储到GOT表中 #define GOT_ENTRY(NAME) .L_ ## NAME = . - .LCTOC1 ; .long NAME // GOT(NAME)获得NAME的存储地址 #define GOT(NAME) .L_ ## NAME (r14) 2. .got2段的声明 /*定义got2段,起始地址(.LCTOC1),段中各表项的起始地址以及相对GOT的地址*/ START_GOT GOT_ENTRY(_GOT2_TABLE_) GOT_ENTRY(_FIXUP_TABLE_) GOT_ENTRY(_start) GOT_ENTRY(_start_of_vectors) GOT_ENTRY(_end_of_vectors) GOT_ENTRY(transfer_to_handler) GOT_ENTRY(__init_end) GOT_ENTRY(_end) GOT_ENTRY(__bss_start) END_GOT//got2段结束 3.上电复位,从flash的起始地址读取硬件复位配置字HRCW(Hard Reset Configuration Word),每次都8位,每四次组成一个32位配置字,分别组成低32位配置字和高32位配置字,分别存放在CFG_HRCW_LOW 和CFG_HRCW_HIGH寄存器。 #define _HRCW_TABLE_ENTRY(w) \ .fill 8,1,(((w)>>24)&0xff); \ .fill 8,1,(((w)>>16)&0xff); \ .fill 8,1,(((w)>> 8)&0xff); \ .fill 8,1,(((w) )&0xff) _HRCW_TABLE_ENTRY(CFG_HRCW_LOW) _HRCW_TABLE_ENTRY(CFG_HRCW_HIGH) HRCW控制时钟及其他硬件的功能,如PCI host和Agent模式,启动位置和大小端。详细配置信息见MPC8313ERM.pdf第四章第三节 4.入口启动,u-boou.lds指定程序入口,ENTRY(_start) .globl _start _start: r21 < = BOOTFLAG_COLD // 从flash启动 r4<= CONFIG_DEFAULT_IMMR // =0xff40 0000,是immr base offset r5<= machine status register IMMRBAR(r4)<= CFG_IMMR //0xe00 0000,IMMRBAR:IMMR基地址寄存器 bl init_e300_core //初始化e300 processor core bl map_flash_by_law1 //通过Local Access Window 将整个boot ROM进行映射,以确保在跳转之后代码可以顺利到 text base r4<=CFG_MONITOR_BASE bl remap_flash_by_law0 bl setup_bats//将所有的BAT(data&instruction)都设置成初始状态 sync bl enable_addr_trans// 通过修改MSR的DR/IR使能address translation sync bl dcache_enable//通过修改硬件启动寄存器HID0使能data cache,同时是data cache flush操作无效 sync bl lock_ram_in_cache//data cach中分配以RAMCFG_INIT_RAM_ADDR为起始地址,以CFG_INIT_RAM_END为结束的ram,同时对这段空间进行清零,然后锁定 sync r1<= CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET//建立ram栈指针并将栈顶清零 GET_GOT /* initialize GOT access */ r3<=CFG_IMMR bl cpu_init_f /* run low-level CPU init code (in Flash)*/ mr r3, r21 // r3<= BOOTFLAG_COLD bl board_init_f // run 1st part of board init code (in Flash) 5.init_e300_core(start.S): ( 初始化机器状态寄存器; 使能机器检查中断machine check interrupt ( 跟据MSR更新 SRR1(save/restore register)参考7.7.1.3.3 ( 初始化Watchdog—修改SWCRR(system watchdog control register),并重置。参考5.4.4.1 ( 初始化硬件执行依赖寄存器(HID),设置HID0,详见表 7-2 ( 所有的BAT置零 ( 关闭所有的TLB(Translation lookaside buffer) entry 6.cpu_init_f(cpu/mpc83xx/cpu_ini.c) ( 对IMMR的一些寄存器进行设置,实现TSEC,复位寄存器,窗口映射和时钟模块等的设置。r3存放的是IMMR的值,作为cpu_int_f的传递参数(PowerPC中,r3-r10作为函数传递参数),结构类型为immap_t(定义在文件include/asm_ppc/immap_83xx.h). ( 设置对全局数据指针gd,并对其进行初始化.gd主要用来保存开发板信息、终端存在标志位、环境变量结构体起始地址、环境变量校验标志位、frame buffer 基地址等。它是指向gd_t 结构体的指针(gd_t定义在include/asm_ppc/global_data.h)。这里都初始化为0。 7.Board_init_f(lib_ppc/board.c) ( 初始化init_sequence中的各个函数 ✓ board_early_init_f:基本的板级相关配置,主要包括设置处理器类型和启动参数地址 ✓ get_clocks:获得并设置CPU 和BUS 时钟 ✓ init_timebase:初始化计数器; ✓ env_init:设置环境变量,初始化环境; ✓ init_baudrate:指定串口的波特率; ✓ serial_init:串口初始化设置;选择通讯端口,设置串口波特率和工作方式. ✓ console_init_f:设置gd->have_console=1,表示可以使用串口通讯控制台 ✓ display_banner:在控制台输出 U-boot 信息 ✓ checkcpu:检查CPU 版本信息 ✓ checkboard:检查board 信息 ✓ init_func_i2c:初始化i2c 接口 ✓ init_func_ram:初始化SDRAM ( 对gd进行设置,即对开发板信息(结构体bd_t定义在文件include/asm_ppc /u-boot.h 中)、终端存在标志位、环境变量结构体起始地址、环境变量校验标志位、frame buffer 基地址等进行赋值。 ( relocate_code (addr_sp, id, addr),将代码加载到的目的地址,addr_sp是相应的栈顶指针,id为全局数据变量gd. 8.relocate_code函数定义在start.S中 .globl relocate_code relocate_code: r4<= CFG_MONITOR_BASE=0xFE000000,源代码地址,text_base r5<=GOT(__init_end) –r4 , GOT获得_init_end,源代码结束地址,定义在u-boot.lds,故差是u-boot代码长度 r6<=CFG_CACHELINE_SIZE /* Cache Line Size,每次搬运32bit*/ // 更新 GOT pointer: New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE)+Destination Address r14<= r14+r10-r4 r0<=(r5+3)/4,每次搬运32bit,即4个字节,r0为将代码copy到ram的次数 mtctr r0 //将搬运次数,存放只计数器 若r0=0,则不需搬运代码,否则需要进行代码搬运 la r8,-4(r4) //r8<=r4-4 la r7,-4(r3) 1: lwzu r0,4(r8) stwu r0,4(r7)//代码搬运 bdnz 1b 然后在进行第二次搬运,并比较,如果发现不同,则表示搬运出错,退出 (注:当目的地址>源地址,则逆序搬运代码,而且不需要进行二次搬运和比较。不知道为什么这么做) //Flush the cache mr r4,r3 5: dcbst 0,r4 //有效地址EA=r4+0,将EA所在的cache行与 内存同步 add r4,r4,r6 cmplw r4,r5 blt 5b sync /* Wait for all dcbst to complete on bus */ mr r4,r3 6: icbi 0,r4 //有效地址EA=r4+0,将EA所在的指令cache行无效 add r4,r4,r6 cmplw r4,r5 blt 6b 7: sync /* Wait for all icbi to complete on bus */ isync /*此时 并不返回,而是跳转到board的第二部分的初始化,即in_ram(start.S), 此后代码在 RAM中运行 */ addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET //r10为目的地址 mtlr r0 blr 1. .globl    relocate_code 2. relocate_code:sss serial_init:串口初始化设置;选择通讯端口,设置串口波特率和工作方式,越早开通串口,对后面的工作越有好处; 9.in_ram(位于start.S中) in_ram: //r0<=GOT表项的个数in_ram: li r0,__got2_entries@sectoff@l//sectoff段中的__got2_entries的低半字,即GOT表项的个数 la r3, GOT(_GOT2_TABLE_) //r3<=.L_GOT2_TABLE_ + r14,GOT表在ram中的起始地址 lwz r11,GOT(_GOT2_TABLE_) //r11<=.L_GOT2_TABLE_(旧) + r14,GOT表在flash中的起始地址 mtctr r0//表项个数存入计数器 sub r11,r3,r11//偏移,注:r11=r11-r3 addi r3,r3,-4 1: lwzu r0,4(r3) add r0,r0,r11 stw r0,0(r3)//将flash中的GOT2表copy到ram bdnz 1b 2: li r0,__fixup_entries@sectoff@l//FIXUP表项个数 lwz r3,GOT(_FIXUP_TABLE_) cmpwi r0,0 mtctr r0 addi r3,r3,-4 beq 4f 3: lwzu r4,4(r3) lwzux r0,r4,r11 //fixup的偏移于got2的相同,可以根据他来计算fixup的flash的起始地址 add r0,r0,r11 stw r10,0(r3) stw r0,0(r4)//fixup表copy bdnz 3b 4: clear_bss: 代码略 mr r3, r9 /* Global Data pointer */ mr r4, r10 /* Destination Address */ bl board_init_r 10 .Board_init_r(lib_ppc/board.c): 调用一系列的初始化函数,初始化高速缓存器和本阶段所用到的外围硬件设备,主要调用了函数: ( watchdog_reset():复位看门狗; ( icache_enable():初始化I-Cache; ( unlock_ram_in_cache():解锁D-Cache; ( flash_init():初始化Nor Flash,使之支持写入、擦除功能; ( cpu_init_r ();对cpu的hiher level部分进行初始化 ( nand_init():初始化Nand Flash; ( console_init_r():再次初始化控制台串口; ( eth_initialize():初始化以太网口; ( main_loop():检查delay时间,若在期间没有按键,则启动操作系统内核
本文档为【uboot代码剖析】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_005190
暂无简介~
格式:doc
大小:42KB
软件:Word
页数:0
分类:生活休闲
上传时间:2017-09-19
浏览量:22