parse elf header of initrd and map it to its entry in vmem

This commit is contained in:
rami 2024-07-05 19:16:52 -04:00
parent 7eec8729e3
commit 766596ef98
5 changed files with 93 additions and 21 deletions

View File

@ -35,7 +35,7 @@ kernel: $(BUILDDIR)/$(KIMG)
$(BUILDDIR)/$(ISO): kernel $(BUILDDIR)/$(ISO): kernel
rm -f $(BUILDDIR)/$(ISO) boot/initrd 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) cp $(BUILDDIR)/$(KIMG) boot/$(KIMG)
grub-mkrescue -o $(BUILDDIR)/$(ISO) . grub-mkrescue -o $(BUILDDIR)/$(ISO) .
iso: $(BUILDDIR)/$(ISO) iso: $(BUILDDIR)/$(ISO)

Binary file not shown.

View File

@ -7,6 +7,14 @@
#define cpu_relax asm volatile ("pause" ::) #define cpu_relax asm volatile ("pause" ::)
#define CHECK_FLAG(x, n) (x & (1<<n)) #define CHECK_FLAG(x, n) (x & (1<<n))
typedef struct {
uint32_t eip;
uint32_t esp;
uint32_t cr3;
} task_t;
#define KERNEL_VMA 0xC0000000
typedef struct { typedef struct {
multi_mmap_t *multi_mmap; multi_mmap_t *multi_mmap;
uint32_t multi_mmap_size; uint32_t multi_mmap_size;
@ -37,6 +45,14 @@ struct gdt_entry {
} __attribute__((packed)); } __attribute__((packed));
typedef struct gdt_entry gdt_t; typedef struct gdt_entry gdt_t;
#define PAGE_PRESENT (1<<0)
#define PAGE_RW (1<<1)
#define PAGE_USER (1<<2)
#define PAGE_DIR_INDEX(x) (((x) >> 22) & 0x3FF)
#define PAGE_TAB_INDEX(x) (((x) >> 12) & 0x3FF)
#define PAGE_OFFSET(x) ((x) & 0xFFF)
struct tss_entry { struct tss_entry {
uint32_t prev_tss; // The previous TSS - with hardware task switching this is used 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 uint32_t esp0; // The stack pointer to load when we change to kernel mode
@ -68,5 +84,42 @@ struct tss_entry {
} __attribute__((packed)); } __attribute__((packed));
typedef struct tss_entry tss_t; 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 #endif

View File

@ -222,8 +222,10 @@ gdtp:
dw gdt_end - gdt - 1 dw gdt_end - gdt - 1
dd gdt dd gdt
global boot_page_dir
align 0x1000 align 0x1000
boot_page_dir: times 1024 dd 0 boot_page_dir: times 1024 dd 0
global boot_page_tab
align 0x1000 align 0x1000
boot_page_tab: times 1024 dd 0 boot_page_tab: times 1024 dd 0

View File

@ -17,6 +17,8 @@ extern void pit_isr(void);
extern void jmp_user_mode(uint32_t esp, uint32_t eip); extern void jmp_user_mode(uint32_t esp, uint32_t eip);
extern void flush_tss(uint32_t segment_selector); extern void flush_tss(uint32_t segment_selector);
extern gdt_t gdt[6]; 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) { 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", 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; cpu_relax;
} }
typedef struct { int strcmp(const char *str1, const char *str2) {
uint32_t eip; while (*str1 && (*str1 == *str2)) {
uint32_t esp; str1++;
uint32_t cr3; str2++;
} task_t; }
return *(uint8_t *)str1 - *(uint8_t *)str2;
#define KERNEL_VMA 0xC0000000 }
void kernel(multiboot_info_t *info) { void kernel(multiboot_info_t *info) {
if (!CHECK_FLAG(info->flags, 3)) goto halt; // Modules 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)); asm volatile ("lidt %0" :: "m"(idtr));
pic_remap(PIC_1_START, PIC_2_START); pic_remap(PIC_1_START, PIC_2_START);
asm volatile ("sti" ::); //asm volatile ("sti" ::);
ctx.ticks = 0; //ctx.ticks = 0;
pit_init(); //pit_init();
uint32_t base = (uint32_t)&tss; uint32_t base = (uint32_t)&tss;
uint32_t limit = base + sizeof(tss_t); 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); tss.ss = tss.ds = tss.es = tss.fs = tss.gs = GDT_SEGMENT_SELECTOR(4, RING3);
flush_tss(GDT_SEGMENT_SELECTOR(5, RING3)); flush_tss(GDT_SEGMENT_SELECTOR(5, RING3));
#define PAGE_PRESENT (1<<0) multi_mod_t *init = (multi_mod_t *)(info->moduleaddress + KERNEL_VMA);
#define PAGE_RW (1<<1) elf_t *elf = (elf_t *)(init->mod_start+KERNEL_VMA);
#define PAGE_USER (1<<2) 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) uint32_t elf_phys = (uint32_t)elf - KERNEL_VMA;
#define PAGE_TAB_INDEX(x) (((x) >> 12) & 0x3FF) LOG("0x%08X\n", elf_phys);
#define PAGE_OFFSET(x) ((x) & 0xFFF) 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(); 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", elf->e_entry+text->sh_offset, stack+0x1000);
LOG("Switching to ring 3... EIP: 0x%08X ESP: 0x%08X\n", init->mod_start+KERNEL_VMA, stack+0x1000); jmp_user_mode(stack+0x1000, elf->e_entry+text->sh_offset);
jmp_user_mode(stack+0x1000, init->mod_start+KERNEL_VMA);
halt: halt:
for (;;) {} for (;;) {}