Skip to contentSkip to conversation

spl: net: Add FIT image support over network boot

PATCH Superseded Andrew F. Davis 2 participants 3 messages Apr 7, 2017

v3 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

PATCH v3 1/1 spl: net: Add FIT image support over network boot

FIT support in the net boot case is much like the RAM boot case in that we load our image to "load_addr" and pass a dummy read function into "spl_load_simple_fit()". As the load address is no longer hard-coded to the final execution address, RAW image loading will rely on "load_addr" pointing to the execution address as they should have before.

---

Changes from v2:
- Rebased on latest upstream/master

Changes from v1:
- move "spl_net_load_read" into #ifdef block as suggested by Vignesh

 common/spl/spl_net.c | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)
common/spl/spl_net.c +27 -3
index 0fba0172ea..3d1d05d833 100644
@@ -11,19 +11,29 @@
 #include <errno.h>
 #include <spl.h>
 #include <net.h>
+#include <libfdt.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
 #if defined(CONFIG_SPL_ETH_SUPPORT) || defined(CONFIG_SPL_USBETH_SUPPORT)
+static ulong spl_net_load_read(struct spl_load_info *load, ulong sector,
+			       ulong count, void *buf)
+{
+	debug("%s: sector %lx, count %lx, buf %lx\n",
+	      __func__, sector, count, (ulong)buf);
+	memcpy(buf, (void *)(load_addr + sector), count);
+	return count;
+}
+
 static int spl_net_load_image(struct spl_image_info *spl_image,
 			      struct spl_boot_device *bootdev)
 {
+	struct image_header *header = (struct image_header *)load_addr;
 	int rv;
 
 	env_init();
 	env_relocate();
 	setenv("autoload", "yes");
-	load_addr = CONFIG_SYS_TEXT_BASE - sizeof(struct image_header);
 	rv = eth_initialize();
 	if (rv == 0) {
 		printf("No Ethernet devices found\n");
@@ -36,8 +46,22 @@ static int spl_net_load_image(struct spl_image_info *spl_image,
 		printf("Problem booting with BOOTP\n");
 		return rv;
 	}
-	return spl_parse_image_header(spl_image,
-				      (struct image_header *)load_addr);
+
+	if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
+	    image_get_magic(header) == FDT_MAGIC) {
+		struct spl_load_info load;
+
+		debug("Found FIT\n");
+		load.bl_len = 1;
+		load.read = spl_net_load_read;
+		rv = spl_load_simple_fit(spl_image, &load, 0, header);
+	} else {
+		debug("Legacy image\n");
+
+		rv = spl_parse_image_header(spl_image, header);
+	}
+
+	return rv;
 }
 #endif
 
Signature · 1 line
2.11.0
#1 lore raw

PATCH v3 1/1 spl: net: Add FIT image support over network boot

Quoted 6 lines · Andrew

FIT support in the net boot case is much like the RAM boot case in that we load our image to "load_addr" and pass a dummy read function into "spl_load_simple_fit()". As the load address is no longer hard-coded to the final execution address, RAW image loading will rely on "load_addr" pointing to the execution address as they should have before.

Sorry, but would you explain how network boot would work in case of non FIT image(same concern I had wrt v2)?

Quoted 73 lines

---

Changes from v2:
- Rebased on latest upstream/master

Changes from v1:
- move "spl_net_load_read" into #ifdef block as suggested by Vignesh

 common/spl/spl_net.c | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)
common/spl/spl_net.c +27 -3
index 0fba0172ea..3d1d05d833 100644
@@ -11,19 +11,29 @@
 #include <errno.h>
 #include <spl.h>
 #include <net.h>
+#include <libfdt.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
 #if defined(CONFIG_SPL_ETH_SUPPORT) || defined(CONFIG_SPL_USBETH_SUPPORT)
