??在上一篇博文 U-Boot 之一 零基礎(chǔ)編譯 U-Boot 過程詳解 及 編譯后的使用說明 中,最后使用階段遇到了一些錯(cuò)誤,然后發(fā)現(xiàn)不能調(diào)試(靠打印信息)實(shí)在是難受,就開始摸索如何調(diào)試 U-Boot,于是就有了這篇博文。
??找了一下網(wǎng)上現(xiàn)有的資料,直接使用 GDB 命令行調(diào)試是一個(gè)選擇,但是明顯效率不高。于是開始探索直接使用 eclipse 對 U-Boot 進(jìn)行編譯及調(diào)試。發(fā)現(xiàn)網(wǎng)上有不少說明文章,但大多數(shù)都太老舊了,因此我決定重新整理一篇,使用的當(dāng)前最新的工具環(huán)境如下:
- Ubuntu 20.04.3
- Eclipse IDE 2021-12 R Packages Eclipse IDE for Embedded C/C++ Developers
- U-boot 2021.10
- J-Link_Linux_V760b_x86_64.deb
下載安裝 eclipse
??首先從官網(wǎng)下載最新的針對嵌入式 C/C++ 的 tar 包(現(xiàn)在 eclipse 針對不同開發(fā)環(huán)境提供了不同的包,我記得之前并沒有分開):Eclipse IDE for Embedded C/C++ Developers,地址:https://www./downloads/packages/release/2021-12/r/eclipse-ide-embedded-cc-developers,然后進(jìn)行安裝(解壓):  解壓之后,我們在 /opt/eclipse/eclipse 目錄(我這里先建立了 eclipse 文件夾導(dǎo)致多了一級,大家可以直接解壓到 /opt )下直接雙擊運(yùn)行 eclipse 程序即可。這里我們直接下載嵌入式專用的版本,主要是出于以下幾點(diǎn):
- 根據(jù)官網(wǎng)提示 “The Eclipse Installer 2021?12 R now includes a JRE for macOS, Windows and Linux.” ,我們不用再安裝 Java 運(yùn)行時(shí) 了。解壓后直接使用就可以了。
- 包含了一些嵌入式使用的插件(例如 J-Link、OpenOCD 等調(diào)試插件 ),這省了我們在去安裝這些插件。例如,選擇 Eclipse IDE for C/C++ Developers,然后去安裝各種插件。
進(jìn)一步,我們可以選擇建立一個(gè) eclipse 的快捷方式,方便后續(xù)啟動:
- 新建
sudo gedit /usr/share/applications/eclipse.desktop - 輸入以下內(nèi)容:
[Desktop Entry]
Encoding=UTF-8
Name=Eclipse
Comment=Eclipse IDE
Exec=/opt/eclipse/eclipse/eclipse
Icon=/opt/eclipse/eclipse/icon.xpm
Terminal=false
StartupNotify=true
Type=Application
Categories=Application;Development;
- 賦予執(zhí)行權(quán)限
sudo chmod u+x /usr/share/applications/eclipse.desktop - 以上步驟之后我們就可以在桌面最左下角的菜單中找到 eclipse 了。當(dāng)然還可以在進(jìn)一步,將
/usr/share/applications/eclipse.desktop 復(fù)制到桌面,然后賦予執(zhí)行權(quán)限(應(yīng)該是還需要右鍵鼠標(biāo),選擇 Allow Launching)。
附 tar 命令:
# 壓縮
tar -czvf ***.tar.gz
tar -cjvf ***.tar.bz2
# 解壓縮
tar -xzvf ***.tar.gz
tar -xjvf ***.tar.bz2
# 參數(shù)
-c :建立一個(gè)壓縮檔案的參數(shù)指令(create 的意思);
-x :解開一個(gè)壓縮檔案的參數(shù)指令!
-t :查看 tarfile 里面的檔案!特別注意,在參數(shù)的下達(dá)中, c/x/t 僅能存在一個(gè)!不可同時(shí)存在!因?yàn)椴豢赡芡瑫r(shí)壓縮與解壓縮。
-z :是否同時(shí)具有 gzip 的屬性,亦即是否需要用 gzip 壓縮
-j :是否同時(shí)具有 bzip2 的屬性,亦即是否需要用 bzip2 壓縮
-v :壓縮的過程中顯示檔案!這個(gè)常用,但不建議用在背景執(zhí)行過程!
-f :使用檔名。注意,在 f 之后要立即接檔名,不要再加參數(shù)!例如使用『 tar -zcvfP tfile sfile 』就是錯(cuò)誤的寫法,要寫成『 tar -zcvPf tfile sfile 』才對!
-p :使用原檔案的原來屬性(屬性不會依據(jù)使用者而變)
-P :可以使用絕對路徑來壓縮!
-N :比后面接的日期(yyyy/mm/dd)還要新的才會被打包進(jìn)新建的檔案中!
下載安裝 J-Link 驅(qū)動
??這個(gè)就相當(dāng)簡單了,SEGGER 提供了安裝包,直接從 https://www./downloads/J-Link/ 下載對應(yīng)的的 linux 的安裝包(例如我的 Ubuntu 對應(yīng) 64-bit DEB Installer ),然后雙擊安裝就可以了。安裝之后默認(rèn)位置是 ./opt/SEGGER 目錄下。  里面的可執(zhí)行程序都沒有對應(yīng)的桌面圖標(biāo),運(yùn)行后在左側(cè)的工具欄上也是黑乎乎的。使用時(shí)直接使用命令行或者到目錄下雙擊對應(yīng)的可執(zhí)行程序即可。
配置 eclipse
??eclipse 的配置分為全局、工作區(qū)、項(xiàng)目,優(yōu)先級前者最低后者最高(后者會覆蓋前者)。對于一些通用的配置(例如我們安裝的 J-Link 驅(qū)動,無論工作區(qū)還是項(xiàng)目,應(yīng)該都用一個(gè)),eclipse 推薦直接在全局或者工作區(qū)中配置,項(xiàng)目直接繼承使用全局或工作區(qū)的配置就可以了。 啟動 eclipse 會提示選擇工作區(qū),默認(rèn)可以選擇不再提示。  啟動之后,直接 菜單 --> Window --> Preferences 打開配置界面,我們主要是配置更改 MCU 這個(gè)目錄(這個(gè)好像是由于我們用的嵌入式版 eclipse 自帶了 CDT 插件才有這個(gè))下的內(nèi)容,其他的配置項(xiàng)則根據(jù)自己的需要自行修改即可。具體如下:  我這里僅僅配置了編譯工具鏈和 J-Link 的安裝位置。之所以這里選擇對全局配置項(xiàng)進(jìn)行配置,主要還是方便在后續(xù)建立項(xiàng)目之后,項(xiàng)目自動繼承這些配置,方便減少很多操作。
??這里再次說明,由于我們選擇的是嵌入式專用的 eclipse(Eclipse IDE for Embedded C/C++ Developers ),因此,我們不需要安裝 CDT 插件等操作。否則光是配置 eclipse 內(nèi)容就挺多!
安裝 CMSIS-Packs
??CMSIS Pack 是 ARM 為 Cortex-M 核定義的一個(gè)規(guī)范,是一種有效的封裝技術(shù),目前支持近 9000 種不同的微控制器。它們?yōu)檐浖M件、設(shè)備參數(shù)和評估板支持提供了一種交付機(jī)制。軟件包(文件集合)包括:
- 源代碼、頭文件和軟件庫
- 文檔和源代碼模板
- 設(shè)備參數(shù)以及啟動代碼和編程算法
- 示例工程
??用過 MDK-ARM(Keil)的應(yīng)該很熟悉,這個(gè)東西不僅可以在 MDK-ARM(Keil)中使用,現(xiàn)在 eclipse、IAR 都集成了 CMSIS Pack,通過 CMSIS Pack 我們可以在線安裝一些芯片的包。
?? 這里我們之所以安裝 CMSIS Pack(確切的說是安裝 CMSIS Pack 中提供的芯片的包),是因?yàn)閺闹形覀兛梢垣@取到芯片的 SVD 文件,而 SVD 文件中記錄了芯片中各種外設(shè)的寄存器,在調(diào)試時(shí)非常有用!如果不使用 SVD 文件,調(diào)試器將無法獲取芯片中外設(shè)的寄存器,只能顯示 ARM 核中的幾個(gè)寄存器。
?? eclipse 中安裝非常簡單,但是由于訪問的是國外的服務(wù)器,速度相當(dāng)慢(那些包都挺大的),而且經(jīng)常出現(xiàn)某些芯片下載不下來報(bào)錯(cuò)。如果出現(xiàn)報(bào)錯(cuò)直接選擇忽略即可。具體操作如下圖所示:  ??CMSIS Pack 的安裝位置可以在 菜單--> Window-->Preferences --> C/C++ --> MCU Packages 下找到及更改。查看其中的內(nèi)容,其實(shí)就是 Keil 中的那一套東西,因此一種變通的方法是將下載好的內(nèi)容直接放到上面的目錄中即可。SVD 文件就位于 CMSIS-Packs\Keil\STM32F7xx_DFP\2.14.1\CMSIS\SVD 目錄下。  注意,上面的這個(gè)目錄應(yīng)該是個(gè)隱藏文件夾!
編譯 U-Boot
新建項(xiàng)目
??準(zhǔn)備好以上環(huán)境及工具之后,就可以直接建立項(xiàng)目了,對于 U-Boot ,我們選擇 Makefile Project with Existing Code 。我這里把步驟盡量把步驟合并到一張圖,以節(jié)約篇幅。具體步驟如下圖所示:  ??其中,我們選擇的編譯工具鏈?zhǔn)?Arm Cross GCC。這里的選擇主要是讓 eclipse 能夠主動使用適合我們的一些配置。如果選擇其他的,后續(xù)也可以再次進(jìn)行更改(步驟會多一些)。
注意,如果選擇在配置章節(jié)說的已經(jīng)在配置了全局或者工作區(qū),下面有些配置其實(shí)可以不用更改。我這里就以沒有配置來進(jìn)行演示(覆蓋全局配置),對于全局配置有影響的地方單獨(dú)說明一下。
??點(diǎn)擊 Finish 之后,默認(rèn)在選擇的源代碼目錄下新建兩個(gè)(隱藏)文件:.cproject 和 .project ,這兩個(gè)就是 eclipse 記錄的項(xiàng)目配置信息文件(我之前以為會和 Windows 上的一些軟件(例如 vs)似得放到選擇的工作區(qū)目錄下,要不然我選擇工作區(qū)干啥?。?。
項(xiàng)目配置
??點(diǎn)擊右鍵菜單最下面的 Properties (也可以通過 菜單 --> Project --> Properties )之后,就打開了項(xiàng)目的配置頁面,接下來就是更改一些項(xiàng)目專用的配置了。下面我們一步步說明需要做哪些更改:
-
新增環(huán)境變量。具體操作如下圖所示:  環(huán)境變量下原有的兩個(gè) CMD 、PWD 我們不用管它(PATH 變量默認(rèn)也應(yīng)該有,不知為何我這里沒有)。我們最終需要新增三個(gè)環(huán)境變量 ARCH 、CROSS_COMPILE 、PATH (如果沒有的話),其中, ARCH 和 CROSS_COMPILE 就是我們使用命令行編譯時(shí)指定的。PATH 主要是告訴 eclipse 我們是用的工具的位置。 ??這里需要特殊注意 PATH 的值。我們需要先通過上面的 Variables 找到系統(tǒng) PATH 變量,然后點(diǎn)擊 OK,此時(shí),eclipse 就會導(dǎo)入系統(tǒng)環(huán)境變量的值。我們需要編輯它,在其中添加我們自己的編譯工具鏈位置(我這里是 /usr/share/gcc-arm-none-eabi-10.3.2021.10/bin ,注意,bin 目錄不止一個(gè)),否則在編譯時(shí)會提示找不到相關(guān)工具。注意,如果在上面說的全局設(shè)置中已經(jīng)添加了編譯器的路徑,這里不用再次添加。 最終添加后如下所示:  我們添加的編譯器路徑用于讓 eclipse 找到編譯器,其他原有的系統(tǒng)環(huán)境變量可以讓 eclipse 找到 make 程序。此外,最下面的 Append xxx 這句不要去掉。 -
更改我們使用的編譯工具鏈以及選擇使用的芯片。  如果沒有配置全局編譯器路徑,這里必須單獨(dú)配置;如果設(shè)置了這里就會自動讀取全局設(shè)置的編譯工具鏈,查看一下是否正確即可。如果這里選擇了芯片,在調(diào)試的時(shí)候會省略一些配置。 -
[可選] 不使用 CDT 內(nèi)建的編譯工具鏈的相關(guān)設(shè)置(因?yàn)槲覀兏鼡Q了編譯工具鏈),注意,這里不更換也沒啥問題!  -
新增我們自己的編譯工具鏈的頭文件路徑。每一個(gè)編譯工具鏈下都會有 include 文件夾用來存放編譯器使用的各種頭文件。需要注意的是, include 可能會有好幾個(gè),最好都添加上。如果在全局中配置了編譯器路徑,eclipse 就會自動識別指定的編譯工具的相關(guān)頭文件,這里就可以不用設(shè)置。  -
[可選] 開啟并行編譯。就是指定 make -jn 參數(shù)(n 根據(jù)處理器來定) 。eclipse 配置如下:  -
[可選] 增加 make stm32f769-disco_defconfig 步驟。完整的構(gòu)建 U-Boot 的步驟中,第一步是生成 .config 文件,而后是 make menuconfig ,最后才是 make 。如果不添加到 eclipse ,則需要先用命令行執(zhí)行以上步驟,否則 eclipse 會提示錯(cuò)誤。  具體添加如下:  之后,我們就可以在 菜單 --> Project --> Build Targets --> Build 中直接點(diǎn)擊上面的配置,執(zhí)行這一步了。 -
[可選] 修改 make clean 。默認(rèn)情況下,我們執(zhí)行 Clean 時(shí),使用是 make clean ,而我們編譯 U-Boot 一般使用 make distclean 。這個(gè)是 eclipse 默認(rèn)的設(shè)置,我們可以通過如下位置進(jìn)行修改:  此外,還可以參考第 6 步中新建一個(gè) Build Targets ,只是使用起來沒有上面這個(gè)方式簡單。我第 6 步的圖示中已經(jīng)建立好了!
編譯
經(jīng)過以上步驟,完整的 U-Boot 編譯環(huán)境就搭建好了,接下來就可以在 eclipse 中構(gòu)建 U-Boot 了。 
調(diào)試 U-Boot
J-Link 連接開發(fā)板
??調(diào)試之前肯定是先把 J-Link 連接到開發(fā)板(開發(fā)板上有個(gè) 20 針腳的 JTAG/SWD 調(diào)試接口),確保連接正確。測試連接具體可以使用我們安裝的 J-Link 驅(qū)動里相應(yīng)的工具:JFlashExe ,新建一個(gè) STM32F769 芯片的項(xiàng)目,然后連接一下:  提示 Connected successfully 即可。
eclipse 調(diào)試相關(guān)配置
??連接沒有問題之后,接下來就是配置 eclipse 了:菜單 --> Run --> Debug Configuration... ,總的來說配置并不麻煩,我這里使用是 J-Link,因此,選擇 GDB SEGGER J-link Debugging ,然后點(diǎn)擊上面的新建圖標(biāo)(或者直接雙擊 GDB SEGGER J-link Debugging )就會出現(xiàn)一個(gè)新的配置,具體步驟如下圖所示:  ??需要注意的就是選擇 C/C++ Application 這一項(xiàng),我們需要從眾多執(zhí)行程序中選擇出我們最終需要 u-boot(這個(gè)是最終編譯出的帶調(diào)試信息的,不是 u-boot.bin。具體見博文U-Boot 之三 U-Boot 源碼文件解析及移植過程詳解)。接下來就是配置界面中剩下的Debugger 、Startup 、Source 、Common 、SVD Path 這 5 個(gè) Tab 頁面內(nèi)容,下面我直接上圖來說明每個(gè)頁面需要的配置:
Main 、Debugger 、Startup  如果已經(jīng)在全局配置中設(shè)置了J-Link 的路徑,這里默認(rèn)是會自動讀取全局的配置的 J-Link,不用更改也可以。當(dāng)然這里再選擇一下肯定沒有問題。芯片類型如果在構(gòu)建時(shí)選擇了芯片,這里也會自動填上選擇的芯片。還有就是 Startup --> Setbreakpoint at: 這個(gè)默認(rèn)是 mian,但是 U-Boot 默認(rèn)沒有 main,這里根據(jù)實(shí)際情況選擇。直接 reset ,簡單粗暴!還有可以使用 _main 。Source 、Common 、SVD Path  如果按照前面說的安裝了 CMSIS-Packs,那么這里就可以找到對應(yīng)芯片的 SVD 文件,選擇 SVD 文件之后,我們在調(diào)試時(shí)就可以查看外設(shè)寄存器的值,否則將無法查看!如下圖所示:  ??注意,eclipse 寄存器分為兩部分:Registers 窗口中是 ARM Cortex 核的寄存器(例如,R0、PC),Peripherals 下面就是我們的 SVD 文件中描述的外設(shè)寄存器。
U-Boot 調(diào)試修改
開啟調(diào)試選項(xiàng)
??默認(rèn)情況下,U-Boot 的編譯已經(jīng)進(jìn)行了優(yōu)化,且默認(rèn)并不開啟調(diào)試的,因此我們需要更改一下 U-Boot 的配置。第一個(gè)是需要取消 General Setup --> Optimise for size ,在一個(gè)就是開啟 General Setup --> Configure standard U-Boot features (expert users) -> enable debug information for tools ,具體如下圖所示:  ??這里需要注意,如果使用 make distclean 會清理所有文件,這就會導(dǎo)致以上的配置被清理!所以除非必要,否則還是使用 make clean 好一些。目前來看 make menuconfig 這一步還是需要在終端中執(zhí)行。
??警告:目前我在測試中發(fā)現(xiàn),去掉 General Setup --> Optimise for size 可能導(dǎo)致程序無法運(yùn)行,暫時(shí)沒找到解決方法!我目前是在僅開啟了 General Setup --> Configure standard U-Boot features (expert users) -> enable debug information for tools 的情況進(jìn)行調(diào)試的。就是偶爾會出現(xiàn)斷點(diǎn)位置不正確,不影響正常調(diào)試!
??這里有個(gè)比較嚴(yán)重的問題,去掉 General Setup --> Optimise for size 之后,會導(dǎo)致程序變大,從而原來默認(rèn)的 SPL 的大?。?x8000)不能容納實(shí)際 SPL 大小,進(jìn)一步導(dǎo)致了 U-Boot 無法啟動。因此,這里我們必須要修改 U-Boot 的基地址。目前,有如下地方需要修改(圖里面的 stm32f769-eval 是我移植的,上文暫時(shí)還沒有更換): 
修改設(shè)備樹配置
??接下來還有個(gè)問題:在啟動調(diào)試之后,調(diào)試的程序在調(diào)試時(shí)只能執(zhí)行一部分代碼,此后就會失敗,而且如果不調(diào)試想要直接運(yùn)行是無法直接啟動!具體現(xiàn)象如下圖所示:  根本原因是由于調(diào)試的程序有沒有設(shè)備樹!默認(rèn)情況下,U-Boot 的可執(zhí)行程序是 bin 后拼接上 dtb 組成的,而我們調(diào)試的程序只有 bin,沒有 dtb!解決方法如下有如下兩種:
- 將設(shè)備樹直接編譯進(jìn) U-Boot 的 bin 文件中,而不是將 設(shè)備樹單獨(dú)出來!U-Boot 本身就有這方面的配置,具體如下:
 如果執(zhí)行過 make distclean 那么每次都需要重新配置上面的選項(xiàng)。 - 在 eclipse 中指定設(shè)備樹地址。如果使用的是 U-Boot 默認(rèn)的分離設(shè)備樹模式,那么在編譯成功之后,會在源碼的根目錄下生成
