Espresso 0.0.2c
This commit is contained in:
@ -13,11 +13,9 @@ char char_entered = 0x00;
|
||||
|
||||
void intro_begin(void)
|
||||
{
|
||||
extern char* kernel_version;
|
||||
|
||||
char* fin = (char*) malloc(strlen(kernel_version) + 6);
|
||||
memset(fin, 0, (strlen(kernel_version) + 5));
|
||||
strcpy(fin, kernel_version);
|
||||
char* fin = (char*) malloc(strlen(KERNEL_VERSION) + 6);
|
||||
memset(fin, 0, (strlen(KERNEL_VERSION) + 5));
|
||||
strcpy(fin, KERNEL_VERSION);
|
||||
|
||||
#ifdef _DEBUG
|
||||
strcat(fin, " DEBUG");
|
||||
|
||||
@ -16,6 +16,12 @@
|
||||
|
||||
#include <kernel/boot.h>
|
||||
#include <kernel/kshell.h>
|
||||
#include <kernel/syscall.h>
|
||||
|
||||
#include <tty.h>
|
||||
#include <vga/vga.h>
|
||||
|
||||
#include <new_tty.h>
|
||||
|
||||
#include <kdebug.h>
|
||||
|
||||
@ -23,54 +29,41 @@
|
||||
#include <drivers/idt.h>
|
||||
#include <drivers/irq.h>
|
||||
|
||||
#include <scheduler.h>
|
||||
|
||||
#include <multiboot.h>
|
||||
|
||||
#include <drivers/pci.h>
|
||||
#include <drivers/ps2_keyboard.h>
|
||||
#include <drivers/keyboard.h>
|
||||
#include <drivers/pit.h>
|
||||
/*#include <drivers/ahci.h>*/
|
||||
#include <drivers/ide.h>
|
||||
#include <mm/mm.h>
|
||||
#include <fs/fat32.h>
|
||||
#include <fs/duckfs.h>
|
||||
/*#include <fs/duckfs.h>*/
|
||||
#include <fs/vfs.h>
|
||||
#include <fs/sfs.h>
|
||||
|
||||
#ifdef DEBUG_USE_SSE2
|
||||
#include <vector_extensions/sse.h>
|
||||
#endif
|
||||
|
||||
#include <kernel/intro.h>
|
||||
|
||||
#include <builtin_games/miner.h>
|
||||
|
||||
#include <fs/ssfs.h>
|
||||
|
||||
#define DEBUG
|
||||
|
||||
|
||||
extern void _hang_asm(void);
|
||||
extern void _sti_asm(void);
|
||||
|
||||
char* espresso_str = ""
|
||||
"####### ##### ###### ###### ####### ##### ##### #######\n"
|
||||
"# # # # # # # # # # # # # #\n"
|
||||
"# # # # # # # # # # #\n"
|
||||
"##### ##### ###### ###### ##### ##### ##### # #\n"
|
||||
"# # # # # # # # # #\n"
|
||||
"# # # # # # # # # # # # #\n"
|
||||
"####### ##### # # # ####### ##### ##### #######\n";
|
||||
|
||||
char* kernel_version = "0.0.2a";
|
||||
|
||||
|
||||
void kernel_main(multiboot_info_t* mbd, uint32_t magic)
|
||||
{
|
||||
|
||||
{
|
||||
/* --- BEGIN INITIALIZATION SECTION --- */
|
||||
|
||||
/* We need to initialize the terminal so that any error/debugging messages show. */
|
||||
terminal_initialize();
|
||||
|
||||
printf("Loading Espresso %s... ", kernel_version);
|
||||
printf("Loading Espresso %s... ", KERNEL_VERSION);
|
||||
|
||||
#ifdef _DEBUG
|
||||
printf("[ DEBUG BUILD ]");
|
||||
@ -96,12 +89,8 @@ void kernel_main(multiboot_info_t* mbd, uint32_t magic)
|
||||
|
||||
gdt_install(false);
|
||||
|
||||
pic_remap();
|
||||
|
||||
pic_remap(); /* must be done before idt_init() */
|
||||
idt_init();
|
||||
|
||||
_sti_asm();
|
||||
|
||||
irq_init(); /* MUST be done after pic_remap() and idt_init() */
|
||||
|
||||
terminal_setcolor(VGA_COLOR_GREEN);
|
||||
@ -112,44 +101,65 @@ void kernel_main(multiboot_info_t* mbd, uint32_t magic)
|
||||
|
||||
heap_init(0xC2000000, 0x80000);
|
||||
|
||||
#ifdef DEBUG_USE_SSE2
|
||||
#ifdef _DEBUG
|
||||
printd("Testing SSE...\n");
|
||||
#endif
|
||||
int32_t sse_test_result = test_sse();
|
||||
if (sse_test_result != 0)
|
||||
{
|
||||
printf("[ DEBUG ] SSE test failed with RV %d\n", sse_test_result);
|
||||
printf("[ SSE ] SSE test failed with RV %d\n", sse_test_result);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
printd("SSE test passed\n");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
pit_init();
|
||||
|
||||
int j = init_tty();
|
||||
|
||||
if (j != 0)
|
||||
{
|
||||
printwc("[ ERROR ] init_tty failed\n", VGA_COLOR_RED);
|
||||
while (1)
|
||||
{
|
||||
asm volatile ("nop" ::: "memory");
|
||||
}
|
||||
}
|
||||
|
||||
keyboard_init();
|
||||
//keyboard_init();
|
||||
init_keyboard();
|
||||
|
||||
ide_initialize();
|
||||
|
||||
pci_init();
|
||||
|
||||
|
||||
init_sysints();
|
||||
|
||||
/*init_scheduler();*/
|
||||
|
||||
_sti_asm();
|
||||
|
||||
|
||||
/* --- END INITIALIZATION SECTION --- */
|
||||
|
||||
|
||||
|
||||
terminal_setcolor(VGA_COLOR_LIGHT_GREEN);
|
||||
|
||||
printf("Guten tag and welcome to Espresso %s\n", kernel_version);
|
||||
printf("Guten tag and welcome to Espresso %s\n", KERNEL_VERSION);
|
||||
|
||||
sleep(1000);
|
||||
|
||||
intro_begin();
|
||||
|
||||
/*extern void terminal_clear(void);
|
||||
extern void terminal_clear(void);
|
||||
|
||||
terminal_clear();
|
||||
|
||||
kshell_start(1, NULL);*/
|
||||
kshell_start();
|
||||
|
||||
while (true)
|
||||
for(;;) /* Loop infinitely. We only do something when an interrupt/syscall happens now. */
|
||||
{
|
||||
/* Loop infinitely. We only do something when a syscall happens now. */
|
||||
asm volatile("hlt" ::: "memory");
|
||||
}
|
||||
}
|
||||
|
||||
230
kernel/kshell.c
230
kernel/kshell.c
@ -6,6 +6,12 @@
|
||||
#include <kernel/ksh_debug.h>
|
||||
#include <arch/x86/intrin.h>
|
||||
|
||||
#include <drivers/elf.h>
|
||||
|
||||
#include <kernel/syscall.h>
|
||||
|
||||
#include <scheduler.h>
|
||||
|
||||
#include <fs/fat16.h>
|
||||
|
||||
#include <kernel/kshell.h>
|
||||
@ -15,7 +21,7 @@ const char* shell_version = "0.0.2";
|
||||
|
||||
char* prompt = NULL;
|
||||
int command = -1;
|
||||
bool _debug = false;
|
||||
bool _debug = true;
|
||||
|
||||
int execute(void);
|
||||
|
||||
@ -44,18 +50,7 @@ static void print_intro(void)
|
||||
printf("CPU: %s\n", _temp == NULL ? "No info" : _temp);
|
||||
printf("CPU vendor: %s\n", temp_ == NULL ? "No info" : temp_);
|
||||
|
||||
printf("\nCopyright 2025 David J Goeke\n");
|
||||
}
|
||||
|
||||
static void parse_opts(int argc, char** argv)
|
||||
{
|
||||
for (int i = 0; i < argc; i++)
|
||||
{
|
||||
if (strcmp(argv[i], "--color") == 0)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
printf("\nCopyright %s David J Goeke\n", KERNEL_RELEASE_YEAR);
|
||||
}
|
||||
|
||||
static char* commands[] = {
|
||||
@ -76,19 +71,28 @@ static char* commands[] = {
|
||||
|
||||
"printrandom",
|
||||
|
||||
"acm", /* ACcess Memory */
|
||||
|
||||
"testfat16",
|
||||
|
||||
"printc",
|
||||
|
||||
"testscheduler",
|
||||
|
||||
"readfat16",
|
||||
|
||||
"help",
|
||||
|
||||
"exec",
|
||||
|
||||
"int16test",
|
||||
|
||||
NULL,
|
||||
};
|
||||
|
||||
#define NUM_COMMANDS 15 /* Yes, including the NULL */
|
||||
const int NUM_COMMANDS = 19; /* Yes, including the NULL */
|
||||
|
||||
int kshell_start(int argc, char** argv)
|
||||
void kshell_start(void)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
printf("Welcome to the kshell!\n");
|
||||
|
||||
prompt = strdup(">");
|
||||
|
||||
@ -102,7 +106,17 @@ int kshell_start(int argc, char** argv)
|
||||
{
|
||||
printf("%s ", prompt);
|
||||
|
||||
i = gets();
|
||||
/*i = gets();*/
|
||||
int j = 0;
|
||||
i = gets_new(&j);
|
||||
|
||||
if (j == 0)
|
||||
{
|
||||
printf("Error?\n");
|
||||
break;
|
||||
}
|
||||
|
||||
i = strnlstrip(i);
|
||||
|
||||
command = -1;
|
||||
|
||||
@ -165,14 +179,14 @@ int kshell_start(int argc, char** argv)
|
||||
|
||||
} while (1);
|
||||
|
||||
if (i != NULL)
|
||||
if (i)
|
||||
{
|
||||
free(i);
|
||||
}
|
||||
|
||||
printf("Goodbye!\n");
|
||||
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -194,7 +208,7 @@ int kshell_start(int argc, char** argv)
|
||||
|
||||
"printrandom",
|
||||
|
||||
"acm",
|
||||
"testfat16",
|
||||
|
||||
NULL,
|
||||
};
|
||||
@ -321,31 +335,6 @@ int execute(void)
|
||||
break;
|
||||
}
|
||||
case 12: {
|
||||
printf("Enter hexadecimal address to access: ");
|
||||
char* g = gets();
|
||||
|
||||
int val = atoi(g);
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
printf("Improper/Malformed string entered\n");
|
||||
|
||||
break;
|
||||
}
|
||||
else if (val < 0x100000)
|
||||
{
|
||||
printf("Invalid address, must be higher than 0x100000\n");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
int val_ = *((int*) val);
|
||||
|
||||
printf("value at %u: %i\n", val, val_);
|
||||
|
||||
break;
|
||||
}
|
||||
case 13: {
|
||||
int retv = fat16_mount(0);
|
||||
|
||||
if (retv != 0)
|
||||
@ -402,6 +391,151 @@ int execute(void)
|
||||
|
||||
fat16_delete_file(fat_name);
|
||||
|
||||
break;
|
||||
}
|
||||
case 13:
|
||||
{
|
||||
printf("Enter char to print in decimal: ");
|
||||
char* g = gets();
|
||||
|
||||
int val = atoi(g);
|
||||
|
||||
if (*g == '\0')
|
||||
{
|
||||
printf("Empty string entered\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf("%c\n", (char) val);
|
||||
|
||||
break;
|
||||
}
|
||||
case 14:
|
||||
{
|
||||
#if 0
|
||||
void taskA() { while (1) printf("A"); }
|
||||
void taskB() { while (1) printf("B"); }
|
||||
|
||||
create_task(taskA);
|
||||
create_task(taskB);
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
case 15:
|
||||
{
|
||||
char* filename = "t.bin";
|
||||
|
||||
int retv = fat16_mount(0);
|
||||
|
||||
if (retv != 0)
|
||||
{
|
||||
printf("There was an error while mounting volume 0.\n");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Volume 0 mounted successfully.\n");
|
||||
|
||||
char fat_name[12];
|
||||
fat16_file_t file;
|
||||
|
||||
filename_to_83(filename, fat_name);
|
||||
retv = fat16_find_file(fat_name, &file);
|
||||
|
||||
if (retv != 0)
|
||||
{
|
||||
printf("file %s could not be found\n", filename);
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t buffer[256];
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
retv = fat16_read_file(&file, buffer);
|
||||
|
||||
if (retv != 0)
|
||||
{
|
||||
printf("Could not read file s\n", (char*) filename);
|
||||
break;
|
||||
}
|
||||
|
||||
printf("read data: %s\n", (char*) buffer);
|
||||
break;
|
||||
}
|
||||
case 16:
|
||||
{
|
||||
printf("Commands:\n");
|
||||
|
||||
for (int i = 0; i < NUM_COMMANDS; i++)
|
||||
{
|
||||
printf("%s\n", commands[i]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 17:
|
||||
{
|
||||
char* filename = "hello.elf";
|
||||
|
||||
printf("Loading and executing file %s\n", filename);
|
||||
|
||||
int retv = fat16_mount(0);
|
||||
|
||||
if (retv != 0)
|
||||
{
|
||||
printf("There was an error while mounting volume 0.\n");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Volume 0 mounted successfully.\n");
|
||||
|
||||
char fat_name[12];
|
||||
fat16_file_t file;
|
||||
|
||||
filename_to_83(filename, fat_name);
|
||||
retv = fat16_find_file(fat_name, &file);
|
||||
|
||||
if (retv != 0)
|
||||
{
|
||||
printf("file %s could not be found\n", filename);
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t* buffer = malloc(file.size);
|
||||
memset(buffer, 0, file.size);
|
||||
|
||||
retv = fat16_read_file(&file, buffer);
|
||||
|
||||
if (retv != 0)
|
||||
{
|
||||
printf("Could not read file s\n", (char*) filename);
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Parsing ELF headers\n");
|
||||
|
||||
elf_executable_t* f = load_elf32(buffer);
|
||||
|
||||
printf("Attempting execution of executable...\n");
|
||||
|
||||
retv = f->entry_point();
|
||||
|
||||
printf("\nreturn value: %i\n", retv);
|
||||
|
||||
break;
|
||||
}
|
||||
case 18:
|
||||
{
|
||||
printf("testing int 16\n");
|
||||
|
||||
const char* str = "HELLO!\n";
|
||||
|
||||
syscall1(SYS_TERMINAL_WRITESTRING, str);
|
||||
|
||||
printf("test ran\n");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
118
kernel/syscall.c
Normal file
118
kernel/syscall.c
Normal file
@ -0,0 +1,118 @@
|
||||
#include <stdio.h>
|
||||
#include <drivers/irq.h>
|
||||
|
||||
#include <mm/pmm.h>
|
||||
#include <mm/paging.h>
|
||||
|
||||
#include <tty.h>
|
||||
|
||||
#include <drivers/serio.h>
|
||||
|
||||
#include <kernel/syscall.h>
|
||||
|
||||
|
||||
/*
|
||||
Espresso has two types of syscalls.
|
||||
|
||||
one: int 16, the only one I've worked on. should be able to be used in kernel code and user-space.
|
||||
two: syscall/sysenter, the ones I haven't worked on because it has to do with userspace code.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
NOTE: passing arguments to fuctions
|
||||
to pass args to functions, use all registers except eax,
|
||||
so ebx is arg0, ecx arg1, edx arg2, esi arg3, edi arg4, ebp arg5
|
||||
*/
|
||||
|
||||
void init_sysints(void)
|
||||
{
|
||||
/* actually nothing to do */
|
||||
|
||||
set_irq_handler(16, (irq_func_t) int16_handler);
|
||||
}
|
||||
|
||||
/* 0 in eax means success most of the time */
|
||||
registers_t* int16_handler(registers_t* regs)
|
||||
{
|
||||
//printf("eax: %0x%x\n", regs->eax);
|
||||
|
||||
uint32_t eax = regs->eax;
|
||||
|
||||
if (eax >= __ENUM_END_MARKER__)
|
||||
{
|
||||
printf("Invalid system call %i\n", eax);
|
||||
return regs;
|
||||
}
|
||||
|
||||
switch (eax)
|
||||
{
|
||||
case SYS_MAP_PAGE:
|
||||
map_page((void*) regs->ebx, (void*) regs->ecx);
|
||||
break;
|
||||
case SYS_PMM_ALLOC_PAGE:
|
||||
eax = (uint32_t) pmm_alloc_page();
|
||||
break;
|
||||
case SYS_PMM_FREE_PAGE:
|
||||
pmm_free_page((void*) regs->ebx);
|
||||
break;
|
||||
case SYS_SERIAL_WRITE:
|
||||
serial_write(regs->ebx);
|
||||
break;
|
||||
case SYS_SERIAL_READ:
|
||||
eax = serial_read();
|
||||
break;
|
||||
case SYS_SERIAL_PUTS:
|
||||
serial_puts((const char*) regs->ebx);
|
||||
break;
|
||||
case SYS_USE_SERIAL:
|
||||
eax = use_serial();
|
||||
break;
|
||||
case SYS_TERMINAL_SCROLL:
|
||||
terminal_scroll();
|
||||
break;
|
||||
case SYS_TERMINAL_CLEAR:
|
||||
terminal_clear();
|
||||
break;
|
||||
case SYS_TERMINAL_SET_CURSOR:
|
||||
terminal_set_cursor(regs->ebx, regs->ecx);
|
||||
break;
|
||||
case SYS_TERMINAL_GET_CURSOR:
|
||||
terminal_get_cursor((int*) regs->ebx, (int*) regs->ecx);
|
||||
break;
|
||||
case SYS_TERMINAL_WRITE:
|
||||
terminal_write((const char*) regs->ebx, regs->ecx);
|
||||
break;
|
||||
case SYS_TERMINAL_WRITESTRING:
|
||||
terminal_writestring((const char*) regs->ebx);
|
||||
break;
|
||||
case SYS_TERMINAL_DEBUG_WRITESTRING:
|
||||
terminal_debug_writestring((const char*) regs->ebx);
|
||||
break;
|
||||
case SYS_TERMINAL_PUTCHAR:
|
||||
terminal_putchar(regs->ebx);
|
||||
break;
|
||||
case SYS_TERMINAL_PUTENTRYAT:
|
||||
terminal_putentryat(regs->ebx, regs->ecx, regs->edx, regs->esi);
|
||||
break;
|
||||
case SYS_TERMINAL_GETCOLOR:
|
||||
eax = terminal_getcolor();
|
||||
break;
|
||||
case SYS_TERMINAL_SETCOLOR:
|
||||
terminal_setcolor(regs->ebx);
|
||||
break;
|
||||
case SYS_READ:
|
||||
eax = read(regs->ebx, (void*) regs->ecx, regs->edx);
|
||||
break;
|
||||
case SYS_WRITE:
|
||||
eax = write(regs->ebx, (void*) regs->ecx, regs->edx);
|
||||
break;
|
||||
default:
|
||||
printf("nothing happened.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
regs->eax = eax;
|
||||
|
||||
return regs;
|
||||
}
|
||||
Reference in New Issue
Block a user