1. 程式人生 > 實用技巧 >u-boot的第一階段

u-boot的第一階段

u-boot的第一階段的任務是完成 部分硬體的設定:

1.設定CPU工作在管理員模式

1 mrs    r0,cpsr
2 bic    r0,r0,#0x1f
3 orr    r0,r0,#0xd3
4 msr    cpsr,r0

2.關閉看門狗

 1 /* turn off the watchdog */
 2 #if defined(CONFIG_S3C2400)
 3 # define pWTCON        0x15300000
 4 # define INTMSK        0x14400008    /* Interupt-Controller base addresses */
 5 # define CLKDIVN    0x14800014    /* clock divisor register */
6 #elif defined(CONFIG_S3C2410) 7 # define pWTCON 0x53000000 8 # define INTMOD 0X4A000004 9 # define INTMSK 0x4A000008 /* Interupt-Controller base addresses */ 10 # define INTSUBMSK 0x4A00001C 11 # define CLKDIVN 0x4C000014 /* clock divisor register */ 12 #endif 13 14 #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
15 ldr r0, =pWTCON 16 mov r1, #0x0 17 str r1, [r0]

3.禁止所有中斷

1     mov    r1, #0xffffffff
2     ldr    r0, =INTMSK
3     str    r1, [r0]
4 # if defined(CONFIG_S3C2410)
5     ldr    r1, =0x3ff
6     ldr    r0, =INTSUBMSK
7     str    r1, [r0]
8 # endif

4.設定時鐘

 1 #define S3C2440_MPLL_400MHZ     ((0x5c<<12
)|(0x01<<4)|(0x01)) 2 #define S3C2440_UPLL_48MHZ ((0x38<<12)|(0x02<<4)|(0x02)) 3 #define S3C2440_CLKDIV (0x05) // | (1<<3)) /* FCLK:HCLK:PCLK = 1:4:8, UCLK = UPLL/2 */ 4 5 ldr r1, =CLKDIVN 6 mov r2, #S3C2440_CLKDIV 7 str r2, [r1] 8 9 mrc p15, 0, r1, c1, c0, 0 // read ctrl register 10 orr r1, r1, #0xc0000000 // Asynchronous 11 mcr p15, 0, r1, c1, c0, 0 // write ctrl register 12 13 ldr r0,=LOCKTIME 14 ldr r1,=0xffffff 15 str r1,[r0] 16 // delay 17 mov r0, #0x200 18 1: subs r0, r0, #1 19 bne 1b 20 21 // Configure MPLL 22 ldr r0,=MPLLCON 23 ldr r1,=S3C2440_MPLL_400MHZ 24 str r1,[r0] 25 // delay 26 mov r0, #0x200 27 1: subs r0, r0, #1 28 bne 1b 29 30 //Configure UPLL 31 ldr r0, =UPLLCON 32 ldr r1, =S3C2440_UPLL_48MHZ 33 str r1, [r0] 34 // delay 35 mov r0, #0x200 36 1: subs r0, r0, #1 37 bne 1b

