Felven的博客 發表於 2020-12-14 14:59:02
一、組成
ZYNQ上面移植Linux作業系統包括四個部分,uboot,devicetree,kernel,ramdisk.
其中uboot類似於bios,負責對設備進行簡單的初始化,devicetree以樹的形式對zynq相連的硬體設備進行描述,kernel是加載的作業系統內核,ramdisk是作業系統啟動之後掛載的文件系統。
二、啟動過程
移植作業系統後zynq的啟動過程如下,首先加載bootrom(zynq中自帶,用戶無法修改),然後執行fsbl(這個根據硬體在sdk中創建),然後執行uboot,uboot會將kernel、devicetree和ramdisk載入ddr,跳轉到內核入口處執行,這樣linux就啟動了。
對bootrom、fsbl和uboot詳細描述如下。
三、uboot設置
uboot可以從xilinx 官方github上面下載,地址是:
通常uboot不需要升級,目前使用的版本為xilinx 2015年底發布的版本2015.4.不過針對不同的模塊uboot需要進行修改,主要修改下面幾個地方。
1、參考時鐘修改
地址位於arch/arm/cpu/armv7/zynq/clk.c
由於ZYNQ設計大多使用50M參考時鐘,需要更改參考時鐘
# define CONFIG_ZYNQ_PS_CLK_FREQ 33333333UL更改為
# define CONFIG_ZYNQ_PS_CLK_FREQ 50000000UL
2、串口配置修改
地址位於include/configs/zynq_zc70x.h
根據硬體串口情況進行配置
#define CONFIG_ZYNQ_SERIAL_UART1 使用串口1
#define CONFIG_ZYNQ_SERIAL_UART0 使用串口0
如果兩個串口都啟用,一起配置即可。
3、DDR配置修改
地址位於include/configs/zynq_zc70x.h
根據DDR實際大小地址修改配置參數
#define CONFIG_SYS_SDRAM_SIZE (1024 * 1024 * 1024) 1GB DDR
#define CONFIG_SYS_SDRAM_SIZE (512 * 1024 * 1024) 512MB DDR
4、PHY地址配置
地址位於include/configs/zynq_zc70x.h
根據硬體PHY地址進行配置,通常硬體會將PHY地址設置為0
#define CONFIG_ZYNQ_GEM_PHY_ADDR0 0
如果硬體啟用了兩個網卡,則需要設置兩個PHY的地址
#define CONFIG_ZYNQ_GEM0
#define CONFIG_ZYNQ_GEM_PHY_ADDR0 1
#define CONFIG_ZYNQ_GEM1
#define CONFIG_ZYNQ_GEM_PHY_ADDR1 18
5、啟動方式配置
地址位於include/configs/zynq_common.h
如果使用QSPI flash方式啟動,需要配置QSPI FLASH對應地址,如下。
"sf probe 0 0 0 && " /
"sf read 0x3000000 0x400000 ${kernel_size} && " /
"sf read 0x2A00000 0x900000 ${devicetree_size} && " /
"echo Copying ramdisk... && " /
"sf read 0x2000000 0x920000 ${ramdisk_size} && " /
"bootm 0x3000000 0x2000000 0x2A00000/0" /
6、IP位址配置
地址位於include/configs/zynq_common.h
#define CONFIG_IPADDR 192.168.100.12 //uboot啟動時板子的IP位址
#define CONFIG_SERVERIP 192.168.100.6 //uboot啟動時能訪問的遠程伺服器地址,若採用TFTP加載,需要將本地電腦配置為該地址
7、啟動延遲設置
地址位於include/configs/zynq_common.h
#define CONFIG_BOOTDELAY 7 /* -1 to Disable autoboot */
Uboot默認延遲7s再從QSPI flash中加載作業系統,如果設置為-1表明禁止自動加載
8、初始化設置
地址位於net/eth.c 和 arch/arm/lib/board.c
Uboot中需要對5396進行初始化,同時使用GPIO對PHY或NOR FLASH等進行復位,可以在eth.c中增加代碼
void mygpio_init()
{ }
然後將Mygpio_init()加入到arch/arm/lib/board.c中
9、Uboot編譯
修改完成後,可以使用下列命令編譯產生uboot
進入u-boot文件夾
$ make distclean //文件夾清理
$ make zynq_zc70x_config // 載入配置,通常使用zynq_zc70x.h文件
$ make
編譯完成後文件夾下會出現u-boot文件,將其修改為u-boot.elf
3、將dtsi,dts文件拷入linux系統下,使用dts工具製作devicetree.dtb文件
4、如果需要修改devicetree文件,可以通過dtc工具轉換為可讀文件dts
生成的1.dts可打開,裡面能看到zynq端的外設信息和啟用情況。通常需要修改網卡配置,如下,下例中phy地址為0
ethernet@e000b000 {
compatible = "xlnx,ps7-ethernet-1.00.a";
reg = ;
status = "okay";
interrupt-parent = ;
interrupts = ;
clocks = ;
clock-names = "ref_clk", "aper_clk";
#address-cells = ;
#size-cells = ;
enet-reset = ;
local-mac-address = [00 0a 35 00 00 00];
phy-mode = "rgmii";
phy-handle = ;
xlnx,eth-mode = ;
xlnx,has-mdio = ;
xlnx,ptp-enet-clock = ;
mdio {
#address-cells = ;
#size-cells = ;
phy@0 {
compatible = "marvell,88e1111";
device_type = "ethernet-phy";
reg = ;
linux,phandle = ;
phandle = ;
};
};
};
當對dts修改完成後,再次使用dtc工具編譯產生devicetree.dtb即可
五、文件系統設置
文件系統一般隨zynq開發板發布,可以從prebuit中找到文件系統的tar文件
在文件系統中,如果需要添加用戶自定義的shell腳本或可執行程序,可以放在/usr/bin目錄下。如果要設置系統自啟動項,可以在/etc/rc5.d中增加shell腳本。
1、文件系統製作
當修改完rootfs後,可以通過下面命令製作uramdisk文件系統
$sh -c 'cd rootfs/ && find . | cpio -H newc -o' | gzip -9 > new_initramfs.cpio.gz
$mkimage -A arm -T ramdisk -C gzip -d new_initramfs.cpio.gz uramdisk.image.gz
執行完畢將會得到uramdisk.image.gz
六、內核配置
內核可以從xilinx官方git下載,地址:
目前linux內核中已經集成了常見的驅動,驅動源碼位於drivers文件夾下。針對內核的修改位於 arch/arm/configs/xilinx_zynq_defconfig文件中,該文件中定義了內核所包含的驅動程序。
1、調試輸出列印
在xilinx_zynq_defconfig中,需要根據硬體設計正確配置串口列印。
CONFIG_DEBUG_LL=y
CONFIG_DEBUG_ZYNQ_UART0=y //使用串口0列印輸出
CONFIG_EARLY_PRINTK=y
2、內核編譯
修改完xilinx_zynq_defconfig後,可以使用下面命令編譯內核
$sudo //編譯內核需要運行在root權限下
$make distclean //清理文件
$make ARCH=arm xilinx_zynq_defconfig //讀取內核配置信息,即xilinx_zynq_defconfig中的內容
$make ARCH=arm menuconfig //進入內核菜單進行可視化配置,如果xilinx_zynq_defconfig中對內核配置準確時,該步驟可以省略
$make ARCH=arm UIMAGE_LOADADDR=0x8000 uImage -j4 //編譯產生uImage
產生的文件位於arch/arm/boot文件夾內
七、常見驅動
1、I2C驅動
目前板子上都會用到I2C,首先需要知道I2C從設備的地址,如2/4/8這些.在devicetree中進行設置
編譯內核的時候加入該驅動,同時修改makefile和kconfig文件
這樣在編譯內核的時候就能看到將驅動編進內核的選項了。
2、ADC驅動
ADC為ZYNQ用來監測電壓或電流的通道,目前ZYNQ中集成了16個通道,首先需要在devicetree中設置啟用的通道,圖中啟用的是0,1,8三個通道
3、NOR FLASH驅動
NOR FLAHS驅動主要實現文件系統的掛載,這裡不需要設置devicetree,只需要在內核中添加掛載文件系統的代碼
上圖中將NOR FALSH分為2個區,大小分別為32MB和64MB,需要注意的是NOR FLASH的起始地址和容量大小設置
#defineWINDOW_ADDR 0x80000000 //和vivado裡面的emc起始地址一致
#defineWINDOW_SIZE 0x8000000 //nor flash大小
在makefile中將該驅動編譯進內核即可
4、外部中斷驅動
當zynq接收來自外部的GPIO中斷時,需要使用UIO機制及時響應中斷,首先在devicetree中模擬出四個GPIO設備
注意上面的中斷號0x1e-0x21要與硬體實際相連的中斷管腳一致。
同時在devicetree中啟用UIO機制
當作業系統啟動完成後就能看到四個外部GPIO設備產生的中斷了
八、啟動文件製作
如下圖所示,在SDK中創建boot.bin需要包含下面五個文件
Fsbl.elf
Zynq_top.bin
u-boot.elf
uImage
devicetree.dtb
uramdisk.image.gz
製作過程中需要正確配置uimage,devicetree.dtb,uramdisk.image.gz的地址,讓其與u-boot中從QSPI flash加載地址匹配
製作完成後將boot.bin通過下載電纜燒入QSPI FLASH中即可。
編輯:hfy
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容圖片侵權或者其他問題,請聯繫本站作侵刪。 侵權投訴