summaryrefslogtreecommitdiffstats
path: root/boot/limine/limine.c
blob: 14f85f542b61e3f32bd9bdd04a08027d541cdeea (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "limine.h"
#include "boot.h"

static char s_kernel_stack[KERNEL_INITIAL_STACK_WIDTH];

struct MemoryMap boot_memorymap;

struct BootModule boot_modules[BOOT_MODULE_MAX_ENTRIES];
struct BootModule boot_kernel_file;
size_t boot_module_count = 0;

uintptr_t boot_kernel_physical_address;
void *boot_kernel_initial_stack_base = &s_kernel_stack;
const char *boot_kernel_cmdline = NULL;

struct limine_memmap_request s_mmap_request = {
    .id = LIMINE_MEMMAP_REQUEST
};
struct limine_kernel_address_request s_kaddr_request = {
    .id = LIMINE_KERNEL_ADDRESS_REQUEST
};
struct limine_kernel_file_request s_kfile_request = {
    .id = LIMINE_KERNEL_FILE_REQUEST
};
struct limine_module_request s_module_request = {
    .id = LIMINE_MODULE_REQUEST
};

static void
s_load_memorymap(void)
{
    struct limine_memmap_response *response = s_mmap_request.response;
    if(response == NULL) return;
    boot_memorymap.count = response->entry_count;
    for(size_t i = 0; i < response->entry_count; i++) {
        struct limine_memmap_entry *e = response->entries[i];
        struct MemoryMapEntry *bme = &boot_memorymap.entries[i];

        bme->base = e->base;
        bme->length = e->length;
        bme->usable = e->type == LIMINE_MEMMAP_USABLE ||
                      e->type == LIMINE_MEMMAP_ACPI_RECLAIMABLE ||
                      e->type == LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE;
    }
}

static void
s_load_modules(void)
{
    struct limine_module_response *response = s_module_request.response;
    if(response->module_count > 4) response->module_count = 4;
    boot_module_count = response->module_count;
    for(size_t i = 0; i < response->module_count; i++) {
        boot_modules[i] = (struct BootModule){
            .path = response->modules[i]->path,
            .cmdline = response->modules[i]->cmdline,
            .size = response->modules[i]->size,
            .addr = (uintptr_t)response->modules[i]->address
        };
    }
}

static void
s_load_kernel_file(void)
{
    struct limine_kernel_file_response *response = s_kfile_request.response;
    boot_kernel_file = (struct BootModule) {
        .path = response->kernel_file->path,
        .cmdline = response->kernel_file->cmdline,
        .size = response->kernel_file->size,
        .addr = (uintptr_t)response->kernel_file->address
    };
    boot_kernel_cmdline = response->kernel_file->cmdline;
}

void _start(void)
{
    boot_kernel_physical_address = s_kaddr_request.response->physical_base;
    s_load_memorymap();
    
    s_load_kernel_file();
    s_load_modules();

    char *kernel_stack_entry = s_kernel_stack + (KERNEL_INITIAL_STACK_WIDTH - 1);
    __asm__ volatile("movq %0, %%rsp":: "r"(kernel_stack_entry));

    extern void kernel_main(void);
    kernel_main();
}