#嵌入式Linux最小系統移植# 對uboot移植和裁剪的一點點個人思考和總結


思路:
1.分析啓動流程
2.移植config文件(smdk440_config)
3.移植包含控制條件編譯宏的.h文件(configs/s3c2440.h)
4.移植板級初始化.c文件(s3c2440.c)
5.移植RAM初始化?DDR?
6.移植NorFlash
7.移植NandFlash
8.uboot應該能啓動了?

//分析啓動流程
1.make xx_config
2.在makefile中有以下依賴關係
%_config:
    $(MKCONFIG) 
3.在mkconfig中會去解析board.cfg,根據輸入的xx去匹配board.cfg中的TARGET項,提取出ARCH、CPU、SOC、VENDOR等
然後自動生成config.h,其中config.h中定義了一些關於ARCH、SOC等的宏,以及包含configs/xx.h頭文件來控制uboot中的條件編譯 

4. make 生成 uboot.bin
uboot.bin依賴於 OBJ LIB LDS,其中LIB變量爲cpu/ drivers/ board/
隨後依次進入各文件夾進行make,生成buitin.o,最後鏈接成uboot.bin



start.s 
    ...
    lowlevel_init.S 
    ...
    _main(arm/lib/crt0.S) 
        board_init_f
         board_early_init_f 
        board_init_r
            board_init

start.S主要完成了: 
a.初始化異常向量表 
b.設置cpu svc模式,關中斷
c.配置cp15協處理器,設置異常向量入口
d.配置cp15,初始化mmu cache tlb
e.板級初始化,pll memory初始化


一、Uboot從norflash啓動和nandflash啓動的區別
1.norflash啓動
norflash是可以片上執行代碼(XIP)的,也就是說,將bootloader燒寫到norflash的開始地址後,開發板上電以後,cpu直接從0x00開始執行(也就是在norflash中執行)整個uboot,直到引導內核啓動。

2.nandflash啓動
由於norflash有地址線,因此可以直接執行代碼,而nandflash只有數據線,因此無法片上執行。開發板上電以後,nandflash控制器會自動把nandflash中的前4K代碼拷貝至CPU內部RAM(SRAM-CACHE),
同時把片內SRAM映射到0x00,隨後CPU從0x00開始執行,這個過程程序不需要干涉。但是uboot肯定是大於4K,這樣的話4K以後的代碼怎麼辦?
所以如果是從nandflash啓動,前4K代碼首先會設置CPU運行模式,關看門狗,設置時鐘,關中斷,初始化內存,初始化nandflash,設置堆棧,然後把整個bootloader搬運到SDRAM中,並跳轉到SDRAM中
執行。


一、總結:
對於Uboot來說,主要有兩大階段,第一階段主要使用彙編語言實現,包括cpu、時鐘、關watchdog、mmu等初始化,並設置堆棧,爲C語言調用做好準備。
隨後進入board_init_f階段,該階段的主要工作就是初始化Clock、serial和RAM,實現最精簡系統啓動。
最後調用board_init_r函數,該階段主要是做了一些mmc、flash、eth等外設的初始化以及環境變量的設置等,最後進入main_loop死循環,打印命令行,等待命令輸入和解析。

uboot移植主要涉及幾方面:
1.向board_cfg文件中添加需要支持的新板,包括SOC、CPU、VENDOR、TARGET等項;
2.向board/文件夾中添加對應的板級函數,如board/samsung/mini2440(mini2440.c Makefile)等;
3.向include/configs文件夾中添加對應的頭文件如mini2440.h,這個文件在mkconfig時會被包含進config.h,用於控制Uboot編譯過程的各條件編譯。
4.修改arch/cpu文件夾下對應的start.S,適配對應的cpu型號(比如主頻、時鐘等)。
5.Uboot可以從norflash、nandflash、RAM啓動,不同的啓動方式在start.S會有不同。


本次Uboot移植主要修改了的文件夾:
u-boot-2012.10\board\samsung\mini2440
u-boot-2012.10\include\configs\mini2440.h 
u-boot-2012.10\arch\arm\cpu\u-boot.lds
u-boot-2012.10\arch\arm\cpu\arm920t\start.S 


本次uboot移植遇到的坑:
1.一操作全局變量(賦值等操作)就卡死;一打印(如puts、printf)就卡死,最後發現原因是使用的arm-linux-gcc4.7.3交叉編譯器的原因,換成4.4.3就好了,原因未明。


uboot移植需要知道的點:
1.要完整一個完全新板的uboot移植並沒有想象的那麼簡單:
a.需要對所使用的cpu型號很熟悉(datasheet) ------> 因爲要配置時鐘、各寄存器等;
b.需要對某一架構(如arm、ppc)熟悉 ------> 因爲在start.S中要配置svc32模式等;
c.需要對某一體系下的彙編指令熟悉(如arm) -----> 因爲start.S都是用匯編實現的;
d.需要對外設的硬件特性熟悉 -----> 比如uboot對nandflash的裸讀/寫(還有要熟悉cpu中的nandflash控制器的寄存器讀寫);

2.uboot編譯過程是通過config.h(會包含板級頭文件,如mini2440.h)文件內定義的宏去控制條件編譯,這是要重點關注的:
a.由於第一點所需要的知識點太過底層,而且一般由芯片廠商實現,如果不想進芯片公司的話,沒有興趣去深入瞭解。因此,關注重點放在了第二點。
在實際的產品開發時,芯片廠商會提供SDK,內含移植好的uboot,但是自研板子的外設不可能和芯片廠商的完全一樣。所以,我們就需要知道如何控制uboot
支持不同的外設。
b.如何知道某個driver是由哪個宏控制的?-----> 可以去driver/文件夾內找,在Makefile中會通過宏去控制對應的c文件是否要包含進去進行編譯。
c.除了支持不同的外設,還需要知道uboot的默認配置在哪改。------> 也是在config.g文件中的各種宏定義。

3.uboot的調試方式:
a.uboot在第一階段沒有初始化串口,所以是沒有打印的,這個時候的調試方式主要是通過點燈來查看運行狀態。
b.還有可以通過彙編直接操作寄存器來輸出相關信息。
c.本次調試還是在確認硬件工作正常的情況下調試的,因此不會去懷疑硬件問題,只需關注代碼實現。如果真的是全新的板子,那麼Uboot的調試難度肯定大幅增加。


UBOOT啓動流程:
時鐘初始化、關看門狗、MMU、TLB初始化 ---> RAM初始化 ---> FLASH_TO_RAM ---> ---> board_init_f ---> 
串口初始化 ---> RAM信息配置 ---> 代碼重定位(對RAM空間進行規劃,如堆棧空間等)---> board_init_r ---> 
NORFLASH初始化 ---> NANDFLASH初始化 ---> ETH以太網PHY初始化 ---> main_loop ---> 接收命令解析命令











































發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章