diff --git a/discover/boot.c b/discover/boot.c
index c301e8a..1075cd8 100644
--- a/discover/boot.c
+++ b/discover/boot.c
@@ -435,7 +435,7 @@ struct boot_task *boot(void *ctx, struct discover_boot_option *opt,
 		boot_status_fn status_fn, void *status_arg)
 {
 	struct pb_url *image = NULL, *initrd = NULL, *dtb = NULL;
-	const struct config *config;
+	const struct config *config = config_get();
 	struct boot_task *boot_task;
 	const char *boot_desc;
 	int rc;
@@ -487,12 +487,10 @@ struct boot_task *boot(void *ctx, struct discover_boot_option *opt,
 		boot_task->args = NULL;
 	}
 
-	if (cmd && cmd->console)
+	if (cmd && cmd->console && !config->manual_console)
 		boot_task->boot_console = talloc_strdup(boot_task, cmd->console);
-	else {
-		config = config_get();
+	else
 		boot_task->boot_console = config ? config->boot_console : NULL;
-	}
 
 	/* start async loads for boot resources */
 	rc = start_url_load(boot_task, "kernel image", image, &boot_task->image)
diff --git a/discover/platform-powerpc.c b/discover/platform-powerpc.c
index 1636955..027da55 100644
--- a/discover/platform-powerpc.c
+++ b/discover/platform-powerpc.c
@@ -59,7 +59,7 @@ static const char *known_params[] = {
 	"petitboot,debug?",
 	"petitboot,write?",
 	"petitboot,snapshots?",
-	"petitboot,tty",
+	"petitboot,console",
 	NULL,
 };
 
@@ -567,9 +567,12 @@ static void populate_config(struct platform_powerpc *platform,
 	if (val)
 		config->disable_snapshots = !strcmp(val, "false");
 
-	val = get_param(platform, "petitboot,tty");
+	val = get_param(platform, "petitboot,console");
 	if (val)
 		config->boot_console = talloc_strdup(config, val);
+	/* If a full path is already set we don't want to override it */
+	config->manual_console = config->boot_console &&
+					!strchr(config->boot_console, '[');
 }
 
 static char *iface_config_str(void *ctx, struct interface_config *config)
@@ -737,8 +740,10 @@ static int update_config(struct platform_powerpc *platform,
 		val = config->allow_writes ? "true" : "false";
 	update_string_config(platform, "petitboot,write?", val);
 
-	val = config->boot_console ?: "";
-	update_string_config(platform, "petitboot,tty", val);
+	if (!config->manual_console) {
+		val = config->boot_console ?: "";
+		update_string_config(platform, "petitboot,console", val);
+	}
 
 	update_network_config(platform, config);
 
diff --git a/discover/platform.c b/discover/platform.c
index 95a905d..93cd057 100644
--- a/discover/platform.c
+++ b/discover/platform.c
@@ -84,6 +84,8 @@ static void dump_config(struct config *config)
 
 	pb_log("  Default UI to boot on: %s\n",
 		config->boot_console ?: "none set");
+	if (config->manual_console)
+		pb_log("    (Manually set)\n");
 
 
 	pb_log(" language: %s\n", config->lang ?: "");
diff --git a/lib/pb-config/pb-config.c b/lib/pb-config/pb-config.c
index 97115bc..189d907 100644
--- a/lib/pb-config/pb-config.c
+++ b/lib/pb-config/pb-config.c
@@ -91,6 +91,7 @@ struct config *config_copy(void *ctx, const struct config *src)
 
 	if (src->boot_console)
 		dest->boot_console = talloc_strdup(dest, src->boot_console);
+	dest->manual_console = src->manual_console;
 
 	if (src->lang && strlen(src->lang))
 		dest->lang = talloc_strdup(dest, src->lang);
diff --git a/lib/pb-protocol/pb-protocol.c b/lib/pb-protocol/pb-protocol.c
index adf2208..3320c48 100644
--- a/lib/pb-protocol/pb-protocol.c
+++ b/lib/pb-protocol/pb-protocol.c
@@ -316,6 +316,7 @@ int pb_protocol_config_len(const struct config *config)
 		len += 4 + optional_strlen(config->consoles[i]);
 
 	len += 4 + optional_strlen(config->boot_console);
+	len += 4; /* manual_console */
 
 	len += 4 + optional_strlen(config->lang);
 
@@ -567,6 +568,8 @@ int pb_protocol_serialise_config(const struct config *config,
 		pos += pb_protocol_serialise_string(pos, config->consoles[i]);
 
 	pos += pb_protocol_serialise_string(pos, config->boot_console);
+	*(uint32_t *)pos = config->manual_console;
+	pos += 4;
 
 	pos += pb_protocol_serialise_string(pos, config->lang);
 
@@ -1102,6 +1105,10 @@ int pb_protocol_deserialise_config(struct config *config,
 
 	config->boot_console = str;
 
+	if (read_u32(&pos, &len, &tmp))
+		goto out;
+	config->manual_console = !!tmp;
+
 	if (read_string(config, &pos, &len, &str))
 		goto out;
 
diff --git a/lib/types/types.h b/lib/types/types.h
index 9154b35..0521aee 100644
--- a/lib/types/types.h
+++ b/lib/types/types.h
@@ -161,6 +161,7 @@ struct config {
 	bool			allow_writes;
 
 	char			*boot_console;
+	bool			manual_console;
 	char			*lang;
 
 	/* not user-settable */
diff --git a/ui/ncurses/nc-config.c b/ui/ncurses/nc-config.c
index 7da2f06..d8bf3be 100644
--- a/ui/ncurses/nc-config.c
+++ b/ui/ncurses/nc-config.c
@@ -33,7 +33,7 @@
 #include "nc-config.h"
 #include "nc-widgets.h"
 
-#define N_FIELDS	42
+#define N_FIELDS	43
 
 extern struct help_text config_help_text;
 
@@ -110,6 +110,7 @@ struct config_screen {
 		struct nc_widget_select		*allow_write_f;
 		struct nc_widget_label		*boot_console_l;
 		struct nc_widget_select		*boot_console_f;
+		struct nc_widget_label		*manual_console_l;
 		struct nc_widget_label		*current_console_l;
 
 		struct nc_widget_label		*safe_mode;
@@ -336,7 +337,7 @@ static int screen_process_form(struct config_screen *screen)
 	if (allow_write != config->allow_writes)
 		config->allow_writes = allow_write;
 
-	if (config->n_consoles) {
+	if (config->n_consoles && !config->manual_console) {
 		idx = widget_select_get_value(screen->widgets.boot_console_f);
 		if (!config->boot_console) {
 			config->boot_console = talloc_strdup(config,
@@ -596,7 +597,15 @@ static void config_screen_layout_widgets(struct config_screen *screen)
 
 	y += 1;
 
-	if (widget_height(widget_select_base(screen->widgets.boot_console_f))) {
+	if (screen->widgets.manual_console_l) {
+		layout_pair(screen, y++, screen->widgets.boot_console_l,
+			widget_label_base(screen->widgets.manual_console_l));
+		widget_move(widget_label_base(screen->widgets.current_console_l),
+			y, screen->field_x);
+		widget_set_visible(widget_select_base(
+			screen->widgets.boot_console_f), false);
+		y += 2;
+	} else if (widget_height(widget_select_base(screen->widgets.boot_console_f))) {
 		layout_pair(screen, y, screen->widgets.boot_console_l,
 			    widget_select_base(screen->widgets.boot_console_f));
 		y += widget_height(widget_select_base(screen->widgets.boot_console_f));
@@ -773,7 +782,7 @@ static void config_screen_setup_widgets(struct config_screen *screen,
 {
 	struct nc_widgetset *set = screen->widgetset;
 	struct interface_config *ifcfg;
-	char *str, *ip, *mask, *gw, *url, *tty;
+	char *str, *ip, *mask, *gw, *url, *tty, *label;
 	enum net_conf_type type;
 	unsigned int i;
 	int add_len, clear_len, any_len, min_len = 20;
@@ -829,7 +838,6 @@ static void config_screen_setup_widgets(struct config_screen *screen,
 
 	for (i = 0; i < sysinfo->n_blockdevs; i++) {
 		struct blockdev_info *bd = sysinfo->blockdevs[i];
-		char *label;
 
 		label = talloc_asprintf(screen, _("disk: %s [uuid: %s]"),
 				bd->name, bd->uuid);
@@ -839,7 +847,7 @@ static void config_screen_setup_widgets(struct config_screen *screen,
 
 	for (i = 0; i < sysinfo->n_interfaces; i++) {
 		struct interface_info *info = sysinfo->interfaces[i];
-		char *label, mac[20];
+		char mac[20];
 
 		mac_str(info->hwaddr, info->hwaddr_size, mac, sizeof(mac));
 
@@ -850,7 +858,6 @@ static void config_screen_setup_widgets(struct config_screen *screen,
 	}
 
 	for (i = DEVICE_TYPE_NETWORK; i < DEVICE_TYPE_UNKNOWN; i++) {
-		char *label;
 
 		if (i == DEVICE_TYPE_ANY)
 			label = talloc_asprintf(screen, _("Any Device"));
@@ -891,7 +898,7 @@ static void config_screen_setup_widgets(struct config_screen *screen,
 	widget_textbox_set_validator_integer(screen->widgets.timeout_f, 0, 999);
 
 	if (config->ipmi_bootdev) {
-		char *label = talloc_asprintf(screen,
+		label = talloc_asprintf(screen,
 				_("%s IPMI boot option: %s"),
 				config->ipmi_bootdev_persistent ?
 				"Persistent" : "Temporary",
@@ -1033,6 +1040,12 @@ static void config_screen_setup_widgets(struct config_screen *screen,
 					config->consoles[i], found);
 	}
 
+	if (config->manual_console) {
+		label = talloc_asprintf(screen, _("Manually set: '%s'"),
+					config->boot_console);
+		screen->widgets.manual_console_l = widget_new_label(set, 0, 0, label);
+	}
+
 	tty = talloc_asprintf(screen, _("Current interface: %s"),
 				ttyname(STDIN_FILENO));
 	screen->widgets.current_console_l = widget_new_label(set, 0 , 0, tty);
diff --git a/utils/Makefile.am b/utils/Makefile.am
index 2bbfb9c..453fdbd 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -34,5 +34,4 @@ dist_pkgdata_DATA = \
 	utils/logrotate.conf \
 	utils/hooks/01-create-default-dtb \
 	utils/hooks/20-update-dtb-sample \
-	utils/hooks/90-sort-dtb \
-	utils/hooks/80-set-stdout
+	utils/hooks/90-sort-dtb
diff --git a/utils/hooks/30-add-offb.c b/utils/hooks/30-add-offb.c
index eca9d13..3d9ec99 100644
--- a/utils/hooks/30-add-offb.c
+++ b/utils/hooks/30-add-offb.c
@@ -512,7 +512,10 @@ static int set_stdout(struct offb_ctx *ctx)
 		return 0;
 	}
 
-	if (strstr(boot_console, "tty") != NULL) {
+	if (strncmp(boot_console, "/dev/", strlen("/dev/")) != 0) {
+		/* We already have the full path */
+		stdout_path = boot_console;
+	} else if (strstr(boot_console, "tty") != NULL) {
 		fprintf(stderr, "TTY recognised: %s\n", boot_console);
 		stdout_path = get_vga_path(ctx);
 	} else {
diff --git a/utils/hooks/80-set-stdout b/utils/hooks/80-set-stdout
deleted file mode 100755
index 92ff030..0000000
--- a/utils/hooks/80-set-stdout
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/sh
-
-# Hook to set the linux,stdout-path property from an nvram property
-# (named $nvram_prop).
-
-nvram_prop=petitboot,console
-
-# we need to be using a dtb
-[ -n "$boot_dtb" ] || exit
-
-console=$(nvram --print-config="$nvram_prop")
-
-[ $? = 0 -a -n "$console" ] || exit
-
-dtb_in=$boot_dtb
-dtb_out=$(mktemp)
-
-(
-	dtc -I dtb -O dts $dtb_in
-	echo '/ { chosen { linux,stdout-path = "'$console'"; }; }; '
-) | dtc -I dts -O dtb -o $dtb_out
-
-[ $? = 0 ] && mv $dtb_out $dtb_in
