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...