[PATCH 2/2] kexec tools: devicetreeblob option

Michael Neuling mikey at neuling.org
Wed Oct 26 12:48:02 EST 2005


This adds the device tree blob option to kexec.  This option is useful
if you want to generate you own device tree blobs.   Also, you can now
do something like:

  dtc -I fs /proc/device-tree -O dts -f > dt.dts
  <insert some massaging[1] of dt.dts>
  dtc -I dts dt.dts -O dtb -f > dt.dtb
  kexec -l vmlinux --devicetreeblob=dt.dtb
  taskset 1 kexec -e

And get a similar results to just running kexec normally.

Also, the --devicetreeblob option won't work with the --initrd option.

1. massaging includes (from memory) 
  - removal of htab entries
  - ensure CPU are ordered from 0 onwards
  - adding of reserve map entries (need to create fake last entry for
      the blob which kexec will patch after loading)

Signed-off-by: Michael Neuling <mikey at neuling.org>
---
 kexec-elf-ppc64.c |   30 +++++++++++++++++++++++++++++-
 kexec-ppc64.c     |    1 +
 2 files changed, 30 insertions(+), 1 deletion(-)

Signed-off-by: Michael Neuling <mikey at neuling.org>
Index: kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-ppc64.c
===================================================================
--- kexec-tools-1.101.orig/kexec/arch/ppc64/kexec-elf-ppc64.c	2005-10-26 12:00:33.000000000 +1000
+++ kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-ppc64.c	2005-10-26 12:00:44.000000000 +1000
@@ -73,16 +73,19 @@
 	const char *input_options;
 	int command_line_len;
 	const char *ramdisk;
+	const char *devicetreeblob;
 	unsigned long *lp;
 	int result;
 	int opt;
 #define OPT_APPEND     (OPT_ARCH_MAX+0)
 #define OPT_RAMDISK     (OPT_ARCH_MAX+1)
+#define OPT_DEVICETREEBLOB     (OPT_ARCH_MAX+2)
 
 	static const struct option options[] = {
 		KEXEC_ARCH_OPTIONS
 		{ "append",             1, NULL, OPT_APPEND },
 		{ "ramdisk",            1, NULL, OPT_RAMDISK },
+		{ "devicetreeblob",     1, NULL, OPT_DEVICETREEBLOB },
 		{ 0,                    0, NULL, 0 },
 	};
 
@@ -94,6 +97,7 @@
 	command_line = 0;
 	input_options = 0;
 	ramdisk = 0;
+	devicetreeblob = 0;
 
 	while ((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) {
 		switch (opt) {
@@ -111,6 +115,9 @@
 		case OPT_RAMDISK:
 			ramdisk = optarg;
 			break;
+		case OPT_DEVICETREEBLOB:
+			devicetreeblob = optarg;
+			break;
 		}
 	}
 
@@ -156,6 +163,10 @@
 
 	/* Add a ram-disk to the current image */
 	if (ramdisk) {
+	  if (devicetreeblob) {
+	    fprintf(stderr, "Can't use ramdisk with device tree blob input\n");
+	    return -1;
+	  }
 		unsigned char *ramdisk_buf = NULL;
 		off_t ramdisk_size = 0;
 		unsigned long long ramdisk_addr;
@@ -182,7 +193,24 @@
 	}
 	memcpy(v2wrap_buf, purgatory, purgatory_size);
 	v2wrap_size = purgatory_size;
-	create_flatten_tree(info, &v2wrap_buf, &v2wrap_size);
+	if (devicetreeblob) {
+	  unsigned char *blob_buf = NULL;
+	  off_t blob_size = 0;
+	  unsigned char *tmp_buf = NULL;
+
+	  /* Grab device tree from buffer */
+	  blob_buf = slurp_file(devicetreeblob, &blob_size);
+
+	  /* Append to purgatory */
+	  tmp_buf = (unsigned char *) realloc(v2wrap_buf, v2wrap_size + blob_size);
+	  v2wrap_buf = tmp_buf;
+	  memcpy(v2wrap_buf+v2wrap_size, blob_buf, blob_size);
+	  v2wrap_size += blob_size;
+
+	} else {
+	  /* create from fs2dt */
+	  create_flatten_tree(info, &v2wrap_buf, &v2wrap_size);
+	}
 	add_buffer(info, v2wrap_buf, v2wrap_size, v2wrap_size, 0, 0,
 			0xFFFFFFFFFFFFFFFFUL, -1);
 
Index: kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.c
===================================================================
--- kexec-tools-1.101.orig/kexec/arch/ppc64/kexec-ppc64.c	2005-10-26 12:00:33.000000000 +1000
+++ kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.c	2005-10-26 12:00:40.000000000 +1000
@@ -468,6 +468,7 @@
 
 void arch_usage(void)
 {
+	fprintf(stderr, "     --devicetreeblob=<filename> Specify device tree blob file.\n");
 }
 
 static struct {



More information about the Linuxppc64-dev mailing list