mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-21 18:44:01 +00:00
Stage 5
This commit is contained in:
@@ -72,6 +72,7 @@ ISR_NOERR 44
|
||||
ISR_NOERR 45
|
||||
ISR_NOERR 46
|
||||
ISR_NOERR 47
|
||||
ISR_NOERR 128
|
||||
|
||||
clks_isr_common:
|
||||
cld
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
clks_bool clks_boot_base_revision_supported(void);
|
||||
const struct limine_framebuffer *clks_boot_get_framebuffer(void);
|
||||
const struct limine_memmap_response *clks_boot_get_memmap(void);
|
||||
const struct limine_file *clks_boot_get_executable_file(void);
|
||||
|
||||
#endif
|
||||
35
clks/include/clks/elf64.h
Normal file
35
clks/include/clks/elf64.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef CLKS_ELF64_H
|
||||
#define CLKS_ELF64_H
|
||||
|
||||
#include <clks/types.h>
|
||||
|
||||
#define CLKS_ELF64_MAX_SEGMENTS 16U
|
||||
|
||||
#define CLKS_ELF64_PT_LOAD 1U
|
||||
|
||||
struct clks_elf64_info {
|
||||
u64 entry;
|
||||
u16 phnum;
|
||||
u16 loadable_segments;
|
||||
u64 total_load_memsz;
|
||||
};
|
||||
|
||||
struct clks_elf64_loaded_segment {
|
||||
void *base;
|
||||
u64 vaddr;
|
||||
u64 memsz;
|
||||
u64 filesz;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
struct clks_elf64_loaded_image {
|
||||
u64 entry;
|
||||
u16 segment_count;
|
||||
struct clks_elf64_loaded_segment segments[CLKS_ELF64_MAX_SEGMENTS];
|
||||
};
|
||||
|
||||
clks_bool clks_elf64_validate(const void *image, u64 size);
|
||||
clks_bool clks_elf64_inspect(const void *image, u64 size, struct clks_elf64_info *out_info);
|
||||
clks_bool clks_elf64_load(const void *image, u64 size, struct clks_elf64_loaded_image *out_loaded);
|
||||
|
||||
#endif
|
||||
9
clks/include/clks/elfrunner.h
Normal file
9
clks/include/clks/elfrunner.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef CLKS_ELFRUNNER_H
|
||||
#define CLKS_ELFRUNNER_H
|
||||
|
||||
#include <clks/types.h>
|
||||
|
||||
void clks_elfrunner_init(void);
|
||||
clks_bool clks_elfrunner_probe_kernel_executable(void);
|
||||
|
||||
#endif
|
||||
@@ -31,6 +31,14 @@
|
||||
0xe304acdfc50c3c62ULL \
|
||||
}
|
||||
|
||||
#define LIMINE_EXECUTABLE_FILE_REQUEST \
|
||||
{ \
|
||||
LIMINE_COMMON_MAGIC, \
|
||||
LIMINE_REQUEST_MAGIC, \
|
||||
0xad97e90e83f1ed67ULL, \
|
||||
0x31eb5d1c5ff23b69ULL \
|
||||
}
|
||||
|
||||
#define LIMINE_MEMMAP_USABLE 0ULL
|
||||
#define LIMINE_MEMMAP_RESERVED 1ULL
|
||||
#define LIMINE_MEMMAP_ACPI_RECLAIMABLE 2ULL
|
||||
@@ -41,6 +49,30 @@
|
||||
#define LIMINE_MEMMAP_FRAMEBUFFER 7ULL
|
||||
#define LIMINE_MEMMAP_RESERVED_MAPPED 8ULL
|
||||
|
||||
struct limine_uuid {
|
||||
u32 a;
|
||||
u16 b;
|
||||
u16 c;
|
||||
u8 d[8];
|
||||
};
|
||||
|
||||
struct limine_file {
|
||||
u64 revision;
|
||||
void *address;
|
||||
u64 size;
|
||||
char *path;
|
||||
char *string;
|
||||
u32 media_type;
|
||||
u32 unused;
|
||||
u32 tftp_ip;
|
||||
u32 tftp_port;
|
||||
u32 partition_index;
|
||||
u32 mbr_disk_id;
|
||||
struct limine_uuid gpt_disk_uuid;
|
||||
struct limine_uuid gpt_part_uuid;
|
||||
struct limine_uuid part_uuid;
|
||||
};
|
||||
|
||||
struct limine_framebuffer {
|
||||
void *address;
|
||||
u64 width;
|
||||
@@ -89,4 +121,15 @@ struct limine_memmap_request {
|
||||
struct limine_memmap_response *response;
|
||||
};
|
||||
|
||||
struct limine_executable_file_response {
|
||||
u64 revision;
|
||||
struct limine_file *executable_file;
|
||||
};
|
||||
|
||||
struct limine_executable_file_request {
|
||||
u64 id[4];
|
||||
u64 revision;
|
||||
struct limine_executable_file_response *response;
|
||||
};
|
||||
|
||||
#endif
|
||||
15
clks/include/clks/syscall.h
Normal file
15
clks/include/clks/syscall.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef CLKS_SYSCALL_H
|
||||
#define CLKS_SYSCALL_H
|
||||
|
||||
#include <clks/types.h>
|
||||
|
||||
#define CLKS_SYSCALL_LOG_WRITE 0ULL
|
||||
#define CLKS_SYSCALL_TIMER_TICKS 1ULL
|
||||
#define CLKS_SYSCALL_TASK_COUNT 2ULL
|
||||
#define CLKS_SYSCALL_CURRENT_TASK_ID 3ULL
|
||||
|
||||
void clks_syscall_init(void);
|
||||
u64 clks_syscall_dispatch(void *frame_ptr);
|
||||
u64 clks_syscall_invoke_kernel(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||
|
||||
#endif
|
||||
222
clks/kernel/elf64.c
Normal file
222
clks/kernel/elf64.c
Normal file
@@ -0,0 +1,222 @@
|
||||
#include <clks/elf64.h>
|
||||
#include <clks/heap.h>
|
||||
#include <clks/string.h>
|
||||
#include <clks/types.h>
|
||||
|
||||
#define CLKS_ELF64_MAGIC_0 0x7FU
|
||||
#define CLKS_ELF64_MAGIC_1 'E'
|
||||
#define CLKS_ELF64_MAGIC_2 'L'
|
||||
#define CLKS_ELF64_MAGIC_3 'F'
|
||||
|
||||
#define CLKS_ELF64_CLASS_64 2U
|
||||
#define CLKS_ELF64_DATA_LSB 1U
|
||||
#define CLKS_ELF64_VERSION 1U
|
||||
|
||||
#define CLKS_ELF64_ET_EXEC 2U
|
||||
#define CLKS_ELF64_ET_DYN 3U
|
||||
|
||||
#define CLKS_ELF64_EM_X86_64 62U
|
||||
|
||||
struct clks_elf64_ehdr {
|
||||
u8 e_ident[16];
|
||||
u16 e_type;
|
||||
u16 e_machine;
|
||||
u32 e_version;
|
||||
u64 e_entry;
|
||||
u64 e_phoff;
|
||||
u64 e_shoff;
|
||||
u32 e_flags;
|
||||
u16 e_ehsize;
|
||||
u16 e_phentsize;
|
||||
u16 e_phnum;
|
||||
u16 e_shentsize;
|
||||
u16 e_shnum;
|
||||
u16 e_shstrndx;
|
||||
};
|
||||
|
||||
struct clks_elf64_phdr {
|
||||
u32 p_type;
|
||||
u32 p_flags;
|
||||
u64 p_offset;
|
||||
u64 p_vaddr;
|
||||
u64 p_paddr;
|
||||
u64 p_filesz;
|
||||
u64 p_memsz;
|
||||
u64 p_align;
|
||||
};
|
||||
|
||||
static clks_bool clks_elf64_header_ok(const struct clks_elf64_ehdr *eh) {
|
||||
if (eh->e_ident[0] != CLKS_ELF64_MAGIC_0 ||
|
||||
eh->e_ident[1] != CLKS_ELF64_MAGIC_1 ||
|
||||
eh->e_ident[2] != CLKS_ELF64_MAGIC_2 ||
|
||||
eh->e_ident[3] != CLKS_ELF64_MAGIC_3) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (eh->e_ident[4] != CLKS_ELF64_CLASS_64 || eh->e_ident[5] != CLKS_ELF64_DATA_LSB) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (eh->e_ident[6] != CLKS_ELF64_VERSION || eh->e_version != CLKS_ELF64_VERSION) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (eh->e_type != CLKS_ELF64_ET_EXEC && eh->e_type != CLKS_ELF64_ET_DYN) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (eh->e_machine != CLKS_ELF64_EM_X86_64) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (eh->e_ehsize != sizeof(struct clks_elf64_ehdr)) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (eh->e_phentsize != sizeof(struct clks_elf64_phdr)) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
static clks_bool clks_elf64_range_ok(u64 off, u64 len, u64 total) {
|
||||
if (off > total) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (len > (total - off)) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
clks_bool clks_elf64_validate(const void *image, u64 size) {
|
||||
const struct clks_elf64_ehdr *eh;
|
||||
u64 ph_table_size;
|
||||
u16 i;
|
||||
|
||||
if (image == CLKS_NULL) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (size < sizeof(struct clks_elf64_ehdr)) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
eh = (const struct clks_elf64_ehdr *)image;
|
||||
|
||||
if (clks_elf64_header_ok(eh) == CLKS_FALSE) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
ph_table_size = (u64)eh->e_phnum * (u64)eh->e_phentsize;
|
||||
|
||||
if (clks_elf64_range_ok(eh->e_phoff, ph_table_size, size) == CLKS_FALSE) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < eh->e_phnum; i++) {
|
||||
const struct clks_elf64_phdr *ph =
|
||||
(const struct clks_elf64_phdr *)((const u8 *)image + eh->e_phoff + ((u64)i * eh->e_phentsize));
|
||||
|
||||
if (ph->p_type != CLKS_ELF64_PT_LOAD) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ph->p_filesz > ph->p_memsz) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (clks_elf64_range_ok(ph->p_offset, ph->p_filesz, size) == CLKS_FALSE) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
clks_bool clks_elf64_inspect(const void *image, u64 size, struct clks_elf64_info *out_info) {
|
||||
const struct clks_elf64_ehdr *eh;
|
||||
u16 i;
|
||||
|
||||
if (out_info == CLKS_NULL) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
clks_memset(out_info, 0, sizeof(*out_info));
|
||||
|
||||
if (clks_elf64_validate(image, size) == CLKS_FALSE) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
eh = (const struct clks_elf64_ehdr *)image;
|
||||
|
||||
out_info->entry = eh->e_entry;
|
||||
out_info->phnum = eh->e_phnum;
|
||||
|
||||
for (i = 0; i < eh->e_phnum; i++) {
|
||||
const struct clks_elf64_phdr *ph =
|
||||
(const struct clks_elf64_phdr *)((const u8 *)image + eh->e_phoff + ((u64)i * eh->e_phentsize));
|
||||
|
||||
if (ph->p_type != CLKS_ELF64_PT_LOAD) {
|
||||
continue;
|
||||
}
|
||||
|
||||
out_info->loadable_segments++;
|
||||
out_info->total_load_memsz += ph->p_memsz;
|
||||
}
|
||||
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
clks_bool clks_elf64_load(const void *image, u64 size, struct clks_elf64_loaded_image *out_loaded) {
|
||||
const struct clks_elf64_ehdr *eh;
|
||||
u16 i;
|
||||
|
||||
if (out_loaded == CLKS_NULL) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
clks_memset(out_loaded, 0, sizeof(*out_loaded));
|
||||
|
||||
if (clks_elf64_validate(image, size) == CLKS_FALSE) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
eh = (const struct clks_elf64_ehdr *)image;
|
||||
out_loaded->entry = eh->e_entry;
|
||||
|
||||
for (i = 0; i < eh->e_phnum; i++) {
|
||||
const struct clks_elf64_phdr *ph =
|
||||
(const struct clks_elf64_phdr *)((const u8 *)image + eh->e_phoff + ((u64)i * eh->e_phentsize));
|
||||
void *dst;
|
||||
|
||||
if (ph->p_type != CLKS_ELF64_PT_LOAD || ph->p_memsz == 0ULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (out_loaded->segment_count >= CLKS_ELF64_MAX_SEGMENTS) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
dst = clks_kmalloc((usize)ph->p_memsz);
|
||||
|
||||
if (dst == CLKS_NULL) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
clks_memset(dst, 0, (usize)ph->p_memsz);
|
||||
clks_memcpy(dst, (const void *)((const u8 *)image + ph->p_offset), (usize)ph->p_filesz);
|
||||
|
||||
out_loaded->segments[out_loaded->segment_count].base = dst;
|
||||
out_loaded->segments[out_loaded->segment_count].vaddr = ph->p_vaddr;
|
||||
out_loaded->segments[out_loaded->segment_count].memsz = ph->p_memsz;
|
||||
out_loaded->segments[out_loaded->segment_count].filesz = ph->p_filesz;
|
||||
out_loaded->segments[out_loaded->segment_count].flags = ph->p_flags;
|
||||
out_loaded->segment_count++;
|
||||
}
|
||||
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
38
clks/kernel/elfrunner.c
Normal file
38
clks/kernel/elfrunner.c
Normal file
@@ -0,0 +1,38 @@
|
||||
#include <clks/boot.h>
|
||||
#include <clks/elf64.h>
|
||||
#include <clks/elfrunner.h>
|
||||
#include <clks/log.h>
|
||||
#include <clks/types.h>
|
||||
|
||||
static clks_bool clks_elfrunner_ready = CLKS_FALSE;
|
||||
|
||||
void clks_elfrunner_init(void) {
|
||||
clks_elfrunner_ready = CLKS_TRUE;
|
||||
clks_log(CLKS_LOG_INFO, "ELF", "ELFRUNNER FRAMEWORK ONLINE");
|
||||
}
|
||||
|
||||
clks_bool clks_elfrunner_probe_kernel_executable(void) {
|
||||
const struct limine_file *exe = clks_boot_get_executable_file();
|
||||
struct clks_elf64_info info;
|
||||
|
||||
if (clks_elfrunner_ready == CLKS_FALSE) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (exe == CLKS_NULL || exe->address == CLKS_NULL || exe->size == 0ULL) {
|
||||
clks_log(CLKS_LOG_ERROR, "ELF", "NO EXECUTABLE FILE FROM LIMINE");
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (clks_elf64_inspect(exe->address, exe->size, &info) == CLKS_FALSE) {
|
||||
clks_log(CLKS_LOG_ERROR, "ELF", "KERNEL ELF INSPECT FAILED");
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
clks_log_hex(CLKS_LOG_INFO, "ELF", "ENTRY", info.entry);
|
||||
clks_log_hex(CLKS_LOG_INFO, "ELF", "PHNUM", info.phnum);
|
||||
clks_log_hex(CLKS_LOG_INFO, "ELF", "LOAD_SEGMENTS", info.loadable_segments);
|
||||
clks_log_hex(CLKS_LOG_INFO, "ELF", "TOTAL_MEMSZ", info.total_load_memsz);
|
||||
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
@@ -3,10 +3,12 @@
|
||||
#include <clks/interrupts.h>
|
||||
#include <clks/log.h>
|
||||
#include <clks/scheduler.h>
|
||||
#include <clks/syscall.h>
|
||||
#include <clks/types.h>
|
||||
|
||||
#define CLKS_IDT_ENTRY_COUNT 256U
|
||||
#define CLKS_INTERRUPT_GATE 0x8EU
|
||||
#define CLKS_USER_INT_GATE 0xEEU
|
||||
|
||||
#define CLKS_PIC1_CMD 0x20U
|
||||
#define CLKS_PIC1_DATA 0x21U
|
||||
@@ -17,6 +19,7 @@
|
||||
#define CLKS_IRQ_BASE 32U
|
||||
#define CLKS_IRQ_TIMER 32U
|
||||
#define CLKS_IRQ_LAST 47U
|
||||
#define CLKS_SYSCALL_VECTOR 128U
|
||||
|
||||
struct clks_idt_entry {
|
||||
u16 offset_low;
|
||||
@@ -107,6 +110,7 @@ extern void clks_isr_stub_44(void);
|
||||
extern void clks_isr_stub_45(void);
|
||||
extern void clks_isr_stub_46(void);
|
||||
extern void clks_isr_stub_47(void);
|
||||
extern void clks_isr_stub_128(void);
|
||||
|
||||
static struct clks_idt_entry clks_idt[CLKS_IDT_ENTRY_COUNT];
|
||||
static u16 clks_idt_code_selector = 0x08U;
|
||||
@@ -228,6 +232,11 @@ static void clks_enable_interrupts(void) {
|
||||
void clks_interrupt_dispatch(struct clks_interrupt_frame *frame) {
|
||||
u64 vector = frame->vector;
|
||||
|
||||
if (vector == CLKS_SYSCALL_VECTOR) {
|
||||
frame->rax = clks_syscall_dispatch((void *)frame);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vector < 32U) {
|
||||
clks_log(CLKS_LOG_ERROR, "EXC", clks_exception_names[vector]);
|
||||
clks_log_hex(CLKS_LOG_ERROR, "EXC", "VECTOR", vector);
|
||||
@@ -238,6 +247,7 @@ void clks_interrupt_dispatch(struct clks_interrupt_frame *frame) {
|
||||
|
||||
if (vector == CLKS_IRQ_TIMER) {
|
||||
clks_timer_ticks++;
|
||||
clks_scheduler_on_timer_tick(clks_timer_ticks);
|
||||
}
|
||||
|
||||
if (vector >= CLKS_IRQ_BASE && vector <= CLKS_IRQ_LAST) {
|
||||
@@ -304,6 +314,8 @@ void clks_interrupts_init(void) {
|
||||
clks_idt_set_gate(46, clks_isr_stub_46, CLKS_INTERRUPT_GATE);
|
||||
clks_idt_set_gate(47, clks_isr_stub_47, CLKS_INTERRUPT_GATE);
|
||||
|
||||
clks_idt_set_gate(CLKS_SYSCALL_VECTOR, clks_isr_stub_128, CLKS_USER_INT_GATE);
|
||||
|
||||
clks_pic_remap_and_mask();
|
||||
clks_load_idt();
|
||||
clks_enable_interrupts();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <clks/boot.h>
|
||||
#include <clks/cpu.h>
|
||||
#include <clks/elfrunner.h>
|
||||
#include <clks/framebuffer.h>
|
||||
#include <clks/heap.h>
|
||||
#include <clks/interrupts.h>
|
||||
@@ -8,6 +9,7 @@
|
||||
#include <clks/pmm.h>
|
||||
#include <clks/scheduler.h>
|
||||
#include <clks/serial.h>
|
||||
#include <clks/syscall.h>
|
||||
#include <clks/tty.h>
|
||||
#include <clks/types.h>
|
||||
|
||||
@@ -18,6 +20,7 @@ void clks_kernel_main(void) {
|
||||
struct clks_heap_stats heap_stats;
|
||||
struct clks_scheduler_stats sched_stats;
|
||||
void *heap_probe = CLKS_NULL;
|
||||
u64 syscall_ticks;
|
||||
|
||||
clks_serial_init();
|
||||
|
||||
@@ -33,7 +36,7 @@ void clks_kernel_main(void) {
|
||||
clks_tty_init();
|
||||
}
|
||||
|
||||
clks_log(CLKS_LOG_INFO, "BOOT", "CLEONOS STAGE4 START");
|
||||
clks_log(CLKS_LOG_INFO, "BOOT", "CLEONOS STAGE5 START");
|
||||
|
||||
if (boot_fb == CLKS_NULL) {
|
||||
clks_log(CLKS_LOG_WARN, "VIDEO", "NO FRAMEBUFFER FROM LIMINE");
|
||||
@@ -93,9 +96,20 @@ void clks_kernel_main(void) {
|
||||
sched_stats = clks_scheduler_get_stats();
|
||||
clks_log_hex(CLKS_LOG_INFO, "SCHED", "TASK_COUNT", sched_stats.task_count);
|
||||
|
||||
clks_elfrunner_init();
|
||||
|
||||
if (clks_elfrunner_probe_kernel_executable() == CLKS_FALSE) {
|
||||
clks_log(CLKS_LOG_ERROR, "ELF", "KERNEL ELF PROBE FAILED");
|
||||
}
|
||||
|
||||
clks_syscall_init();
|
||||
|
||||
clks_interrupts_init();
|
||||
clks_log(CLKS_LOG_INFO, "INT", "IDT + PIC INITIALIZED");
|
||||
|
||||
syscall_ticks = clks_syscall_invoke_kernel(CLKS_SYSCALL_TIMER_TICKS, 0ULL, 0ULL, 0ULL);
|
||||
clks_log_hex(CLKS_LOG_INFO, "SYSCALL", "TICKS", syscall_ticks);
|
||||
|
||||
clks_log(CLKS_LOG_INFO, "TTY", "VIRTUAL TTY0 READY");
|
||||
clks_log(CLKS_LOG_DEBUG, "KERNEL", "IDLE LOOP ENTER");
|
||||
|
||||
|
||||
@@ -21,6 +21,13 @@ CLKS_USED static volatile struct limine_memmap_request limine_memmap_request
|
||||
.response = CLKS_NULL,
|
||||
};
|
||||
|
||||
CLKS_USED static volatile struct limine_executable_file_request limine_executable_file_request
|
||||
__attribute__((section(".limine_requests"))) = {
|
||||
.id = LIMINE_EXECUTABLE_FILE_REQUEST,
|
||||
.revision = 0,
|
||||
.response = CLKS_NULL,
|
||||
};
|
||||
|
||||
CLKS_USED static volatile u64 limine_requests_end[]
|
||||
__attribute__((section(".limine_requests_end"))) = LIMINE_REQUESTS_END_MARKER;
|
||||
|
||||
@@ -50,4 +57,14 @@ const struct limine_memmap_response *clks_boot_get_memmap(void) {
|
||||
}
|
||||
|
||||
return request->response;
|
||||
}
|
||||
|
||||
const struct limine_file *clks_boot_get_executable_file(void) {
|
||||
volatile struct limine_executable_file_request *request = &limine_executable_file_request;
|
||||
|
||||
if (request->response == CLKS_NULL) {
|
||||
return CLKS_NULL;
|
||||
}
|
||||
|
||||
return request->response->executable_file;
|
||||
}
|
||||
102
clks/kernel/syscall.c
Normal file
102
clks/kernel/syscall.c
Normal file
@@ -0,0 +1,102 @@
|
||||
#include <clks/interrupts.h>
|
||||
#include <clks/log.h>
|
||||
#include <clks/scheduler.h>
|
||||
#include <clks/syscall.h>
|
||||
#include <clks/types.h>
|
||||
|
||||
struct clks_syscall_frame {
|
||||
u64 rax;
|
||||
u64 rbx;
|
||||
u64 rcx;
|
||||
u64 rdx;
|
||||
u64 rsi;
|
||||
u64 rdi;
|
||||
u64 rbp;
|
||||
u64 r8;
|
||||
u64 r9;
|
||||
u64 r10;
|
||||
u64 r11;
|
||||
u64 r12;
|
||||
u64 r13;
|
||||
u64 r14;
|
||||
u64 r15;
|
||||
u64 vector;
|
||||
u64 error_code;
|
||||
u64 rip;
|
||||
u64 cs;
|
||||
u64 rflags;
|
||||
u64 rsp;
|
||||
u64 ss;
|
||||
};
|
||||
|
||||
static clks_bool clks_syscall_ready = CLKS_FALSE;
|
||||
|
||||
static u64 clks_syscall_log_write(u64 arg0, u64 arg1) {
|
||||
const char *src = (const char *)arg0;
|
||||
u64 len = arg1;
|
||||
char buf[192];
|
||||
u64 i;
|
||||
|
||||
if (src == CLKS_NULL || len == 0ULL) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (len > (sizeof(buf) - 1U)) {
|
||||
len = sizeof(buf) - 1U;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
buf[i] = src[i];
|
||||
}
|
||||
|
||||
buf[len] = '\0';
|
||||
clks_log(CLKS_LOG_INFO, "SYSCALL", buf);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void clks_syscall_init(void) {
|
||||
clks_syscall_ready = CLKS_TRUE;
|
||||
clks_log(CLKS_LOG_INFO, "SYSCALL", "INT80 FRAMEWORK ONLINE");
|
||||
}
|
||||
|
||||
u64 clks_syscall_dispatch(void *frame_ptr) {
|
||||
struct clks_syscall_frame *frame = (struct clks_syscall_frame *)frame_ptr;
|
||||
u64 id;
|
||||
|
||||
if (clks_syscall_ready == CLKS_FALSE || frame == CLKS_NULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
id = frame->rax;
|
||||
|
||||
switch (id) {
|
||||
case CLKS_SYSCALL_LOG_WRITE:
|
||||
return clks_syscall_log_write(frame->rbx, frame->rcx);
|
||||
case CLKS_SYSCALL_TIMER_TICKS:
|
||||
return clks_interrupts_timer_ticks();
|
||||
case CLKS_SYSCALL_TASK_COUNT: {
|
||||
struct clks_scheduler_stats stats = clks_scheduler_get_stats();
|
||||
return stats.task_count;
|
||||
}
|
||||
case CLKS_SYSCALL_CURRENT_TASK_ID: {
|
||||
struct clks_scheduler_stats stats = clks_scheduler_get_stats();
|
||||
return stats.current_task_id;
|
||||
}
|
||||
default:
|
||||
return (u64)-1;
|
||||
}
|
||||
}
|
||||
|
||||
u64 clks_syscall_invoke_kernel(u64 id, u64 arg0, u64 arg1, u64 arg2) {
|
||||
u64 ret;
|
||||
|
||||
__asm__ volatile(
|
||||
"int $0x80"
|
||||
: "=a"(ret)
|
||||
: "a"(id), "b"(arg0), "c"(arg1), "d"(arg2)
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user