#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef KEXT_NET_DOORSTUCK_SOCKS_ACPI #include #endif #ifdef KEXT_NET_DOORSTUCK_SOCKS_FBCON #include #endif #define PTR32(x) ((void *)((uintptr_t)(x))) static ml_cpu_block g_bootstrap_cpu = {0}; static struct framebuffer_varinfo __bootfb_varinfo; static struct framebuffer_fixedinfo __bootfb_fixedinfo; /* start and end of kernel image (physical addresses) */ extern char __pstart[], __pend[]; static void bootstrap_cpu_init(void) { ml_cpu_block_init(&g_bootstrap_cpu); ml_cpu_block_use(&g_bootstrap_cpu); } static void early_vm_init(void) { uintptr_t alloc_start = VM_KERNEL_VOFFSET; /* boot code mapped 2 GiB of memory from VM_KERNEL_VOFFSET */ uintptr_t alloc_end = VM_KERNEL_VOFFSET + 0x7fffffff; memblock_init(alloc_start, alloc_end, VM_KERNEL_VOFFSET); printk("memblock: allocating from [0x%llx-0x%llx]", alloc_start, alloc_end); memblock_reserve(0x00, (uintptr_t)__pend); printk("memblock: reserved bios+kernel at [0x%016llx-0x%016llx]", 0, (uintptr_t)__pend); } static void init_bootfb(multiboot_info_t *mb) { __bootfb_varinfo.fb_xres = mb->framebuffer_width; __bootfb_varinfo.fb_yres = mb->framebuffer_height; __bootfb_varinfo.fb_bpp = mb->framebuffer_bpp; __bootfb_varinfo.fb_stride = mb->framebuffer_pitch; __bootfb_fixedinfo.fb_baseptr = mb->framebuffer_addr; switch (mb->framebuffer_type) { case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED: __bootfb_varinfo.fb_flags = FB_MODE_PALETTE; __bootfb_varinfo.fb_palette_addr = mb->framebuffer_palette_addr; __bootfb_varinfo.fb_palette_nr_colours = mb->framebuffer_palette_num_colors; break; case MULTIBOOT_FRAMEBUFFER_TYPE_RGB: __bootfb_varinfo.fb_flags = FB_MODE_RGB; __bootfb_varinfo.fb_red.b_length = mb->framebuffer_red_mask_size; __bootfb_varinfo.fb_red.b_offset = mb->framebuffer_red_field_position; __bootfb_varinfo.fb_green.b_length = mb->framebuffer_green_mask_size; __bootfb_varinfo.fb_green.b_offset = mb->framebuffer_green_field_position; __bootfb_varinfo.fb_blue.b_length = mb->framebuffer_blue_mask_size; __bootfb_varinfo.fb_blue.b_offset = mb->framebuffer_blue_field_position; __bootfb_varinfo.fb_alpha.b_length = 0; __bootfb_varinfo.fb_alpha.b_offset = 0; break; case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT: __bootfb_fixedinfo.fb_baseptr = 0xb8000; __bootfb_varinfo.fb_flags = FB_MODE_VGATEXT; __bootfb_varinfo.fb_xcells = 80; __bootfb_varinfo.fb_ycells = 25; break; default: break; } } static void use_uniprocessor_topology(void) { cpu_set_available(0); cpu_set_online(0); } int ml_init(uintptr_t arg) { multiboot_info_t *mb = (multiboot_info_t *)arg; parse_cmdline(PTR32(mb->cmdline)); init_bootfb(mb); bootstrap_cpu_init(); #ifdef KEXT_NET_DOORSTUCK_SOCKS_FBCON early_vgacon_init(); #endif serialcon_init(115200); clock_calibrate(500); print_kernel_banner(); early_vm_init(); printk("video mode: %ux%u", mb->framebuffer_width, mb->framebuffer_height); e820_scan(PTR32(mb->mmap_addr), mb->mmap_length); pmap_bootstrap(); #ifdef KEXT_NET_DOORSTUCK_SOCKS_ACPI acpi_scan_cpu_topology(); #else use_uniprocessor_topology(); #endif init_per_cpu_areas(); struct cpu_data *this_cpu = get_this_cpu(); memset(this_cpu, 0x0, sizeof *this_cpu); this_cpu->c_flags = CPU_ONLINE; this_cpu->c_id = this_cpu(); g_bootstrap_cpu.c_data = this_cpu; put_cpu(this_cpu); struct vm_zone_descriptor vm_zones[] = { { .zd_id = VM_ZONE_DMA, .zd_node = 0, .zd_name = "dma", .zd_base = 0x00, .zd_limit = 0xffffff }, { .zd_id = VM_ZONE_NORMAL, .zd_node = 0, .zd_name = "normal", .zd_base = 0x1000000, .zd_limit = UINTPTR_MAX }, }; vm_bootstrap(vm_zones, sizeof vm_zones / sizeof vm_zones[0]); object_bootstrap(); init_kernel_kext(); sched_init(); device_init(); #ifdef KEXT_NET_DOORSTUCK_SOCKS_ACPI acpi_init(); #endif tty_bootstrap(); ml_int_enable(); return 0; } const struct framebuffer_varinfo *bootfb_varinfo(void) { return &__bootfb_varinfo; } const struct framebuffer_fixedinfo *bootfb_fixedinfo(void) { return &__bootfb_fixedinfo; }