=== drivers/keyboard.c
==================================================================
--- drivers/keyboard.c	(revision 2252)
+++ drivers/keyboard.c	(local)
@@ -326,6 +326,11 @@
 	return 0;
 }
 
+static struct console_input_driver cons = {
+	.havekey = keyboard_havechar,
+	.getchar = keyboard_getchar
+};
+
 void keyboard_init(void)
 {
 	u8 mode;
@@ -350,5 +355,7 @@
 
 	/* Write the new mode */
 	keyboard_set_mode(mode);
+
+	console_add_input_driver(&cons);
 }
 
=== drivers/serial.c
==================================================================
--- drivers/serial.c	(revision 2252)
+++ drivers/serial.c	(local)
@@ -58,15 +58,27 @@
 	outb(reg &= ~0x80, port + 0x03);
 }
 
+static struct console_input_driver consin = {
+	.havekey = serial_havechar,
+	.getchar = serial_getchar
+};
+
+static struct console_output_driver consout = {
+	.putchar = serial_putchar
+};
+
 void serial_init(void)
 {
 #ifdef CONFIG_SERIAL_SET_SPEED
 	serial_hardware_init(IOBASE, CONFIG_SERIAL_BAUD_RATE, 8, 0, 1);
 #endif
+	console_add_input_driver(&consin);
+	console_add_output_driver(&consout);
 }
 
-void serial_putchar(unsigned char c)
+void serial_putchar(unsigned int c)
 {
+	c &= 0xff;
 	while ((inb(IOBASE + 0x05) & 0x20) == 0) ;
 	outb(c, IOBASE);
 }
=== drivers/usb/usbhid.c
==================================================================
--- drivers/usb/usbhid.c	(revision 2252)
+++ drivers/usb/usbhid.c	(local)
@@ -145,10 +145,21 @@
 	dev->controller->control (dev, OUT, sizeof (dev_req_t), &dr, 0, 0);
 }
 
+static struct console_input_driver cons = {
+	.havekey = usbhid_havechar,
+	.getchar = usbhid_getchar
+};
+
 void
 usb_hid_init (usbdev_t *dev)
 {
 
+	static int installed = 0;
+	if (!installed) {
+		installed = 1;
+		console_add_input_driver (&cons);
+	}
+
 	configuration_descriptor_t *cd = (configuration_descriptor_t*)dev->configuration;
 	interface_descriptor_t *interface = (interface_descriptor_t*)(((char *) cd) + cd->bLength);
 
=== drivers/video/video.c
==================================================================
--- drivers/video/video.c	(revision 2252)
+++ drivers/video/video.c	(local)
@@ -111,6 +111,11 @@
 
 void video_console_putchar(unsigned int ch)
 {
+	/* replace black-on-black with light-gray-on-black.
+	   do it here, instead of in libc/console.c */
+	if ((ch & 0xFF00) == 0) {
+		ch |= 0x0700;
+	}
 	switch(ch & 0xFF) {
 	case '\r':
 		cursorx = 0;
@@ -165,6 +170,10 @@
 	video_console_fixup_cursor();
 }
 
+static struct console_output_driver cons = {
+	.putchar = video_console_putchar
+};
+
 int video_console_init(void)
 {
 		int i;
@@ -187,6 +196,8 @@
 			return 0;
 		}
 
+		console_add_output_driver(&cons);
+
 		return 0;
 }
 
=== include/libpayload.h
==================================================================
--- include/libpayload.h	(revision 2252)
+++ include/libpayload.h	(local)
@@ -145,7 +145,7 @@
  */
 void serial_init(void);
 void serial_hardware_init(int port, int speed, int word_bits, int parity, int stop_bits);
-void serial_putchar(unsigned char c);
+void serial_putchar(unsigned int c);
 int serial_havechar(void);
 int serial_getchar(void);
 void serial_clear(void);
@@ -192,7 +192,7 @@
  * @{
  */
 void console_init(void);
-int putchar(int c);
+int putchar(unsigned int c);
 int puts(const char *s);
 int havekey(void);
 int getchar(void);
@@ -200,6 +200,22 @@
 
 extern int last_putchar;
 
+struct console_input_driver;
+struct console_input_driver {
+	struct console_input_driver *next;
+	int (*havekey) (void);
+	int (*getchar) (void);
+};
+
+struct console_output_driver;
+struct console_output_driver {
+	struct console_output_driver *next;
+	void (*putchar) (unsigned int);
+};
+
+void console_add_output_driver(struct console_output_driver *out);
+void console_add_input_driver(struct console_input_driver *in);
+
 #define havechar havekey
 /** @} */
 
=== libc/console.c
==================================================================
--- libc/console.c	(revision 2252)
+++ libc/console.c	(local)
@@ -31,6 +31,21 @@
 #include <libpayload.h>
 #include <usb/usb.h>
 
+struct console_output_driver *console_out;
+struct console_input_driver *console_in;
+
+void console_add_output_driver(struct console_output_driver *out)
+{
+	out->next = console_out;
+	console_out = out;
+}
+
+void console_add_input_driver(struct console_input_driver *in)
+{
+	in->next = console_in;
+	console_in = in;
+}
+
 void console_init(void)
 {
 #ifdef CONFIG_VIDEO_CONSOLE
@@ -46,15 +61,12 @@
 
 static void device_putchar(unsigned char c)
 {
-#ifdef CONFIG_VIDEO_CONSOLE
-	video_console_putchar(0x700| c);
-#endif
-#ifdef CONFIG_SERIAL_CONSOLE
-	serial_putchar(c);
-#endif
+	struct console_output_driver *out;
+	for (out = console_out; out != 0; out = out->next)
+		out->putchar(c);
 }
 
-int putchar(int c)
+int putchar(unsigned int c)
 {
 	c &= 0xff;
 	if (c == '\n')
@@ -78,19 +90,13 @@
 
 int havekey(void)
 {
-#ifdef CONFIG_USB_HID
+#ifdef CONFIG_USB
 	usb_poll();
-	if (usbhid_havechar())
-		return 1;
 #endif
-#ifdef CONFIG_SERIAL_CONSOLE
-	if (serial_havechar())
-		return 1;
-#endif
-#ifdef CONFIG_PC_KEYBOARD
-	if (keyboard_havechar())
-		return 1;
-#endif
+	struct console_input_driver *in;
+	for (in = console_in; in != 0; in = in->next)
+		if (in->havekey())
+			return 1;
 	return 0;
 }
 
@@ -101,19 +107,13 @@
 int getchar(void)
 {
 	while (1) {
-#ifdef CONFIG_USB_HID
+#ifdef CONFIG_USB
 		usb_poll();
-		if (usbhid_havechar())
-			return usbhid_getchar();
 #endif
-#ifdef CONFIG_SERIAL_CONSOLE
-		if (serial_havechar())
-			return serial_getchar();
-#endif
-#ifdef CONFIG_PC_KEYBOARD
-		if (keyboard_havechar())
-			return keyboard_getchar();
-#endif
+		struct console_input_driver *in = console_in;
+		for (in = console_in; in != 0; in = in->next)
+			if (in->havechar())
+				return in->getchar();
 	}
 }
 
