aboutsummaryrefslogtreecommitdiff
path: root/linux/kernel/printk.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/kernel/printk.c')
-rw-r--r--linux/kernel/printk.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/linux/kernel/printk.c b/linux/kernel/printk.c
new file mode 100644
index 0000000..7a70dc3
--- /dev/null
+++ b/linux/kernel/printk.c
@@ -0,0 +1,33 @@
+/*
+ * When in kernel-mode, we cannot use printf, as fs is liable to
+ * point to 'interesting' things. Make a printf with fs-saving, and
+ * all is well.
+ */
+#include <stdarg.h>
+#include <stddef.h>
+
+#include <linux/kernel.h>
+
+static char buf[1024];
+
+int printk(const char *fmt, ...)
+{
+ va_list args;
+ int i;
+
+ va_start(args, fmt);
+ i=vsprintf(buf,fmt,args);
+ va_end(args);
+ __asm__("push %%fs\n\t"
+ "push %%ds\n\t"
+ "pop %%fs\n\t"
+ "pushl %0\n\t"
+ "pushl $_buf\n\t"
+ "pushl $0\n\t"
+ "call _tty_write\n\t"
+ "addl $8,%%esp\n\t"
+ "popl %0\n\t"
+ "pop %%fs"
+ ::"r" (i):"ax","cx","dx");
+ return i;
+}