]> git.dujemihanovic.xyz Git - nameless-os.git/blob - boot/x86/stage3/prekernel.c
Load ELF kernel instead of flat binary
[nameless-os.git] / boot / x86 / stage3 / prekernel.c
1 #include <elf.h>
2 #include <paging.h>
3
4 /* This bit of code will be run right after the segment registers have been set
5 * up for protected mode. */
6
7 const char *error_messages[] = {
8 "Tried to page an invalid address, the bootloader is buggy!",
9 "Tried to page an invalid address, the bootloader is buggy!",
10 "Tried to page an invalid address, the bootloader is buggy!",
11 "Tried to page an invalid address, the bootloader is buggy!",
12 "KERNEL.ELF is not a valid ELF file!",
13 "KERNEL.ELF is a non-x86 or userspace executable!",
14 "KERNEL.ELF is not an executable ELF file!"
15 };
16
17 void printerr(const char *error)
18 {
19 char *message = (char *) error;
20 for (int i=0;;i++) {
21 char temp = *message;
22 if (!temp) return;
23 *(char *) (0xb8000+i*2) = temp;
24 *(char *) (0xb8000+1+i*2) = 0xcf;
25 message++;
26 }
27 }
28
29 void halt()
30 {
31 loop:
32 asm("hlt":);
33 goto loop;
34 }
35
36 void run_kernel(void *e820_map, unsigned int e820_map_size, struct elf_header *kernel, unsigned int kernel_size)
37 {
38 /* Before trying to parse our kernel ELF, let's set up paging. */
39 unsigned int bootloader_mem_size = 0x100000 + kernel_size;
40
41 /* Align the size to a 4K boundary. */
42 if (bootloader_mem_size & 0xfff) {
43 bootloader_mem_size += 0x1000;
44 bootloader_mem_size &= ~0xfff;
45 }
46
47 /* Map the bootloader memory. */
48 int ret = map_range(0, (void *) bootloader_mem_size, 0, (void *) bootloader_mem_size, 2);
49 if (ret) {
50 printerr(error_messages[ret-1]);
51 halt();
52 }
53 set_up_page_directory();
54 enable_paging();
55
56 /* Parse and run the kernel ELF. */
57 ret = execute_elf(kernel, e820_map, e820_map_size);
58 if (ret) {
59 printerr(error_messages[ret-1]);
60 halt();
61 }
62 }