add extremely wonky kernel shell
This commit is contained in:
parent
2219635e99
commit
2e4b88141f
|
@ -84,7 +84,7 @@ void* keyboard_read() {
|
|||
}
|
||||
|
||||
void* keyboard_write() {
|
||||
return (void*) -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int keyboard_init(void) {
|
||||
|
|
|
@ -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
157
arch/x86_64/prog/shell.c
Normal 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
6
include/kernel.h
Normal 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
17
include/prog/shell.h
Normal 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;
|
||||
};
|
Loading…
Reference in a new issue