U-BOOT start.S分析

U-BOOT start.S分析
一.存储八个异常跳转表,以及七个异常地址,一个内存标志,deadbeef 表示以上内存禁止操作
[plain] view plaincopyprint?
.globl _start  
_start: b   start_code  
    ldr pc, _undefined_instruction  
    ldr pc, _software_interrupt  
    ldr pc, _prefetch_abort  
    ldr pc, _data_abort  
    ldr pc, _not_used  
    ldr pc, _irq  
    ldr pc, _fiq  
  
_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  
  
    .balignl 16,0xdeadbeef  
.globl _start
_start: b start_code
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq


_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


.balignl 16,0xdeadbeef二.存储地址标号变量,比如 bss_start ,_start 标号的地址。
[plain] view plaincopyprint?
_TEXT_BASE:  
    .word   TEXT_BASE  
  
.globl _armboot_start  
_armboot_start:  
    .word _start  
  
/*  
 * These are defined in the board-specific linker script.  
 */  
.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_START  
IRQ_STACK_START:  
    .word   0x0badc0de  
  
/* IRQ stack memory (calculated at run-time) */  
.globl FIQ_STACK_START  
FIQ_STACK_START:  
    .word 0x0badc0de  
#endif  
_TEXT_BASE:
.word TEXT_BASE


.globl _armboot_start
_armboot_start:
.word _start


/*
 * These are defined in the board-specific linker script.
 */
.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_START
IRQ_STACK_START:
.word 0x0badc0de


/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif三.开始代码:


  1.使cpu进入svc模式
[plain] view plaincopyprint?
mrs r0, cpsr  
bic r0, r0, #0x1f  
orr r0, r0, #0xd3  
msr cpsr, r0  
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr, r0  2.关闭看门狗。
[plain] view plaincopyprint?
ldr r0, =pWTCON  
mov r1, #0x0  
str r1, [r0]  
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]  3.关中断,以及子中断。
[plain] view plaincopyprint?
    mov r1, #0xffffffff  
    ldr r0, =INTMSK  
    str r1, [r0]  
# if defined(CONFIG_S3C2410)  
    ldr r1, =0x7ff  
    ldr r0, =INTSUBMSK  
    str r1, [r0]  
# endif  
  
#if defined(CONFIG_S3C2440)  
    ldr r1, =0x7fff   
    ldr r0, =INTSUBMSK  
    str r1, [r0]  
#endif  
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
# if defined(CONFIG_S3C2410)
ldr r1, =0x7ff
ldr r0, =INTSUBMSK
str r1, [r0]
# endif


#if defined(CONFIG_S3C2440)
ldr r1, =0x7fff
ldr r0, =INTSUBMSK
str r1, [r0]
#endif  4.设置时钟寄存器,使 FCLK = 400M HCLK = 100M PCLK = 50M
[plain] view plaincopyprint?
/* FCLK:HCLK:PCLK = 1:4:8 */  
ldr r0, =CLKDIVN  
mov r1, #5  
str r1, [r0]  
  
mrc p15, 0, r1, c1, c0, 0     
orr r1, r1, #0xc0000000       
mcr p15, 0, r1, c1, c0, 0     
  
  
mov r1, #CLK_CTL_BASE     
mov r2, #MDIV_405     
add r2, r2, #PSDIV_405    
str r2, [r1, #0x04]     /* MPLLCON tekkaman */  
/* FCLK:HCLK:PCLK = 1:4:8 */
ldr r0, =CLKDIVN
mov r1, #5
str r1, [r0]

mrc p15, 0, r1, c1, c0, 0
orr r1, r1, #0xc0000000
mcr p15, 0, r1, c1, c0, 0


mov r1, #CLK_CTL_BASE
mov r2, #MDIV_405
add r2, r2, #PSDIV_405
str r2, [r1, #0x04] /* MPLLCON tekkaman */  5.初始化内存以及MMU,进入cpu_init_crit函数


    (1) 使数据cache和指令cache无效
[plain] view plaincopyprint?
mov r0, #0  
mcr p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */  
mcr p15, 0, r0, c8, c7, 0   /* flush v4 TLB */  
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */    (2) 关闭MMU
[plain] view plaincopyprint?
mrc p15, 0, r0, c1, c0, 0  
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)  
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)  
orr r0, r0, #0x00000002 @ set bit 2 (A) Align  
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache  
mcr p15, 0, r0, c1, c0, 0  
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
mcr p15, 0, r0, c1, c0, 0    (3) 进入lowlevel_init.S, 初始化内存。因为内存所用芯片是与开发板有关,所以这个文件在/board里面
[plain] view plaincopyprint?
mov ip, lr  
  
bl  lowlevel_init  
mov ip, lr


