diff options
author | Danny Holman <dholman@gymli.org> | 2024-02-16 12:32:40 -0600 |
---|---|---|
committer | Danny Holman <dholman@gymli.org> | 2024-02-16 12:32:40 -0600 |
commit | a267b8c076793cf59c2f6c80a31d7d094a215aab (patch) | |
tree | 2f73f36ebfd69a8e8709a9ee8434b9bcf57c386c | |
parent | 1d40d14e09c8c22ffbdf5a5cad95ae552587ce53 (diff) |
kernel: make kprintf print to a ring buffer
The function kprintf should print to an internal ringbuffer instead of
directly to the framebuffer. This reduces dependence on the existence of
a framebuffer in the first place.
Signed-off-by: Danny Holman <dholman@gymli.org>
-rw-r--r-- | include/kernel/data/ringbuf.h | 50 | ||||
-rw-r--r-- | include/kernel/io.h | 4 | ||||
-rw-r--r-- | kernel/io.c | 34 |
3 files changed, 75 insertions, 13 deletions
diff --git a/include/kernel/data/ringbuf.h b/include/kernel/data/ringbuf.h new file mode 100644 index 0000000..4f30874 --- /dev/null +++ b/include/kernel/data/ringbuf.h @@ -0,0 +1,50 @@ +#ifndef KERNEL_RINGBUF_H +#define KERNEL_RINGBUF_H + +#include <kernel/mem.h> +#include <kernel/string.h> +#include <stdint.h> + +struct ringbuf { + void *buffer; + void *buf_end; + uint32_t capacity; + uint32_t count; + uint32_t size; + void *head; + void *tail; +}; + +static inline void rb_init(struct ringbuf *rb, uint32_t capacity, uint32_t size) { + rb->buffer = kmalloc(capacity * size); + rb->buf_end = (char*)rb->buffer + (capacity * size); + rb->capacity = capacity; + rb->size = size; + rb->head = rb->buffer; + rb->tail = rb->buffer; +} + +static inline int rb_push_back(struct ringbuf *rb, const void *item, size_t size) { + if (rb->count == rb->capacity) + return -1; + if (size > rb->size) + return -1; + + void *tmp = rb->tail + rb->size; + if (tmp > rb->head + rb->capacity * rb->size) + rb->tail = rb->head; + memcpy(rb->tail, item, size); + rb->tail += rb->size; + rb->count++; + return 0; +} + +static inline void rb_pop_front(struct ringbuf *rb, void *item) { + memcpy(item, rb->tail, rb->size); + rb->tail = (char*)rb->tail + rb->size; + if (rb->tail == rb->buf_end) + rb->tail = rb->buffer; + rb->count--; +} + +#endif diff --git a/include/kernel/io.h b/include/kernel/io.h index 8f5fa59..cf8404a 100644 --- a/include/kernel/io.h +++ b/include/kernel/io.h @@ -1,5 +1,5 @@ -#ifndef IO_H -#define IO_H +#ifndef KERNEL_IO_H +#define KERNEL_IO_H #include <stdarg.h> diff --git a/kernel/io.c b/kernel/io.c index 71b01bd..0a4ba6d 100644 --- a/kernel/io.c +++ b/kernel/io.c @@ -1,6 +1,10 @@ #include <kernel/io.h> +#include <kernel/framebuffer.h> +#include <kernel/data/ringbuf.h> #include <kernel/string.h> -#include <kernel/tty.h> + +static int ringbuf_init = 0; +static struct ringbuf rb; char* convert(unsigned int num, int base) { static char rep[] = "0123456789ABCDEF"; @@ -19,12 +23,18 @@ char* convert(unsigned int num, int base) { } int vkprintf(const char *fmt, va_list args) { + if (ringbuf_init == 0) { + rb_init(&rb, 1024, 4096); + ringbuf_init = 1; + } + char *s; int i; + char buffer[4096]; for (size_t n = 0; n < strlen(fmt); n++) { if (fmt[n] != '%') { - tty_putchar(fmt[n]); + buffer[strlen(buffer)] = fmt[n]; continue; } else { n++; @@ -33,30 +43,32 @@ int vkprintf(const char *fmt, va_list args) { switch (fmt[n]) { case 'c': i = va_arg(args, int); - tty_putchar(i); + buffer[strlen(buffer)] = i; + break; + case 's': + s = va_arg(args, char*); + strcat(buffer, s); break; case 'd': i = va_arg(args, int); if (i < 0) { i = -i; - tty_putchar('-'); + strcat(buffer, "-"); } - tty_writestring(convert(i, 10)); + strcat(buffer, convert(i, 10)); break; case 'o': i = va_arg(args, unsigned int); - tty_writestring(convert(i, 8)); - break; - case 's': - s = va_arg(args, char*); - tty_writestring(s); + strcat(buffer, convert(i, 10)); break; case 'x': i = va_arg(args, unsigned int); - tty_writestring(convert(i, 16)); + strcat(buffer, convert(i, 16)); break; } } + rb_push_back(&rb, buffer, strlen(buffer)); + memset(buffer, 0, 4096); return 0; } |