Skip to content

Commit ba618c0

Browse files
committed
Documentation and fixes for booting full PetaLinux with wolfBoot on Versal VMK180
1 parent 3ec98ec commit ba618c0

File tree

4 files changed

+509
-486
lines changed

4 files changed

+509
-486
lines changed

docs/Targets.md

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,6 +2037,154 @@ Application running successfully!
20372037
Entering idle loop...
20382038
```
20392039

2040+
### Booting PetaLinux
2041+
2042+
wolfBoot can boot a signed Linux kernel on the Versal VMK180. This replaces U-Boot entirely for a secure boot chain.
2043+
2044+
#### Prerequisites
2045+
2046+
1. **PetaLinux 2024.2** (or compatible version) built for VMK180
2047+
2. **Pre-built Linux images** from your PetaLinux build:
2048+
- `Image` - Uncompressed Linux kernel (ARM64)
2049+
- `system-default.dtb` - Device tree blob for VMK180
2050+
- `bl31.elf` - ARM Trusted Firmware
2051+
- `plm.elf` - Platform Loader & Manager
2052+
- `psmfw.elf` - PSM firmware
2053+
2054+
3. **SD card** with root filesystem (PetaLinux rootfs.ext4 written to partition 2)
2055+
2056+
#### Boot Flow
2057+
2058+
```
2059+
PLM -> PSM -> BL31 (EL3) -> wolfBoot (EL2) -> Linux (EL1)
2060+
```
2061+
2062+
wolfBoot:
2063+
1. Loads the signed FIT image from QSPI flash
2064+
2. Verifies the cryptographic signature (ECC384/SHA384)
2065+
3. Parses the FIT image to extract kernel and DTB
2066+
4. Applies DTB fixups (bootargs for root filesystem)
2067+
5. Transitions from EL2 to EL1 and jumps to the kernel
2068+
2069+
#### Creating the FIT Image
2070+
2071+
wolfBoot uses a FIT (Flattened Image Tree) image containing the kernel and device tree. Create the FIT image using the provided ITS file:
2072+
2073+
```sh
2074+
# Copy Linux images to wolfBoot root directory
2075+
cp /path/to/petalinux/images/linux/Image .
2076+
cp /path/to/petalinux/images/linux/system-default.dtb .
2077+
2078+
# Create FIT image using mkimage
2079+
mkimage -f hal/versal.its fitImage
2080+
```
2081+
2082+
The ITS file (`hal/versal.its`) specifies:
2083+
- Kernel load address: `0x00200000`
2084+
- DTB load address: `0x00001000`
2085+
- SHA256 hashes for integrity
2086+
2087+
#### Signing the FIT Image
2088+
2089+
Sign the FIT image with wolfBoot tools:
2090+
2091+
```sh
2092+
# Sign with ECC384 (default for Versal config)
2093+
./tools/keytools/sign --ecc384 --sha384 fitImage wolfboot_signing_private_key.der 1
2094+
```
2095+
2096+
This creates `fitImage_v1_signed.bin`.
2097+
2098+
#### DTB Fixup for Root Filesystem
2099+
2100+
wolfBoot automatically modifies the device tree to set the kernel command line (`bootargs`). The default configuration mounts the root filesystem from SD card partition 2:
2101+
2102+
```
2103+
earlycon root=/dev/mmcblk0p2 rootwait
2104+
```
2105+
2106+
To customize the root device, add to your config:
2107+
2108+
```makefile
2109+
# Mount root from SD card partition 4
2110+
CFLAGS_EXTRA+=-DLINUX_BOOTARGS_ROOT=\"/dev/mmcblk0p4\"
2111+
```
2112+
2113+
#### Flashing to QSPI
2114+
2115+
Flash the signed FIT image to the boot partition at `0x800000`:
2116+
2117+
```sh
2118+
# From U-Boot (via SD card boot)
2119+
tftp ${loadaddr} fitImage_v1_signed.bin
2120+
sf probe 0
2121+
sf erase 0x800000 +${filesize}
2122+
sf write ${loadaddr} 0x800000 ${filesize}
2123+
```
2124+
2125+
#### Automated Testing
2126+
2127+
The test script supports Linux boot testing:
2128+
2129+
```sh
2130+
# Set path to PetaLinux images
2131+
export LINUX_IMAGES_DIR=/path/to/petalinux/images/linux
2132+
2133+
# Build wolfBoot, create signed FIT, flash to QSPI, and boot
2134+
./tools/scripts/versal_test.sh --linux
2135+
```
2136+
2137+
#### Example Linux Boot Output
2138+
2139+
```
2140+
========================================
2141+
wolfBoot Secure Boot - AMD Versal
2142+
========================================
2143+
Current EL: 2
2144+
QSPI: Lower ID: 20 BB 21
2145+
QSPI: Upper ID: 20 BB 21
2146+
QSPI: 75MHz, Quad mode, DMA
2147+
Versions: Boot 1, Update 0
2148+
Trying Boot partition at 0x800000
2149+
Loading header 512 bytes from 0x800000 to 0xFFFFE00
2150+
Loading image 24658696 bytes from 0x800200 to 0x10000000...done (701 ms)
2151+
Boot partition: 0xFFFFE00 (sz 24658696, ver 0x1, type 0x601)
2152+
Checking integrity...done (167 ms)
2153+
Verifying signature...done (3 ms)
2154+
Successfully selected image in part: 0
2155+
Firmware Valid
2156+
Loading elf at 0x10000000
2157+
Invalid elf, falling back to raw binary
2158+
Flattened uImage Tree: Version 17, Size 24658696
2159+
Loading Image kernel-1: 0x100000D8 -> 0x200000 (24617472 bytes)
2160+
Image kernel-1: 0x200000 (24617472 bytes)
2161+
Loading Image fdt-1: 0x1177A3DC -> 0x1000 (39384 bytes)
2162+
Image fdt-1: 0x1000 (39384 bytes)
2163+
Loading DTS: 0x1000 -> 0x1000 (39384 bytes)
2164+
FDT: Version 17, Size 39384
2165+
FDT: Setting bootargs: earlycon root=/dev/mmcblk0p2 rootwait
2166+
FDT: Set chosen (28076), bootargs=earlycon root=/dev/mmcblk0p2 rootwait
2167+
Booting at 0x200000
2168+
[ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd083]
2169+
[ 0.000000] Linux version 6.6.40-xilinx-g2b7f6f70a62a ...
2170+
[ 0.000000] Machine model: Xilinx Versal vmk180 Eval board revA
2171+
...
2172+
PetaLinux 2024.2 xilinx-vmk180 ttyAMA0
2173+
2174+
xilinx-vmk180 login:
2175+
```
2176+
2177+
#### Boot Performance
2178+
2179+
Typical boot timing with ECC384/SHA384 signing:
2180+
2181+
| Operation | Time |
2182+
|-----------|------|
2183+
| Load 24MB FIT from QSPI | ~700ms |
2184+
| SHA384 integrity check | ~167ms |
2185+
| ECC384 signature verify | ~3ms |
2186+
| **Total wolfBoot overhead** | **~870ms** |
2187+
20402188

20412189
## Cypress PSoC-6
20422190

hal/versal.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,29 @@
5050
#include "hal/versal.h"
5151
#include "image.h"
5252
#include "printf.h"
53+
#include "fdt.h"
5354

5455
#ifndef ARCH_AARCH64
5556
# error "wolfBoot versal HAL: wrong architecture. Please compile with ARCH=AARCH64."
5657
#endif
5758

59+
/* ============================================================================
60+
* Linux Boot Arguments
61+
* ============================================================================
62+
* DTB fixup for kernel command line. Override LINUX_BOOTARGS or
63+
* LINUX_BOOTARGS_ROOT in your config to customize.
64+
*/
65+
66+
/* Linux kernel command line arguments */
67+
#ifndef LINUX_BOOTARGS
68+
#ifndef LINUX_BOOTARGS_ROOT
69+
#define LINUX_BOOTARGS_ROOT "/dev/mmcblk0p2"
70+
#endif
71+
72+
#define LINUX_BOOTARGS \
73+
"earlycon root=" LINUX_BOOTARGS_ROOT " rootwait"
74+
#endif
75+
5876

5977
/* ============================================================================
6078
* UART Driver
@@ -1297,6 +1315,54 @@ void* hal_get_dts_update_address(void)
12971315
return NULL;
12981316
#endif
12991317
}
1318+
1319+
#ifdef __WOLFBOOT
1320+
/**
1321+
* Fixup Device Tree before booting Linux
1322+
*
1323+
* This function modifies the DTB to set bootargs for the kernel.
1324+
* Called from do_boot() before jumping to the kernel.
1325+
*
1326+
* @param dts_addr: Pointer to the device tree blob in memory
1327+
* @return: 0 on success, negative error code on failure
1328+
*/
1329+
int hal_dts_fixup(void* dts_addr)
1330+
{
1331+
int off, ret;
1332+
struct fdt_header *fdt = (struct fdt_header *)dts_addr;
1333+
1334+
/* Verify FDT header */
1335+
ret = fdt_check_header(dts_addr);
1336+
if (ret != 0) {
1337+
wolfBoot_printf("FDT: Invalid header! %d\n", ret);
1338+
return ret;
1339+
}
1340+
1341+
wolfBoot_printf("FDT: Version %d, Size %d\n",
1342+
fdt_version(fdt), fdt_totalsize(fdt));
1343+
1344+
/* Expand total size to allow adding/modifying properties */
1345+
fdt_set_totalsize(fdt, fdt_totalsize(fdt) + 512);
1346+
1347+
/* Find /chosen node */
1348+
off = fdt_find_node_offset(fdt, -1, "chosen");
1349+
if (off < 0) {
1350+
/* Create /chosen node if it doesn't exist */
1351+
off = fdt_add_subnode(fdt, 0, "chosen");
1352+
}
1353+
1354+
if (off >= 0) {
1355+
/* Set bootargs property */
1356+
wolfBoot_printf("FDT: Setting bootargs: %s\n", LINUX_BOOTARGS);
1357+
fdt_fixup_str(fdt, off, "chosen", "bootargs", LINUX_BOOTARGS);
1358+
} else {
1359+
wolfBoot_printf("FDT: Failed to find/create chosen node (%d)\n", off);
1360+
return off;
1361+
}
1362+
1363+
return 0;
1364+
}
1365+
#endif /* __WOLFBOOT */
13001366
#endif /* MMU */
13011367

13021368
#ifdef WOLFBOOT_DUALBOOT

hal/versal.its

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/dts-v1/;
2+
3+
/ {
4+
description = "Xilinx Versal VMK180 - wolfBoot Linux";
5+
#address-cells = <1>;
6+
7+
images {
8+
kernel-1 {
9+
description = "Linux Kernel";
10+
data = /incbin/("../Image");
11+
type = "kernel";
12+
arch = "arm64";
13+
os = "linux";
14+
compression = "none";
15+
load = <0x00200000>;
16+
entry = <0x00200000>;
17+
hash-1 {
18+
algo = "sha256";
19+
};
20+
};
21+
fdt-1 {
22+
description = "Flattened Device Tree blob";
23+
data = /incbin/("../system-default.dtb");
24+
type = "flat_dt";
25+
arch = "arm64";
26+
compression = "none";
27+
load = <0x00001000>;
28+
hash-1 {
29+
algo = "sha256";
30+
};
31+
};
32+
};
33+
configurations {
34+
default = "conf1";
35+
conf1 {
36+
description = "Linux kernel and FDT blob";
37+
kernel = "kernel-1";
38+
fdt = "fdt-1";
39+
hash-1 {
40+
algo = "sha256";
41+
};
42+
};
43+
};
44+
};

0 commit comments

Comments
 (0)