#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** * Pristine copy of the LWK boot command line. */ char lwk_command_line[COMMAND_LINE_SIZE]; /** * This is the architecture-independent kernel entry point. Before it is * called, architecture-specific code has done the bare minimum initialization * necessary. This function initializes the kernel and its various subsystems. * It calls back to architecture-specific code at several well defined points, * which all architectures must implement (e.g., setup_arch()). */ void start_kernel() { unsigned int cpu; unsigned int timeout; int status; /* * Parse the kernel boot command line. * This is where boot-time configurable variables get set, * e.g., the ones with param() and driver_param() specifiers. */ parse_params(lwk_command_line); /* * Initialize the console subsystem. * printk()'s will be visible after this. */ console_init(); /* * Hello, Dave. */ printk(lwk_banner); printk(KERN_DEBUG "%s\n", lwk_command_line); /* * Do architecture specific initialization. * This detects memory, CPUs, etc. */ setup_arch(); /* * Initialize the kernel memory subsystem. Up until now, the simple * boot-time memory allocator (bootmem) has been used for all dynamic * memory allocation. Here, the bootmem allocator is destroyed and all * of the free pages it was managing are added to the kernel memory * pool (kmem) or the user memory pool (umem). * * After this point, any use of the bootmem allocator will cause a * kernel panic. The normal kernel memory subsystem API should be used * instead (e.g., kmem_alloc() and kmem_free()). */ mem_subsys_init(); /* * Initialize the address space management subsystem. */ aspace_subsys_init(); /* * Initialize the task management subsystem. */ task_subsys_init(); /* * Initialize the task scheduling subsystem. */ sched_subsys_init(); /* * Initialize the task scheduling subsystem. */ timer_subsys_init(); /* * Boot all of the other CPUs in the system, one at a time. */ printk(KERN_INFO "Number of CPUs detected: %d\n", num_cpus()); for_each_cpu_mask(cpu, cpu_present_map) { /* The bootstrap CPU (that's us) is already booted. */ if (cpu == 0) { cpu_set(cpu, cpu_online_map); continue; } printk(KERN_DEBUG "Booting CPU %u.\n", cpu); arch_boot_cpu(cpu); /* Wait for ACK that CPU has booted (5 seconds max). */ for (timeout = 0; timeout < 50000; timeout++) { if (cpu_isset(cpu, cpu_online_map)) break; udelay(100); } if (!cpu_isset(cpu, cpu_online_map)) panic("Failed to boot CPU %d.\n", cpu); } #ifdef CONFIG_V3VEE { struct v3_os_hooks os_hooks; struct v3_ctrl_ops v3_ops; struct guest_info * vm_info = 0; struct v3_vm_config vm_config; memset(&os_hooks, 0, sizeof(struct v3_os_hooks)); memset(&v3_ops, 0, sizeof(struct v3_ctrl_ops)); memset(&vm_config, 0, sizeof(struct v3_vm_config)); printk( KERN_INFO "Calling Init_V3\n" ); Init_V3(&os_hooks, &v3_ops); printk( KERN_INFO "Rombios: %p @ %d\n", &rombios_start, &rombios_end - &rombios_start, ); printk( KERN_INFO "VGA Bios: %p @ %d\n", &vgabios_start, &vgabios_end - &vgabios_start ); } #endif /* * Start up user-space... */ printk(KERN_INFO "Loading initial user-level task (init_task)...\n"); if ((status = create_init_task()) != 0) panic("Failed to create init_task (status=%d).", status); schedule(); /* This should not return */ BUG(); }