Move print stuff to its own file
diff --git a/src/drivers/disk.c b/src/drivers/disk.c
index 5621e50f..d3303090 100644
--- a/src/drivers/disk.c
+++ b/src/drivers/disk.c
@@ -5,6 +5,7 @@
#include <lib/real.h>
#include <lib/blib.h>
#include <lib/part.h>
+#include <lib/print.h>
#define SECTOR_SIZE 512
#define BLOCK_SIZE_IN_SECTORS 16
diff --git a/src/drivers/vbe.c b/src/drivers/vbe.c
index 31ca8d54..9dceb5dc 100644
--- a/src/drivers/vbe.c
+++ b/src/drivers/vbe.c
@@ -3,6 +3,7 @@
#include <drivers/vbe.h>
#include <lib/blib.h>
#include <lib/real.h>
+#include <lib/print.h>
struct vbe_info_struct {
char signature[4];
diff --git a/src/fs/echfs.c b/src/fs/echfs.c
index bc9c79ea..b9f1af9e 100644
--- a/src/fs/echfs.c
+++ b/src/fs/echfs.c
@@ -2,6 +2,7 @@
#include <stdint.h>
#include <lib/libc.h>
#include <lib/blib.h>
+#include <lib/print.h>
#include <drivers/disk.h>
#include <stdbool.h>
diff --git a/src/fs/fat32.c b/src/fs/fat32.c
index 7a5f2c36..6ee619b0 100644
--- a/src/fs/fat32.c
+++ b/src/fs/fat32.c
@@ -2,6 +2,7 @@
#include <lib/blib.h>
#include <drivers/disk.h>
#include <lib/libc.h>
+#include <lib/print.h>
#include <stdbool.h>
#define FAT32_LFN_MAX_ENTRIES 20
diff --git a/src/lib/acpi.c b/src/lib/acpi.c
index b6e771cd..cdd2f03c 100644
--- a/src/lib/acpi.c
+++ b/src/lib/acpi.c
@@ -2,6 +2,7 @@
#include <lib/acpi.h>
#include <lib/blib.h>
#include <lib/libc.h>
+#include <lib/print.h>
void *get_rsdp(void) {
for (size_t i = 0x80000; i < 0x100000; i += 16) {
diff --git a/src/lib/blib.c b/src/lib/blib.c
index 742eecf5..ecda51f0 100644
--- a/src/lib/blib.c
+++ b/src/lib/blib.c
@@ -8,12 +8,16 @@
#include <lib/real.h>
#include <lib/cio.h>
#include <lib/e820.h>
+#include <lib/print.h>
// Checks if a given memory range is entirely within a usable e820 entry.
// TODO: Consider the possibility of adjacent usable entries.
// TODO: Consider the possibility of usable entry being overlapped by non-usable
// ones.
void is_valid_memory_range(size_t base, size_t size) {
+ // We don't allow loads below 1MB
+ if (base < 0x100000)
+ panic("Trying to overwrite bootloader.");
for (size_t i = 0; i < e820_entries; i++) {
if (e820_map[i].type != 1)
continue;
@@ -294,183 +298,3 @@ void gets(const char *orig_str, char *buf, size_t limit) {
}
}
}
-
-static const char *base_digits = "0123456789abcdef";
-
-#define PRINT_BUF_MAX 512
-
-static void prn_str(char *print_buf, size_t *print_buf_i, const char *string) {
- size_t i;
-
- for (i = 0; string[i]; i++) {
- if (*print_buf_i == (PRINT_BUF_MAX - 1))
- break;
- print_buf[(*print_buf_i)++] = string[i];
- }
-
- print_buf[*print_buf_i] = 0;
-
- return;
-}
-
-static void prn_nstr(char *print_buf, size_t *print_buf_i, const char *string, size_t len) {
- size_t i;
-
- for (i = 0; i < len; i++) {
- if (*print_buf_i == (PRINT_BUF_MAX - 1))
- break;
- print_buf[(*print_buf_i)++] = string[i];
- }
-
- print_buf[*print_buf_i] = 0;
-
- return;
-}
-
-static void prn_char(char *print_buf, size_t *print_buf_i, char c) {
- if (*print_buf_i < (PRINT_BUF_MAX - 1)) {
- print_buf[(*print_buf_i)++] = c;
- }
-
- print_buf[*print_buf_i] = 0;
-
- return;
-}
-
-static void prn_i(char *print_buf, size_t *print_buf_i, int64_t x) {
- int i;
- char buf[20] = {0};
-
- if (!x) {
- prn_char(print_buf, print_buf_i, '0');
- return;
- }
-
- int sign = x < 0;
- if (sign) x = -x;
-
- for (i = 18; x; i--) {
- buf[i] = (x % 10) + 0x30;
- x = x / 10;
- }
- if (sign)
- buf[i] = '-';
- else
- i++;
-
- prn_str(print_buf, print_buf_i, buf + i);
-
- return;
-}
-
-static void prn_ui(char *print_buf, size_t *print_buf_i, uint64_t x) {
- int i;
- char buf[21] = {0};
-
- if (!x) {
- prn_char(print_buf, print_buf_i, '0');
- return;
- }
-
- for (i = 19; x; i--) {
- buf[i] = (x % 10) + 0x30;
- x = x / 10;
- }
-
- i++;
- prn_str(print_buf, print_buf_i, buf + i);
-
- return;
-}
-
-static void prn_x(char *print_buf, size_t *print_buf_i, uint64_t x) {
- int i;
- char buf[17] = {0};
-
- if (!x) {
- prn_str(print_buf, print_buf_i, "0x0");
- return;
- }
-
- for (i = 15; x; i--) {
- buf[i] = base_digits[(x % 16)];
- x = x / 16;
- }
-
- i++;
- prn_str(print_buf, print_buf_i, "0x");
- prn_str(print_buf, print_buf_i, buf + i);
-
- return;
-}
-
-void print(const char *fmt, ...) {
- va_list args;
-
- va_start(args, fmt);
-
- char print_buf[PRINT_BUF_MAX];
- size_t print_buf_i = 0;
-
- for (;;) {
- while (*fmt && *fmt != '%')
- prn_char(print_buf, &print_buf_i, *fmt++);
-
- if (!*fmt++)
- goto out;
-
- switch (*fmt++) {
- case 's': {
- char *str = (char *)va_arg(args, const char *);
- if (!str)
- prn_str(print_buf, &print_buf_i, "(null)");
- else
- prn_str(print_buf, &print_buf_i, str); }
- break;
- case 'S': {
- char *str = (char *)va_arg(args, const char *);
- size_t str_len = va_arg(args, size_t);
- if (!str)
- prn_str(print_buf, &print_buf_i, "(null)");
- else
- prn_nstr(print_buf, &print_buf_i, str, str_len); }
- break;
- case 'd':
- prn_i(print_buf, &print_buf_i, (int64_t)va_arg(args, int32_t));
- break;
- case 'u':
- prn_ui(print_buf, &print_buf_i, (uint64_t)va_arg(args, uint32_t));
- break;
- case 'x':
- prn_x(print_buf, &print_buf_i, (uint64_t)va_arg(args, uint32_t));
- break;
- case 'D':
- prn_i(print_buf, &print_buf_i, va_arg(args, int64_t));
- break;
- case 'U':
- prn_ui(print_buf, &print_buf_i, va_arg(args, uint64_t));
- break;
- case 'X':
- prn_x(print_buf, &print_buf_i, va_arg(args, uint64_t));
- break;
- case 'c': {
- char c = (char)va_arg(args, int);
- prn_char(print_buf, &print_buf_i, c); }
- break;
- default:
- prn_char(print_buf, &print_buf_i, '?');
- break;
- }
- }
-
-out:
- va_end(args);
- text_write(print_buf, print_buf_i);
-
-#ifdef E9_OUTPUT
- for (size_t i = 0; i < print_buf_i; i++)
- port_out_b(0xe9, print_buf[i]);
-#endif
-
- return;
-}
diff --git a/src/lib/blib.h b/src/lib/blib.h
index 4fbcbb02..6e5ce6e5 100644
--- a/src/lib/blib.h
+++ b/src/lib/blib.h
@@ -25,7 +25,6 @@ void *balloc_aligned(size_t count, size_t alignment);
#define GETCHAR_CURSOR_UP (-12)
#define GETCHAR_CURSOR_DOWN (-13)
-void print(const char *fmt, ...);
int getchar(void);
void gets(const char *orig_str, char *buf, size_t limit);
uint64_t strtoui(const char *s);
diff --git a/src/lib/e820.c b/src/lib/e820.c
index aaea8570..6648e5e2 100644
--- a/src/lib/e820.c
+++ b/src/lib/e820.c
@@ -3,6 +3,7 @@
#include <lib/e820.h>
#include <lib/real.h>
#include <lib/blib.h>
+#include <lib/print.h>
struct e820_entry_t *e820_map;
size_t e820_entries;
diff --git a/src/lib/elf.c b/src/lib/elf.c
index 71742545..8e4375f4 100644
--- a/src/lib/elf.c
+++ b/src/lib/elf.c
@@ -3,6 +3,7 @@
#include <lib/blib.h>
#include <lib/libc.h>
#include <lib/elf.h>
+#include <lib/print.h>
#include <fs/file.h>
#define PT_LOAD 0x00000001
diff --git a/src/lib/print.c b/src/lib/print.c
new file mode 100644
index 00000000..773e5c47
--- /dev/null
+++ b/src/lib/print.c
@@ -0,0 +1,177 @@
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <lib/print.h>
+#include <lib/blib.h>
+#include <drivers/vga_textmode.h>
+
+static const char *base_digits = "0123456789abcdef";
+
+#define PRINT_BUF_MAX 512
+
+static void prn_str(char *print_buf, size_t *print_buf_i, const char *string) {
+ size_t i;
+
+ for (i = 0; string[i]; i++) {
+ if (*print_buf_i == (PRINT_BUF_MAX - 1))
+ break;
+ print_buf[(*print_buf_i)++] = string[i];
+ }
+
+ print_buf[*print_buf_i] = 0;
+}
+
+static void prn_nstr(char *print_buf, size_t *print_buf_i, const char *string, size_t len) {
+ size_t i;
+
+ for (i = 0; i < len; i++) {
+ if (*print_buf_i == (PRINT_BUF_MAX - 1))
+ break;
+ print_buf[(*print_buf_i)++] = string[i];
+ }
+
+ print_buf[*print_buf_i] = 0;
+}
+
+static void prn_char(char *print_buf, size_t *print_buf_i, char c) {
+ if (*print_buf_i < (PRINT_BUF_MAX - 1)) {
+ print_buf[(*print_buf_i)++] = c;
+ }
+
+ print_buf[*print_buf_i] = 0;
+}
+
+static void prn_i(char *print_buf, size_t *print_buf_i, int64_t x) {
+ int i;
+ char buf[20] = {0};
+
+ if (!x) {
+ prn_char(print_buf, print_buf_i, '0');
+ return;
+ }
+
+ int sign = x < 0;
+ if (sign) x = -x;
+
+ for (i = 18; x; i--) {
+ buf[i] = (x % 10) + 0x30;
+ x = x / 10;
+ }
+ if (sign)
+ buf[i] = '-';
+ else
+ i++;
+
+ prn_str(print_buf, print_buf_i, buf + i);
+}
+
+static void prn_ui(char *print_buf, size_t *print_buf_i, uint64_t x) {
+ int i;
+ char buf[21] = {0};
+
+ if (!x) {
+ prn_char(print_buf, print_buf_i, '0');
+ return;
+ }
+
+ for (i = 19; x; i--) {
+ buf[i] = (x % 10) + 0x30;
+ x = x / 10;
+ }
+
+ i++;
+ prn_str(print_buf, print_buf_i, buf + i);
+}
+
+static void prn_x(char *print_buf, size_t *print_buf_i, uint64_t x) {
+ int i;
+ char buf[17] = {0};
+
+ if (!x) {
+ prn_str(print_buf, print_buf_i, "0x0");
+ return;
+ }
+
+ for (i = 15; x; i--) {
+ buf[i] = base_digits[(x % 16)];
+ x = x / 16;
+ }
+
+ i++;
+ prn_str(print_buf, print_buf_i, "0x");
+ prn_str(print_buf, print_buf_i, buf + i);
+}
+
+void print(const char *fmt, ...) {
+ va_list args;
+
+ va_start(args, fmt);
+ vprint(fmt, args);
+ va_end(args);
+}
+
+void vprint(const char *fmt, va_list args) {
+ char *print_buf = balloc(PRINT_BUF_MAX);
+ size_t print_buf_i = 0;
+
+ for (;;) {
+ while (*fmt && *fmt != '%')
+ prn_char(print_buf, &print_buf_i, *fmt++);
+
+ if (!*fmt++)
+ goto out;
+
+ switch (*fmt++) {
+ case 's': {
+ char *str = (char *)va_arg(args, const char *);
+ if (!str)
+ prn_str(print_buf, &print_buf_i, "(null)");
+ else
+ prn_str(print_buf, &print_buf_i, str); }
+ break;
+ case 'S': {
+ char *str = (char *)va_arg(args, const char *);
+ size_t str_len = va_arg(args, size_t);
+ if (!str)
+ prn_str(print_buf, &print_buf_i, "(null)");
+ else
+ prn_nstr(print_buf, &print_buf_i, str, str_len); }
+ break;
+ case 'd':
+ prn_i(print_buf, &print_buf_i, (int64_t)va_arg(args, int32_t));
+ break;
+ case 'u':
+ prn_ui(print_buf, &print_buf_i, (uint64_t)va_arg(args, uint32_t));
+ break;
+ case 'x':
+ prn_x(print_buf, &print_buf_i, (uint64_t)va_arg(args, uint32_t));
+ break;
+ case 'D':
+ prn_i(print_buf, &print_buf_i, va_arg(args, int64_t));
+ break;
+ case 'U':
+ prn_ui(print_buf, &print_buf_i, va_arg(args, uint64_t));
+ break;
+ case 'X':
+ prn_x(print_buf, &print_buf_i, va_arg(args, uint64_t));
+ break;
+ case 'c': {
+ char c = (char)va_arg(args, int);
+ prn_char(print_buf, &print_buf_i, c); }
+ break;
+ default:
+ prn_char(print_buf, &print_buf_i, '?');
+ break;
+ }
+ }
+
+out:
+ text_write(print_buf, print_buf_i);
+
+#ifdef E9_OUTPUT
+ for (size_t i = 0; i < print_buf_i; i++)
+ port_out_b(0xe9, print_buf[i]);
+#endif
+
+ brewind(PRINT_BUF_MAX);
+}
diff --git a/src/lib/print.h b/src/lib/print.h
new file mode 100644
index 00000000..fad90a86
--- /dev/null
+++ b/src/lib/print.h
@@ -0,0 +1,9 @@
+#ifndef __LIB__PRINT_H__
+#define __LIB__PRINT_H__
+
+#include <stdarg.h>
+
+void print(const char *fmt, ...);
+void vprint(const char *fmt, va_list args);
+
+#endif
diff --git a/src/main.c b/src/main.c
index a04f2157..7807463a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -21,6 +21,7 @@ asm (
#include <lib/part.h>
#include <lib/config.h>
#include <lib/e820.h>
+#include <lib/print.h>
#include <fs/file.h>
#include <lib/elf.h>
#include <protos/stivale.h>
diff --git a/src/protos/linux.c b/src/protos/linux.c
index e55713f3..d7344bce 100644
--- a/src/protos/linux.c
+++ b/src/protos/linux.c
@@ -6,6 +6,7 @@
#include <lib/real.h>
#include <drivers/vga_textmode.h>
#include <lib/config.h>
+#include <lib/print.h>
#define KERNEL_LOAD_ADDR ((size_t)0x100000)
#define INITRD_LOAD_ADDR ((size_t)0x1000000)
diff --git a/src/protos/stivale.c b/src/protos/stivale.c
index 5e1609ac..1886f34e 100644
--- a/src/protos/stivale.c
+++ b/src/protos/stivale.c
@@ -8,6 +8,7 @@
#include <lib/e820.h>
#include <lib/config.h>
#include <lib/time.h>
+#include <lib/print.h>
#include <drivers/vbe.h>
#include <drivers/vga_textmode.h>
#include <fs/file.h>
