This article describes a flow to build a CentOS 8 system for Zynq UltraScale+ which includes building UEFI firmware, building the CentOS 8 kernel and installing these images on a prebuilt CentOS 8 disk image for booting on a ZCU102.
Table of Contents
Table of Contents | ||||
---|---|---|---|---|
|
...
Because the installed CentOS kernel image may not include some critical configurations required for Zynq UltraScale+, you may need to build a bootstrap kernel. Once we boot the bootstrap kernel, we can formally install the kernel RPMS which will install installs the newly configured kernel , update and updates the initrd , and update the GRUB configuration.
Code Block | ||
---|---|---|
| ||
$ grep 'SERIAL_XILINX\|ARCH_ZYNQMP\|SDHCI_OF_ARASAN' SOURCES/kernel-aarch64.config |
If all of these are options are enabled, then the installed kernel should support Zynq UltraScale+ and you can skip this sectionThese are the minimal kernel configs required to boot the ZCU102 from an SD card with serial console.
Code Block | ||
---|---|---|
| ||
CONFIG_ARCH_ZYNQMP=y CONFIG_SERIAL_XILINX_PS_UART=y CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y CONFIG_MMC_SDHCI_OF_ARASAN=m |
...
Tip |
---|
If all of these are options are enabled, then the installed kernel should boot on the ZCU102 and you can skip to “Build the Kernel RPM Packages.” |
Warning |
---|
If the kernel hangs, i.e. no kernel console messages, then revisit this section and try building a bootstrap kernel. Note you should still see the FSBL banner, PMUFW, ATF and u-boot messages. If you don’t, then something is wrong with your boot.bin on the FAT partition. |
First we need to run the “%prep” stage in our SPEC file which will unpack and patch the kernel source.
...
You may optionally change the password with “virt-customize”.
Code Block | ||
---|---|---|
| ||
$ virt-customize -a CentOS-8-aarch64-1905-dvd1.qcow2 --root-password password:zynqmp |
...
Code Block |
---|
$ qemu-img convert CentOS-8-aarch64-1905-dvd1.qcow2 CentOS-8-aarch64-1905-dvd1.raw |
Now lets examine the partitions in this disk image. You will see there are 3 partitions. The first is the EFI System Partition (ESP) which is a FAT formatted partition. The second partition is an EXT4 Linux partition. The third partition is an LVM root filesystem.
Code Block |
---|
$ fdisk -l CentOS-8-aarch64-1905-dvd1.raw Disk CentOS-8-aarch64-1905-dvd1.raw: 7 GiB, 7516192768 bytes, 14680064 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: gpt Disk identifier: E51C2C48-87F2-419D-BA13-687E3930A160 Device Start End Sectors Size Type CentOS-8-aarch64-1905-dvd1.raw1 2048 1230847 1228800 600M EFI System CentOS-8-aarch64-1905-dvd1.raw2 1230848 3327999 2097152 1G Linux filesystem CentOS-8-aarch64-1905-dvd1.raw3 3328000 14678015 11350016 5.4G Linux LVM |
The first thing we note is that “Disklabel type” is set to “gpt”. However, Zynq UltraScale+ only support MBR partitioned disks, so we need to convert from GPT to MBR with “sgdisk”.
Code Block | ||
---|---|---|
| ||
$ sgdisk -m 1:2:3 CentOS-8-aarch64-1905-dvd1.raw
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)
GPT data structures destroyed! You may now partition the disk using fdisk or
other utilities. |
...
Code Block |
---|
$ sfdisk -A CentOS-8-aarch64-1905-dvd1.raw 1
The bootable flag on partition 1 is enabled now.
The partition table has been altered.
Syncing disks. |
...
Code Block |
---|
$ fdisk -l CentOS-8-aarch64-1905-dvd1.raw Disk CentOS-8-aarch64-1905-dvd1.raw: 7 GiB, 7516192768 bytes, 14680064 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x00000000 Device Boot Start End Sectors Size Id Type CentOS-8-aarch64-1905-dvd1.raw1 * 2048 1230847 1228800 600M ef EFI (FAT-12/16/32) CentOS-8-aarch64-1905-dvd1.raw2 1230848 3327999 2097152 1G 83 Linux CentOS-8-aarch64-1905-dvd1.raw3 3328000 14678015 11350016 5.4G 8e Linux LVM |
...
Code Block |
---|
$ cd $COS_BUILD/images
$ sudo kpartx -va CentOS-8-aarch64-1905-dvd1.raw
add map loop0p1 (253:12): 0 1228800 linear 7:4 2048
add map loop0p2 (253:13): 0 2097152 linear 7:4 1230848
add map loop0p3 (253:14): 0 11350016 linear 7:4 3328000
$ sudo mount /dev/mapper/loop0p1 efi
$ sudo mount /dev/mapper/loop0p2 boot |
The Zynq UltraScale+ boot ROM will search for boot“boot.bin bin” on the first partition. The boot ROM will load FSBL and PMU firmware. FSBL will in turn load the u-boot. U-boot acting as the UEFI firmware will search the current partition for the corresponding board DTB file and pass it to the EFI bootloader through the EFI configuration table. If it doesn’t find one, it will pass its own DTB to the EFI bootloader. However, this DTB may not be compatible with your kernel version, so I recommend using the DTB built with the kernel. So let's install the UEFI firmware (boot.bin) and ZCU102 DTB as shown below from the deploy directory.
...
Since we are not using UEFI secure boot, we want to boot GRUB directly. So we need to replace shim (bootaa64.efi) with GRUB (grubaa64.efi). Note that we need to maintain the naming convention bootaa64.efi. That is the name searched for by the UEFI firmware.
Code Block |
---|
$ sudo cp efi/EFI/centos/grubaa64.efi efi/EFI/BOOT/bootaa64.efi |
UEFI firmware will search for an image named bootaa64.efi which is why we needed to rename the EFI image.
Next lets install the bootstrap kernel and kernel RPM packages into the BOOT directory.
...
Code Block | ||
---|---|---|
| ||
$ sudo umount efi
$ sudo umount boot
$ sudo kpartx -d CentOS-8-aarch64-1905-dvd1.raw
loop deleted : /dev/loop0 |
Now the raw disk image is ready to write to the SD card. With the CD card plugged into your CentOS machine, note the device node of your card (/dev/sdX) and install the image as shown below.
...
You may use “dmesg” to find the device node corresponding to your SD card. | ||
Code Block | ||
---|---|---|
| ||
$ sudo dd if=CentOS-8-aarch64-1905-dvd1.raw of=/dev/sdX bs=4M iflag=fullblock oflag=direct status=progress; sync |
Info |
---|
You may use “dmesg” to find the device node corresponding to your SD card. |
Booting ZCU102
Open a terminal emulator of your choice on your host machine and connect to the serial port on the ZCU102. Insert the SD card on the ZCU102, make sure the dip switches are set to SD boot and power on the board. If everything goes well, you should see an FSBL banner, PMU firmware version and U-boot messages.
...