Boot Images
This section will cover image generation and boot flows with QEMU.
PetaLinux provides a simpler way to customize boot flow, however this section will cover lower-level tools available for more complex boot flows, should they be needed.
This section does not cover building the files used when creating the boot images. If they are not available, they can be built in a PetaLinux project.
Using SD for Boot
Creating the SD Image
We will create the SD image using dd
, mkfs
, and mcopy
.
mcopy
is a part of mtools
, and can be downloaded through your package manager (e.g. apt-get
) or from GNU.org.
dd if=/dev/zero of=qemu_sd.img bs=256M count=1 mkfs.vfat -F 32 qemu_sd.img mcopy -i qemu_sd.img BOOT.BIN ::/ mcopy -i qemu_sd.img Image ::/ mcopy -i qemu_sd.img system.dtb ::/
Booting the Image in QEMU
Booting the Image with Zynq UltraScale+ MPSoC
To boot with SD on Zynq UltraScale+ MPSoC, specify:-boot mode=3
-drive index=0
or
-boot mode=5
-drive index=1
For SD0 or SD1 respectively.
qemu-system-aarch64 -M microblaze-fdt \ -nographic \ -hw-dtb ${PROJ_DIR}/images/linux/zynqmp-qemu-multiarch-pmu.dtb \ -kernel ${PROJ_DIR}/images/linux/pmu_rom_qemu_sha3.elf \ -device loader,file=${PROJ_DIR}/images/linux/pmufw.elf \ -device loader,addr=0xfd1a0074,data=0x01011003,data-len=4 \ -device loader,addr=0xfd1a007c,data=0x01010f03,data-len=4 \ -machine-path /tmp/qemu-shm
qemu-system-aarch64 -M arm-generic-fdt \ -serial mon:stdio \ -m 4G \ -global xlnx,zynqmp-boot.cpu-num=0 \ -global xlnx,zynqmp-boot.use-pmufw=true \ -global xlnx,zynqmp-boot.load-pmufw-cfg=false \ -nographic \ -hw-dtb ${PROJ_DIR}/images/linux/zynqmp-qemu-arm.dtb \ -device loader,file=${PROJ_DIR}/images/linux/zynqmp_fsbl.elf,cpu-num=1 \ -drive file=qemu_sd.img,if=sd,format=raw,index=0 \ -net nic -net nic -net nic -net nic \ -boot mode=5 \ -machine-path /tmp/qemu-shm
Even though we put the FSBL in the SD image (as a part of BOOT.BIN), it needs to be passed through the command line as an ELF since QEMU does not have a boot ROM to load the FSBL.
Booting the Image with Versal Adaptive SoC
To boot with SD on Versal Adaptive SoC, specify:-boot mode=3
-drive index=0
or
-boot mode=5
-drive index=1
For SD0 or SD1 respectively.
qemu-system-aarch64 -M microblaze-fdt \ -nographic \ -serial mon:stdio \ -hw-dtb ${PROJ_DIR}/images/linux/versal-qemu-multiarch-pmc.dtb \ -device loader,file=${PROJ_DIR}/images/linux/pmc_cdo.bin,addr=0xf2000000 \ -device loader,file=${PROJ_DIR}/images/linux/plm.elf,cpu-num=1 \ -device loader,file=${PROJ_DIR}/images/linux/BOOT_bh.bin,addr=0xf201e000,force-raw \ -device loader,addr=0xf0000000,data=0xba020004,data-len=4 \ -device loader,addr=0xf0000004,data=0xb800fffc,data-len=4 \ -device loader,addr=0xf1110620,data=0x1,data-len=4 \ -device loader,addr=0xf1110624,data=0x0,data-len=4 \ -machine-path /tmp/qemu-shm
qemu-system-aarch64 -M arm-generic-fdt \ -m 8G \ -nographic \ -serial null \ -serial null \ -serial mon:stdio \ -hw-dtb ${PROJ_DIR}/images/linux/versal-qemu-ps.dtb \ -dtb ${PROJ_DIR}/images/linux/system.dtb \ -drive file=qemu_sd.img,if=sd,format=raw,index=1 \ -net nic -net nic \ -boot mode=5 \ -machine-path /tmp/qemu-shm
Even though we put the FSBL in the SD image (as a part of BOOT.BIN), it needs to be passed through the command line as an ELF since QEMU needs access to the boot ROM.
Using QSPI for Boot
This section will cover both single flash and dual parallel mode.
Use the one that is more suited to your needs.
The read and write addresses given in these examples depend on the sizes of your images and how your flash is partitioned.
In this example, Our flash is partitioned in the following way for Zynq UltraScale+ MPSoC:
Partition Start | Partition End | Partition Name |
---|---|---|
0x0 | 0x1e00000 | Boot |
0x1e00000 | 0x1e40000 | DTB |
0x1e40000 | 0x4240000 | Kernel |
and has only one partition on Versal Adaptive SoC:
Partition Start | Partition End | Partition Name |
---|---|---|
0x0 | 0x20000000 | Flash |
If you're not sure how your flash is partitioned, you can view the partitions in a few ways:
- On the Linux guest, run
cat /proc/mtd
- In a PetaLinux project, run
petalinux-config
and navigate toSubsystem AUTO Hardware Settings
→Flash Settings
, and change your partitions as desired.
After configuration the partitions, build your project withpetalinux-build
. - Unflatten your
system.dtb
file by doingdtc -I dtb -O dts system.dtb -o system.dts
and find the node forspi@ff0f0000
on Zynq UltraScale+ MPSoC, orspi@f1030000
on Versal ACAP. The flash will be a child node of the SPI node.
The partitions are defined in thereg
property in the format ofreg = <partition_start partition_size>;
. Modify them as you see fit.
Once done, reflatten the DTB by doingdtc -I dts -O dtb system.dts -o system.dtb
More information on modifying device trees can be found here.
Note that only methods 2 and 3 allow modification of the partitions.
QSPI Boot with Zynq UltraScale+ MPSoC
Creating the QSPI boot image
Single Flash Mode
dd if=/dev/zero of=qemu_qspi.bin bs=256M count=1 dd if=BOOT.BIN of=qemu_qspi.bin bs=1 seek=0 conv=notrunc dd if=system.dtb of=qemu_qspi.bin bs=1 seek=31457280 conv=notrunc # Seek offset is 0x1E00000 in hex dd if=Image of=qemu_qspi.bin bs=1 seek=31719424 conv=notrunc # Seek offset is 0x1E40000 in hex
Dual Parallel Mode
If using parallel mode, you must use the flash_strip_bw
utility.
Information and a download for flash_strip_bw
can be found