5.使能SDRAM

 1 adr    r0, _start        /* r0 <- current position of code   */
 2     ldr    r1, _TEXT_BASE        /* test if we run from flash or RAM */
 3     cmp     r0, r1                  /* don't reloc during debug         */
 4     blne    cpu_init_crit
 5 
 6 
 7 
 8 cpu_init_crit:
 9     /*
10      * flush v4 I/D caches
11      */
12     mov    r0, #0
13     mcr    p15, 0, r0, c7, c7, 0    /* flush v3/v4 cache */
14     mcr    p15, 0, r0, c8, c7, 0    /* flush v4 TLB */
15 
16     /*
17      * disable MMU stuff and caches
18      */
19     mrc    p15, 0, r0, c1, c0, 0
20     bic    r0, r0, #0x00002300    @ clear bits 13, 9:8 (--V- --RS)
21     bic    r0, r0, #0x00000087    @ clear bits 7, 2:0 (B--- -CAM)
22     orr    r0, r0, #0x00000002    @ set bit 2 (A) Align
23     orr    r0, r0, #0x00001000    @ set bit 12 (I) I-Cache
24     mcr    p15, 0, r0, c1, c0, 0
25 
26     /*
27      * before relocating, we have to setup RAM timing
28      * because memory timing is board-dependend, you will
29      * find a lowlevel_init.S in your board directory.
30      */
31     mov    ip, lr
32     bl    lowlevel_init
33     mov    lr, ip
34     mov    pc, lr
35 
36 
37 
38 _TEXT_BASE:
39     .word    TEXT_BASE
40 
41 .globl lowlevel_init
42 lowlevel_init:
43     /* memory control configuration */
44     /* make r0 relative the current location so that it */
45     /* reads SMRDATA out of FLASH rather than memory ! */
46     ldr     r0, =SMRDATA
47     ldr    r1, _TEXT_BASE
48     sub    r0, r0, r1
49     ldr    r1, =BWSCON    /* Bus Width Status Controller */
50     add     r2, r0, #13*4
51 0:
52     ldr     r3, [r0], #4
53     str     r3, [r1], #4
54     cmp     r2, r0
55     bne     0b
56 
57     /* everything is fine now */
58     mov    pc, lr
59 
60     .ltorg
61 /* the literal pools origin */
62 
63 SMRDATA:
64     .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)) 
65     .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
66     .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
67     .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
68     .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
69     .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
70     .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
71     .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
72     .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
73     .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
74     .word 0xb1
75     .word 0x30
76     .word 0x30

6.設定棧

1 stack_setup:
2     ldr    r0, _TEXT_BASE        /* upper 128 KiB: relocated uboot   */
3     sub    r0, r0, #CFG_MALLOC_LEN    /* malloc area                      */
4     sub    r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo                        */
5 
6 #ifdef CONFIG_USE_IRQ
7     sub    r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
8 #endif
9     sub    sp, r0, #12        /* leave 3 words for abort-stack    */

7.程式碼重定位

 1 relocate:                /* relocate U-Boot to RAM        */
 2     adr    r0, _start        /* r0 <- current position of code   */
 3     ldr    r1, _TEXT_BASE        /* test if we run from flash or RAM */
 4     cmp     r0, r1                  /* don't reloc during debug         */
 5     beq     clear_bss
 6     
 7     ldr    r2, _armboot_start
 8     ldr    r3, _bss_start
 9     sub    r2, r3, r2        /* r2 <- size of armboot            */
10 #if 1
11     bl  CopyCode2Ram    /* r0: source, r1: dest, r2: size */
12 #else
13     add    r2, r0, r2        /* r2 <- source end address         */
14 
15 copy_loop:
16     ldmia    r0!, {r3-r10}        /* copy from source address [r0]    */
17     stmia    r1!, {r3-r10}        /* copy to   target address [r1]    */
18     cmp    r0, r2            /* until source end addreee [r2]    */
19     ble    copy_loop
 1 int CopyCode2Ram(unsigned long start_addr, unsigned char *buf, int size)
 2 {
 3     unsigned int *pdwDest;
 4     unsigned int *pdwSrc;
 5     int i;
 6 
 7     if (bBootFrmNORFlash())
 8     {
 9         pdwDest = (unsigned int *)buf;
10         pdwSrc  = (unsigned int *)start_addr;
11         /* 從 NOR Flash啟動 */
12         for (i = 0; i < size / 4; i++)
13         {
14             pdwDest[i] = pdwSrc[i];
15         }
16         return 0;
17     }
18     else
19     {
20         /* 初始化NAND Flash */
21         nand_init_ll();
22         /* 從 NAND Flash啟動 */
23         nand_read_ll_lp(buf, start_addr, (size + NAND_BLOCK_MASK_LP)&~(NAND_BLOCK_MASK_LP));
24         return 0;
25     }
26 }

8.清除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, r0, #4
    cmp    r0, r1
    ble    clbss_l

第一階段到這結束,後面經過一個C函式跳轉至u-boot啟動的第二階段