原创 续:深入剖析barebox(U-BOOT-II)在i.MX27上的移植

2011-10-31 11:32 1788 13 13 分类: 消费电子

深入剖析barebox(U-BOOT-II)在i.MX27上的移植

 

writel(IMX_PLL_PD(1) |

               IMX_PLL_MFD(12) |

               IMX_PLL_MFI(9) |

               IMX_PLL_MFN(3), SPCTL0) /* SPLL = 2 * 26 * 4.61538 MHz = 240 MHz */

 

       writel(CSCR_MPLL_RESTART | CSCR_SPLL_RESTART | CSCR_ARM_SRC_MPLL |

              CSCR_MCU_SEL | CSCR_SP_SEL | CSCR_FPM_EN | CSCR_MPEN |

              CSCR_SPEN | CSCR_ARM_DIV(0) | CSCR_AHB_DIV(1) | CSCR_USB_DIV(3) |

              CSCR_SD_CNT(3) | CSCR_SSI2_SEL | CSCR_SSI1_SEL | CSCR_H264_SEL |

              CSCR_MSHC_SEL, CSCR)

 

       sdram_init

#ifdef CONFIG_NAND_IMX_BOOT

       ldr   sp, =0xa0f00000         /* Setup a temporary stack in SDRAM [ram start+15M offset] */

 

       ldr   r0, =IMX_NFC_BASE        /* start of NFC SRAM                */

       ldr   r2, =IMX_NFC_BASE + 0x1000       /* end of NFC SRAM                  */

 

       /* skip NAND boot if not running from NFC space */

       cmp pc, r0

       bls   ret                 #if(pc < r0) goto ret

       cmp pc, r2           

       bhi  ret                 ##if(pc > r2) goto ret

 

       /* Move ourselves out of NFC SRAM */

       ldr   r1, =TEXT_BASE  #0xa7f0_0000

 

copy_loop:

       ldmia      r0!, {r3-r9}            /* copy from source address [r0]    */

       stmia      r1!, {r3-r9}            /* copy to   target address [r1]    */

       cmp r0, r2                    /* until source end addreee [r2]    */

       ble  copy_loop

 

       ldr   pc, =1f                 /* Jump to SDRAM                    */

1:

       bl    nand_boot           /* Load barebox from NAND Flash      */

 

       ldr   r1, =IMX_NFC_BASE - TEXT_BASE

       sub r10, r10, r1          /* adjust return address from NFC SRAM */

                                   /* to SDRAM                            */

 

#endif /* CONFIG_NAND_IMX_BOOT */

 

ret:

       mov pc,r10

 

Reset函数流程如下

  • ARM进入svc32 mode 因为arm芯片内部有许多寄存器都只能在SVC32mode下才能访问,否则会产生abort异常,或则读取不到数据。比如mx27内部的AIPI模块
  • 禁用MMU和cache  必须采用物理地址访问而且不能进行cache。
  • 调用board_init_lowlevel函数进行板级初始化
  • 调用board_init_lowlevel_return进行代码的重定位

board_init_lowlevel函数在 arch/arm/boards/你的电路板目录下面/lowlevel.c文件中,流程如下

  • 保护lr地址到r10中,以便返回
  • 配置AIPI接口,设置外设模块总线宽度
  • 判断当前程序是否在RAM中执行,如果已经在RAM中则直接返回,因为有可能barebox是通过tftp下载到ram中,然后再跳转执行的,因为已经完成了后面的初始化了,所以直接返回。
  • 设置MPLL和SPLL时钟 分别为400M和240M
  • 设置时钟源寄存器,从而设置各个外设的时钟
  • 初始化SDRAM
  • 判断自己是否在NANDFLASH的内部RAM中,如果是则将自己拷贝2K到SDRAM中的TEXT_BASE处
  • 拷贝完毕后,跳转到SDRAM中接着从跳转前的偏移位置处开始执行,也就是bl    nand_boot,至于为什么要这样做,是因为接下来马上要从NANDFLASH中拷贝剩余的barebox代码到SDRAM中,而一旦拷贝就需要用到NAND FLASH控制器中的SRAM也就是boot ram,而拷贝前我们代码正是在这段ram中,所以我们要把这段ram让出来。
  • 现在我们的pc指针已经在sdram中了,接着调用nand_boot函数将nandflash中的barebox完整的拷贝到sdram的TEXT_BASE处。拷贝的大小是256K。
  • 接着计算出NANDFLASH控制器中RAM的起始地址和SDRAM的TEXT_BASE的偏移地址,然后将第一步保存的lr地址减去计算出来的偏移地址就得到了,board_init_lowlevel函数经过重新拷贝到sdram中后应该返回的地址。然后跳转到该地址去
  • 跳转到board_init_lowlevel_return 继续执行
  • 那么你可能会问了,既然mx27在冷启动的时候只能复制nandflash中的前2k代码出来,那么我们怎么才能保证exception_vectors和reset函数,还有board_init_lowlevel函数,以及nand_boot函数在前面的2K代码内。这还得看链接文件

.text      :

{

        _stext = .;

        _text = .;

        *(.text_entry*)

        *(.text_bare_init*)

        *(.text*)

}

              看看几个函数的申明

       void __naked __section(.text_entry) exception_vectors(void)

说明exception_vectors在*(.text_entry*)节中

              void __naked __bare_init reset(void)

              void __bare_init nand_boot(void)

                     .section ".text_bare_init","ax”

.globl board_init_lowlevel

board_init_lowlevel:

       #define __bare_init          __section(.text_bare_init.text)

说明这三个函数在*(.text_bare_init*)节中,这样就保证了这4个关键函数在最前面的2K,不会将他们链接到其他地方去。

 

  • board_init_lowlevel_return函数主要是继续地址重定位,当barebox的代码定位到TEXT_BASE处,为什么前面的board_init_lowlevel中以及进行了重定位了,这里还需要重定位啦?这是因为board_init_lowlevel中的重定位操作是可以配置的,也就是某些平台可能没有启用NAND FLASH启动方式,所以这里需要再检查一下是否以及重定位了,如果没有在进行一次重定位操作,然后跳转到start_barebox中,完成了最底层的初始化加载操作。
  • start_barebox 函数在common/startup.c中,主要按照预先设置的顺序调用核心模块以及负责加载驱动等等,所有在这里被调用的函数都属于barebox.lds.S中

__barebox_initcalls_start = .;

.barebox_initcalls : { INITCALLS }

__barebox_initcalls_end = .;

 

 

文章评论0条评论)

登录后参与讨论
我要评论
0
13
关闭 站长推荐上一条 /2 下一条