diff --git a/kernel/printk.c b/kernel/printk.c
index 5b75d0e..9889f5a 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -37,6 +37,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/plat-s3c24xx/neo1973.h>
+#include <asm/io.h>
 
 /*
  * Architectures can override it:
@@ -145,6 +146,15 @@ static char *log_buf = __log_buf;
 static int log_buf_len = __LOG_BUF_LEN;
 static unsigned logged_chars; /* Number of chars produced since last read+clear operation */
 
+struct ramconsole_header {
+	__u32 magic;
+	unsigned start;
+	unsigned end;
+	unsigned len;
+	char data[1];
+};
+static struct ramconsole_header *ramconsole;
+
 static int __init log_buf_len_setup(char *str)
 {
 	unsigned size = memparse(str, &str);
@@ -500,6 +510,12 @@ static void emit_log_char(char c)
 		con_start = log_end - log_buf_len;
 	if (logged_chars < log_buf_len)
 		logged_chars++;
+	if (ramconsole) {
+		ramconsole->data[ramconsole->end % ramconsole->len] = c;
+		ramconsole->end++;
+		if (ramconsole->end - ramconsole->start > ramconsole->len)
+			ramconsole->start = ramconsole->end - ramconsole->len;
+	}
 }
 
 /*
@@ -1341,4 +1357,42 @@ bool printk_timed_ratelimit(unsigned long *caller_jiffies,
 	return false;
 }
 EXPORT_SYMBOL(printk_timed_ratelimit);
+
+static int __init ramconsole_start(void)
+{
+	unsigned i;
+	struct ramconsole_header *log;
+
+	log = ioremap(0x30000000 + (127<<20), 1024*1024);
+	if (!log) {
+		printk(KERN_WARNING "ramconsole: ioremap failed\n");
+		return 1;
+	}
+
+	if (log->magic == 0xffffffff) {
+		printk(KERN_NOTICE "ramconsole: found uninitialized memory, initializing ramconsole\n");
+		log->magic = 0x12345678;
+		log->start = 0;
+		log->end = 0;
+		log->len = 1024*512;
+	} else if (log->magic == 0x12345678) {
+		log->len = 1024*512;
+		printk(KERN_NOTICE "ramconsole: found existing ramconsole. Dumping %d bytes of data:\n", log->len);
+		if (log->end - log->start > log->len) {
+			printk(KERN_WARNING "ramconsole: end - start > len\n");
+			log->start = log->end - log->len;
+		}
+		for (i = log->start; i != log->end; i++) {
+			emit_log_char(log->data[i % log->len]);
+		}
+		printk(KERN_NOTICE "ramconsole: old data ends here\n");
+	} else {
+		printk(KERN_WARNING "ramconsole: invalid magic %08x\n", log->magic);
+		return 1;
+	}
+
+	ramconsole = log;
+	return 1;
+}
+late_initcall(ramconsole_start);
 #endif
