summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-04-02 16:38:20 +1000
committerJeremy Kerr <jk@ozlabs.org>2007-04-03 14:16:31 +1000
commitbd803b47266f399c41c7e560b8769ef172f0fca9 (patch)
tree5cefd39807d025c6145eacd06b7089695e3bf85c
parent2ee42ce22b643f865e52088b0f0451ec1f3a8f09 (diff)
downloadtalos-petitboot-bd803b47266f399c41c7e560b8769ef172f0fca9.tar.gz
talos-petitboot-bd803b47266f399c41c7e560b8769ef172f0fca9.zip
Hookup kexec
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--devices.c41
-rw-r--r--petitboot.c20
-rw-r--r--petitboot.h3
3 files changed, 54 insertions, 10 deletions
diff --git a/devices.c b/devices.c
index 28cb3a3..0a06450 100644
--- a/devices.c
+++ b/devices.c
@@ -152,21 +152,22 @@ out:
static int read_option(int fd, struct device_context *dev_ctx)
{
- struct boot_option opt;
+ struct boot_option *opt = malloc(sizeof(*opt));
twin_pixmap_t *icon;
int index = -1;
- if (!read_strings(fd, opt))
+ if (!opt)
return TWIN_FALSE;
- LOG("got option: '%s'\n", opt.name);
- icon = get_icon(opt.icon_file);
+ if (!read_strings(fd, (*opt)))
+ return TWIN_FALSE;
- if (icon)
- index = pboot_add_option(dev_ctx->device_idx, opt.name,
- opt.description, icon);
+ LOG("got option: '%s'\n", opt->name);
+ icon = get_icon(opt->icon_file);
- free_strings(opt);
+ if (icon)
+ index = pboot_add_option(dev_ctx->device_idx, opt->name,
+ opt->description, icon, opt);
return index != -1;
}
@@ -270,3 +271,27 @@ int pboot_start_device_discovery(void)
return TWIN_TRUE;
}
+void pboot_exec_option(void *data)
+{
+ struct boot_option *opt = data;
+ char *kexec_opts[10];
+ int nr_opts = 2;
+
+ kexec_opts[0] = "/sbin/kexec";
+ kexec_opts[1] = "-f";
+ if (opt->initrd_file) {
+ kexec_opts[nr_opts] = malloc(10 + strlen(opt->initrd_file));
+ sprintf(kexec_opts[nr_opts], "--initrd=%s", opt->initrd_file);
+ nr_opts++;
+ }
+ if (opt->boot_args) {
+ kexec_opts[nr_opts] = malloc(10 + strlen(opt->boot_args));
+ sprintf(kexec_opts[nr_opts], "--command-line=%s",
+ opt->boot_args);
+ nr_opts++;
+ }
+
+ kexec_opts[nr_opts++] = opt->boot_image_file;
+ kexec_opts[nr_opts] = NULL;
+ execv(kexec_opts[0], kexec_opts);
+}
diff --git a/petitboot.c b/petitboot.c
index 44e1cc8..e7eff4c 100644
--- a/petitboot.c
+++ b/petitboot.c
@@ -76,6 +76,7 @@ struct _pboot_option
twin_pixmap_t *badge;
twin_pixmap_t *cache;
twin_rect_t box;
+ void *data;
};
struct _pboot_device
@@ -400,6 +401,17 @@ static void pboot_rpane_mousetrack(twin_coord_t x, twin_coord_t y)
pboot_rpane->mouse_target = candidate;
}
+static void pboot_choose_option(void)
+{
+ pboot_device_t *dev = pboot_devices[pboot_dev_sel];
+ pboot_option_t *opt = &dev->options[pboot_rpane->focus_curindex];
+
+ LOG("Selected device %s\n", opt->title);
+
+ /* Give user feedback, make sure errors and panics will be seen */
+ pboot_exec_option(opt->data);
+}
+
static twin_bool_t pboot_rpane_event (twin_window_t *window,
twin_event_t *event)
{
@@ -412,6 +424,9 @@ static twin_bool_t pboot_rpane_event (twin_window_t *window,
pboot_rpane_mousetrack(event->u.pointer.x, event->u.pointer.y);
return TWIN_TRUE;
case TwinEventButtonDown:
+ pboot_select_rpane();
+ pboot_rpane_mousetrack(event->u.pointer.x, event->u.pointer.y);
+ pboot_choose_option();
case TwinEventButtonUp:
return TWIN_TRUE;
case TwinEventKeyDown:
@@ -425,6 +440,8 @@ static twin_bool_t pboot_rpane_event (twin_window_t *window,
case KEY_LEFT:
pboot_select_lpane();
return TWIN_TRUE;
+ case KEY_ENTER:
+ pboot_choose_option();
default:
break;
}
@@ -437,7 +454,7 @@ static twin_bool_t pboot_rpane_event (twin_window_t *window,
int pboot_add_option(int devindex, const char *title,
- const char *subtitle, twin_pixmap_t *badge)
+ const char *subtitle, twin_pixmap_t *badge, void *data)
{
pboot_device_t *dev;
pboot_option_t *opt;
@@ -474,6 +491,7 @@ int pboot_add_option(int devindex, const char *title,
index * PBOOT_RIGHT_OPTION_STRIDE;
opt->box.bottom = opt->box.top + PBOOT_RIGHT_OPTION_HEIGHT;
+ opt->data = data;
return index;
}
diff --git a/petitboot.h b/petitboot.h
index aeac73b..147fe7f 100644
--- a/petitboot.h
+++ b/petitboot.h
@@ -9,7 +9,8 @@
int pboot_add_device(const char *dev_id, const char *name,
twin_pixmap_t *pixmap);
int pboot_add_option(int devindex, const char *title,
- const char *subtitle, twin_pixmap_t *badge);
+ const char *subtitle, twin_pixmap_t *badge, void *data);
int pboot_remove_device(const char *dev_id);
int pboot_start_device_discovery(void);
+void pboot_exec_option(void *data);
OpenPOWER on IntegriCloud