+static ulong spl_net_load_read(struct spl_load_info *load, ulong sector,
+			       ulong count, void *buf)
+{
+	debug("%s: sector %lx, count %lx, buf %lx\n",
+	      __func__, sector, count, (ulong)buf);
+	memcpy(buf, (void *)(load_addr + sector), count);
+	return count;
+}
+
 static int spl_net_load_image(struct spl_image_info *spl_image,
 			      struct spl_boot_device *bootdev)
 {
+	struct image_header *header = (struct image_header *)load_addr;
 	int rv;
 
 	env_init();
 	env_relocate();
 	setenv("autoload", "yes");
-	load_addr = CONFIG_SYS_TEXT_BASE - sizeof(struct image_header);
 	rv = eth_initialize();
 	if (rv == 0) {
 		printf("No Ethernet devices found\n");
@@ -36,8 +46,22 @@ static int spl_net_load_image(struct spl_image_info *spl_image,
 		printf("Problem booting with BOOTP\n");
 		return rv;
 	}
-	return spl_parse_image_header(spl_image,
-				      (struct image_header *)load_addr);
+
+	if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
+	    image_get_magic(header) == FDT_MAGIC) {
+		struct spl_load_info load;
+
+		debug("Found FIT\n");
+		load.bl_len = 1;
+		load.read = spl_net_load_read;
+		rv = spl_load_simple_fit(spl_image, &load, 0, header);
+	} else {
+		debug("Legacy image\n");
+
+		rv = spl_parse_image_header(spl_image, header);
+	}
+
+	return rv;
 }
 #endif
 
#2 lore raw

PATCH v3 1/1 spl: net: Add FIT image support over network boot

Quoted 10 lines · Vignesh R
Quoted 6 lines · Andrew

FIT support in the net boot case is much like the RAM boot case in that we load our image to "load_addr" and pass a dummy read function into "spl_load_simple_fit()". As the load address is no longer hard-coded to the final execution address, RAW image loading will rely on "load_addr" pointing to the execution address as they should have before.

Quoted 3 lines

Sorry, but would you explain how network boot would work in case of non FIT image(same concern I had wrt v2)?

Same as last time, the global 'load_addr' will need to be set correctly. I guess we could also use the 'load_addr' provided by the legacy image header then relocate the image. I'll add that for v4.

Quoted 73 lines
Quoted 73 lines

---

Changes from v2:
- Rebased on latest upstream/master

Changes from v1:
- move "spl_net_load_read" into #ifdef block as suggested by Vignesh

 common/spl/spl_net.c | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)
common/spl/spl_net.c +27 -3
index 0fba0172ea..3d1d05d833 100644
@@ -11,19 +11,29 @@
 #include <errno.h>
 #include <spl.h>
 #include <net.h>
+#include <libfdt.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
 #if defined(CONFIG_SPL_ETH_SUPPORT) || defined(CONFIG_SPL_USBETH_SUPPORT)
+static ulong spl_net_load_read(struct spl_load_info *load, ulong sector,
+			       ulong count, void *buf)
+{
+	debug("%s: sector %lx, count %lx, buf %lx\n",
+	      __func__, sector, count, (ulong)buf);
+	memcpy(buf, (void *)(load_addr + sector), count);
+	return count;
+}
+
 static int spl_net_load_image(struct spl_image_info *spl_image,
 			      struct spl_boot_device *bootdev)
 {
+	struct image_header *header = (struct image_header *)load_addr;
 	int rv;
 
 	env_init();
 	env_relocate();
 	setenv("autoload", "yes");
-	load_addr = CONFIG_SYS_TEXT_BASE - sizeof(struct image_header);
 	rv = eth_initialize();
 	if (rv == 0) {
 		printf("No Ethernet devices found\n");
@@ -36,8 +46,22 @@ static int spl_net_load_image(struct spl_image_info *spl_image,
 		printf("Problem booting with BOOTP\n");
 		return rv;
 	}
-	return spl_parse_image_header(spl_image,
-				      (struct image_header *)load_addr);
+
+	if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
+	    image_get_magic(header) == FDT_MAGIC) {
+		struct spl_load_info load;
+
+		debug("Found FIT\n");
+		load.bl_len = 1;
+		load.read = spl_net_load_read;
+		rv = spl_load_simple_fit(spl_image, &load, 0, header);
+	} else {
+		debug("Legacy image\n");
+
+		rv = spl_parse_image_header(spl_image, header);
+	}
+
+	return rv;
 }
 #endif