bl lowlevel_init  6.判断代码位置,比较_start 的地址和 _TEXT_BASE 是否相同,如果相同说明代码是在内存中,否则就在内部RAM中,或者NorFlash中.
[plain] view plaincopyprint?
adr r0, _start      /* r0 <- current position of code   */  
ldr r1, _TEXT_BASE      /* test if we run from flash or RAM */  
cmp r0, r1          /* don't reloc during debug         */  
beq stack_setup  
adr r0, _start /* r0 <- current position of code   */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug         */
beq stack_setup  7.判断启动方式,采用读取BWSCON寄存器中内容的方式,是NANDFALSH或者NARFLASH启动是由引脚OM【1:0】决定的,而他们的状态影响 BWSCON【2:1】,


    如果OM【1:0】=00,BWSCON【2:1】=00,为NANDFLASH启动,否则为NORFLASH启动.
[plain] view plaincopyprint?
#define rBWSCON 0x48000000  
  
        mov     r0, #rBWSCON   
        ldr     r0, [r0]  
        bic     r0, r0, #0xfffffff5  /* BWSCON[2:1] is controled by OM[1:0] */  
        cmp     r0, #0               /* when OM[1:0] is 00,BSWCON[2:1]=00, nand flash boot */  
        bne     relocate             /* norflash boot */  
#define rBWSCON 0x48000000


        mov     r0, #rBWSCON 
        ldr     r0, [r0]
        bic     r0, r0, #0xfffffff5  /* BWSCON[2:1] is controled by OM[1:0] */
        cmp     r0, #0               /* when OM[1:0] is 00,BSWCON[2:1]=00, nand flash boot */
        bne     relocate             /* norflash boot */四.复制代码到内存
  1.NANDFLASH启动


    (1) 复位NANDFLASH,初始化堆栈指针,为进入C函数做好准备。
[plain] view plaincopyprint?
#define LENGTH_UBOOT 0x60000  
#define NAND_CTL_BASE 0x4E000000  
  
