Skip to content

Commit a957fcb

Browse files
committed
docs: document FIT compressed and ramdisk paths for ZynqMP/Versal/PolarFire
PolarFire MPFS250, Versal VMK180, and ZynqMP "Booting PetaLinux" walkthroughs now describe both options for handing PetaLinux off through the FIT image: * Option A (default GZIP=1): set compression="gzip" in the .its, point data at Image.gz / linux.bin.gz, and let mkimage build the FIT directly. wolfBoot decompresses straight to the kernel load address at boot and verifies hash-1. * Option B (GZIP=0): keep the existing host-side gzip -cdvk / gunzip step and compression="none" in the .its. ZynqMP also gains a "FIT ramdisk (initramfs)" subsection covering RAMDISK=1, WOLFBOOT_LOAD_RAMDISK_ADDRESS, the commented-out opt-in block in zynqmp_sdcard.config, gzip ramdisk support, and a sample ITS layout with kernel + DTB + ramdisk subimages.
1 parent 491ce40 commit a957fcb

1 file changed

Lines changed: 173 additions & 1 deletion

File tree

docs/Targets.md

Lines changed: 173 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1259,6 +1259,44 @@ Build images are output to: `./tmp-glibc/deploy/images/mpfs-video-kit/`
12591259
12601260
#### Custom FIT image, signing and coping to SDCard
12611261
1262+
wolfBoot can either decompress a gzipped kernel at boot time (`GZIP=1`,
1263+
the default for `polarfire_mpfs250.config` and `polarfire_mpfs250_qspi.config`)
1264+
or accept a pre-decompressed kernel inside the FIT (`GZIP=0`). Pick one path.
1265+
1266+
##### Option A - Compressed FIT (`GZIP=1`, default)
1267+
1268+
Set `compression = "gzip"` and point `data` at the gzipped kernel directly
1269+
in `hal/mpfs250.its`:
1270+
1271+
```dts
1272+
images {
1273+
kernel-1 {
1274+
data = /incbin/("../yocto-dev-polarfire/build/tmp-glibc/work/mpfs_video_kit-oe-linux/linux-mchp/6.12.22+git/build/linux.bin.gz");
1275+
compression = "gzip";
1276+
load = <0x80200000>;
1277+
entry = <0x80200000>;
1278+
hash-1 { algo = "sha256"; };
1279+
...
1280+
};
1281+
};
1282+
```
1283+
1284+
Then build the FIT directly - no manual `gzip -cdvk` step:
1285+
1286+
```sh
1287+
sudo dd if=wolfboot.bin of=/dev/sdc1 bs=512 && sudo cmp wolfboot.bin /dev/sdc1
1288+
mkimage -f hal/mpfs250.its fitImage
1289+
```
1290+
1291+
At boot, wolfBoot decompresses the kernel into `0x80200000` directly out of
1292+
the FIT `data` blob and verifies the FIT `hash-1` SHA-256 against the
1293+
decompressed bytes (defense-in-depth on top of the outer wolfBoot signature).
1294+
1295+
##### Option B - Uncompressed FIT (`GZIP=0`)
1296+
1297+
Build wolfBoot with `GZIP=0` and pre-decompress the kernel on the host.
1298+
Keep `compression = "none"` in `hal/mpfs250.its`:
1299+
12621300
```sh
12631301
# Copy wolfBoot to "BIOS" partition
12641302
sudo dd if=wolfboot.bin of=/dev/sdc1 bs=512 && sudo cmp wolfboot.bin /dev/sdc1
@@ -3390,6 +3428,95 @@ Application running successfully!
33903428
Entering idle loop...
33913429
```
33923430

