Hi,大家好!我是CrazyCatJack,你們可以叫我CCJ或者瘋貓。今天我給大家帶來的是u-boot的源代碼匯編段分析,以后還會給大家講解后續的C代碼,請持續關注哦^_^
先簡單說一下u-boot,在嵌入式開發中,u-boot起着至關重要的作用:讀出嵌入式系統內核並啟動內核。因此非常有必要對u-boot進行理解,了解其是如何啟動內核的,這樣我們才能隨心所欲地初始化系統,無論基於什么架構,什么開發板,都能夠輕松的去啟動內核。這一點難道不是最有吸引力的嗎?
如果大家有看到我的前一篇博客,就會對u-boot的啟動有一定程度的了解了。執行u-boot,首先是從啟動文件start.S開始的。它位於你所用CPU的文件下。比如我的路徑就是:“uboot-1.1.6/cpu/arm920t/start.S”。這基於你具體使用的CPU架構。打開它:
首先看第一條語句,跳轉到reset語句執行。那我們來看reset。
根據注釋,我們知道是要先讓CPU進入SVC32模式,也就是管理模式。具體的匯編代碼不再分析,需要大家自己去學習。若是你已經掌握了一定的匯編,則完全可以閱讀本篇博客,不然還是建議先學習一下匯編。u-boot代碼量還是很大的,再接着往下來看:
根據注釋,我們要關閉看門狗,否則此時CPU會不斷地重啟重啟。。。很明顯,在定義了具體的SOC型號后,define寄存器地址。包括看門狗控制寄存器、中斷屏蔽寄存器、還有時鍾分頻。關閉看門狗,關閉所有的中斷。
這里如果你是從NOR Flash啟動的,這里的r0就是0。如果你是從下載器或者調試器直接將代碼下載到SDRAM的,r0就為你自己設置的SDRAM代碼段的啟動地址(詳情看我的上一篇博客)。這里會比較一下這兩個地址是否相同,就可以知道你是從哪里啟動的了,是從NOR Flash還是直接從SDRAM。如果你從SDRAM啟動,則說明你已經初始化了SDRAM。如果你是從FLASH啟動,則這里跳轉到 cpu_init_crit函數執行。
這里是關caches,關MMU,然后跳轉到lowlevel_init函數執行開發板相關的配置。
這一部分程序博主開始很不理解,因為這里涉及到了一個鏈接地址的概念。博主分不清此刻程序到底是在FLASH還是在RAM上。但是后來在論壇提問,大神給予了解答,博主終於懂了。這里的SMRDATA是即將在SDRAM存儲的13個寄存器的鏈接地址,也就是說此刻這13個寄存器的值並未真正存儲到SDRAM,而是在NOR FLASH中。但是我們用這個SDRAM上的寄存器鏈接地址減去SDRAM代碼段開始地址(_TEXT_BASE),就得出了相對地址。又因為NOR FLASH的起始地址是0,所以起始地址+相對地址就是這13個寄存器在NOR FLASH上真正存儲的開始地址。這段代碼就是因為上述原因而進行的地址轉換。目的是得到13個寄存器在NOR FLASH上存儲的開始地址。
我們接着分析,下一步根據注釋是設置堆棧,將代碼段地址給r0,這里我們設置的是0x33F80000.然后設置MALLOC段:分配空間,r0減去此段大小。再設置CFG_GBL_DATA段,同理r0減去此段大小,分配空間。再設置IRQ段、FIQ段。最后r0減去12,留出3個字節的空間。下一步是跳轉到clock_init設置時鍾。
relocate這段代碼是要將u-boot從FLASH復制到RAM。_start是當前代碼的開始地址,_TEXT_BASE是代碼段的鏈接地址,如果二者相等則證明是從RAM啟動,無需復制代碼。轉去執行清BSS段代碼。_armboot_start是在當前文件即start.S中定義的第一條指令的運行地址,_bss_start是在board/開發板型號/u-boot.lds中定義的代碼段結束地址。結束地址減去開始地址等於代碼段長度,賦值給r2。然后就是如果你是從FLASH啟動則需進行代碼賦值,這里是用C函數實現。
這里我們設置的是USB48MHZ,總時鍾400MHZ.根據代碼,再接下來是清BSS段。
所謂的BSS段就是未初始化的靜態變量和全局變量,或者初始化為0的靜態變量和全局變量。將他們存入只會浪費空間。所以用到他們的時候再去初始化。這里的清BSS段就是這樣的作用。
清完BSS段就是要復制代碼到RAM。這里韋東山老師是自己用C語言實現的從FLASH到RAM程序的復制。因為版權原因,我們不便貼出。其實也是很容易的內存塊復制。
最后是進入到了_start_armboot。這是一個C函數,從這里開始就是用C來實現讀出內核,啟動內核了。硬件相關的匯編程序講解結束!
版權聲明:
本博客未經允許,禁止轉載。
我尊重DENX Software Engineering為開源代碼做出的貢獻,他們做出u-boot,並將其開源供全世界的人們下載、學習和使用。
博主是跟隨韋東山老師學習的嵌入式Linux開發,其中的CopyCode2Ram函數為韋東山老師編寫。本文源於對學習成果的總結。
CCJ
2016-11-19 11:14:00