U-BOOT start.S分析
U-BOOT start.S分析
一.存储八个异常跳转表,以及七个异常地址,一个内存标志,deadbeef 表示以上内存禁止操作
.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 标号的地址。
_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模式 mrs r0,cpsr bic r0,r0,#0x1f orr r0,#0xd3 msr cpsr,r0 ? 2.关闭看门狗。 ldr r0,=pWTCON mov r1,#0x0 str r1,[r0] ? 3.关中断,以及子中断。 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,[r0] #endif ? 4.设置时钟寄存器,使 FCLK = 400M HCLK = 100M PCLK = 50M /* FCLK:HCLK:PCLK = 1:4:8 */ ldr r0,=CLKDIVN mov r1,#5 str r1,[r0] mrc p15,r1,c1,c0,0 orr r1,#0xc0000000 mcr p15,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无效 mov r0,#0 mcr p15,c7,0 /* flush v3/v4 cache */ mcr p15,c8,0 /* flush v4 TLB */ ? ? (2) 关闭MMU mrc p15,0 bic r0,#0x00002300 @ clear bits 13,9:8 (--V- --RS) bic r0,#0x00000087 @ clear bits 7,2:0 (B--- -CAM) orr r0,#0x00000002 @ set bit 2 (A) Align orr r0,#0x00001000 @ set bit 12 (I) I-Cache mcr p15,0 ? ? (3) 进入lowlevel_init.S,初始化内存。因为内存所用芯片是与开发板有关,所以这个文件在/board里面 mov ip,lr bl lowlevel_init ? 6.判断代码位置,比较_start 的地址和 _TEXT_BASE 是否相同,如果相同说明代码是在内存中,否则就在内部RAM中,或者NorFlash中. 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启动. #define rBWSCON 0x48000000 mov r0,#rBWSCON ldr r0,[r0] bic 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函数做好准备。 #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,#oNFCONF] ldr r2,#oNFCONF] ldr r2,=( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control str r2,#oNFCONT] ldr r2,#oNFCONT] ldr r2,=(0x6) @ RnB Clear str r2,#oNFSTAT] ldr r2,#oNFSTAT] mov r2,#0xff @ RESET command strb r2,#oNFCMD] mov r3,#0 @ wait nand1: add r3,r3,#0x1 cmp r3,#0xa blt nand1 nand2: ldr r2,#oNFSTAT] @ wait ready tst r2,#0x4 beq nand2 ldr r2,#oNFCONT] orr r2,#0x2 @ Flash Memory Chip Disable str r2,#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 复制到内存。 bl nand_read_ll ? ? (3) 验证是否复制成功,主要检查在地址0x0 和地址_TEXT_BASE处的以后4K代码是否完全一样。如果一样就正常执行,否则死在这里了。 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,#4 beq stack_setup bne go_next notmatch: loop3: b loop3 @ infinite loop? 2 NORFLASH启动 ? ? (1) 简单的拷贝代码 relocate: /* relocate U-Boot to RAM */ adr r0,r1 /* don't reloc during debug */ beq stack_setup ldr r2,_armboot_start ldr r3,_bss_start sub r2,r2 /* r2 <- size of armboot */ add r2,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 五.初始化堆栈,就是将堆栈指针指向一个确切的地址
stack_setup: ldr r0,_TEXT_BASE /* upper 128 KiB: relocated uboot */ sub r0,#CONFIG_SYS_MALLOC_LEN /* malloc area */ sub r0,#CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ #ifdef CONFIG_USE_IRQ sub r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp,#12 /* leave 3 words for abort-stack */ 六.清除bss段
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,#4 cmp r0,r1 ble clbss_l 七.跳转到第二阶段的 start_armboot 函数执行。
ldr pc,_start_armboot _start_armboot: .word start_armboot (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |