DM365的UBL原始碼分析

2021-06-21 22:09:21 字數 4596 閱讀 7036

dm365的ubl原始碼分析

dm365是的啟動方式有兩種,通過bootsel[2:0]引腳決定。當其為001時,直接從aemif上啟動,比如nor和onenand。除此之外皆是從rbl啟動,順序為rbl-ubl-uboot-kernel,比如nand,串列埠,sd卡等。rbl會搜尋block1到block24去找 ubl,關於rbl啟動的詳細細節可以參考使用者指南關於arm子系統的那篇文件,很詳盡,下面只分析ubl的原始碼。

ubl原始碼在psp包裡的board_utilities/flash_utils目錄下,主要是common目錄和各子平台的目錄如dm36x等,內中除了ubl的原始碼外還有ccs下jtag的擦除燒寫原始碼,串列埠燒寫原始碼等(flash_utils\dm36x\ccs下包括nandwriter和ubl兩個資料夾,分別對應針對ipnc的ccs的project)。下面只分析ubl的啟動**。

入門**是彙編檔案start.s,主要是切換操作模式,建立堆疊等,然後跳轉到main函式,進入到

board_utilities/flash_utils/

common/ubl/src目錄下的c檔案 ubl.c中。main函式如下:

// main entry point

void main(

void

)

u-boot一般存在於device_nand_ubl_search_start_block以後塊的第0頁,ubl試著從 device_nand_ubl_search_start_block塊向後搜尋每塊的第0頁,找到後,前24個位元組分別記錄著u-boot描述,如入口函式等

//dm36x/ccs/nandwriter/src/nandwriter.c   nandwriter()函式中

// fill in nandboot header,rxbuf為剛搜到的頁

gnandboot.entrypoint =*(

((uint32 *)(

&rxbuf[4]))

);gnandboot.numpage =*(

((uint32 *)(

&rxbuf[8]))

);/* the second "long" is the number of pages ,**總頁數,有多少資料要載入到ddr*/

gnandboot.block =*(

((uint32 *)(

&rxbuf[12]))

);gnandboot.page =*(

((uint32 *)(

&rxbuf[16]))

);gnandboot.ldaddress =*(

((uint32 *)(

&rxbuf[20]))

);

根據以上資訊一次讀入每一頁,然後將u-boot入口傳遞給gentrypoint。

main函式主要呼叫了local_boot函式來進行實質的引導功能,下面是此函式的內容:

static uint32 local_boot(

void

)// platform initialization

if( device_init()!

= e_pass )        /*

device_init函式來進行平台的最底層初始化,包括電源域,時鐘,ddr,emif,uart,i2c,timer等*/

else

// set ram pointer to beginning of ram space

util_setcurrmemptr(0)

;        /*

對全域性變數currmemptr賦值*/

// send some information to host

debug_printstring(

"ti ubl version: ");

debug_printstring(ubl_version_string)

;debug_printstring(

"\r\nbooting catalog boot loader\r\nbootmode = ");

// select boot mode

#if defined(ubl_nand)}#

elif defined(ubl_nor)}#

elif defined(ubl_sd_mmc)}#

else

#endif

debug_printstring(

" done");

util_waitloop(10000)

;device_timer0stop(

);   

return e_pass;

}

先通過呼叫device_bootmode函式來判斷啟動方式(通過讀取sys暫存器實現),而後呼叫了device_init函式來進行平台的最底層初始化,包括電源域,時鐘,ddr,emif,uart,i2c,timer等。

而後通過util_setcurrmemptr函式對全域性變數currmemptr賦值,以後用到。接著通過判斷不同的引導方式,採取不同的處理辦法,以 nand啟動為例,將呼叫nandboot_copy函式。此函式將nand中的某些內容(就是uboot)搬移到ram中,而後 ubl結束,控制權正式交給uboot。

看看ubl對平台的初始化,主要是呼叫了device_init函式,函式內容如下:

uint32 device_init(

)

首先遮蔽和清除中斷,然後呼叫device_pscinit函式實現對各模組的電源時鐘使能,實質是呼叫psc電源時鐘管理模組的暫存器實現,函式內容如下:

void device_pscinit(

)else

if(lpscgroup =

= 1)

else

//next=0x3, enable lpsc's

for(i=lpsc_start; i<

=lpsc_end; i++)

//program goctl to start transition sequence for lpscs

psc-

>ptcmd =

(1<

;//wait for gostat = no transition from psc for pdomain 0

while(!

(((psc-

>ptstat >

> pdnum)

& 0x00000001)

== 0));

//wait for modstat = enable from lpsc's

for(i=lpsc_start; i<

=lpsc_end; i++)

}}

然後呼叫device_pinmuxcontrol函式決定復用引腳的功能選擇,詳見資料手冊檢視引腳功能。

接著呼叫dm36x/common/src/device.c下的device_pll1init函式實現了pll1的配置,預分頻,倍頻,後分頻,分頻到各個模組,其設定順序可以參看使用者指南arm子系統文件,有詳細的介紹,pll2類似,函式內容如下:

uint32 device_pll1init(uint32 pllmult)

uint32 device_pll2init()

繼續在device_init函式中,下面是呼叫device_ddr2init函式來配置ddr控制器,這是ubl中重要的一部分,如果硬體電路需要更換記憶體晶元的話,需要在ubl中修改這個函式,即按照晶元手冊來配置ddr控制暫存器中的相關引數,比如時序,bank數,頁大小等。這個函式主要是操作 sys模組和ddr模組的相關暫存器來配置記憶體,函式中呼叫的device_lpsctransition函式用來實現模組的電源時鐘狀態的改變,函式內容如下:

uint32 device_ddr2init(

)void device_lpsctransition(uint8 module, uint8 domain, uint8 state)

而後呼叫device_emifinit函式來配置emif模組,這個模組用來接外存,比如nand,nor等。dm365有兩個片選空間,如果某一空間配置成nand,則需要在暫存器中設定,其函式內容如下:

uint32 device_emifinit(

)

而後呼叫device_uart0init函式來配置串列埠0,呼叫device_timer0init函式來配置timer0,呼叫 device_i2c0init函式來配置i2c控制器,都是操作某一模組的控制暫存器實現,具體如何設定可以參考相關模組的手冊,這三個函式的內容如下:

uint32 device_uart0init(

)uint32 device_i2c0init(

)uint32 device_timer0init(

)

至此,device_init函式結束,程式返回至local_boot函式中,接著就呼叫nandboot_copy函式了。

DM365的UBL原始碼分析

dm365是的啟動方式有兩種,通過bootsel 2 0 引腳決定。當其為001時,直接從aemif上啟動,比如nor和onenand。除此之外皆是從rbl啟動,順序為rbl ubl uboot kernel,比如nand,串列埠,sd卡等。rbl會搜尋block1到block24去找 ubl,關於...

Qt 4 7 2在dm365下的移植

qt 4.7.2 及qtembedded 4.7.2 在ubuntu11.10 下的安裝 後續,主要參考 部落格 同樣,參照他的部落格中關於 dm365 下的移植來做,我又遇到了新的問題,主要的問題出現在 configure 上,按照他的 configure 引數配置成 arm版本的 qt庫後,我編...

ClassLoader的原始碼分析

classloader 抽象類 同乙個類的來自不同classloader的子類的類會出現轉型失敗的情況,要注意。loadclass 執行緒安全 1.findloadedclass name 查詢該類是否已經載入。2.如果尚未載入,則執行3 3.判斷該類的父類是否載入,如果尚未載入,遞迴呼叫loadc...