原文來自德儀中文在線,需要的直接去下原文吧
在基於Linux的AM335x軟件開發流程中,第一步就是U-Boot/SPL(Second Program Loader)的移植。在移植中遇到問題比較常見,而U-Boot/SPL的調試手段比較簡陋,不便於迅速找到問題。利用仿真器可以單步調試的特點,就可以迅速定位到出問題的代碼所在位置,加速移植的調試過程。本文主要介紹如何用CCS+emulator調試基於AM335x的U-Boot/SPL。
1. AM335x Linux啓動過程以及U-Boot/SPL調試代碼的準備
1.1 AM335x Linux的啓動過程
AM335x Linux的啓動主要包括ROM,SPL, U-Boot 和kernel四個啓動步驟:
A. ROM code
ROM code是固化在芯片內部的代碼,當上電時序正確,而且晶振等芯片啓動所需的條件都具備時,AM335x會從ROM code開始運行。
ROM code首先會讀取sys_boot引腳上的配置,以確定存放SPL的存儲器,或者可以獲取SPL的外設。
具體可以參考AM335x technical reference manual中的第26章 Initialization。
ROM code會從相應的地方讀取/獲取SPL,並運行SPL。
B. SPL
SPL和U-Boot 是bootloader的兩個階段。這裏分爲兩個階段的原因是, ROMcode中不會配置DDR,時鐘等最小系統,所以ROM code只能把bootloader加載到片上SRAM中,而片上SRAM對成本影響很大,所以通常很小,例如在AM335x上只有64K,不足夠放下整個U-Boot,所以將U-Boot分成兩部分,SPL和U-Boot。
SPL主要的職責就是初始化DDR,時鐘等最小系統,以讀取U-Boot,並加載到DDR中。具體來看,SPL 由ROM code加載到片上SRAM的起始位置,也就是0x402F0400。SPL會進一步對芯片進行配置,主要包括以下幾個方面以完成其主要職責:
a. 配置ARM core。 主要包括對中斷向量表,cache,MMU等的配置。
b. 配置時鐘系統,主要是PLL等。這個是配置各個功能模塊的基礎。
c. 配置UART,timer等。主要用於輸出必要的調試信息,或者提供些時鐘工具。
d. 配置I2C和PMIC。這個主要是爲了配置電源管理芯片。
e. 配置DDR。
f. 配置 U-Boot所在的存儲器或者外設。
完成配置後,SPL會讀取U-Boot,並運行U-Boot。
C. U-Boot
U-Boot 主要的工作就是正確加載Kernel。和SPL類似,U-Boot也是要加載下一個階段的image,但是U-Boot提供了更多外設的支持和更多的調試工具。所以,U-Boot也要進行各個模塊的配置,上述SPL配置的部分, 除了DDR外,U-Boot也會根據需求重新配置(這裏重置主要是U-Boot是一個開源工程,其要兼容某些特殊的芯片,從而需要做重載)。此外,U-Boot也會對網口,SD卡等根據需求進行配置。
U-Boot 和SPL的工作流程比有一點是有較大差異的,就是會對自身進行一次重載。這個在後面介紹U-Boot調試的時候,會有具體介紹。
完成配置後,U-Boot 會從相應的存儲器或者外設讀取Kernel,並傳遞參數給kernel,運行kernel。
D. Kernel
Kernel運行起來就代表Linux運行起來了,表明了啓動過程的結束。
1.2 U-Boot/SPL 調試代碼的準備
1.2.1下載U-Boot/SPL 代碼
U-Boot/SPL的代碼在一個包裏面,通過編譯宏來分別編譯。目前TI U-Boot/SPL 代碼發佈主要有兩個渠道,具體如下
A. 通過Git開源的方式發佈:
git://arago-project.org/git/projects/U-Boot-am33x.git
可以獲取最新的代碼,包含了最新的bug的修復。
B. 通過TI的官網的EZSDK發佈:
http://software-dl.ti.com/dsps/dsps_public_sw/am_bu/sdk/AM335xSDK/latest/index_FDS.html
EZSDK是正式發佈的軟件包,經過全面測試,性能穩定,U-Boot/SPL在board-support 目錄中。可以選擇EZSDK作爲開發的基礎代碼。當有問題時, 可到GIT上查找最新的代碼是否有bug fix。
1.2.2 U-Boot/SPL的編譯。
爲了便於用CCS進行調試, 在編譯上需要注意兩點,其一,是要加入調試信息,就是爲了加入symbol等信息;其二,去掉編譯器的性能優化編譯選項,這個主要是因爲,優化後的代碼執行順序相對C代碼會有調整。
針對這兩點,在Uboot/SPL中,需要在config.mk中進行修改:
A. 在CFLAG 和 AFLAG中加入調試編譯選項,從而加入調試信息:
278 ALL_AFLAGS = $(AFLAGS)$(AFLAGS_$(BCURDIR)/$(@F)) $(AFLAGS_$(BCURDIR))–g
279 ALL_CFLAGS = $(CFLAGS)$(CFLAGS_$(BCURDIR)/$(@F)) $(CFLAGS_$(BCURDIR))–g
B. 去掉 CFLAG中的編譯選項, -O2(U-Boot中默認是-O2)
61 HOSTCFLAGS = -Wall-Wstrict-prototypes -O2 -fomit-frame-pointer
編譯過程可以參考http://processors.wiki.ti.com/index.php/AM335x_U-Boot_User%27s_Guide
1.2.3 可執行文件
經過編譯後,就會生成可執行文件,也就是我們通常所說的image,這裏會生成的image主要用AM335x Linux啓動的兩個階段,MLO(SPL)和U-Boot。
這裏,SPL生成的image在am335/U-Boot-am33x/am335x/spl中,
A. am335/U-Boot-am33x/MLO 負責AM335x啓動的第一階段。
B. U-Boot-spl 作爲帶有調試信息的image,可以在CCS中用作導入調試信息。
C. U-Boot-spl.bin 包含有調試信息,是調試時需要的image。
D. U-Boot-spl.map 這個文件裏面存儲了spl的memory map信息,可以找到各函數入口的地址。
U-Boot生成的image在U-Boot-am33x/am335x中,具體如下:
A. U-Boot.img負責AM335x啓動的第二階段
B. U-Boot 包含有調試信息,屬於ELF格式,是調試時需要的image。
C. U-Boot.map這個文件裏面存儲了U-Boot的memory map信息,可以找到各函數入口的地址
2. 調試環境的準備
調試環境主要包含3個部分,仿真器,集成調試環境和開發板。下面將逐一介紹:
2.1 仿真器(emulator)
目前支持AM335x的仿真器的型號比較多,有XDS560v2, XDS510,XDS100v2, XDS100v3,等,比較常見的是XDS560v2和XDS100v2。
XDS560v2,性能好,速度快,具有trace功能,但是價格偏貴。 XDS100v2價格比較便宜。 其具備和XDS560v2 一樣的基本調試功能,只是XDS100v2的速度相對略慢。
XDS560v2和XDS100v2在PC機上的驅動(Windows, Linux)都已經包含在CCS中了,所以安裝了最新版的CCS,就會安裝相應的驅動。
2.2 集成開發環境
TI有自己的集成開發環境(IDE)CCS.目前最新的版本是基於Eclipse IDE架構的,界面新穎方便。
下載地址 http://processors.wiki.ti.com/index.php/Download_CCS。
CCS有Windows版本和Linux 版本,後面會在介紹調試過程中具體介紹兩者的差異。
2.3 開發板
目前,針對不同的應用,TI發佈了基於AM335x的多個開發板。其中BeagleBone,Starter Kit和ICE上配置了基於FT2232的xds100v2。而GPEVM和IDK上引出了CTI JTAG接口。
這裏選擇GP EVM 和 Spectrum DigitalXDS560v2 作爲調試平臺。
3. CCS 調試Uboot/SPL的具體步驟
下面正式開始CCS的調試。調試的過程主要分爲導入U-Boot/SPL工程, CCS 連接AM335x,代碼調試等幾個部分。
3.1 導入CCS代碼。
在CCS中, Menu File ->Import … 選擇 Makefile 方式導入,如下圖所示:
在ezsdk中,U-Boot/SPL所對應的Makefile的具體路徑如下:
/home/sitara/ti-sdk-am335x-evm-05.05.00.00/board-support/U-Boot-2011.09-psp04.06.00.08
如前面所提到,U-Boot 和SPL的源碼在同一個文件夾的,通過不同的Makefile管理不同的編譯宏來區分的。這裏導入的是U-Boot的代碼對應的Makefile,會相應的導入U-Boot對應的預編譯選項,因爲其包含了所有的代碼。而對於SPL,也會相應的一起帶入,只是在CCS中看到的代碼的宏定義有些不對,但這個不影響調試。
3.2 CCS 連接 AM335x.
主要分成仿真器的連接,target連接和Debug配置等幾部分:
3.2.1 仿真器的連接
對於 AM335x GP EVM選用Spectrum DigitalXDS560v2 的20 pin的接口板,連在baseboard的J2口上即可,注意pin腳的順序,不要把JTAG 接口插反了。
對於beaglebone,StarterKit,ICE等,這些板子已經把XDS100v2 仿真器集成到板子上了,所以直接用usb線連到PC機上即可。
A. CCS的配置
CCS的配置主要包括Target的配置和連接兩部分。
a. Target 配置
Target的配置包含兩個部分,一個是仿真器(XDS560v2),另一個就是SOC(AM335x)。具體操作如下:
i. View -> Target Configurations
ii. 點右鍵選擇New TargetConfiguration.
iii. 新建一個叫做AM335_EVM的target.
iv. Connection中選擇 Spectrum DigitalXDS560V2 STM USB Emulator.
v. 對於XDS100v2 , 可以選擇 Texas InstrumentsXDS100v2 USB Emulator.
vi. 在Board or Device 中選擇AM335x.
vii. 點擊Save 保存。
viii. 點擊Test Connection 看是否能夠正常連接。
配置target成功後,會看到如下界面
3.2.2 Target 連接
A. 右鍵選中Target Configurations中已配置好的target,AM335x_EVM.ccxml, 在右鍵菜單中選擇Launch SelectedConfiguration,連接成功後,可以得到下圖
此時,PC 和仿真器以及仿真器和SOC的JTAG連接成功,但是ARM core還沒有連上。從圖中可以看到,有多個core的配置選項,由於U-Boot/SPL, Linux 運行在ARM coretex-A8 core上,這裏只關注ARM core。
B. 在Debug窗口中,右鍵點擊CortxA8 core, 選擇Connect Target. 連接成功後,如下圖所示:
此時,已經成功連上AM335x的Cortex-A8 core了。
3.2.3 Debug配置
這裏的debug配置,是對emulator連上core後行爲的設置。 可以通過鼠標右鍵點擊properties,得到以下界面:
在該頁配置中,在調試過程需要調整的就是Auto RunOptions,可以根據需要設置,當加載了image後,core自動運行到指定的symbol,並且被JTAG接口所停住
3.3 SPL的調試
調試U-Boot/SPL 的方式有兩種,主要涉及如何加載image:一種是把image通過JTAG下載到片上RAM或者DDR中,然後導入symbol,重置 PC指針到image的入口處,進行調試;另一種,把image燒到SD卡或者其他啓動存儲器上,啓動板子,通過JTAG停住core的PC指針,導入symbol,重置 PC指針到image的入口處,進行調試。
下面會在具體步驟中說明這兩種方式如何操作:
A. 下載SPL image到AM335x中。
如果AM335x是從SD卡方式啓動,此時 SPL image已經被ROM code成功讀到片上 RAM中,就不需要加載 SPL image了。
如果選擇SPL image通過CCS下載,鼠標左鍵選擇CortxA8 core , 然後在CCS菜單中,Tools -> Load Memory, 選擇編譯好的SPL image U-Boot-spl.bin,如下圖所示:
選擇加載的地址。由於加載的U-Boot-spl.bin 是RAW data,所以需要指定load address,這個地址就是SPL的入口地址
對於AM335x,SPL的入口地址是 0x402F0400,對應的宏定義爲CONFIG_SPL_TEXT_BASE, 該宏定義在include/configs/am335x_evm.h中。通過編譯出的map文件U-Boot-spl.map也可以查到,是__start symbol對應的地址。
設定加載image內型。 由於所有的代碼都是運行在ARM(32bit)模式下。所以Type-size也要設成32bit。設置界面如下:
最後點擊Finish,SPL就會被load到片上RAM中了。如果在console窗口中有錯誤信息,需要把SPL image重新加載 一遍。
B. 加載 symbol。
在上一步裏,只是加載了RAW image,還沒有加載調試所需要的帶有調試信息的symbol。
可以通過Run -> Load -> Load Symbols 加載symbol信息,界面如下:
這裏選擇的是帶有symbol信息的U-Boot-spl.
C. 設置Cortex-A8 core到ARM狀態。
ARM core 啓動後,默認在Thumb(16bit)模式下,如前面所說,需要將其切換到ARM(32bit)下。具體做法是,View->Registers, 展開CPSR寄存器,把T位設置爲0。界面如下:
D. SPL的單步調試。
a. 從SPL編譯的memory map可知,SPL從0x402f0400開始執行,所以首先就要把寄存器PC的值設爲0x402f0400。可以通過View->Registers中設置PC指針的值即可, 界面如下,將紅色框裏面的改爲0x402f0400即可。
b. 點擊Debug窗口(view->debug)上tool bar中的彙編單步按鈕,如下圖所示,就開始調試了。
這時,在反彙編窗口(view->disassembly)中,如下圖所示,看到的是彙編代碼,而且在編輯窗口這邊看不到源碼。這是由於開始執行的代碼在/arch/arm/cpu/armv7/start.s 中,反彙編和彙編一樣,所以沒有顯示源碼。
同時,可以看到PC指針運行到0x402f0458處。這裏只是單步執行了一條指令,爲什麼跳過了這麼大塊地址?這裏的單步運行,指令地址空間跳轉了n指令,而不是一條指令,這是因爲0x402f0400處存放的是異常中斷向量表,通過默認啓動的入口跳到reset symbol對應的地址了,也就是在0x402f0400處跳轉到0x402f0458了,具體代碼(arch/arm/cpu/armv7/start.S)如下:
_start: b reset
reset:
bl save_boot_params
接下來,可以在C代碼中設置斷點,進行調試了。有兩點值得注意:
i. 如果編譯的時候,交叉編譯器的性能優化選項是開着的,那麼優化後編譯生成的代碼,其執行循序和C源碼有差別,這時設置斷點時,其實際的位置不會很準。所以,這裏可以根據需要,決定是否關閉-O2選項。
ii. 在CCS中,把core停下來時,CCS會根據image中調試信息所包含的源碼路徑,找到對應的源碼和symbol。由於U-Boot/SPL是在Linux中編譯,所以其路徑都是Linux下的路徑,所以Linux版本的CCS可以直接找到對應的源碼,而對於Windows版本的CCS不能直接找到,需要通過手動找到源碼,但是找到一個文件的源碼後,CCS會根據相對路徑找到其他文件。除了這點外,Linux和Windows的CCS配置使用是一樣的。
3.4 U-Boot的調試
總體來說, U-Boot的調試過程和SPL調試過程是類似的,這裏主要說明不同的幾點:
A. 從AM335x的啓動過程可知,U-Boot是運行在DDR中的,而DDR是由SPL來初始化的,所以,加載U-Boot前,先加載並運行SPL。
B. 加載U-Boot 的image是 U-Boot。 這裏U-Boot 是ELF格式的, 其包含了加載地址, symbol等信息,所以使用CCS 菜單 Run-> Load-> LoadProgram, 加載U-Boot 即可。加載成功後, 如下圖所示:
如圖所示, PC直接指到0x80100000地址了,也就是U-Boot的起始地址(入口)了,該地址是CCS從頭ELF頭裏面得到的,其定義在CONFIG_SYS_TEXT_BASE(include/configs/am335x_evm.h)中。
C. 相對 SPL 的調試, U-Boot有個地方不同,即有代碼的重載(code relocation), 重載後代碼的在SOC上的memory map和編譯出的memory map會有個偏移。這個過程是在函數relocate_code()中完成的。 relocate_code()函數是在board_init_f() 中調用的,如果需要調試從調用該函數開始後面的代碼,則加上偏移重載symbol。
在CCS的菜單, Run -> Load -> AddSymbols, 加載的image還是前面的U-Boot, data/code offset都是0x9FF88000。 這裏的offset是從gd->relocaddr(arch/arm arch/arm/lib/board.c)得到的。設置界面如下:
注意到上述幾點,然後就可以按照SPL的調試過程對U-Boot進行調試了。
4. 總結
關於用CCS+emulator對AM335x的U-Boot/SPL的調試就介紹完了。這裏介紹的方法,包含了CCS+emulator調試的基本原則,不僅僅可以運用於U-Boot/SPL調試,也可以運用於Starterware,Kernel等調試。
在基於Linux的AM335x軟件開發流程中,第一步就是U-Boot/SPL(SecondProgram Loader)的移植。在移植中遇到問題比較常見,而U-Boot/SPL的調試手段比較簡陋,不便於迅速找到問題。利用仿真器可以單步調試的特點,就可以迅速定位到出問題的代碼所在位置,加速移植的調試過程。本文主要介紹如何用CCS+emulator調試基於AM335x的U-Boot/SPL。