summaryrefslogtreecommitdiff
path: root/kernel/core/kernel_main.cpp
diff options
context:
space:
mode:
authorArseney300 <Arseney300@gmail.com>2026-03-29 02:07:17 +0700
committerArseney300 <Arseney300@gmail.com>2026-04-08 01:19:07 +0700
commit4912796d2e88c6eb5d02fbf0fb9c39f8c9f7cd4c (patch)
tree9ee8110e2c090c888f23797cda56c7e2df531695 /kernel/core/kernel_main.cpp
bastion: initial implementation
ready project skeleton dual-arch build system with Linux-config style configuration UEFI EFI stub loader (PE32+) for x86_64 and AArch64 ELF64 kernel parser Temporary framebuffer console freestanding string and c++ abi stubs For now, kernel boots, prints banner, memory map and go halt
Diffstat (limited to 'kernel/core/kernel_main.cpp')
-rw-r--r--kernel/core/kernel_main.cpp113
1 files changed, 113 insertions, 0 deletions
diff --git a/kernel/core/kernel_main.cpp b/kernel/core/kernel_main.cpp
new file mode 100644
index 0000000..9c744c7
--- /dev/null
+++ b/kernel/core/kernel_main.cpp
@@ -0,0 +1,113 @@
+// ============================================================================
+// core/kernel_main.cpp - Kernel entry point
+//
+// Called by arch-specific entry.S after stack setup.
+// Receives BootInfo* by the UEFI loader (or in future from other loader).
+// ============================================================================
+
+#include <boot/boot_info.h>
+#include <kernel/kprint.h>
+#include <kernel/arch.h>
+
+// ── Memory region type names ───────────────────────────────────────────────
+
+namespace {
+//TODO: Move it to another cpp/h file
+//TODO: use reflection to get field name
+[[nodiscard]] constexpr const char* mem_type_name(MemoryRegionType type) {
+ switch (type) {
+ case MemoryRegionType::Usable: return "Usable";
+ case MemoryRegionType::Reserved: return "Reserved";
+ case MemoryRegionType::AcpiReclaimable: return "ACPI Reclaimable";
+ case MemoryRegionType::AcpiNvs: return "ACPI NVS";
+ case MemoryRegionType::BootloaderReclaimable: return "Boot Reclaimable";
+ case MemoryRegionType::KernelAndModules: return "Kernel";
+ case MemoryRegionType::Framebuffer: return "Framebuffer";
+ }
+ return "Unknown";
+}
+
+} // anonymous namespace
+
+// ── Kernel entry ───────────────────────────────────────────────────────────
+// Called from entry.S with BootInfo* in RDI (x86_64) / X0 (AArch64).
+extern "C" void kernel_main(BootInfo* boot_info) {
+ // Validate magic — if wrong we can't print, just halt.
+ if (boot_info->magic != BOOT_INFO_MAGIC)
+ arch::halt();
+
+ // Initialize framebuffer console.
+ // TODO: Add driver skeleton and move framebuffer to early drivers.
+ kcon::init(boot_info->framebuffer);
+
+ // ── Banner ─────────────────────────────────────────────────────────
+
+ kcon::println("========================================");
+ kcon::println(" Bastion Kernel " CONFIG_KERNEL_VERSION);
+ kcon::kprintf(" Architecture: %s\n", arch::name());
+ kcon::println("========================================");
+ kcon::putchar('\n');
+
+ // ── Framebuffer info ───────────────────────────────────────────────
+
+ kcon::kprintf("Framebuffer: %ux%u, pitch=%u, base=%x\n",
+ boot_info->framebuffer.width,
+ boot_info->framebuffer.height,
+ boot_info->framebuffer.pitch,
+ boot_info->framebuffer.base);
+ kcon::putchar('\n');
+
+ // ── Firmware tables ────────────────────────────────────────────────
+
+#ifdef CONFIG_X86
+ if (boot_info->rsdp_address)
+ kcon::kprintf("ACPI RSDP at: %x\n", boot_info->rsdp_address);
+#elif CONFIG_AARCH64
+ if (boot_info->fdt_address)
+ kcon::kprintf("Device Tree at: %x\n", boot_info->fdt_address);
+#endif
+ kcon::putchar('\n');
+
+ // ── Memory map ─────────────────────────────────────────────────────
+
+ kcon::kprintf("Memory map (%u entries):\n", boot_info->memory_map_count);
+
+ uint64_t total_usable = 0;
+ for (uint64_t i = 0; i < boot_info->memory_map_count; i++) {
+ const auto& region = boot_info->memory_map[i];
+
+ // Skip tiny reserved regions to avoid flooding the console.
+ if (region.type == MemoryRegionType::Reserved && region.length < 0x10000)
+ continue;
+
+ kcon::kprintf(" %x - %x [%s]\n",
+ region.base,
+ region.base + region.length,
+ mem_type_name(region.type));
+
+ if (region.type == MemoryRegionType::Usable)
+ total_usable += region.length;
+ }
+
+ kcon::putchar('\n');
+ kcon::kprintf("Total usable memory: %u MiB\n", total_usable / (1024u * 1024u));
+
+ // ── Kernel info ────────────────────────────────────────────────────
+
+ kcon::putchar('\n');
+ kcon::kprintf("Kernel loaded at phys %x, virt %x, size %u KiB\n",
+ boot_info->kernel_phys_base,
+ boot_info->kernel_virt_base,
+ boot_info->kernel_size / 1024u);
+
+ // ── Done (for now) ─────────────────────────────────────────────────
+
+ kcon::putchar('\n');
+ kcon::println("Hello, World from BastionOS!");
+ kcon::putchar('\n');
+ kcon::println("Kernel initialized successfully.");
+ kcon::println("Next: GDT, IDT, paging, memory allocator...");
+ kcon::println("Halting.");
+
+ arch::halt(); // [[noreturn]] — never comes back
+}