parse elf header of initrd and map it to its entry in vmem
This commit is contained in:
parent
7eec8729e3
commit
766596ef98
2
Makefile
2
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)
|
||||
|
|
BIN
boot/initrd
BIN
boot/initrd
Binary file not shown.
|
@ -7,6 +7,14 @@
|
|||
#define cpu_relax asm volatile ("pause" ::)
|
||||
#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 {
|
||||
multi_mmap_t *multi_mmap;
|
||||
uint32_t multi_mmap_size;
|
||||
|
@ -37,6 +45,14 @@ struct gdt_entry {
|
|||
} __attribute__((packed));
|
||||
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 {
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 (;;) {}
|
||||
|
|
Loading…
Reference in New Issue
Block a user