diff --git a/.gitignore b/.gitignore index c6e49ef..0c7f43f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ +obj/src/ obj/ bin/ +bin/os +image.hdd diff --git a/bin/os b/bin/os index e51b798..6cec5cc 100755 Binary files a/bin/os and b/bin/os differ diff --git a/fortune b/fortune index ddad7f5..028305f 100644 --- a/fortune +++ b/fortune @@ -1,2 +1,16 @@ -Many hands make light work. - -- John Heywood +_/I\_____________o______________o___/I\ l * / /_/ * __ ' .* l +I"""_____________l______________l___"""I\ l *// _l__l_ . *. l + [__][__][(******)__][__](******)[__][] \l l-\ ---//---*----(oo)----------l + [][__][__(******)][__][_(******)_][__] l l \\ // ____ >-( )-< / l + [__][__][_l l[__][__][l l][__][] l l \\)) ._****_.(......) .@@@:::l + [][__][__]l .l_][__][__] .l__][__] l l ll _(o_o)_ (@*_*@ l + [__][__][/ <_)[__][__]/ <_)][__][] l l ll ( / \ ) / / / ) l + [][__][ /..,/][__][__][/..,/_][__][__] l l / \\ _\ \_ / _\_\ l + [__][__(__/][__][__][_(__/_][__][__][] l l______________________________l + [__][__]] l , , . [__][__][] l + [][__][_] l . i. '/ , [][__][__] l /\**/\ season's + [__][__]] l O .\ / /, O [__][__][] l ( o_o )_) greetings +_[][__][_] l__l======='=l____[][__][__] l_______,(u u ,),__________________ + [__][__]]/ /l\-------/l\ [__][__][]/ {}{}{}{}{}{} + +In Ellen's house it is warm and toasty while fuzzies play in the snow outside. diff --git a/image.hdd b/image.hdd index 9d3b219..f50cb29 100644 Binary files a/image.hdd and b/image.hdd differ diff --git a/limine b/limine index e0e61c9..eecf8d6 160000 --- a/limine +++ b/limine @@ -1 +1 @@ -Subproject commit e0e61c946933696453f591da525ab1f8a66a553d +Subproject commit eecf8d682a749701691e31b89f66f330f525c611 diff --git a/limine.sh b/limine.sh index ca98929..835232c 100644 --- a/limine.sh +++ b/limine.sh @@ -19,11 +19,14 @@ make -C limine mformat -i image.hdd@@1M -F # Make relevant subdirectories. -mmd -i image.hdd@@1M ::/EFI ::/EFI/BOOT ::/boot ::/boot/limine ::/fort +mmd -i image.hdd@@1M ::/EFI ::/EFI/BOOT ::/boot ::/boot/limine ::/fort ::/usr ::/usr/bin + +#fortune -l > fortune # Copy over the relevant files. mcopy -i image.hdd@@1M bin/os ::/boot mcopy -i image.hdd@@1M limine.conf limine/limine-bios.sys ::/boot/limine mcopy -i image.hdd@@1M limine/BOOTX64.EFI ::/EFI/BOOT mcopy -i image.hdd@@1M limine/BOOTIA32.EFI ::/EFI/BOOT +mcopy -i image.hdd@@1M mnt/usr/bin/test ::/usr/bin/test mcopy -i image.hdd@@1M fortune ::/fort/fortu.ne diff --git a/obj/src/int.c.d b/obj/src/int.c.d index ef52c69..e4af4f5 100644 --- a/obj/src/int.c.d +++ b/obj/src/int.c.d @@ -1,5 +1,11 @@ -obj/src/int.c.o: src/int.c src/apic.h src/common.h src/print.h src/kbd.h +obj/src/int.c.o: src/int.c src/apic.h src/common.h src/print.h src/kbd.h \ + src/syscalls.h src/lib/sys.h src/int.h src/lib/stdio.h src/lib/malloc.h src/apic.h: src/common.h: src/print.h: src/kbd.h: +src/syscalls.h: +src/lib/sys.h: +src/int.h: +src/lib/stdio.h: +src/lib/malloc.h: diff --git a/obj/src/int.c.o b/obj/src/int.c.o index cb5e576..760d2c6 100644 Binary files a/obj/src/int.c.o and b/obj/src/int.c.o differ diff --git a/obj/src/main.c.d b/obj/src/main.c.d index c828c7c..203febb 100644 --- a/obj/src/main.c.d +++ b/obj/src/main.c.d @@ -1,12 +1,12 @@ obj/src/main.c.o: src/main.c src/../include/limine.h src/prompt/lex.h \ - src/prompt/file.h src/acpi.h src/common.h src/ahci.h src/alloc.h \ - src/apic.h src/fat32.h src/lib/ctype.h src/lib/string.h \ - src/lib/../lib/stdio.h src/lib/../lib/malloc.h \ - src/lib/../lib/../common.h src/lib/../lib/../kbd.h \ - src/lib/../lib/../print.h src/lib/stdio.h src/print.h + src/prompt/file.h src/prompt/file.h src/acpi.h src/common.h src/ahci.h \ + src/alloc.h src/apic.h src/fat32.h src/lib/ctype.h src/lib/string.h \ + src/lib/../lib/stdio.h src/lib/../lib/malloc.h src/lib/../lib/../kbd.h \ + src/lib/../lib/../print.h src/lib/elf/elf64.h src/../include/limine.h: src/prompt/lex.h: src/prompt/file.h: +src/prompt/file.h: src/acpi.h: src/common.h: src/ahci.h: @@ -17,8 +17,6 @@ src/lib/ctype.h: src/lib/string.h: src/lib/../lib/stdio.h: src/lib/../lib/malloc.h: -src/lib/../lib/../common.h: src/lib/../lib/../kbd.h: src/lib/../lib/../print.h: -src/lib/stdio.h: -src/print.h: +src/lib/elf/elf64.h: diff --git a/obj/src/main.c.o b/obj/src/main.c.o index 28af1eb..e6e83ff 100644 Binary files a/obj/src/main.c.o and b/obj/src/main.c.o differ diff --git a/src/fat32.h b/src/fat32.h index 2079f03..bdd696d 100644 --- a/src/fat32.h +++ b/src/fat32.h @@ -82,9 +82,7 @@ static u32 fat32_next(int port, fat32_vol_t* vol, u32 cluster) { u32 fat_sect = vol->fat_start + fat_off / TODO_MAKE_ME_DYNAMIC_BLOCK_SIZE; u32 fat_idx = (fat_off & (TODO_MAKE_ME_DYNAMIC_BLOCK_SIZE-1)); - printf("fat_next: cluster=%u fat_off=%u fat_sect=%u byte_off=%u\n", - cluster, fat_off, fat_sect, fat_off); - + u8* buff = (u8*) alloc(4096); if(ahci_read(port, fat_sect, 2, buff) < 0) { printf("fat_next: read failed at lba=%u\n", fat_sect); @@ -192,7 +190,6 @@ static fat32_dirent_t* fat32_find(int port, fat32_vol_t* vol, u32 dir_cluster, c if (strneq(e->name, name83, 8) && strneq(e->ext, name83 + 8, 3)) { fat32_dirent_t* result = (fat32_dirent_t*) alloc(sizeof(fat32_dirent_t)); - printf("\nFOUND: %.8s'.'%3s\n", e->name, e->ext); *result = *e; return result; } @@ -229,19 +226,16 @@ static FILE* fat32_find_path(int port, fat32_vol_t* vol, const char* path) { int len = 0; while (path[len] && path[len] != '/') len++; if (len > 11) return NULL; // can't possibly be valid 8.3 - printn(path, len); memcpy(part, path, len); part[len] = '\0'; path += len; if (*path == '/') path++; - put('\n'); // convert component to 8.3 u8 name83[11]; fat32_to_name83(part, name83); - printf("\nNAME83: %.8s.%.3s\n", name83, name83+8); fat32_dirent_t* e = fat32_find(port, vol, cluster, name83); if (!e) return NULL; @@ -293,6 +287,7 @@ static u8* slurp(struct FILE* file) { sz *= TODO_MAKE_ME_DYNAMIC_BLOCK_SIZE; u8* buff = (u8*) calloc(file->info.file_size, 1); + printf("SLURP: Buffer Copied\n"); if(!buff) { printf("fat32_slurp: %.8s'.'%.3s: Failed to allocate buffer of size %u\n", file->info.name, file->info.ext, file->info.file_size); } @@ -305,4 +300,8 @@ static u8* slurp(struct FILE* file) { } return buff; -} \ No newline at end of file +} + + +extern i8 read_active_port; +extern fat32_vol_t active_vol; \ No newline at end of file diff --git a/src/int.c b/src/int.c index 061e03d..2610703 100644 --- a/src/int.c +++ b/src/int.c @@ -5,9 +5,9 @@ #include "print.h" #include "kbd.h" #include "common.h" - -// for trap debugging -u64 dbg_var = 0; +#include "syscalls.h" +#include "int.h" +#include "lib/stdio.h" pstruct int_desc { u16 addr_low; @@ -60,30 +60,29 @@ void load_idt(void *addr) { extern void draw(u8 vect); -struct cpu_ctx { - u64 r15, r14, r13, r12, r11, r10, r9, r8, rdi, rsi, rdx, rcx, rbx, rax; - - u64 vect; - u64 err; - - u64 iret_rip; - u64 iret_cs; - u64 iret_flags; - u64 iret_rsp; - u64 iret_ss; -}; - -struct cpu_ctx *interrupt_dispatch(struct cpu_ctx *ctx) { - if(ctx->vect = 0x21) { +struct cpu_ctx *interrupt_dispatch(struct cpu_ctx* ctx) { + if(ctx->vect == 0x21) { kbd_handler(); return ctx; } + + if(ctx->vect == 0x80) { + print("SYSCALL\n"); + syscall_handler(ctx); + return ctx; + } + + print("\n[IRQ "); print8(ctx->vect); - print("] with message: "); - print64(dbg_var); + print("] with err: "); + print64(ctx->err); print("\n"); + if(ctx->vect == 0x0D || ctx->vect == 0x0E) { + while(1); + } + return ctx; } @@ -302,5 +301,7 @@ void init_idt(void) { for (int i = 0; i < 256; i++) { set_idt(i, isr_table[i], 0); } + + set_idt(0x80, isr128, 3); load_idt(idt); } diff --git a/src/int.h b/src/int.h new file mode 100644 index 0000000..2e1a8fb --- /dev/null +++ b/src/int.h @@ -0,0 +1,14 @@ +#pragma once + +struct cpu_ctx { + u64 r15, r14, r13, r12, r11, r10, r9, r8, rdi, rsi, rdx, rcx, rbx, rax; + + u64 vect; + u64 err; + + u64 iret_rip; + u64 iret_cs; + u64 iret_flags; + u64 iret_rsp; + u64 iret_ss; +}; \ No newline at end of file diff --git a/src/lib/elf/elf64.h b/src/lib/elf/elf64.h new file mode 100644 index 0000000..3a36982 --- /dev/null +++ b/src/lib/elf/elf64.h @@ -0,0 +1,264 @@ +#pragma once + +#include "../../common.h" +#include "../../lib/stdio.h" +#include "../../lib/malloc.h" + +#pragma pack(push, 1) +typedef struct elf64_header { + u32 MAGIC; /* '\x7FELF' */ + enum : u8 { ELF32 = 1, ELF64 = 2} size; /* 1 for ELF32, 2 for ELF64 */ + enum : u8 { ELF64_LE = 1, ELF64_BE = 2} endianness; /* 1 for little-endian, 2 for big-endian */ + u8 version; /* ELF version */ + u8 abi; /* ABI identification */ + u8 abi_version; /* ABI version */ + u8 padding[7]; /* Padding to align the structure */ + + enum : u16 { + ELF_RELOC = 1, + ELF_EXEC = 2, + ELF_SHARED = 3, + ELF_CORe = 4, + } type; /* 1 for relocatable, 2 for executable, 3 for shared, 4 for core */ + u16 instruction_set; /* Architecture: e.g., EM_X86_64 = 62 */ + u32 elf_version; /* Version of the ELF specification */ + u64 prog_entry_offset; /* Entry point address */ + u64 prog_header_table_offset; /* Program header table offset */ + u64 sect_header_table_offset; /* Section header table offset */ + u32 flags; /* Processor-specific flags */ + u16 header_size; /* Size of this header */ + u16 prog_entry_size; /* Size of program entry */ + u16 prog_entry_count; /* Number of program entries */ + u16 sect_entry_size; /* Size of section entry */ + u16 sect_entry_count; /* Number of section entries */ + u16 sect_index; /* Index of the section header string table */ +} elf64_header_t; + +typedef struct elf64_prog_header { + enum : u32 { + ELF64_IGNORE, + ELF64_LOAD, + ELF64_DYNAMIC, + ELF64_INTERP, + ELF64_NOTE, + } type; + enum : u32 { ELF64_X = 1, ELF64_W = 2, ELF64_R = 4} flags; + u64 data_offset; + u64* vmem_start; + u64 seg_phys; + u64 seg_filesize; + u64 seg_memsize; + u64 req_alignment; +} elf64_prog_header_t; + +typedef struct elf64_sect_header { + u32 name_offset; + enum : u32 { + SHT_NULL = 0, + SHT_PROGBITS = 1, + SHT_SYMTAB = 2, + SHT_STRTAB = 3, + SHT_RELA = 4, + SHT_NOBITS = 8, + SHT_REL = 9, + } type; + u64 flags; + u64 addr; + u64 offset; // offset in file + u64 size; + u32 link; // for RELA: index of associated symbol table section + u32 info; // for RELA: index of section the relocations apply to + u64 addralign; + u64 entsize; +} elf64_sect_header_t; + +typedef struct elf64_sym { + u32 name_offset; + u8 info; // binding (high 4) + type (low 4) + u8 other; + u16 sect_index; + u64 value; // offset within its section for relocatable files + u64 size; +} elf64_sym_t; + +typedef struct elf64_rela { + u64 offset; // offset within the target section to patch + u64 info; // symbol index (high 32) + relocation type (low 32) + i64 addend; +} elf64_rela_t; + +#pragma pack(pop) + +#define ELF_MAGIC 0x464C457F // '\x7FELF' as little-endian u32 +#define R_X86_64_64 1 // S + A +#define R_X86_64_PC32 2 // S + A - P +#define R_X86_64_PLT32 4 // S + A - P (treat same as PC32 for static) +#define R_X86_64_32 10 // S + A (zero-extend to 64) +#define R_X86_64_32S 11 // S + A (sign-extend to 64) + +#define RELA_SYM(info) ((info) >> 32) +#define RELA_TYPE(info) ((u32)(info)) + +static bool elf64_validate(const elf64_header_t *hdr) { + return !((hdr->MAGIC != ELF_MAGIC) + || (hdr->size != ELF64) + || (hdr->endianness != ELF64_LE) + || (hdr->instruction_set != 62)); +} + +static inline void *elf_off(const elf64_header_t *hdr, u64 offset) { + return (void *)((u8 *)hdr + offset); +} + +static inline elf64_sect_header_t *elf_sect(const elf64_header_t *hdr, u64 i) { + return (elf64_sect_header_t *)((u8 *)hdr + + hdr->sect_header_table_offset + + i * hdr->sect_entry_size); +} + +static u64 (*elf64_resolve_entry(const elf64_header_t* hdr, void** sect_bases)) () { + u64 entry_offset = hdr->prog_entry_offset; + + for(u64 i = 0; i < hdr->sect_entry_count; i++) { + elf64_sect_header_t* sh = elf_sect(hdr, i); + if(!sect_bases[i]) continue; + + if(entry_offset >= sh->addr && entry_offset < sh->addr + sh->size) + return (u64 (*)())((u8*) sect_bases[i] + (entry_offset - sh->addr)); + } + + // fallback: offset into sect 1 (.text) + printf("elf64_resolve_entry: using fallback offset into section 1 (.text)\n"); + if (hdr->sect_entry_count > 1 && sect_bases[1]) + return (u64 (*)())((u8 *)sect_bases[1] + entry_offset); + + return NULL; +} + +static void elf64_alloc_section(const elf64_header_t *hdr, + const elf64_sect_header_t *sh, + void **out) { + *out = NULL; + + if (sh->type != SHT_PROGBITS && sh->type != SHT_NOBITS) return; + if (sh->size == 0) return; + + void *mem = calloc(sh->size, 1); + if (!mem) { + print("elf64: calloc failed\n"); + return; + } + + if (sh->type == SHT_PROGBITS) { + u8 *src = (u8 *)elf_off(hdr, sh->offset); + u8 *dst = (u8 *)mem; + for (u64 b = 0; b < sh->size; b++) + dst[b] = src[b]; + } + + *out = mem; +} + +static void **elf64_alloc_sections(const elf64_header_t *hdr) { + u64 n = hdr->sect_entry_count; + + void **bases = calloc(n, sizeof(void *)); + if (!bases) { + print("elf64: calloc failed for section table\n"); + return NULL; + } + + for (u64 i = 0; i < n; i++) + elf64_alloc_section(hdr, elf_sect(hdr, i), &bases[i]); + + return bases; +} + +static void elf64_apply_rela(const elf64_rela_t *rela, + const elf64_sym_t *symtab, + void **section_bases, + void *target_base) { + u64 sym_idx = RELA_SYM(rela->info); + u32 rel_type = RELA_TYPE(rela->info); + + const elf64_sym_t* sym = &symtab[sym_idx]; + + u64 s = (sym->sect_index != 0 && section_bases[sym->sect_index])? + (u64)section_bases[sym->sect_index] + sym->value : 0; + + i64 offset = rela->addend; + u64 reference = (u64)target_base + rela->offset; + + switch(rel_type) { + case R_X86_64_64: + *(u64*)reference = (u64)(s+offset); + break; + case R_X86_64_32: + *(u32*)reference = (u32)(s+offset); + break; + case R_X86_64_32S: + *(i32*)reference = (i32)(s+offset); + break; + case R_X86_64_PC32: + case R_X86_64_PLT32: + *(i32*)reference = (i32)(s+offset - (i64)reference); + break; + default: + printf("elf64_apply_rela: unhandled relocation type\n"); + break; + } +} + +static void elf64_process_rela_section(const elf64_header_t *hdr, + const elf64_sect_header_t *rela_sh, + void **section_bases) { + u64 target_idx = rela_sh->info; + if (!section_bases[target_idx]) return; + + elf64_sect_header_t *sym_sh = elf_sect(hdr, rela_sh->link); + elf64_sym_t *symtab = (elf64_sym_t *)elf_off(hdr, sym_sh->offset); + elf64_rela_t *relas = (elf64_rela_t *)elf_off(hdr, rela_sh->offset); + u64 n_relas = rela_sh->size / sizeof(elf64_rela_t); + + for (u64 r = 0; r < n_relas; r++) + elf64_apply_rela(&relas[r], symtab, section_bases, section_bases[target_idx]); +} + +static void elf64_relocate(const elf64_header_t *hdr, void **section_bases) { + for (u64 i = 0; i < hdr->sect_entry_count; i++) { + elf64_sect_header_t *sh = elf_sect(hdr, i); + if (sh->type == SHT_RELA) + elf64_process_rela_section(hdr, sh, section_bases); + } +} + +static u64 elf64_load(elf64_header_t* hdr) { + if(!hdr || !elf64_validate(hdr)) { + printf("elf64_load: Invalid ELF64 header\n"); + return -1; + } + + void** sect_bases = elf64_alloc_sections(hdr); + if(!sect_bases) { + printf("elf64_load: Failed to allocate sections.\n"); + } + + elf64_relocate(hdr, sect_bases); + + u64 (*entry)() = elf64_resolve_entry(hdr, sect_bases); + + if(!entry) { + printf("elf64_load: failed to resolve entry point\n"); + return -1; + } + + for(size_t i = 0; i < 64; i++) { + char c = ((char*)entry)[i]; + print8(c); + put(((i & 7) == 7)? '\n' : ' '); + } + printf("elf64_load: jumping to entry\n"); + u64 ret = entry(); + printf("elf64_load: returning"); + return ret; +} \ No newline at end of file diff --git a/src/lib/sys.h b/src/lib/sys.h new file mode 100644 index 0000000..8785bfd --- /dev/null +++ b/src/lib/sys.h @@ -0,0 +1,6 @@ +#pragma once + +#define SYS_OPEN 0 +#define SYS_SLURP 1 + + diff --git a/src/main.c b/src/main.c index 4b5dade..4b6b25c 100644 --- a/src/main.c +++ b/src/main.c @@ -16,6 +16,7 @@ void print_tok(struct token* tok); #include "fat32.h" #include "print.h" #include "lib/stdio.h" +#include "lib/elf/elf64.h" // credit owed to https://wiki.osdev.org/Limine_Bare_Bones for the limine setup // code @@ -265,24 +266,24 @@ void kmain() { ahci_init(); - i8 port = -1; + read_active_port = -1; for(u8 i = 0; i < 32; i++) { if(ahci_port_active(i)) { // assume we want the first port - if(port < 0) - port = i; + if(read_active_port < 0) + read_active_port = i; printf("Port %d is active!\n", i); } } - if(port < 0) { + if(read_active_port < 0) { printf("Couldn't find a port to read the FS from :(\n"); hang(); } fat32_mbr_t* mbr = alloc(1<<12); - ahci_read(port, 0, 1, mbr); + ahci_read(read_active_port, 0, 1, mbr); i8 bootpart = -1; fat32_mbr_partition_t bpart; @@ -307,33 +308,23 @@ void kmain() { printf("Failed to find boot partition :(\n"); } - // reuse buffer fat32_bpb_t* bpb = (fat32_bpb_t*) mbr; mbr = NULL; // hardcode for now :( u32 part_lba = 2048; - ahci_read(port, part_lba, 1, bpb); + ahci_read(read_active_port, part_lba, 1, bpb); - fat32_vol_t vol = vol_from_bpb(bpb, part_lba); + active_vol = vol_from_bpb(bpb, part_lba); - u64 root_lba = fat32_cluster_to_lba(&vol, vol.root_cluster); + u64 root_lba = fat32_cluster_to_lba(&active_vol, active_vol.root_cluster); printf("root_lba=%u\n", (u32)root_lba); u8 *raw = alloc(4096); - ahci_read(port, root_lba, vol.sectors_per_cluster, raw); - printf("raw: "); - for(int i = 0; i < 64; i++) - printf("%x ", raw[i]); - printf("\n"); + ahci_read(read_active_port, root_lba, active_vol.sectors_per_cluster, raw); - ls(port, 0, &vol, vol.root_cluster); - - struct FILE* fortune = fat32_find_path(port, &vol, "fort/fortu.ne"); - - - printf("Fortune size: %d\n", fortune->info.file_size); + struct FILE* fortune = fat32_find_path(read_active_port, &active_vol, "fort/fortu.ne"); u8* fort = slurp(fortune); @@ -341,5 +332,20 @@ void kmain() { free(fort); + FILE* execfile = fat32_find_path(read_active_port, &active_vol, "/usr/bin/test"); + + if(!execfile) { + printf("Didn't find executable :("); + } else { + printf("Found:\n"); + elf64_header_t* hdr = (elf64_header_t*) slurp(execfile); + char* ret = (char*)elf64_load(hdr); + printf("AFTER:\n"); + print64((u64)ret); + } + + while(1); + + hang(); } diff --git a/src/print.c b/src/print.c index 1d53c92..4e47d51 100644 --- a/src/print.c +++ b/src/print.c @@ -28,8 +28,8 @@ void print_init(struct limine_framebuffer *fb) { static void scrollback() { memmove((void *)fb_scr, (void *)(fb_scr + fb_width * GLYPH_HEIGHT), fb_width * (fb_height - GLYPH_HEIGHT) * sizeof(u32)); - size_t last_row_start = (term_height - 1) * fb_width; - for (size_t i = 0; i < fb_width; i++) { + size_t last_row_start = (term_height - 1) * GLYPH_HEIGHT * fb_width; + for (size_t i = 0; i < fb_width * GLYPH_HEIGHT; i++) { fb_scr[last_row_start + i] = bg; } } diff --git a/src/syscalls.c b/src/syscalls.c new file mode 100644 index 0000000..3284040 --- /dev/null +++ b/src/syscalls.c @@ -0,0 +1,146 @@ +#include "syscalls.h" +#include "int.h" +#include "fat32.h" +#include "lib/stdio.h" + +static FILE* filetable[256]; +size_t file_idx = 0; + + +i8 read_active_port = -1; +fat32_vol_t active_vol; + +static void sys_open_impl(struct cpu_ctx* ctx) { + printf("Open called on %s\n", ctx->rdi); + if(file_idx >= 256) { + printf("sys_open: ran out of files"); + ctx->rax = -1; + return; + } + + filetable[file_idx] = fat32_find_path(read_active_port, &active_vol, (u8*)ctx->rdi); + + if(!filetable[file_idx]) { + printf("sys_open: could not find path: %s\n", ctx->rdi); + ctx->rax = -1; + return; + } + + ctx->rax = file_idx++; +} + +static void sys_slurp_impl(struct cpu_ctx* ctx) { + printf("SLURP CALLED\n"); + i64 fd = ctx->rdi; + if(fd >= (i64)file_idx || fd < 0) { + printf("sys_slurp: ran out of files\m"); + ctx->rax = 0; + return; + } + + ctx->rax = (u64) slurp(filetable[fd]); +} + +static syscall_t syscalls[] = { + [SYS_OPEN] sys_open_impl, + [SYS_SLURP] sys_slurp_impl, +}; + +// Function to dump the contents of cpu_ctx +void dump_cpu_ctx(struct cpu_ctx *ctx) { + print("CPU Context Dump:\n"); + + print("r15: "); + print64(ctx->r15); + print("\n"); + + print("r14: "); + print64(ctx->r14); + print("\n"); + + print("r13: "); + print64(ctx->r13); + print("\n"); + + print("r12: "); + print64(ctx->r12); + print("\n"); + + print("r11: "); + print64(ctx->r11); + print("\n"); + + print("r10: "); + print64(ctx->r10); + print("\n"); + + print("r9: "); + print64(ctx->r9); + print("\n"); + + print("r8: "); + print64(ctx->r8); + print("\n"); + + print("rdi: "); + print64(ctx->rdi); + print("\n"); + + print("rsi: "); + print64(ctx->rsi); + print("\n"); + + print("rdx: "); + print64(ctx->rdx); + print("\n"); + + print("rcx: "); + print64(ctx->rcx); + print("\n"); + + print("rbx: "); + print64(ctx->rbx); + print("\n"); + + print("rax: "); + print64(ctx->rax); + print("\n"); + + print("vect: "); + print64(ctx->vect); + print("\n"); + + print("err: "); + print64(ctx->err); + print("\n"); + + print("iret_rip: "); + print64(ctx->iret_rip); + print("\n"); + + print("iret_cs: "); + print64(ctx->iret_cs); + print("\n"); + + print("iret_flags: "); + print64(ctx->iret_flags); + print("\n"); + + print("iret_rsp: "); + print64(ctx->iret_rsp); + print("\n"); + + print("iret_ss: "); + print64(ctx->iret_ss); + print("\n"); +} + +void syscall_handler(struct cpu_ctx* ctx) { + + dump_cpu_ctx(ctx); + + if(ctx->rax < 2) + syscalls[ctx->rax](ctx); + + printf("SYSCALL COMPLETE\n"); +} \ No newline at end of file diff --git a/src/syscalls.h b/src/syscalls.h new file mode 100644 index 0000000..693040d --- /dev/null +++ b/src/syscalls.h @@ -0,0 +1,8 @@ +#pragma once +#include "common.h" +#include "lib/sys.h" +#include "int.h" + +typedef void (*syscall_t)(struct cpu_ctx*); + +void syscall_handler(struct cpu_ctx* ctx);