Skip to content

Commit 21dbad1

Browse files
committed
Finished support for Flattened uImage Tree (FIT) image (FDT format).
1 parent 5e9a28f commit 21dbad1

File tree

7 files changed

+240
-102
lines changed

7 files changed

+240
-102
lines changed

IDE/XilinxSDK/README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,24 @@ WOLFBOOT_ORIGIN=0x0
7171
WOLFBOOT_SHA_BLOCK_SIZE=4096
7272
WOLFBOOT_SIGN_RSA4096
7373
WOLFBOOT_UBOOT_LEGACY
74+
```
75+
76+
Note: If not using Position Independent Code (PIC) the linker script `ldscript.ld` must have the start address offset to match the `WOLFBOOT_LOAD_ADDRESS`.
77+
78+
79+
## Zynq UltraScale+ ARMv8 Crypto Extensions
80+
81+
To enable ARM assembly speedups for SHA:
82+
83+
1) Add these build symbols:
84+
85+
```
7486
WOLFSSL_ARMASM
7587
WOLFSSL_ARMASM_INLINE
7688
```
7789

78-
Note: If not using Position Independent Code (PIC) the linker script `ldscript.ld` must have the start address offset to match the `WOLFBOOT_LOAD_ADDRESS`.
90+
2) Add these compiler misc flags: `-mcpu=generic+crypto -mstrict-align -DWOLFSSL_AARCH64_NO_SQRMLSH`
91+
7992

8093
## Generate signing key
8194

@@ -339,3 +352,4 @@ Output image(s) successfully created.
339352
### References:
340353
* [ZAPP1319](https://www.xilinx.com/support/documentation/application_notes/xapp1319-zynq-usp-prog-nvm.pdf): Programming BBRAM and eFUSEs
341354
* [UG1283](https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_2/ug1283-bootgen-user-guide.pdf): Bootgen User Guide
355+
* [Using Cryptography in Zynq UltraScale MPSoC](https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842541/Using+Cryptography+in+Zynq+UltraScale+MPSoC)

hal/zynq.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ static int qspi_flash_read_id(QspiDev_t* dev, uint8_t* id, uint32_t idSz)
532532
{
533533
int ret;
534534
uint8_t cmd[20]; /* size multiple of uint32_t */
535-
uint8_t status;
535+
uint8_t status = 0;
536536

537537
memset(cmd, 0, sizeof(cmd));
538538
cmd[0] = MULTI_IO_READ_ID_CMD;
@@ -562,7 +562,7 @@ static int qspi_write_enable(QspiDev_t* dev)
562562
{
563563
int ret;
564564
uint8_t cmd[4]; /* size multiple of uint32_t */
565-
uint8_t status;
565+
uint8_t status = 0;
566566

567567
memset(cmd, 0, sizeof(cmd));
568568
cmd[0] = WRITE_ENABLE_CMD;

include/fdt.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,9 @@ const char* fdt_get_string(const void *fdt, int stroffset, int *lenp);
139139
const void *fdt_getprop(const void *fdt, int nodeoffset, const char *name, int *lenp);
140140
int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val, int len);
141141

142-
int fdt_find_node_offset(void* fdt, int startoff, const char* node);
142+
void* fdt_getprop_address(const void *fdt, int nodeoffset, const char *name);
143+
144+
int fdt_find_node_offset(void* fdt, int startoff, const char* nodename);
143145
int fdt_find_prop_offset(void* fdt, int startoff, const char* propname, const char* propval);
144146

145147
int fdt_find_devtype(void* fdt, int startoff, const char* node);
@@ -155,6 +157,10 @@ int fdt_fixup_val64(void* fdt, int off, const char* node, const char* name, uint
155157

156158
int fdt_shrink(void* fdt);
157159

160+
/* FIT */
161+
const char* fit_find_images(void* fdt, const char** pkernel, const char** pflat_dt);
162+
void* fit_load_image(void* fdt, const char* image, int* lenp);
163+
158164
#ifdef __cplusplus
159165
}
160166
#endif

src/fdt.c

Lines changed: 118 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -502,15 +502,15 @@ const char* fdt_get_name(const void *fdt, int nodeoffset, int *len)
502502
{
503503
int err;
504504
const struct fdt_node_header *nh = fdt_offset_ptr_(fdt, nodeoffset);
505-
int namelen = 0;
505+
size_t namelen = 0;
506506
const char* name = NULL;
507507

508508
err = fdt_check_header(fdt);
509509
if (err == 0) {
510510
err = fdt_check_node_offset_(fdt, nodeoffset);
511511
if (err >= 0) {
512512
name = nh->name;
513-
namelen = strlen(nh->name);
513+
namelen = (int)strlen(nh->name);
514514
}
515515
}
516516
if (err < 0)
@@ -524,7 +524,7 @@ const char* fdt_get_string(const void *fdt, int stroffset, int *lenp)
524524
{
525525
const char *s = (const char*)fdt + fdt_off_dt_strings(fdt) + stroffset;
526526
if (lenp) {
527-
*lenp = strlen(s);
527+
*lenp = (int)strlen(s);
528528
}
529529
return s;
530530
}
@@ -560,7 +560,7 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val,
560560
return err;
561561
}
562562

563-
const void *fdt_getprop(const void *fdt, int nodeoffset, const char *name,
563+
const void* fdt_getprop(const void *fdt, int nodeoffset, const char *name,
564564
int *lenp)
565565
{
566566
int poffset;
@@ -577,19 +577,39 @@ const void *fdt_getprop(const void *fdt, int nodeoffset, const char *name,
577577
return NULL;
578578
}
579579

580-
int fdt_find_node_offset(void* fdt, int startoff, const char* node)
580+
void* fdt_getprop_address(const void *fdt, int nodeoffset, const char *name)
581581
{
582-
int off;
583-
int nodelen = strlen(node);
584-
int nlen;
582+
void* ret = NULL;
583+
int len = 0;
584+
void* val = (void*)fdt_getprop(fdt, nodeoffset, name, &len);
585+
if (val != NULL && len > 0) {
586+
if (len == 8) {
587+
uint64_t* val64 = (uint64_t*)val;
588+
ret = (void*)((uintptr_t)fdt64_to_cpu(*val64));
589+
}
590+
else if (len == 4) {
591+
uint32_t* val32 = (uint32_t*)val;
592+
ret = (void*)((uintptr_t)fdt32_to_cpu(*val32));
593+
}
594+
}
595+
return ret;
596+
}
597+
598+
int fdt_find_node_offset(void* fdt, int startoff, const char* nodename)
599+
{
600+
int off, nlen, fnlen;
585601
const char* nstr = NULL;
586602

603+
if (nodename == NULL)
604+
return -1;
605+
606+
fnlen = (int)strlen(nodename);
587607
for (off = fdt_next_node(fdt, startoff, NULL);
588608
off >= 0;
589609
off = fdt_next_node(fdt, off, NULL))
590610
{
591611
nstr = fdt_get_name(fdt, off, &nlen);
592-
if ((nlen == nodelen) && (memcmp(nstr, node, nodelen) == 0)) {
612+
if ((nlen == fnlen) && (memcmp(nstr, nodename, fnlen) == 0)) {
593613
break;
594614
}
595615
}
@@ -599,16 +619,19 @@ int fdt_find_node_offset(void* fdt, int startoff, const char* node)
599619
int fdt_find_prop_offset(void* fdt, int startoff, const char* propname,
600620
const char* propval)
601621
{
602-
int len, off;
622+
int len, off, pvallen;
603623
const void* val;
604-
int nodelen = strlen(propval)+1;
605624

625+
if (propname == NULL || propval == NULL)
626+
return -1;
627+
628+
pvallen = (int)strlen(propval)+1;
606629
for (off = fdt_next_node(fdt, startoff, NULL);
607630
off >= 0;
608631
off = fdt_next_node(fdt, off, NULL))
609632
{
610633
val = fdt_getprop(fdt, off, propname, &len);
611-
if (val && (len == nodelen) && (memcmp(val, propval, len) == 0)) {
634+
if (val && (len == pvallen) && (memcmp(val, propval, len) == 0)) {
612635
break;
613636
}
614637
}
@@ -745,4 +768,87 @@ int fdt_fixup_val64(void* fdt, int off, const char* node, const char* name,
745768
return fdt_setprop(fdt, off, name, &val, sizeof(val));
746769
}
747770

771+
772+
/* FIT Specific */
773+
const char* fit_find_images(void* fdt, const char** pkernel, const char** pflat_dt)
774+
{
775+
const void* val;
776+
const char *conf = NULL, *kernel = NULL, *flat_dt = NULL;
777+
int off, len = 0;
778+
779+
/* Find the default configuration (optional) */
780+
off = fdt_find_node_offset(fdt, -1, "configurations");
781+
if (off > 0) {
782+
val = fdt_getprop(fdt, off, "default", &len);
783+
if (val != NULL && len > 0) {
784+
conf = (const char*)val;
785+
}
786+
}
787+
if (conf != NULL) {
788+
off = fdt_find_node_offset(fdt, -1, conf);
789+
if (off > 0) {
790+
kernel = fdt_getprop(fdt, off, "kernel", &len);
791+
flat_dt = fdt_getprop(fdt, off, "fdt", &len);
792+
}
793+
}
794+
if (kernel == NULL) {
795+
/* find node with "type" == kernel */
796+
off = fdt_find_prop_offset(fdt, -1, "type", "kernel");
797+
if (off > 0) {
798+
val = fdt_get_name(fdt, off, &len);
799+
if (val != NULL && len > 0) {
800+
kernel = (const char*)val;
801+
}
802+
}
803+
}
804+
if (flat_dt == NULL) {
805+
/* find node with "type" == flat_dt */
806+
off = fdt_find_prop_offset(fdt, -1, "type", "flat_dt");
807+
if (off > 0) {
808+
val = fdt_get_name(fdt, off, &len);
809+
if (val != NULL && len > 0) {
810+
flat_dt = (const char*)val;
811+
}
812+
}
813+
}
814+
815+
if (pkernel)
816+
*pkernel = kernel;
817+
if (pflat_dt)
818+
*pflat_dt = flat_dt;
819+
820+
return conf;
821+
}
822+
823+
void* fit_load_image(void* fdt, const char* image, int* lenp)
824+
{
825+
void *load, *entry, *data = NULL;
826+
int off, len = 0;
827+
828+
off = fdt_find_node_offset(fdt, -1, image);
829+
if (off > 0) {
830+
/* get load and entry */
831+
data = (void*)fdt_getprop(fdt, off, "data", &len);
832+
load = fdt_getprop_address(fdt, off, "load");
833+
entry = fdt_getprop_address(fdt, off, "entry");
834+
if (data != NULL && load != NULL && data != load) {
835+
wolfBoot_printf("Loading Image %s: %p -> %p (%d bytes)\n",
836+
image, data, load, len);
837+
memcpy(load, data, len);
838+
839+
/* load should always have entry, but if not use load adress */
840+
data = (entry != NULL) ? entry : load;
841+
}
842+
wolfBoot_printf("Image %s: %p (%d bytes)\n", image, data, len);
843+
}
844+
else {
845+
wolfBoot_printf("Image %s: Not found!\n", image);
846+
}
847+
if (lenp != NULL) {
848+
*lenp = len;
849+
}
850+
return data;
851+
852+
}
853+
748854
#endif /* MMU && !BUILD_LOADER_STAGE1 */

src/update_ram.c

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -290,36 +290,62 @@ void RAMFUNCTION wolfBoot_start(void)
290290
#endif
291291

292292
#ifdef MMU
293+
/* Is this a Flattened uImage Tree (FIT) image (FDT format) */
294+
if (wolfBoot_get_dts_size(load_address) > 0) {
295+
void* fit = (void*)load_address;
296+
const char *kernel = NULL, *flat_dt = NULL;
297+
298+
wolfBoot_printf("Flattened uImage Tree: Version %d, Size %d\n",
299+
fdt_version(fit), fdt_totalsize(fit));
300+
301+
(void)fit_find_images(fit, &kernel, &flat_dt);
302+
if (kernel != NULL) {
303+
load_address = fit_load_image(fit, kernel, NULL);
304+
}
305+
if (flat_dt != NULL) {
306+
dts_addr = fit_load_image(fit, flat_dt, NULL);
307+
if (dts_addr != NULL) {
308+
/* check DTS */
309+
ret = wolfBoot_get_dts_size(dts_addr);
310+
if (ret < 0) {
311+
wolfBoot_printf("FIT FDT parsing failed!\n");
312+
/* Allow failure, continue booting */
313+
}
314+
}
315+
}
316+
}
317+
else {
293318
/* Load DTS to RAM */
294319
#ifdef EXT_FLASH
295-
if (PART_IS_EXT(&os_image) &&
296-
wolfBoot_open_image(&os_image, PART_DTS_BOOT) >= 0) {
297-
dts_addr = (uint8_t*)WOLFBOOT_LOAD_DTS_ADDRESS;
298-
dts_size = (uint32_t)os_image.fw_size;
299-
300-
wolfBoot_printf("Loading DTS (size %lu) to RAM at %08lx\n",
301-
dts_size, dts_addr);
302-
ext_flash_check_read((uintptr_t)os_image.fw_base,
303-
(uint8_t*)dts_addr, dts_size);
304-
}
305-
else
320+
if (PART_IS_EXT(&os_image) &&
321+
wolfBoot_open_image(&os_image, PART_DTS_BOOT) >= 0) {
322+
dts_addr = (uint8_t*)WOLFBOOT_LOAD_DTS_ADDRESS;
323+
dts_size = (uint32_t)os_image.fw_size;
324+
325+
wolfBoot_printf("Loading DTS (size %lu) to RAM at %08lx\n",
326+
dts_size, dts_addr);
327+
ext_flash_check_read((uintptr_t)os_image.fw_base,
328+
(uint8_t*)dts_addr, dts_size);
329+
}
330+
else
306331
#endif /* EXT_FLASH */
307-
{
308-
dts_addr = hal_get_dts_address();
309-
if (dts_addr) {
310-
ret = wolfBoot_get_dts_size(dts_addr);
311-
if (ret < 0) {
312-
wolfBoot_printf("Failed parsing DTB to load\n");
313-
/* Allow failure, continue booting */
314-
}
315-
else {
316-
/* relocate DTS to RAM */
317-
uint8_t* dts_dst = (uint8_t*)WOLFBOOT_LOAD_DTS_ADDRESS;
318-
dts_size = (uint32_t)ret;
319-
wolfBoot_printf("Loading DTB (size %d) from %p to RAM at %p\n",
332+
{
333+
dts_addr = hal_get_dts_address();
334+
if (dts_addr) {
335+
ret = wolfBoot_get_dts_size(dts_addr);
336+
if (ret < 0) {
337+
wolfBoot_printf("Failed parsing DTB to load\n");
338+
/* Allow failure, continue booting */
339+
}
340+
else {
341+
/* relocate DTS to RAM */
342+
uint8_t* dts_dst = (uint8_t*)WOLFBOOT_LOAD_DTS_ADDRESS;
343+
dts_size = (uint32_t)ret;
344+
wolfBoot_printf("Loading DTB (size %d) from %p to RAM at %p\n",
320345
dts_size, dts_addr, WOLFBOOT_LOAD_DTS_ADDRESS);
321-
memcpy(dts_dst, dts_addr, dts_size);
322-
dts_addr = dts_dst;
346+
memcpy(dts_dst, dts_addr, dts_size);
347+
dts_addr = dts_dst;
348+
}
323349
}
324350
}
325351
}

tools/fdt-parser/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,26 @@ root (node offset 0, depth 1, len 0):
3636
## Example FIT Output
3737

3838
```sh
39+
% ./tools/fdt-parser/fdt-parser -i ./tools/fdt-parser/lynx-test-arm.srp
40+
FDT Parser (./tools/fdt-parser/lynx-test-arm.srp):
41+
FDT Version 17, Size 164232633
42+
FIT: Found 'conf@1' configuration
43+
description (len 46): LynxSecure 2024.06.0-96ce6f31a0 SRP (aarch64)
44+
Kernel Image: kernel@1
45+
description (len 46): LynxSecure 2024.06.0-96ce6f31a0 SRP (aarch64)
46+
type (len 7): kernel
47+
os (len 6): linux
48+
arch (len 6): arm64
49+
compression (len 5): none
50+
load (len 4):
51+
entry (len 4):
52+
data (len 164186944): not rendering
53+
FDT Image: fdt@1
54+
description (len 77): Flattened Device Tree blob for LynxSecure 2024.06.0-96ce6f31a0 SRP (aarch64)
55+
type (len 8): flat_dt
56+
arch (len 6): arm64
57+
compression (len 5): none
58+
padding (len 8):
59+
data (len 44770): not rendering
60+
Return 0
3961
```

0 commit comments

Comments
 (0)