void lrt_pic_init(lrt_pic_handler h) { LRT_Assert(has_lapic()); init_idt(); disable_pic(); //Disable the pit, irq 0 could have fired and therefore //wouldn't have been masked and then we enable interrupts //so we must reset the PIT (and we may as well prevent it from firing) disable_pit(); //Disable the rtc, irq 8 could have fired and therefore //wouldn't have been masked and then we enable interrupts //so we must disable it disable_rtc(); acpi_init(); enable_lapic(); lrt_pic_myid = get_lapic_id(); lrt_pic_mapipi(h); lrt_pic_loop(); }
void arch_init(void) { k_stacks = (void*) &k_stacks_start; assert(!((vir_bytes) k_stacks % K_STACK_SIZE)); #ifndef CONFIG_SMP /* * use stack 0 and cpu id 0 on a single processor machine, SMP * configuration does this in smp_init() for all cpus at once */ tss_init(0, get_k_stack_top(0)); #endif #if !CONFIG_OXPCIE ser_init(); #endif #ifdef USE_ACPI acpi_init(); #endif #if defined(USE_APIC) && !defined(CONFIG_SMP) if (config_no_apic) { BOOT_VERBOSE(printf("APIC disabled, using legacy PIC\n")); } else if (!apic_single_cpu_init()) { BOOT_VERBOSE(printf("APIC not present, using legacy PIC\n")); } #endif /* Reserve some BIOS ranges */ cut_memmap(&kinfo, BIOS_MEM_BEGIN, BIOS_MEM_END); cut_memmap(&kinfo, BASE_MEM_TOP, UPPER_MEM_END); }
int arch_devtree_populate(struct vmm_devtree_node **root) { int rc = VMM_OK; struct fdt_fileinfo fdt; /* Parse skeletal FDT */ rc = libfdt_parse_fileinfo((virtual_addr_t) & dt_blob_start, &fdt); if (rc) { return rc; } /* Populate skeletal FDT */ rc = libfdt_parse_devtree(&fdt, root); if (rc) { return rc; } /* FIXME: Populate device tree from ACPI table */ #if CONFIG_ACPI /* * Initialize the ACPI table to help initialize * other devices. */ acpi_init(); #endif return VMM_OK; }
PUBLIC void arch_init(void) { #ifdef CONFIG_APIC /* * this is setting kernel segments to cover most of the phys memory. The * value is high enough to reach local APIC nad IOAPICs before paging is * turned on. */ prot_set_kern_seg_limit(0xfff00000); reload_ds(); #endif idt_init(); tss_init(&tss, &k_boot_stktop, 0); acpi_init(); #if defined(CONFIG_APIC) && !defined(CONFIG_SMP) if (config_no_apic) { BOOT_VERBOSE(printf("APIC disabled, using legacy PIC\n")); } else if (!apic_single_cpu_init()) { BOOT_VERBOSE(printf("APIC not present, using legacy PIC\n")); } #endif fpu_init(); }
void arch_pre_smp_init(void) { if (config.cpu_active == 1) { #ifdef CONFIG_SMP acpi_init(); #endif /* CONFIG_SMP */ } }
void main (uint32_t mboot_magic, uint32_t mboot_info) { multiboot_memmap_t *first_free; uint64_t *new_stack; asm volatile ("cli"); cpu_early_init(); x64_gdt_init(); x64_idt_init(); vga_console_init(); printk("\n================================\n"); printk("||==Welcome to CELLOS 64 bit==||"); printk("\n================================\n"); /* Read mboot header */ first_free = mboot_init(mboot_info, mboot_magic); if (first_free == NULL) { panic("No free memory for use! STOP~!\n"); } mb_parse_kernel_image(); paging_init(first_free->base_addr, first_free->base_addr + first_free->length); /* Init page allocator */ page_alloc_init(mem_get_low_addr(),mem_get_high_addr()); /* Initialize the memory pool */ init_memory_pool(CONFIG_KHEAP_SIZE, (void *)page_alloc_contig(CONFIG_KHEAP_SIZE/PAGE_SIZE)); detect_cpu(); acpi_init(); smp_init(); paging_late_init(); sched_core_init(); sched_init(); reschedule(); /* No reached */ }
/** PC platform initialization. */ __init_text void platform_init(void) { pic_init(); acpi_init(); /* If the LAPIC is not available, we must use the PIT as the timer. */ if(!lapic_enabled()) pit_init(); i8042_init(); }
void arch_cpu_processor_init_2(void) { acpi_init(); x86_hpet_init(); #if _DBOS_KERNEL_HAVE_CPU_SMP probe_smp(); init_lapic(); calibrate_lapic_timer(1000); init_ioapic(); set_ksf(KSF_SMP_ENABLE); #endif }
NTSTATUS Bus_StartFdo ( PFDO_DEVICE_DATA FdoData, PIRP Irp ) { NTSTATUS status = STATUS_SUCCESS; POWER_STATE powerState; ACPI_STATUS AcpiStatus; PAGED_CODE (); FdoData->Common.DevicePowerState = PowerDeviceD0; powerState.DeviceState = PowerDeviceD0; PoSetPowerState ( FdoData->Common.Self, DevicePowerState, powerState ); SET_NEW_PNP_STATE(FdoData->Common, Started); AcpiStatus = AcpiInitializeSubsystem(); if(ACPI_FAILURE(AcpiStatus)){ DPRINT1("Unable to AcpiInitializeSubsystem\n"); return STATUS_UNSUCCESSFUL; } AcpiStatus = AcpiInitializeTables(NULL, 16, 0); if (ACPI_FAILURE(status)){ DPRINT1("Unable to AcpiInitializeSubsystem\n"); return STATUS_UNSUCCESSFUL; } AcpiStatus = AcpiLoadTables(); if(ACPI_FAILURE(AcpiStatus)){ DPRINT1("Unable to AcpiLoadTables\n"); AcpiTerminate(); return STATUS_UNSUCCESSFUL; } DPRINT("Acpi subsystem init\n"); /* Initialize ACPI bus manager */ AcpiStatus = acpi_init(); if (!ACPI_SUCCESS(AcpiStatus)) { DPRINT1("acpi_init() failed with status 0x%X\n", AcpiStatus); AcpiTerminate(); return STATUS_UNSUCCESSFUL; } status = ACPIEnumerateDevices(FdoData); return status; }
PUBLIC void arch_init(void) { #ifdef USE_APIC /* * this is setting kernel segments to cover most of the phys memory. The * value is high enough to reach local APIC nad IOAPICs before paging is * turned on. */ prot_set_kern_seg_limit(0xfff00000); reload_ds(); #endif idt_init(); /* FIXME stupid a.out * align the stacks in the stack are to the K_STACK_SIZE which is a * power of 2 */ k_stacks = (void*) (((vir_bytes)&k_stacks_start + K_STACK_SIZE - 1) & ~(K_STACK_SIZE - 1)); #ifndef CONFIG_SMP /* * use stack 0 and cpu id 0 on a single processor machine, SMP * configuration does this in smp_init() for all cpus at once */ tss_init(0, get_k_stack_top(0)); #endif #if !CONFIG_OXPCIE ser_init(); #endif #ifdef USE_ACPI acpi_init(); #endif #if defined(USE_APIC) && !defined(CONFIG_SMP) if (config_no_apic) { BOOT_VERBOSE(printf("APIC disabled, using legacy PIC\n")); } else if (!apic_single_cpu_init()) { BOOT_VERBOSE(printf("APIC not present, using legacy PIC\n")); } #endif }
/** * This is the first real C function ever called. It performs a lot of * hardware-specific initialization, then creates a pseudo-context to * execute the bootstrap function in. */ void kmain() { GDB_CALL_HOOK(boot); dbg_init(); dbgq(DBG_CORE, "Kernel binary:\n"); dbgq(DBG_CORE, " text: 0x%p-0x%p\n", &kernel_start_text, &kernel_end_text); dbgq(DBG_CORE, " data: 0x%p-0x%p\n", &kernel_start_data, &kernel_end_data); dbgq(DBG_CORE, " bss: 0x%p-0x%p\n", &kernel_start_bss, &kernel_end_bss); page_init(); pt_init(); slab_init(); pframe_init(); acpi_init(); apic_init(); pci_init(); intr_init(); gdt_init(); /* initialize slab allocators */ #ifdef __VM__ anon_init(); shadow_init(); #endif vmmap_init(); proc_init(); kthread_init(); #ifdef __DRIVERS__ bytedev_init(); blockdev_init(); #endif void *bstack = page_alloc(); pagedir_t *bpdir = pt_get(); KASSERT(NULL != bstack && "Ran out of memory while booting."); context_setup(&bootstrap_context, bootstrap, 0, NULL, bstack, PAGE_SIZE, bpdir); context_make_active(&bootstrap_context); panic("\nReturned to kmain()!!!\n"); }
int main(int argc, char *argv[]) { char c, *prog; int sleep_type; prog = argv[0]; if (argc < 2) usage(prog); /* NOTREACHED */ sleep_type = -1; acpi_init(); while ((c = getopt(argc, argv, "hi:k:s:")) != -1) { switch (c) { case 'i': acpi_battinfo(atoi(optarg)); break; case 'k': acpi_sleep_ack(atoi(optarg)); break; case 's': if (optarg[0] == 'S') sleep_type = optarg[1] - '0'; else sleep_type = optarg[0] - '0'; if (sleep_type < 1 || sleep_type > 4) errx(EX_USAGE, "invalid sleep type (%d)", sleep_type); break; case 'h': default: usage(prog); /* NOTREACHED */ } } argc -= optind; argv += optind; if (sleep_type != -1) acpi_sleep(sleep_type); close(acpifd); exit (0); }
int __init arch_cpu_early_init(void) { /* * Host virtual memory, device tree, heap is up. * Do necessary early stuff like iomapping devices * memory or boot time memory reservation here. */ #if CONFIG_ACPI /* * Initialize the ACPI table to help initialize * other devices. */ acpi_init(); #endif return 0; }
int main() { //Start video driver (must always be before loading message) mm_init(); pg_init(); real_init(); video_init(); video_setdriver(video_vgatext_getdriver(),0); //Put loading message cli_puts("ArcaneOS Loading...\n"); //Setup kernel gdt_init(); idt_init(); isr_init(); irq_init(); timer_init(); kb_init(); ui_init(); cpuid_init(); cmos_init(); rtc_init(); acpi_init(); power_init(); mt_init(); syscall_init(); floppy_init(); __asm__ __volatile__ ("sti"); //Enable ACPI acpi_enable(); //Create thread for ui mt_create_thread(mt_kernel_process,test,2); //Endless loop to prevent bugs when all threads are sleeping for(;;) __asm__ __volatile__ ("hlt"); }
void bsp_init() { serial_init(); console_bold(); console_puts("Starting nubbin " VERSION); console_reset(); kdata_init(); memory_map_init_finish(); acpi_init(); smbios_init(); cpu_bsp_init(); hello_user(); /* Bounces to cpu_trampoline() on return */ }
void test_acpi(void) { acpi_init(); }
// The main function int init(unsigned long magic, multiboot_info_t* hdr) { setGDT(); init_heap(); #ifdef SLAB slab_alloc_init(); #endif textInit(); /** * \todo Make complement_heap so that it allocates memory from pte */ complement_heap(&end, HEAPSIZE); addr_t tmp = (addr_t)hdr + offset; hdr = (multiboot_info_t*)tmp; if (magic != MULTIBOOT_BOOTLOADER_MAGIC) { printf("\nInvalid magic word: %X\n", magic); panic(""); } if (hdr->flags & MULTIBOOT_INFO_MEMORY) { memsize = hdr->mem_upper; memsize += 1024; } else panic("No memory flags!"); if (!(hdr->flags & MULTIBOOT_INFO_MEM_MAP)) panic("Invalid memory map"); mmap = (multiboot_memory_map_t*) hdr->mmap_addr; /** Build the memory map and allow for allocation */ x86_pte_init(); page_alloc_init(mmap, (unsigned int)hdr->mmap_length); vm_init(); #ifdef PA_DBG // endProg(); #endif /** In the progress of phasing out */ /** Set up paging administration */ x86_page_init(memsize); mboot_page_setup(mmap, (uint32_t)hdr->mmap_length); mboot_map_modules((void*)hdr->mods_addr, hdr->mods_count); /** For now this is the temporary page table map */ build_map(mmap, (unsigned int) hdr->mmap_length); /** end of deprication */ task_init(); page_init(); printf(WELCOME); // The only screen output that should be maintained page_unmap_low_mem(); pic_init(); setIDT(); setup_irq_data(); if (dev_init() != -E_SUCCESS) panic("Couldn't initialise /dev"); ol_pit_init(1024); // program pic to 1024 hertz debug("Size of the heap: 0x%x\tStarting at: %x\n", HEAPSIZE, heap); acpi_init(); ol_cpu_t cpu = kalloc(sizeof (*cpu)); if (cpu == NULL) panic("OUT OF MEMORY!"); ol_cpu_init(cpu); ol_ps2_init_keyboard(); ol_apic_init(cpu); init_ioapic(); ol_pci_init(); debug("Little endian 0xf in net endian %x\n", htons(0xf)); #ifdef DBG #ifdef __IOAPIC_DBG ioapic_debug(); #endif #ifdef __MEMTEST ol_detach_all_devices(); /* free's al the pci devices */ #endif #ifdef __DBG_HEAP printf("Heap list:\n"); ol_dbg_heap(); #endif printf("\nSome (temp) debug info:\n"); printf("CPU vendor: %s\n", cpus->vendor); if(systables->magic == SYS_TABLE_MAGIC) { printf("RSDP ASCII signature: 0x%x%x\n", *(((uint32_t*) systables->rsdp->signature) + 1), *(((uint32_t*) systables->rsdp->signature))); printf("MP specification signature: 0x%x\n", systables->mp->signature); } #endif #ifdef PA_DBG addr_t p = (addr_t)page_alloc(); page_free((void*)p); printf("Allocated: %X\n", p); page_dump(); #endif #ifdef PA_DBG addr_t p = (addr_t)page_alloc(); page_free((void*)p); printf("Allocated: %X\n", p); page_dump(); #endif core_loop(); return 0; // To keep the compiler happy. }
int kern_init(uint64_t mbmagic, uint64_t mbmem) { extern char edata[], end[]; memset(edata, 0, end - edata); /* percpu variable for CPU0 is preallocated */ percpu_offsets[0] = __percpu_start; cons_init(); // init the console const char *message = "(THU.CST) os is loading ..."; kprintf("%s\n\n", message); if(mbmagic == MULTIBOOT_BOOTLOADER_MAGIC){ kprintf("Multiboot dectected: param %p\n", (void*)mbmem); mbmem2e820((Mbdata*)VADDR_DIRECT(mbmem)); parse_initrd((Mbdata*)VADDR_DIRECT(mbmem)); } print_kerninfo(); /* get_cpu_var not available before tls_init() */ hz_init(); gdt_init(per_cpu_ptr(cpus, 0)); tls_init(per_cpu_ptr(cpus, 0)); acpitables_init(); lapic_init(); numa_init(); pmm_init_numa(); // init physical memory management, numa awared /* map the lapic */ lapic_init_late(); //init the acpi stuff idt_init(); // init interrupt descriptor table pic_init(); // init interrupt controller // acpi_conf_init(); percpu_init(); cpus_init(); #ifdef UCONFIG_ENABLE_IPI ipi_init(); #endif refcache_init(); vmm_init(); // init virtual memory management sched_init(); // init scheduler proc_init(); // init process table sync_init(); // init sync struct /* ext int */ ioapic_init(); acpi_init(); ide_init(); // init ide devices #ifdef UCONFIG_SWAP swap_init(); // init swap #endif fs_init(); // init fs clock_init(); // init clock interrupt mod_init(); trap_init(); //XXX put here? bootaps(); intr_enable(); // enable irq interrupt #ifdef UCONFIG_HAVE_LINUX_DDE36_BASE dde_kit_init(); #endif /* do nothing */ cpu_idle(); // run idle process }
/** * This is the first real C function ever called. It performs a lot of * hardware-specific initialization, then creates a pseudo-context to * execute the bootstrap function in. */ void kmain() { GDB_CALL_HOOK(boot); dbg_init(); dbgq(DBG_CORE, "Kernel binary:\n"); dbgq(DBG_CORE, " text: 0x%p-0x%p\n", &kernel_start_text, &kernel_end_text); dbgq(DBG_CORE, " data: 0x%p-0x%p\n", &kernel_start_data, &kernel_end_data); dbgq(DBG_CORE, " bss: 0x%p-0x%p\n", &kernel_start_bss, &kernel_end_bss); page_init(); pt_init(); slab_init(); pframe_init(); acpi_init(); apic_init(); pci_init(); intr_init(); gdt_init(); /* initialize slab allocators */ #ifdef __VM__ anon_init(); shadow_init(); #endif vmmap_init(); proc_init(); kthread_init(); #ifdef __DRIVERS__ bytedev_init(); blockdev_init(); #endif void *bstack = page_alloc(); pagedir_t *bpdir = pt_get(); KASSERT(NULL != bstack && "Ran out of memory while booting."); /* This little loop gives gdb a place to synch up with weenix. In the * past the weenix command started qemu was started with -S which * allowed gdb to connect and start before the boot loader ran, but * since then a bug has appeared where breakpoints fail if gdb connects * before the boot loader runs. See * * https://bugs.launchpad.net/qemu/+bug/526653 * * This loop (along with an additional command in init.gdb setting * gdb_wait to 0) sticks weenix at a known place so gdb can join a * running weenix, set gdb_wait to zero and catch the breakpoint in * bootstrap below. See Config.mk for how to set GDBWAIT correctly. * * DANGER: if GDBWAIT != 0, and gdb is not running, this loop will never * exit and weenix will not run. Make SURE the GDBWAIT is set the way * you expect. */ while (gdb_wait) ; context_setup(&bootstrap_context, bootstrap, 0, NULL, bstack, PAGE_SIZE, bpdir); context_make_active(&bootstrap_context); panic("\nReturned to kmain()!!!\n"); }
/* * Ok, the machine is now initialized. None of the devices * have been touched yet, but the CPU subsystem is up and * running, and memory and process management works. * * Now we can finally start doing some real work.. */ static void __init do_basic_setup(void) { /* * Tell the world that we're going to be the grim * reaper of innocent orphaned children. * * We don't want people to have to make incorrect * assumptions about where in the task array this * can be found. */ child_reaper = current; #if defined(CONFIG_MTRR) /* Do this after SMP initialization */ /* * We should probably create some architecture-dependent "fixup after * everything is up" style function where this would belong better * than in init/main.c.. */ mtrr_init(); #endif #ifdef CONFIG_SYSCTL sysctl_init(); #endif /* * Ok, at this point all CPU's should be initialized, so * we can start looking into devices.. */ #if defined(CONFIG_ARCH_S390) s390_init_machine_check(); #endif #ifdef CONFIG_ACPI_INTERPRETER acpi_init(); #endif #ifdef CONFIG_PCI pci_init(); #endif #ifdef CONFIG_SBUS sbus_init(); #endif #if defined(CONFIG_PPC) ppc_init(); #endif #ifdef CONFIG_MCA mca_init(); #endif #ifdef CONFIG_ARCH_ACORN ecard_init(); #endif #ifdef CONFIG_ZORRO zorro_init(); #endif #ifdef CONFIG_DIO dio_init(); #endif #ifdef CONFIG_NUBUS nubus_init(); #endif #ifdef CONFIG_ISAPNP isapnp_init(); #endif #ifdef CONFIG_TC tc_init(); #endif /* Networking initialization needs a process context */ sock_init(); start_context_thread(); do_initcalls(); #ifdef CONFIG_IRDA irda_proto_init(); irda_device_init(); /* Must be done after protocol initialization */ #endif #ifdef CONFIG_PCMCIA init_pcmcia_ds(); /* Do this last */ #endif }
static BOOT_CODE bool_t try_boot_sys( unsigned long multiboot_magic, multiboot_info_t* mbi ) { /* ==== following code corresponds to the "select" in abstract specification ==== */ acpi_rsdt_t* acpi_rsdt; /* physical address of ACPI root */ paddr_t mods_end_paddr; /* physical address where boot modules end */ paddr_t load_paddr; word_t i; p_region_t ui_p_regs; multiboot_module_t *modules = (multiboot_module_t*)(word_t)mbi->mod_list; if (multiboot_magic != MULTIBOOT_MAGIC) { printf("Boot loader not multiboot compliant\n"); return false; } cmdline_parse((const char *)(word_t)mbi->cmdline, &cmdline_opt); if ((mbi->flags & MULTIBOOT_INFO_MEM_FLAG) == 0) { printf("Boot loader did not provide information about physical memory size\n"); return false; } if (!x86_cpuid_initialize()) { printf("Warning: Your x86 CPU has an unsupported vendor, '%s'.\n" "\tYour setup may not be able to competently run seL4 as " "intended.\n" "\tCurrently supported x86 vendors are AMD and Intel.\n", x86_cpuid_get_identity()->vendor_string); } if (!is_compiled_for_microarchitecture()) { printf("Warning: Your kernel was not compiled for the current microarchitecture.\n"); } #if CONFIG_MAX_NUM_NODES > 1 /* copy boot code for APs to lower memory to run in real mode */ if (!copy_boot_code_aps(mbi->mem_lower)) { return false; } /* Initialize any kernel TLS */ mode_init_tls(0); #endif /* initialize the memory. We track two kinds of memory regions. Physical memory * that we will use for the kernel, and physical memory regions that we must * not give to the user. Memory regions that must not be given to the user * include all the physical memory in the kernel window, but also includes any * important or kernel devices. */ boot_state.mem_p_regs.count = 0; init_allocated_p_regions(); if (mbi->flags & MULTIBOOT_INFO_MMAP_FLAG) { if (!parse_mem_map(mbi->mmap_length, mbi->mmap_addr)) { return false; } } else { /* calculate memory the old way */ p_region_t avail; avail.start = HIGHMEM_PADDR; avail.end = ROUND_DOWN(avail.start + (mbi->mem_upper << 10), PAGE_BITS); if (!add_mem_p_regs(avail)) { return false; } } boot_state.ki_p_reg.start = PADDR_LOAD; boot_state.ki_p_reg.end = kpptr_to_paddr(ki_end); /* copy VESA information from multiboot header */ if ((mbi->flags & MULTIBOOT_INFO_GRAPHICS_FLAG) == 0) { boot_state.vbe_info.vbeMode = -1; printf("Multiboot gave us no video information\n"); } else { boot_state.vbe_info.vbeInfoBlock = *(seL4_VBEInfoBlock_t*)(seL4_Word)mbi->vbe_control_info; boot_state.vbe_info.vbeModeInfoBlock = *(seL4_VBEModeInfoBlock_t*)(seL4_Word)mbi->vbe_mode_info; boot_state.vbe_info.vbeMode = mbi->vbe_mode; printf("Got VBE info in multiboot. Current video mode is %d\n", mbi->vbe_mode); boot_state.vbe_info.vbeInterfaceSeg = mbi->vbe_interface_seg; boot_state.vbe_info.vbeInterfaceOff = mbi->vbe_interface_off; boot_state.vbe_info.vbeInterfaceLen = mbi->vbe_interface_len; } printf("Kernel loaded to: start=0x%lx end=0x%lx size=0x%lx entry=0x%lx\n", boot_state.ki_p_reg.start, boot_state.ki_p_reg.end, boot_state.ki_p_reg.end - boot_state.ki_p_reg.start, (paddr_t)_start ); /* remapping legacy IRQs to their correct vectors */ pic_remap_irqs(IRQ_INT_OFFSET); if (config_set(CONFIG_IRQ_IOAPIC)) { /* Disable the PIC so that it does not generate any interrupts. We need to * do this *before* we initialize the apic */ pic_disable(); } /* get ACPI root table */ acpi_rsdt = acpi_init(); if (!acpi_rsdt) { return false; } /* check if kernel configuration matches platform requirments */ if (!acpi_fadt_scan(acpi_rsdt)) { return false; } if (!config_set(CONFIG_IOMMU) || cmdline_opt.disable_iommu) { boot_state.num_drhu = 0; } else { /* query available IOMMUs from ACPI */ acpi_dmar_scan( acpi_rsdt, boot_state.drhu_list, &boot_state.num_drhu, MAX_NUM_DRHU, &boot_state.rmrr_list ); } /* query available CPUs from ACPI */ boot_state.num_cpus = acpi_madt_scan(acpi_rsdt, boot_state.cpus, &boot_state.num_ioapic, boot_state.ioapic_paddr); if (boot_state.num_cpus == 0) { printf("No CPUs detected\n"); return false; } if (config_set(CONFIG_IRQ_IOAPIC)) { if (boot_state.num_ioapic == 0) { printf("No IOAPICs detected\n"); return false; } } else { if (boot_state.num_ioapic > 0) { printf("Detected %d IOAPICs, but configured to use PIC instead\n", boot_state.num_ioapic); } } if (!(mbi->flags & MULTIBOOT_INFO_MODS_FLAG)) { printf("Boot loader did not provide information about boot modules\n"); return false; } printf("Detected %d boot module(s):\n", mbi->mod_count); if (mbi->mod_count < 1) { printf("Expect at least one boot module (containing a userland image)\n"); return false; } mods_end_paddr = 0; for (i = 0; i < mbi->mod_count; i++) { printf( " module #%ld: start=0x%x end=0x%x size=0x%x name='%s'\n", i, modules[i].start, modules[i].end, modules[i].end - modules[i].start, (char *) (long)modules[i].name ); if ((sword_t)(modules[i].end - modules[i].start) <= 0) { printf("Invalid boot module size! Possible cause: boot module file not found by QEMU\n"); return false; } if (mods_end_paddr < modules[i].end) { mods_end_paddr = modules[i].end; } } mods_end_paddr = ROUND_UP(mods_end_paddr, PAGE_BITS); assert(mods_end_paddr > boot_state.ki_p_reg.end); printf("ELF-loading userland images from boot modules:\n"); load_paddr = mods_end_paddr; load_paddr = load_boot_module(modules, load_paddr); if (!load_paddr) { return false; } /* calculate final location of userland images */ ui_p_regs.start = boot_state.ki_p_reg.end; ui_p_regs.end = ui_p_regs.start + load_paddr - mods_end_paddr; printf( "Moving loaded userland images to final location: from=0x%lx to=0x%lx size=0x%lx\n", mods_end_paddr, ui_p_regs.start, ui_p_regs.end - ui_p_regs.start ); memcpy((void*)ui_p_regs.start, (void*)mods_end_paddr, ui_p_regs.end - ui_p_regs.start); /* adjust p_reg and pv_offset to final load address */ boot_state.ui_info.p_reg.start -= mods_end_paddr - ui_p_regs.start; boot_state.ui_info.p_reg.end -= mods_end_paddr - ui_p_regs.start; boot_state.ui_info.pv_offset -= mods_end_paddr - ui_p_regs.start; /* ==== following code corresponds to abstract specification after "select" ==== */ if (!platAddDevices()) { return false; } /* Total number of cores we intend to boot */ ksNumCPUs = boot_state.num_cpus; printf("Starting node #0 with APIC ID %lu\n", boot_state.cpus[0]); if (!try_boot_sys_node(boot_state.cpus[0])) { return false; } if (config_set(CONFIG_IRQ_IOAPIC)) { ioapic_init(1, boot_state.cpus, boot_state.num_ioapic); } /* initialize BKL before booting up APs */ SMP_COND_STATEMENT(clh_lock_init()); SMP_COND_STATEMENT(start_boot_aps()); /* grab BKL before leaving the kernel */ NODE_LOCK_SYS; printf("Booting all finished, dropped to user space\n"); return true; }