通过大家的讲解,我也稍微明白了一些。 看U-Boot中start.S,还有几处不太明白,可能还是没有理解好吧…… #include <config.h> #include <version.h>
#define PINSEL0 0xe002c000 #define PINSEL2 0xe002c014 #define BCFG0 0xffe00000 #define BCFG1 0xffe00004 #define MEMMAP 0xe01fc040 #define PLLCON 0xe01fc080 #define PLLCFG 0xe01fc084 #define PLLSTAT 0xe01fc088 #define PLLFEED 0xe01fc08c #define VPBDIV 0xe01fc100 #define RAM_SIZE 0x20000 + 1024 * 128 #define RAM_BASE 0x81000000 .globl _start _start: ldr pc,reset add pc,pc,#0x01000000 疑问1 add pc,pc,#0x01000000 add pc,pc,#0x01000000 add pc,pc,#0x01000000 add pc,pc,#0x01000000 add pc,pc,#0x01000000 add pc,pc,#0x01000000
.balignl 16,0xdeadbeef
_TEXT_BASE: .word TEXT_BASE
.globl _armboot_start _armboot_start: .word _start
.globl _bss_start _bss_start: .word __bss_start
.globl _bss_end _bss_end: .word _end
reset: /* **first set cpu to svc32 mode */ mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0x13 msr cpsr,r0 /* ok the cpu is setted to svc32 mode then we should first close the watch dog and the others Interrupt */
Init_cpu: ldr r1,=PINSEL0 ldr r2,=0x0//common io str r2,[r1] ldr r1,=PINSEL2 ldr r2,=0x0f814914 str r2,[r1]
ldr r1,=BCFG0 ldr r2,=0x1000ffef str r2,[r1] ldr r1,=BCFG1 ldr r2,=0x1000ffef str r2,[r1]
//////////////////////////////////////////////////////////////////////////////// PLL_CON: .word 0xaa .word 0x55
#define Fosc 11059200 #define Fcclk (Fosc*4) #define Fcco (Fcclk*4) #define Fpclk (Fcclk/4)*1
Init_target: ldr r1,=MEMMAP mov r2,#3 str r2,[r1]
ldr r1,=VPBDIV mov r2,#0 str r2,[r1] ldr r1,=PLLCFG mov r2,#0x23 str r2,[r1] ldr r1,=PLLCON mov r2,#01 str r2,[r1] ldr r1,=PLLFEED mov r2,#0xaa str r2,[r1]
mov r2,#0x55 str r2,[r1] wait_lock: ldr r1,=PLLSTAT ldr r2,[r1] tst r2,#0x400 beq wait_lock
ldr r1,=PLLCON mov r2,#0x03 str r2,[r1] ldr r1,=PLLFEED mov r2,#0xaa str r2,[r1] mov r2,#0x55 str r2,[r1]
/* relocate the mem */ relocate: adr r0,_start 疑问2 ldr r1,_TEXT_BASE //compare how many mem we should copy ldr r2,_armboot_start ldr r3,_bss_start sub r2,r3,r2//r3-r2->r2 add r2,r0,r2//from start to _bss_start copy_loop: ldmia r0!,{r3-r10} stmia r1!,{r3-r10} cmp r0,r2 ble copy_loop //ok ,finish copyed ///////////////////////////////////////////// //now setup the stack and ready to jump to C code adr r0,real_vectors add r2,r0,#1024 ldr r1,=0x81000000//this is the base of first ram //////////////////////////////////////////////////////// //new added add r1,r1,#0x08 //////////////////////////////////////////////////////// v_copy_loop: ldmia r0!,{r3-r10} stmia r1!,{r3-r10} cmp r0,r2 ble v_copy_loop stack_setup:
ldr r0,_TEXT_BASE sub r0,r0,#CFG_MALLOC_LEN sub r0,r0,#CFG_GBL_DATA_SIZE #ifdef CONFIG_USE_IRQ sub r0,r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub r0,r0,#12 mov fp,#0 疑问3 mov a2,#0 ///////////////////////////////////////////// ldr pc,_start_armboot _start_armboot: .word start_armboot
real_vectors: 疑问4 b reset b undefined b software b preabort b dataabort b not_use b irq b fiq
undefined: mov r6,#3 b reset software: mov r6,#4 b reset preabort: mov r6,#5 b reset dataabort: mov r6,#6 b reset not_use: mov r6,#7 b reset irq: mov r6,#8 b reset fiq: mov r6,#9 b reset 上边这段代码把MEMMAP设定为0x3,就是说中断向量从外部存储器重新映射,代码已经把中断向量表拷贝到RAM的基地址处0x81000000,那么我在疑问一的地方,是否可以添加add pc,pc,#0x01000000 这样的指令,发生请求时先到flash去指令(pc指针是0x8@@@@@@@吧?),然后将pc指针相加,指到外部的RAM空间0x81000000中,那里有中断向量表的一份拷贝。 疑问2的地方,为什么要用adr呢?那adr r0,_start, 当程序在flash中运行时和程序在ram运行时r0值是否相同,还是r0值根本不变,是由uboot.lds中指定呢?程序里有一个_start,lds文件也有一个?到底曲哪个呢? 疑问3的地方一直不明白在干什么... 疑问4的地方使用的跳转指令,执行到这的时候,一定在ram里了,那它跳转的时候是到了flash中的代码,还是到了ram中的代码呢 这些问题困扰了我很久了。。。。。 |