#include #include #include #include "io/term/term.h" #include "io/term/printf.h" #include "io/serial/serial.h" #include "mem/gdt/gdt.h" #include "mem/misc/utils.h" #include "idt/idt.h" #include "kernel.h" #include "time/timer.h" #include "io/kbd/ps2.h" #include "mem/paging/pmm.h" #include "mem/paging/paging.h" #include "mem/paging/vmm.h" #include "mem/heap/kheap.h" // Limine version used __attribute__((used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3); // Framebuffer request __attribute__((used, section(".limine_requests"))) static volatile struct limine_framebuffer_request framebuffer_request = { .id = LIMINE_FRAMEBUFFER_REQUEST, .revision = 0 }; // Memory map request __attribute__((used, section(".limine_requests"))) static volatile struct limine_memmap_request memmap_request = { .id = LIMINE_MEMMAP_REQUEST, .revision = 0 }; // Higher Half Direct Map __attribute__((used, section(".limine_requests"))) static volatile struct limine_hhdm_request hhdm_request = { .id = LIMINE_HHDM_REQUEST, .revision = 0 }; // Executable Address/Kernel Address (find base phys/virt address of kernel) __attribute__((used, section(".limine_requests"))) static volatile struct limine_kernel_address_request kerneladdr_request = { .id = LIMINE_KERNEL_ADDRESS_REQUEST, .revision = 0 }; __attribute__((used, section(".limine_requests_start"))) static volatile LIMINE_REQUESTS_START_MARKER; __attribute__((used, section(".limine_requests_end"))) static volatile LIMINE_REQUESTS_END_MARKER; struct limine_framebuffer* framebuffer; // Panic (should dump registers etc. in the future) void hcf() { for (;;) { asm("hlt"); } } // This is our entry point void kmain() { if (!LIMINE_BASE_REVISION_SUPPORTED) hcf(); if (framebuffer_request.response == NULL || framebuffer_request.response->framebuffer_count < 1) hcf(); // We should probably grab all the boot info in a boot context struct // that would be a bit cleaner than this mess // Get the first framebuffer from the response framebuffer = framebuffer_request.response->framebuffers[0]; serial_init(); if (memmap_request.response == NULL) hcf(); memmap_display(memmap_request.response); if (hhdm_request.response == NULL) hcf(); hhdm_display(hhdm_request.response); if (kerneladdr_request.response == NULL) hcf(); DEBUG("kernel: phys_base=0x%p virt_base=0x%p", kerneladdr_request.response->physical_base, kerneladdr_request.response->virtual_base); CLEAR_INTERRUPTS; gdt_init(); idt_init(); timer_init(); SET_INTERRUPTS; pmm_init(memmap_request.response, hhdm_request.response); // Remap kernel , HHDM and framebuffer paging_init(kerneladdr_request.response, framebuffer); kheap_init(); void* ptr = kmalloc(10); DEBUG("(KMALLOC TEST) Allocated 10 bytes at 0x%p", ptr); void* ptr2 = kmalloc(200); DEBUG("(KMALLOC TEST) Allocated 200 bytes at 0x%p", ptr2); kfree(ptr); void* ptr3 = kmalloc(5); DEBUG("(KMALLOC TEST) Allocated 5 bytes at 0x%p", ptr3); vmm_init(); keyboard_init(FR); term_init(); // Draw something printf("%s, %s!\n", "Hello", "world"); // Yoohoooooo! //DEBUG("kernel initialized successfully! hanging... wow=%d", 42); printf("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non justo a magna bibendum auctor viverra rutrum diam. In hac habitasse platea dictumst. Vestibulum suscipit ipsum eget tortor maximus lobortis. Donec vel ipsum id lacus fringilla bibendum id eget risus. Fusce vestibulum diam sit amet nunc ultricies, nec rutrum nibh congue. Donec fringilla a dui sit amet ullamcorper. Donec pharetra quis tortor id congue. Aliquam erat volutpat. Duis suscipit nulla vel ligula iaculis, in gravida mauris pellentesque. Vestibulum nunc nisl, posuere eu eros et, dictum molestie dolor. Donec posuere laoreet hendrerit. Suspendisse potenti. Proin fringilla vehicula malesuada. Quisque a dui est. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur nec aliquam lacus, at lacinia enim. "); hcf(); }