這篇博文講述的是在Linux環境下,將生成的新BOOT.BIN利用dd指令寫入板上qspi flash中。板子從flash啓動後,轉至SD卡執行linux內核。這篇博文是爲了之後不使用SD卡,將linux內核以及根文件系統放入emmc啓動做準備。
目錄
2 - 建立新的"BOOT_FOR_QSPIFLASH.BIN"
3 - 利用SD卡上運行的linux系統燒錄新的BOOT.BIN到FLASH中
0 - 前言
前面我們使用petalinux製作linux從板子上啓動都是從SD卡(TF卡)啓動的,但是在絕大部分的應用場景中,使用SD卡作爲存儲載體明顯不是一個很好的選擇。爲了探究如何擺脫SD卡的存儲方式,這篇博文記載了些實驗性的研究。
ZYNQ的上電啓動其實可以分爲三個部分:BootROM、FSBL(First Stage Boot Loader)以及用戶程序。這裏用戶程序可能是裸機程序,或者其他更“高級”操作系統的BootLoader,對於linux來說這裏就是uboot。
這裏我們不細談上電啓動,感興趣的可以參考xilinx的XAPP1158,是講解vxworks在zynq上的部署方法,但是前半部分講解了zynq的啓動流程。我們知道,在使用petalinux生成linux時,執行petalinux-package後會生成兩個文件,一個BOOT.BIN,一個是image.ub,根據你給的指令,會打包不同的文件進入BOOT.BIN。這裏我們以下面這個命令舉例:
petalinux-package --boot --fsbl --fpga --u-boot --force
執行這條語句,會將FSBL、比特流文件(PL端配置程序)及uboot打包爲BOOT.BIN文件。當ZYNQ上電啓動後,先執行固化在內部的BootROM程序,初始化NAND、NOR、Quad-SPI、SD以及PCAP。BootROM執行完畢後,會將FSBL加載到OCM(On Chip Memory)然後執行FSBL。FSBL中會用比特流文件對PL部分編程,初始化DDR,然後將用戶程序(uboot)拷貝到DDR來執行。這裏可以看到,FSBL以及我們的UBOOT其實是被打包在了BOOT.BIN文件中,而我們的linux內核,linux根文件系統則可以在其他的地方,只要告訴uboot執行時跳轉到哪裏調用linux內核即可。
因此,我們爲了使用板載的“固態”存儲器來啓動linux系統,我們有兩種方法來完成這個操作:
- BOOT.BIN放置在QSPI Flash中,linux內核(image.ub)、linux根文件系統放置在emmc中。選擇從QSPI啓動
- BOOT.BIN、image.ub以及根文件系統都放置到emmc中。選擇從emmc啓動
那麼就有一個問題,我們要如何將BOOT.BIN、image.ub以及根文件系統分別放置到flash和emmc中呢?因爲這些板載的存儲器並不像sd卡或者tf卡一樣可以直接使用讀卡器從電腦上進行讀寫。有一種方便的方法就是用已經在sd卡中搭建好的linux來對這些flash和emmc進行操作。
下面以將BOOT.BIN寫入FLASH中,uboot喚起SD卡中的image.ub做個例子。爲啥不做emmc的?因爲我新買的板子還沒到,手頭這個板子沒得emmc。
注:zynq7000系列不支持將emmc作爲第一啓動設備,即不支持從emmc讀取BOOT.BIN中的FSBL,ultrascale系列支持這項操作。
參考:
- https://www.xilinx.com/support/answers/50991.html
- 《UG585- Zynq-7000 SoC Technical Reference Manual 》中 11.2.1 Boot Device
1 - 準備工作
一塊已經能從sd卡跑linux的,板上有QSPI FLASH,並且vivado建立工程時已經連接好這個flash,petalinux生成的linux(或者包含好了qspi flash驅動的linux)的一塊fpga板卡。
2 - 建立新的"BOOT_FOR_QSPIFLASH.BIN"
打開之前的工程(可以參考之前的博客https://blog.csdn.net/sements/article/details/88921275#6%20-%20%E7%94%9F%E6%88%90BOOT.BIN%E5%8F%8Aimage.ub%E6%96%87%E4%BB%B6),運行下面的指令進行petalinux的配置
petalinux-config
在打開的頁面中,修改下列的選項
- 設置boot image settings存儲媒介爲primary flash(即我們板上的QSPI FLASH)
- 設置kernel image settings存儲媒介爲primary sd
#Subsystem AUTO Hardware Settings --->
# Advanced bootable images storage Settings --->
# boot image settings --->
# image storage media ---> primary flash
# kernel image settings --->
# image storage media ---> primary sd
題外話:zynq支持兩個SD/SDIO外設,可以接SD卡或者emmc芯片。當兩者都在硬件設計上存在時,接在SD0上的設備在/dev中顯示爲mmcblk0,SD1上的顯示爲mmcblk1。這裏不需要考慮,因爲我板上沒有添加emmc硬件,只有sd卡硬件,但是當後面兩者同時存在時,則需要在SD/SDIO Settings 配置項中指定主要的SD外設。
參考【 】CH10 調整EMMC和SD的掛載順序並且實現開機自動燒錄QSPI - LINUX教程(2018) 米聯客 http://www.osrc.cn/forum.php?mod=viewthread&tid=1647&extra=page%3D1%26filter%3Dauthor%26orderby%3Ddateline
重新編譯:
petalinux-build
編譯完成後,我們打包生成BOOT.BIN
petalinux-package --boot --fsbl --fpga --u-boot --force
從images/linux文件夾下拷貝出BOOT.BIN備用。
3 - 利用SD卡上運行的linux系統燒錄新的BOOT.BIN到FLASH中
將新的BOOT.BIN拷貝到正在運行的SD卡上的linux系統中(可以用sftp傳輸)。
打開/dev文件夾,查看FLASH:
ls /dev
可以看到,這裏mtd開頭的即是我們板上的flash了,我們接下來需要將新的BOOT.BIN寫入到mtdblock0中即可
dd if=新的BOOT.BIN of=/dev/mtdblock0
寫入完畢後,poweroff關機linux,將開發板啓動模式選擇爲QSPI,將SD卡拔出,上電,我們可以看到以下的調試信息
U-Boot 2018.01 (Apr 28 2019 - 12:58:04 +0000) Xilinx Zynq ZC702
Model: Zynq ALINX Development Board
Board: Xilinx Zynq
Silicon: v3.1
I2C: ready
DRAM: ECC disabled 512 MiB
MMC: Card did not respond to voltage select!
mmc_init: -95, time 23
mmc@e0100000 - probe failed: -95
Card did not respond to voltage select!
mmc_init: -95, time 24
SF: Detected w25q256 with page size 256 Bytes, erase size 4 KiB, total 32 MiB
*** Warning - bad CRC, using default environment
In: serial@e0001000
Out: serial@e0001000
Err: serial@e0001000
Model: Zynq ALINX Development Board
Board: Xilinx Zynq
Silicon: v3.1
Net: ZYNQ GEM: e000b000, phyaddr 1, interface rgmii-id
eth0: ethernet@e000b000
U-BOOT for alinx_linux_base
ethernet@e000b000 Waiting for PHY auto negotiation to complete...... done
BOOTP broadcast 1
DHCP client bound to address 192.168.2.54 (8 ms)
Hit any key to stop autoboot: 0
Card did not respond to voltage select!
mmc_init: -95, time 23
** Bad device mmc 0 **
no mmc device at slot 0
Zynq>
說明已經正常的從QSPI FLASH中加載新的BOOT.BIN,並運行uboot了,只是這裏由於我將SD卡拔出,所以"no mmc device at slot0"
斷電,將帶有image.ub的SD卡插入,重新上電(還是從QSPI啓動),可以看到以下調試信息
可以看到linux系統已經正常的跑起來了。