Initial elf64 loading

This commit is contained in:
Conál Paxton 2026-03-05 21:38:31 -05:00
parent 993092a854
commit dd2f204ab5
19 changed files with 531 additions and 63 deletions

3
.gitignore vendored
View File

@ -1,2 +1,5 @@
obj/src/
obj/ obj/
bin/ bin/
bin/os
image.hdd

BIN
bin/os

Binary file not shown.

18
fortune
View File

@ -1,2 +1,16 @@
Many hands make light work. _/I\_____________o______________o___/I\ l * / /_/ * __ ' .* l
-- John Heywood 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\ [__][__][]/ {}{}{}{}{}{}<R>
In Ellen's house it is warm and toasty while fuzzies play in the snow outside.

BIN
image.hdd

Binary file not shown.

2
limine

@ -1 +1 @@
Subproject commit e0e61c946933696453f591da525ab1f8a66a553d Subproject commit eecf8d682a749701691e31b89f66f330f525c611

View File

@ -19,11 +19,14 @@ make -C limine
mformat -i image.hdd@@1M -F mformat -i image.hdd@@1M -F
# Make relevant subdirectories. # 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. # Copy over the relevant files.
mcopy -i image.hdd@@1M bin/os ::/boot 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.conf limine/limine-bios.sys ::/boot/limine
mcopy -i image.hdd@@1M limine/BOOTX64.EFI ::/EFI/BOOT 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 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 mcopy -i image.hdd@@1M fortune ::/fort/fortu.ne

View File

@ -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/apic.h:
src/common.h: src/common.h:
src/print.h: src/print.h:
src/kbd.h: src/kbd.h:
src/syscalls.h:
src/lib/sys.h:
src/int.h:
src/lib/stdio.h:
src/lib/malloc.h:

Binary file not shown.

View File

@ -1,12 +1,12 @@
obj/src/main.c.o: src/main.c src/../include/limine.h src/prompt/lex.h \ 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/prompt/file.h src/prompt/file.h src/acpi.h src/common.h src/ahci.h \
src/apic.h src/fat32.h src/lib/ctype.h src/lib/string.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/stdio.h src/lib/../lib/malloc.h src/lib/../lib/../kbd.h \
src/lib/../lib/../common.h src/lib/../lib/../kbd.h \ src/lib/../lib/../print.h src/lib/elf/elf64.h
src/lib/../lib/../print.h src/lib/stdio.h src/print.h
src/../include/limine.h: src/../include/limine.h:
src/prompt/lex.h: src/prompt/lex.h:
src/prompt/file.h: src/prompt/file.h:
src/prompt/file.h:
src/acpi.h: src/acpi.h:
src/common.h: src/common.h:
src/ahci.h: src/ahci.h:
@ -17,8 +17,6 @@ src/lib/ctype.h:
src/lib/string.h: src/lib/string.h:
src/lib/../lib/stdio.h: src/lib/../lib/stdio.h:
src/lib/../lib/malloc.h: src/lib/../lib/malloc.h:
src/lib/../lib/../common.h:
src/lib/../lib/../kbd.h: src/lib/../lib/../kbd.h:
src/lib/../lib/../print.h: src/lib/../lib/../print.h:
src/lib/stdio.h: src/lib/elf/elf64.h:
src/print.h:

Binary file not shown.

View File

