Add minimal shell, find out that stuff is broken :'(
This commit is contained in:
parent
41e3953d2c
commit
2a82f01493
4 changed files with 117 additions and 3 deletions
|
@ -26,10 +26,11 @@ The kernel is based on [the bare bones kernel from the OSDev wiki](https://wiki.
|
|||
### Features
|
||||
|
||||
- [x] Terminal output (with newlines!)
|
||||
- [x] _Very_ basic memory management
|
||||
- [x] _Very_ basic (and probably broken) memory management
|
||||
- [x] Interrupt handling
|
||||
- [x] Keyboard input
|
||||
- [x] Exception handling
|
||||
- [x] Minimal shell
|
||||
- [ ] Filesystem interaction
|
||||
- [ ] Show 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
|
||||
- [ ] Running executables from filesystem
|
||||
- [ ] 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).
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "terminal.c"
|
||||
#include "memory.c"
|
||||
#include "interrupts.c"
|
||||
#include "shell.c"
|
||||
|
||||
static inline bool are_interrupts_enabled() {
|
||||
unsigned long flags;
|
||||
|
@ -61,7 +62,6 @@ void kernel_main(void)
|
|||
interrupt_init();
|
||||
|
||||
for(;;) {
|
||||
char curr_char = getchar();
|
||||
terminal_putchar(curr_char);
|
||||
shell_step();
|
||||
}
|
||||
}
|
111
kernel/shell.c
Normal file
111
kernel/shell.c
Normal 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
|
|
@ -77,6 +77,7 @@ void terminal_putchar(char c) {
|
|||
return;
|
||||
}
|
||||
if (c == 0x08) {
|
||||
terminal_putentryat(' ', terminal_color, terminal_column, terminal_row);
|
||||
if (terminal_column == 0) {
|
||||
if(terminal_row != 0) {
|
||||
terminal_row--;
|
||||
|
|
Loading…
Reference in a new issue