From 766596ef98ee425044800fbe497b721e90b1c9ac Mon Sep 17 00:00:00 2001 From: rami Date: Fri, 5 Jul 2024 19:16:52 -0400 Subject: [PATCH] parse elf header of initrd and map it to its entry in vmem --- Makefile | 2 +- boot/initrd | Bin 7 -> 432 bytes include/kernel/kernel.h | 53 +++++++++++++++++++++++++++++++++++++ kernel/init.asm | 2 ++ kernel/kernel.c | 57 ++++++++++++++++++++++++++-------------- 5 files changed, 93 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index c6f1a27..df2f4de 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ kernel: $(BUILDDIR)/$(KIMG) $(BUILDDIR)/$(ISO): kernel rm -f $(BUILDDIR)/$(ISO) boot/initrd - nasm -fbin user/userinit.asm -o boot/initrd + nasm -felf32 user/userinit.asm -o boot/initrd cp $(BUILDDIR)/$(KIMG) boot/$(KIMG) grub-mkrescue -o $(BUILDDIR)/$(ISO) . iso: $(BUILDDIR)/$(ISO) diff --git a/boot/initrd b/boot/initrd index 60f94fd8f6cec639f54f65d846d22344a364a3fa..11500d7f5c39295b7fbb3df27397a821cf8e84ab 100644 GIT binary patch literal 432 zcmb<-^>JflWMqH=Mh0dE1doBi0V-hvrZpH?8JJ*7Nuoh!f-oCYmjIB%j%0!WlnoMN zMiN&5s#8SbgUkQ{K_EtUNdQp70Vu`-#32138f2ym7MsZ0|Nn#R^RhbK+A$){NtSn^nSr|V4M^*$1X<;M*0g!7- bi&KmAK}2R=W{F;6aV|rAaY> 22) & 0x3FF) +#define PAGE_TAB_INDEX(x) (((x) >> 12) & 0x3FF) +#define PAGE_OFFSET(x) ((x) & 0xFFF) + struct tss_entry { uint32_t prev_tss; // The previous TSS - with hardware task switching this is used uint32_t esp0; // The stack pointer to load when we change to kernel mode @@ -68,5 +84,42 @@ struct tss_entry { } __attribute__((packed)); typedef struct tss_entry tss_t; +#define EI_NIDENT 16 + +typedef uint16_t Elf32_Half; +typedef uint32_t Elf32_Addr; +typedef uint32_t Elf32_Off; +typedef uint32_t Elf32_Word; +typedef int32_t Elf32_Sword; + +typedef struct { + uint8_t e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} elf_t; + +typedef struct { + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; +} section_t; #endif diff --git a/kernel/init.asm b/kernel/init.asm index 1a8635c..a934bab 100644 --- a/kernel/init.asm +++ b/kernel/init.asm @@ -222,8 +222,10 @@ gdtp: dw gdt_end - gdt - 1 dd gdt +global boot_page_dir align 0x1000 boot_page_dir: times 1024 dd 0 +global boot_page_tab align 0x1000 boot_page_tab: times 1024 dd 0 diff --git a/kernel/kernel.c b/kernel/kernel.c index 995ef8d..0e37cb7 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -17,6 +17,8 @@ extern void pit_isr(void); extern void jmp_user_mode(uint32_t esp, uint32_t eip); extern void flush_tss(uint32_t segment_selector); extern gdt_t gdt[6]; +extern uint32_t boot_page_dir[1024]; +extern uint32_t boot_page_tab[1024]; void exception_handler(int_stack_frame_t r) { LOG("Exception 0x%X (0x%X) has occurred\nEAX: 0x%08X\nECX: 0x%08X\nEDX: 0x%08X\nEBX: 0x%08X\nESI: 0x%08X\nEDI: 0x%08X\nEBP: 0x%08X\nESP: 0x%08X\n", @@ -31,13 +33,13 @@ void sleep(int delay) { cpu_relax; } -typedef struct { - uint32_t eip; - uint32_t esp; - uint32_t cr3; -} task_t; - -#define KERNEL_VMA 0xC0000000 +int strcmp(const char *str1, const char *str2) { + while (*str1 && (*str1 == *str2)) { + str1++; + str2++; + } + return *(uint8_t *)str1 - *(uint8_t *)str2; +} void kernel(multiboot_info_t *info) { if (!CHECK_FLAG(info->flags, 3)) goto halt; // Modules @@ -62,10 +64,10 @@ void kernel(multiboot_info_t *info) { asm volatile ("lidt %0" :: "m"(idtr)); pic_remap(PIC_1_START, PIC_2_START); - asm volatile ("sti" ::); + //asm volatile ("sti" ::); - ctx.ticks = 0; - pit_init(); + //ctx.ticks = 0; + //pit_init(); uint32_t base = (uint32_t)&tss; uint32_t limit = base + sizeof(tss_t); @@ -84,19 +86,34 @@ void kernel(multiboot_info_t *info) { tss.ss = tss.ds = tss.es = tss.fs = tss.gs = GDT_SEGMENT_SELECTOR(4, RING3); flush_tss(GDT_SEGMENT_SELECTOR(5, RING3)); -#define PAGE_PRESENT (1<<0) -#define PAGE_RW (1<<1) -#define PAGE_USER (1<<2) + multi_mod_t *init = (multi_mod_t *)(info->moduleaddress + KERNEL_VMA); + elf_t *elf = (elf_t *)(init->mod_start+KERNEL_VMA); + section_t *str = (section_t *)((uint32_t)elf + elf->e_shoff + elf->e_shstrndx*elf->e_shentsize); + section_t *text = 0; + for (int i = 0; i < elf->e_shnum; i++) { + section_t *sec = (section_t *)((uint32_t)elf + elf->e_shoff + i*elf->e_shentsize); + //LOG("Pingas: %d\n", elf->e_shstrndx); + const char *name = (char *)((uint32_t)elf + str->sh_offset + sec->sh_name); + if (!strcmp(name, ".text")) { + text = sec; + } + } -#define PAGE_DIR_INDEX(x) (((x) >> 22) & 0x3FF) -#define PAGE_TAB_INDEX(x) (((x) >> 12) & 0x3FF) -#define PAGE_OFFSET(x) ((x) & 0xFFF) + uint32_t elf_phys = (uint32_t)elf - KERNEL_VMA; + LOG("0x%08X\n", elf_phys); + uint32_t *elf_page_dir = mmap_find_first_free_block(); + uint32_t *elf_page_tab = mmap_find_first_free_block(); + elf_page_dir[768] = ((uint32_t)boot_page_tab - KERNEL_VMA) | 3; + elf_page_dir[PAGE_DIR_INDEX(elf->e_entry)] = ((uint32_t)elf_page_tab - KERNEL_VMA) | 7; + for (int i = 0; i < 1024; i++) { + elf_page_tab[i] = (elf_phys + 0x1000*i) | 7; + } + + asm volatile ("mov %0, %%cr3" :: "r"((uint32_t)elf_page_dir - KERNEL_VMA)); uint32_t stack = (uint32_t)mmap_find_first_free_block(); - multi_mod_t *init = (multi_mod_t *)(info->moduleaddress + KERNEL_VMA); - LOG("Switching to ring 3... EIP: 0x%08X ESP: 0x%08X\n", init->mod_start+KERNEL_VMA, stack+0x1000); - - jmp_user_mode(stack+0x1000, init->mod_start+KERNEL_VMA); + LOG("Switching to ring 3... EIP: 0x%08X ESP: 0x%08X\n", elf->e_entry+text->sh_offset, stack+0x1000); + jmp_user_mode(stack+0x1000, elf->e_entry+text->sh_offset); halt: for (;;) {}