Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision 5030acadeab877d574032b6cbe0e3a5f0551de90)
+++ HelenOS.config	(revision 6bbe470e275a3b9a63f777eb4b7ae8586c4ec665)
@@ -464,5 +464,5 @@
 
 % Use NS16550 controller as dummy serial output (kernel console)
-! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&(PLATFORM=ia32|PLATFORM=amd64)&CONFIG_NS16550_KCON=y] CONFIG_NS16550_DSRLNOUT (y)
+! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&(PLATFORM=ia32|PLATFORM=amd64)&CONFIG_NS16550_KCON=y] CONFIG_NS16550_OUT (y)
 
 % Support for ARM926 on-chip UART
@@ -491,5 +491,5 @@
 
 % Dummy serial line output
-! [CONFIG_MIPS_PRN=y|CONFIG_ARM_PRN=y|CONFIG_NS16550_DSRLNOUT=y] CONFIG_DSRLNOUT (y)
+! [CONFIG_MIPS_PRN=y|CONFIG_ARM_PRN=y] CONFIG_DSRLNOUT (y)
 
 % Serial line input module
Index: kernel/arch/amd64/src/amd64.c
===================================================================
--- kernel/arch/amd64/src/amd64.c	(revision 5030acadeab877d574032b6cbe0e3a5f0551de90)
+++ kernel/arch/amd64/src/amd64.c	(revision 6bbe470e275a3b9a63f777eb4b7ae8586c4ec665)
@@ -55,5 +55,4 @@
 #include <genarch/kbrd/kbrd.h>
 #include <genarch/srln/srln.h>
-#include <genarch/drivers/dsrln/dsrlnout.h>
 #include <genarch/multiboot/multiboot.h>
 #include <genarch/multiboot/multiboot2.h>
@@ -219,12 +218,12 @@
 #endif
 
-#ifdef CONFIG_NS16550
+#if (defined(CONFIG_NS16550) || defined(CONFIG_NS16550_OUT))
 	/*
-	 * Initialize the ns16550 controller. Then initialize the serial
-	 * input module and connect it to ns16550.
+	 * Initialize the ns16550 controller.
 	 */
 	ns16550_instance_t *ns16550_instance
 	    = ns16550_init((ns16550_t *) NS16550_BASE, IRQ_NS16550, NULL, NULL);
 	if (ns16550_instance) {
+#ifdef CONFIG_NS16550
 		srln_instance_t *srln_instance = srln_init();
 		if (srln_instance) {
@@ -234,14 +233,11 @@
 			trap_virtual_enable_irqs(1 << IRQ_NS16550);
 		}
-	}
-#endif
-
-#ifdef CONFIG_NS16550_DSRLNOUT
-	/*
-	 * Initialize dummy serial output to the ns16550.
-	 */
-	outdev_t *dsrlndev = dsrlnout_init(NS16550_BASE);
-	if (dsrlndev) {
-		stdout_wire(dsrlndev);
+#endif
+#ifdef CONFIG_NS16550_OUT
+		outdev_t *ns16550_out = ns16550_output(ns16550_instance);
+		if (ns16550_out) {
+			stdout_wire(ns16550_out);
+		}
+#endif
 	}
 #endif
Index: kernel/arch/ia32/src/ia32.c
===================================================================
--- kernel/arch/ia32/src/ia32.c	(revision 5030acadeab877d574032b6cbe0e3a5f0551de90)
+++ kernel/arch/ia32/src/ia32.c	(revision 6bbe470e275a3b9a63f777eb4b7ae8586c4ec665)
@@ -56,5 +56,4 @@
 #include <genarch/kbrd/kbrd.h>
 #include <genarch/srln/srln.h>
-#include <genarch/drivers/dsrln/dsrlnout.h>
 #include <genarch/multiboot/multiboot.h>
 #include <genarch/multiboot/multiboot2.h>
@@ -173,12 +172,12 @@
 #endif
 
-#ifdef CONFIG_NS16550
+#if (defined(CONFIG_NS16550) || defined(CONFIG_NS16550_OUT))
 	/*
-	 * Initialize the ns16550 controller. Then initialize the serial
-	 * input module and connect it to ns16550.
+	 * Initialize the ns16550 controller.
 	 */
 	ns16550_instance_t *ns16550_instance
 	    = ns16550_init((ns16550_t *) NS16550_BASE, IRQ_NS16550, NULL, NULL);
 	if (ns16550_instance) {
+#ifdef CONFIG_NS16550
 		srln_instance_t *srln_instance = srln_init();
 		if (srln_instance) {
@@ -188,14 +187,11 @@
 			trap_virtual_enable_irqs(1 << IRQ_NS16550);
 		}
-	}
-#endif
-	
-#ifdef CONFIG_NS16550_DSRLNOUT
-	/*
-	 * Initialize dummy serial output to the ns16550.
-	 */
-	outdev_t *dsrlndev = dsrlnout_init(NS16550_BASE);
-	if (dsrlndev) {
-		stdout_wire(dsrlndev);
+#endif
+#ifdef CONFIG_NS16550_OUT
+		outdev_t *ns16550_out = ns16550_output(ns16550_instance);
+		if (ns16550_out) {
+			stdout_wire(ns16550_out);
+		}
+#endif
 	}
 #endif
