Patchwork [U-Boot,v2,4/4] x86: Support loading kernel setup from a FIT

login
register
mail settings
Submitter Simon Glass
Date Nov. 10, 2013, 4:12 a.m.
Message ID <1384056727-12082-5-git-send-email-sjg@chromium.org>
Download mbox | patch
Permalink /patch/290034/
State New
Delegated to: Simon Glass
Headers show

Comments

Simon Glass - Nov. 10, 2013, 4:12 a.m.
Add a new setup@ section to the FIT which can be used to provide a setup
binary for booting Linux on x86. This makes it possible to boot x86 from
a FIT.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Rebase to master

 common/cmd_bootm.c                    | 23 ++++++++++++++--
 common/image-fit.c                    | 22 +++++++++++++++
 common/image.c                        | 11 ++++++++
 doc/uImage.FIT/kernel.its             | 50 +++++++++++++++++++++++++++++++++++
 doc/uImage.FIT/source_file_format.txt | 23 +++++++++-------
 include/bootstage.h                   |  3 +++
 include/image.h                       | 13 +++++++++
 7 files changed, 133 insertions(+), 12 deletions(-)

Patch

diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index ba73f57..2e7c37f 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -20,6 +20,7 @@ 
 #include <lmb.h>
 #include <linux/ctype.h>
 #include <asm/byteorder.h>
+#include <asm/errno.h>
 #include <asm/io.h>
 #include <linux/compiler.h>
 
@@ -207,6 +208,7 @@  static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
 			 char * const argv[])
 {
 	const void *os_hdr;
+	int ret;
 
 	/* get kernel image header, start address and length */
 	os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
@@ -225,6 +227,7 @@  static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
 
 		images.os.end = image_get_image_end(os_hdr);
 		images.os.load = image_get_load(os_hdr);
+		images.os.arch = image_get_arch(os_hdr);
 		break;
 #if defined(CONFIG_FIT)
 	case IMAGE_FORMAT_FIT:
@@ -249,6 +252,12 @@  static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
 			return 1;
 		}
 
+		if (fit_image_get_arch(images.fit_hdr_os,
+				       images.fit_noffset_os, &images.os.arch)) {
+			puts("Can't get image ARCH!\n");
+			return 1;
+		}
+
 		images.os.end = fit_get_end(images.fit_hdr_os);
 
 		if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os,
@@ -264,8 +273,18 @@  static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
 		return 1;
 	}
 
