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


u-boot分析(十)

  上篇博文我們按照210的啟動流程,分析到了初始化nand flash,由於接下來的關閉ABB比較簡單所以跳過,所以我們今天按照u-boot的啟動流程繼續進行分析。

今天我們會用到的文檔:

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

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

3.        210芯片手冊:S5PV210_UM_REV1.1(我的不知道為什么傳不上去大家去百度搜吧)

4.        Nand flash芯片手冊:大家根據自己的nand flash芯片型號,找到對應的手冊

 

今天我們會分析到以下內容:

1.      設置堆棧

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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM