QT210烧写UBOOT到SD卡原理以及UBOOT启动

世界早已进入cortex-a8了,我也得跟进一下所以买了QT210的开发板。

        长话短说开始搞SD卡烧写UBOOT,从SD启动UBOOT。

        从s5pv210_irom_applicationnote_preliminary_20091126.pdf知道,s5pv210启动分BL0、BL1、BL2阶段。BL0是s5pv210内部IROM固化的代码,这段代码根据OM引脚配置状态来选择从哪个外部存储设备加载BL1段代码(实际上BL1代码就是我们编写的UBOOT的前8K代码,这段代码要包含完整的将后半部UBOOT代码复制和清bss段的功能,当然我们要从SD卡启动烧写在上面的UBOOT,OM引脚就必须配置为从SD卡启动配置)。

           1

从上图可知,从sd启动的时候BL0加载的代码是从第512个字节处开始加载代码,为什么要这样做呢?由于以后功能扩展的需要三星的软件工程师写的固化到IROM中的BL0代码是从SD卡的512字节处加载BL1的,他就是这样写的,我们对应UBOOT放置在SD卡中的位置就要往后移动512字节,后面有介绍怎么指定把uboot写到sd卡指定的位置的命令。

       还有一定要注意如下所示的地方:

                                                                                          图2

在BL1之前要加16个字节的头部信息。也就是在真正的UBOOT第一条指令之前要加16个字节的头部信息,于是就有我们所看到的uboot代码如下的用宏定义的一段:

[cpp]  view plain copy
  1. #if defined(CONFIG_EVT1) && !defined(CONFIG_FUSED)  
  2.     .word 0x2000  
  3.     .word 0x0  
  4.     .word 0x0  
  5.     .word 0x0  
  6. #endif  
  7.   
  8. .globl _start  
  9. _start: b   reset  
  10.     ldr pc, _undefined_instruction  
  11.     ldr pc, _software_interrupt  
  12.     ldr pc, _prefetch_abort  

其中的 .word 0x2000  代表BL1size(8K长度),.word 0x0 为保留字节 .word 0x0为checksum(后续会通过一个mkbl1工具来计算bl1的checksum并填写这个位置),最后一个.word 0x0也为保留字节。

        再来看看uboot的下面的部分,如果bl0正常读取了bl1,代码就会到如下段:

