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

login
register
mail settings
Submitter Simon Glass
Date Jan. 12, 2013, 5:48 p.m.
Message ID <1358012928-2112-5-git-send-email-sjg@chromium.org>
Download mbox | patch
Permalink /patch/211527/
State RFC
Headers show

Comments

Simon Glass - Jan. 12, 2013, 5:48 p.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>
---
 common/cmd_bootm.c                    |   22 +++++++++++++-
 common/image-fit.c                    |   20 +++++++++++++
 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, 130 insertions(+), 12 deletions(-)

Patch

diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index de3dfc5..35fc4bf 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -36,6 +36,7 @@ 
 #include <lmb.h>
 #include <linux/ctype.h>
 #include <asm/byteorder.h>
+#include <asm/errno.h>
 #include <asm/io.h>
 #include <linux/compiler.h>
 
@@ -215,6 +216,7 @@  static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
 
 		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:
@@ -239,6 +241,12 @@  static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
 			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,
@@ -254,8 +262,18 @@  static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
 		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 9f3ece2..04093a0 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -1654,3 +1654,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 26b9653..7c44bc7 100644
--- a/common/image.c
+++ b/common/image.c
@@ -151,6 +151,7 @@  static const table_entry_t uimage_type[] = {
 	{	IH_TYPE_SCRIPT,     "script",	  "Script",		},
 	{	IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
 	{	IH_TYPE_UBLIMAGE,   "ublimage",   "Davinci UBL image",},
+	{	IH_TYPE_X86_SETUP,  "x86_setup",  "x86 setup.bin",    },
 	{	-1,		    "",		  "",			},
 };
 
@@ -1064,6 +1065,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 6d20707..b0d9a71 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 2a28e23..a7f41ce 100644
--- a/include/bootstage.h
+++ b/include/bootstage.h
@@ -174,6 +174,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 a724926..dc61823 100644
--- a/include/image.h
+++ b/include/image.h
@@ -201,6 +201,7 @@  struct lmb;
 #define IH_TYPE_AISIMAGE	13	/* TI Davinci AIS Image		*/
 #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_X86_SETUP	16	/* x86 setup.bin Image		*/
 
 /*
  * Compression Types
@@ -241,6 +242,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;
 
 /*
@@ -271,6 +273,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
@@ -381,6 +387,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
@@ -394,6 +403,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
  *
@@ -662,6 +674,7 @@  int image_setup_linux(bootm_headers_t *images);
 #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)) */