summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeoff Levand <geoff@infradead.org>2013-04-15 15:23:05 -0700
committerJeremy Kerr <jk@ozlabs.org>2013-06-24 13:07:57 +0800
commitc11bcba9a99e858e618f4d872a5be7d52dcaaa5a (patch)
treefeff36ae437774c66bd19b9ce6b16b19e8d7da0e
parent9f895134427d9a72be3d296e596c0360014a9753 (diff)
downloadpetitboot-c11bcba9a99e858e618f4d872a5be7d52dcaaa5a.zip
petitboot-c11bcba9a99e858e618f4d872a5be7d52dcaaa5a.tar.gz
Add initial dtb support
Updates & fixes by Jeremy Kerr <jk@ozlabs.org>. Signed-off-by: Geoff Levand <geoff@infradead.org> Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
-rw-r--r--discover/boot.c49
-rw-r--r--discover/device-handler.c5
-rw-r--r--discover/device-handler.h1
-rw-r--r--discover/kboot-parser.c25
-rw-r--r--lib/pb-protocol/pb-protocol.c13
-rw-r--r--lib/types/types.h2
-rw-r--r--ui/common/discover-client.c1
-rw-r--r--ui/common/discover-client.h1
-rw-r--r--ui/ncurses/nc-boot-editor.c18
-rw-r--r--ui/ncurses/nc-cui.c2
-rw-r--r--ui/test/discover-test.c1
-rw-r--r--ui/twin/pbt-client.c2
12 files changed, 101 insertions, 19 deletions
diff --git a/discover/boot.c b/discover/boot.c
index 5ca69b9..c922fb6 100644
--- a/discover/boot.c
+++ b/discover/boot.c
@@ -16,16 +16,18 @@
* kexec_load - kexec load helper.
* @l_image: The local image file for kexec to execute.
* @l_initrd: Optional local initrd file for kexec --initrd, can be NULL.
+ * @l_dtb: Optional local dtb file for kexec --dtb, can be NULL.
* @args: Optional command line args for kexec --append, can be NULL.
*/
static int kexec_load(const char *l_image, const char *l_initrd,
- const char *args, int dry_run)
+ const char *l_dtb, const char *args, int dry_run)
{
int result;
- const char *argv[6];
+ const char *argv[7];
const char **p;
char *s_initrd = NULL;
+ char *s_dtb = NULL;
char *s_args = NULL;
p = argv;
@@ -38,14 +40,20 @@ static int kexec_load(const char *l_image, const char *l_initrd,
*p++ = s_initrd; /* 3 */
}
+ if (l_dtb) {
+ s_dtb = talloc_asprintf(NULL, "--dtb=%s", l_dtb);
+ assert(s_dtb);
+ *p++ = s_dtb; /* 4 */
+ }
+
if (args) {
s_args = talloc_asprintf(NULL, "--append=%s", args);
assert(s_args);
- *p++ = s_args; /* 4 */
+ *p++ = s_args; /* 5 */
}
- *p++ = l_image; /* 5 */
- *p++ = NULL; /* 6 */
+ *p++ = l_image; /* 6*/
+ *p++ = NULL; /* 7 */
result = pb_run_cmd(argv, 1, dry_run);
@@ -53,6 +61,7 @@ static int kexec_load(const char *l_image, const char *l_initrd,
pb_log("%s: failed: (%d)\n", __func__, result);
talloc_free(s_initrd);
+ talloc_free(s_dtb);
talloc_free(s_args);
return result;
@@ -128,16 +137,18 @@ static void update_status(boot_status_fn fn, void *arg, int type,
int boot(void *ctx, struct discover_boot_option *opt, struct boot_command *cmd,
int dry_run, boot_status_fn status_fn, void *status_arg)
{
- char *local_image, *local_initrd;
+ char *local_image, *local_initrd, *local_dtb;
+ struct pb_url *image, *initrd, *dtb;
unsigned int clean_image = 0;
unsigned int clean_initrd = 0;
- struct pb_url *image, *initrd;
+ unsigned int clean_dtb = 0;
char *args;
int result;
local_initrd = NULL;
image = NULL;
initrd = NULL;
+ dtb = NULL;
args = NULL;
if (cmd && cmd->boot_image_file) {
@@ -155,6 +166,12 @@ int boot(void *ctx, struct discover_boot_option *opt, struct boot_command *cmd,
initrd = opt->initrd->url;
}
+ if (cmd && cmd->dtb_file) {
+ dtb = pb_url_parse(opt, cmd->dtb_file);
+ } else if (opt && opt->dtb) {
+ dtb = opt->dtb->url;
+ }
+
if (cmd && cmd->boot_args) {
args = talloc_strdup(ctx, cmd->boot_args);
} else if (opt && opt->option->boot_args) {
@@ -183,10 +200,23 @@ int boot(void *ctx, struct discover_boot_option *opt, struct boot_command *cmd,
}
}
+ local_dtb = NULL;
+ if (dtb) {
+ update_status(status_fn, status_arg, BOOT_STATUS_INFO,
+ "loading device tree");
+ local_dtb = load_url(NULL, dtb, &clean_dtb);
+ if (!local_dtb) {
+ update_status(status_fn, status_arg, BOOT_STATUS_ERROR,
+ "Couldn't load device tree");
+ goto no_load;
+ }
+ }
+
update_status(status_fn, status_arg, BOOT_STATUS_INFO,
"performing kexec_load");
- result = kexec_load(local_image, local_initrd, args, dry_run);
+ result = kexec_load(local_image, local_initrd, local_dtb,
+ args, dry_run);
if (result) {
update_status(status_fn, status_arg, BOOT_STATUS_ERROR,
@@ -198,9 +228,12 @@ no_load:
unlink(local_image);
if (clean_initrd)
unlink(local_initrd);
+ if (clean_dtb)
+ unlink(local_dtb);
talloc_free(local_image);
talloc_free(local_initrd);
+ talloc_free(local_dtb);
if (!result) {
update_status(status_fn, status_arg, BOOT_STATUS_INFO,
diff --git a/discover/device-handler.c b/discover/device-handler.c
index 46fecd2..d2a3f16 100644
--- a/discover/device-handler.c
+++ b/discover/device-handler.c
@@ -460,6 +460,7 @@ static bool __attribute__((used)) boot_option_is_resolved(
{
return resource_is_resolved(opt->boot_image) &&
resource_is_resolved(opt->initrd) &&
+ resource_is_resolved(opt->dtb) &&
resource_is_resolved(opt->icon);
}
@@ -484,6 +485,7 @@ static bool boot_option_resolve(struct discover_boot_option *opt,
{
return resource_resolve(opt->boot_image, "boot_image", opt, handler) &&
resource_resolve(opt->initrd, "initrd", opt, handler) &&
+ resource_resolve(opt->dtb, "dtb", opt, handler) &&
resource_resolve(opt->icon, "icon", opt, handler);
}
@@ -495,6 +497,7 @@ static void boot_option_finalise(struct device_handler *handler,
/* check that the parsers haven't set any of the final data */
assert(!opt->option->boot_image_file);
assert(!opt->option->initrd_file);
+ assert(!opt->option->dtb_file);
assert(!opt->option->icon_file);
assert(!opt->option->device_id);
@@ -502,6 +505,8 @@ static void boot_option_finalise(struct device_handler *handler,
opt->option->boot_image_file = opt->boot_image->url->full;
if (opt->initrd)
opt->option->initrd_file = opt->initrd->url->full;
+ if (opt->dtb)
+ opt->option->dtb_file = opt->dtb->url->full;
if (opt->icon)
opt->option->icon_file = opt->icon->url->full;
diff --git a/discover/device-handler.h b/discover/device-handler.h
index 60a33b7..693f5e4 100644
--- a/discover/device-handler.h
+++ b/discover/device-handler.h
@@ -46,6 +46,7 @@ struct discover_boot_option {
struct resource *boot_image;
struct resource *initrd;
+ struct resource *dtb;
struct resource *icon;
};
diff --git a/discover/kboot-parser.c b/discover/kboot-parser.c
index 4b4c2f7..9d0322d 100644
--- a/discover/kboot-parser.c
+++ b/discover/kboot-parser.c
@@ -21,6 +21,7 @@ static void kboot_process_pair(struct conf_context *conf, const char *name,
char *args;
const char *initrd;
const char *root;
+ const char *dtb;
/* ignore bare values */
@@ -50,6 +51,7 @@ static void kboot_process_pair(struct conf_context *conf, const char *name,
args = talloc_strdup(opt, "");
initrd = conf_get_global_option(conf, "initrd");
root = conf_get_global_option(conf, "root");
+ dtb = conf_get_global_option(conf, "dtb");
pos = strchr(value, ' ');
@@ -79,6 +81,11 @@ static void kboot_process_pair(struct conf_context *conf, const char *name,
continue;
}
+ if (streq(cl_name, "dtb")) {
+ dtb = cl_value;
+ continue;
+ }
+
args = talloc_asprintf_append(args, "%s=%s ", cl_name,
cl_value);
}
@@ -93,15 +100,22 @@ out_add:
} else
opt->boot_args = args;
+ opt->description = talloc_asprintf(opt, "%s %s", value,
+ opt->boot_args);
+
if (initrd) {
d_opt->initrd = create_devpath_resource(d_opt,
conf->dc->device, initrd);
+ opt->description = talloc_asprintf_append(opt->description,
+ " initrd=%s", initrd);
+ }
- opt->description = talloc_asprintf(opt, "%s initrd=%s %s",
- value, initrd, opt->boot_args);
- } else
- opt->description = talloc_asprintf(opt, "%s %s", value,
- opt->boot_args);
+ if (dtb) {
+ d_opt->dtb = create_devpath_resource(d_opt,
+ conf->dc->device, dtb);
+ opt->description = talloc_asprintf_append(opt->description,
+ " dtb=%s", dtb);
+ }
conf_strip_str(opt->boot_args);
conf_strip_str(opt->description);
@@ -110,6 +124,7 @@ out_add:
}
static struct conf_global_option kboot_global_options[] = {
+ { .name = "dtb" },
{ .name = "initrd" },
{ .name = "root" },
{ .name = "video" },
diff --git a/lib/pb-protocol/pb-protocol.c b/lib/pb-protocol/pb-protocol.c
index d3174af..bcc7230 100644
--- a/lib/pb-protocol/pb-protocol.c
+++ b/lib/pb-protocol/pb-protocol.c
@@ -34,6 +34,7 @@
* 4-byte len, icon_file
* 4-byte len, boot_image_file
* 4-byte len, initrd_file
+ * 4-byte len, dtb_file
* 4-byte len, boot_args
*
* action = 0x2: device remove message
@@ -45,6 +46,7 @@
* 4-byte len, boot option id
* 4-byte len, boot_image_file
* 4-byte len, initrd_file
+ * 4-byte len, dtb_file
* 4-byte len, boot_args
*
*/
@@ -67,6 +69,7 @@ void pb_protocol_dump_device(const struct device *dev, const char *text,
fprintf(stream, "%s\t\ticon: %s\n", text, opt->icon_file);
fprintf(stream, "%s\t\tboot: %s\n", text, opt->boot_image_file);
fprintf(stream, "%s\t\tinit: %s\n", text, opt->initrd_file);
+ fprintf(stream, "%s\t\tdtb: %s\n", text, opt->dtb_file);
fprintf(stream, "%s\t\targs: %s\n", text, opt->boot_args);
}
}
@@ -178,6 +181,7 @@ int pb_protocol_boot_option_len(const struct boot_option *opt)
4 + optional_strlen(opt->icon_file) +
4 + optional_strlen(opt->boot_image_file) +
4 + optional_strlen(opt->initrd_file) +
+ 4 + optional_strlen(opt->dtb_file) +
4 + optional_strlen(opt->boot_args) +
sizeof(opt->is_default);
}
@@ -187,6 +191,7 @@ int pb_protocol_boot_len(const struct boot_command *boot)
return 4 + optional_strlen(boot->option_id) +
4 + optional_strlen(boot->boot_image_file) +
4 + optional_strlen(boot->initrd_file) +
+ 4 + optional_strlen(boot->dtb_file) +
4 + optional_strlen(boot->boot_args);
}
@@ -226,6 +231,7 @@ int pb_protocol_serialise_boot_option(const struct boot_option *opt,
pos += pb_protocol_serialise_string(pos, opt->icon_file);
pos += pb_protocol_serialise_string(pos, opt->boot_image_file);
pos += pb_protocol_serialise_string(pos, opt->initrd_file);
+ pos += pb_protocol_serialise_string(pos, opt->dtb_file);
pos += pb_protocol_serialise_string(pos, opt->boot_args);
*(bool *)pos = opt->is_default;
@@ -245,6 +251,7 @@ int pb_protocol_serialise_boot_command(const struct boot_command *boot,
pos += pb_protocol_serialise_string(pos, boot->option_id);
pos += pb_protocol_serialise_string(pos, boot->boot_image_file);
pos += pb_protocol_serialise_string(pos, boot->initrd_file);
+ pos += pb_protocol_serialise_string(pos, boot->dtb_file);
pos += pb_protocol_serialise_string(pos, boot->boot_args);
assert(pos <= buf + buf_len);
@@ -423,6 +430,9 @@ int pb_protocol_deserialise_boot_option(struct boot_option *opt,
if (read_string(opt, &pos, &len, &opt->initrd_file))
goto out;
+ if (read_string(opt, &pos, &len, &opt->dtb_file))
+ goto out;
+
if (read_string(opt, &pos, &len, &opt->boot_args))
goto out;
@@ -455,6 +465,9 @@ int pb_protocol_deserialise_boot_command(struct boot_command *cmd,
if (read_string(cmd, &pos, &len, &cmd->initrd_file))
goto out;
+ if (read_string(cmd, &pos, &len, &cmd->dtb_file))
+ goto out;
+
if (read_string(cmd, &pos, &len, &cmd->boot_args))
goto out;
diff --git a/lib/types/types.h b/lib/types/types.h
index 5be2cb6..9fed7aa 100644
--- a/lib/types/types.h
+++ b/lib/types/types.h
@@ -24,6 +24,7 @@ struct boot_option {
char *icon_file;
char *boot_image_file;
char *initrd_file;
+ char *dtb_file;
char *boot_args;
bool is_default;
@@ -36,6 +37,7 @@ struct boot_command {
char *option_id;
char *boot_image_file;
char *initrd_file;
+ char *dtb_file;
char *boot_args;
};
diff --git a/ui/common/discover-client.c b/ui/common/discover-client.c
index ae5d5cd..c3f3f38 100644
--- a/ui/common/discover-client.c
+++ b/ui/common/discover-client.c
@@ -249,6 +249,7 @@ static void create_boot_command(struct boot_command *command,
command->option_id = boot_option->id;
command->boot_image_file = data->image;
command->initrd_file = data->initrd;
+ command->dtb_file = data->dtb;
command->boot_args = data->args;
}
diff --git a/ui/common/discover-client.h b/ui/common/discover-client.h
index 83bb9c9..ed1f504 100644
--- a/ui/common/discover-client.h
+++ b/ui/common/discover-client.h
@@ -9,6 +9,7 @@ struct discover_client;
struct pb_boot_data {
char *image;
char *initrd;
+ char *dtb;
char *args;
};
diff --git a/ui/ncurses/nc-boot-editor.c b/ui/ncurses/nc-boot-editor.c
index fb0bee8..4579b1a 100644
--- a/ui/ncurses/nc-boot-editor.c
+++ b/ui/ncurses/nc-boot-editor.c
@@ -185,6 +185,9 @@ static struct pb_boot_data *boot_editor_prepare_data(
bd->initrd = *s ? talloc_strdup(bd, s) : NULL;
s = boot_editor_chomp(field_buffer(boot_editor->fields[2], 0));
+ bd->dtb = *s ? talloc_strdup(bd, s) : NULL;
+
+ s = boot_editor_chomp(field_buffer(boot_editor->fields[3], 0));
bd->args = *s ? talloc_strdup(bd, s) : NULL;
return bd;
@@ -315,6 +318,7 @@ struct boot_editor *boot_editor_init(void *ui_ctx,
pb_log("%s: image: '%s'\n", __func__, bd->image);
pb_log("%s: initrd: '%s'\n", __func__, bd->initrd);
+ pb_log("%s: dtb: '%s'\n", __func__, bd->dtb);
pb_log("%s: args: '%s'\n", __func__, bd->args);
assert(on_exit);
@@ -337,15 +341,17 @@ struct boot_editor *boot_editor_init(void *ui_ctx,
boot_editor->on_exit = on_exit;
- boot_editor->fields = talloc_array(boot_editor, FIELD *, 7);
+ boot_editor->fields = talloc_array(boot_editor, FIELD *, 9);
boot_editor->fields[0] = boot_editor_setup_field(0, 9, bd->image);
boot_editor->fields[1] = boot_editor_setup_field(1, 9, bd->initrd);
- boot_editor->fields[2] = boot_editor_setup_field(2, 9, bd->args);
- boot_editor->fields[3] = boot_editor_setup_label(0, 1, "image:");
- boot_editor->fields[4] = boot_editor_setup_label(1, 1, "initrd:");
- boot_editor->fields[5] = boot_editor_setup_label(2, 1, "args:");
- boot_editor->fields[6] = NULL;
+ boot_editor->fields[2] = boot_editor_setup_field(2, 9, bd->dtb);
+ boot_editor->fields[3] = boot_editor_setup_field(3, 9, bd->args);
+ boot_editor->fields[4] = boot_editor_setup_label(0, 1, "image:");
+ boot_editor->fields[5] = boot_editor_setup_label(1, 1, "initrd:");
+ boot_editor->fields[6] = boot_editor_setup_label(2, 1, "dtb:");
+ boot_editor->fields[7] = boot_editor_setup_label(3, 1, "args:");
+ boot_editor->fields[8] = NULL;
boot_editor->ncf = new_form(boot_editor->fields);
diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c
index 82e534d..1acc2f0 100644
--- a/ui/ncurses/nc-cui.c
+++ b/ui/ncurses/nc-cui.c
@@ -158,6 +158,7 @@ static void cui_boot_editor_on_exit(struct boot_editor *boot_editor, enum boot_e
pb_log("%s: updating opt '%s'\n", __func__, cod->name);
pb_log(" image '%s'\n", cod->bd->image);
pb_log(" initrd '%s'\n", cod->bd->initrd);
+ pb_log(" dtb '%s'\n", cod->bd->dtb);
pb_log(" args '%s'\n", cod->bd->args);
}
@@ -375,6 +376,7 @@ static int cui_boot_option_add(struct device *dev, struct boot_option *opt,
cod->bd->image = talloc_strdup(cod->bd, opt->boot_image_file);
cod->bd->initrd = talloc_strdup(cod->bd, opt->initrd_file);
+ cod->bd->dtb = talloc_strdup(cod->bd, opt->dtb_file);
cod->bd->args = talloc_strdup(cod->bd, opt->boot_args);
pmenu_item_setup(cui->main, i, insert_pt, cod->name);
diff --git a/ui/test/discover-test.c b/ui/test/discover-test.c
index b81d367..45a4c74 100644
--- a/ui/test/discover-test.c
+++ b/ui/test/discover-test.c
@@ -22,6 +22,7 @@ static int print_device_add(struct device *device,
printf("\t\ticon: %s\n", opt->icon_file);
printf("\t\tboot: %s\n", opt->boot_image_file);
printf("\t\tinit: %s\n", opt->initrd_file);
+ printf("\t\tdtb: %s\n", opt->dtb_file);
printf("\t\targs: %s\n", opt->boot_args);
}
diff --git a/ui/twin/pbt-client.c b/ui/twin/pbt-client.c
index 09d8e99..445c865 100644
--- a/ui/twin/pbt-client.c
+++ b/ui/twin/pbt-client.c
@@ -147,6 +147,8 @@ static int pbt_boot_option_add(struct device *dev, struct boot_option *opt,
opt->boot_image_file);
opt_data->bd->initrd = talloc_strdup(opt_data->bd,
opt->initrd_file);
+ opt_data->bd->dtb = talloc_strdup(opt_data->bd,
+ opt->dtb_file);
opt_data->bd->args = talloc_strdup(opt_data->bd,
opt->boot_args);
opt_data->opt = opt;
OpenPOWER on IntegriCloud