Index: kernel/genarch/include/drivers/ns16550/ns16550.h
===================================================================
--- kernel/genarch/include/drivers/ns16550/ns16550.h	(revision 5030acadeab877d574032b6cbe0e3a5f0551de90)
+++ kernel/genarch/include/drivers/ns16550/ns16550.h	(revision 6bbe470e275a3b9a63f777eb4b7ae8586c4ec665)
@@ -38,4 +38,5 @@
 #define KERN_NS16550_H_
 
+#include <ddi/ddi.h>
 #include <ddi/irq.h>
 #include <typedefs.h>
@@ -50,5 +51,8 @@
 /** NS16550 registers. */
 typedef struct {
-	ioport8_t rbr;      /**< Receiver Buffer Register. */
+	union {
+		ioport8_t rbr;      /**< Receiver Buffer Register (read). */
+		ioport8_t thr;      /**< Transmitter Holder Register (write). */
+	} __attribute__ ((packed));
 	ioport8_t ier;      /**< Interrupt Enable Register. */
 	union {
@@ -65,9 +69,12 @@
 	irq_t irq;
 	ns16550_t *ns16550;
-	indev_t *kbrdin;
+	indev_t *input;
+	outdev_t *output;
+	parea_t parea;
 } ns16550_instance_t;
 
 extern ns16550_instance_t *ns16550_init(ns16550_t *, inr_t, cir_t, void *);
 extern void ns16550_wire(ns16550_instance_t *, indev_t *);
+extern outdev_t *ns16550_output(ns16550_instance_t *);
 
 #endif
Index: kernel/genarch/src/drivers/ns16550/ns16550.c
===================================================================
--- kernel/genarch/src/drivers/ns16550/ns16550.c	(revision 5030acadeab877d574032b6cbe0e3a5f0551de90)
+++ kernel/genarch/src/drivers/ns16550/ns16550.c	(revision 6bbe470e275a3b9a63f777eb4b7ae8586c4ec665)
@@ -41,6 +41,8 @@
 #include <mm/slab.h>
 #include <ddi/device.h>
+#include <str.h>
 
 #define LSR_DATA_READY  0x01
+#define LSR_TH_READY    0x20
 
 static irq_ownership_t ns16550_claim(irq_t *irq)
@@ -62,5 +64,5 @@
 	if (pio_read_8(&dev->lsr) & LSR_DATA_READY) {
 		uint8_t data = pio_read_8(&dev->rbr);
-		indev_push_character(instance->kbrdin, data);
+		indev_push_character(instance->input, data);
 	}
 }
@@ -72,4 +74,28 @@
 		(void) pio_read_8(&dev->rbr);
 }
+
+static void ns16550_sendb(ns16550_t *dev, uint8_t byte)
+{
+	while (!(pio_read_8(&dev->lsr) & LSR_TH_READY))
+		;
+	pio_write_8(&dev->thr, byte);
+}
+
+static void ns16550_putchar(outdev_t *dev, wchar_t ch)
+{
+	ns16550_instance_t *instance = (ns16550_instance_t *) dev->data;
+	
+	if ((!instance->parea.mapped) || (console_override)) {
+		if (ascii_check(ch))
+			ns16550_sendb(instance->ns16550, (uint8_t) ch);
+		else
+			ns16550_sendb(instance->ns16550, U_SPECIAL);
+	}
+}
+
+static outdev_operations_t ns16550_ops = {
+	.write = ns16550_putchar,
+	.redraw = NULL
+};
 
 /** Initialize ns16550.
@@ -90,5 +116,6 @@
 	if (instance) {
 		instance->ns16550 = dev;
-		instance->kbrdin = NULL;
+		instance->input = NULL;
+		instance->output = NULL;
 		
 		irq_initialize(&instance->irq);
@@ -100,4 +127,10 @@
 		instance->irq.cir = cir;
 		instance->irq.cir_arg = cir_arg;
+		
+		instance->parea.pbase = (uintptr_t) dev;
+		instance->parea.frames = 1;
+		instance->parea.unpriv = false;
+		instance->parea.mapped = false;
+		ddi_parea_register(&instance->parea);
 	}
 	
@@ -105,10 +138,10 @@
 }
 
-void ns16550_wire(ns16550_instance_t *instance, indev_t *kbrdin)
+void ns16550_wire(ns16550_instance_t *instance, indev_t *input)
 {
 	ASSERT(instance);
-	ASSERT(kbrdin);
+	ASSERT(input);
 	
-	instance->kbrdin = kbrdin;
+	instance->input = input;
 	irq_register(&instance->irq);
 	
@@ -120,4 +153,21 @@
 }
 
+outdev_t *ns16550_output(ns16550_instance_t *instance)
+{
+	ASSERT(instance);
+	
+	if (instance->output == NULL) {
+		instance->output = malloc(sizeof(outdev_t),
+		    FRAME_ATOMIC);
+		if (instance->output) {
+			outdev_initialize("ns16550", instance->output,
+			    &ns16550_ops);
+			instance->output->data = instance;
+		}
+	}
+	
+	return instance->output;
+}
+
 /** @}
  */
