From 42455873fffc46606f10a5a33c058f9361291098 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Sun, 30 Aug 2020 18:47:14 -0700 Subject: [PATCH] [kernel] Make stdout channel available to processes The "fake" stdout channel is now being passed in the new j6_process_init structure to processes, and nulldrv now uses it to print a message to the console. --- src/drivers/nulldrv/main.cpp | 16 +++++++++++++++- src/drivers/nulldrv/main.s | 9 ++++++--- src/include/j6/types.h | 7 +++++++ src/kernel/console.cpp | 9 +++++++-- src/kernel/console.h | 2 +- src/kernel/main.cpp | 12 +++++++++--- src/kernel/scheduler.cpp | 13 +++++++++++++ 7 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/drivers/nulldrv/main.cpp b/src/drivers/nulldrv/main.cpp index fdda149..c6aeb32 100644 --- a/src/drivers/nulldrv/main.cpp +++ b/src/drivers/nulldrv/main.cpp @@ -7,11 +7,14 @@ #include -const char message[] = "Hello! This is a message being sent over a channel!"; +const char message[] = "Hello! This is a message being sent over a channel!\n"; char inbuf[1024]; j6_handle_t chan = j6_handle_invalid; +j6_process_init *init = nullptr; + extern "C" { + void _init_libc(j6_process_init *); int main(int, const char **); } @@ -40,6 +43,12 @@ thread_proc() _syscall_thread_exit(0); } +void +_init_libc(j6_process_init *i) +{ + init = i; +} + int main(int argc, const char **argv) { @@ -52,6 +61,11 @@ main(int argc, const char **argv) if (result != j6_status_ok) return result; + size_t size = sizeof(message); + result = _syscall_channel_send(init->output, &size, (void*)message); + if (result != j6_status_ok) + return result; + _syscall_system_log("main thread created channel"); result = _syscall_thread_create(reinterpret_cast(&thread_proc), &child); diff --git a/src/drivers/nulldrv/main.s b/src/drivers/nulldrv/main.s index 5fce330..07ffdfe 100644 --- a/src/drivers/nulldrv/main.s +++ b/src/drivers/nulldrv/main.s @@ -3,19 +3,22 @@ mymessage: resq 1024 extern main +extern _init_libc extern exit section .text global _start _start: - xor rbp, rbp ; Sentinel rbp - push rbp - push rbp mov rbp, rsp + mov rdi, rsp + sub rdi, 8 + call _init_libc + mov rdi, 0 mov rsi, 0 + call main mov rdi, rax diff --git a/src/include/j6/types.h b/src/include/j6/types.h index 9bff9b0..99b679d 100644 --- a/src/include/j6/types.h +++ b/src/include/j6/types.h @@ -20,3 +20,10 @@ typedef uint64_t j6_signal_t; typedef uint64_t j6_rights_t; #define j6_handle_invalid 0xffffffff + +/// A process' initial data structure for communicating with the system +struct j6_process_init +{ + j6_handle_t input; + j6_handle_t output; +}; diff --git a/src/kernel/console.cpp b/src/kernel/console.cpp index 67a322e..cd1b7d1 100644 --- a/src/kernel/console.cpp +++ b/src/kernel/console.cpp @@ -261,11 +261,16 @@ console::set_color(uint8_t fg, uint8_t bg) } } -void +size_t console::puts(const char *message) { - while (message && *message) + size_t n = 0; + while (message && *message) { + n++; putc(*message++); + } + + return n; } void diff --git a/src/kernel/console.h b/src/kernel/console.h index 213bd0d..5014ef1 100644 --- a/src/kernel/console.h +++ b/src/kernel/console.h @@ -16,7 +16,7 @@ public: void set_color(uint8_t fg = 7, uint8_t bg = 0); void putc(char c); - void puts(const char *message); + size_t puts(const char *message); void vprintf(const char *fmt, va_list args); inline void printf(const char *fmt, ...) diff --git a/src/kernel/main.cpp b/src/kernel/main.cpp index 91d0c21..177b390 100644 --- a/src/kernel/main.cpp +++ b/src/kernel/main.cpp @@ -92,7 +92,13 @@ stdout_task() } buffer[n] = 0; - cons->puts(reinterpret_cast(buffer)); + const char *s = reinterpret_cast(buffer); + + while (n) { + size_t r = cons->puts(s); + n -= r + 1; + s += r + 1; + } } } @@ -193,6 +199,8 @@ kernel_main(args::header *header) syscall_enable(); scheduler *sched = new scheduler(devices.get_lapic()); + std_out = new channel; + for (auto &ird : initrds) { for (auto &f : ird.files()) { if (f.executable()) { @@ -203,8 +211,6 @@ kernel_main(args::header *header) } } - std_out = new channel; - sched->create_kernel_task(logger_task, scheduler::max_priority-1, true); sched->create_kernel_task(stdout_task, scheduler::max_priority-1, true); diff --git a/src/kernel/scheduler.cpp b/src/kernel/scheduler.cpp index 921bfbd..c24a22a 100644 --- a/src/kernel/scheduler.cpp +++ b/src/kernel/scheduler.cpp @@ -11,6 +11,7 @@ #include "kernel_memory.h" #include "log.h" #include "msr.h" +#include "objects/channel.h" #include "objects/process.h" #include "page_manager.h" #include "scheduler.h" @@ -18,6 +19,7 @@ #include "elf/elf.h" #include "kutil/assert.h" + scheduler *scheduler::s_instance = nullptr; const uint64_t rflags_noint = 0x002; @@ -69,6 +71,7 @@ load_process_image(const void *image_start, size_t bytes, TCB *tcb) page_manager *pager = page_manager::get(); thread *th = thread::from_tcb(tcb); + process &proc = th->parent(); log::debug(logs::loader, "Loading task! ELF: %016lx [%d]", image_start, bytes); @@ -115,6 +118,16 @@ load_process_image(const void *image_start, size_t bytes, TCB *tcb) kutil::memcpy(dest, src, header->size); } + tcb->rsp3 -= 2 * sizeof(uint64_t); + uint64_t *sentinel = reinterpret_cast(tcb->rsp3); + sentinel[0] = sentinel[1] = 0; + + tcb->rsp3 -= sizeof(j6_process_init); + j6_process_init *init = reinterpret_cast(tcb->rsp3); + + extern channel *std_out; + init->output = proc.add_handle(std_out); + th->clear_state(thread::state::loading); uintptr_t entrypoint = image.entrypoint();