-	/* find kernel entry point */
-	if (images.legacy_hdr_valid) {
+	/* If we have a valid setup.bin, we will use that for entry (x86) */
+	if (images.os.arch == IH_ARCH_I386) {
+		ulong len;
+
+		puts("Looking for setup\n");
+		ret = boot_get_setup(&images, IH_ARCH_I386, &images.ep, &len);
+		if (ret < 0 && ret != -ENOENT) {
+			puts("Could not find a valid setup.bin for x86n");
+			return 1;
+		}
+		/* Kernel entry point is the setup.bin */
+	} else if (images.legacy_hdr_valid) {
 		images.ep = image_get_ep(&images.legacy_hdr_os_copy);
 #if defined(CONFIG_FIT)
 	} else if (images.fit_uname_os) {
diff --git a/common/image-fit.c b/common/image-fit.c
index cf4b67e..95c3cb7 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -1559,11 +1559,13 @@  int fit_image_load(bootm_headers_t *images, const char *prop_name, ulong addr,
 	}
 
 	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
+#ifndef CONFIG_SANDBOX
 	if (!fit_image_check_target_arch(fit, noffset)) {
 		puts("Unsupported Architecture\n");
 		bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
 		return -ENOEXEC;
 	}
+#endif
 
 	if (image_type == IH_TYPE_FLATDT &&
 	    !fit_image_check_comp(fit, noffset, IH_COMP_NONE)) {
@@ -1660,3 +1662,23 @@  int fit_image_load(bootm_headers_t *images, const char *prop_name, ulong addr,
 
 	return noffset;
 }
+
+int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
+			ulong *setup_start, ulong *setup_len)
+{
+	int noffset;
+	ulong addr;
+	ulong len;
+	int ret;
+
+	addr = map_to_sysmem(images->fit_hdr_os);
+	noffset = fit_get_node_from_config(images, FIT_SETUP_PROP, addr);
+	if (noffset < 0)
+		return noffset;
+
+	ret = fit_image_load(images, FIT_SETUP_PROP, addr, NULL, NULL,
+		arch, IH_TYPE_X86_SETUP, BOOTSTAGE_ID_FIT_SETUP_START,
+		FIT_LOAD_REQUIRED, setup_start, &len);
+
+	return ret;
+}
diff --git a/common/image.c b/common/image.c
index b0ae58f..c39bb60 100644
--- a/common/image.c
+++ b/common/image.c
@@ -136,6 +136,7 @@  static const table_entry_t uimage_type[] = {
 	{	IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
 	{	IH_TYPE_UBLIMAGE,   "ublimage",   "Davinci UBL image",},
 	{	IH_TYPE_MXSIMAGE,   "mxsimage",   "Freescale MXS Boot Image",},
+	{	IH_TYPE_X86_SETUP,  "x86_setup",  "x86 setup.bin",    },
 	{	-1,		    "",		  "",			},
 };
 
@@ -1051,6 +1052,16 @@  error:
 }
 #endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */
 
+int boot_get_setup(bootm_headers_t *images, uint8_t arch,
+		   ulong *setup_start, ulong *setup_len)
+{
+#if defined(CONFIG_FIT)
+	return boot_get_setup_fit(images, arch, setup_start, setup_len);
+#else
+	return -ENOENT;
+#endif
+}
+
 #ifdef CONFIG_SYS_BOOT_GET_CMDLINE
 /**
  * boot_get_cmdline - allocate and initialize kernel cmdline
diff --git a/doc/uImage.FIT/kernel.its b/doc/uImage.FIT/kernel.its
index ef3ab8f..1b662aa 100644
--- a/doc/uImage.FIT/kernel.its
+++ b/doc/uImage.FIT/kernel.its
@@ -35,3 +35,53 @@ 
 		};
 	};
 };
+
+
+
+For x86 a setup node is also required:
+
+/dts-v1/;
+
+/ {
+	description = "Simple image with single Linux kernel on x86";
+	#address-cells = <1>;
+
+	images {
+		kernel@1 {
+			description = "Vanilla Linux kernel";
+			data = /incbin/("./Image");
+			type = "kernel";
+			arch = "x86";
+			os = "linux";
+			compression = "lzo";
+			load = <00000000>;
+			entry = <00000000>;
+			hash@2 {
+				algo = "sha1";
+			};
+		};
+
+		setup@1 {
+			description = "Linux setup.bin";
+			data = /incbin/("./setup.bin");
+			type = "setup";
+			arch = "x86";
+			os = "linux";
+			compression = "none";
+			load = <00100000>;
+			entry = <00100000>;
+			hash@2 {
+				algo = "sha1";
+			};
+		};
+	};
+
+	configurations {
+		default = "config@1";
+		config@1 {
+			description = "Boot Linux kernel";
+			kernel = "kernel@1";
+			setup = "setup@1";
+		};
+	};
+};
diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt
index 160b2d0..cb23df3 100644
--- a/doc/uImage.FIT/source_file_format.txt
+++ b/doc/uImage.FIT/source_file_format.txt
@@ -55,7 +55,7 @@  FIT is formally a flattened device tree (in the libfdt meaning), which
 conforms to bindings defined in this document.
 
 .its	- image tree source
-.itb	- image tree blob
+.fit	- flattened image tree blob
 
 c) Image building procedure
 
@@ -101,15 +101,15 @@  Root node of the uImage Tree should have the following layout:
     |
     o images
     | |
-    | o img@1 {...}
-    | o img@2 {...}
+    | o image@1 {...}
+    | o image@2 {...}
     | ...
     |
     o configurations
-      |- default = "cfg@1"
+      |- default = "conf@1"
       |
-      o cfg@1 {...}
-      o cfg@2 {...}
+      o conf@1 {...}
+      o conf@2 {...}
       ...
 
 
@@ -159,11 +159,11 @@  the '/images' node should have the following layout:
   - description : Textual description of the component sub-image
   - type : Name of component sub-image type, supported types are:
     "standalone", "kernel", "ramdisk", "firmware", "script", "filesystem",
-    "fdt".
+    "fdt" and others (see uimage_type in common/images.c).
   - data : Path to the external file which contains this node's binary data.
   - compression : Compression used by included data. Supported compressions
-    are "gzip" and "bzip2". If no compression is used compression property
-    should be set to "none".
+    include "gzip" and "bzip2" (see uimage_comp in common/images.c). If no
+    compression is used, the compression property should be set to "none".
 
   Conditionally mandatory property:
   - os : OS name, mandatory for type="kernel", valid OS names are: "openbsd",
@@ -173,7 +173,8 @@  the '/images' node should have the following layout:
   - arch : Architecture name, mandatory for types: "standalone", "kernel",
     "firmware", "ramdisk" and "fdt". Valid architecture names are: "alpha",
     "arm", "i386", "ia64", "mips", "mips64", "ppc", "s390", "sh", "sparc",
-    "sparc64", "m68k", "microblaze", "nios2", "blackfin", "avr32", "st200".
+    "sparc64", "m68k", "microblaze", "nios2", "blackfin", "avr32", "st200",
+    "sandbox".
   - entry : entry point address, address size is determined by
     '#address-cells' property of the root node. Mandatory for for types:
     "standalone" and "kernel".
@@ -246,6 +247,8 @@  o config@1
     node of a "ramdisk" type).
   - fdt : Unit name of the corresponding fdt blob (component image node of a
     "fdt type").
+  - setup : Unit name of the corresponding setup binary (used for booting
+    an x86 kernel). This contains the setup.bin file built by the kernel.
 
 The FDT blob is required to properly boot FDT based kernel, so the minimal
 configuration for 2.6 FDT kernel is (kernel, fdt) pair.
diff --git a/include/bootstage.h b/include/bootstage.h
index 87bf906..df13ab2 100644
--- a/include/bootstage.h
+++ b/include/bootstage.h
@@ -159,6 +159,9 @@  enum bootstage_id {
 	/* Next 10 IDs used by BOOTSTAGE_SUB_... */
 	BOOTSTAGE_ID_FIT_RD_START = 120,	/* Ramdisk stages */
 
+	/* Next 10 IDs used by BOOTSTAGE_SUB_... */
+	BOOTSTAGE_ID_FIT_SETUP_START = 130,	/* x86 setup stages */
+
 	BOOTSTAGE_ID_IDE_FIT_READ = 140,
 	BOOTSTAGE_ID_IDE_FIT_READ_OK,
 
diff --git a/include/image.h b/include/image.h
index ee6eb8d..35d6c87 100644
--- a/include/image.h
+++ b/include/image.h
@@ -213,6 +213,7 @@  struct lmb;
 #define IH_TYPE_KERNEL_NOLOAD	14	/* OS Kernel Image, can run from any load address */
 #define IH_TYPE_PBLIMAGE	15	/* Freescale PBL Boot Image	*/
 #define IH_TYPE_MXSIMAGE	16	/* Freescale MXSBoot Image	*/
+#define IH_TYPE_X86_SETUP	17	/* x86 setup.bin Image		*/
 
 /*
  * Compression Types
@@ -253,6 +254,7 @@  typedef struct image_info {
 	ulong		image_start, image_len; /* start of image within blob, len of image */
 	ulong		load;			/* load addr for the image */
 	uint8_t		comp, type, os;		/* compression, type of image, os type */
+	uint8_t		arch;			/* CPU architecture */
 } image_info_t;
 
 /*
@@ -283,6 +285,10 @@  typedef struct bootm_headers {
 	void		*fit_hdr_fdt;	/* FDT blob FIT image header */
 	const char	*fit_uname_fdt;	/* FDT blob subimage node unit name */
 	int		fit_noffset_fdt;/* FDT blob subimage node offset */
+
+	void		*fit_hdr_setup;	/* x86 setup FIT image header */
+	const char	*fit_uname_setup; /* x86 setup subimage node name */
+	int		fit_noffset_setup;/* x86 setup subimage node offset */
 #endif
 
 #ifndef USE_HOSTCC
@@ -396,6 +402,9 @@  enum fit_load_op {
 	FIT_LOAD_REQUIRED,	/* Must be provided */
 };
 
+int boot_get_setup(bootm_headers_t *images, uint8_t arch, ulong *setup_start,
+		   ulong *setup_len);
+
 #ifndef USE_HOSTCC
 /* Image format types, returned by _get_format() routine */
 #define IMAGE_FORMAT_INVALID	0x00
@@ -409,6 +418,9 @@  ulong genimg_get_image(ulong img_addr);
 int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
 		uint8_t arch, ulong *rd_start, ulong *rd_end);
 
+int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
+		       ulong *setup_start, ulong *setup_len);
+
 /**
  * fit_image_load() - load an image from a FIT
  *
@@ -689,6 +701,7 @@  int bootz_setup(ulong image, ulong *start, ulong *end);
 #define FIT_RAMDISK_PROP	"ramdisk"
 #define FIT_FDT_PROP		"fdt"
 #define FIT_DEFAULT_PROP	"default"
+#define FIT_SETUP_PROP		"setup"
 
 #define FIT_MAX_HASH_LEN	20	/* max(crc32_len(4), sha1_len(20)) */