文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>u-boot stage1分析

u-boot stage1分析

时间:2010-10-13  来源:strongerII

u-boot stage 1分析

嵌入式系统设计与应用 2008-09-02 23:05:47 阅读72 评论0  字号:大中小 订阅

#include <config.h>
#include <version.h>

/*
 * 全局入口为.globl_start
 * 设置异常向量
*/
.globl _start
_start: b       reset                 /* 0x00000000*/复位
 ldr pc, _undefined_instruction    /* 0x00000004*/未定义指令
 ldr pc, _software_interrupt       /* 0x00000008*/软件中断
 ldr pc, _prefetch_abort           /* 0x0000000c*/预取指中止
 ldr pc, _data_abort               /* 0x00000010*/访问数据存储器中止
 ldr pc, _not_used                 /* 0x00000014*/该向量没有使用
 ldr pc, _irq                      /* 0x00000018*/正常中断
 ldr pc, _fiq                      /* 0x0000001c*/快速中断

_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/*该伪操作指定对齐方式,16字节对齐*/

/////////////////////////////////////上面用于定义异常向量//////////////////////////////
 *************************************************************************
 *
 * Startup Code (reset vector)
 *
 * do important init only if we don't start from memory!
 * relocate armboot to ram
 * setup stack
 * jump to second stage
 *
 *************************************************************************
 */

_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


/*
 * the actual reset code,这边才是真正的开始,开机后直接跳到这边执行
 */

reset:
 /*
  * set the cpu to SVC32 mode
  * cpsr的低八位是:I F T M M M M M
  *  中断禁止位:I F  Thumb位 模式位  svc为10011
  */
 mrs r0,cpsr       /*将处理器状态传送到到 ARM 寄存器的指令*/
 bic r0,r0,#0x1f   /*位清除指令*/
 orr r0,r0,#0xd3   /*置位指令,禁止中断,进入SVC模式*/
 msr cpsr,r0

/* turn off the watchdog */
#if defined(CONFIG_S3C2400)
# define pWTCON  0x15300000
# define INTMSK  0x14400008 /* Interupt-Controller base addresses */
# define CLKDIVN 0x14800014 /* clock divisor register */
#elif defined(CONFIG_S3C2410)
# define pWTCON  0x53000000     /*看门狗定时器控制寄存器*/
# define INTMSK  0x4A000008 /* Interupt-Controller base addresses */中断控制器基地址
# define INTSUBMSK 0x4A00001C
# define CLKDIVN 0x4C000014 /* clock divisor register */时钟分频器寄存器
#endif

#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
 ldr     r0, =pWTCON
 mov     r1, #0x0
 str     r1, [r0]/*关掉看门狗*/

 /*
  * mask all IRQs by setting all bits in the INTMR - default,关掉所有中断
  */
 mov r1, #0xffffffff
 ldr r0, =INTMSK
 str r1, [r0]
# if defined(CONFIG_S3C2410)
 ldr r1, =0x3ff
 ldr r0, =INTSUBMSK
 str r1, [r0]
# endif

 /* FCLK:HCLK:PCLK = 1:2:4 */
 /* default FCLK is 120 MHz ! */设置CPU的频率,默认为120MHz
 ldr r0, =CLKDIVN
 mov r1, #3
 str r1, [r0]
#endif /* CONFIG_S3C2400 || CONFIG_S3C2410 */

 /*
  * we do sys-critical inits only at reboot,
  * not when booting from ram!
  */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
 bl cpu_init_crit
#endif

#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate:    /* relocate U-Boot to RAM     */把自身拷贝到RAM中
 adr r0, _start  /* r0 <- current position of code   */
 ldr r1, _TEXT_BASE  /* test if we run from flash or RAM *//* 把_TEXT_BASE地址,就是BOOT在RAM中运行地址 */
 cmp     r0, r1                  /* don't reloc during debug         */ /* 比较两个地址是否相同,如果相同,就已经在RAM运行,否则就是FLASH中运行。*/

 beq     stack_setup/*如果已经是在RAM中,则跳转*/

 ldr r2, _armboot_start
 ldr r3, _bss_start
 sub r2, r3, r2  /* r2 <- size of armboot            */
 add r2, r0, r2  /* r2 <- source end address         *//*r0为基地址,r2为末地址*/

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//循环拷贝
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */

 /* Set up the stack          */栈空间设置
stack_setup:
 ldr r0, _TEXT_BASE  /* upper 128 KiB: relocated uboot   */
 sub r0, r0, #CFG_MALLOC_LEN /* malloc area                      */
 sub r0, r0, #CFG_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    */设置sp,留下3个字为Abort

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/*循环清除BSS段*/

