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

#嵌入式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中的前4
K程式碼拷貝至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 ---> 接收命令解析命令