Files
RockOS/kernel/kmain.c

174 lines
4.2 KiB
C
Raw Normal View History

2026-06-14 00:34:11 -05:00
#include "multiboot.h"
#include "interrupts.h"
#include "gdt.h"
#include "common.h"
2026-07-01 20:00:22 -05:00
#include "scheduler.h"
2026-06-30 00:03:21 -05:00
#include "vfs.h"
#include "elf.h"
2026-07-01 20:00:22 -05:00
#include "gdt.h"
2026-07-12 04:37:46 -05:00
#include "kbd.h"
#include <lib/print.h>
#include <lib/stream.h>
#include <lib/memory.h>
2026-07-15 08:07:06 -05:00
#include <lib/console.h>
#include <memory/mm.h>
2026-06-09 23:16:25 -05:00
#include <drivers/iso/iso.h>
#include <drivers/ide/ide.h>
#include <drivers/pic/pic.h>
#include <drivers/ps2/ps2.h>
#include <drivers/pit/pit.h>
#include <drivers/vga/vga.h>
2026-06-30 00:03:21 -05:00
#include <drivers/cpio/cpio.h>
#include <drivers/devfs/devfs.h>
2026-07-14 17:40:30 -05:00
#include <drivers/serial/serial.h>
2026-06-11 23:23:39 -05:00
2026-06-14 00:34:11 -05:00
#include <stddef.h>
2026-06-11 23:23:39 -05:00
#include <stdint.h>
2026-06-15 18:09:04 -04:00
extern char __kernel_start;
extern char __kernel_end;
2026-07-14 17:40:30 -05:00
#define SERIAL_DBG
2026-07-01 20:00:22 -05:00
extern uint32_t page_directory[1024];
void* kernel_cr3 = page_directory;
void parse_multiboot_modules(uint32_t mbi_vaddr) {
// find where grub put the boot module containing initrd
multiboot_info* mbi = (multiboot_info*)mbi_vaddr;
uint32_t mod_count = mbi->mods_count;
multiboot_module_t* mod = (multiboot_module_t*)((uint32_t)mbi->mods_addr + 0xC0000000);
for (uint32_t i = 0; i < mod_count; i++) {
uint32_t start = mod[i].mod_start;
uint32_t end = mod[i].mod_end;
uint32_t cmdline = mod[i].cmdline;
multiboot_module_info_table[i].mod_start = start + 0xC0000000;
multiboot_module_info_table[i].mod_end = end + 0xC0000000;
multiboot_module_info_table[i].cmdline = cmdline + 0xC0000000;
2026-06-16 18:44:31 -05:00
}
}
2026-06-30 00:03:21 -05:00
vfs_node_t* load_initrd() {
multiboot_module_t* initrd_module = &multiboot_module_info_table[0];
kprintf("initrd found @ [v] 0x%x\n", initrd_module->mod_start);
2026-06-30 00:03:21 -05:00
return cpio_read_fs(initrd_module->mod_start);
}
2026-07-01 20:00:22 -05:00
void load_root_program(const char* path) {
2026-07-07 18:52:22 -05:00
lock_scheduler();
2026-07-01 20:00:22 -05:00
uint32_t kernel_cr3 = fetch_cr3();
2026-07-08 19:11:39 -05:00
void* cr3 = create_new_pd();
2026-07-07 18:52:22 -05:00
load_pd(cr3);
flush_tlb();
2026-06-30 00:03:21 -05:00
uint32_t eip = load_elf_program(path);
if (eip == 0) {
kprintf("Failed to load elf program file\n");
return;
}
2026-07-01 20:00:22 -05:00
uint32_t stack_sz = PAGE_SIZE * 16;
uint32_t stack_top = 0xBFFF0000;
uint32_t stack_bottom = stack_top - stack_sz;
for (uint32_t vaddr = stack_bottom; vaddr < stack_top; vaddr += PAGE_SIZE) {
void* phys_frame = p_alloc_frame();
map_page(vaddr, (uint32_t)phys_frame, PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER);
2026-07-01 20:00:22 -05:00
}
uint32_t* u_esp = (uint32_t*)stack_top;
*(--u_esp) = 0; // envp = NULL
*(--u_esp) = 0; // argv = NULL
*(--u_esp) = 0; // argc = 0
process_t* process = kalloc(sizeof(process_t));
init_task(process, eip, (uint32_t)cr3, 1, (uint32_t)u_esp);
add_task(process);
2026-07-07 18:52:22 -05:00
unlock_scheduler();
2026-07-04 00:26:20 -05:00
2026-07-01 20:00:22 -05:00
load_pd((void*)kernel_cr3);
2026-07-03 22:25:24 -05:00
flush_tlb();
2026-06-16 18:44:31 -05:00
}
2026-07-14 17:40:30 -05:00
void kmain(multiboot_info* mbi) {
disable_interrupts();
2026-07-14 00:07:50 -05:00
2026-07-14 17:40:30 -05:00
init_serial();
2026-06-12 23:03:00 -04:00
2026-07-14 00:07:50 -05:00
// need mmap and fb info
if (!(mbi->flags & (1 << 6)) || !(mbi->flags & (1 << 12))) {
return;
}
2026-06-16 18:44:31 -05:00
2026-07-14 17:40:30 -05:00
parse_multiboot_modules((uint32_t)mbi);
uint32_t vga_fb_address = mbi->framebuffer_addr;
uint32_t vga_fb_width = mbi->framebuffer_width;
uint32_t vga_fb_height = mbi->framebuffer_height;
uint32_t vga_fb_pitch = mbi->framebuffer_pitch;
uint32_t vga_fb_bpp = mbi->framebuffer_bpp;
2026-06-15 23:35:01 -05:00
2026-06-12 23:03:00 -04:00
init_gdt();
2026-06-11 23:23:39 -05:00
init_idt();
2026-06-13 13:27:39 -05:00
init_pic();
init_pit();
2026-07-14 17:40:30 -05:00
uint32_t mmap_virtual_addr = mbi->mmap_addr + 0xC0000000;
init_pmm((void*)mmap_virtual_addr, mbi->mmap_length);
2026-06-15 18:09:04 -04:00
init_page_tables();
2026-07-16 14:44:08 -05:00
disable_interrupts();
init_scheduler();
enable_interrupts();
vfs_node_t* vfs_root = vfs_create_root();
vfs_node_t* initrd_root = load_initrd();
if (!initrd_root) {
kprintf("failed to load initrd\n");
}
2026-07-01 20:00:22 -05:00
2026-07-10 07:46:46 -05:00
vfs_mount(vfs_root, initrd_root);
kprintf("initrd read, mounted @ /\n");
vfs_node_t* devfs = create_devfs();
if (!devfs) {
kprintf("failed to create devfs\n");
return;
}
2026-07-12 04:37:46 -05:00
vfs_node_t* kbd_dev = devfs->create(devfs, "kbd");
kbd_dev->read = kbd_read;
2026-07-16 14:44:08 -05:00
vfs_node_t* vga_dev = devfs->create(devfs, "vga");
vga_init(vga_dev,
vga_fb_address,
vga_fb_width,
vga_fb_height,
vga_fb_pitch,
vga_fb_bpp);
kprintf("vga initialized\n");
vfs_node_t* dev = vfs_find("/dev");
2026-07-16 14:44:08 -05:00
if (!dev) {
kprintf("failed to find dev mnt point\n");
return;
}
2026-07-16 14:44:08 -05:00
dev->mnt = devfs;
kprintf("mounted devfs\n");
2026-07-16 16:09:12 -05:00
kprintf("basic initializations complete\n");
2026-07-16 14:44:08 -05:00
kprintf("starting rockos\n");
2026-07-07 18:52:22 -05:00
2026-07-16 16:09:12 -05:00
load_root_program("/usr/bin/rockterm");
2026-06-09 23:16:25 -05:00
}