1、(3)初始化系统内存分配函数。(4)如果目标系统拥有NAND设备,则初始化NAND设备。(5)如果目标系统有显示设备,则初始化该类设备。(6)初始化相关网络设备,填写IP、MAC地址等。(7)进去命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。3 U-Boot.lds 代码分析 /*/OUTPUT_FORMAT(elf32-littlearm, ) ;指定输出可执行文件是elf格式,32位ARM指令,小端OUTPUT_ARCH(arm)指定输出可执行文件的平台为ARMENTRY(_start)指定输出可执行文件的起始代码段为_start.SECTIONS .
2、 = 0x00000000 ; 指明目标代码的起始地址从0x0位置开始,.代表的是当前位置 . = ALIGN(4) ; 代码以4字节对齐 .text :指定代码段 cpu/arm920t/start.o (.text) ; 代码的第一个代码部分,指明start.s是入口程序代码,被放到代码段的开头 *(.text) ;其它代码部分 . = ALIGN(4) .rodata : *(.rodata) ;指定只读数据段,RO段 . = ALIGN(4); .data : *(.data) ;指定读/写数据段,RW段 .got : *(.got) ;指定got段, got段式是uboot自定义的一
3、个段, 非标准段 _u_boot_cmd_start = . ;把_u_boot_cmd_start赋值为当前位置, 即起始位置 .u_boot_cmd : *(.u_boot_cmd) ;指定u_boot_cmd段, uboot把所有的uboot命令放在该段. _u_boot_cmd_end = .;把_u_boot_cmd_end赋值为当前位置,即结束位置 _bss_start = .; 把_bss_start赋值为当前位置,即bss段的开始位置 .bss : *(.bss) ; 指定bss段 _end = .; 把_end赋值为当前位置,即bss段的结束位置/*/ 从这里可以看出star
4、t.s是程序的入口点。4 start.S 代码分析/global声明一个符号可被其它文件引用,相当于声明了一个全局变量,.globl与.global相同。/该部分为处理器的异常处理向量表。地址范围为0x0000 0000 0x0000 0020,刚好8条指令。.globl _start_start: b reset /*跳转到reset标号执行*/ ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort ldr pc, _data_abort ldr pc, _not_used ldr
5、 pc, _irq ldr pc, _fiq/ .word伪操作用于分配一段字内存单元(分配的单元都是字对齐的),并用伪操作中的expr初始化。.long与.int作用与之/相同。_undefined_instruction: .word undefined_instruction_software_interrupt: .word software_interrupt_prefetch_abort: .word prefetch_abort_data_abort: .word data_abort_not_used: .word not_used_irq: .word irq_fiq: .w
6、ord fiq .balignl 16,0xdeadbeef/* Startup Code (reset vector)* do important init only if we dont start from RAM!* - relocate armboot to ram* - setup stack* - jump to second stage*/ TEXT_BASE在开发板相关的目录中的config.mk文件中定义, 它定义了/ 代码在运行时所在的地址, 那么_TEXT_BASE中保存了这个地址_TEXT_BASE: .word TEXT_BASE/ 声明 _armboot_star
7、t 并用 _start 来进行初始化,在board/u-boot.lds中定义。.globl _armboot_start_armboot_start: .word _start* These are defined in the board-specific linker script./ 声明_bss_start并用_bss_start来初始化,其中_bss_start定义在与板相关的u-boot.lds中。/ _bss_start保存的是_bss_start这个标号所在的地址, 这里涉及到当前代码所在/ 的地址不是编译时的地址的情况, 这里直接取得该标号对应的地址, 不受编译时/ 地址的
8、影响. _bss_end也是同样的道理.globl _bss_start_bss_start: .word _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.globl FIQ_STACK_STARTFIQ_STACK_START:#endif/ MRS Rd,CPSR|SPSR 将CPSRSPSR传送
9、到Rd/ 使用这两条指令将状态寄存器传送到一般寄存器,只修改必要的位,再将结果传送回状态寄存器,这样可以最好地完成对CRSP或者SPSR的修改/ MSR CPSR_|SPSR_,Rm 或者是 MSR CPSR_f|SPSR_f,#/ MRS与MSR配合使用,作为更新PSR的“读取修改写回”序列的一部分/ bic r0,r1,r2 ;r0:=r1 and not r2/ orr ro,r1,r2 ;=r1 or r2/ 这几条指令执行完毕后,进入SVC模式,该模式主要用来处理软件中断(SWI)reset: mrs r0,cpsr /* set the cpu to SVC32 mode */ b
10、ic r0,r0,#0x1f /* (superviser mode, M=10011) */ orr r0,r0,#0xb3 /*disable irq and frq SVC mode*/ msr cpsr,r0/* 关闭看门狗,S3C2410手则 */#if defined(CONFIG_S3C2400)# define pWTCON 0x15300000# define INTMSK 0x14400008 /* Interupt-Controller base addresses */# define CLKDIVN 0x14800014 /* clock divisor regist
11、er */#elif defined(CONFIG_S3C2410)# define pWTCON 0x53000000# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */# define INTSUBMSK 0x4A00001C# define CLKDIVN 0x4C000014 /* clock divisor register */#if defined(CONFIG_S3C2400) | defined(CONFIG_S3C2410) ldr r0, =pWTCON mov r1, #0x0 str r
12、1, r0 /* * 屏蔽所有中断 */ mov r1, #0xffffffff ldr r0, =INTMSK# if defined(CONFIG_S3C2410) ldr r1, =0x3ff ldr r0, =INTSUBMSK# endif /* 设置FCLK:HCLK:PCLK = 1:2:4 */ /*FCLK默认为120 MHz ! ldr r0, =CLKDIVN mov r1, #3#endif /* CONFIG_S3C2400 | CONFIG_S3C2410 */ /*该语句首先调用cpu_init_crit进行CPU的初始化,并把下一条指令的地址保存在LR中,以使得
13、执行完后能够正常返回。后面会分析*/#ifndef CONFIG_SKIP_LOWLEVEL_INIT bl cpu_init_crit/调试阶段的代码是直接在RAM中运行的,而最后需要把这些代码固化到Flash中,因此U-Boot需要自己从Flash转移到/RAM中运行,这也是重定向的目的所在。/通过adr指令得到当前代码的地址信息:如果U-boot是从RAM开始运行,则从adr,r0,_start得到的地址信息为/r0=_start=_TEXT_BASE=TEXT_BASE=0xa3000000;如果U-boot从Flash开始运行,即从处理器对应的地址运行,/则r0=0x0000,这时将
14、会执行copy_loop标识的那段代码了。/ _TEXT_BASE 定义在board/pxa255_idp/config.mk中#ifndef CONFIG_SKIP_RELOCATE_UBOOTrelocate: /* relocate 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_set
15、up ldr r2, _armboot_start ldr r3, _bss_start sub r2, r3, r2 /* r2 - size of armboot */ add r2, r0, r2 /* r2 0) 11. 305*s;12. 306bootdelay;13. 30714. 308#ifdefCONFIG_PREBOOT 15. 309*p;16. 31017. 311CONFIG_BOOTCOUNT_LIMIT 18. 312unsignedlongbootcount0;19. 313bootlimit20. 314*bcs;21. 315bcs_set16;22. 316#endif/*CONFIG_BOOTCOUNT_LIMIT*/ 23. 31724. 318defined(CONFIG_VFD)defined(VFD_TEST_LOGO) 25. 319ulongbmpdefaultbitmap26. 320externtrab_vfd(ulongbitmap);27. 321
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1