summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordzwdz2021-08-11 15:57:21 +0000
committerdzwdz2021-08-11 15:57:21 +0000
commita32374156ea2cf129b413fa017d7e52e59570c04 (patch)
tree0d191308425e6bf376d539b4b77e9485b1cf8722 /src
parent0dbd5803e14d72b45ddae17e25bdd84308410f9a (diff)
read _syscall_debuglog arguments across page boundaries
Diffstat (limited to 'src')
-rw-r--r--src/init/main.c16
-rw-r--r--src/kernel/syscalls.c26
2 files changed, 28 insertions, 14 deletions
diff --git a/src/init/main.c b/src/init/main.c
index 5615980..89f964f 100644
--- a/src/init/main.c
+++ b/src/init/main.c
@@ -1,13 +1,15 @@
#include <kernel/syscalls.h>
-int main() {
- _syscall_debuglog("hello from init! ",
- sizeof("hello from init! ") - 1);
-
- _syscall_fork();
+#define STR_64 "This string has exactly 64 characters. It'll be repeated a bunch"
+#define STR_256 STR_64 STR_64 STR_64 STR_64
+#define STR_1K STR_256 STR_256 STR_256 STR_256
+#define STR_4K STR_1K STR_1K STR_1K STR_1K
+#define STR_LNG "start " STR_4K STR_4K " finished! "
- _syscall_debuglog("i got forked. ",
- sizeof("i got forked. ") - 1);
+int main() {
+ // try to print a string which is longer than a page
+ _syscall_debuglog(STR_LNG,
+ sizeof(STR_LNG) - 1);
_syscall_exit("bye from init! ",
sizeof("bye from init! ") - 1);
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 47f8b2b..7234e10 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -23,15 +23,27 @@ int _syscall_fork() {
int _syscall_debuglog(const char *msg, size_t len) {
struct pagedir *pages = process_current->pages;
- void *phys = pagedir_virt2phys(pages, msg, true, false);
+ size_t remaining = len;
- // page overrun check
- if (((uintptr_t)msg & PAGE_MASK) + len > PAGE_SIZE)
- len = PAGE_SIZE - ((uintptr_t)msg & PAGE_MASK);
- if (((uintptr_t)msg & PAGE_MASK) + len > PAGE_SIZE)
- panic(); // just in case I made an off by 1 error
+ while (remaining > 0) {
+ /* note: While i'm pretty sure that this should always work, this
+ * was only tested in cases where the pages were consecutive both in
+ * virtual and physical memory, which might not always be the case.
+ * TODO test this */
+
+ void *phys = pagedir_virt2phys(pages, msg, true, false);
+ size_t partial = remaining;
+
+ // don't read past the page
+ if (((uintptr_t)msg & PAGE_MASK) + remaining > PAGE_SIZE)
+ partial = PAGE_SIZE - ((uintptr_t)msg & PAGE_MASK);
+
+ tty_write(phys, partial);
+
+ remaining -= partial;
+ msg += partial;
+ }
- tty_write(phys, len);
return len;
}