feature (TTY): made tty easy linkable with process stdio/pipes
This commit is contained in:
parent
328d48e381
commit
33713a805a
|
@ -5,22 +5,22 @@
|
||||||
|
|
||||||
#include "drivers/graphics/renderer.h"
|
#include "drivers/graphics/renderer.h"
|
||||||
#include "utils/stream.h"
|
#include "utils/stream.h"
|
||||||
|
#include "proc/pipe.h"
|
||||||
#define TTY_STD_STREAM_SIZE 0x800 // 2048 bytes
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
graphics_buffer_T* graphics_buffer;
|
graphics_buffer_T* graphics_buffer;
|
||||||
stream_T* stream;
|
pipe_T* output;
|
||||||
|
pipe_T input;
|
||||||
position_T cursor;
|
position_T cursor;
|
||||||
color_argb_T color;
|
color_argb_T color;
|
||||||
} tty_T;
|
} tty_T;
|
||||||
|
|
||||||
void tty_init ();
|
void tty_init ();
|
||||||
tty_T* tty_get_active ();
|
|
||||||
|
|
||||||
tty_T* tty_alloc (uint32_t stream_size);
|
tty_T* tty_alloc ();
|
||||||
void tty_destruct (tty_T* tty);
|
void tty_update ();
|
||||||
void tty_update (tty_T* tty);
|
uint32_t tty_write (string_t string);
|
||||||
uint32_t tty_write (tty_T* tty, string_t string);
|
|
||||||
|
extern tty_T* g_tty;
|
||||||
|
|
||||||
#endif //NOXOS_TTY_H
|
#endif //NOXOS_TTY_H
|
||||||
|
|
|
@ -18,9 +18,10 @@ typedef struct {
|
||||||
process_T* receiver;
|
process_T* receiver;
|
||||||
process_T* senders [PIPE_MAX_SENDERS];
|
process_T* senders [PIPE_MAX_SENDERS];
|
||||||
bitmap_T senders_bitmap;
|
bitmap_T senders_bitmap;
|
||||||
|
void (*on_write)();
|
||||||
} pipe_T;
|
} 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);
|
void pipe_destruct (pipe_T* pipe);
|
||||||
bool pipe_add_sender (pipe_T* pipe, process_T* sender);
|
bool pipe_add_sender (pipe_T* pipe, process_T* sender);
|
||||||
void pipe_remove_sender (pipe_T* pipe, process_T* sender);
|
void pipe_remove_sender (pipe_T* pipe, process_T* sender);
|
||||||
|
|
|
@ -64,5 +64,16 @@ void kmain(boot_info_T boot_info) {
|
||||||
|
|
||||||
log(LOG_INFO, "!=====[ Kernel Initialized ]=====!\n");
|
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
|
CORE_HALT_FOREVER
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ void ps2_keyboard_init() {
|
||||||
|
|
||||||
void ps2_keyboard_read() {
|
void ps2_keyboard_read() {
|
||||||
uint8_t scancode = ps2_controller_read_data();
|
uint8_t scancode = ps2_controller_read_data();
|
||||||
char chr;
|
char chr [2]; chr[1] = '\0';
|
||||||
|
|
||||||
if (extended_key) {
|
if (extended_key) {
|
||||||
extended_key = false;
|
extended_key = false;
|
||||||
|
@ -89,17 +89,17 @@ void ps2_keyboard_read() {
|
||||||
}
|
}
|
||||||
|
|
||||||
case PS2_SCANCODE_SET_1_BACKSPACE: {
|
case PS2_SCANCODE_SET_1_BACKSPACE: {
|
||||||
chr = '\b';
|
chr[0] = '\b';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case PS2_SCANCODE_SET_1_SPACE: {
|
case PS2_SCANCODE_SET_1_SPACE: {
|
||||||
chr = ' ';
|
chr[0] = ' ';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case PS2_SCANCODE_SET_1_RETURN: {
|
case PS2_SCANCODE_SET_1_RETURN: {
|
||||||
chr = '\n';
|
chr[0] = '\n';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,20 +111,16 @@ void ps2_keyboard_read() {
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
chr = scancode_set_1[scancode];
|
chr[0] = scancode_set_1[scancode];
|
||||||
if (shift_enabled) {
|
if (shift_enabled) {
|
||||||
if (string_is_char_lowercase(chr)) chr -= 32;
|
if (string_is_char_lowercase(chr[0])) chr[0] -= 32;
|
||||||
else if (string_is_char_uppercase(chr)) chr += 32;
|
else if (string_is_char_uppercase(chr[0])) chr[0] += 32;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char buffer[2];
|
tty_write(chr);
|
||||||
buffer[0] = chr;
|
|
||||||
buffer[1] = '\0';
|
|
||||||
|
|
||||||
tty_write(tty_get_active(), buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string_t ps2_keyboard_command_to_string(ps2_keyboard_command_E command) {
|
string_t ps2_keyboard_command_to_string(ps2_keyboard_command_E command) {
|
||||||
|
|
|
@ -7,48 +7,37 @@
|
||||||
tty_T* g_tty;
|
tty_T* g_tty;
|
||||||
|
|
||||||
void tty_init() {
|
void tty_init() {
|
||||||
g_tty = tty_alloc(TTY_STD_STREAM_SIZE);
|
g_tty = tty_alloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
tty_T* tty_get_active() {
|
tty_T* tty_alloc() {
|
||||||
return g_tty;
|
|
||||||
}
|
|
||||||
|
|
||||||
tty_T* tty_alloc(uint32_t stream_size) {
|
|
||||||
tty_T* tty = memory_allocate(sizeof(tty_T));
|
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->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.x = 0;
|
||||||
tty->cursor.y = 0;
|
tty->cursor.y = 0;
|
||||||
tty->color = g_color_palette[COLOR_PAL_GREY_LIGHT];
|
tty->color = g_color_palette[COLOR_PAL_GREY_LIGHT];
|
||||||
|
tty->output = NULL;
|
||||||
|
pipe_init(&tty->input, NULL, tty_update);
|
||||||
|
|
||||||
return tty;
|
return tty;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tty_destruct(tty_T* tty) {
|
void tty_update() {
|
||||||
graphics_buffer_destruct(tty->graphics_buffer);
|
|
||||||
stream_destruct(tty->stream);
|
|
||||||
|
|
||||||
memory_free(tty);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tty_update(tty_T* tty) {
|
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
uint32_t read_bytes = 255;
|
uint32_t read_bytes = 255;
|
||||||
while (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';
|
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();
|
graphics_renderer_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t tty_write(tty_T* tty, string_t string) {
|
uint32_t tty_write(string_t string) {
|
||||||
uint32_t num = stream_write(tty->stream, (void*)string, string_length(string));
|
pipe_write(g_tty->output, string, string_length(string));
|
||||||
|
|
||||||
tty_update(tty);
|
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();
|
||||||
return num;
|
|
||||||
}
|
}
|
|
@ -3,10 +3,11 @@
|
||||||
#include "proc/pipe.h"
|
#include "proc/pipe.h"
|
||||||
#include "proc/process.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->stream = stream_alloc(PIPE_STD_STREAM_SIZE);
|
||||||
pipe->receiver = receiver;
|
pipe->receiver = receiver;
|
||||||
pipe->senders_bitmap = bitmap_init(PIPE_MAX_SENDERS);
|
pipe->senders_bitmap = bitmap_init(PIPE_MAX_SENDERS);
|
||||||
|
pipe->on_write = on_write;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pipe_destruct(pipe_T* pipe) {
|
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) {
|
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);
|
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);
|
bitmap_set(&pipe->receiver->waiting, PROCESS_BLOCK_WAIT_PIPE_IN, false);
|
||||||
process_start(pipe->receiver);
|
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;
|
return written_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t pipe_read(pipe_T* pipe, void* buffer_out, uint64_t n) {
|
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);
|
uint64_t read_bytes = stream_read(pipe->stream, buffer_out, n);
|
||||||
|
|
||||||
for (int i = 0; i < PIPE_MAX_SENDERS; i++) {
|
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]);
|
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);
|
bitmap_set(&pipe->receiver->waiting, PROCESS_BLOCK_WAIT_PIPE_IN, true);
|
||||||
process_pause(pipe->receiver);
|
process_pause(pipe->receiver);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ void process_kernel_spawn(elf_executable_T* executable) {
|
||||||
process->stderr = NULL;
|
process->stderr = NULL;
|
||||||
process->waiting = bitmap_init(PROCESS_BLOCK_ENUM_SIZE);
|
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);
|
memory_copy("kernel", process->name, 7);
|
||||||
|
|
||||||
process->page_map = g_kernel_page_map;
|
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->stderr = NULL;
|
||||||
process->waiting = bitmap_init(PROCESS_BLOCK_ENUM_SIZE);
|
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));
|
memory_copy(name, process->name, MIN(string_length(name), 127));
|
||||||
|
|
||||||
process->page_map = page_map_create();
|
process->page_map = page_map_create();
|
||||||
|
|
Loading…
Reference in New Issue