aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_syslog.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_syslog.c')
-rw-r--r--sys/kern/kern_syslog.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/sys/kern/kern_syslog.c b/sys/kern/kern_syslog.c
index 88ae8bc..712b69b 100644
--- a/sys/kern/kern_syslog.c
+++ b/sys/kern/kern_syslog.c
@@ -30,10 +30,46 @@
#include <sys/syslog.h>
#include <sys/machdep.h>
#include <sys/tty.h>
+#include <sys/cdefs.h>
#include <dev/vcons/vcons.h>
+#include <fs/procfs.h>
#include <string.h>
+#if defined(__KMSG_BUF_SHIFT)
+#define KMSG_BUF_SHIFT __KMSG_BUF_SHIFT
+#else
+#define KMSG_BUF_SHIFT 12
+#endif
+
+#define KMSG_BUF_SIZE (1 << KMSG_BUF_SHIFT)
+
+__STATIC_ASSERT(KMSG_BUF_SHIFT <= 16, "Log buffer shift too large!\n");
+
+static char kmsg_buf[KMSG_BUF_SIZE];
+static size_t kmsg_buf_idx = 0;
+static struct proc_entry *kmsg_proc;
+
struct vcons_screen g_syslog_screen = {0};
+bool g_syslog_use_tty = true;
+
+static inline void
+kmsg_buf_putc(char c)
+{
+ kmsg_buf[kmsg_buf_idx++] = c;
+ kmsg_buf[kmsg_buf_idx] = '\0';
+ if (kmsg_buf_idx >= (KMSG_BUF_SIZE - 1))
+ kmsg_buf_idx = 0;
+}
+
+static int
+proc_kmsg_read(struct proc_entry *p, struct sio_txn *sio)
+{
+ if (sio->len > KMSG_BUF_SIZE)
+ sio->len = KMSG_BUF_SIZE;
+
+ memcpy(sio->buf, kmsg_buf, sio->len);
+ return sio->len;
+}
static void
syslog_write(const char *s, size_t len)
@@ -45,7 +81,11 @@ syslog_write(const char *s, size_t len)
#if defined(__SERIAL_DEBUG)
serial_dbgch(*tmp_s);
#endif /* defined(__SERIAL_DEBUG) */
- tty_putc(&g_root_tty, *tmp_s++, TTY_SOURCE_RAW);
+ kmsg_buf_putc(*tmp_s);
+ if (g_syslog_use_tty)
+ tty_putc(&g_root_tty, *tmp_s, TTY_SOURCE_RAW);
+
+ ++tmp_s;
}
tty_flush(&g_root_tty);
@@ -71,6 +111,14 @@ kprintf(const char *fmt, ...)
}
void
+syslog_init_proc(void)
+{
+ kmsg_proc = procfs_alloc_entry();
+ kmsg_proc->read = proc_kmsg_read;
+ procfs_add_entry("kmsg", kmsg_proc);
+}
+
+void
syslog_init(void)
{
g_syslog_screen.bg = 0x000000;