slight progress
This commit is contained in:
parent
dd2f204ab5
commit
897dced938
@ -28,5 +28,5 @@ 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 mnt/usr/bin/test.o ::/usr/bin/test
|
||||
mcopy -i image.hdd@@1M fortune ::/fort/fortu.ne
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
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/syscalls.h src/lib/sys.h src/int.h src/lib/stdio.h \
|
||||
src/lib/malloc.h src/lib/../common.h src/lib/../kbd.h \
|
||||
src/lib/../print.h
|
||||
src/apic.h:
|
||||
src/common.h:
|
||||
src/print.h:
|
||||
@ -9,3 +11,6 @@ src/lib/sys.h:
|
||||
src/int.h:
|
||||
src/lib/stdio.h:
|
||||
src/lib/malloc.h:
|
||||
src/lib/../common.h:
|
||||
src/lib/../kbd.h:
|
||||
src/lib/../print.h:
|
||||
|
||||
BIN
obj/src/int.c.o
BIN
obj/src/int.c.o
Binary file not shown.
@ -1,12 +1,14 @@
|
||||
obj/src/main.c.o: src/main.c 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 \
|
||||
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/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/lib/elf/elf64.h src/lib/elf/../../common.h \
|
||||
src/lib/elf/../../lib/stdio.h src/lib/elf/../../lib/malloc.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,6 +19,12 @@ 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:
|
||||
src/lib/elf/../../common.h:
|
||||
src/lib/elf/../../lib/stdio.h:
|
||||
src/lib/elf/../../lib/malloc.h:
|
||||
|
||||
BIN
obj/src/main.c.o
BIN
obj/src/main.c.o
Binary file not shown.
13
src/int.c
13
src/int.c
@ -61,27 +61,32 @@ void load_idt(void *addr) {
|
||||
extern void draw(u8 vect);
|
||||
|
||||
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("COMING THROUGH");
|
||||
print("\n[IRQ ");
|
||||
print8(ctx->vect);
|
||||
print("] with err: ");
|
||||
print64(ctx->err);
|
||||
print(" and cr2: ");
|
||||
u64 cr2;
|
||||
asm volatile("mov %%cr2, %0" : "=r"(cr2));
|
||||
print64(cr2);
|
||||
printf(" rip: 0x");
|
||||
print64(ctx->iret_rip);
|
||||
print("\n");
|
||||
|
||||
if(ctx->vect == 0x0D || ctx->vect == 0x0E) {
|
||||
if(ctx->vect < 0x10)
|
||||
while(1);
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@ -72,23 +72,23 @@ char kbd_buffer_getc() {
|
||||
return c;
|
||||
}
|
||||
|
||||
static u8 held_map[0x100/16];
|
||||
u8 kbd_held_map[0x100/16];
|
||||
static void hold_key(u8 key) {
|
||||
key &= (0x100/2)-1;
|
||||
|
||||
held_map[key>>3] |= (1 << (key & 7));
|
||||
kbd_held_map[key>>3] |= (1 << (key & 7));
|
||||
}
|
||||
|
||||
static void release_key(u8 key) {
|
||||
key &= (0x100/2)-1;
|
||||
|
||||
held_map[key>>3] &= ~(1 << (key & 7));
|
||||
kbd_held_map[key>>3] &= ~(1 << (key & 7));
|
||||
}
|
||||
|
||||
static bool key_held(u8 key) {
|
||||
key &= (0x100/2)-1;
|
||||
|
||||
return (held_map[key>>3] & (1 << (key & 7)));
|
||||
return (kbd_held_map[key>>3] & (1 << (key & 7)));
|
||||
}
|
||||
|
||||
void kbd_handler() {
|
||||
|
||||
@ -5,139 +5,276 @@
|
||||
#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 */
|
||||
|
||||
u32 MAGIC; /* '\x7FELF' as LE u32 = 0x464C457F */
|
||||
|
||||
enum : u8 {
|
||||
ELF32 = 1,
|
||||
ELF64 = 2,
|
||||
} size; /* 1 = ELF32, 2 = ELF64 */
|
||||
|
||||
enum : u8 {
|
||||
ELF64_LE = 1,
|
||||
ELF64_BE = 2,
|
||||
} endianness; /* 1 = little-endian, 2 = big-endian */
|
||||
|
||||
u8 version; /* ELF spec version (always 1) */
|
||||
u8 abi; /* OS/ABI identifier */
|
||||
u8 abi_version; /* ABI version */
|
||||
u8 padding[7]; /* Reserved, must be zero */
|
||||
|
||||
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 */
|
||||
ELF_RELOC = 1, /* Relocatable object */
|
||||
ELF_EXEC = 2, /* Executable */
|
||||
ELF_SHARED = 3, /* Shared object */
|
||||
ELF_CORE = 4, /* Core dump */
|
||||
} type;
|
||||
|
||||
u16 instruction_set; /* Architecture (EM_X86_64 = 62) */
|
||||
u32 elf_version; /* ELF version (always 1) */
|
||||
u64 prog_entry_offset; /* Virtual entry-point address */
|
||||
u64 prog_header_table_offset;/* Offset of program header table */
|
||||
u64 sect_header_table_offset;/* Offset of section header table */
|
||||
u32 flags; /* Processor-specific flags */
|
||||
u16 header_size; /* Size of this header (64 bytes) */
|
||||
u16 prog_entry_size; /* Size of one program header entry */
|
||||
u16 prog_entry_count; /* Number of program header entries */
|
||||
u16 sect_entry_size; /* Size of one section header entry */
|
||||
u16 sect_entry_count; /* Number of section header entries */
|
||||
u16 sect_index; /* Section-name string table index */
|
||||
} 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;
|
||||
enum : u32 {
|
||||
ELF64_PT_NULL = 0,
|
||||
ELF64_PT_LOAD = 1,
|
||||
ELF64_PT_DYNAMIC = 2,
|
||||
ELF64_PT_INTERP = 3,
|
||||
ELF64_PT_NOTE = 4,
|
||||
} type;
|
||||
enum : u32 {
|
||||
ELF64_PF_X = 1,
|
||||
ELF64_PF_W = 2,
|
||||
ELF64_PF_R = 4,
|
||||
} flags;
|
||||
u64 data_offset; /* Offset of segment data in file */
|
||||
u64 *vmem_start; /* Desired virtual load address */
|
||||
u64 seg_phys; /* Physical address (often ignored) */
|
||||
u64 seg_filesize; /* Bytes in file image of segment */
|
||||
u64 seg_memsize; /* Bytes in memory image (>= filesize) */
|
||||
u64 req_alignment; /* Required alignment (power of 2) */
|
||||
} elf64_prog_header_t;
|
||||
|
||||
typedef struct elf64_sect_header {
|
||||
u32 name_offset;
|
||||
u32 name_offset; /* Offset into .shstrtab */
|
||||
enum : u32 {
|
||||
SHT_NULL = 0,
|
||||
SHT_PROGBITS = 1,
|
||||
SHT_SYMTAB = 2,
|
||||
SHT_STRTAB = 3,
|
||||
SHT_RELA = 4,
|
||||
SHT_NOBITS = 8,
|
||||
SHT_REL = 9,
|
||||
SHT_NULL = 0, /* Inactive section */
|
||||
SHT_PROGBITS = 1, /* Program-defined data (.text, .data, …) */
|
||||
SHT_SYMTAB = 2, /* Full symbol table */
|
||||
SHT_STRTAB = 3, /* String table */
|
||||
SHT_RELA = 4, /* Relocation with explicit addends */
|
||||
SHT_HASH = 5, /* Symbol hash table */
|
||||
SHT_DYNAMIC = 6, /* Dynamic linking info */
|
||||
SHT_NOTE = 7, /* Notes */
|
||||
SHT_NOBITS = 8, /* Occupies no file space (.bss) */
|
||||
SHT_REL = 9, /* Relocation without explicit addends */
|
||||
SHT_DYNSYM = 11, /* Dynamic linker symbol table */
|
||||
} 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;
|
||||
u64 addr; /* Load address (0 for relocatable) */
|
||||
u64 offset; /* Offset of section data in file */
|
||||
u64 size; /* Size of section data in file */
|
||||
u32 link; /* Section link index (type-dependent) */
|
||||
u32 info; /* Extra info (type-dependent) */
|
||||
u64 addralign; /* Required alignment (power of 2) */
|
||||
u64 entsize; /* Size of fixed-size entries, if any */
|
||||
} elf64_sect_header_t;
|
||||
|
||||
/* Section-header flags */
|
||||
#define SHF_WRITE 0x1ULL /* Writable at runtime */
|
||||
#define SHF_ALLOC 0x2ULL /* Occupies memory at runtime */
|
||||
#define SHF_EXECINSTR 0x4ULL /* Contains executable instructions */
|
||||
|
||||
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;
|
||||
u32 name_offset; /* Offset into owning string table */
|
||||
u8 info; /* Binding (high 4 bits) | Type (low 4 bits) */
|
||||
u8 other; /* Visibility (low 2 bits) */
|
||||
u16 sect_index; /* Section index (SHN_* or section number) */
|
||||
u64 value; /* Symbol value / offset within section */
|
||||
u64 size; /* Size of the object / function */
|
||||
} 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;
|
||||
u64 offset; /* Offset within target section to patch */
|
||||
u64 info; /* Symbol index (high 32) | type (low 32) */
|
||||
i64 addend; /* Explicit 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 ELF_MAGIC 0x464C457FU /* '\x7FELF' in little-endian u32 */
|
||||
|
||||
#define RELA_SYM(info) ((info) >> 32)
|
||||
/* x86-64 relocation types (System V ABI) */
|
||||
#define R_X86_64_NONE 0 /* No relocation */
|
||||
#define R_X86_64_64 1 /* S + A (64-bit) */
|
||||
#define R_X86_64_PC32 2 /* S + A - P (32-bit PC-relative) */
|
||||
#define R_X86_64_GOT32 3 /* G + A (32-bit GOT offset) */
|
||||
#define R_X86_64_PLT32 4 /* L + A - P (treated as PC32 for static linking) */
|
||||
#define R_X86_64_32 10 /* S + A, zero-extend to 64 bits */
|
||||
#define R_X86_64_32S 11 /* S + A, sign-extend to 64 bits */
|
||||
#define R_X86_64_PC64 24 /* S + A - P (64-bit PC-relative) */
|
||||
|
||||
/* Special section indices */
|
||||
#define SHN_UNDEF 0 /* Undefined / external symbol */
|
||||
#define SHN_ABS 0xFFF1U /* Absolute value, not relocated */
|
||||
#define SHN_COMMON 0xFFF2U /* Common block */
|
||||
|
||||
/* Symbol binding (high 4 bits of info) */
|
||||
#define STB_LOCAL 0
|
||||
#define STB_GLOBAL 1
|
||||
#define STB_WEAK 2
|
||||
#define ELF64_ST_BIND(info) ((info) >> 4)
|
||||
|
||||
/* Symbol type (low 4 bits of info) */
|
||||
#define STT_NOTYPE 0
|
||||
#define STT_OBJECT 1
|
||||
#define STT_FUNC 2
|
||||
#define STT_SECTION 3
|
||||
#define STT_FILE 4
|
||||
#define ELF64_ST_TYPE(info) ((info) & 0xFU)
|
||||
|
||||
/* Symbol visibility (low 2 bits of other) */
|
||||
#define STV_DEFAULT 0
|
||||
#define STV_INTERNAL 1
|
||||
#define STV_HIDDEN 2
|
||||
#define STV_PROTECTED 3
|
||||
|
||||
/* Pack/unpack rela.info */
|
||||
#define RELA_SYM(info) ((u64)(info) >> 32)
|
||||
#define RELA_TYPE(info) ((u32)(info))
|
||||
#define RELA_INFO(sym, type) (((u64)(sym) << 32) | (u32)(type))
|
||||
|
||||
/* Validate an ELF64 LE x86-64 header. */
|
||||
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));
|
||||
if (!hdr) {
|
||||
printf("elf64_validate: NULL header\n");
|
||||
return false;
|
||||
}
|
||||
if (hdr->MAGIC != ELF_MAGIC) {
|
||||
printf("elf64_validate: bad magic 0x%08X\n", hdr->MAGIC);
|
||||
return false;
|
||||
}
|
||||
if (hdr->size != ELF64) {
|
||||
printf("elf64_validate: not a 64-bit ELF (class=%u)\n", (u32)hdr->size);
|
||||
return false;
|
||||
}
|
||||
if (hdr->endianness != ELF64_LE) {
|
||||
printf("elf64_validate: not little-endian (data=%u)\n", (u32)hdr->endianness);
|
||||
return false;
|
||||
}
|
||||
if (hdr->instruction_set != 62) {
|
||||
printf("elf64_validate: unexpected ISA %u (expected 62 = x86-64)\n",
|
||||
(u32)hdr->instruction_set);
|
||||
return false;
|
||||
}
|
||||
if (hdr->version != 1 || hdr->elf_version != 1) {
|
||||
printf("elf64_validate: unexpected ELF version\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Pointer arithmetic from the raw ELF image base. */
|
||||
static inline void *elf_off(const elf64_header_t *hdr, u64 offset) {
|
||||
return (void *)((u8 *)hdr + offset);
|
||||
}
|
||||
|
||||
/* Return a pointer to section header i. */
|
||||
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;
|
||||
/* Return the string table pointer for section i (must be SHT_STRTAB). */
|
||||
static inline const char *elf_strtab(const elf64_header_t *hdr, u64 i) {
|
||||
if (i == 0 || i >= hdr->sect_entry_count) return NULL;
|
||||
elf64_sect_header_t *sh = elf_sect(hdr, i);
|
||||
if (sh->type != SHT_STRTAB) return NULL;
|
||||
return (const char *)elf_off(hdr, sh->offset);
|
||||
}
|
||||
|
||||
static void elf64_alloc_section(const elf64_header_t *hdr,
|
||||
/* Return a section's name from .shstrtab (NULL if unavailable). */
|
||||
static inline const char *elf_sect_name(const elf64_header_t *hdr,
|
||||
const elf64_sect_header_t *sh) {
|
||||
const char *shstrtab = elf_strtab(hdr, hdr->sect_index);
|
||||
if (!shstrtab) return "<no-shstrtab>";
|
||||
return shstrtab + sh->name_offset;
|
||||
}
|
||||
|
||||
static elf64_sect_header_t *elf64_section_by_name(const elf64_header_t *hdr,
|
||||
const char *name) {
|
||||
const char *shstrtab = elf_strtab(hdr, hdr->sect_index);
|
||||
if (!shstrtab) return NULL;
|
||||
|
||||
for (u64 i = 0; i < hdr->sect_entry_count; i++) {
|
||||
elf64_sect_header_t *sh = elf_sect(hdr, i);
|
||||
const char *sname = shstrtab + sh->name_offset;
|
||||
|
||||
/* Simple strcmp — replace with your lib's version if available. */
|
||||
const char *a = sname, *b = name;
|
||||
while (*a && *a == *b) { a++; b++; }
|
||||
if (*a == *b) return sh;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static u64 elf64_find_symtab_index(const elf64_header_t *hdr) {
|
||||
u64 dynsym_idx = 0;
|
||||
for (u64 i = 1; i < hdr->sect_entry_count; i++) {
|
||||
elf64_sect_header_t *sh = elf_sect(hdr, i);
|
||||
if (sh->type == SHT_SYMTAB) return i;
|
||||
if (sh->type == SHT_DYNSYM && !dynsym_idx) dynsym_idx = i;
|
||||
}
|
||||
return dynsym_idx;
|
||||
}
|
||||
|
||||
static const elf64_sym_t *elf64_lookup_symbol(const elf64_header_t *hdr,
|
||||
const char *name,
|
||||
u64 *sect_idx_out) {
|
||||
u64 symtab_idx = elf64_find_symtab_index(hdr);
|
||||
if (!symtab_idx) return NULL;
|
||||
|
||||
elf64_sect_header_t *sym_sh = elf_sect(hdr, symtab_idx);
|
||||
elf64_sect_header_t *str_sh = elf_sect(hdr, sym_sh->link);
|
||||
const char *strtab = (const char *)elf_off(hdr, str_sh->offset);
|
||||
const elf64_sym_t *syms = (const elf64_sym_t *)elf_off(hdr, sym_sh->offset);
|
||||
u64 n_syms = sym_sh->size / sizeof(elf64_sym_t);
|
||||
|
||||
for (u64 i = 0; i < n_syms; i++) {
|
||||
const char *sname = strtab + syms[i].name_offset;
|
||||
const char *a = sname, *b = name;
|
||||
while (*a && *a == *b) { a++; b++; }
|
||||
if (*a == *b) {
|
||||
if (sect_idx_out) *sect_idx_out = symtab_idx;
|
||||
return &syms[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate memory for a single section and copy its data.
|
||||
*
|
||||
* - SHT_PROGBITS: allocate and copy from file image.
|
||||
* - SHT_NOBITS : allocate and zero (calloc already does this).
|
||||
* - Everything else: *out = NULL (no runtime allocation needed).
|
||||
*/
|
||||
static void elf64_alloc_section(const elf64_header_t *hdr,
|
||||
const elf64_sect_header_t *sh,
|
||||
void **out) {
|
||||
void **out) {
|
||||
*out = NULL;
|
||||
|
||||
if (sh->type != SHT_PROGBITS && sh->type != SHT_NOBITS) return;
|
||||
@ -145,26 +282,34 @@ static void elf64_alloc_section(const elf64_header_t *hdr,
|
||||
|
||||
void *mem = calloc(sh->size, 1);
|
||||
if (!mem) {
|
||||
print("elf64: calloc failed\n");
|
||||
printf("elf64_alloc_section: calloc(%u) failed\n", (unsigned long long)sh->size);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sh->type == SHT_PROGBITS) {
|
||||
u8 *src = (u8 *)elf_off(hdr, sh->offset);
|
||||
u8 *dst = (u8 *)mem;
|
||||
const u8 *src = (const u8 *)elf_off(hdr, sh->offset);
|
||||
u8 *dst = (u8 *)mem;
|
||||
for (u64 b = 0; b < sh->size; b++)
|
||||
dst[b] = src[b];
|
||||
}
|
||||
/* SHT_NOBITS (.bss) stays zeroed from calloc. */
|
||||
|
||||
*out = mem;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and initialise all allocatable sections.
|
||||
* Returns a heap-allocated array of (sect_entry_count) void* pointers.
|
||||
* Non-allocatable sections have their pointer set to NULL.
|
||||
* The caller must free this array (and each non-NULL element) when done.
|
||||
*/
|
||||
static void **elf64_alloc_sections(const elf64_header_t *hdr) {
|
||||
u64 n = hdr->sect_entry_count;
|
||||
|
||||
void **bases = calloc(n, sizeof(void *));
|
||||
void **bases = (void **)calloc(n, sizeof(void *));
|
||||
if (!bases) {
|
||||
print("elf64: calloc failed for section table\n");
|
||||
printf("elf64_alloc_sections: calloc failed for %u-entry table\n",
|
||||
(unsigned long long)n);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -174,6 +319,32 @@ static void **elf64_alloc_sections(const elf64_header_t *hdr) {
|
||||
return bases;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free all sections allocated by elf64_alloc_sections, then free the array.
|
||||
*/
|
||||
static void elf64_free_sections(void **section_bases, u64 count) {
|
||||
if (!section_bases) return;
|
||||
for (u64 i = 0; i < count; i++)
|
||||
if (section_bases[i]) free(section_bases[i]);
|
||||
free(section_bases);
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply a single RELA relocation.
|
||||
*
|
||||
* Formulae (System V AMD64 ABI):
|
||||
* R_X86_64_64 : *(u64*)P = S + A
|
||||
* R_X86_64_32 : *(u32*)P = (u32)(S + A) [zero-extend]
|
||||
* R_X86_64_32S : *(i32*)P = (i32)(S + A) [sign-extend]
|
||||
* R_X86_64_PC32 : *(i32*)P = (i32)(S + A - P) [PC-relative]
|
||||
* R_X86_64_PLT32: same as PC32 for static linking
|
||||
* R_X86_64_PC64 : *(i64*)P = S + A - P [64-bit PC-relative]
|
||||
*
|
||||
* Where:
|
||||
* S = runtime address of the referenced symbol
|
||||
* A = explicit addend (rela->addend)
|
||||
* P = runtime address of the location to be patched
|
||||
*/
|
||||
static void elf64_apply_rela(const elf64_rela_t *rela,
|
||||
const elf64_sym_t *symtab,
|
||||
void **section_bases,
|
||||
@ -181,41 +352,85 @@ static void elf64_apply_rela(const elf64_rela_t *rela,
|
||||
u64 sym_idx = RELA_SYM(rela->info);
|
||||
u32 rel_type = RELA_TYPE(rela->info);
|
||||
|
||||
const elf64_sym_t* sym = &symtab[sym_idx];
|
||||
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;
|
||||
/* Compute S: the runtime address of the symbol. */
|
||||
u64 s = 0;
|
||||
if (sym->sect_index == SHN_ABS) {
|
||||
/* Absolute symbol — value is the literal address. */
|
||||
s = sym->value;
|
||||
} else if (sym->sect_index != SHN_UNDEF
|
||||
&& sym->sect_index != SHN_COMMON
|
||||
&& section_bases[sym->sect_index]) {
|
||||
s = (u64)section_bases[sym->sect_index] + sym->value;
|
||||
} else if (sym->sect_index == SHN_UNDEF) {
|
||||
/* Unresolved external — only fatal for non-weak symbols. */
|
||||
if (ELF64_ST_BIND(sym->info) != STB_WEAK) {
|
||||
printf("elf64_apply_rela: unresolved non-weak symbol (sym_idx=u, type=%u)\n",
|
||||
(unsigned long long)sym_idx, rel_type);
|
||||
}
|
||||
/* For weak unresolved symbols, s remains 0 (ABI-defined behaviour). */
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
/* P: the runtime address of the patch location. */
|
||||
u64 p = (u64)target_base + rela->offset;
|
||||
i64 a = rela->addend;
|
||||
|
||||
switch (rel_type) {
|
||||
case R_X86_64_NONE:
|
||||
break;
|
||||
|
||||
case R_X86_64_64:
|
||||
*(u64 *)p = (u64)(s + (u64)a);
|
||||
break;
|
||||
|
||||
case R_X86_64_32:
|
||||
*(u32 *)p = (u32)((u64)(s + (u64)a));
|
||||
break;
|
||||
|
||||
case R_X86_64_32S:
|
||||
*(i32 *)p = (i32)((i64)s + a);
|
||||
break;
|
||||
|
||||
case R_X86_64_PC32:
|
||||
case R_X86_64_PLT32:
|
||||
/* PC-relative: result must fit in 32 bits after sign-extension. */
|
||||
*(i32 *)p = (i32)((i64)s + a - (i64)p);
|
||||
break;
|
||||
|
||||
case R_X86_64_PC64:
|
||||
*(i64 *)p = (i64)s + a - (i64)p;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("elf64_apply_rela: unhandled relocation type %u\n", rel_type);
|
||||
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);
|
||||
if (target_idx >= hdr->sect_entry_count) {
|
||||
printf("elf64_process_rela_section: target section index %u out of range\n",
|
||||
(unsigned long long)target_idx);
|
||||
return;
|
||||
}
|
||||
if (!section_bases[target_idx]) {
|
||||
/* Target section was not allocated (e.g. non-allocatable debug section). */
|
||||
return;
|
||||
}
|
||||
|
||||
u64 link = rela_sh->link;
|
||||
if (link == 0 || link >= hdr->sect_entry_count) {
|
||||
printf("elf64_process_rela_section: invalid symtab link index %u\n",
|
||||
(unsigned long long)link);
|
||||
return;
|
||||
}
|
||||
|
||||
elf64_sect_header_t *sym_sh = elf_sect(hdr, 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);
|
||||
@ -224,6 +439,7 @@ static void elf64_process_rela_section(const elf64_header_t *hdr,
|
||||
elf64_apply_rela(&relas[r], symtab, section_bases, section_bases[target_idx]);
|
||||
}
|
||||
|
||||
/* Walk all section headers and apply every SHT_RELA section. */
|
||||
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);
|
||||
@ -232,33 +448,80 @@ static void elf64_relocate(const elf64_header_t *hdr, void **section_bases) {
|
||||
}
|
||||
}
|
||||
|
||||
static u64 elf64_load(elf64_header_t* hdr) {
|
||||
if(!hdr || !elf64_validate(hdr)) {
|
||||
printf("elf64_load: Invalid ELF64 header\n");
|
||||
return -1;
|
||||
}
|
||||
static u64 (*elf64_resolve_entry(const elf64_header_t *hdr,
|
||||
void **sect_bases))() {
|
||||
u64 entry_va = hdr->prog_entry_offset;
|
||||
|
||||
void** sect_bases = elf64_alloc_sections(hdr);
|
||||
if(!sect_bases) {
|
||||
printf("elf64_load: Failed to allocate sections.\n");
|
||||
}
|
||||
/* Pass 1: find the section whose VMA range contains entry_va. */
|
||||
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 (sh->addr == 0) continue; /* No VMA assigned */
|
||||
if (entry_va >= sh->addr && entry_va < sh->addr + sh->size) {
|
||||
return (u64 (*)())((u8 *)sect_bases[i] + (entry_va - sh->addr));
|
||||
}
|
||||
}
|
||||
|
||||
elf64_relocate(hdr, sect_bases);
|
||||
/* Pass 2: entry_va is a file offset — search for an executable section. */
|
||||
printf("elf64_resolve_entry: VMA match failed; "
|
||||
"trying executable section + file offset\n");
|
||||
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 (sh->flags & SHF_EXECINSTR) {
|
||||
printf("elf64_resolve_entry: using section %u (%s) as .text fallback\n",
|
||||
(unsigned long long)i, elf_sect_name(hdr, sh));
|
||||
return (u64 (*)())((u8 *)sect_bases[i] + entry_va);
|
||||
}
|
||||
}
|
||||
|
||||
u64 (*entry)() = elf64_resolve_entry(hdr, sect_bases);
|
||||
printf("elf64_resolve_entry: failed to resolve entry point (entry_va=0x%x)\n",
|
||||
(unsigned long long)entry_va);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!entry) {
|
||||
printf("elf64_load: failed to resolve entry point\n");
|
||||
return -1;
|
||||
}
|
||||
static u64 elf64_load(elf64_header_t *hdr) {
|
||||
if (!hdr) {
|
||||
printf("elf64_load: NULL header\n");
|
||||
return (u64)-1;
|
||||
}
|
||||
if (!elf64_validate(hdr)) {
|
||||
printf("elf64_load: invalid ELF64 header\n");
|
||||
return (u64)-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;
|
||||
/* Allocate runtime memory for each section. */
|
||||
void **sect_bases = elf64_alloc_sections(hdr);
|
||||
if (!sect_bases) {
|
||||
printf("elf64_load: failed to allocate sections\n");
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
/* Apply all RELA relocations. */
|
||||
elf64_relocate(hdr, sect_bases);
|
||||
|
||||
/* Resolve entry point. */
|
||||
u64 (*entry)() = elf64_resolve_entry(hdr, sect_bases);
|
||||
if (!entry) {
|
||||
printf("elf64_load: failed to resolve entry point\n");
|
||||
elf64_free_sections(sect_bases, hdr->sect_entry_count);
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
/* Dump the first 64 bytes of entry for debugging. */
|
||||
printf("elf64_load: entry point at 0x%x — first 64 bytes:\n",
|
||||
(unsigned long long)(u64)entry);
|
||||
for (u64 i = 0; i < 64; i++) {
|
||||
u8 byte = ((const u8 *)entry)[i];
|
||||
/* Print as two hex nibbles */
|
||||
print8(byte);
|
||||
put(((i & 7) == 7) ? '\n' : ' ');
|
||||
}
|
||||
|
||||
printf("elf64_load: jumping to entry\n");
|
||||
u64 ret = entry();
|
||||
printf("elf64_load: entry returned 0x%x\n", (unsigned long long)ret);
|
||||
|
||||
elf64_free_sections(sect_bases, hdr->sect_entry_count);
|
||||
return ret;
|
||||
}
|
||||
@ -2,5 +2,14 @@
|
||||
|
||||
#define SYS_OPEN 0
|
||||
#define SYS_SLURP 1
|
||||
#define SYS_GETFB 2
|
||||
#define SYS_PRINT 3
|
||||
#define SYS_GETLINE 4
|
||||
#define SYS_GETKEYS 5
|
||||
#define SYS_FREE 6
|
||||
|
||||
|
||||
typedef struct sys_framebuffer {
|
||||
u32* fb;
|
||||
u32 width;
|
||||
u32 height;
|
||||
} sys_framebuffer_t;
|
||||
44
src/main.c
44
src/main.c
@ -235,35 +235,13 @@ void kmain() {
|
||||
|
||||
rsdp = (struct acpi_rsdp_header *)(rsdp_req.response->address);
|
||||
|
||||
print("Found RSDP @ 0x");
|
||||
print64((u64)rsdp);
|
||||
put('\n');
|
||||
|
||||
print("With signature: ");
|
||||
printn((char *)rsdp->signature, sizeof(rsdp->signature));
|
||||
|
||||
print(" v");
|
||||
print8(rsdp->revision);
|
||||
print("\nRSDT at 0x");
|
||||
struct acpi_rsdt *rsdt =
|
||||
(struct acpi_rsdt *)((rsdp->revision ? rsdp->ptr64 : rsdp->ptr32) +
|
||||
hhdm_offset);
|
||||
print64((u64)rsdt);
|
||||
print("\nSDT Signature: ");
|
||||
|
||||
printn((const char *)rsdt->signature, sizeof(rsdt->signature));
|
||||
print("\nAPIC Local Base: ");
|
||||
|
||||
/* I should check cpuid to ensure its supported but it will
|
||||
* be for my machines ;^) */
|
||||
/* APIC stuff */
|
||||
apic_enable();
|
||||
print("APIC Enabled\n");
|
||||
ioapic_init();
|
||||
|
||||
asm volatile("sti");
|
||||
|
||||
|
||||
ahci_init();
|
||||
|
||||
read_active_port = -1;
|
||||
@ -272,7 +250,6 @@ void kmain() {
|
||||
// assume we want the first port
|
||||
if(read_active_port < 0)
|
||||
read_active_port = i;
|
||||
printf("Port %d is active!\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -287,7 +264,6 @@ void kmain() {
|
||||
|
||||
i8 bootpart = -1;
|
||||
fat32_mbr_partition_t bpart;
|
||||
printf("Fat32 Partitions:\n");
|
||||
for(size_t i = 0; i < 4; i++) {
|
||||
fat32_mbr_partition_t* part = &mbr->partitions[i];
|
||||
u32 lba_start = part->lba_start;
|
||||
@ -297,11 +273,7 @@ void kmain() {
|
||||
bootpart = i;
|
||||
bpart = *part;
|
||||
}
|
||||
|
||||
printf("\t%s, %d Sectors [0x%x-0x%x]\n",
|
||||
(part->status == 0x80)? "[BOOTABLE]" : "[UNBOOTABLE]",
|
||||
part->sector_count,
|
||||
lba_start, lba_end);
|
||||
|
||||
}
|
||||
|
||||
if(bootpart < 0) {
|
||||
@ -324,24 +296,14 @@ void kmain() {
|
||||
u8 *raw = alloc(4096);
|
||||
ahci_read(read_active_port, root_lba, active_vol.sectors_per_cluster, raw);
|
||||
|
||||
struct FILE* fortune = fat32_find_path(read_active_port, &active_vol, "fort/fortu.ne");
|
||||
|
||||
u8* fort = slurp(fortune);
|
||||
|
||||
printn(fort, fortune->info.file_size);
|
||||
|
||||
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");
|
||||
extern volatile u32* fb_scr;
|
||||
elf64_header_t* hdr = (elf64_header_t*) slurp(execfile);
|
||||
char* ret = (char*)elf64_load(hdr);
|
||||
printf("AFTER:\n");
|
||||
print64((u64)ret);
|
||||
elf64_load(hdr);
|
||||
}
|
||||
|
||||
while(1);
|
||||
|
||||
55
src/print.c
55
src/print.c
@ -1,26 +1,24 @@
|
||||
#define TAB_STOP 4
|
||||
|
||||
#include "etc.h"
|
||||
#include "font.h"
|
||||
|
||||
#include "../include/limine.h"
|
||||
|
||||
u32 bg = 0x00000000;
|
||||
u32 fg = (0x007F1754 << 1);
|
||||
static size_t row;
|
||||
static size_t col;
|
||||
static size_t term_width, term_height;
|
||||
static size_t fb_width, fb_height;
|
||||
static volatile u32 *fb_scr;
|
||||
|
||||
size_t fb_width, fb_height;
|
||||
volatile u32 *fb_scr;
|
||||
#define TAB_STOP 4
|
||||
|
||||
// buffer at each edge for readability
|
||||
#define GLYPH_WIDTH (FONT_WIDTH + 2)
|
||||
#define GLYPH_HEIGHT (FONT_HEIGHT + 2)
|
||||
#define SCALE 4
|
||||
#define GLYPH_WIDTH ((FONT_WIDTH + 2) * SCALE)
|
||||
#define GLYPH_HEIGHT ((FONT_HEIGHT + 2) * SCALE)
|
||||
|
||||
void print_init(struct limine_framebuffer *fb) {
|
||||
term_width = fb->width / GLYPH_WIDTH;
|
||||
term_width = fb->width / GLYPH_WIDTH;
|
||||
term_height = fb->height / GLYPH_HEIGHT;
|
||||
fb_width = fb->width;
|
||||
fb_width = fb->width;
|
||||
fb_height = fb->height;
|
||||
fb_scr = fb->address;
|
||||
}
|
||||
@ -36,7 +34,6 @@ static void scrollback() {
|
||||
|
||||
void put(int ch) {
|
||||
ch = (unsigned char)ch;
|
||||
|
||||
if (!isprint(ch)) {
|
||||
if (ch == '\n') {
|
||||
col = 0;
|
||||
@ -53,12 +50,10 @@ void put(int ch) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (col >= term_width) {
|
||||
col = 0;
|
||||
row++;
|
||||
}
|
||||
|
||||
if (row >= term_height) {
|
||||
scrollback();
|
||||
row = term_height - 1;
|
||||
@ -66,23 +61,37 @@ void put(int ch) {
|
||||
|
||||
size_t idx = ch - ' ';
|
||||
u32 glyph = font[idx];
|
||||
|
||||
size_t px = col * GLYPH_WIDTH;
|
||||
size_t py = row * GLYPH_HEIGHT;
|
||||
|
||||
for (size_t y = 0; y < GLYPH_HEIGHT; y++) {
|
||||
for (size_t x = 0; x < GLYPH_WIDTH; x++) {
|
||||
size_t off = (py + y) * fb_width + (px + x);
|
||||
bool padding =
|
||||
(y == 0 || y == GLYPH_HEIGHT - 1 || x == 0 || x == GLYPH_WIDTH - 1);
|
||||
fb_scr[off] = ((~glyph & 1) | padding) ? ((fb_scr[off] == fg) ? bg : fb_scr[off]) : fg;
|
||||
// iterate over logical (unscaled) glyph pixels
|
||||
size_t unscaled_w = FONT_WIDTH + 2;
|
||||
size_t unscaled_h = FONT_HEIGHT + 2;
|
||||
for (size_t y = 0; y < unscaled_h; y++) {
|
||||
for (size_t x = 0; x < unscaled_w; x++) {
|
||||
bool padding = (y == 0 || y == unscaled_h - 1 || x == 0 || x == unscaled_w - 1);
|
||||
u32 color = ((~glyph & 1) | padding)
|
||||
? ((/* will fill per scaled pixel */ 0), bg)
|
||||
: fg;
|
||||
// for padding, preserve existing unless it was fg
|
||||
// expand each logical pixel into SCALE x SCALE block
|
||||
for (size_t sy = 0; sy < SCALE; sy++) {
|
||||
for (size_t sx = 0; sx < SCALE; sx++) {
|
||||
size_t off = (py + y * SCALE + sy) * fb_width + (px + x * SCALE + sx);
|
||||
if (padding)
|
||||
fb_scr[off] = (fb_scr[off] == fg) ? bg : fb_scr[off];
|
||||
else
|
||||
fb_scr[off] = color;
|
||||
}
|
||||
}
|
||||
glyph >>= !padding;
|
||||
}
|
||||
}
|
||||
|
||||
col++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void print(const char *msg) {
|
||||
while (*msg) {
|
||||
put(*(msg++));
|
||||
@ -132,4 +141,4 @@ void unput(void) {
|
||||
for (size_t y = 0; y < GLYPH_HEIGHT; y++)
|
||||
for (size_t x = 0; x < GLYPH_WIDTH; x++)
|
||||
fb_scr[(py + y) * fb_width + (px + x)] = bg;
|
||||
}
|
||||
}
|
||||
@ -38,12 +38,73 @@ static void sys_slurp_impl(struct cpu_ctx* ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->rdi = (u64) filetable[fd]->info.file_size;
|
||||
ctx->rax = (u64) slurp(filetable[fd]);
|
||||
}
|
||||
|
||||
extern volatile u32 *fb_scr;
|
||||
static sys_framebuffer_t g_fb;
|
||||
extern size_t fb_width, fb_height;
|
||||
|
||||
static void sys_getfb_impl(struct cpu_ctx* ctx) {
|
||||
printf("SYS_GETFB\n");
|
||||
g_fb.fb = fb_scr;
|
||||
g_fb.width = fb_width;
|
||||
g_fb.height = fb_height;
|
||||
|
||||
ctx->rax = (u64)&g_fb;
|
||||
}
|
||||
|
||||
static void sys_print_impl(struct cpu_ctx* ctx) {
|
||||
const char* fmt = (const char*)ctx->rdi;
|
||||
if (!fmt) {
|
||||
ctx->rax = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Remaining GP registers hold the variadic args (System V AMD64 ABI)
|
||||
ctx->rax = ctx->rsi;
|
||||
printn((const char*)ctx->rdi, ctx->rsi);
|
||||
}
|
||||
|
||||
|
||||
static void sys_getline_impl(struct cpu_ctx* ctx) {
|
||||
asm volatile("sti");
|
||||
ctx->rax = (u64)getline_alloc(0);
|
||||
}
|
||||
|
||||
extern u8 kbd_held_map[0x100/16];
|
||||
static void sys_getkeys_impl(struct cpu_ctx* ctx) {
|
||||
const char* fmt = (const char*)ctx->rdi;
|
||||
if (!fmt) {
|
||||
ctx->rax = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if(ctx->rdi == 0) {
|
||||
ctx->rax = (u64)malloc(sizeof(kbd_held_map));
|
||||
} else {
|
||||
ctx->rax = ctx->rdi;
|
||||
}
|
||||
|
||||
if(ctx->rax)
|
||||
memcpy((void*)ctx->rax, &kbd_held_map[0], sizeof(kbd_held_map));
|
||||
}
|
||||
|
||||
static void sys_free_impl(struct cpu_ctx* ctx) {
|
||||
void* addr = (void*)ctx->rdi;
|
||||
free(addr);
|
||||
}
|
||||
|
||||
|
||||
static syscall_t syscalls[] = {
|
||||
[SYS_OPEN] sys_open_impl,
|
||||
[SYS_SLURP] sys_slurp_impl,
|
||||
[SYS_OPEN] = sys_open_impl,
|
||||
[SYS_SLURP] = sys_slurp_impl,
|
||||
[SYS_GETFB] = sys_getfb_impl,
|
||||
[SYS_PRINT] = sys_print_impl,
|
||||
[SYS_GETLINE] = sys_getline_impl,
|
||||
[SYS_GETKEYS] = sys_getkeys_impl,
|
||||
[SYS_FREE] = sys_free_impl,
|
||||
};
|
||||
|
||||
// Function to dump the contents of cpu_ctx
|
||||
@ -137,10 +198,10 @@ void dump_cpu_ctx(struct cpu_ctx *ctx) {
|
||||
|
||||
void syscall_handler(struct cpu_ctx* ctx) {
|
||||
|
||||
dump_cpu_ctx(ctx);
|
||||
//dump_cpu_ctx(ctx);
|
||||
|
||||
if(ctx->rax < 2)
|
||||
if(ctx->rax < sizeof(syscalls)/sizeof(syscalls[0]))
|
||||
syscalls[ctx->rax](ctx);
|
||||
|
||||
printf("SYSCALL COMPLETE\n");
|
||||
//printf("SYSCALL COMPLETE\n");
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user