Index: Makefile
===================================================================
--- Makefile	(revision a7fdfe105a1a679fcd33e43de73fce4e1fde4aa4)
+++ Makefile	(revision 26777587cc06315d26b419e506af97ae2163613a)
@@ -94,6 +94,9 @@
 
 GENERIC_SOURCES = \
+	generic/src/console/chardev.c \
+	generic/src/console/console.c \
 	generic/src/cpu/cpu.c \
 	generic/src/main/main.c \
+	generic/src/main/kconsole.c \
 	generic/src/main/kinit.c \
 	generic/src/main/uinit.c \
Index: arch/mips32/src/drivers/keyboard.c
===================================================================
--- arch/mips32/src/drivers/keyboard.c	(revision a7fdfe105a1a679fcd33e43de73fce4e1fde4aa4)
+++ arch/mips32/src/drivers/keyboard.c	(revision 26777587cc06315d26b419e506af97ae2163613a)
@@ -1,3 +1,4 @@
 /*
+ * Copyright (C) 2003 Josef Cejka
  * Copyright (C) 2005 Jakub Jermar
  * All rights reserved.
@@ -28,15 +29,52 @@
 
 #include <arch/drivers/keyboard.h>
+#include <console/chardev.h>
+#include <console/console.h>
 #include <arch/cp0.h>
 #include <putchar.h>
+#include <synch/spinlock.h>
+#include <synch/waitq.h>
+#include <typedefs.h>
 
+static chardev_t kbrd;
+
+static void keyboard_enable(void);
+
+/** Initialize keyboard subsystem. */
 void keyboard_init(void)
 {
-	/* unmask keyboard interrupt */
+	cp0_unmask_int(KEYBOARD_IRQ);
+	chardev_initialize(&kbrd, keyboard_enable);
+	stdin = &kbrd;
+}
+
+/** Process keyboard interrupt.
+ *
+ * This function is called directly from the interrupt handler.
+ * It feeds the keyboard buffer with characters read. When the buffer
+ * is full, it simply masks the keyboard interrupt signal.
+ */
+void keyboard(void)
+{
+	char ch;
+
+	spinlock_lock(&kbrd.lock);
+	kbrd.counter++;
+	if (kbrd.counter == CHARDEV_BUFLEN - 1) {
+	        /* buffer full => disable keyboard interrupt */
+		cp0_mask_int(KEYBOARD_IRQ);
+	}
+
+	ch = *((char *) KEYBOARD_ADDRESS);
+	putchar(ch);
+	kbrd.buffer[kbrd.index++] = ch;
+	kbrd.index = kbrd.index % CHARDEV_BUFLEN; /* index modulo size of buffer */
+	waitq_wakeup(&kbrd.wq, WAKEUP_FIRST);
+	spinlock_unlock(&kbrd.lock);
+}
+
+/* Called from getc(). */
+void keyboard_enable(void)
+{
 	cp0_unmask_int(KEYBOARD_IRQ);
 }
-
-void keyboard(void)
-{
-	putchar(*((char *) KEYBOARD_ADDRESS));
-}
Index: arch/mips32/src/mips32.c
===================================================================
--- arch/mips32/src/mips32.c	(revision a7fdfe105a1a679fcd33e43de73fce4e1fde4aa4)
+++ arch/mips32/src/mips32.c	(revision 26777587cc06315d26b419e506af97ae2163613a)
@@ -38,4 +38,5 @@
 #include <arch/interrupt.h>
 #include <arch/drivers/arc.h>
+#include <arch/drivers/keyboard.h>
 #include <proc/thread.h>
 #include <print.h>
@@ -83,4 +84,5 @@
 
 	console_init();
+	keyboard_init();
 	arc_print_memory_map();
 	arc_print_devices();
Index: generic/include/console/chardev.h
===================================================================
--- generic/include/console/chardev.h	(revision 26777587cc06315d26b419e506af97ae2163613a)
+++ generic/include/console/chardev.h	(revision 26777587cc06315d26b419e506af97ae2163613a)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __CHARDEV_H__
+#define __CHARDEV_H__
+
+#include <typedefs.h>
+#include <arch/types.h>
+#include <synch/waitq.h>
+#include <synch/spinlock.h>
+
+#define CHARDEV_BUFLEN 10
+
+typedef void (* ready_func_t)(void);
+
+/** Character input device. */
+struct chardev {
+	waitq_t wq;
+	spinlock_t lock;		/**< Protects everything below. */
+	__u8 buffer[CHARDEV_BUFLEN];
+	count_t counter;
+	index_t index;
+	ready_func_t ready_func;	/**< Function to re-enable input from the device. */
+};
+
+extern void chardev_initialize(chardev_t *chardev, ready_func_t r);
+
+#endif /* __CHARDEV_H__ */
Index: generic/include/console/console.h
===================================================================
--- generic/include/console/console.h	(revision 26777587cc06315d26b419e506af97ae2163613a)
+++ generic/include/console/console.h	(revision 26777587cc06315d26b419e506af97ae2163613a)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __CONSOLE_H__
+#define __CONSOLE_H__
+
+#include <arch/types.h>
+#include <typedefs.h>
+
+extern chardev_t *stdin;
+
+extern __u8 getc(chardev_t *chardev);
+extern void gets(chardev_t *chardev, __u8 *buf, size_t buflen);
+
+#endif /* __CHARDEV_H__ */
Index: generic/include/main/kconsole.h
===================================================================
--- generic/include/main/kconsole.h	(revision 26777587cc06315d26b419e506af97ae2163613a)
+++ generic/include/main/kconsole.h	(revision 26777587cc06315d26b419e506af97ae2163613a)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __KCONSOLE_H__
+#define __KCONSOLE_H__
+
+extern void kconsole(void *arg);
+
+#endif
Index: generic/include/typedefs.h
===================================================================
--- generic/include/typedefs.h	(revision a7fdfe105a1a679fcd33e43de73fce4e1fde4aa4)
+++ generic/include/typedefs.h	(revision 26777587cc06315d26b419e506af97ae2163613a)
@@ -80,3 +80,5 @@
 typedef struct the the_t;
 
+typedef struct chardev chardev_t;
+
 #endif
Index: generic/src/console/chardev.c
===================================================================
--- generic/src/console/chardev.c	(revision 26777587cc06315d26b419e506af97ae2163613a)
+++ generic/src/console/chardev.c	(revision 26777587cc06315d26b419e506af97ae2163613a)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <console/chardev.h>
+#include <synch/waitq.h>
+#include <synch/spinlock.h>
+
+/** Initialize character device. */
+void chardev_initialize(chardev_t *chardev, ready_func_t r)
+{
+	waitq_initialize(&chardev->wq);
+	spinlock_initialize(&chardev->lock);
+	chardev->counter = 0;
+	chardev->index = 0;
+	chardev->ready_func = r;
+}
Index: generic/src/console/console.c
===================================================================
--- generic/src/console/console.c	(revision 26777587cc06315d26b419e506af97ae2163613a)
+++ generic/src/console/console.c	(revision 26777587cc06315d26b419e506af97ae2163613a)
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2003 Josef Cejka
+ * Copyright (C) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <console/console.h>
+#include <console/chardev.h>
+#include <synch/waitq.h>
+#include <synch/spinlock.h>
+#include <arch/types.h>
+#include <typedefs.h>
+#include <arch.h>
+
+/** Standard input character device. */
+chardev_t *stdin = NULL;
+
+/** Get string from character device.
+ *
+ * Read characters from character device until first occurrence
+ * of newline character.
+ *
+ * @param chardev Character device.
+ * @param string Buffer where to store string terminated by '\0'.
+ * @param len Size of the buffer.
+ */
+void gets(chardev_t *chardev, __u8 *string, size_t buflen)
+{
+	index_t index = 0;
+	char ch;
+
+	while (index < buflen) {
+		ch = getc(chardev);
+		if (ch == '\n') { /* end of string => write 0, return */
+			string[index] = '\0';
+			return;
+		}
+		string[index++] = ch;
+	}
+	return;
+}
+
+/** Get character from character device.
+ *
+ * @param chardev Character device.
+ *
+ * @return Character read.
+ */
+__u8 getc(chardev_t *chardev)
+{
+	__u8 ch;
+	ipl_t ipl;
+
+	waitq_sleep(&chardev->wq);
+	ipl = interrupts_disable();
+	spinlock_lock(&chardev->lock);
+	ch = chardev->buffer[(chardev->index - chardev->counter) % CHARDEV_BUFLEN];
+	chardev->counter--;
+	spinlock_unlock(&chardev->lock);
+	interrupts_restore(ipl);
+
+	chardev->ready_func();
+
+	return ch;
+}
Index: generic/src/main/kconsole.c
===================================================================
--- generic/src/main/kconsole.c	(revision 26777587cc06315d26b419e506af97ae2163613a)
+++ generic/src/main/kconsole.c	(revision 26777587cc06315d26b419e506af97ae2163613a)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <main/kconsole.h>
+#include <console/console.h>
+#include <console/chardev.h>
+#include <print.h>
+#include <typedefs.h>
+#include <arch/types.h>
+
+/** Kernel console managing thread.
+ *
+ * @param arg Not used.
+ */
+void kconsole(void *arg)
+{
+	__u8 buf[CHARDEV_BUFLEN];
+
+	if (!stdin) {
+		printf("%s: no stdin\n", __FUNCTION__);
+		return;
+	}
+	
+	while (true) {
+		printf("%s> ", __FUNCTION__);
+		gets(stdin, buf, sizeof(buf));
+	}
+}
Index: generic/src/main/kinit.c
===================================================================
--- generic/src/main/kinit.c	(revision a7fdfe105a1a679fcd33e43de73fce4e1fde4aa4)
+++ generic/src/main/kinit.c	(revision 26777587cc06315d26b419e506af97ae2163613a)
@@ -27,8 +27,9 @@
  */
 
