diff --git a/arch/x86_64/drivers/keyboard/keyboard.c b/arch/x86_64/drivers/keyboard/keyboard.c index 1c1a1ad..e08d8c9 100644 --- a/arch/x86_64/drivers/keyboard/keyboard.c +++ b/arch/x86_64/drivers/keyboard/keyboard.c @@ -84,7 +84,7 @@ void* keyboard_read() { } void* keyboard_write() { - return (void*) -1; + return -1; } int keyboard_init(void) { diff --git a/arch/x86_64/kernel.c b/arch/x86_64/kernel.c index aac8846..7b4fbb9 100644 --- a/arch/x86_64/kernel.c +++ b/arch/x86_64/kernel.c @@ -1,5 +1,4 @@ #include - #include #include #include @@ -7,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -14,10 +14,9 @@ #include #include #include - +#include static u8 stack[16384]; -bool is_running = true; int keyboard_descriptor = 0; int terminal_descriptor = 0; @@ -88,11 +87,8 @@ framebuffer_t *framebuffer; extern usize _kernel_start; extern usize _kernel_end; - -struct test_struct { - unsigned int something; - int hello; -}; +u64 total_memory; +bool using_framebuffer = false; void _start(struct stivale2_struct *stivale2_struct) { struct stivale2_struct_tag_framebuffer *tag_fb = stivale2_get_tag(stivale2_struct, STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID); @@ -113,11 +109,11 @@ void _start(struct stivale2_struct *stivale2_struct) { framebuffer->pixelwidth = tag_fb->framebuffer_bpp / 8; terminal_descriptor = terminal_initialize(framebuffer); + using_framebuffer = true; printf("Terminal initialized, descriptor: %d\n", terminal_descriptor); - printf("Framebuffer | addr: %#lX, width: %d, height: %d, depth: %d, pitch: %d\n", (usize)framebuffer->address, framebuffer->width, framebuffer->height, framebuffer->depth, framebuffer->pitch); - u64 total_memory, largest_usable_base, largest_usable_size; + u64 largest_usable_base, largest_usable_size; for (u64 i = 0; i < tag_mmap->entries; i++) { struct stivale2_mmap_entry entry = tag_mmap->memmap[i]; char *entry_name; @@ -142,75 +138,29 @@ void _start(struct stivale2_struct *stivale2_struct) { printf("Memory map entry | name: %s, base: %#lX, length: %ld KiB\n", entry_name, entry.base, entry.length / 1024); } printf("Total memory: %ld KiB\n", total_memory / 1024); - //printf("\"\"\"Used\"\"\" memory: %ld B\n", (_kernel_end - _kernel_start)); printf("Memory map entry chosen for memory manager | base: %#lX, length: %ld KiB\n", largest_usable_base, largest_usable_size / 1024); mem_populate_blocks(largest_usable_base); - if (mem_test_mm()) { - printf("memory manager test passed\n"); - } - printf("Preparing interrupts... "); pic_init(); isr_install(); printf("done\n"); - /* - printf("Preparing IDE driver... \n"); - printf("Searching for IDE devices... \n"); - ide_init(); - */ - fillrect(framebuffer, 750, 550, 25, 25, 0x00FFD5FF); keyboard_descriptor = keyboard_init(); printf("Keyboard ready, descriptor: %d\n", keyboard_descriptor); - printf("Are interrupts enabled? "); - if (are_interrupts_enabled() == 1) { - printf("yes\n"); - } else { - printf("no\n"); - } - usize start_mem_addr = (usize)_start; printf("_start memory address: %#lX\n", start_mem_addr); - printf("----------\n"); - printf("hello yes"); - - while (is_running) { - printf("\n> "); - - while (true) { - usize scancode = (usize)read(keyboard_descriptor, NULL); - if (!scancode) continue; - - bool special = true; - bool finished = false; - - switch (scancode) { - case 72: - terminal_row--; - break; - case 75: - terminal_column--; - break; - case 77: - terminal_column++; - break; - case 80: - terminal_row++; - break; - case 0x1C: - finished = true; - break; - default: - special = false; - } - - if (finished) break; - if (!special) putchar(keyboard_get_key_from_scancode(scancode)); - terminal_updatecursor(); - } - } + shell_register_basic_commands(); + shell_start(keyboard_descriptor); +} + +bool is_using_framebuffer() { + return using_framebuffer; +} + +u64 get_total_memory() { + return total_memory; } diff --git a/arch/x86_64/prog/shell.c b/arch/x86_64/prog/shell.c new file mode 100644 index 0000000..2f29c7e --- /dev/null +++ b/arch/x86_64/prog/shell.c @@ -0,0 +1,157 @@ +#include "drivers/device/device.h" +#include "drivers/keyboard/keyboard.h" +#include "drivers/terminal/terminal.h" +#include "prog/shell.h" +#include "mem/mem.h" +#include "types.h" +#include "std/stdio.h" +#include "std/string.h" +#include "kernel.h" + +bool shell_running = false; + +struct registered_command *registered_commands[COMMAND_REGISTER_SIZE]; +int registered_commands_index = 0; + +char shell_buf[SHELL_BUFFER_SIZE]; +int shell_buf_index = 0; + +void shell_start(int kbfd) +{ + printf("hhhos kernel shell\n"); + shell_running = true; + while (shell_running) + { + printf("\n& "); + + while (true) + { + usize scancode = (usize)read(kbfd, NULL); + if (!scancode) + continue; + + bool special = true; + bool finished = false; + + switch (scancode) + { + case 72: + terminal_row--; + break; + case 75: + terminal_column--; + break; + case 77: + terminal_column++; + break; + case 80: + terminal_row++; + break; + case 0x1C: + finished = true; + break; + default: + special = false; + } + + if (finished) + { + char cmd_name_buffer[64]; + int i; + for (i = 0; i < shell_buf_index; i++) + { + if (shell_buf[i] == ' ' || shell_buf[i] == '\0') + break; + cmd_name_buffer[i] = shell_buf[i]; + } + cmd_name_buffer[i + 1] = '\0'; + if (!shell_handle_command(cmd_name_buffer, shell_buf)) + { + printf("\nshell: no such registered command %s", cmd_name_buffer); + }; + shell_buf_index = 0; + break; + } + if (!special) + { + if (shell_buf_index < SHELL_BUFFER_SIZE) + { + const unsigned char key = keyboard_get_key_from_scancode(scancode); + shell_buf[shell_buf_index] = key; + terminal_putchar(key); + shell_buf_index++; + } + else + { + printf("shell: buffer overflow (i = %d)\n", shell_buf_index); + break; + } + } + terminal_updatecursor(); + } + } +} + +void shell_stop() +{ + for (int i = 0; i < registered_commands_index; i++) + { + free(registered_commands[i]); + } + registered_commands_index = 0; + shell_buf_index = 0; + + shell_running = false; +} + +void shell_register_command_handler(const char *command, int fd_handler) +{ + struct registered_command *reg = (struct registered_command *)malloc(sizeof(struct registered_command)); + reg->command = command; + reg->fd_handler = fd_handler; + registered_commands[registered_commands_index] = reg; + registered_commands_index++; +} + +int shell_handle_command(const char *command, const char *args) +{ + /* find the command handler */ + for (int i = 0; i < registered_commands_index; i++) + { + struct registered_command *reg = (struct registered_command *)registered_commands[i]; + if (!memcmp(reg->command, command, strlen(command))) + { + struct command_run_packet *packet = (struct command_run_packet *)malloc(sizeof(struct command_run_packet)); + packet->args = args; + /* communicate the arguments and other parameters to the command handler by writing to its file descriptor */ + write(reg->fd_handler, packet); + free(packet); + return 1; + } + } + /* we didn't find anything :( */ + return 0; +} + +void shell_register_basic_commands() +{ + void *dummy_read(void *unused) + { + return -1; + } + + void *fishfetch_write(void *unused) + { + printf("\n<>< OS: hhhos\n"); + printf(" SHELL: hhhos kernel shell compatible\n"); + printf(" DISPLAY: %s\n", (is_using_framebuffer()) ? "Framebuffer" : "Other"); + printf(" TOTAL MEMORY: %ld KiB\n", get_total_memory() / 1024); + } + + struct device fishfetch_device = { + write : &fishfetch_write, + read : &dummy_read + }; + + shell_register_command_handler("fishfetch", push_device(fishfetch_device)); +} diff --git a/include/kernel.h b/include/kernel.h new file mode 100644 index 0000000..2700de5 --- /dev/null +++ b/include/kernel.h @@ -0,0 +1,6 @@ +#pragma once + +#include "types.h" + +u64 get_total_memory(); +bool is_using_framebuffer(); diff --git a/include/prog/shell.h b/include/prog/shell.h new file mode 100644 index 0000000..1429930 --- /dev/null +++ b/include/prog/shell.h @@ -0,0 +1,17 @@ +#pragma once + +#define COMMAND_REGISTER_SIZE 128 +#define SHELL_BUFFER_SIZE 1024 + +void shell_start(int kbfd); +void shell_register_basic_commands(); +void shell_register_command_handler(const char *command, int fd_handler); + +struct registered_command { + const char* command; + int fd_handler; +}; + +struct command_run_packet { + const char* args; +};