add extremely wonky kernel shell

This commit is contained in:
hippoz 2021-08-24 20:56:50 +03:00
parent 2219635e99
commit 2e4b88141f
Signed by untrusted user who does not match committer: hippoz
GPG key ID: 7C52899193467641
5 changed files with 197 additions and 67 deletions

View file

@ -84,7 +84,7 @@ void* keyboard_read() {
}
void* keyboard_write() {
return (void*) -1;
return -1;
}
int keyboard_init(void) {

View file

@ -1,5 +1,4 @@
#include <types.h>
#include <stivale2.h>
#include <std/inline.h>
#include <std/util.h>
@ -7,6 +6,7 @@
#include <std/stdio.h>
#include <drivers/idt/isr.h>
#include <drivers/keyboard/keyboard.h>
#include <prog/shell.h>
#include <drivers/pic/pic.h>
#include <drivers/device/device.h>
#include <drivers/ide/ide.h>
@ -14,10 +14,9 @@
#include <psf.h>
#include <paging.h>
#include <mem/mem.h>
#include <kernel.h>
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;
}

157
arch/x86_64/prog/shell.c Normal file
View file

@ -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));
}

6
include/kernel.h Normal file
View file

@ -0,0 +1,6 @@
#pragma once
#include "types.h"
u64 get_total_memory();
bool is_using_framebuffer();

17
include/prog/shell.h Normal file
View file

@ -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;
};