+#include <main/kinit.h>
+#include <main/kconsole.h>
+#include <main/uinit.h>
 #include <config.h>
 #include <arch.h>
-#include <main/kinit.h>
-#include <main/uinit.h>
 #include <proc/scheduler.h>
 #include <proc/task.h>
@@ -83,5 +84,5 @@
 			waitq_sleep(&kmp_completion_wq);
 		}
-		else panic("thread_create/kmp");
+		else panic("thread_create/kmp\n");
 	}
 #endif /* CONFIG_SMP */
@@ -110,9 +111,16 @@
 				thread_ready(t);
 			}
-			else panic("thread_create/kcpulb");
+			else panic("thread_create/kcpulb\n");
 
 		}
 	}
 #endif /* CONFIG_SMP */
+
+	/*
+	 * Create kernel console.
+	 */
+	if (t = thread_create(kconsole, NULL, TASK, 0))
+		thread_ready(t);
+	else panic("thread_create/kconsole\n");
 
 	interrupts_enable();
@@ -124,11 +132,11 @@
 	m = vm_create(NULL);
 	if (!m)
-		panic("vm_create");
+		panic("vm_create\n");
 	u = task_create(m);
 	if (!u)
-		panic("task_create");
+		panic("task_create\n");
 	t = thread_create(uinit, NULL, u, THREAD_USER_STACK);
 	if (!t)
-		panic("thread_create");
+		panic("thread_create\n");
 
 	/*
@@ -137,5 +145,5 @@
 	a = vm_area_create(m, VMA_TEXT, 1, UTEXT_ADDRESS);
 	if (!a)
-		panic("vm_area_create: vm_text");
+		panic("vm_area_create: vm_text\n");
 	vm_area_map(a, m);
 	memcpy((void *) PA2KA(a->mapping[0]), (void *) utext, utext_size < PAGE_SIZE ? utext_size : PAGE_SIZE);
@@ -146,5 +154,5 @@
 	a = vm_area_create(m, VMA_STACK, 1, USTACK_ADDRESS);
 	if (!a)
-		panic("vm_area_create: vm_stack");
+		panic("vm_area_create: vm_stack\n");
 	vm_area_map(a, m);	
 	
@@ -156,5 +164,4 @@
 #endif /* CONFIG_TEST */
 
-
 	while (1) {
 		thread_sleep(60);
Index: generic/src/main/main.c
===================================================================
--- generic/src/main/main.c	(revision a7fdfe105a1a679fcd33e43de73fce4e1fde4aa4)
+++ generic/src/main/main.c	(revision 26777587cc06315d26b419e506af97ae2163613a)
@@ -71,5 +71,5 @@
 	char *revision = "";
 #endif
-char *copyright = "Copyright (C) 2001-2005 Jakub Jermar\nCopyright (C) 2005 HelenOS project";
+char *copyright = "Copyright (C) 2001-2005 HelenOS project";
 
 config_t config;
