u-boot分析(十)----堆棧設置|代碼拷貝|完成BL1階段

u-boot分析(十)數據結構

  上篇博文咱們按照210的啓動流程,分析到了初始化nand flash,因爲接下來的關閉ABB比較簡單因此跳過,因此咱們今天按照u-boot的啓動流程繼續進行分析。函數

今天咱們會用到的文檔:ui

1.        2440芯片手冊:http://download.csdn.net/detail/wrjvszq/8358949spa

2.        6410芯片手冊:http://download.csdn.net/detail/wrjvszq/8358965.net

3.        210芯片手冊:S5PV210_UM_REV1.1(個人不知道爲何傳不上去你們去百度搜吧)指針

4.        Nand flash芯片手冊:你們根據本身的nand flash芯片型號,找到對應的手冊code

 

今天咱們會分析到如下內容:orm

1.      設置堆棧blog

2.      複製BL2到內存,並跳到內存執行代碼進程

 

l  設置棧

1.       什麼棧

相信學過數據結構的,都知道棧是一種先進後出的數據存儲形式。

2.       基本概念

l  滿棧:堆棧指針SP老是指向最後進棧的數據。(以下圖)

l  空棧:SP老是指向下一個將要存放數據的空位置(以下圖)

l  升棧:SP由低地址向高地址移動。(以下圖)

l  降棧:SP由高地址向低地址移動。(以下圖)

l  棧幀:每一個進程程對應一個棧空間,進程中的函數會在該棧空間分配到一個屬於本身的空間,該空間就是棧幀。棧幀有邊界,上邊界是FPr11),下邊界是SPr13)。

注:arm採用的是滿降棧

3.       如何初始化

棧的初始化比較簡單,咱們只要將SP指針指向內存中的某地址便可。在此就不過多分析

 

1 call_board_init_f:
2     ldr    sp, =(CONFIG_SYS_INIT_SP_ADDR)
3     bic    sp, sp, #7 /* 8-byte alignment for ABI compliance */
4     ldr    r0,=0x00000000

 

l  複製BL2到內存,並跳到內存執行代碼

由於咱們初始化了棧,因此此時徹底能夠用C語言完成咱們代碼的拷貝,整個過程也是至關簡單的,代碼也沒有任何難度,因此在此再也不分析。 

 1 void board_init_f_nand(unsigned long bootflag)
 2 {
 3         __attribute__((noreturn)) void (*uboot)(void);
 4         copy_uboot_to_ram_nand();
 5 
 6         /* Jump to U-Boot image */
 7         uboot = (void *)CONFIG_SYS_TEXT_BASE;
 8     (*uboot)();
 9         /* Never returns Here */
10 }

 

 1 int copy_uboot_to_ram_nand (void)
 2 {
 3     int large_block = 0;
 4     int i;
 5     vu_char id;
 6 
 7     NAND_CONTROL_ENABLE();
 8         NAND_ENABLE_CE();
 9         NFCMD_REG = NAND_CMD_READID;
10         NFADDR_REG =  0x00;
11 
12     /* wait for a while */
13         for (i=0; i<200; i++);
14     id = NFDATA8_REG;
15     id = NFDATA8_REG;
16 
17     if (id > 0x80)
18         large_block = 1;
19 
20     /* read NAND Block.
21      * 128KB ->240KB because of U-Boot size increase. by scsuh
22      * So, read 0x3c000 bytes not 0x20000(128KB).
23      */
24     return nandll_read_blocks(CONFIG_SYS_TEXT_BASE, COPY_BL2_SIZE, large_block);
25 }
 1 static int nandll_read_blocks (ulong dst_addr, ulong size, int large_block)
 2 {
 3         uchar *buf = (uchar *)dst_addr;
 4         int i;
 5     uint page_shift = 9;
 6 
 7     if (large_block)
 8         page_shift = 11;
 9 
10         /* Read pages */
11         for (i = (0x6000>>page_shift); i < (size>>page_shift); i++, buf+=(1<<page_shift)) {
12                 nandll_read_page(buf, i, large_block);//最終調用到了nand的頁讀
13         }
14 
15         return 0;
16 }
相關文章
相關標籤/搜索