u-boot.dtb ,這個(gè)就是設(shè)備數(shù)編譯之后的文件,而我們可執(zhí)行程序的結(jié)束地址可以從源碼的根目錄下的 u-boot.map 文件中的 __end 符號找到。  有了 u-boot.dtb 和 __end 之后,我們就可以在 eclipse 中通過命令來解決:  如果 U-Boot 的可執(zhí)行程序大小有變化,每次都需要更改這里!而且在剛開始啟動調(diào)試時(shí),eclipse 會報(bào)一個(gè)錯(cuò)誤,稍等一會即可正常進(jìn)入調(diào)試。
??經(jīng)過以上兩種方法的任意一種,再次啟動調(diào)試時(shí),就可以正常執(zhí)行 board_inti_f 這個(gè)函數(shù)了!注意,由于這個(gè)函數(shù)里包含很多接口,執(zhí)行速度可能有些慢!
重定位配置
??接下來的問題就是內(nèi)存重定位,U-Boot 中存在一段內(nèi)存重定位的代碼,重定位之后將導(dǎo)致調(diào)試失敗!這主要是因?yàn)?,在重定位之后,eclipse 正確加載符號表中的各符號。  ??目前,我還沒有找到比較好的解決方法,官網(wǎng)推薦的方法是 使用 gdb 命令行來手動加載符號表 。命令非常簡單:add-symbol-file u-boot 重定位后的地址 。重定位后的地址就位于 gd 中的成員變量 unsigned long relocaddr; 中。 
調(diào)試
??經(jīng)過上面的配置之后,我們就可以使用 eclipse 對 U-Boot 進(jìn)行調(diào)試了。這里需要注意的是,我們調(diào)試的如果是 U-Boot 本身,需要現(xiàn)將 SPL 燒寫好,當(dāng)然我們也可以調(diào)試 SPL。啟動調(diào)試如下圖所示: 
參考
- https:///debugging-using-segger-j-link-jtag/
- https://www.cnblogs.com/humaoxiao/p/4166230.html
- https:///blog/2021/09/19/how-to-debug-u-boot/
- https://community./products/devtools/single-board-computers/riotboard/b/blog/posts/automate-uboot-build-with-eclipse
- https:///article/68662419084/
|