@ -82,8 +82,6 @@ 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_sect = vol->fat_start + fat_off / TODO_MAKE_ME_DYNAMIC_BLOCK_SIZE;
u32 fat_idx = (fat_off & (TODO_MAKE_ME_DYNAMIC_BLOCK_SIZE-1)); 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); u8* buff = (u8*) alloc(4096);
if(ahci_read(port, fat_sect, 2, buff) < 0) { if(ahci_read(port, fat_sect, 2, buff) < 0) {
@ -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)) { if (strneq(e->name, name83, 8) && strneq(e->ext, name83 + 8, 3)) {
fat32_dirent_t* result = (fat32_dirent_t*) alloc(sizeof(fat32_dirent_t)); fat32_dirent_t* result = (fat32_dirent_t*) alloc(sizeof(fat32_dirent_t));
printf("\nFOUND: %.8s'.'%3s\n", e->name, e->ext);
*result = *e; *result = *e;
return result; return result;
} }
@ -229,19 +226,16 @@ static FILE* fat32_find_path(int port, fat32_vol_t* vol, const char* path) {
int len = 0; int len = 0;
while (path[len] && path[len] != '/') len++; while (path[len] && path[len] != '/') len++;
if (len > 11) return NULL; // can't possibly be valid 8.3 if (len > 11) return NULL; // can't possibly be valid 8.3
printn(path, len);
memcpy(part, path, len); memcpy(part, path, len);
part[len] = '\0'; part[len] = '\0';
path += len; path += len;
if (*path == '/') path++; if (*path == '/') path++;
put('\n');
// convert component to 8.3 // convert component to 8.3
u8 name83[11]; u8 name83[11];
fat32_to_name83(part, name83); fat32_to_name83(part, name83);
printf("\nNAME83: %.8s.%.3s\n", name83, name83+8);
fat32_dirent_t* e = fat32_find(port, vol, cluster, name83); fat32_dirent_t* e = fat32_find(port, vol, cluster, name83);
if (!e) return NULL; if (!e) return NULL;
@ -293,6 +287,7 @@ static u8* slurp(struct FILE* file) {
sz *= TODO_MAKE_ME_DYNAMIC_BLOCK_SIZE; sz *= TODO_MAKE_ME_DYNAMIC_BLOCK_SIZE;
u8* buff = (u8*) calloc(file->info.file_size, 1); u8* buff = (u8*) calloc(file->info.file_size, 1);
printf("SLURP: Buffer Copied\n");
if(!buff) { 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); printf("fat32_slurp: %.8s'.'%.3s: Failed to allocate buffer of size %u\n", file->info.name, file->info.ext, file->info.file_size);
} }
@ -306,3 +301,7 @@ static u8* slurp(struct FILE* file) {
return buff; return buff;
} }
extern i8 read_active_port;
extern fat32_vol_t active_vol;

View File

@ -5,9 +5,9 @@
#include "print.h" #include "print.h"
#include "kbd.h" #include "kbd.h"
#include "common.h" #include "common.h"
#include "syscalls.h"
// for trap debugging #include "int.h"
u64 dbg_var = 0; #include "lib/stdio.h"
pstruct int_desc { pstruct int_desc {
u16 addr_low; u16 addr_low;
@ -60,30 +60,29 @@ void load_idt(void *addr) {
extern void draw(u8 vect); 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) { struct cpu_ctx *interrupt_dispatch(struct cpu_ctx* ctx) {
if(ctx->vect = 0x21) { if(ctx->vect == 0x21) {
kbd_handler(); kbd_handler();
return ctx; return ctx;
} }
if(ctx->vect == 0x80) {
print("SYSCALL\n");
syscall_handler(ctx);
return ctx;
}
print("\n[IRQ "); print("\n[IRQ ");
print8(ctx->vect); print8(ctx->vect);
print("] with message: "); print("] with err: ");
print64(dbg_var); print64(ctx->err);
print("\n"); print("\n");
if(ctx->vect == 0x0D || ctx->vect == 0x0E) {
while(1);
}
return ctx; return ctx;
} }
@ -302,5 +301,7 @@ void init_idt(void) {
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; i++) {
set_idt(i, isr_table[i], 0); set_idt(i, isr_table[i], 0);
} }
set_idt(0x80, isr128, 3);
load_idt(idt); load_idt(idt);
} }

14
src/int.h Normal file
View File

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

264
src/lib/elf/elf64.h Normal file
View File

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

6
src/lib/sys.h Normal file
View File