#if 0
 /* try doing this stuff after the relocation */
 ldr     r0, =pWTCON
 mov     r1, #0x0
 str     r1, [r0]

 /*
  * mask all IRQs by setting all bits in the INTMR - default
  */
 mov r1, #0xffffffff
 ldr r0, =INTMR
 str r1, [r0]

 /* FCLK:HCLK:PCLK = 1:2:4 */
 /* default FCLK is 120 MHz ! */
 ldr r0, =CLKDIVN
 mov r1, #3
 str r1, [r0]
 /* END stuff after relocation */
#endif

#ifdef CONFIG_S3C2410_NAND_BOOT
    bl    copy_myself
 
      @ jump to ram
    ldr   r1, =on_the_ram
    add  pc, r1, #0
    nop
    nop
    1:    b     1b          @ infinite loop/*无限循环*/
 
on_the_ram:
#endif

 ldr pc, _start_armboot

_start_armboot: .word start_armboot/*开始进入C代码部分*/

#ifdef CONFIG_S3C2410_NAND_BOOT
copy_myself:
    mov r10, lr
@ reset NAND
    mov r1, #NAND_CTL_BASE
     ldr   r2, =0xf830           @ initial value
    str   r2, [r1, #oNFCONF]
    ldr   r2, [r1, #oNFCONF]
    bic  r2, r2, #0x800              @ enable chip
    str   r2, [r1, #oNFCONF]
    mov r2, #0xff         @ RESET command
    strb r2, [r1, #oNFCMD]
    mov r3, #0                   @ wait

1:add  r3, r3, #0x1
    cmp r3, #0xa
    blt   1b
2:ldr   r2, [r1, #oNFSTAT]      @ wait ready
    tst    r2, #0x1
    beq  2b
    ldr   r2, [r1, #oNFCONF]
    orr  r2, r2, #0x800              @ disable chip
    str   r2, [r1, #oNFCONF]

@ 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 vivi to RAM
    ldr   r0, =UBOOT_RAM_BASE
    mov     r1, #0x0
    mov r2, #0x20000
    bl    nand_read_ll
    tst    r0, #0x0
    beq  ok_nand_read

#ifdef CONFIG_DEBUG_LL
    bad_nand_read:
    ldr   r0, STR_FAIL
    ldr   r1, SerBase
    bl    PrintWord
1:b     1b          @ infinite loop
#endif

ok_nand_read:
#ifdef CONFIG_DEBUG_LL
    ldr   r0, STR_OK
    ldr   r1, SerBase
    bl    PrintWord
#endif

@ verify
    mov r0, #0
    ldr   r1, =UBOOT_RAM_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  done_nand_read
    bne  go_next

notmatch:
#ifdef CONFIG_DEBUG_LL
    sub  r0, r0, #4
    ldr   r1, SerBase
    bl    PrintHexWord
    ldr   r0, STR_FAIL
    ldr   r1, SerBase
    mov r2, #0
     mov r3, r2
    mov r4, r2
    mov r5, r2
    mov r6, r2
    mov r7, r2
    mov r8, r2
    mov r9, r2

clear_loop:
    stmia      r0!, {r2-r9}
    subs r1, r1, #(8 * 4)
    bne  clear_loop
    mov pc, lr

#endif

1:b     1b
done_nand_read:
#ifdef CONFIG_DEBUG_LL
    ldr   r0, STR_OK
    ldr   r1, SerBase
    bl    PrintWord
#endif
    mov pc, r10
@ clear memory
@ r0: start address
@ r1: length
    mem_clear:
    mov r2, #0
     mov r3, r2
    mov r4, r2
    mov r5, r2
    mov r6, r2
    mov r7, r2
    mov r8, r2
    mov r9, r2

clear_loop:
    stmia      r0!, {r2-r9}
    subs r1, r1, #(8 * 4)
    bne  clear_loop
    mov pc, lr

#endif @ CONFIG_S3C2410_NAND_BOOT

/*
 *************************************************************************
 *
 * CPU_init_critical registers
 *
 * setup important registers
 * setup memory timing
 *
 *************************************************************************
 */


cpu_init_crit:
 /*
  * flush v4 I/D caches
  */
 mov r0, #0
 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */使cache无效
 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */使TLB无效

 /*
  * disable MMU stuff and caches禁止MMU和cache
  */
 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

 /*
  * before relocating, we have to setup RAM timing重定位之前,应该先进行RAM时序的设置
  * because memory timing is board-dependend, you will
  * find a lowlevel_init.S in your board directory.
  */
 mov ip, lr
 bl lowlevel_init/*设置存储控制器的相关参数*/
 mov lr, ip
 mov pc, lr/*cpu_init_crit返回*/


/*
 *************************************************************************
 *
 * Interrupt handling
 *
 *************************************************************************
 */

@
@ IRQ stack frame.
@
#define S_FRAME_SIZE 72

#define S_OLD_R0 68
#define S_PSR  64
#define S_PC  60
#define S_LR  56
#define S_SP  52

#define S_IP  48
#define S_FP  44
#define S_R10  40
#define S_R9  36
#define S_R8  32
#define S_R7  28
#define S_R6  24
#define S_R5  20
#define S_R4  16
#define S_R3  12
#define S_R2  8
#define S_R1  4
#define S_R0  0

#define MODE_SVC 0x13
#define I_BIT  0x80

/*
 * use bad_save_user_regs for abort/prefetch/undef/swi ...
 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
 */

 .macro bad_save_user_regs
 sub sp, sp, #S_FRAME_SIZE
 stmia sp, {r0 - r12}   @ Calling r0-r12
 ldr r2, _armboot_start
 sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
 sub r2, r2, #(CFG_GBL_DATA_SIZE+8)  @ set base 2 words into abort stack
 ldmia r2, {r2 - r3}   @ get pc, cpsr
 add r0, sp, #S_FRAME_SIZE  @ restore sp_SVC

 add r5, sp, #S_SP
 mov r1, lr
 stmia r5, {r0 - r3}   @ save sp_SVC, lr_SVC, pc, cpsr
 mov r0, sp
 .endm

 .macro irq_save_user_regs
 sub sp, sp, #S_FRAME_SIZE
 stmia sp, {r0 - r12}   @ Calling r0-r12
 add     r8, sp, #S_PC
 stmdb   r8, {sp, lr}^                   @ Calling SP, LR
 str     lr, [r8, #0]                    @ Save calling PC
 mrs     r6, spsr
 str     r6, [r8, #4]                    @ Save CPSR
 str     r0, [r8, #8]                    @ Save OLD_R0
 mov r0, sp
 .endm

 .macro irq_restore_user_regs
 ldmia sp, {r0 - lr}^   @ Calling r0 - lr
 mov r0, r0
 ldr lr, [sp, #S_PC]   @ Get PC
 add sp, sp, #S_FRAME_SIZE
 subs pc, lr, #4   @ return & move spsr_svc into cpsr
 .endm

 .macro get_bad_stack
 ldr r13, _armboot_start  @ setup our mode stack
 sub r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
 sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack

 str lr, [r13]   @ save caller lr / spsr
 mrs lr, spsr
 str     lr, [r13, #4]

 mov r13, #MODE_SVC   @ prepare SVC-Mode
 @ msr spsr_c, r13
 msr spsr, r13
 mov lr, pc
 movs pc, lr
 .endm

 .macro get_irq_stack   @ setup IRQ stack
 ldr sp, IRQ_STACK_START
 .endm

 .macro get_fiq_stack   @ setup FIQ stack
 ldr sp, FIQ_STACK_START
 .endm

/*
 * exception handlers
 */
 .align  5
undefined_instruction:
 get_bad_stack
 bad_save_user_regs
 bl  do_undefined_instruction

 .align 5
software_interrupt:
 get_bad_stack
 bad_save_user_regs
 bl  do_software_interrupt

 .align 5
prefetch_abort:
 get_bad_stack
 bad_save_user_regs
 bl  do_prefetch_abort

 .align 5
data_abort:
 get_bad_stack
 bad_save_user_regs
 bl  do_data_abort

 .align 5
not_used:
 get_bad_stack
 bad_save_user_regs
 bl  do_not_used

#ifdef CONFIG_USE_IRQ

 .align 5
irq:
 get_irq_stack
 irq_save_user_regs
 bl  do_irq
 irq_restore_user_regs

 .align 5
fiq:
 get_fiq_stack
 /* someone ought to write a more effiction fiq_save_user_regs */
 irq_save_user_regs
 bl  do_fiq
 irq_restore_user_regs

#else

 .align 5
irq:
 get_bad_stack
 bad_save_user_regs
 bl  do_irq

 .align 5
fiq:
 get_bad_stack
 bad_save_user_regs
 bl  do_fiq

#endif

 .align     2
DW_STACK_START:
 .word      STACK_BASE+STACK_SIZE-4

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载