From 33713a805a6a6416b4574560c98087437ad9c21b Mon Sep 17 00:00:00 2001 From: antifallobst Date: Sun, 30 Apr 2023 17:25:53 +0200 Subject: [PATCH] feature (TTY): made tty easy linkable with process stdio/pipes --- inc/drivers/tty.h | 16 ++++++++-------- inc/proc/pipe.h | 3 ++- src/boot/kmain.c | 11 +++++++++++ src/drivers/ps2/keyboard.c | 20 ++++++++------------ src/drivers/tty.c | 33 +++++++++++---------------------- src/proc/pipe.c | 14 +++++++++++--- src/proc/process.c | 4 ++-- 7 files changed, 53 insertions(+), 48 deletions(-) diff --git a/inc/drivers/tty.h b/inc/drivers/tty.h index 00ebd40..b9b2ae8 100644 --- a/inc/drivers/tty.h +++ b/inc/drivers/tty.h @@ -5,22 +5,22 @@ #include "drivers/graphics/renderer.h" #include "utils/stream.h" - -#define TTY_STD_STREAM_SIZE 0x800 // 2048 bytes +#include "proc/pipe.h" typedef struct { graphics_buffer_T* graphics_buffer; - stream_T* stream; + pipe_T* output; + pipe_T input; position_T cursor; color_argb_T color; } tty_T; void tty_init (); -tty_T* tty_get_active (); -tty_T* tty_alloc (uint32_t stream_size); -void tty_destruct (tty_T* tty); -void tty_update (tty_T* tty); -uint32_t tty_write (tty_T* tty, string_t string); +tty_T* tty_alloc (); +void tty_update (); +uint32_t tty_write (string_t string); + +extern tty_T* g_tty; #endif //NOXOS_TTY_H diff --git a/inc/proc/pipe.h b/inc/proc/pipe.h index 4c58284..f2f2473 100644 --- a/inc/proc/pipe.h +++ b/inc/proc/pipe.h @@ -18,9 +18,10 @@ typedef struct { process_T* receiver; process_T* senders [PIPE_MAX_SENDERS]; bitmap_T senders_bitmap; + void (*on_write)(); } pipe_T; -void pipe_init (pipe_T* pipe, process_T* receiver); +void pipe_init (pipe_T* pipe, process_T* receiver, void (*on_write)()); void pipe_destruct (pipe_T* pipe); bool pipe_add_sender (pipe_T* pipe, process_T* sender); void pipe_remove_sender (pipe_T* pipe, process_T* sender); diff --git a/src/boot/kmain.c b/src/boot/kmain.c index 229ef90..09bf724 100644 --- a/src/boot/kmain.c +++ b/src/boot/kmain.c @@ -64,5 +64,16 @@ void kmain(boot_info_T boot_info) { log(LOG_INFO, "!=====[ Kernel Initialized ]=====!\n"); + void* buffer = vfs_resolve_path(&g_root_fs, "/initrd/test.elf")->cache->buffer; + elf_executable_T* exec = elf_executable_create(buffer); + pid_t proc = process_spawn(PROCESS_KERNEL, "shell", exec, buffer); + + process_T* process = scheduler_get_process(proc); + + g_tty->output = &process->stdin; + process->stdout = &g_tty->input; + + thread_start(thread_spawn(proc, symbol_resolve_from_name(exec->symbols, exec->num_symbols, "_start")->address + MEM_REGION_PROCESS_EXEC)); + CORE_HALT_FOREVER } diff --git a/src/drivers/ps2/keyboard.c b/src/drivers/ps2/keyboard.c index 92db0a8..7f699f3 100644 --- a/src/drivers/ps2/keyboard.c +++ b/src/drivers/ps2/keyboard.c @@ -42,7 +42,7 @@ void ps2_keyboard_init() { void ps2_keyboard_read() { uint8_t scancode = ps2_controller_read_data(); - char chr; + char chr [2]; chr[1] = '\0'; if (extended_key) { extended_key = false; @@ -89,17 +89,17 @@ void ps2_keyboard_read() { } case PS2_SCANCODE_SET_1_BACKSPACE: { - chr = '\b'; + chr[0] = '\b'; break; } case PS2_SCANCODE_SET_1_SPACE: { - chr = ' '; + chr[0] = ' '; break; } case PS2_SCANCODE_SET_1_RETURN: { - chr = '\n'; + chr[0] = '\n'; break; } @@ -111,20 +111,16 @@ void ps2_keyboard_read() { } default: { - chr = scancode_set_1[scancode]; + chr[0] = scancode_set_1[scancode]; if (shift_enabled) { - if (string_is_char_lowercase(chr)) chr -= 32; - else if (string_is_char_uppercase(chr)) chr += 32; + if (string_is_char_lowercase(chr[0])) chr[0] -= 32; + else if (string_is_char_uppercase(chr[0])) chr[0] += 32; } break; } } - char buffer[2]; - buffer[0] = chr; - buffer[1] = '\0'; - - tty_write(tty_get_active(), buffer); + tty_write(chr); } string_t ps2_keyboard_command_to_string(ps2_keyboard_command_E command) { diff --git a/src/drivers/tty.c b/src/drivers/tty.c index 68dc86b..8a24c82 100644 --- a/src/drivers/tty.c +++ b/src/drivers/tty.c @@ -7,48 +7,37 @@ tty_T* g_tty; void tty_init() { - g_tty = tty_alloc(TTY_STD_STREAM_SIZE); + g_tty = tty_alloc(); } -tty_T* tty_get_active() { - return g_tty; -} - -tty_T* tty_alloc(uint32_t stream_size) { +tty_T* tty_alloc() { tty_T* tty = memory_allocate(sizeof(tty_T)); tty->graphics_buffer = graphics_buffer_request(0, 0, graphics_renderer_get_width(), graphics_renderer_get_height(), GRAPHICS_BUFFER_STANDARD); - tty->stream = stream_alloc(stream_size); tty->cursor.x = 0; tty->cursor.y = 0; tty->color = g_color_palette[COLOR_PAL_GREY_LIGHT]; + tty->output = NULL; + pipe_init(&tty->input, NULL, tty_update); return tty; } -void tty_destruct(tty_T* tty) { - graphics_buffer_destruct(tty->graphics_buffer); - stream_destruct(tty->stream); - - memory_free(tty); -} - -void tty_update(tty_T* tty) { +void tty_update() { char buffer[256]; uint32_t read_bytes = 255; while (read_bytes == 255) { - read_bytes = stream_read(tty->stream, buffer, 255); + read_bytes = pipe_read(&g_tty->input, buffer, 255); buffer[read_bytes] = '\0'; - tty->cursor = graphics_buffer_draw_string(tty->graphics_buffer, tty->cursor.x, tty->cursor.y, tty->color, buffer); + g_tty->cursor = graphics_buffer_draw_string(g_tty->graphics_buffer, g_tty->cursor.x, g_tty->cursor.y, g_tty->color, buffer); } graphics_renderer_update(); } -uint32_t tty_write(tty_T* tty, string_t string) { - uint32_t num = stream_write(tty->stream, (void*)string, string_length(string)); +uint32_t tty_write(string_t string) { + pipe_write(g_tty->output, string, string_length(string)); - tty_update(tty); - - return num; + g_tty->cursor = graphics_buffer_draw_string(g_tty->graphics_buffer, g_tty->cursor.x, g_tty->cursor.y, g_tty->color, string); + graphics_renderer_update(); } \ No newline at end of file diff --git a/src/proc/pipe.c b/src/proc/pipe.c index e4ab751..e97b6bb 100644 --- a/src/proc/pipe.c +++ b/src/proc/pipe.c @@ -3,10 +3,11 @@ #include "proc/pipe.h" #include "proc/process.h" -void pipe_init(pipe_T* pipe, process_T* receiver) { +void pipe_init(pipe_T* pipe, process_T* receiver, void (*on_write)()) { pipe->stream = stream_alloc(PIPE_STD_STREAM_SIZE); pipe->receiver = receiver; pipe->senders_bitmap = bitmap_init(PIPE_MAX_SENDERS); + pipe->on_write = on_write; } void pipe_destruct(pipe_T* pipe) { @@ -38,9 +39,10 @@ void pipe_remove_sender(pipe_T* pipe, process_T* sender) { } uint64_t pipe_write(pipe_T* pipe, void* buffer_in, uint64_t n) { + if (pipe == NULL) return 0; uint64_t written_bytes = stream_write(pipe->stream, buffer_in, n); - if (bitmap_get(&pipe->receiver->waiting, PROCESS_BLOCK_WAIT_PIPE_IN)) { + if (pipe->receiver != NULL && bitmap_get(&pipe->receiver->waiting, PROCESS_BLOCK_WAIT_PIPE_IN)) { bitmap_set(&pipe->receiver->waiting, PROCESS_BLOCK_WAIT_PIPE_IN, false); process_start(pipe->receiver); } @@ -54,10 +56,16 @@ uint64_t pipe_write(pipe_T* pipe, void* buffer_in, uint64_t n) { } } + if (pipe->on_write != NULL) { + pipe->on_write(); + } + return written_bytes; } uint64_t pipe_read(pipe_T* pipe, void* buffer_out, uint64_t n) { + if (pipe == NULL) return 0; + uint64_t read_bytes = stream_read(pipe->stream, buffer_out, n); for (int i = 0; i < PIPE_MAX_SENDERS; i++) { @@ -68,7 +76,7 @@ uint64_t pipe_read(pipe_T* pipe, void* buffer_out, uint64_t n) { process_start(pipe->senders[i]); } - if (read_bytes < n) { + if (pipe->receiver != NULL && read_bytes < n) { bitmap_set(&pipe->receiver->waiting, PROCESS_BLOCK_WAIT_PIPE_IN, true); process_pause(pipe->receiver); } diff --git a/src/proc/process.c b/src/proc/process.c index a20503d..70a2165 100644 --- a/src/proc/process.c +++ b/src/proc/process.c @@ -17,7 +17,7 @@ void process_kernel_spawn(elf_executable_T* executable) { process->stderr = NULL; process->waiting = bitmap_init(PROCESS_BLOCK_ENUM_SIZE); - pipe_init(&process->stdin, process); + pipe_init(&process->stdin, process, NULL); memory_copy("kernel", process->name, 7); process->page_map = g_kernel_page_map; @@ -40,7 +40,7 @@ pid_t process_spawn(pid_t parent, string_t name, elf_executable_T* executable, v process->stderr = NULL; process->waiting = bitmap_init(PROCESS_BLOCK_ENUM_SIZE); - pipe_init(&process->stdin, process); + pipe_init(&process->stdin, process, NULL); memory_copy(name, process->name, MIN(string_length(name), 127)); process->page_map = page_map_create();