@ -0,0 +1,6 @@
#pragma once
#define SYS_OPEN 0
#define SYS_SLURP 1

View File

@ -16,6 +16,7 @@ void print_tok(struct token* tok);
#include "fat32.h" #include "fat32.h"
#include "print.h" #include "print.h"
#include "lib/stdio.h" #include "lib/stdio.h"
#include "lib/elf/elf64.h"
// credit owed to https://wiki.osdev.org/Limine_Bare_Bones for the limine setup // credit owed to https://wiki.osdev.org/Limine_Bare_Bones for the limine setup
// code // code
@ -265,24 +266,24 @@ void kmain() {
ahci_init(); ahci_init();
i8 port = -1; read_active_port = -1;
for(u8 i = 0; i < 32; i++) { for(u8 i = 0; i < 32; i++) {
if(ahci_port_active(i)) { if(ahci_port_active(i)) {
// assume we want the first port // assume we want the first port
if(port < 0) if(read_active_port < 0)
port = i; read_active_port = i;
printf("Port %d is active!\n", 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"); printf("Couldn't find a port to read the FS from :(\n");
hang(); hang();
} }
fat32_mbr_t* mbr = alloc(1<<12); fat32_mbr_t* mbr = alloc(1<<12);
ahci_read(port, 0, 1, mbr); ahci_read(read_active_port, 0, 1, mbr);
i8 bootpart = -1; i8 bootpart = -1;
fat32_mbr_partition_t bpart; fat32_mbr_partition_t bpart;
@ -307,33 +308,23 @@ void kmain() {
printf("Failed to find boot partition :(\n"); printf("Failed to find boot partition :(\n");
} }
// reuse buffer // reuse buffer
fat32_bpb_t* bpb = (fat32_bpb_t*) mbr; fat32_bpb_t* bpb = (fat32_bpb_t*) mbr;
mbr = NULL; mbr = NULL;
// hardcode for now :( // hardcode for now :(
u32 part_lba = 2048; 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); printf("root_lba=%u\n", (u32)root_lba);
u8 *raw = alloc(4096); u8 *raw = alloc(4096);
ahci_read(port, root_lba, vol.sectors_per_cluster, raw); ahci_read(read_active_port, root_lba, active_vol.sectors_per_cluster, raw);
printf("raw: ");
for(int i = 0; i < 64; i++)
printf("%x ", raw[i]);
printf("\n");
ls(port, 0, &vol, vol.root_cluster); struct FILE* fortune = fat32_find_path(read_active_port, &active_vol, "fort/fortu.ne");
struct FILE* fortune = fat32_find_path(port, &vol, "fort/fortu.ne");
printf("Fortune size: %d\n", fortune->info.file_size);
u8* fort = slurp(fortune); u8* fort = slurp(fortune);
@ -341,5 +332,20 @@ void kmain() {
free(fort); 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(); hang();
} }

View File

@ -28,8 +28,8 @@ void print_init(struct limine_framebuffer *fb) {
static void scrollback() { static void scrollback() {
memmove((void *)fb_scr, (void *)(fb_scr + fb_width * GLYPH_HEIGHT), memmove((void *)fb_scr, (void *)(fb_scr + fb_width * GLYPH_HEIGHT),
fb_width * (fb_height - GLYPH_HEIGHT) * sizeof(u32)); fb_width * (fb_height - GLYPH_HEIGHT) * sizeof(u32));
size_t last_row_start = (term_height - 1) * fb_width; size_t last_row_start = (term_height - 1) * GLYPH_HEIGHT * fb_width;
for (size_t i = 0; i < fb_width; i++) { for (size_t i = 0; i < fb_width * GLYPH_HEIGHT; i++) {
fb_scr[last_row_start + i] = bg; fb_scr[last_row_start + i] = bg;
} }
} }

146
src/syscalls.c Normal file
View File

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

8
src/syscalls.h Normal file
View File

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