#include #include #include #include #include #include #include #include #include "limine.h" [[__initdata_sorted("limine.0")]] static volatile uint64_t limine_start[] = LIMINE_REQUESTS_START_MARKER; [[__initdata_sorted("limine.1")]] static volatile uint64_t limine_revision[] = LIMINE_BASE_REVISION(6); [[__initdata_sorted("limine.2")]] static volatile uint64_t limine_end[] = LIMINE_REQUESTS_END_MARKER; #define LIMINE_REQUEST(request, tag, rev) \ [[__initdata_sorted("limine.1")]] \ static volatile struct limine_##request request = { \ .id = tag, \ .revision = rev, \ .response = nullptr, \ } LIMINE_REQUEST(memmap_request, LIMINE_MEMMAP_REQUEST_ID, 0); LIMINE_REQUEST(hhdm_request, LIMINE_HHDM_REQUEST_ID, 0); LIMINE_REQUEST(executable_address_request, LIMINE_EXECUTABLE_ADDRESS_REQUEST_ID, 0); LIMINE_REQUEST(executable_file_request, LIMINE_EXECUTABLE_FILE_REQUEST_ID, 0); LIMINE_REQUEST(framebuffer_request, LIMINE_FRAMEBUFFER_REQUEST_ID, 1); LIMINE_REQUEST(module_request, LIMINE_MODULE_REQUEST_ID, 0); LIMINE_REQUEST(dtb_request, LIMINE_DTB_REQUEST_ID, 0); LIMINE_REQUEST(rsdp_request, LIMINE_RSDP_REQUEST_ID, 0); [[__initdata]] static struct phys_mem mem[128]; [[__initdata]] static struct boot_file files[8]; [[__init]] void kernel_entry() { kernel_early_init(); struct boot_info info = {}; const struct limine_memmap_response* mm_res = memmap_request.response; const struct limine_hhdm_response* hhdm_res = hhdm_request.response; const struct limine_module_response* module_res = module_request.response; const struct limine_executable_address_response* exec_res = executable_address_request.response; const struct limine_executable_file_response* exec_file_res = executable_file_request.response; const struct limine_rsdp_response* rsdp_res = rsdp_request.response; assert(mm_res, "memmap_request returned no response!"); assert(hhdm_res, "hhdm_request returned no response!"); info.cmdline = exec_file_res->executable_file->string; info.kernel_file.data = (phys_t)((uintptr_t)exec_file_res->executable_file->address - hhdm_res->offset); info.kernel_file.length = exec_file_res->executable_file->size; info.num_mem_maps = MIN(ARRAY_SIZE(mem), mm_res->entry_count); for (size_t i = 0; i < info.num_mem_maps; i++) { mem[i].address = mm_res->entries[i]->base; mem[i].length = mm_res->entries[i]->length; switch (mm_res->entries[i]->type) { case LIMINE_MEMMAP_USABLE: mem[i].usage = PHYS_USABLE; break; case LIMINE_MEMMAP_ACPI_RECLAIMABLE: case LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE: mem[i].usage = PHYS_RECLAIMABLE; break; case LIMINE_MEMMAP_EXECUTABLE_AND_MODULES: mem[i].usage = PHYS_STATIC; break; default: mem[i].usage = PHYS_RESERVED; break; } } if (module_res) { info.files = files; info.num_files = MIN(ARRAY_SIZE(files), module_res->module_count); for (size_t i = 0; i < info.num_files; i++) { files[i].data = (phys_t)module_res->modules[i]->address - hhdm_res->offset; files[i].length = module_res->modules[i]->size; strncpy(files[i].path, module_res->modules[i]->path, sizeof(files[i].path) - 1); files[i].path[sizeof(files[i].path) - 1] = 0; } } info.mem_map = mem; info.phys_base = (phys_t)exec_res->physical_base; info.virt_base = (uintptr_t)exec_res->virtual_base; info.hhdm_base = (uintptr_t)hhdm_res->offset; const struct limine_dtb_response* dtb_res = dtb_request.response; if (dtb_res && dtb_res->dtb_ptr) { info.dtb = (phys_t)((uintptr_t)dtb_res->dtb_ptr - hhdm_res->offset); info.dtb_size = fdt_read_u32((const uint8_t*)dtb_res->dtb_ptr + 4); } const struct limine_framebuffer_response* fb_res = framebuffer_request.response; if (fb_res) { // Only use the first framebuffer. if (fb_res->framebuffer_count >= 1) { const struct limine_framebuffer* fb = framebuffer_request.response->framebuffers[0]; info.fb.base = (phys_t)((uintptr_t)fb->address - hhdm_res->offset); info.fb.width = fb->width; info.fb.height = fb->height; info.fb.pitch = fb->pitch; info.fb.bytes_per_pixel = fb->bpp / 8; info.fb.red.shift = fb->red_mask_shift; info.fb.red.size = fb->red_mask_size; info.fb.green.shift = fb->green_mask_shift; info.fb.green.size = fb->green_mask_size; info.fb.blue.shift = fb->blue_mask_shift; info.fb.blue.size = fb->blue_mask_size; } } #if CONFIG_ACPI if (rsdp_request.response) { info.rsdp = (phys_t)rsdp_request.response->address; if (info.rsdp >= info.hhdm_base) info.rsdp -= info.hhdm_base; } #endif kernel_main(&info); }