新闻中心

EEPW首页>嵌入式系统>设计应用> 自制bootloader 之文本代码

自制bootloader 之文本代码

作者: 时间:2012-08-31 来源:网络 收藏
想移植uboot1.4到板子上,搞了半天没成功,决心弄明白uboot原理,大概流程,所以决定写个简单的来理顺一下应该做些什么,怎么做~~~~

首先应该描述一下该的基本功能:板子上电后能进行LED流水灯(万能的流水灯啊)。实现该功能分两步:第一步,真正的功能,即实现硬件的初始化以及将内核程序(LED流水灯)从ROM(flash)搬移到RAM(sdram);第二步,内核程序的实现

第一步也可分两段:1,板子硬件初始化;2,内核程序的搬移。代码文件:boot.s

板子硬件初始化:1. 异常向量初始化
       2. 初始化CPSR,包括关闭中断及设定svc模式等
       3. 关闭看门狗定时器
       4. 初始化系统时钟
     5. 初始化CPU Cache(这步可以不做,但是系统效率会明显下降许多)

内核执行流程:1,内核异常向量初始化

       2,初始化堆栈

       3,跳转到C程序中执行万能的流水灯~~~~

代码如下: .equ SYSCFG, 0x01c00000 .equ BWSCON, 0x01c80000 .equ WTCON, 0x01d30000 .equ PLLCON, 0x01d80000 .equ CLKCON, 0x01d80004 .equ KERNEL_START, 0x0c000100 @ 内核执行的起始位置(RAM) .equ KERNEL_VECTOR, 0x0c000000 @ 内核的异常向量入口(RAM) .equ KERNEL_DATA, 0x00000100 @ 内核数据在ROM中的起始位置 .equ KERNEL_CPLMT, 0x00001000 @ 复制界限(内核数据在ROM中的终止位置,4KB).equ REFEN,    0x01.equ  TREFMD,   0x0.equ  Trp,      0x1.equ  Trc,     0x1.equ Tchr,     0x2.equ REFCNT,   1550vectors:    b    reset    ldr pc, = KERNEL_VECTOR @ 未定义协处理器指令    ldr pc, = KERNEL_VECTOR + 4 @ SWI(软中断) ldr pc, = KERNEL_VECTOR + 8 @ 预取指令中止 ldr pc, = KERNEL_VECTOR + 12 @ 数据中止 b . ldr pc, = KERNEL_VECTOR + 16 @ IRQ(普通中断请求) ldr pc, = KERNEL_VECTOR + 20 @ FIQ(快速中断请求)reset:    mov    r0,0xd3    ;禁止IRQ,FIQ,SVC模式    msr    cpsr_c,r0    ldr    r0,=WTCON ;关看门狗    mov    r1,#0    str    r1,[r0]    ldr    r0,=PLLCON ;初始化PLLCON    mov    r1,#0x48032
;Fin=10M Fpllo=40M Mdiv=0x48 Pdiv=0x3 Sdiv=0x2    str    r1,[r0]    ldr    r0,=CLKCON    ldr    r1,=0x7f88    ;提供给所有外设时钟    str    r1,[r0]    ldr    r0,=SYSCFG ;初始化cpu cach    mov    r1,#0x0e ;8K cache 写缓冲使能    str    r1,[r0]    ldr    r0,=SMRDATA ;初始化存储器    ldmia   r0,{r1-r13}    ldr    r0,=BWSCON    stmia   r0,{r1-r13};将内核程序(LED流水灯)从0x00000100(flash)复制到0x0c000000(sdram)    ldr    fp,=KERNEL_DATA    ldr    ip,=KERNEL_VECTOR    ldr    sp,=KERNEL_CPLMT1:   ldmia   fp!,{r0-r7}    stmia   ip!,{r0-r7}    cmp    fp,ip    bcc     1b    ldr    pc,=KERNEL_STARTsmrdata : .word 0x11110090.word 0x00000600.word 0x00000700 @ BANKCON1: 默认 .word 0x00000700 @ BANKCON2: 默认 .word 0x00000700 @ BANKCON3: 默认 .word 0x00000700 @ BANKCON4: 默认 .word 0x00000700 @ BANKCON5: 默认 .word 0x00018000 @ BANKCON6: SDRAM,SCAN=8位,Trcd=2个时钟 .word 0x00000700 @ BANKCON7: 默认 .word
((REFEN23)+(TREFMD22)+(Trp20)+(Trc18)+(Tchr16)+REFCNT)
;refresh register .word 0x00000016 @ BANKSIZE: SLCKEN=1, BK76MAP=8M .word 0x00000020 @ MRSRB6: CL=2个时钟 .word   0x20 @MRSRB7第二步:内核程序的实现,代码文件 head.s内核程序大致三步:1,内核异常向量初始化;2,内核堆栈初始化;3,执行LED程序;代码如下:.equ    KERNEL_STACK,    0x0c002000.equ    KERNEL_LIMIT,     0x0c001000vectors: b undef_handler @ 内核异常向量0 b swi_handler @ 内核异常向量1 b pabort_handler @ 内核异常向量2 b dabort_handler @ 内核异常向量3 b irq_handler @ 内核异常向量4 b fiq_handler @ 内核异常向量5.space    0x100-6*4 @字节填充至地址:0x0c000100start:    ldr    sp,=KERNEL_STACK    ldr    sl,=KERNEL_LIMIT    bl    entryundef_handler: swi_handler: pabort_handler: dabort_handler: irq_handler: fiq_handler: b . @ 目前什么都不做

以上两个文本程序基本实现了一个bootloader的功能,至少符合我的板子,只要再加上上一篇LED篇中的LED程序,就是一个完整的bootloader程序了。当然,还是需要几番调试的。而大debug之前还是有很多工作要做滴。下一篇再说吧,这里太长了~~~~



评论


相关推荐

技术专区

关闭