[cpp]  view plain copy
  1.         /* Read booting information */  
  2.         ldr r0, =PRO_ID_BASE  
  3.         ldr r1, [r0,#OMR_OFFSET]   //读OM引脚的配置状态  
  4.         bic r2, r1, #0xffffffc1  
  5.   
  6. #ifdef CONFIG_VOGUES  
  7.     /* PS_HOLD(GPH0_0) set to output high */  
  8.     ldr r0, =ELFIN_GPIO_BASE  
  9.     ldr r1, =0x00000001  
  10.     str r1, [r0, #GPH0CON_OFFSET]  
  11.   
  12.     ldr r1, =0x5500  
  13.     str r1, [r0, #GPH0PUD_OFFSET]  
  14.   
  15.     ldr r1, =0x01  
  16.     str r1, [r0, #GPH0DAT_OFFSET]  
  17. #endif  
  18.   
  19.     /* NAND BOOT */  
  20.     cmp r2, #0x0        @ 512B 4-cycle  
  21.     moveq   r3, #BOOT_NAND          //根据OM引脚配置状态来给R3寄存器赋予代表系统是从何冲外部存储器启动的配置值。  
  22.   
  23.     cmp r2, #0x2        @ 2KB 5-cycle  
  24.     moveq   r3, #BOOT_NAND  
  25.   
  26.     cmp r2, #0x4        @ 4KB 5-cycle   8-bit ECC  
  27.     moveq   r3, #BOOT_NAND  
  28.   
  29.     cmp r2, #0x6        @ 4KB 5-cycle   16-bit ECC  
  30.     moveq   r3, #BOOT_NAND  
  31.   
  32.     cmp r2, #0x8        @ OneNAND Mux  
  33.     moveq   r3, #BOOT_ONENAND  
  34.   
  35.     /* SD/MMC BOOT */  
  36.     cmp     r2, #0xc<pre name="code" class="cpp">   ldr sp, _TEXT_PHY_BASE  /* setup temp stack pointer */  
  37.     sub sp, sp, #12  
  38.     mov fp, #0          /* no previous frame, so fp=0 */  
  39.   
  40.     /* when we already run in ram, we don't need to relocate U-Boot. 
  41.      * and actually, memory controller must be configured before U-Boot 
  42.      * is running in ram. 
  43.      */  
  44.     ldr r0, =0xff000fff  
  45.     bic r1, pc, r0      /* r0 <- current base addr of code */  
  46.     ldr r2, _TEXT_BASE      /* r1 <- original base addr in ram */  
  47.     bic r2, r2, r0      /* r0 <- current base addr of code */  
  48.     cmp     r1, r2                  /* compare r0, r1                  */  
  49.     beq     after_copy      /* r0 == r1 then skip flash copy   */</pre><br>  
  50. moveq r3, #BOOT_MMCSD/* NOR BOOT */cmp r2, #0x14moveq r3, #BOOT_NOR#if 0 /* Android C110 BSP uses OneNAND booting! *//* For second device booting *//* OneNAND BOOTONG failed */cmp r2, #0x8moveq r3, #BOOT_SEC_DEV#endif/* Uart BOOTONG failed */cmp r2, #(0x1<<4)moveq  
  51.  r3, #BOOT_SEC_DEVldr r0, =INF_REG_BASEstr r3, [r0, #INF_REG3_OFFSET] //将配置值存入到用户使用的寄存器中,方便以后使用的时候读取此寄存器来了解此次启动时从何种外部存储设备启动  
  52. <pre></pre>  
  53. <p></p>  
  54. <pre></pre>  
  55. <pre name="code" class="cpp">   //ldr   sp, =0xd0036000 /* end of sram dedicated to u-boot */  
  56.     ldr sp, =0xd0035400  //BL1段的函数进行操作的堆栈位置,这里我修改了堆栈到了0xd0035400是由于图2中所示BL0代码进行了它自己代码堆栈的初始化,而RW/ZI region Heap的最低部就位于0xd0035400,为了不修改BL0堆栈和BL0代码已经写好的一些函数功能(会在下面用到),我将堆栈修改到了0xd0035400  
  57.     sub sp, sp, #12 /* set stack */  
  58.     mov fp, #0  
  59.       
  60.     bl  lowlevel_init   /* go setup pll,mux,memory */ //这里会进行始终,内存,串口初始化</pre>  
  61. <p>之后运行到</p>  
  62. <p></p>  
  63. <pre name="code" class="cpp">   ldr sp, _TEXT_PHY_BASE  /* setup temp stack pointer */   //由于上面一步已经初始化了DRAM,所以在这里将以后的堆栈设置到了DRAM中的位置(以后BL2代码中函数都是基于此堆栈)  
  64.     sub sp, sp, #12  
  65.     mov fp, #0          /* no previous frame, so fp=0 */  
  66.   
  67.     /* when we already run in ram, we don't need to relocate U-Boot. 
  68.      * and actually, memory controller must be configured before U-Boot 
  69.      * is running in ram. 
  70.      */  
  71.     ldr r0, =0xff000fff  
  72.     bic r1, pc, r0      /* r0 <- current base addr of code */    
  73.     ldr r2, _TEXT_BASE      /* r1 <- original base addr in ram */  //加载程序要运行的编译地址,同现在程序运行的地址比较  
  74.     bic r2, r2, r0      /* r0 <- current base addr of code */  
  75.     cmp     r1, r2                  /* compare r0, r1                  */  
  76.     beq     after_copy      /* r0 == r1 then skip flash copy   */  //如果两地址相等,代码程序已经再DRAM中运行不必再拷贝,不相等代表程序没有在编译地址运行,还要拷贝代码到编译地址去,最后跳到对应编译地址内运行代码。</pre><pre name="code" class="cpp">  ldr r0, =INF_REG_BASE  
  77.     ldr r1, [r0, #INF_REG3_OFFSET]  
  78.     cmp r1, #BOOT_NAND      /* 0x0 => boot device is nand */  
  79.     beq nand_boot  
  80.     cmp r1, #BOOT_ONENAND   /* 0x1 => boot device is onenand */  
  81.     beq onenand_boot  
  82.     cmp     r1, #BOOT_MMCSD  
  83.     beq     mmcsd_boot  
  84.     cmp     r1, #BOOT_NOR  
  85.     beq     nor_boot  
  86.     cmp     r1, #BOOT_SEC_DEV  
  87.     beq     mmcsd_boot      //代码判断要拷贝后,读取之前存入到用户使用寄存器中的值来判断此次启动从何种外部存储设备启动,这里为sd卡启动  
  88.       ~~~~~省略若干代码~~~~~~~~  
  89. mmcsd_boot:  
  90. #if DELETE  
  91.     ldr     sp, _TEXT_PHY_BASE        
  92.     sub     sp, sp, #12  
  93.     mov     fp, #0  
  94. #endif  
  95.     bl      movi_bl2_copy   //最后BL1代码来到此处从sd卡拷贝剩余的代码  
  96.     b       after_copy</pre><br>  
  97. <pre></pre>  
  98. <pre name="code" class="cpp"></pre>  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值