#ifdef CONFIG_S3C2440  
/* Offset */  
#define oNFCONF 0x00  
#define oNFCONT 0x04  
#define oNFCMD 0x08  
#define oNFSTAT 0x20  
  
        @ reset NAND  
        mov     r1, #NAND_CTL_BASE  
        ldr     r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )  
        str     r2, [r1, #oNFCONF]  
        ldr     r2, [r1, #oNFCONF]  
  
        ldr     r2, =( (1<<4)|(0<<1)|(1<<0) )   @ Active low CE Control  
        str     r2, [r1, #oNFCONT]  
        ldr     r2, [r1, #oNFCONT]  
  
        ldr     r2, =(0x6)      @ RnB Clear  
        str     r2, [r1, #oNFSTAT]  
        ldr     r2, [r1, #oNFSTAT]  
  
        mov     r2, #0xff       @ RESET command  
        strb    r2, [r1, #oNFCMD]  
  
        mov     r3, #0  @ wait  
nand1:  
        add     r3, r3, #0x1  
        cmp     r3, #0xa  
        blt     nand1  
nand2:  
        ldr     r2, [r1, #oNFSTAT]      @ wait ready  
        tst     r2, #0x4  
        beq     nand2  
  
  
        ldr     r2, [r1, #oNFCONT]  
        orr     r2, r2, #0x2    @ Flash Memory Chip Disable  
        str     r2, [r1, #oNFCONT]  
  
        @ get read to call C functions (for nand_read())  
        ldr     sp, DW_STACK_START      @ setup stack pointer  
        mov     fp, #0  @ no previous frame, so fp=0  
  
        @ copy U-Boot to RAM  
        ldr     r0, =TEXT_BASE  
        mov     r1, #0x0  
        mov     r2, #LENGTH_UBOOT  
#define LENGTH_UBOOT 0x60000
#define NAND_CTL_BASE 0x4E000000


#ifdef CONFIG_S3C2440
/* Offset */
#define oNFCONF 0x00
#define oNFCONT 0x04
#define oNFCMD 0x08
#define oNFSTAT 0x20


        @ reset NAND
        mov     r1, #NAND_CTL_BASE
        ldr     r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )
        str     r2, [r1, #oNFCONF]
        ldr     r2, [r1, #oNFCONF]


        ldr     r2, =( (1<<4)|(0<<1)|(1<<0) )   @ Active low CE Control
        str     r2, [r1, #oNFCONT]
        ldr     r2, [r1, #oNFCONT]


        ldr     r2, =(0x6)      @ RnB Clear
        str     r2, [r1, #oNFSTAT]
        ldr     r2, [r1, #oNFSTAT]


        mov     r2, #0xff       @ RESET command
        strb    r2, [r1, #oNFCMD]


        mov     r3, #0  @ wait
nand1:
        add     r3, r3, #0x1
        cmp     r3, #0xa
        blt     nand1
nand2:
        ldr     r2, [r1, #oNFSTAT]      @ wait ready
        tst     r2, #0x4
        beq     nand2




        ldr     r2, [r1, #oNFCONT]
        orr     r2, r2, #0x2    @ Flash Memory Chip Disable
        str     r2, [r1, #oNFCONT]


        @ get read to call C functions (for nand_read())
        ldr     sp, DW_STACK_START      @ setup stack pointer
        mov     fp, #0  @ no previous frame, so fp=0


        @ copy U-Boot to RAM
        ldr     r0, =TEXT_BASE
        mov     r1, #0x0
        mov     r2, #LENGTH_UBOOT    (2) 调用/board/chuangwaiyuntian/mini2440/nand_read.c 中的 nand_read_ll 函数将u-boot 复制到内存。
[plain] view plaincopyprint?
bl      nand_read_ll  
       bl      nand_read_ll    (3) 验证是否复制成功,主要检查在地址0x0 和地址_TEXT_BASE处的以后4K代码是否完全一样。如果一样就正常执行,否则死在这里了。
[plain] view plaincopyprint?
bad_nand_read:  
loop2:  
        b       loop2   @ infinite loop  
ok_nand_read:  
        @ verify  
        mov     r0, #0  
        ldr     r1, =TEXT_BASE  
        mov     r2, #0x400      @ 4 bytes * 1024 = 4K-bytes  
go_next:  
        ldr     r3, [r0], #4  
        ldr     r4, [r1], #4  
        teq     r3, r4  
        bne     notmatch  
        subs    r2, r2, #4  
        beq     stack_setup  
        bne     go_next  
  
  
notmatch:  
loop3:  
        b       loop3   @ infinite loop  
bad_nand_read:
loop2:
        b       loop2   @ infinite loop
ok_nand_read:
        @ verify
        mov     r0, #0
        ldr     r1, =TEXT_BASE
        mov     r2, #0x400      @ 4 bytes * 1024 = 4K-bytes
go_next:
        ldr     r3, [r0], #4
        ldr     r4, [r1], #4
        teq     r3, r4
        bne     notmatch
        subs    r2, r2, #4
        beq     stack_setup
        bne     go_next




notmatch:
loop3:
        b       loop3   @ infinite loop  2 NORFLASH启动


    (1) 简单的拷贝代码
[plain] view plaincopyprint?
relocate:               /* 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          /* don't reloc during debug         */  
    beq stack_setup  
    ldr r2, _armboot_start  
    ldr r3, _bss_start  
    sub r2, r3, r2      /* r2 <- size of armboot            */  
    add r2, r0, r2      /* r2 <- source end address         */  
  
  
copy_loop:  
    ldmia   r0!, {r3-r10}       /* copy from source address [r0]    */  
    stmia   r1!, {r3-r10}       /* copy to   target address [r1]    */  
    cmp r0, r2          /* until source end addreee [r2]    */  
    ble copy_loop  
relocate: /* 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 /* don't reloc during debug         */
beq stack_setup
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /* r2 <- size of armboot            */
add r2, r0, r2 /* r2 <- source end address         */




copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0]    */
stmia r1!, {r3-r10} /* copy to   target address [r1]    */
cmp r0, r2 /* until source end addreee [r2]    */
ble copy_loop五.初始化堆栈,就是将堆栈指针指向一个确切的地址
[plain] view plaincopyprint?
stack_setup:  
    ldr r0, _TEXT_BASE      /* upper 128 KiB: relocated uboot   */  
    sub r0, r0, #CONFIG_SYS_MALLOC_LEN  /* malloc area              */  
    sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                 */  
#ifdef CONFIG_USE_IRQ  
    sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)  
#endif  
    sub sp, r0, #12     /* leave 3 words for abort-stack    */  
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot   */
sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area              */
sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                 */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack    */六.清除bss段
[plain] view plaincopyprint?
clear_bss:  
    ldr r0, _bss_start      /* find start of bss segment        */  
    ldr r1, _bss_end        /* stop here                        */  
    mov r2, #0x00000000     /* clear                            */  
  
clbss_l:str r2, [r0]        /* clear loop...                    */  
    add r0, r0, #4  
    cmp r0, r1  
    ble clbss_l  
clear_bss:
ldr r0, _bss_start /* find start of bss segment        */
ldr r1, _bss_end /* stop here                        */
mov r2, #0x00000000 /* clear                            */


clbss_l:str r2, [r0] /* clear loop...                    */
add r0, r0, #4
cmp r0, r1
ble clbss_l七.跳转到第二阶段的 start_armboot 函数执行。
[plain] view plaincopyprint?
ldr pc, _start_armboot  
  
start_armboot:  .word start_armboot   
ldr pc, _start_armboot


_start_armboot: .word start_armboot
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值