3431+
**Booting PetaLinux**
3432+
3433+
ZynqMP can chain into a PetaLinux kernel using the same FIT mechanism as
3434+
the Versal target. wolfBoot's FIT-using configs (`zynqmp.config` and
3435+
`zynqmp_sdcard.config`) default to `GZIP=1`, which lets you point the
3436+
FIT at a gzipped kernel (`Image.gz`) directly:
3437+
3438+
```dts
3439+
images {
3440+
kernel-1 {
3441+
data = /incbin/("Image.gz");
3442+
compression = "gzip";
3443+
load = <0x10000000>;
3444+
entry = <0x10000000>;
3445+
hash-1 { algo = "sha256"; };
3446+
};
3447+
};
3448+
```
3449+
3450+
`mkimage -f your-zynqmp.its fitImage` then produces a single signed FIT
3451+
that wolfBoot decompresses straight to the kernel load address at boot.
3452+
See the [Versal "Booting PetaLinux"](#versal-gen-1-vmk180) section for a
3453+
full walkthrough - the flow is identical apart from the load addresses
3454+
and the `bl31`/`fsbl` versus `bl31`/`plm` boot chain. Set `GZIP=0` in
3455+
`.config` if you want to keep using an uncompressed `Image` plus
3456+
`compression = "none"`.
3457+
3458+
**FIT ramdisk (initramfs)**
3459+
3460+
When PetaLinux is built with `INITRAMFS_IMAGE_BUNDLE = "0"` the rootfs cpio
3461+
ships as a separate `ramdisk` node in the FIT alongside the kernel and DTB.
3462+
wolfBoot can extract it, copy it to a configurable RAM address, and patch the
3463+
loaded DTB with `/chosen/linux,initrd-{start,end}` so the kernel finds it.
3464+
Enable this with `RAMDISK=1`:
3465+
3466+
```sh
3467+
cp config/examples/zynqmp_sdcard.config .config
3468+
# Uncomment the RAMDISK / WOLFBOOT_LOAD_RAMDISK_ADDRESS / LINUX_BOOTARGS
3469+
# block under "Optional: FIT-bundled initramfs" and comment out the
3470+
# LINUX_BOOTARGS_ROOT line above it.
3471+
make
3472+
```
3473+
3474+
Key options (in `config/examples/zynqmp_sdcard.config`):
3475+
- `RAMDISK=1` - enables FIT ramdisk extraction (`-DWOLFBOOT_FIT_RAMDISK`).
3476+
- `WOLFBOOT_LOAD_RAMDISK_ADDRESS=0x40000000` - destination address. Pick a
3477+
region clear of the kernel image (`~0x80000` + tens of MB) and clear of
3478+
FIT staging (`WOLFBOOT_LOAD_ADDRESS=0x10000000` + FIT size). The default
3479+
`0x40000000` leaves ~1 GB of headroom on a 4 GB ZCU102. Set to `0` to
3480+
honor the FIT's own `load = <...>` property verbatim instead.
3481+
- `LINUX_BOOTARGS` should drop `root=...` since the ramdisk is the rootfs.
3482+
3483+
Compressed (gzip) ramdisks are supported transparently when `GZIP=1` is set
3484+
(the same gzip path used for the kernel handles `compression = "gzip"` on
3485+
the ramdisk node). The outer wolfBoot signature already authenticates the
3486+
entire FIT, so the ramdisk inherits authentication without per-image
3487+
hashing - though if the FIT does include a `hash-1` subnode under the
3488+
ramdisk image, wolfBoot will verify it after decompression.
3489+
3490+
Example FIT layout:
3491+
3492+
```dts
3493+
images {
3494+
kernel-1 { ... };
3495+
fdt-1 { ... };
3496+
ramdisk-1 {
3497+
data = /incbin/("rootfs.cpio.gz");
3498+
type = "ramdisk";
3499+
compression = "gzip"; /* or "none" */
3500+
hash-1 { algo = "sha256"; };
3501+
};
3502+
};
3503+
configurations {
3504+
default = "conf-zcu102";
3505+
conf-zcu102 {
3506+
kernel = "kernel-1";
3507+
fdt = "fdt-1";
3508+
ramdisk = "ramdisk-1";
3509+
};
3510+
};
3511+
```
3512+
3513+
Successful boot prints:
3514+
```
3515+
Loading ramdisk: 0x... -> 0x40000000 (N bytes)
3516+
FDT: Set chosen (...), linux,initrd-start=1073741824
3517+
FDT: Set chosen (...), linux,initrd-end=...
3518+
```
3519+
33933520

33943521
## Versal Gen 1 VMK180
33953522

@@ -3552,6 +3679,7 @@ Prerequisites:
35523679
1. **PetaLinux 2024.2** (or compatible version) built for VMK180
35533680
2. **Pre-built Linux images** from your PetaLinux build:
35543681
- `Image` - Uncompressed Linux kernel (ARM64)
3682+
- `Image.gz` - gzip-compressed kernel (used with `GZIP=1`, see below)
35553683
- `system-default.dtb` - Device tree blob for VMK180
35563684
3. **SD card** with root filesystem (PetaLinux rootfs.ext4 written to partition 2)
35573685

@@ -3560,7 +3688,51 @@ wolfBoot uses a FIT (Flattened Image Tree) image containing the kernel and devic
35603688
- DTB load address: `0x00001000`
35613689
- SHA256 hashes for integrity
35623690

3563-
Create and sign the FIT image, then flash to QSPI:
3691+
`config/examples/versal_vmk180.config` and `config/examples/versal_vmk180_sdcard.config`
3692+
default to `GZIP=1`, so wolfBoot can decompress a gzipped kernel at boot
3693+
time. Pick one of the two flows below.
3694+
3695+
##### Option A - Compressed kernel (`GZIP=1`, default)
3696+
3697+
Edit `hal/versal.its` to point the kernel `data` at the gzipped kernel
3698+
and set `compression = "gzip"`:
3699+
3700+
```dts
3701+
images {
3702+
kernel-1 {
3703+
data = /incbin/("Image.gz");
3704+
compression = "gzip";
3705+
load = <0x00200000>;
3706+
entry = <0x00200000>;
3707+
hash-1 { algo = "sha256"; };
3708+
...
3709+
};
3710+
};
3711+
```
3712+
3713+
Then build and flash the FIT directly - no manual `gunzip` step:
3714+
3715+
```sh
3716+
cp /path/to/petalinux/images/linux/Image.gz .
3717+
cp /path/to/petalinux/images/linux/system-default.dtb .
3718+
mkimage -f hal/versal.its fitImage
3719+
./tools/keytools/sign --ecc384 --sha384 fitImage wolfboot_signing_private_key.der 1
3720+
3721+
tftp ${loadaddr} fitImage_v1_signed.bin
3722+
sf probe 0
3723+
sf erase 0x800000 +${filesize}
3724+
sf write ${loadaddr} 0x800000 ${filesize}
3725+
```
3726+
3727+
The compressed FIT is roughly half the size of the uncompressed equivalent
3728+
on a typical PetaLinux ARM64 kernel, which lets a larger kernel fit in the
3729+
existing 44 MB QSPI partition. wolfBoot decompresses to `0x00200000` at boot
3730+
and verifies the FIT `hash-1` SHA-256 against the decompressed bytes.
3731+
3732+
##### Option B - Uncompressed kernel (`GZIP=0`)
3733+
3734+
Build wolfBoot with `GZIP=0` and use the uncompressed `Image` directly.
3735+
Keep `compression = "none"` in `hal/versal.its`:
35643736

35653737
```sh
35663738
cp /path/to/petalinux/images/linux/Image .

0 commit comments

Comments
 (0)