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
|
@ -3,3 +3,7 @@ Do you want to improve Soaplin? You can by contributing to the project!
|
||||||
|
|
||||||
## Contributing guidelines
|
## Contributing guidelines
|
||||||
* Before making a commit, please run `make format`. This will run clang-format over all the C source files in kernel/src.
|
* Before making a commit, please run `make format`. This will run clang-format over all the C source files in kernel/src.
|
||||||
|
* Large language model-generated code is **allowed**, with the condition that you do extensive testing over that code.
|
||||||
|
You must also know how to make the LLM-generated code by yourself.
|
||||||
|
|
||||||
|
Note: Even if LLM-generated code is allowed, please try to not use it.
|
|
@ -83,7 +83,6 @@ run-aarch64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).iso
|
||||||
|
|
||||||
.PHONY: run-hdd-aarch64
|
.PHONY: run-hdd-aarch64
|
||||||
run-hdd-aarch64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).hdd
|
run-hdd-aarch64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).hdd
|
||||||
@echo " Starting QEMU with $(IMAGE_NAME).hdd"
|
|
||||||
@qemu-system-$(ARCH) \
|
@qemu-system-$(ARCH) \
|
||||||
-M virt \
|
-M virt \
|
||||||
-cpu cortex-a72 \
|
-cpu cortex-a72 \
|
||||||
|
@ -204,8 +203,8 @@ $(IMAGE_NAME).iso: limine/limine kernel
|
||||||
@mkdir -p iso_root/boot/limine
|
@mkdir -p iso_root/boot/limine
|
||||||
@cp -v limine.conf iso_root/boot/limine/
|
@cp -v limine.conf iso_root/boot/limine/
|
||||||
@mkdir -p iso_root/EFI/BOOT
|
@mkdir -p iso_root/EFI/BOOT
|
||||||
|
@cp -v initramfs.tar iso_root/
|
||||||
ifeq ($(ARCH),x86_64)
|
ifeq ($(ARCH),x86_64)
|
||||||
@cp -v testing/sk-hello.elf iso_root/
|
|
||||||
@cp -v limine/limine-bios.sys limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/boot/limine/
|
@cp -v limine/limine-bios.sys limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/boot/limine/
|
||||||
@cp -v limine/BOOTX64.EFI iso_root/EFI/BOOT/
|
@cp -v limine/BOOTX64.EFI iso_root/EFI/BOOT/
|
||||||
@cp -v limine/BOOTIA32.EFI iso_root/EFI/BOOT/
|
@cp -v limine/BOOTIA32.EFI iso_root/EFI/BOOT/
|
||||||
|
|
BIN
initramfs.tar
Normal file
BIN
initramfs.tar
Normal file
Binary file not shown.
1
initramfs/dir/subtest.txt
Normal file
1
initramfs/dir/subtest.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Hello World from a subdirectory!
|
1
initramfs/test.txt
Normal file
1
initramfs/test.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Hello World!
|
|
@ -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/elf.h"
|
||||||
#include "exec/exec.h"
|
#include "exec/exec.h"
|
||||||
|
#include "fs/tapefs.h"
|
||||||
|
#include "fs/vfs.h"
|
||||||
#include "mm/liballoc/liballoc.h"
|
#include "mm/liballoc/liballoc.h"
|
||||||
#include "mm/pmm.h"
|
#include "mm/pmm.h"
|
||||||
#include "mm/vma.h"
|
#include "mm/vma.h"
|
||||||
|
@ -11,29 +13,22 @@
|
||||||
#include "sys/syscall.h"
|
#include "sys/syscall.h"
|
||||||
#include <font.h>
|
#include <font.h>
|
||||||
#include <limine.h>
|
#include <limine.h>
|
||||||
|
#include <mm/memop.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/arch/x86_64/fpu.h>
|
#include <sys/arch/x86_64/fpu.h>
|
||||||
#include <sys/arch/x86_64/gdt.h>
|
#include <sys/arch/x86_64/gdt.h>
|
||||||
#include <sys/arch/x86_64/idt.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/backends/fb.h>
|
||||||
#include <sys/gfx/flanterm/flanterm.h>
|
#include <sys/gfx/flanterm/flanterm.h>
|
||||||
#include <sys/log.h>
|
#include <sys/log.h>
|
||||||
#include <sys/printf.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__((
|
__attribute__((
|
||||||
used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3);
|
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__((
|
__attribute__((
|
||||||
used,
|
used,
|
||||||
section(
|
section(
|
||||||
|
@ -45,14 +40,6 @@ __attribute__((
|
||||||
section(".limine_requests"))) static volatile struct limine_module_request
|
section(".limine_requests"))) static volatile struct limine_module_request
|
||||||
module_request = {.id = LIMINE_MODULE_REQUEST, .revision = 0};
|
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,
|
__attribute__((used,
|
||||||
section(".limine_requests_"
|
section(".limine_requests_"
|
||||||
"start"))) static volatile LIMINE_REQUESTS_START_MARKER;
|
"start"))) static volatile LIMINE_REQUESTS_START_MARKER;
|
||||||
|
@ -62,38 +49,14 @@ __attribute__((
|
||||||
section(
|
section(
|
||||||
".limine_requests_end"))) static volatile LIMINE_REQUESTS_END_MARKER;
|
".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 limine_framebuffer *fb;
|
||||||
struct flanterm_context *ft_ctx;
|
struct flanterm_context *ft_ctx;
|
||||||
uint32_t fg = 0xFFFFFF;
|
|
||||||
|
|
||||||
char kstack[8192];
|
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) {
|
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) {
|
if (framebuffer_request.response != NULL) {
|
||||||
|
|
||||||
// Fetch the first framebuffer.
|
|
||||||
struct limine_framebuffer *framebuffer =
|
struct limine_framebuffer *framebuffer =
|
||||||
framebuffer_request.response->framebuffers[0];
|
framebuffer_request.response->framebuffers[0];
|
||||||
fb = framebuffer;
|
fb = framebuffer;
|
||||||
|
@ -103,12 +66,11 @@ void kmain(void) {
|
||||||
framebuffer->height, framebuffer->pitch, framebuffer->red_mask_size,
|
framebuffer->height, framebuffer->pitch, framebuffer->red_mask_size,
|
||||||
framebuffer->red_mask_shift, framebuffer->green_mask_size,
|
framebuffer->red_mask_shift, framebuffer->green_mask_size,
|
||||||
framebuffer->green_mask_shift, framebuffer->blue_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);
|
VGA8, 8, 16, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n Soaplin 1.0-sild is booting up your computer...\n\n");
|
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]);
|
gdt_init(&kstack[8192]);
|
||||||
idt_init();
|
idt_init();
|
||||||
|
@ -125,21 +87,13 @@ void kmain(void) {
|
||||||
asm("hlt");
|
asm("hlt");
|
||||||
}
|
}
|
||||||
|
|
||||||
// acpi_init();
|
|
||||||
syscall_init();
|
syscall_init();
|
||||||
pit_init(1000);
|
pit_init(1000);
|
||||||
sched_init();
|
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");
|
log("kernel - Soaplin initialized sucessfully.\n");
|
||||||
|
|
||||||
while (1)
|
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 pml2_entry = (vaddr >> 21) & 0x1ff;
|
||||||
uint64_t pml1_entry = (vaddr >> 12) & 0x1ff;
|
uint64_t pml1_entry = (vaddr >> 12) & 0x1ff;
|
||||||
|
|
||||||
|
uint64_t *pml3 =
|
||||||
uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, flags | VMM_WRITABLE,
|
__vmm_get_next_lvl(pm->toplevel, pml4_entry, flags | VMM_WRITABLE,
|
||||||
true); // PML3 / Page Directory Pointer Entry
|
true); // PML3 / Page Directory Pointer Entry
|
||||||
uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, flags | VMM_WRITABLE,
|
uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, flags | VMM_WRITABLE,
|
||||||
true); // PML2 / Page Directory Entry
|
true); // PML2 / Page Directory Entry
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "mm/vmm.h"
|
#include "mm/vmm.h"
|
||||||
#include "sys/arch/x86_64/idt.h"
|
#include "sys/arch/x86_64/idt.h"
|
||||||
#include "sys/log.h"
|
#include "sys/log.h"
|
||||||
|
#include <lib/string.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
sched_process *proc_list;
|
sched_process *proc_list;
|
||||||
|
@ -47,16 +48,11 @@ void sched_init() {
|
||||||
|
|
||||||
sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm,
|
sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm,
|
||||||
uint32_t flags) {
|
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();
|
sched_process *proc = pmm_request_page();
|
||||||
memset(proc, 0, sizeof(sched_process));
|
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->pid = current_pid;
|
||||||
proc->type = SCHED_RUNNING;
|
proc->type = SCHED_RUNNING;
|
||||||
proc->flags = flags;
|
proc->flags = flags;
|
||||||
|
@ -141,7 +137,6 @@ void schedule(registers_t *regs) {
|
||||||
|
|
||||||
prev_proc->next = curr_proc->next;
|
prev_proc->next = curr_proc->next;
|
||||||
|
|
||||||
// Now, it is safe to free the process's memory.
|
|
||||||
vmm_release_pm(curr_proc->pm);
|
vmm_release_pm(curr_proc->pm);
|
||||||
pmm_free_page(curr_proc->stack_base_physical);
|
pmm_free_page(curr_proc->stack_base_physical);
|
||||||
|
|
||||||
|
@ -155,15 +150,7 @@ void schedule(registers_t *regs) {
|
||||||
if (curr_proc == NULL)
|
if (curr_proc == NULL)
|
||||||
curr_proc = proc_list;
|
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));
|
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);
|
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/pmm.h"
|
||||||
#include "mm/vmm.h"
|
#include "mm/vmm.h"
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
|
@ -7,39 +5,20 @@
|
||||||
#include "sys/arch/x86_64/rtc.h"
|
#include "sys/arch/x86_64/rtc.h"
|
||||||
#include "sys/log.h"
|
#include "sys/log.h"
|
||||||
#include "sys/syscall.h"
|
#include "sys/syscall.h"
|
||||||
// #include "sys/sched.h"
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/arch/x86_64/idt.h>
|
#include <sys/arch/x86_64/idt.h>
|
||||||
#include <sys/arch/x86_64/io.h>
|
#include <sys/arch/x86_64/io.h>
|
||||||
// #include <sys/errhand/panic.h>
|
|
||||||
|
|
||||||
int pit_millis = 0;
|
int pit_millis = 0;
|
||||||
int pit_secs = 0;
|
int pit_secs = 0;
|
||||||
extern int vmm_kernel_pm_exists;
|
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 pit_handler(registers_t *regs);
|
||||||
|
|
||||||
void exception_handler(registers_t *regs) {
|
void exception_handler(registers_t *regs) {
|
||||||
vmm_load_pagemap(vmm_kernel_pm);
|
vmm_load_pagemap(vmm_kernel_pm);
|
||||||
|
|
||||||
if (regs->int_no < 32) {
|
if (regs->int_no < 32) {
|
||||||
// panic(kmode_cpu_exception, regs);
|
|
||||||
log("ints - %d (RIP: %p, ERR: %d)\n", regs->int_no, regs->rip,
|
log("ints - %d (RIP: %p, ERR: %d)\n", regs->int_no, regs->rip,
|
||||||
regs->err_code);
|
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));
|
log("ints - PF: Faulting page map: %p\n", PHYSICAL(vmm_current_pm));
|
||||||
}
|
}
|
||||||
|
|
||||||
// dump_backtrace(regs);
|
|
||||||
asm("cli");
|
asm("cli");
|
||||||
while (1)
|
while (1)
|
||||||
asm("hlt");
|
asm("hlt");
|
||||||
|
@ -73,7 +51,6 @@ void exception_handler(registers_t *regs) {
|
||||||
} else if (regs->int_no == 0x80) {
|
} else if (regs->int_no == 0x80) {
|
||||||
syscall_handle(regs);
|
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);
|
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(
|
struct flanterm_context *flanterm_fb_init(
|
||||||
/* If _malloc and _free are nulled, use the bump allocated instance (1 use
|
/* If _malloc and _free are nulled, use the bump allocated instance (1 use
|
||||||
only). */
|
only). */
|
||||||
void *(*_malloc)(size_t size),
|
void *(*_malloc)(size_t size), void (*_free)(void *ptr, size_t size),
|
||||||
void (*_free)(void *ptr, size_t size), uint32_t *framebuffer, size_t width,
|
uint32_t *framebuffer, size_t width, size_t height, size_t pitch,
|
||||||
size_t height, size_t pitch, uint8_t red_mask_size, uint8_t red_mask_shift,
|
uint8_t red_mask_size, uint8_t red_mask_shift, uint8_t green_mask_size,
|
||||||
uint8_t green_mask_size, uint8_t green_mask_shift, uint8_t blue_mask_size,
|
uint8_t green_mask_shift, uint8_t blue_mask_size, uint8_t blue_mask_shift,
|
||||||
uint8_t blue_mask_shift, uint32_t *canvas, /* If nulled, no canvas. */
|
uint32_t *canvas, /* If nulled, no canvas. */
|
||||||
uint32_t *ansi_colours,
|
uint32_t *ansi_colours,
|
||||||
uint32_t *ansi_bright_colours, /* If nulled, default. */
|
uint32_t *ansi_bright_colours, /* If nulled, default. */
|
||||||
uint32_t *default_bg, uint32_t *default_fg, /* 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/arch/x86_64/io.h"
|
||||||
#include "sys/gfx/flanterm/flanterm.h"
|
#include "sys/gfx/flanterm/flanterm.h"
|
||||||
#include <lib/spinlock.h>
|
#include <lib/spinlock.h>
|
||||||
|
#include <lib/string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <sys/printf.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
|
// TODO: replace this call with a call to printf() when the RTC is
|
||||||
// implemented.
|
// implemented.
|
||||||
char *date = "1970-01-01 00:00:00 | ";
|
char *date = "1970-01-01 00:00:00 | ";
|
||||||
int i2 = 0;
|
|
||||||
for (i2; date[i2] != 0; i2++)
|
|
||||||
;
|
|
||||||
;
|
|
||||||
if (ft_ctx)
|
if (ft_ctx)
|
||||||
flanterm_write(ft_ctx, date, i2);
|
flanterm_write(ft_ctx, date, strlen(date));
|
||||||
|
|
||||||
char buf[2048];
|
char buf[2048];
|
||||||
va_list l;
|
va_list l;
|
||||||
|
@ -27,14 +24,10 @@ void log(char *format, ...) {
|
||||||
npf_vsnprintf(buf, 2048, format, l);
|
npf_vsnprintf(buf, 2048, format, l);
|
||||||
va_end(l);
|
va_end(l);
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
for (i; buf[i] != 0; i++)
|
|
||||||
;
|
|
||||||
;
|
|
||||||
if (ft_ctx)
|
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')
|
if (date[i] == '\0')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -46,7 +39,7 @@ void log(char *format, ...) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
outb(0xE9, buf[i]);
|
outb(0xE9, buf[i]);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// spinlock_release(&log_lock);
|
// spinlock_release(&log_lock);
|
||||||
}
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
// This code is part of the Soaplin kernel and is licensed under the terms of
|
// This code is part of the Soaplin kernel and is licensed under the terms of
|
||||||
// the MIT License.
|
// the MIT License.
|
||||||
#include "sys/gfx/flanterm/flanterm.h"
|
#include "sys/gfx/flanterm/flanterm.h"
|
||||||
|
#include <lib/string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1
|
#define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1
|
||||||
|
@ -25,11 +26,6 @@ void printf(char *format, ...) {
|
||||||
va_end(lst);
|
va_end(lst);
|
||||||
|
|
||||||
// rt_print(buf);
|
// rt_print(buf);
|
||||||
int i = 0;
|
|
||||||
for (i; buf[i] != 0; i++)
|
|
||||||
;
|
|
||||||
;
|
|
||||||
|
|
||||||
if (ft_ctx)
|
if (ft_ctx)
|
||||||
flanterm_write(ft_ctx, buf, i);
|
flanterm_write(ft_ctx, buf, strlen(buf));
|
||||||
}
|
}
|
|
@ -6,4 +6,4 @@ verbose: yes
|
||||||
protocol: limine
|
protocol: limine
|
||||||
|
|
||||||
path: boot():/boot/soaplin
|
path: boot():/boot/soaplin
|
||||||
module_path: boot():/sk-hello.elf
|
module_path: boot():/initramfs.tar
|
Loading…
Add table
Add a link
Reference in a new issue