Espresso 0.0.2c

This commit is contained in:
2026-03-20 16:57:08 -05:00
parent 021fdbbcef
commit 5971218b56
77 changed files with 4538 additions and 518 deletions

View File

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

View File

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

View File

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