do not edit — generated by btf.
git.druid.rocksindexdruid520kaboomsrc/kernel/kmain.nsc

src/kernel/kmain.nsc


/*
 * kernel entry point, called directly from boot.s's long_mode_entry
 * once the cpu is actually in 64-bit mode with paging live. this file
 * intentionally does no -s/freestanding-mode nscc tricks (see docs
 * note below) -- it's just an ordinary function that boot.s calls.
 *
 * why not nscc's -s mode: -s hardcodes the entry function's name to
 * "main" and emits a _start that ends in a real linux/netbsd exit
 * syscall, which is meaningless with no os underneath. boot.s is the
 * real entry point; this is just the first ordinary function it calls,
 * same extern-linking pattern as everything else in this kernel.
 */
 
include "klog.nsh";
include "../fs/kfs.nsh";
include "exec.nsh";
include "vmm.nsh";
 
void gdt_init(void);
void idt_init(void);
void vga_init(void);
void vga_puts(ptr str);
void serial_init(void);
void serial_puts(ptr str);
void kbd_init(void);
void alloc_init(void);
void klog_init(void);
void halt(void);
void sti(void);
void vmm_init(void);
void vmm_e820_from_pvh(void);
u32 get_bios_boot_flag(void);
u32 get_bios_e820_ptr32(void);
u32 get_bios_e820_count32(void);
u64 get_cr3(void);
 
global void
kmain(void)
{
	kernel_cr3 = get_cr3();
	ptr argv0[1];
 
	/* boot progress used to also go straight to vga+serial (every
	 * "kaboom: X ok" line, printed twice over -- once here via
	 * klog_write, once again by hand on the console) -- removed from
	 * the console specifically, not from the log: klog_write still
	 * records every line below exactly as before, so `klogs` shows
	 * the full boot sequence; the console itself now stays quiet until
	 * sh's own first "$ " prompt, or a genuine fatal halt below. */
	klog_init();
	klog_write("kaboom: boot start\n");
 
	gdt_init();
	klog_write("kaboom: gdt ok\n");
	idt_init();
	klog_write("kaboom: idt ok\n");
	alloc_init();
	klog_write("kaboom: alloc ok\n");
 
	/* which boot path got us here, pvh (qemu -kernel) or real-bios
	 * (dynamite.s) -- dynamite sets an explicit, otherwise-impossible
	 * sentinel in %ebp right before jumping in (see its own comment),
	 * which boot.s's _start saves off before anything else can touch
	 * it; a genuine pvh boot never runs dynamite.s at all, so this flag
	 * reads as whatever qemu's own pvh loader happened to leave there,
	 * never this exact value. */
	if((u64)get_bios_boot_flag() == (u64)0xb105b00b)
	{
		vmm_e820_from_bios((u64)get_bios_e820_ptr32(), (u64)get_bios_e820_count32());
	}
	else
	{
		vmm_e820_from_pvh();
	}
	vmm_init();
	klog_write("kaboom: vmm ok\n");
 
	serial_init();
 
	vga_init();
	kbd_init();
	klog_write("kaboom: vga+kbd ok\n");
 
	klog_write("kaboom: enabling interrupts\n");
 
	/* everything up to here ran entirely with interrupts off (boot.s's
	 * initial cli, never re-enabled) -- irq1 (keyboard) is unmasked in
	 * the pic but the cpu's IF flag still has to actually be set or it
	 * never fires regardless. */
	sti();
 
	if(kfs_mount() == 0)
	{
		serial_puts("kaboom: no kfs filesystem on disk -- halting\n");
		vga_puts("no filesystem -- halting\n");
		while(1)
		{
			halt();
		}
	}
	klog_write("kaboom: kfs mounted\n");
 
	proc_init();
 
	/* sh is init here, not a process something else launches -- if it
	 * ever returns (the user typed "exit"), respawn it rather than
	 * halt, the same way a real getty would. exec failing outright
	 * (sh missing from the disk entirely) is the only real halt path. */
	while(1)
	{
		argv0[0] = "sh";
		if(sys_exec("sh", (u64)2, (i64)1, (ptr)&argv0[0]) == (i64)(-1))
		{
			serial_puts("kaboom: exec sh failed -- halting\n");
			vga_puts("exec sh failed -- halting\n");
			while(1)
			{
				halt();
			}
		}
	}
}
powered by btf.