kernel: various changes.
+ kernel: replace sk-hello test executable with a test initramfs + panic: start implementing a proper kernel panic screen + lib: added a new string.h library for string manipulation. + kernel: replace all the strlen implementations with the strlen() function
This commit is contained in:
parent
7fb04f134b
commit
a838d99a5a
19 changed files with 173 additions and 149 deletions
|
@ -1,28 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
// btw fuck sun
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define VNODE_TYPE_FILE 0
|
||||
#define VNODE_TYPE_DIR 1
|
||||
#define VNODE_TYPE_DEV 2
|
||||
|
||||
typedef struct __vnode {
|
||||
char name[128];
|
||||
int type;
|
||||
|
||||
struct __vnode *children;
|
||||
struct __vnode *next;
|
||||
struct __vnode *parent;
|
||||
|
||||
void (*write)(void *buffer, uint64_t off, uint64_t size);
|
||||
void (*read)(void *buffer, uint64_t off, uint64_t size);
|
||||
} vnode;
|
||||
|
||||
typedef struct __vfs_mount {
|
||||
struct vfs_node
|
||||
*mount_point; // The directory in the main VFS where this is mounted
|
||||
struct vfs_node *mounted_root; // The root node of the mounted filesystem
|
||||
struct vfs_mount *next; // Pointer to next mount point
|
||||
} vfs_mount;
|
57
kernel/src/lib/string.c
Normal file
57
kernel/src/lib/string.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include <lib/string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
int strlen(const char *str) {
|
||||
int len = 0;
|
||||
while (str[len])
|
||||
len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
int strcmp(const char *s1, const char *s2) {
|
||||
while (*s1 && *s1 == *s2) {
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return *s1 - *s2;
|
||||
}
|
||||
|
||||
char *strcpy(char *dest, const char *src)
|
||||
{
|
||||
if (dest == NULL || src == NULL)
|
||||
return NULL;
|
||||
|
||||
char *temp = dest;
|
||||
while((*dest++ = *src++) != '\0');
|
||||
return temp;
|
||||
}
|
||||
|
||||
char *strchr(const char *s, int c) {
|
||||
while (*s++) {
|
||||
if (*s == c)
|
||||
return (char *)s;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *strrchr(const char *s, int c) {
|
||||
const char *p = NULL;
|
||||
|
||||
for (;;) {
|
||||
if (*s == (char)c)
|
||||
p = s;
|
||||
if (*s++ == '\0')
|
||||
return (char *)p;
|
||||
}
|
||||
}
|
||||
|
||||
int oct2bin(unsigned char *str, int size) {
|
||||
int n = 0;
|
||||
unsigned char *c = str;
|
||||
while (size-- > 0) {
|
||||
n *= 8;
|
||||
n += *c - '0';
|
||||
c++;
|
||||
}
|
||||
return n;
|
||||
}
|
8
kernel/src/lib/string.h
Normal file
8
kernel/src/lib/string.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
int strlen(const char *str);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
char *strchr(const char *s, int c);
|
||||
char *strcpy(char *dest, const char *src);
|
||||
char *strrchr(const char *s, int c);
|
||||
int oct2bin(unsigned char *str, int size);
|
|
@ -1,5 +1,7 @@
|
|||
#include "exec/elf.h"
|
||||
#include "exec/exec.h"
|
||||
#include "fs/tapefs.h"
|
||||
#include "fs/vfs.h"
|
||||
#include "mm/liballoc/liballoc.h"
|
||||
#include "mm/pmm.h"
|
||||
#include "mm/vma.h"
|
||||
|
@ -11,29 +13,22 @@
|
|||
#include "sys/syscall.h"
|
||||
#include <font.h>
|
||||
#include <limine.h>
|
||||
#include <mm/memop.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/arch/x86_64/fpu.h>
|
||||
#include <sys/arch/x86_64/gdt.h>
|
||||
#include <sys/arch/x86_64/idt.h>
|
||||
#include <sys/error_handling/panic.h>
|
||||
#include <sys/gfx/flanterm/backends/fb.h>
|
||||
#include <sys/gfx/flanterm/flanterm.h>
|
||||
#include <sys/log.h>
|
||||
#include <sys/printf.h>
|
||||
|
||||
// Set the base revision to 3, this is recommended as this is the latest
|
||||
// base revision described by the Limine boot protocol specification.
|
||||
// See specification for further info.
|
||||
|
||||
__attribute__((
|
||||
used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3);
|
||||
|
||||
// The Limine requests can be placed anywhere, but it is important that
|
||||
// the compiler does not optimise them away, so, usually, they should
|
||||
// be made volatile or equivalent, _and_ they should be accessed at least
|
||||
// once or marked as used with the "used" attribute as done here.
|
||||
|
||||
__attribute__((
|
||||
used,
|
||||
section(
|
||||
|
@ -45,14 +40,6 @@ __attribute__((
|
|||
section(".limine_requests"))) static volatile struct limine_module_request
|
||||
module_request = {.id = LIMINE_MODULE_REQUEST, .revision = 0};
|
||||
|
||||
/*__attribute__((used, section(".limine_requests")))
|
||||
static volatile struct limine_entry_point_request entrypoint_request = {
|
||||
.id = LIMINE_ENTRY_POINT_REQUEST,
|
||||
.revision = 3
|
||||
};*/
|
||||
// Finally, define the start and end markers for the Limine requests.
|
||||
// These can also be moved anywhere, to any .c file, as seen fit.
|
||||
|
||||
__attribute__((used,
|
||||
section(".limine_requests_"
|
||||
"start"))) static volatile LIMINE_REQUESTS_START_MARKER;
|
||||
|
@ -62,38 +49,14 @@ __attribute__((
|
|||
section(
|
||||
".limine_requests_end"))) static volatile LIMINE_REQUESTS_END_MARKER;
|
||||
|
||||
// Halt and catch fire function.
|
||||
static void hcf(void) {
|
||||
for (;;) {
|
||||
#if defined(__x86_64__)
|
||||
asm("hlt");
|
||||
#elif defined(__aarch64__) || defined(__riscv)
|
||||
asm("wfi");
|
||||
#elif defined(__loongarch64)
|
||||
asm("idle 0");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
struct limine_framebuffer *fb;
|
||||
struct flanterm_context *ft_ctx;
|
||||
uint32_t fg = 0xFFFFFF;
|
||||
|
||||
char kstack[8192];
|
||||
|
||||
// The following will be our kernel's entry point.
|
||||
// If renaming kmain() to something else, make sure to change the
|
||||
// linker script accordingly.
|
||||
void kmain(void) {
|
||||
// Ensure the bootloader actually understands our base revision (see spec).
|
||||
/*if (LIMINE_BASE_REVISION_SUPPORTED == false) {
|
||||
hcf();
|
||||
}*/
|
||||
|
||||
// Ensure we got a framebuffer.
|
||||
if (framebuffer_request.response != NULL) {
|
||||
|
||||
// Fetch the first framebuffer.
|
||||
struct limine_framebuffer *framebuffer =
|
||||
framebuffer_request.response->framebuffers[0];
|
||||
fb = framebuffer;
|
||||
|
@ -103,12 +66,11 @@ void kmain(void) {
|
|||
framebuffer->height, framebuffer->pitch, framebuffer->red_mask_size,
|
||||
framebuffer->red_mask_shift, framebuffer->green_mask_size,
|
||||
framebuffer->green_mask_shift, framebuffer->blue_mask_size,
|
||||
framebuffer->blue_mask_shift, NULL, NULL, NULL, NULL, &fg, NULL, NULL,
|
||||
framebuffer->blue_mask_shift, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
VGA8, 8, 16, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
printf("\n Soaplin 1.0-sild is booting up your computer...\n\n");
|
||||
// printf("Physical kernel EP: %p", entrypoint_request.entry);
|
||||
|
||||
gdt_init(&kstack[8192]);
|
||||
idt_init();
|
||||
|
@ -125,21 +87,13 @@ void kmain(void) {
|
|||
asm("hlt");
|
||||
}
|
||||
|
||||
// acpi_init();
|
||||
syscall_init();
|
||||
pit_init(1000);
|
||||
sched_init();
|
||||
// user_init();
|
||||
|
||||
struct limine_file *f = module_request.response->modules[0];
|
||||
log("kmain - %s\n", f->path);
|
||||
|
||||
program_t *prog = elf_load((char *)f->address, 1);
|
||||
|
||||
sched_create("Init", prog->entry, prog->pm, SCHED_USER_PROCESS);
|
||||
|
||||
log("kernel - Soaplin initialized sucessfully.\n");
|
||||
|
||||
while (1)
|
||||
;
|
||||
; //__asm__ volatile ("hlt");
|
||||
;
|
||||
}
|
||||
|
|
|
@ -211,8 +211,8 @@ void vmm_map_user(pagemap_t *pm, uint64_t vaddr, uint64_t paddr,
|
|||
uint64_t pml2_entry = (vaddr >> 21) & 0x1ff;
|
||||
uint64_t pml1_entry = (vaddr >> 12) & 0x1ff;
|
||||
|
||||
|
||||
uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, flags | VMM_WRITABLE,
|
||||
uint64_t *pml3 =
|
||||
__vmm_get_next_lvl(pm->toplevel, pml4_entry, flags | VMM_WRITABLE,
|
||||
true); // PML3 / Page Directory Pointer Entry
|
||||
uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, flags | VMM_WRITABLE,
|
||||
true); // PML2 / Page Directory Entry
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "mm/vmm.h"
|
||||
#include "sys/arch/x86_64/idt.h"
|
||||
#include "sys/log.h"
|
||||
#include <lib/string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
sched_process *proc_list;
|
||||
|
@ -47,16 +48,11 @@ void sched_init() {
|
|||
|
||||
sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm,
|
||||
uint32_t flags) {
|
||||
// TODO: implement a separate strlen function
|
||||
// as there's like 4 strlen impls in the kernel.
|
||||
int i = 0;
|
||||
while (name[i] != 0)
|
||||
i++;
|
||||
|
||||
sched_process *proc = pmm_request_page();
|
||||
memset(proc, 0, sizeof(sched_process));
|
||||
|
||||
memcpy(proc->name, name, i);
|
||||
memcpy(proc->name, name, strlen(name) > 128 ? 128 : strlen(name));
|
||||
proc->pid = current_pid;
|
||||
proc->type = SCHED_RUNNING;
|
||||
proc->flags = flags;
|
||||
|
@ -141,7 +137,6 @@ void schedule(registers_t *regs) {
|
|||
|
||||
prev_proc->next = curr_proc->next;
|
||||
|
||||
// Now, it is safe to free the process's memory.
|
||||
vmm_release_pm(curr_proc->pm);
|
||||
pmm_free_page(curr_proc->stack_base_physical);
|
||||
|
||||
|
@ -155,15 +150,7 @@ void schedule(registers_t *regs) {
|
|||
if (curr_proc == NULL)
|
||||
curr_proc = proc_list;
|
||||
|
||||
//log("sched - I choosed process %d\n", curr_proc->pid);
|
||||
|
||||
//log("sched - I choosed process %d (pm: %s, rip: %p)\n", curr_proc->pid, curr_proc->pm == vmm_kernel_pm ? "kernel" : "user", curr_proc->regs.rip);
|
||||
memcpy(regs, &curr_proc->regs, sizeof(registers_t));
|
||||
|
||||
// Finally, load our pagemap
|
||||
// if (memcmp(curr_proc->name, "Init", 4)== 0) {
|
||||
vmm_load_pagemap(curr_proc->pm);
|
||||
// asm("cli");
|
||||
// while (1)
|
||||
// asm("hlt");}
|
||||
}
|
|
@ -1,5 +1,3 @@
|
|||
// #include "mm/pmm.h"
|
||||
// #include "mm/vmm.h"
|
||||
#include "mm/pmm.h"
|
||||
#include "mm/vmm.h"
|
||||
#include "sched/sched.h"
|
||||
|
@ -7,39 +5,20 @@
|
|||
#include "sys/arch/x86_64/rtc.h"
|
||||
#include "sys/log.h"
|
||||
#include "sys/syscall.h"
|
||||
// #include "sys/sched.h"
|
||||
#include <stdint.h>
|
||||
#include <sys/arch/x86_64/idt.h>
|
||||
#include <sys/arch/x86_64/io.h>
|
||||
// #include <sys/errhand/panic.h>
|
||||
|
||||
int pit_millis = 0;
|
||||
int pit_secs = 0;
|
||||
extern int vmm_kernel_pm_exists;
|
||||
|
||||
struct Idt_StackFrame {
|
||||
struct Idt_StackFrame *rbp;
|
||||
uint64_t rip;
|
||||
} __attribute__((packed));
|
||||
|
||||
void dump_backtrace(registers_t *r) {
|
||||
log("ints - backtrace : \n");
|
||||
struct Idt_StackFrame *frame = (struct Idt_StackFrame *)r->rbp;
|
||||
|
||||
while (frame) {
|
||||
log("ints - %s (ip: %p)\n", frame->rip);
|
||||
frame = frame->rbp;
|
||||
}
|
||||
log("ints - <end of backtrace>\n");
|
||||
}
|
||||
|
||||
void pit_handler(registers_t *regs);
|
||||
|
||||
void exception_handler(registers_t *regs) {
|
||||
vmm_load_pagemap(vmm_kernel_pm);
|
||||
|
||||
if (regs->int_no < 32) {
|
||||
// panic(kmode_cpu_exception, regs);
|
||||
log("ints - %d (RIP: %p, ERR: %d)\n", regs->int_no, regs->rip,
|
||||
regs->err_code);
|
||||
|
||||
|
@ -53,7 +32,6 @@ void exception_handler(registers_t *regs) {
|
|||
log("ints - PF: Faulting page map: %p\n", PHYSICAL(vmm_current_pm));
|
||||
}
|
||||
|
||||
// dump_backtrace(regs);
|
||||
asm("cli");
|
||||
while (1)
|
||||
asm("hlt");
|
||||
|
@ -73,7 +51,6 @@ void exception_handler(registers_t *regs) {
|
|||
} else if (regs->int_no == 0x80) {
|
||||
syscall_handle(regs);
|
||||
}
|
||||
// logln(info, "arch/ints", "Received interrupt %d\n", regs->int_no);
|
||||
//vmm_load_pagemap(curr_proc->pm);
|
||||
|
||||
pic_ack(regs->int_no - 32);
|
||||
}
|
|
@ -1 +1,75 @@
|
|||
void panic_ctx() {}
|
||||
#include "sys/arch/x86_64/idt.h"
|
||||
#include <sys/log.h>
|
||||
|
||||
static registers_t __panic_regdump;
|
||||
|
||||
static void __panic_dump_regs() {
|
||||
asm volatile(
|
||||
// Save general purpose registers
|
||||
"movq %%r15, %0\n\t"
|
||||
"movq %%r14, %1\n\t"
|
||||
"movq %%r13, %2\n\t"
|
||||
"movq %%r12, %3\n\t"
|
||||
"movq %%r11, %4\n\t"
|
||||
"movq %%r10, %5\n\t"
|
||||
"movq %%r9, %6\n\t"
|
||||
"movq %%r8, %7\n\t"
|
||||
"movq %%rdi, %8\n\t"
|
||||
"movq %%rsi, %9\n\t"
|
||||
"movq %%rbp, %10\n\t"
|
||||
"movq %%rbx, %11\n\t"
|
||||
"movq %%rdx, %12\n\t"
|
||||
"movq %%rcx, %13\n\t"
|
||||
"movq %%rax, %14\n\t"
|
||||
|
||||
// The rest of the registers (rip, cs, rflags, rsp, ss) would typically
|
||||
// be captured in the interrupt/exception handler context and passed in
|
||||
// We'll zero them out here since we don't have direct access
|
||||
: "=m"(__panic_regdump.r15), "=m"(__panic_regdump.r14),
|
||||
"=m"(__panic_regdump.r13), "=m"(__panic_regdump.r12),
|
||||
"=m"(__panic_regdump.r11), "=m"(__panic_regdump.r10),
|
||||
"=m"(__panic_regdump.r9), "=m"(__panic_regdump.r8),
|
||||
"=m"(__panic_regdump.rdi), "=m"(__panic_regdump.rsi),
|
||||
"=m"(__panic_regdump.rbp), "=m"(__panic_regdump.rbx),
|
||||
"=m"(__panic_regdump.rdx), "=m"(__panic_regdump.rcx),
|
||||
"=m"(__panic_regdump.rax)
|
||||
:
|
||||
: "memory");
|
||||
|
||||
// Zero out the registers we can't directly access in this context
|
||||
__panic_regdump.int_no = 0;
|
||||
__panic_regdump.err_code = 0;
|
||||
__panic_regdump.rip = 0;
|
||||
__panic_regdump.cs = 0;
|
||||
__panic_regdump.rflags = 0;
|
||||
__panic_regdump.rsp = 0;
|
||||
__panic_regdump.ss = 0;
|
||||
}
|
||||
|
||||
void panic() {
|
||||
__panic_dump_regs();
|
||||
|
||||
log(" _ __ _ ___ _ \n");
|
||||
log("| |/ /___ _ _ _ _ ___| | | _ \\__ _ _ _ (_)__ \n");
|
||||
log("| ' </ -_) '_| ' \\/ -_) | | _/ _` | ' \\| / _|_ _ _ \n");
|
||||
log("|_|\\_\\___|_| |_||_\\___|_| |_| \\__,_|_||_|_\\__(_|_|_)\n");
|
||||
log("\n");
|
||||
log("Due to an error that can't be recovered from, Soaplin was needed to "
|
||||
"halt the PC.\n");
|
||||
log("Please report this error to the Soaplin developers, along with the "
|
||||
"information provided below:\n");
|
||||
log("-- REGISTER DUMP --\n");
|
||||
log("RDI: %p, RSI: %p, RDX: %p, RCX: %p, R8: %p, R9: %p\n",
|
||||
__panic_regdump.rdi, __panic_regdump.rsi, __panic_regdump.rdx,
|
||||
__panic_regdump.rcx, __panic_regdump.r8, __panic_regdump.r9);
|
||||
log("RAX: %p, RBP: %p, RBX: %p, R10: %p, R11: %p, R12: %p\n",
|
||||
__panic_regdump.rax, __panic_regdump.rbp, __panic_regdump.rbx,
|
||||
__panic_regdump.r10, __panic_regdump.r11, __panic_regdump.r12);
|
||||
log("R13: %p, R14: %p, R15: %p\n", __panic_regdump.r13, __panic_regdump.r14,
|
||||
__panic_regdump.r15);
|
||||
log("System halted.");
|
||||
|
||||
asm("cli");
|
||||
for (;;)
|
||||
asm("hlt");
|
||||
}
|
1
kernel/src/sys/error_handling/panic.h
Normal file
1
kernel/src/sys/error_handling/panic.h
Normal file
|
@ -0,0 +1 @@
|
|||
void panic();
|
|
@ -45,11 +45,11 @@ extern "C" {
|
|||
struct flanterm_context *flanterm_fb_init(
|
||||
/* If _malloc and _free are nulled, use the bump allocated instance (1 use
|
||||
only). */
|
||||
void *(*_malloc)(size_t size),
|
||||
void (*_free)(void *ptr, size_t size), uint32_t *framebuffer, size_t width,
|
||||
size_t height, size_t pitch, uint8_t red_mask_size, uint8_t red_mask_shift,
|
||||
uint8_t green_mask_size, uint8_t green_mask_shift, uint8_t blue_mask_size,
|
||||
uint8_t blue_mask_shift, uint32_t *canvas, /* If nulled, no canvas. */
|
||||
void *(*_malloc)(size_t size), void (*_free)(void *ptr, size_t size),
|
||||
uint32_t *framebuffer, size_t width, size_t height, size_t pitch,
|
||||
uint8_t red_mask_size, uint8_t red_mask_shift, uint8_t green_mask_size,
|
||||
uint8_t green_mask_shift, uint8_t blue_mask_size, uint8_t blue_mask_shift,
|
||||
uint32_t *canvas, /* If nulled, no canvas. */
|
||||
uint32_t *ansi_colours,
|
||||
uint32_t *ansi_bright_colours, /* If nulled, default. */
|
||||
uint32_t *default_bg, uint32_t *default_fg, /* If nulled, default. */
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "sys/arch/x86_64/io.h"
|
||||
#include "sys/gfx/flanterm/flanterm.h"
|
||||
#include <lib/spinlock.h>
|
||||
#include <lib/string.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/printf.h>
|
||||
|
||||
|
@ -14,12 +15,8 @@ void log(char *format, ...) {
|
|||
// TODO: replace this call with a call to printf() when the RTC is
|
||||
// implemented.
|
||||
char *date = "1970-01-01 00:00:00 | ";
|
||||
int i2 = 0;
|
||||
for (i2; date[i2] != 0; i2++)
|
||||
;
|
||||
;
|
||||
if (ft_ctx)
|
||||
flanterm_write(ft_ctx, date, i2);
|
||||
flanterm_write(ft_ctx, date, strlen(date));
|
||||
|
||||
char buf[2048];
|
||||
va_list l;
|
||||
|
@ -27,14 +24,10 @@ void log(char *format, ...) {
|
|||
npf_vsnprintf(buf, 2048, format, l);
|
||||
va_end(l);
|
||||
|
||||
int i = 0;
|
||||
for (i; buf[i] != 0; i++)
|
||||
;
|
||||
;
|
||||
if (ft_ctx)
|
||||
flanterm_write(ft_ctx, buf, i);
|
||||
flanterm_write(ft_ctx, buf, strlen(buf));
|
||||
|
||||
for (int i = 0;; i++) {
|
||||
/*for (int i = 0;; i++) {
|
||||
if (date[i] == '\0')
|
||||
break;
|
||||
|
||||
|
@ -46,7 +39,7 @@ void log(char *format, ...) {
|
|||
break;
|
||||
|
||||
outb(0xE9, buf[i]);
|
||||
}
|
||||
}*/
|
||||
|
||||
// spinlock_release(&log_lock);
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
// This code is part of the Soaplin kernel and is licensed under the terms of
|
||||
// the MIT License.
|
||||
#include "sys/gfx/flanterm/flanterm.h"
|
||||
#include <lib/string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1
|
||||
|
@ -25,11 +26,6 @@ void printf(char *format, ...) {
|
|||
va_end(lst);
|
||||
|
||||
// rt_print(buf);
|
||||
int i = 0;
|
||||
for (i; buf[i] != 0; i++)
|
||||
;
|
||||
;
|
||||
|
||||
if (ft_ctx)
|
||||
flanterm_write(ft_ctx, buf, i);
|
||||
flanterm_write(ft_ctx, buf, strlen(buf));
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue