summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kexec/arch/ppc64/kexec-elf-ppc64.c30
-rw-r--r--kexec/arch/ppc64/kexec-ppc64.c1
2 files changed, 30 insertions, 1 deletions
diff --git a/kexec/arch/ppc64/kexec-elf-ppc64.c b/kexec/arch/ppc64/kexec-elf-ppc64.c
index f7fbeae..4423636 100644
--- a/kexec/arch/ppc64/kexec-elf-ppc64.c
+++ b/kexec/arch/ppc64/kexec-elf-ppc64.c
@@ -73,16 +73,19 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
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 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
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 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
case OPT_RAMDISK:
ramdisk = optarg;
break;
+ case OPT_DEVICETREEBLOB:
+ devicetreeblob = optarg;
+ break;
}
}
@@ -156,6 +163,10 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
/* 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 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
}
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);
diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c
index 536bab3..11138b7 100644
--- a/kexec/arch/ppc64/kexec-ppc64.c
+++ b/kexec/arch/ppc64/kexec-ppc64.c
@@ -468,6 +468,7 @@ int file_types = sizeof(file_type) / sizeof(file_type[0]);
void arch_usage(void)
{
+ fprintf(stderr, " --devicetreeblob=<filename> Specify device tree blob file.\n");
}
static struct {