天津高端网站制作,残疾人招聘网站建设,0453信息网免费发布,网站内容创造本文转载自nidetech的Blog芯片到uboot启动流程ROM → SPL→ uboot.img简介在335x 中ROM code是第一级的bootlader。mpu上电后将会自动执行这里的代码#xff0c;完成部分初始化和引导第二级的bootlader#xff0c;第二级的bootlader引导第三级bootader#xff0c;在ti官方上…本文转载自nidetech的Blog芯片到uboot启动流程ROM → SPL→ uboot.img简介在335x 中ROM code是第一级的bootlader。mpu上电后将会自动执行这里的代码完成部分初始化和引导第二级的bootlader第二级的bootlader引导第三级bootader在ti官方上对于第二级和第三级的bootlader由uboot提供。SPLTo unify all existing implementations for a secondary program loader (SPL) and to allow simply adding of new implementations this generic SPL framework has been created. With this framework almost all source files for a board can be reused. No code duplication or symlinking is necessary anymore.1 Basic ARM initialization2 UART console initialization3 Clocks and DPLL locking (minimal)4 SDRAM initialization5 Mux (minimal)6 BootDevice initialization(based on where we are booting from.MMC1/MMC2/Nand/Onenand)7 Bootloading real u-boot from the BootDevice and passing control to it.uboot spl源代码分析一、makefile分析打开spl文件夹只有一个makefile 可见spl都是复用uboot原先的代码。主要涉及的代码文件为u-boot-2011.09-psp04.06.00.03/arch/arm/cpu/armv7u-boot-2011.09-psp04.06.00.03/arch/arm/libu-boot-2011.09-psp04.06.00.03/driversLDSCRIPT : $(TOPDIR)/board/$(BOARDDIR)/u-boot-spl.lds这个为链接脚本二、u-boot-spl.ldsSram 0x402F0400 Sdram 0x80000000 .bss .TEXT arch/arm/cpu/armv7/start.o .rodata .data __start 为程序开始__image_copy_end_end三、代码解析__start 为程序开始 arch/arm/cpu/armv7/start.S.globl _start 这是在定义u-boot的启动定义入口点汇编程序的缺省入口是 start标号用户也可以在连接脚本文件中用ENTRY标志指明其它入口点。.global是GNU ARM汇编的一个伪操作声明一个符号可被其他文档引用相当于声明了一个全局变量.globl和.global相同。该部分为处理器的异常处理向量表。地址范围为0x0000 0000 ~ 0x0000 0020,刚好8条指令。为什么是8条指令呢这里来算一算。首先一条arm指令为32bit位0x0000 0020换算成十进制为2^532B字节而32B 4 * 8B 4 * 8 * 8 bit所以刚好8条指令一个字节Byte包含8个位bit。下面是在汇编程序种经常会遇到的异常向量表。Arm处理器一般包括复位、未定义指令、SWI、预取终止、数据终止、IRQ、FIQ等异常其中U-Boot中关于异常向量的定义如下_start: b reset _start 标号表明 oot程序从这里开始执行。b是不带返回的跳转bl是带返回的跳转意思是无条件直接跳转到reset标号出执行程序。b是最简单的分支一旦遇到一个 b指令ARM 处理器将立即跳转到给定的地址从那里继续执行。注意存储在分支指令中的实际的值是相对当前的 R15 的值的一个偏移量而不是一个绝对地址。它的值由汇编器来计算它是 24 位有符号数左移两位后有符号扩展为 32 位表示的有效偏移为 26 位。ldr pc, _undefined_instr tion //未定义指令ldr pc, _software_interrupt //软中断SWIldr pc, _prefetch_abort //预取终止ldr pc, _data_abort //数访问终止ldr pc, _not_usedldr pc, _irq //中断请求IRQldr pc, _fiq //快速中断FIQ#ifdef CONFIG_SPL_BUILD //该阶段为spl执行下面代码_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: .word _fiq_pad: .word 0x12345678 /* now 16*464 */#else_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: .word fiq_pad: .word 0x12345678 /* now 16*464 */#endif /* CONFIG_SPL_BUILD */.word为ARM汇编特有的伪操作符语法如下.word {,} …作用插入一个32-bit的数据队列。与armasm中的DCD功能相同.balignl 16,0xdeadbeef.align伪操作用于表示对齐方式通过添加填充字节使当前位置满足一定的对齐方式。接下来是对各个段代码的定义略Rest (arch/arm/cpu/armv7/start.S)bl save_boot_paramssave_boot_params: arch/arm/cpu/armv7/ti81xx/lowlevel_init.S#ifdef CONFIG_SPL_BUILDldr r4, ti81xx_boot_device //ti81xx_boot_device BOOT_DEVICE_NAND//启动方式ldr r5, [r0, #BOOT_DEVICE_OFFSET]and r5, r5, #BOOT_DEVICE_MASKstr r5, [r4]#endifbx lr回到reset(arch/arm/cpu/armv7/start.S) //设置cpu的工作模式 设置CPU的状态类型为SVC特权模式mrs r0, cpsrbic r0, r0, #0x1forr r0, r0, #0xd3msr cpsr,r0cpu_init_crit: (arch/arm/cpu/armv7/start.S)mov r0, #0 set up for MCRmcr p15, 0, r0, c8, c7, 0 invalidate TLBsmcr p15, 0, r0, c7, c5, 0 invalidate icachemcr p15, 0, r0, c7, c5, 6 invalidate BP arraymcr p15, 0, r0, c7, c10, 4 DSBmcr p15, 0, r0, c7, c5, 4 ISB//关闭mmu 缓存mrc p15, 0, r0, c1, c0, 0bic r0, r0, #0x00002000 clear bits 13 (--V-)bic r0, r0, #0x00000007 clear bits 2:0 (-CAM)orr r0, r0, #0x00000002 set bit 1 (--A-) Alignorr r0, r0, #0x00000800 set bit 11 (Z---) BTB#ifdef CONFIG_SYS_ICACHE_OFFbic r0, r0, #0x00001000 clear bit 12 (I) I-cache#elseorr r0, r0, #0x00001000 set bit 12 (I) I-cache#endifmcr p15, 0, r0, c1, c0, 0//调用初始化 函数mov ip, lr persevere link reg across callbl lowlevel_init go setup pll,mux,memorylowlevel_initarch/arm/cpu/armv7/ti81xx/lowlevel.S/* The link register is saved in ip by start.S */mov r6, ip/* check if we are already running from RAM */ldr r2, _lowlevel_init_TEXT_BASE:.word CONFIG_SYS_TEXT_BASE /* Load address (RAM) */#define CONFIG_SYS_TEXT_BASE 0x80800000SDRAM的前8MB作为spl的bss段然后前64bytes做为u-boot.img的头ldr r3, _TEXT_BASEsub r4, r2, r3sub r0, pc, r4//设置堆栈指针/* require dummy instr or subtract pc by 4 instead im doing stack init */ldr sp, SRAM_STACKmark1:ldr r5, _mark1sub r5, r5, r2 /* bytes between mark1 and lowlevel_init */sub r0, r0, r5 /* r0 - _start w.r.t current place of execution */mov r10, #0x0 /* r10 has in_ddr used by s_init() */ands r0, r0, #0xC0000000 /* MSB 2 bits 0 then we are in ocmc or DDR */cmp r0, #0x80000000bne s_init_startmov r10, #0x01b s_init_starts_init_start:arch/arm/cpu/armv7/ti81xx/lowlevel.Smov r0, r10 /* passing in_ddr in r0 */bl s_init初始化pll mux memery/* back to arch calling code */mov pc, r6call_board_init_f:arch/arm/cpu/armv7/start.s)//设置堆栈指针并调用board_init_fldr sp, (CONFIG_SYS_INIT_SP_ADDR)bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ldr r0,0x00000000bl board_init_fvoid board_init_f(ulong dummy)『u-boot-2011.09-psp04.06.00.03/arch/arm/cpu/armv7/omap-common/spl.c』调用relocate_code(CONFIG_SPL_STACK, gdata, CONFIG_SPL_TEXT_BASE);这里使用了 CONFIG_SPL_STACK#define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK#define LOW_LEVEL_SRAM_STACK (SRAM0_START SRAM0_SIZE – 4)gdata 为.bss 前一段的空间 描述镜像头#define CONFIG_SPL_TEXT_BASE 0x402F0400relocate_code: arch/arm/cpu/armv7/start.s)重载定位代码jump_2_ram: arch/arm/cpu/armv7/start.s)跳转到spl的第二阶段board_init_r:(u-boot-2011.09-psp04.06.00.03/arch/arm/cpu/armv7/omap-common/spl.c)初始化时钟 timer_initi2c 初始化 i2c_init获取启动方式 omap_boot_device();判断启动方式从不同的地方装载镜像从mmc 中装载镜像 spl_mmc_load_image()从nand 中装载镜像 spl_nand_load_image()从 uart 中装载镜像 spl_ymodem_load_image()判断镜像类型跳转到镜像中执行镜像 jump_to_image_no_args();装载镜像 将会从配置的存储介质中读取数据 及uboot镜像然后跳转到uboot中执行uboot 注文章版权属于成都莱得科技有限公司所有转载请注明出处保留此行文字。