Add minimal shell, find out that stuff is broken :'(

This commit is contained in:
Robbe Van Herck 2020-01-09 18:32:12 +01:00
parent 41e3953d2c
commit 2a82f01493
No known key found for this signature in database
GPG key ID: A66F76F7B81BD784
4 changed files with 117 additions and 3 deletions

View file

@ -26,10 +26,11 @@ The kernel is based on [the bare bones kernel from the OSDev wiki](https://wiki.
### Features ### Features
- [x] Terminal output (with newlines!) - [x] Terminal output (with newlines!)
- [x] _Very_ basic memory management - [x] _Very_ basic (and probably broken) memory management
- [x] Interrupt handling - [x] Interrupt handling
- [x] Keyboard input - [x] Keyboard input
- [x] Exception handling - [x] Exception handling
- [x] Minimal shell
- [ ] Filesystem interaction - [ ] Filesystem interaction
- [ ] Show files in directory - [ ] Show files in directory
- [ ] Read files in directory - [ ] Read files in directory
@ -37,5 +38,6 @@ The kernel is based on [the bare bones kernel from the OSDev wiki](https://wiki.
- [ ] Tests - [ ] Tests
- [ ] Running executables from filesystem - [ ] Running executables from filesystem
- [ ] Better memory management - [ ] Better memory management
- [ ] Better shell
As a test, I've implemented day 1 of [advent of code](https://adventofcode.com/) on the [AoC branch](https://github.com/Robbe7730/RoBoot/tree/AoC). As a test, I've implemented day 1 of [advent of code](https://adventofcode.com/) on the [AoC branch](https://github.com/Robbe7730/RoBoot/tree/AoC).

View file

@ -15,6 +15,7 @@
#include "terminal.c" #include "terminal.c"
#include "memory.c" #include "memory.c"
#include "interrupts.c" #include "interrupts.c"
#include "shell.c"
static inline bool are_interrupts_enabled() { static inline bool are_interrupts_enabled() {
unsigned long flags; unsigned long flags;
@ -61,7 +62,6 @@ void kernel_main(void)
interrupt_init(); interrupt_init();
for(;;) { for(;;) {
char curr_char = getchar(); shell_step();
terminal_putchar(curr_char);
} }
} }

111
kernel/shell.c Normal file
View file

@ -0,0 +1,111 @@
#ifndef SHELL_C
#define SHELL_C
#define SHELL_CMD_BUFFER_SIZE 128
#include <stddef.h>
#include "terminal.c"
#include "drivers/keyboard/keyboard.c"
char buffer[SHELL_CMD_BUFFER_SIZE];
int buffer_idx = 0;
int echo(char* input) {
terminal_writestring(input);
terminal_putchar('\n');
return 0;
}
int hello(char* unused) {
terminal_writestring("Hello, world!\n");
return 0;
}
int cls(char* unused) {
terminal_initialize();
return 0;
}
int ree(char* unused) {
terminal_initialize();
terminal_putchar('R');
for (int i = 1; i < VGA_WIDTH * VGA_HEIGHT; i++) {
terminal_putchar('e');
}
return 0;
}
int run_command(char* buffer) {
// TODO If I make these 2 global, it breaks...
// TODO This is ugly, fix this
const char* shell_commands_strings[] = {
"echo",
"hello",
"cls",
"ree",
NULL
};
int (*shell_commands_functions[]) (char*) = {
echo,
hello,
cls,
ree
};
if(buffer[0] == 0) {
return 0;
}
char command[SHELL_CMD_BUFFER_SIZE] = {0};
int i = 0;
while (buffer[i] != 0 && buffer[i] != ' ') {
command[i] = buffer[i];
i++;
}
int command_idx = 0;
while(shell_commands_strings[command_idx] != NULL) {
int check_idx = 0;
while(command[check_idx] != 0 && shell_commands_strings[command_idx][check_idx] == command[check_idx]) {
check_idx++;
}
if (command[check_idx] == 0 && shell_commands_strings[command_idx][check_idx] == 0) {
return (shell_commands_functions[command_idx])(buffer + i + 1);
}
command_idx++;
}
return -1;
}
void shell_step() {
char curr_char = getchar();
if (curr_char == '\n') {
terminal_putchar(curr_char);
buffer[buffer_idx] = 0;
int result = run_command(buffer);
for (int i = 0; i < SHELL_CMD_BUFFER_SIZE; i++) {
buffer[i] = 0;
}
buffer_idx = 0;
if (result == -1) {
terminal_writestring("No such command\n");
}
} else if (curr_char == 0x08) {
if (buffer_idx != 0) {
buffer_idx--;
buffer[buffer_idx] = 0;
terminal_putchar(curr_char);
}
} else {
buffer[buffer_idx] = curr_char;
buffer_idx++;
terminal_putchar(curr_char);
}
}
#endif //SHELL_C

View file

@ -77,6 +77,7 @@ void terminal_putchar(char c) {
return; return;
} }
if (c == 0x08) { if (c == 0x08) {
terminal_putentryat(' ', terminal_color, terminal_column, terminal_row);
if (terminal_column == 0) { if (terminal_column == 0) {
if(terminal_row != 0) { if(terminal_row != 0) {
terminal_row--; terminal_row--;