1)摘自【正點原子】領航者 ZYNQ 之linux驅動開發指南
2)實驗平臺:正點原子領航者ZYNQ開發板
3)平臺購買地址:https://item.taobao.com/item.htm?&id=606160108761
4)全套實驗源碼+手冊+視頻下載:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html
5)對正點原子FPGA感興趣的同學可以加群討論:876744900
6)關注正點原子公眾號,獲取最新資料
第二十章另一種方式編譯ZYNQ鏡像
本篇是ARM Linux驅動開發篇中的第一章,本章跟驅動開發並沒有什麼關係,由於前面我們一直都是使用xilinx的petalinux工具編譯鏡像文件,例如包括U-Boot、linux內核、設備樹、ZYNQ PL端的bitstream文件以及fsbl等,雖然petalinux功能上比較全面,但是在編譯速度上太慢了!完全是在浪費時間,相信大家在使用petalinux的時候已經感受到了它給你帶來的無奈之處;為此筆者專門去研究了一下,那本章筆者就帶大家通過另外一種比較快的方式編譯各種鏡像文件。
本章採用分步式的方式編譯啟動開發板所需要的各種鏡像文件,雖然步驟比較繁瑣,但靈活性比較高;雖然本章使用的是另一種方式編譯鏡像,但還是得需要用到petalinux提供的一些工具,所以大家一定要安裝petalinux。
20.1由hdf文件得到bit文件
.bit文件是zynq pl端所需要用到的bitstream文件,例如我們使用petalinux-build命令完成工程編譯之後會在images/linux目錄會產生一個system.bit文件,這個就是我們這裡說到bitstream文件,.bit可以通過.hdf硬體描述符文件得到,怎麼得到呢?下面給大家說來。
將ZYNQ開發板資料盤(A盤)\4_SourceCode\ZYNQ_7010\3_Embedded_Linux\vivado_pro\Navigator_7010\Navigator_7010.sdk文件夾拷貝到Ubuntu系統目錄下,例如/home/zynq/hdf/目錄,大家根據自己的情況選擇目錄,本實驗以領航者7010為例,如果大家用的是領航者7020,則選擇ZYNQ開發板資料盤(A盤)\4_SourceCode\ZYNQ_7020\3_Embedded_Linux\vivado_pro\Navigator_7020\Navigator_7020.sdk文件夾。
在Navigator_7010.sdk目錄下有一個.hdf文件,如下所示:
圖 31.1.1 hdf文件
接下來使用source命令執行petalinux的環境配置腳本settings.sh,如下所示:
圖 31.1.2 運行settings.sh腳本文件
/home/zynq/petalinux/v2018.3是筆者的petalinux安裝目錄,完成環境配置之後執行hsi命令進入到hsi命令模式,如下所示:
圖 31.1.3 hsi命令行
執行命令之後就可以進入到hsi命令行模式下了,hsi命令行模式就跟我們的linux命令行模式差不多,都可以執行命令,只不過執行的命令不同;hsi命令是petalinux工具提供的,所以一定安裝petalinux才行;在這個模式下可以執行一些命令,例如執行下面這條命令可以打開硬體設計文件hdf得到bit文件:
圖 31.1.4 打開hdf文件
Open_hw_design命令緊跟著的是hdf文件路徑,命令執行成功之後會在hdf文件所在目錄下產生bit文件以及ps7_init命名的.c文件和.h文件,如下所示(在hsi命令行模式下執行exit命令退出該模式):
exit
圖 31.1.5 退出hsi命令行模式
圖 31.1.6 產生bit文件及其它文件
從上圖中可以看到在hdf文件所在目錄下產生了design_navigator_7010_wrapper.bit文件以及.c和.h文件。
20.2自動生成設備樹文件
Petalinux可以根據hdf文件描述的硬體信息自動配置U-Boot和內核所需的設備樹文件,那麼我們也可以通過hsi命令來生成;首先需要導入xilinx的device-tree倉庫,在我們提供的資料包中已經給大家準備好了,路徑為:ZYNQ開發板資料盤(A盤)\4_SourceCode\ZYNQ_7010\3_Embedded_Linux\misc\device-tree-xlnx-xilinx-v2018.3.tar.gz,大家也可以通過https://github.com/Xilinx/device-tree-xlnx/releases網址進行下載,選擇2018.3版本.tar.gz壓縮格式文件,如下所示:
圖 31.2.1 設備樹倉庫下載
Xilinx device-tree描述了設備與設備樹之間的匹配關係,將下載好或是資料包中的device-tree-xlnx-xilinx-v2018.3.tar.gz壓縮文件拷貝到Ubuntu系統目錄下,例如/home/zynq/device-tree,大家根據自己的情況選擇,然後將其解壓當前目錄,解壓之後會產生一個device-tree-xlnx-xilinx-v2018.3文件夾,如下所示:
圖 31.2.2 device-tree目錄
那麼device-tree-xlnx-xilinx-v2018.3目錄就是我們所需要的device-tree倉庫。接下來我們執行hsi命令進入到hsi命令行模式,執行下面這些命令:
圖 31.2.3 生成設備樹文件
首先也是通過open_hw_design命令打開hdf文件,然後使用set_repo_path命令設置device-tree倉庫所在路徑,例如/home/zynq/device-tree/device-tree-xlnx-xilinx-v2018.3;使用create_sw_design創建軟體設計,」 -os device_tree」指定了軟體設計的類型,我們這裡使用device-tree表示它是一個設備樹類型,」 -proc ps7_cortexa9_0」指定處理器的名稱,在hsi命令模式下使用」xxxx -help」可以查看xxxx命令的用法說明,這裡就不給大家列舉了;最後使用generate_target命令去產生目標,也就是我們的設備樹文件,」 -dir /home/zynq/linux/dts」指定路徑。
此時我們可以退出hsi命令行模式,進入到/home/zynq/linux/dts目錄下,可以看到自動配置產生的.dts和.dtsi文件,如下所示:
圖 31.2.4 生成設備樹文件
Linux設備樹是是一個很重要的知識點,將會在後面給大家詳細說明,本章先不講,這些文件後面我們會用到。
20.3創建、編譯fsbl工程
fsbl(First Stage Boot Loader)是ZYNQ第一啟動引導加載代碼,它的主要任務就是初始化DDR,並將用戶代碼(例如U-Boot、bit文件或者是SDK裸機代碼)從存儲設備中拷貝到DDR中運行。在使用petalinux-build命令編譯完成之後,在images/linux目錄下有一個zynq_fsbl.elf文件,這個就是fsbl編譯之後產生了elf格式文件,同樣也可以使用hsi命令來創建fsbl工程並進行編譯。
首先我們需要導入Xilinx embeddedsw存儲庫,該embeddedsw倉庫用於裸機應用,例如fsbl、pmu固件、plm等,在我們提供的資料包中已經給大家準備好了,路徑:ZYNQ開發板資料盤(A盤)\4_SourceCode\ZYNQ_7010\3_Embedded_Linux\misc\embeddedsw-xilinx-v2018.3.tar.gz,大家也可以從https://github.com/Xilinx/embeddedsw/releases網址進行下載,選擇2018.3版本.tar.gz壓縮格式,如下所示:
圖 31.3.1 下載embeddedsw倉庫
將下載好或是資料包中的embeddedsw-xilinx-v2018.3.tar.gz壓縮文件拷貝到Ubuntu系統目錄下,例如/home/zynq/embeddedsw,大家根據自己的情況選擇;然後將其解壓當前目錄,解壓之後會產生一個embeddedsw-xilinx-v2018.3文件夾,如下所示:
圖 31.3.2 embeddedsw目錄
在Ubuntu中執行下面這條命令,建立一個軟連結文件gmake,連結到make:
圖 31.3.3 建立gmake軟連結文件
因為在編譯的過程中會用到gmake,其實gmake就是GNU make的縮寫,Linux系統環境下的make就是GNU make;之所有有gmake,是因為在別的平臺上,make一般被佔用,GNU make只好叫gmake了;比如在進行編譯時要使用make命令,但如果在非GNU系統中運行,必須使用GNU make,而不是使用系統自帶的make版本,這時要用gmake代替make進行編譯。
完成上面的工作之後,我們就可以進行fsbl的創建與編譯了,執行hsi命令進入hsi命令行模式,執行下面這些命令:
圖 31.3.4 編譯fsbl-1
圖 31.3.5 編譯fsbl-2
首先還是使用open_hw_design命令打開hdf硬體描述符文件;使用set_repo_path命令設置embeddedsw倉庫所在路徑,例如/home/zynq/embeddedsw/embeddedsw-xilinx-v2018.3;set命令用於定義變量,我們使用set命令定義了一個hwdsgn變量等於design_navigator_7010_wrapper,當執行generate_app命令的時候使用該變量,定義了一個fsbl_dir變量定義了用於存放fsbl工程的路徑;最後使用generate_app命令產生和編譯fsbl,」-hw $hwdsgn」指定硬體設計的名字,就是hdf文件去掉後綴即可,」-os standalone」指定我們的app是一個無作業系統的裸機程序,」-proc ps7_cortexa9_0」指定處理器,」-app zynq_fsbl」指定app的名字(這個不能改),」-compile」表示要編譯生成的源文件(如果不加的話則表示僅產生fsbl工程源碼並不進行編譯),」-sw fsbl」指定本軟體設計的名字(這個名字可以自己定),」-dir $fsbl_dir」我們的fsbl工程存放的路徑,筆者這裡以/home/zynq/linux/fsbl為例,大家根據自己的情況設定。
整個過程完成之後,我們可以執行exit命令退出hsi命令行模式了,此時/home/zynq/linux/fsbl目錄下的內容如下所示:
圖 31.3.6 fsbl工程源碼目錄
/home/zynq/linux/fsbl就是我們通過hsi命令生成的fsbl對應的源碼目錄,這個就像是在Windows下使用SDK軟體創建了一個FSBL工程一樣,上圖中的executable.elf文件fsbl工程編譯之後得到elf格式文件;得到fsbl源碼工程之後,我們就可以直接在fsbl工程目錄進行編譯了,例如,在/home/zynq/linux/fsbl目錄下執行make clean命令對fsbl工程目錄進行清理,如下:
make clean
圖 31.3.7 清理工程
我們可以修改Makefile文件,將編譯產生的fsbl鏡像文件名字改為zynq_fsbl.elf,在fsbl工程目錄下,打開Makefile文件,修改EXEC變量,如下所示:
vi Makefile
圖 31.3.8 修改EXEC變量
將該變量由executable.elf修改為zynq_fsbl.elf,除此之外,我們還可以看到變量CC := arm-none-eabi-gcc,這指定了編譯fsbl時使用的交叉編譯工具,這個不用改,修改完成之後保存退出即可!我們直接在該目錄下執行make命令即可編譯,如下:
make
圖 31.3.9 make編譯fsbl工程
編譯成功之後產生的鏡像文件就成了fsbl_zynq.elf,如下所示:
圖 31.3.10 fsbl鏡像文件
20.4編譯U-Boot
在<第十四章 U-Boot移植>中,已經讓大家把xilinx官方的U-Boot拷貝到Ubuntu系統中了,並對他們進行了修改,添加了一些自己定義的文件,本篇教程不使用前面移植後的U-Boot,我們用一份新的xilinx官方2018.3版本(這個版本是xilinx設定的版本,其U-Boot版本為2018.01)的U-Boot源碼,源碼已經提供給大家了,路徑為:ZYNQ開發板資料盤(A盤)\4_SourceCode\ZYNQ_7010\3_Embedded_Linux\資源文件\uboot\u-boot-xlnx-xilinx-v2018.3.tar.gz,大家也可以通過https://github.com/Xilinx/u-boot-xlnx/releases網址進行下載。
首先將U-Boot源碼壓縮包文件拷貝到Ubuntu系統目錄中,例如/home/zynq/linux/u-boot目錄,並將其解壓到當前目錄,解壓之後會產生一個u-boot-xlnx-xilinx-v2018.3文件夾,進入到該目錄下,就可以看到U-boot源碼目錄下的文件和文件夾了,如下所示:
圖 31.4.1 U-Boot源碼目錄
在前面給大家講過,使用&34;命令可以對U-Boot進行配置、使用&34;命令可以編譯u-boot,那麼這些方法都是使用petalinux工具時的做法,這裡教大家如何在U-Boot源碼目錄下配置、編譯而不通過petalinux-xxx命令;
關於U-Boot我們已經在前面給大家進行了詳細的講解,包括Makefile文件、各個文件目錄的作用以及源碼的分析、U-Boot配置、U-Boot常用命令等等,這裡就不再講解。
1、添加設備樹文件
關於設備樹的概念現在不給大家講,後面會說。除了Linux內核支持設備樹之外,我們使用的U-Boot也是支持設備樹的;在31.2小節中我們使用hsi命令生成了一些dts和dtsi的設備樹源文件,現在我們要用到它們了,這些設備樹文件都是根據我們的hdf硬體設計而自動生成的,如果我們使用U-Boot中自帶的設備樹文件則不能滿足我們的情況。
將前面生成的設備樹文件(筆者這裡生成的設備樹文件在/home/zynq/linux/dts目錄下)pcw.dtsi、pl.dtsi、system-top.dts以及zynq-7000.dtsi四個文件拷貝到U-Boot源碼目錄下的arch/arm/dts目錄下,拷貝過去之後進入到arch/arm/dts目錄下查看,如下所示:
圖 31.4.2 拷貝設備樹文件到U-Boot
接下來我們需要對system-top.dts文件進行一個簡單地修改,打開system-top.dts文件,修改之前內容如下:
示例代碼20.4.1 system-top.dts修改之前
修改完成之後保存退出即可!
以上主要修改了bootargs屬性、添加了model屬性、網口0的MAC地址以及給qspi進行了分區操作。修改完成之後,我們還需要將system-top.dts文件添加到arch/arm/dts/Makefile文件中,找到dtb-$(CONFIG_ARCH_ZYNQ)這裡,將system-top.dtb(.dts編譯之後得到的就是.dtb文件)添加上去,這樣當CONFIG_ARCH_ZYNQ宏被選中的時候,system-top.dts才會被編譯進去,如下所示:
圖 31.4.3 添加system-top.dtb文件
注意在zynq-zybo.dtb後面加上一個反斜槓」\」,跟上面的保持一致。
添加好之後保存退出文件。
2、修改zynq-common.h和zynq_zc70x.h配置文件
include/configs/目錄下有很多的配置文件,該目錄下的配置文件中有很多宏定義,這些宏定義將會在編譯U-Boot源碼時會被用到;前面我們使用petalinux工具的時候並沒有去配置U-Boot、內核等,原因在於petalinux確實比較智能,它能夠根據hdf文件記錄的信息自動配置,例如一些時鐘頻率、外設時鐘、環境變量偏移量等。
zynq-common.h和zynq_zc70x.h都在include/configs目錄下,zynq-common.h是xilinx提供的用於配置zynq系列處理器的通用配置文件,zynq-common.h頭文件被zynq_zc70x.h包含,下面我們要對這兩個頭文件進行一些簡單地修改!
首先對zynq_zc70x.h文件進行修改,修改之前如下所示:
示例代碼20.4.3 zynq_zc70x.h修改之前
這裡我們要把CONFIG_ZYNQ_I2C0和CONFIG_ZYNQ_EEPROM宏定義給去掉,原因就是我不想在U-Boot中使用I2C設備,直接給去掉!修改之後如下:
示例代碼20.4.4 zynq_zc70x.h修改之後
接下來修改zynq-common.h文件,打開該文件,修改CONFIG_CPU_FREQ_HZ(ARM主頻),將頻率由800000000修改為666666687(如果是7020核心板則修改為766666687):
示例代碼20.4.5 zynq-common.h修改內容-1
修改CONFIG_ENV_SIZE(環境變量大小),由(128 << 10)修改為0x20000:
示例代碼20.4.7 zynq-common.h修改內容-3
修改CONFIG_ENV_OFFSET(環境變量存儲位置偏移量),由0xE0000修改為0x500000:
[size=13.3333px]示例代碼20.4.8 zynq-common.h修改內容-4
需要注意CONFIG_ENV_SIZE和CONFIG_ENV_OFFSET這兩個是U-Boot環境變量存儲有關的,在下面menuconfig配置U-Boot的時候我們會將環境變量存儲在QSPI中,CONFIG_ENV_SIZE指定了環境變量分區的大小,CONFIG_ENV_OFFSET指定環境變量分區的偏移量,這些都與QSPI的分區表有關!
修改完成之後保存退出即可,接下來就可以正式使用make命令進行配置和編譯了。
3、defconfig配置
在U-Boot的源碼目錄下,執行下面這條命令對xilinx官方的U-Boot進行defconfig配置,如下所示:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zynq_zc702_defconfig
圖 31.4.4 defconfig配置
「ARCH=arm」指定了u-boot運行的機器架構,「CROSS_COMPILE=arm-linux-gnueabihf-」指定了交叉編譯工具的前綴,交叉編譯工具我們使用的是xilinx官方提供的,在我們安裝petalinux的時候也安裝了,在petalinux安裝目錄下的tools/linux-i386目錄,如下所示:
圖 31.4.5 交叉編譯工具鏈安裝目錄
gcc-arm-linux-gnueabi和gcc-arm-none-eabi兩個目錄下安裝的是兩種不同的交叉編譯工具鏈(其它那幾個目錄安裝的也是交叉編譯工具鏈,對於ZYNQ 7010/7020來說用不上),兩者之間的區別大家可以簡單地理解為gcc-arm-linux-gnueabi一般用於編譯linux系統的源碼,例如ARM Linux內核源碼、ARM Linux應用程式等,而gcc-arm-none-eabi一般用於編譯ARM裸機程序,例如我們前面編譯fsbl代碼的時候用的就是它;這麼一說的話,那我們編譯U-Boot應該用gcc-arm-none-eabi咯,但這裡我們用的是gcc-arm-linux-gnueabi,主要筆者看到xilinx wiki文檔中用的也是這個,那就這個吧。
交叉編譯命令就在安裝目錄下的bin文件夾中,例如:
圖 31.4.6 交叉編譯命令
CROSS_COMPILE指定的就是這些命令的前綴,我們在前面source petalinux目錄下的settings.sh腳本時已經將它們的路徑導出到環境變量了,所以不用加全路徑。
zynq_zc702_defconfig是xilinx為7010/7020添加的配置文件,所以我們也是使用這個!
4、menuconfig圖形化配置
U-Boot圖形化配置前面已經給大家講過了,在U-Boot源碼目錄下,執行下面這條命令進入到menuconfig圖形化配置界面:
圖 31.4.7 menuconfig配置
各個配置項就不給大家一一講解了,相信大家通過前面的學習已經對U-Boot的menuconfig圖形化配置有一定的認識和理解了,接下來我直接把配置列出來:
配置完成之後保存退出,執行下面這條命進行編譯:
圖 31.4.8 編譯U-Boot
編譯完成之後將會在當前目錄下生成一個u-boot文件、u-boot.bin文件以及其它一些文件,如下所示:
圖 31.4.9 編譯完成
u-boot文件是elf格式的鏡像文件,而u-boot.bin則是純二進位格式的鏡像文件。
20.5編譯kernel
同樣本篇教程不使用前面移植後的Linux內核源碼,我們用一份新的xilinx官方2018.3版本(這個版本是xilinx設定的版本,其linux版本為4.14.0)的內核源碼,源碼已經提供給大家了,路徑為:ZYNQ開發板資料盤(A盤)\4_SourceCode\ZYNQ_7010\3_Embedded_Linux\資源文件\kernel\linux-xlnx-xilinx-v2018.3.tar.gz,大家也可以通過https://github.com/Xilinx/linux-xlnx/releases網址進行下載。
將內核源碼壓縮包文件拷貝到Ubuntu系統目錄中,例如/home/zynq/linux/kernel目錄,並將其解壓到當前目錄,解壓之後會產生一個linux-xlnx-xilinx-v2018.3文件夾,進入到該目錄下,就可以看到內核源碼目錄下的文件和文件夾了,如下所示:
圖 31.5.1 內核源碼目錄
本小節我們也是直接在內核源碼目錄下進行編譯,而不使用petalinux工具,其實這些知識前面都已經給大家介紹過了。
1、添加設備樹文件
這裡我們直接將前面U-Boot源碼arch/arm/dts目錄下的那四個設備樹文件(pl.dtsi、pcw.dtsi、system-top.dts和zynq-7000.dtsi)直接拷貝到內核源碼目錄下的arch/arm/boot/dts目錄中,不用進行修改。同樣我們也需要修改arch/arm/boot/dts目錄下的Makefile文件,將設備樹添加上去,如下:
圖 31.5.2 Makefile中添加設備樹
修改完成之後保存退出即可!
2、defconfig配置
在內核源碼目錄下執行下面這條命令對內核進行defconfig配置:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- xilinx_zynq_defconfig
圖 31.5.3 defconfig配置
命令這裡就不給大家解釋了,前面我們已經解釋過,內核的配置、編譯方式基本跟U-Boot是一樣的,需要注意的是命令中間的空格不要漏掉了,因為以前發現很多初學者老是會漏掉這些空格,這樣就導致命令執行失敗。
3、menuconfig配置
這裡我們暫時就不進行配置,以後有需要的時候再配,先保持默認!
4、編譯內核
執行下面這條命令編譯內核源碼:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage -j10
圖 31.5.4 編譯內核
圖 31.5.5 編譯完成
編譯完成之後會在arch/arm/boot/目錄下生成一個名為zImage的內核鏡像文件,後面我們在用。
5、編譯設備樹
內核與u-boot不同的是,U-Boot的設備樹默認是與內核一起編譯的,並且產生的dtb文件已經與U-Boot鏡像文件集成在一起了;在內核裡邊我們需要單獨編譯出設備樹的dtb文件,前面已經將我們所需要的設備樹文件拷貝到內核的arch/arm/boot/dts目錄下了,接下來執行這條命令編譯system-top.dtb文件:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- system-top.dtb -j10
圖 31.5.6 編譯設備樹
編譯成功之後會在arch/arm/boot/dts目錄下生成system-top.dtb文件。
20.6編譯rootfs
根文件系統我們直接使用petalinux進行編譯即可,首先進入petalinux的安裝目錄,使用petalinux-create命令新建一個petalinux工程,如下:
petalinux-create --type project --template zynq --name ALIENTEK-ZYNQ
圖 31.6.1 新建petalinux工程
進入到ALIENTEK-ZYNQ工程目錄下,執行petalinux-config --get-hw命令導入hdf硬體描述符文件:
cd ALIENTEK-ZYNQ
圖 31.6.2 導入hdf文件
這裡用的hdf文件就是31.1小節中使用的,在彈出來的配置界面中,我們不用進行任何配置,直接保存退出即可!等待它配置完成。
接下來直接編譯根文件系統:
圖 31.6.3 編譯根文件系統
等待其編譯完成,完成之後產生的根文件系統壓縮包在images/linux目錄下,如下所示:
圖 31.6.4 產生的根文件系統壓縮包
因為我們要使用SD卡啟動,並且SD卡會有一個EXT4格式的分區專門存放根文件系統,所以我們要使用壓縮格式的根文件系統,例如rootfs.tar.gz或rootfs.tar.bz2。
20.7啟動開發板
經過上面一系列的過程之後,我們就已經得到了啟動開發板的所有所需的鏡像文件了。例如我們使用petalinux工具會生成image.ub和BOOT.BIN文件,使用這兩個文件我們就可以啟動開發板了,但是這裡我們不這樣做。
前面給大家介紹過image.ub這個文件的本質,那麼它其實是多個文件組合在一起的,包括內核鏡像、dtb以及根文件系統,這樣的做法有一個弊端,不夠靈活,一個變了整個image.ub文件就得重新製作一遍,很麻煩。同樣BOOT.BIN文件是fsbl鏡像、u-boot鏡像以及pl端bit文件集合在一起的,那麼既然是集合在一起的,那麼我們單獨使用也是可以的嘛。
所以我們這裡的思路就是將內核鏡像文件zImage、內核設備樹文件以及根文件系統從image.ub文件中分離出來;而將bit文件從BOOT.BIN文件中分離出來,這樣做之後我們的SD卡中將會存在5部分內容:zImage、dtb、rootfs、bit以及BOOT.BIN(fsbl鏡像與u-boot鏡像的集合體),明確之後我們將他們拷貝到我們的SD卡中。
1、製作SD啟動卡
SD啟動卡的製作方式在17.2.10小節當中已經給大家介紹過了,這裡不再細說,筆者直接將一張16G的TF卡格式化了2個分區,FAT32和EXT4,如下所示:
圖 31.7.1 SD啟動卡分區信息
2、拷貝鏡像到FAT分區
將前面過程當中生成的各種鏡像文件拷貝到SD啟動卡的FAT分區,包括zImage(內核鏡像,內核源碼目錄arch/arm/boot/zImage)、system-top.dtb(內核設備樹dtb文件,內核源碼目錄arch/arm/boot/dts/system-top.dtb)、design_navigator_7010_wrapper.bit(pl端bitstream文件,/home/zynq/hdf/Navigator_7010.sdk/design_navigator_7010_wrapper.bit)。大家根據自己前面步驟當中文件存放的目錄去找到相應的這些鏡像文件。
接下來我們需要將BOOT.BIN文件拷貝到FAT分區,但是前面的過程中我們並沒有生成BOOT.BIN文件,這裡就需要使用前面生成的u-boot(U-Boot elf格式鏡像,U-Boot源碼目錄u-boot)和zynq_fsbl.elf(fsbl elf格式鏡像,/home/zynq/linux/fsbl/zynq_fsbl.elf)來製作BOOT.BIN文件。
首先我們進入到U-Boot源碼目錄下,將生成的u-boot文件重命名為u-boot.elf,如下所示:
圖 31.7.2 u-boot重命名
為啥要重命名呢?因為筆者發現使用petalinux-package命令製作BOOT.BIN文件的時候,如果elf格式文件沒有帶.elf後綴名會識別不了。接下來我們就可以用petalinux-package命令去生成BOOT.BIN文件了,在U-Boot源碼目錄下執行下面這條命令:
petalinux-package --boot -p /home/zynq/petalinux/v2018.3/ALIENTEK-ZYNQ --fsbl /home/zynq/linux/fsbl/zynq_fsbl.elf --u-boot ./u-boot.elf -o ./BOOT.BIN --force
圖 31.7.3 生成BOOT.BIN文件
petalinux-package命令前面已經給大家介紹過了,」-p」選項指定一個petalinux工程,如果直接在petalinux工程目錄下運行該命令則不需要用」-p」指定;」--fsbl」指定fsbl的elf格式鏡像;」 --u-boot」指定U-Boot的elf格式鏡像文件,大家根據自己的路徑情況進行修改;」-o」選項指定輸出文件的名字以及存放的路徑,例如這裡是將BOOT.BIN文件存放在當前目錄下,命令執行完成之後就會在當前目錄下生成一個BOOT.BIN文件,如上圖所示。我們使用ls查看下它的大小:
圖 31.7.4 BOOT.BIN文件大小
我們發現它只有600多K,但是u-boot.elf文件可是有4M多的,而zynq_fsbl.elf文件也有600多K,為啥合成為BOOT.BIN文件之後只有600多K了呢?原因在于格式問題,elf格式文件中除了機器碼之外,還包含了很多額外的信息,例如符號表、調試信息、重定位表、運行地址和加載地址等,信息量很大,所以導致elf文件很大,例如linux下的應用程式就是elf格式的,程序加載運行的時候會去解析,但是裸機下不能用elf格式,包括內核鏡像和U-Boot鏡像等都不能用elf格式;而bin文件則是最純粹的二進位機器代碼,沒有任何多餘的信息,所以文件小。
使用petalinux-package命令生成的BOOT.BIN文件的時候,它會解析我們給定的elf格式文件,獲取它的運行地址、加載地址以及真正的二進位機器代碼,然後再把它倆集合起來,所以BOOT.BIN文件就是一個.bin格式的文件,所以它小,相信說到這裡大家應該明白了!需要注意我們生成的BOOT.BIN文件中並不包含bit文件,前面已經跟大家說過了。
之後將BOOT.BIN文件也拷貝到SD啟動卡的FAT分區,那麼此時來看看我們的FAT分區有哪些文件:
圖 31.7.5 FAT分區文件列表
為了方便、好看,筆者將design_navigator_7010_wrapper.bit文件和system-top.dtb文件進行了重命名,分別為system.bit和system.dtb,如下:
圖 31.7.6 文件重命名
3、將根文件系統解壓到EXT4分區
接下來我們需要將31.6小節編譯的根文件系統壓縮包文件解壓到SD啟動卡的EXT4分區,這裡筆者使用rootfs.tar.gz壓縮包文件,進入到rootfs.tar.gz壓縮包文件所在目錄,執行解壓命令:
圖 31.7.7 解壓rootfs.tar.gz
/media/zynq/ext4是筆者的SD啟動卡對應的EXT4分區的掛載點,注意解壓的時候需要使用前面要加sudo,也就是要以root用戶的身份進行解壓。解壓完成之後執行sync命令將數據同步到SD卡中,之後卸載SD啟動卡,卸載成功之後拔掉它!
圖 31.7.8 卸載SD啟動卡
4、啟動開發板
將我們做好的啟動卡插入開發板,連接電源、串口啟動,列印信息如下所示:
圖 31.7.9 開發板啟動
在U-Boot啟動2秒倒計時之前,按回車或者是空格鍵停止啟動,進入到U-Boot的命令行模式,因為現在不能直接啟動,我們需要對U-Boot環境變量進行修改,在U-Boot命令行下執行下面這些命令設置環境變量,如下所示:
圖 31.7.10 設置環境變量
示例代碼20.7.1 U-Boot環境變量設置
關於U-Boot命令的使用在前面已經給大家講解過,不過這裡也給大家簡單地說明一下我們設置的這些環境變量的作用:
首先第一條命令我們設置了bitstream_load_address變量存放bitstream文件從SD卡中拷貝到內存中的地址;第二條命設置了bitstream_image變量等於SD卡中bitstream文件的名字,也就是system.bit;第三條命設置了bitstream_size變量等於bitstream文件的大小;第四條命令設置了kernel_image變量等於SD卡中內核鏡像的名字,也就是zImage;第五條命令設置了devicetree_image變量等於SD卡中內核設備樹dtb文件的名字,也就是system.dtb;kernel_image和devicetree_image我們的這個U-Boot中默認是有的,只不過它們的內容並不是我們SD中的文件名,所以需要重新設定。
最後一條命令設置了sdboot變量,其實這個變量在我們使用的這個U-Boot中也是存在的,這裡也是對他重新定義,這個變量的內容很長,我們可以把它的內容整理一下,如下:
示例代碼20.7.2 sdboot變量內容整理
「&&」符號其實就是C語言中」與」,跟C語言裡面的作用一毛一樣,${xxx}就是變量的引用,if … fi這個就是if條件判斷語句了,fi表示條件判斷的結束,U-Boot裡邊的這種語法很簡單地,就不給大家細說了,如果不明白可以在網上找找資料。
前面跟大家講過,U-Boot中的bootcmd變量的作用,U-Boot啟動內核或在命令行下執行boot命令時其實就是去執行bootcmd,那我們來看看bootcmd的內容是什麼:
圖 31.7.11 bootcmd的內容
圖 31.7.12 modeboot的內容
所以從上面可以知道,bootcmd的內容其實就是運行sdboot,也就是上面定義的那個。
變量設置完成之後,執行saveenv保存環境變量到QSPI Flash中,那麼下次就不用再設置了
圖 31.7.13 保存環境變量
保存完成執行boot命令啟動內核:
圖 31.7.14 啟動內核
啟動完成之後登陸系統(用戶名和密碼都是root):
圖 31.7.15 登陸系統
後面我們的驅動開發篇將以本章使用的U-Boot源碼、內核源碼等進行開發工作!
20.8tcl腳本
前面我們在hsi終端下通過執行相應的命令去獲取bit文件、自動生成設備樹以及構建一個fsbl源碼等,覺得這樣非常的不方便,每次都要先執行hsi命令進入到hsi終端模式,然後在一個一個命令敲,這樣感覺非常不好,那可不可以像shell命令一樣,創建一個shell腳本之類的呢?其實是可以的,我們可以創建一個後綴名為.tcl的腳本,然後把我們的命令添加上去,然後直接執行這個腳本就行了。
例如我在Ubuntu目錄下新建一個hsi_test.tcl文件,內容如下所示:
文件中的hsi::open_hw_design xxx.hdf就表示執行his的open_hw_design命令,後面跟著的參數就是對應的hdf文件路徑了,例如我們將31.2小節中執行的命令寫入到hsi_test.tcl腳本中,如下所示:
示例代碼20.8.1 tcl腳本示例 hsi_test.tcl內容
圖 31.8.1 運行hsi_test.tcl腳本
「xsct xxx.tcl」即可!xsct也是petalinux工具安裝的時候自帶的,它也是命令行終端,例如運行xsct命令就會進入到xsct終端模式,如下所示:
圖 31.8.2 xsct終端
例如我們在xsct終端下也可以執行腳本中的命令,例如:
圖 31.8.3 xsct運行hsi命令
所以當我們執行」xsct hsi_test.tcl」命令時其實就是類似於將hsi_test.tcl交給xsct去解析並運行。
關於xsct、hsi以及tcl腳本等更多的內容這裡就不講了,筆者對這些沒有什麼深入的了解!如果大家感興趣自己去網上找找相關的資料。