




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、大多数bootloader 都分为stagel和stage2两部分,u-boot也不例外。依赖于 CPU体系结构的代码(如设备初始化代码等)通常都放在 stage1 且可以用汇编语言来实现,而 stage2 则通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。1 、 Stage1 代码结构u-boot 的 stage1 代码通常放在文件中,他用汇编语言写成,其主要代码部分如下:(1 )定义入口。由于一个可执行的 Image 必须有一个入口点,并且只能有一个全局入口, 通常这个入口放在 RO(MFlash )的 0x0 地址, 因此, 必须通知编译器以使其知道这个入口, 该
2、工作可通过修改连接器脚本来完成。(2)设置异常向量( Exception Vector )。(3)设置CPU的速度、时钟频率及终端控制寄存器。( 4 )初始化内存控制器。(5 )将ROM中的程序复制到 RAM中。( 6 )初始化堆栈。(7)转到RAM中执行,该工作可使用指令Idr pc来完成。2、Stage2 C 语言代码部分lib_arm/中的start arm boot是C语言开始的函数也是整个启动代码中C语言的主函数,同时还是整个 u-boot ( armboot )的主函数,该函数只要完成如下操作:(1)调用一系列的初始化函数。( 2)初始化 Flash 设备。( 3)初始化系统内存分
3、配函数。(4)如果目标系统拥有 NAN蛮备,则初始化 NAN蛮备。( 5)如果目标系统有显示设备,则初始化该类设备。(6) 初始化相关网络设备,填写IP、MAC地址等。(7) 进去命令循环(即整个boot 的工作循环) ,接受用户从串口输入的命令,然后进行相 应的工作。3、U-Boot 的启动顺序 ( 示例,其他 u-boot 版本类似 ) cpu/arm920t/文件包含处理#include 由顶层的 mkconfig 生成, 其中只包含了一个文件: configs/.h#include #include /* Jump vector table as in table in 1*/注:AR
4、M微处理器支持字节(8位)、半字(16位)、字(32位)3种数据类型向量跳转表,每条占四个字节(一个字),地址范围为 0x0000 00000x0000 0020AR体系结构规定在上电复位后的起始位置,必须有8条连续的跳专指令,通过硬件实现。他们就是异常向量表。ARM在上电复位后, 巷从0x00000000开始启动的,其实如果 bootloader 存在,在执行下面第一条指令后,就无条件跳转到start_code ,下面一部分并没 执行。设置异常向量表的作用是识别bootloader。以后系统每当有异常出现,贝U CPU会根据异常号,从内存的0x00000000 处开始查表 做相应的处理/*;
5、当一个异常出现以后,ARM会自动执行以下几个步骤:;1.把下一条指令的地址放到连接寄存器LR(通常是R14).-保存位置;2.将相应的 CPSR当前程序状态寄存器)复制到SPSR备份的程序状态寄存器 )中-保存CPSR3根据异常类型,强制设置CPSR的运行模式位;4.强制PC(程序计数器)从相关异常向量地址取出下一条指令执行,从而跳转到相应的异常处理程序中*/.globl _start /* 系统复位位置 , 整个程序入口 */_start是GNU汇编器的默认入口标签,.globl将_start 声明为外部程序可访问的标签,.globl是GNU匚编的保留关键字,前面加点是GNU匚编的语法_st
6、art: b start_code 0x00ARMt电后执行的第一条指令,也即复位向量,跳转到 start_codereset用b,就是因为reset在MMU建立前后都有可能发生鎭他的异常只有在 MMU建立之后才会发生ldr pc, _un defi ned_in structi on /*未定义指令异常 ,0x04*/ldr pc, _prefetch_abort /* 内存操作异常 ,0x0c*/ldr pc, _data_abort /* 数据异常 ,0x10*/ldr pc, _not_used /* 未适用 ,0x14*/ldr pc, _irq /*慢速中断异常 ,0x18*/ld
7、r pc, _fiq /*快速中断异常 ,0x1c*/寸于ARM数据从内存到 CPU之间的移动只能通过 L/S指令,如:ldr rO,Ox为把Ox内存中 的数据写到rO中,还有一个就是ldr伪指令,女如: ldr rO,=Ox为把Ox地址写到rO中,mov 只能完成寄存器间数据的移动,而且立即数长度限制在 8 位_undefined_instruction: .word undefined_instruction_software_interrupt: .word software_interrupt_prefetch_abort: .word prefetch_abort_data_abor
8、t: .word data_abort_not_used: .word not_used_irq: .word irq_fiq: .word fiq.word为GNU ARMC编特有的伪操作,为分配一段字内存单元(分配的单元为字对齐的),可以使用.word把标志符作为常量使用。如_fiq:.word fiq即把fiq存入内存变量_fiq中, 也即是把 fiq 放到地址 _fiq 中。.balignl 16,Oxdeadbeef.balig nl 是.balig n的变体 .align 伪操作用于表示对齐方式:通过添加填充字节使当前位置满足一定的对齐方式。 .balign 的作用同 .align
9、 。 .align alignment ,fill ,max 其中: alignment 用于指定对齐方式,可能的取值为 2 的次幂,缺省为4。fill是填充内容,缺省用 0填充。max是填充字节矽最大值,如果填充字节数超过 max, 就不进行对齐 , 例如: .align 4 /* 指定对齐方式为字对齐 */参考好野人的窝,于关 u-boot 中的 .balignl 16,0xdeadbeef的理解】/* Startup Code (called from the ARM reset exception vector)* do important init only if we dont s
10、tart from memory!* relocate armboot to ram* setup stack* jump to second stage*保存变量的数据区,保存一些全局变量,用于BOOT程序从FLASH拷贝到RAM或者其它的使用。还有一些变量的长度是通过连接脚本里得到, 实际上由编译器算出来的_TEXT_BASE:因为 linux 开始地址是 Ox,我这里是 64M SDRAM所以 TEXT_BASE = 0x33F80000?.word TEXT_BASE /*uboot 映像在 SDRAM中 的重定位地址 */TEXT_BAS在开发板相关的目录中的文档中定义,他定C了代码
11、在运行时所在的地址,那么_TEXT_BAS冲保存了这个地t (这个TEXT_BAS怎么来的还不清楚).globl _armboot_start_armboot_start:.word _start 用 _start 来初始化 _armboot_start 。(为什么要这么定义一下还不明白)/* * These are defined in the board-specific linker script.*/下面这些是定义在开发板目录链接脚本中的.globl _bss_start_bss_start:.word _bss_start标号所在的地_bss_start 定义在和开发板相关的中, _
12、bss_start 保存的是 _bss_start 址。.globl _bss_end_bss_end:.word _end同上,这样赋值是因为代码所在地址非编译时的地址,直接取得该标号对应地址。中断的堆栈设置#ifdef CONFIG_USE_IRQ/* IRQ stack memory (calculated at run-time) */.globl IRQ_STACK_STARTIRQ_STACK_START: .word 0x0badc0de/* IRQ stack memory (calculated at run-time) */ .globl FIQ_STACK_STARTFI
13、Q_STACK_START:.word 0x0badc0de#endif/* the actual start code*/复位后执行程序薛正的初始化从这里开始了。其实在CPU上电以后就是跳到这里执行的reset:/* set the cpu to SVC32 mode*/更改处理器模式为管理模式对状态寄存器的修改要按照:读出- 修改- 写回的顺序来执行31 30 29 28 - 7 6 - 4 3 2 1 0 N Z C V I F M4 M3 M2 M1 M0 0 0 0 0 0 User26 模式 0 0 0 0 1 FIQ26 模式 0 0 0 1 0 IRQ26 模式 0 0 0 1
14、 1 SVC26 模式1 0 0 0 0 User 模式1 0 0 0 1 FIQ模式1 0 0 1 0 IRQ 模式1 0 0 1 1 SVC 模式1 0 1 1 1 ABT 模式1 1 0 1 1 UND 模式1 1 1 1 1 SYS 模式mrs r0,cpsr将 cpsr 的值读到 r0 中bic r0,r0,#0x1f清除 M0M4orr r0,r0,#0xd3禁止 IRQ,FIQ 中断,并将处理器置于管理模式msr cpsr,r0以下是点灯了,这里应该会牵涉到硬件设置,移植的时候应该可以不要bl coloured_LED_initbl red_LED_on针对AT91RM920Q进
15、行特殊处理#if defined(CONFIG_AT91RM9200DK) | defined(CONFIG_AT91RM9200EK)/* * relocate exception table*/ ldr r0, =_startldr r1, =0x0mov r2, #16copyex:subs r2, r2, #1sub带上了 s用来更改进位标志,对于sub来说,若发生借位则C标志置0,没有则为1,这跟 adds 指令相反!要注意。ldr r3, r0, #4str r3, r1, #4bne copyex#endif酚对S3C2400和S3C2410进行特殊处理CONFIG_S3C240
16、0CONFIG_S3C241等定义在include/configs/下不同开发板的头文件中#if defined(CONFIG_S3C2400) | defined(CONFIG_S3C2410)/* turn off the watchdog */关闭看门狗定时器的自动复位功能并屏蔽所有中断,上电后看门狗为开,中断为关# if defined(CONFIG_S3C2400)# define pWTCON 0x# define INTMSK 0x /* Interupt-Controller base addresses */# define CLKDIVN 0x /* clock divis
17、or register */#else s3c2410 的配置# define pWTCON 0xpWTCO定义为看门狗控制寄存器的地址(S3C2410和S3C2440相同)# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */INTMS定义为主中断屏蔽寄存器的地址(S3C2410和s3c2440相同)# define INTSUBMSK 0x4A00001CINTSUBMS定义为副中断屏蔽寄存器的地址(S3C2410和s3c2440相同)# define CLKDIVN 0x4C000014 /* CloCk d
18、iviSor regiSter */CLKDIV定义为时钟分频控制寄存器的地址(S3C2410和s3c2440相同)# endif至此寄存器地址设置完毕ldr r0, =pWTCONmov r1, #0x0Str r1, r0寸于S3C2440和S3C2410的WTCO寄存器的0控制允许或禁止看门狗定时器的复位输出功 能,设置为“ 0”禁止复位功能。/* maSk all IRQS by Setting all bitS in the INTMR - default*/mov r1, #0xffffffffldr r0, =INTMSKStr r1, r0# if defined(CONFIG
19、_S3C2410)ldr r1, =0x3ff 2410 好像应该为 7ff 才寸(不理解 uboot 为何是这个数字)ldr r0, =INTSUBMSKstr r1, r0 # endif寸于S3C2410的INTMSK寄存器的32位和INTSUBMS寄存器的低11位每一位对应一个中断,相应位置“1”为不响应相应的中断。 对于S3C2440的INTSUBMSI有 15位可用,所以应该为0x7fff 了。/* FCLI:HCLI:PCLI = 1:2:4 */* default FCLI is 120 MHz ! */ldr r0, =CLIDIVNmov r1, #3str r1, r0寸
20、钟分频设置,FCLK为核心提供时钟,HCLK为AHB( ARM920T内存妙制器,中断控制器,LCD控制器,DMA和主USB模块)提供时钟,PCLI为APB (看门狗、IIS、I2C、PWM MMCADC UART GPIO RTC SPI)提供时钟。分频数一般选择 1: 4: 8,所以 HDIVN=2,PDIVN=1,CLKDIVN=5这里仅仅是配置了分频寄存器,3纳出CLKDIVN的值跟分频的关系:0x0 = 1:1:1 , 0x1 = 1:1:2 , 0x2 = 1:2:2 , 0x3 = 1:2:4, 0x4 = 1:4:4, 0x5 = 1:4:8,0x6 = 1:3:3,0x7 =
21、 1:3:6S3C2440勺输出时钟计算式为:Mpll=(2*m*Fi n)/(p*2S)S3C2410 的输出时钟计算式为:Mpll=(m*Fi n)/(p*2As)m=M(the value for divider M)+8;p=P(the value for divider P)+2M,P,S 的选择根据 datasheet 中 PLL VALUE SELECTION TABLE表格进行,我的开发板晶振为,所以输出频率选为:的话 M=0x6e,P=3,S=1s3c2440增加了摄像头,其FCLK、HCLK PCLK的分频数还受到CAMDIVN9(默认为0),CAMDIVN8 (默认为 0
22、)的影响#endif /* CONFIG_S3C2400 | CONFIG_S3C2410 */* we do sys-critical inits only at reboot,* not when booting from ram!*/选择是否初始化 CPU#ifndef CONFIG_SKIP_LOWLEVEL_INITbl cpu_init_crit妙行CPU初始化,BL完成跳转的同时会把后面紧跟的一条指令地址保存到连接寄存器LR(R14)中。以使子程序执行完后正常返回。#endif酬试阶段的代码是直接在RAM中运行的,而最后需要把这些代码固化到Flash中,因此U-Boot 需要自己
23、从 Flash 转移到RA中运行,这也是重定向的目的所在。通过 adr 指令得到当前代码的地址信息:如果U-boot 是从 RAM 开始运行,则从adr,r0,_start 得到的地址信息为r0=_start=_TEXT_BASE=TEXT_BASE=0x33F80000ffl果 U-boot 从 Flash 开始运行,即从处 理器对应的地址运行,则 r0=0x0000, 这时将会执行 copy_loop 标识的那段代码了。 _TEXT_BASE定义在 board/smdk2410/ 中#ifndef CONFIG_SKIP_RELOCATE_UBOOTrelocate: /* relocat
24、e U-Boot to RAM */ adr r0, _start /* r0 - current position of code */ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ cmp r0, r1 /* dont reloc during debug */ beq stack_setupldr r2, _armboot_start_armboot_start 为 _start 地址ldr r3, _bss_start_bss_start 为数据段地址sub r2, r3, r2 /* r2 - size of arm
25、boot */add r2, r0, r2 /* r2 - source end address */ copy_loop:ldmia r0!, r3-r10 /* copy from source address r0 */ 从源地址 r0 读取 8 个字节到寄存器 , 每读一个就更新一次 r0 地址ldmia:r0 安字节增长stmia r1!, r3-r10 /* copy to target address r1 */LDM(STM)于在寄存器所指的一片连续存储器和寄存器列表的寄存器间进行数据移动,或是进行压栈和出栈操作。格式为:LDM(STM)条件类型基址寄存器 ! ,寄存器列表 仔
26、对于类型有以下几种情况:IA 每次传送后地址加 1,用于移动数据块IB 每次传送前地址加 1,用于移动数据块DA 每次传送后地址减 1,用于移动数据块DB 每次传送前地址减 1,用于移动数据块FD 满递减堆栈,用于操作堆栈(即先移动指针再操作数据,相当于DB)ED 空递减堆栈,用于操作堆栈(即先操作数据再移动指针,相当于DA)FA 满递增堆栈,用于操作堆栈(即先移动指针再操作数据,相当于IB )EA 空递增堆栈,用于操作堆栈(即先操作数据再移动指针,相当于IA )(这里是不是应该要涉及到NAND或者NOR的读写没有看出来)cmp r0, r2 /* until source end addre
27、ee r2 */ble copy_loop#endif /* CONFIG_SKIP_RELOCATE_UBOOT */* Set up the stack */初始化堆栈stack_setup:ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */获取分配区域起始指针,sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */CFG_MALLOC_LEN=128*1024+CFG_ENV_SIZE=128*1024+0x10000=192K用来存储开发板sub r0, r0, #CONFIG
28、_SYS_GBL_DATA_SIZE /* bdinfo */CFG_GBL_DATA_SIZE 128-size in bytes reserved for initial data信息#ifdef CONFIG_USE_IRQ这里如果需要使用 IRQ, 还有给 IRQ 保留堆栈空间 , 一般不使用 . sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endifsub sp, r0, #12 /* leave 3 words for abort-stack */该部分将未初始化数据段 _bss_start_bss_end 中
29、的数据 清零clear_bss:ldr r0, _bss_start /* find start of bss segment */ldr r1, _bss_end /* stop here */mov r2, #0x00000000 /* clear */ clbss_l:str r2, r0 /* clear loop. */add r0, r0, #4cmp r0, r1ble clbss_l跳到阶段二 C 语言中去ldr pc, _start_armboot_start_armboot: .word start_armbootC语言start_armboot 在 /lib_arm/ 中
30、,到这里因该是第一阶段已经完成了吧,下面就要去 中执行第二阶段了吧/* CPU_init_critical registers* setup important registers* setup memory timing*/CP初始化在“ relocate: /* relocate U-Boot to RAM */”之前被调用#ifndef CONFIG_SKIP_LOWLEVEL_INITcpu_init_crit:/* flush v4 I/D caches*/初始化 CACHESmov r0, #0mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cac
31、he */mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */* disable MMU stuff and caches*/关闭 MMI和 CACHESmrc p15, 0, r0, c1, c0, 0bic r0, r0, #0x00002300 clear bits 13, 9:8 (-V- -RS) bic r0, r0, #0x00000087 clear bits 7, 2:0 (B- -CAM) orr r0, r0, #0x00000002 set bit 2 (A) Align orr r0, r0, #0x00001000 set bit
32、 12 (I) I-Cache mcr p15, 0, r0, c1, c0, 0 对协处理器的操作还是看不懂,暂时先不管吧,有时间研究一下 部分。/* before relocating, we have to setup RAM timing* because memory timing is board-dependend, you will* find a in your board directory.*/初始化RAM寸钟,因为内存是跟开发板密切相关的,所以这部分在 mov ip, lr保存LR,以便正常返回,注意前面是通过 BL跳到cpu_init_crit ( ARM9有 37
33、个寄存器,ARM7有 27 个)37个寄存器=7个未分组寄存器(R0R7) + 2X ( 5个分组寄存器 R14=lr 分组寄存器) + 1(R15=PC) +1(CPSR) + 5(SPSR) 用途和访问权限:R(R7:USR(用户模式)、fiq (快速中断模式)、irq (中断模式)、ARM技术手册的协处理器/ 开发板目录 / 中实现来的。R8R12) +6X 2( R13=SPsvc (超级用法模式)、abt、undR8R12: R8_usr R12_usr (usr , irq , svc , abt , und)R8_fiq R12_fiq (fiq )R11=fpR12=IP(从反
34、汇编上看,fp和ip 一般用于存放 SP的值)R13R14: R13_usr R14_usr( 每种模式都有自己的寄存器 )SP lr : R13_fiq R14_fiqR13_irq R14_irqR13_svc R14_svcR13_abt R14_abtR13_und R14_undR15(PC):都可以访问(即 PC的值为当前指令的地址值加8个字节)R16 :( (Current Program Status Register ,当前程序状态寄存器 ) )SPSR _fiq,SPSR_irq,SPSR_abt,SPSR_und(USR 模式没有 )#if defined(CONFIG_
35、AT91RM9200EK)#elsebl lowlevel_init在重定向代码之前,必须初始化内存时序,因为重定向时需要将flash 中的代码复制到内存中 lowlevel_init 在 /board/smdk2410/ 中。#endifmov lr, ip mov pc, lr返回到主程序#endif /* CONFIG_SKIP_LOWLEVEL_INIT */* Interrupt handling*/这段没有看明白,不过好像跟移植关系不是很大,先放一放。 IRQ stack frame.#define S_FRAME_SIZE 72#define S_OLD_R0 68#define
36、 S_PSR 64#define S_PC 60#define S_LR 56 #define S_SP 52#define S_IP 48 #define S_FP 44#define S_R10 40#define S_R9 36#define S_R8 32#define S_R7 28#define S_R6 24#define S_R5 20#define S_R4 16#define S_R3 12#define S_R2 8#define S_R1 4#define S_R0 0#define MODE_SVC 0x13#define I_BIT 0x80/* use bad_s
37、ave_user_regs for abort/prefetch/undef/swi .* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling*/.macro bad_save_user_regssub sp, sp, #S_FRAME_SIZEstmia sp, r0 - r12 Calling r0-r12ldr r2, _armboot_startsub r2, r2, #(CONFIG_STACKSIZE)sub r2, r2, #(CONFIG_SYS_MALLOC_LEN)sub r2, r2, #
38、(CONFIG_SYS_GBL_DATA_SIZE+8) set base 2 words into abort stackldmia r2, r2 - r3 get pc, cpsradd r0, sp, #S_FRAME_SIZE restore sp_SVCadd r5, sp, #S_SPmov r1, lrstmia r5, r0 - r3 save sp_SVC, lr_SVC, pc, cpsrmov r0, sp.endm.macro irq_save_user_regssub sp, sp, #S_FRAME_SIZEstmia sp, r0 - r12 Calling r0
39、-r12add r7, sp, #S_PCstmdb r7, sp, lrA Calli ng SP, LRstr lr, r7, #0 Save calling PCmrs r6, spsrstr r6, r7, #4 Save CPSRstr r0, r7, #8 Save OLD_R0mov r0, sp .endm.macro irq_restore_user_regsIdmia sp, r0 - lrA Calli ng r0 - Irmov r0, r0ldr lr, sp, #S_PC Get PCadd sp, sp, #S_FRAME_SIZEsubs pc, lr, #4 return & move spsr_svc into cpsr.endm.macro get_bad_stackldr r13, _armboot_start setup our mode stacksub r13, r13, #(CONFIG_STACKSIZE)sub r13, r13, #(CONFIG_SYS_MALLOC_L
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 泉州海洋职业学院《中医思维学》2023-2024学年第二学期期末试卷
- 西安海棠职业学院《工程伦理五》2023-2024学年第二学期期末试卷
- 江西洪州职业学院《RFD原理及应用》2023-2024学年第二学期期末试卷
- 2025年中医药师考试试题及答案分享
- 山东省济南市部分学校2025年高三高考全真模拟卷(三)英语试题含解析
- 2025年心理学职业发展理论考试试题及答案
- 2025年英语翻译专业技能考试试卷及答案
- 2025年物流与供应链管理考试题目及答案
- 邵东县2025年初三调研测试(二)语文试题理试题含解析
- 武汉理工大学《休闲体育产业》2023-2024学年第一学期期末试卷
- 套管修复(2010大赛)
- 人居与环境-诗意的栖居 课件-2024-2025学年高中美术人美版(2019)美术鉴赏
- 辽宁省鞍山市(2024年-2025年小学五年级语文)部编版阶段练习(下学期)试卷及答案
- 酒店工作安全培训(共60张课件)
- 历史人物范仲淹介绍
- 四年级下册数学方程题100道及答案
- 2024年中证金融研究院事业单位招聘23人历年高频难、易错点500题模拟试题附带答案详解
- 2024挂轨式巡检机器人
- CJJT 182-2014 城镇供水与污水处理化验室技术规范
- 排水暗渠施工方案
- 小升初奥数竞赛题100例附答案(完整版)
评论
0/150
提交评论