Porting Linux for Zynq¶
Khái niệm chung về chuỗi boot xem tại Bootloader trong hệ nhúng Linux. Environment, FIT image và các lệnh boot của U-Boot xem tại U-Boot. Trang này tập trung vào phần riêng của Zynq.
Chuỗi boot trên Zynq-7000¶
Zynq-7000 có hai phần: PS (Processing System, 2 nhân Cortex-A9) và PL (Programmable Logic, FPGA). PS luôn khởi động trước, PL chỉ hoạt động sau khi được nạp bitstream. Chuỗi boot gồm:
- BootROM: code cố định trong chip. Đọc chân boot mode (trên Zedboard chọn bằng jumper JP7 đến JP11), tìm boot header trong boot media, nạp FSBL vào OCM (On-Chip Memory, 256 KB; FSBL tối đa khoảng 192 KB). BootROM cũng xử lý giải mã và xác thực FSBL nếu bật secure boot.
- FSBL (First Stage Boot Loader): generate từ Xilinx SDK/Vitis theo file thiết kế phần cứng (
.hdf/.xsa), vì nó chứaps7_initcấu hình clock, DDR, MIO đúng như thiết kế trong Vivado. FSBL đọc các partition trongBOOT.BIN: nạp bitstream vào PL qua PCAP (nếu có), nạp U-Boot vào DDR rồi nhảy sang U-Boot. - U-Boot (SSBL, Second Stage Boot Loader): nạp kernel, DTB, rootfs (hoặc initramfs) rồi boot Linux.
Boot media mà BootROM hỗ trợ: JTAG, QSPI, NAND, NOR và SD (chỉ SD0). Zynq-7000 không boot trực tiếp từ eMMC: thường boot từ QSPI rồi để U-Boot nạp kernel và rootfs từ eMMC.
U-Boot SPL thay cho FSBL
Mainline U-Boot hỗ trợ SPL cho Zynq-7000: SPL dùng file ps7_init_gpl.c sinh từ thiết kế phần cứng và đóng vai trò FSBL, output là spl/boot.bin. Cách này bỏ được phụ thuộc vào SDK, nhưng FSBL của Xilinx vẫn là cách phổ biến và được hỗ trợ tốt hơn (secure boot, multiboot, fallback).
BOOT.BIN và bootgen¶
BOOT.BIN là file BootROM đọc, gồm boot header và các partition. File này tạo bằng bootgen từ một file .bif mô tả các partition theo thứ tự:
[bootloader]đánh dấu partition FSBL, BootROM nạp phần này vào OCM.- Bitstream
system.bitlà tùy chọn. Nếu bỏ, có thể nạp bitstream sau bằng lệnhfpga loadbtrong U-Boot hoặc qua FPGA Manager trong Linux. - Có thể thêm partition dữ liệu nạp vào DDR tại địa chỉ cố định, ví dụ
[load=0x2a00000] system.dtb. - Petalinux tạo file này bằng
petalinux-package --boot --fsbl <fsbl.elf> --fpga <system.bit> --u-boot.
Bố trí SD card¶
Với boot mode SD, BootROM đọc BOOT.BIN từ phân vùng FAT đầu tiên. Bố trí thường dùng:
| Phân vùng | Định dạng | Nội dung |
|---|---|---|
| 1 | FAT32 | BOOT.BIN, kernel (uImage/zImage) và system.dtb, hoặc image.ub (FIT), boot.scr hoặc uEnv.txt |
| 2 | ext4 | Root filesystem |
Chi tiết các bước xem tại Boot from SD Card with ext4 filesystem.
Một bootcmd tối giản để boot từ SD với kernel uImage (build với UIMAGE_LOADADDR=0x8000 như phần Linux Kernel):
=> setenv bootargs console=ttyPS0,115200 root=/dev/mmcblk0p2 rw rootwait earlycon
=> fatload mmc 0 0x3000000 uImage
=> fatload mmc 0 0x2a00000 system.dtb
=> bootm 0x3000000 - 0x2a00000
Với kernel zImage thay bootm bằng bootz. U-Boot của Xilinx các bản mới dùng Standard Boot / distro boot, tự tìm boot.scr trên phân vùng FAT; Petalinux sinh sẵn boot.scr này.
QSPI¶
Với boot mode QSPI, BOOT.BIN ghi từ offset 0 của flash. Kernel, DTB và rootfs đặt ở các offset tiếp theo (theo bảng phân vùng trong cấu hình Petalinux hoặc trong DTB). Ghi flash từ U-Boot:
=> sf probe 0
=> fatload mmc 0 ${loadaddr} BOOT.BIN
=> sf erase 0 +${filesize}
=> sf write ${loadaddr} 0 ${filesize}
Hoặc dùng program_flash của Vivado/SDK qua JTAG, cần chỉ định FSBL để công cụ khởi tạo PS trước khi ghi.
Khác biệt trên Zynq UltraScale+ MPSoC (ZynqMP)¶
ZynqMP (Cortex-A53 64-bit, Cortex-R5, PMU) có chuỗi boot dài hơn:
PMU ROM + CSU BootROM ──► FSBL (A53 hoặc R5) ──► PMU firmware
│
├──► TF-A BL31 (EL3) ──► U-Boot (EL2) ──► Linux
└──► (tùy chọn) bitstream, OP-TEE, firmware R5
- PMU firmware chạy trên MicroBlaze trong PMU, quản lý nguồn và reset cho toàn chip. Linux gọi tới nó qua TF-A (giao thức EEMI).
- TF-A BL31 ở lại EL3 lúc runtime để xử lý PSCI và SMC. Xem Secure boot và TrustZone.
- U-Boot chạy ở EL2 và boot kernel
Imagebằngbooti. - Từ Versal, PMU và CSU được thay bằng PMC và PLM,
BOOT.BINchuyển sang định dạng PDI.
File .bif cho ZynqMP chỉ rõ CPU đích và exception level cho từng partition:
the_ROM_image:
{
[bootloader, destination_cpu=a53-0] zynqmp_fsbl.elf
[pmufw_image] pmufw.elf
[destination_device=pl] system.bit
[destination_cpu=a53-0, exception_level=el-3, trustzone] bl31.elf
[destination_cpu=a53-0, exception_level=el-2] u-boot.elf
}
U-Boot on Zynq¶
References¶
[1] - Build U-Boot - xilinx-wiki.atlassian.net
Build U-Boot for Zedboard¶
Tiến hành build u-boot cho chip Zynq7000 trên Zedboard theo hướng dẫn từ xilinx-wiki.atlassian.net - Build U-Boot.
Quá trình build U-Boot cho một thiết bị Zynq7000 có thể tiến hành bằng cách sử dụng bộ công cụ Petalinux của Xilinx. Thử nghiệm này sẽ trực tiếp build U-Boot từ mã nguồn cung cấp bởi Xilinx từ Github bằng compiler cung cấp bởi Xilinx SDK.
make U-Boot
Tiến hành theo các bước hướng dẫn trong [1], tiến hành fetch source code, cấu hình và make U-Boot.
> git clone https://github.com/Xilinx/u-boot-xlnx.git
> cd u-boot-xlnx
> export CROSS_COMPILE=arm-linux-gnueabihf-
> export ARCH=arm
> source <SDK setting.sh file> // khai báo arm-linux-gnueabihf compiler
> make distclean
> make zynq_zed_defconfig
> make
u-boot.elf. File này có thể tiến hành chạy thử nghiệm bằng phương pháp sử dụng XSCT được mô tả ở phần Zedboard.
Nhận xét¶
- Compiler sử dụng cho build U-Boot là họ chương trình: arm-linux-gnueabihf-*. Ví dụ gcc được định nghĩa tại [SDX Installation Dir]/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-gcc.
zynq_zed_defconfiglà bộ cấu hình dành riêng cho board zed. Các phần cứng khác sẽ có bộ cấu hình tương tự, ví dụzynq_zc706_defconfigcho ZC706.
Linux Kernel¶
Quá trình thực hiện được tham khảo từ hướng dẫn chi tiết Build kernel của Xilinx.
Xilinx duy trì một github repository chứa source code Linux kernel. Quá trình build Linux kernel từ mã nguồn này tương đối đơn giản. Cần lưu ý một số điểm quan trọng như sau:
- Quá trình build kernel sử dụng họ compiler arm-linux-gnueabihf, do đó cần cấu hình
export CROSS_COMPILE=arm-linux-gnueabihf- - Tại source code của Linux kernel thực hiện những bước sau:
- Kết quả build kernel được lưu tại: [Linux source]/arch/arm/boot/ bao gồm các nội dung như dưới đây. Trong đó quan trọng nhất là Image, uImage, zImage.
drwxrwxr-x 2 vutt6 vutt6 4096 Feb 15 00:53 bootp drwxrwxr-x 2 vutt6 vutt6 4096 Mar 4 15:21 compressed -rwxr-xr-x 1 vutt6 vutt6 1805 Feb 15 00:53 deflate_xip_data.sh drwxrwxr-x 2 vutt6 vutt6 73728 Feb 15 00:53 dts -rwxrwxr-x 1 vutt6 vutt6 10662592 Mar 4 15:21 Image -rw-rw-r-- 1 vutt6 vutt6 1648 Feb 15 00:53 install.sh -rw-rw-r-- 1 vutt6 vutt6 3128 Feb 15 00:53 Makefile -rw-rw-r-- 1 vutt6 vutt6 4160040 Mar 4 15:21 uImage -rwxrwxr-x 1 vutt6 vutt6 4159976 Mar 4 15:21 zImage
uImage sẽ được sử dụng cho quá trình đóng gói boot.bin.
Device Tree¶
Build Device Tree Blob - Xilinx.
Trong hướng dẫn của Xilinx hướng dẫn nhiều cách để build device tree cho một thiết bị Zynq.
Generate Device Tree bằng HSM/HSI¶
Khởi động HSM bằng command hsm, trong đó HSM là một công cụ tích hợp trong SDK của Xilinx. Quá trình generate bằng HSM được thực hiện tuần tự trong hướng dẫn của Xilinx (tại đây).
Tổng hợp DTB bằng công cụ dtc¶
Device tree được generate dưới dạng các file dts/dtsi. Công cụ dtc (Device tree compiler) hỗ trợ compiling từ dạng dtsi/dts sang dtb. Cú pháp compile như sau:
dtc -I dts -O dts -o system.dtb system.dts
Lưu ý rằng dtc cũng hỗ trợ quá trình dịch ngược từ dtb -> dts.
Build rootfs¶
http://xilinx.wikidot.com/zynq-rootfs
Create boot image¶
Sử dụng công cụ bootgen tích hợp trong Xilinx SDK. Xem mục BOOT.BIN và bootgen.
Tool for package images¶
mkimage - Generate image for U-Boot
The mkimage command is used to create images for use with the U-Boot boot loader. Thes eimages can contain the linux kernel, device tree blob, root file system image, firmware images etc., either separate or combined.
mkimage is used in Petalinux 2017.4 at do_xilinx_fitimage:
uboot-mkimage -f fit-image.its fitImage
In do_image_cpio, mkimage is used to packaged ramdisk file petalinux-user-image-plnx_arm-20190301083938.
cpio - copy files to and from archives
mke2fs - create an ext2/ext3/ext4 filesystem