从start_kernel到开发板初始化
- -->//板子上电启动后进入start_kernel( )
- start_kernel( )
- -->setup_arch(&command_line)
- //command_line由内核传入
- -->mdesc = setup_machine(machine_arch_type);
- -->list = lookup_machine_type(nr);
- //汇编实现查找机器码所定义的平台,找到后返回mdesc结构
- -->init_machine = mdesc->init_machine;
- //struct machine_desc *mdesc;machine_desc结构很重要,在saar.c中定义此结构
- //machine_arch_type机器码,在UBOOT有定义,内核中也有定义定义
- -->rest_init()
- -->kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
- //定义进程kernel_init,此进程pid=1,会在kthreadd进程创建好后调度运行
- -->kernel_init()
- -->do_basic_setup()
- -->driver_init()
- -->devices_init()
- -->buses_init()
- -->classes_init()
- -->platform_bus_init()
- -->do_initcalls()
- //此函数很重要,执行了initcall表中所有的函数,包含了init_machine(saar_init())函数
- -->saar_init()
- -->init_post()
- //调度用户空间程序,比如bash,在用户空间死循环执行程序
- -->pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
- //定义进程kthreadd
- /******************start_kernel() @ /init/main.c *************************/
- asmlinkage void __init start_kernel(void)
- {
- char * command_line;
- extern struct kernel_param __start___param[], __stop___param[];
- smp_setup_processor_id();
- /*
- * Need to run as early as possible, to initialize the
- * lockdep hash:
- */
- lockdep_init();
- debug_objects_early_init();
- cgroup_init_early();
- local_irq_disable();
- early_boot_irqs_off();
- early_init_irq_lock_class();
- /*
- * Interrupts are still disabled. Do necessary setups, then
- * enable them
- */
- lock_kernel();
- tick_init();
- boot_cpu_init();
- page_address_init();
- printk(KERN_NOTICE);
- printk(linux_banner);
- setup_arch(&command_line);
- mm_init_owner(&init_mm, &init_task);
- setup_command_line(command_line);
- setup_per_cpu_areas();
- setup_nr_cpu_ids();
- smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
- /*
- * Set up the scheduler prior starting any interrupts (such as the
- * timer interrupt). Full topology setup happens at smp_init()
- * time - but meanwhile we still have a functioning scheduler.
- */
- sched_init();
- /*
- * Disable preemption - early bootup scheduling is extremely
- * fragile until we cpu_idle() for the first time.
- */
- preempt_disable();
- build_all_zonelists();
- page_alloc_init();
- printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);
- parse_early_param();
- parse_args("Booting kernel", static_command_line, __start___param,
- __stop___param - __start___param,
- &unknown_bootoption);
- if (!irqs_disabled()) {
- printk(KERN_WARNING "start_kernel(): bug: interrupts were "
- "enabled *very* early, fixing it\n");
- local_irq_disable();
- }
- sort_main_extable();
- trap_init();
- rcu_init();
- /* init some links before init_ISA_irqs() */
- early_irq_init();
- init_IRQ();
- pidhash_init();
- init_timers();
- hrtimers_init();
- softirq_init();
- timekeeping_init();
- time_init();
- sched_clock_init();
- profile_init();
- if (!irqs_disabled())
- printk(KERN_CRIT "start_kernel(): bug: interrupts were "
- "enabled early\n");
- early_boot_irqs_on();
- local_irq_enable();
- /*
- * HACK This is early. We're enabling the console before
- * we've done PCI setups etc, and console_init() must be aware of
- * this. But we do want output early, in case something goes wrong.
- */
- console_init();
- if (panic_later)
- panic(panic_later, panic_param);
- lockdep_info();
- /*
- * Need to run this when irqs are enabled, because it wants
- * to self-test [hard/soft]-irqs on/off lock inversion bugs
- * too:
- */
- locking_selftest();
- #ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_start && !initrd_below_start_ok &&
- page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
- printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
- "disabling it.\n",
- page_to_pfn(virt_to_page((void *)initrd_start)),
- min_low_pfn);
- initrd_start = 0;
- }
- #endif
- vmalloc_init();
- vfs_caches_init_early();
- cpuset_init_early();
- page_cgroup_init();
- mem_init();
- enable_debug_pagealloc();
- cpu_hotplug_init();
- kmem_cache_init();
- debug_objects_mem_init();
- idr_init_cache();
- setup_per_cpu_pageset();
- numa_policy_init();
- if (late_time_init)
- late_time_init();
- calibrate_delay();
- pidmap_init();
- pgtable_cache_init();
- prio_tree_init();
- anon_vma_init();
- #ifdef CONFIG_X86
- if (efi_enabled)
- efi_enter_virtual_mode();
- #endif
- thread_info_cache_init();
- cred_init();
- fork_init(num_physpages);
- proc_caches_init();
- buffer_init();
- key_init();
- security_init();
- vfs_caches_init(num_physpages);
- radix_tree_init();
- signals_init();
- /* rootfs populating might need page-writeback */
- page_writeback_init();
- #ifdef CONFIG_PROC_FS
- proc_root_init();
- #endif
- cgroup_init();
- cpuset_init();
- taskstats_init_early();
- delayacct_init();
- check_bugs();
- acpi_early_init(); /* before LAPIC and SMP init */
- ftrace_init();
- /* Do the rest non-__init'ed, we're now alive */
- rest_init();
- }
- /******************start_kernel() end **********************/
- void __init setup_arch(char **cmdline_p)
- {
- struct tag *tags = (struct tag *)&init_tags;
- struct machine_desc *mdesc;
- char *from = default_command_line;
- setup_processor();
- mdesc = setup_machine(machine_arch_type);
- machine_name = mdesc->name;
- if (mdesc->soft_reboot)
- reboot_setup("s");
- if (__atags_pointer)
- tags = phys_to_virt(__atags_pointer);
- else if (mdesc->boot_params)
- tags = phys_to_virt(mdesc->boot_params);
- /*
- * If we have the old style parameters, convert them to
- * a tag list.
- */
- if (tags->hdr.tag != ATAG_CORE)
- convert_to_tag_list(tags);
- if (tags->hdr.tag != ATAG_CORE)
- tags = (struct tag *)&init_tags;
- if (mdesc->fixup)
- mdesc->fixup(mdesc, tags, &from, &meminfo);
- if (tags->hdr.tag == ATAG_CORE) {
- if (meminfo.nr_banks != 0)
- squash_mem_tags(tags);
- save_atags(tags);
- parse_tags(tags);
- }
- init_mm.start_code = (unsigned long) _text;
- init_mm.end_code = (unsigned long) _etext;
- init_mm.end_data = (unsigned long) _edata;
- init_mm.brk = (unsigned long) _end;
- memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
- boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
- parse_cmdline(cmdline_p, from);
- paging_init(mdesc);
- request_standard_resources(&meminfo, mdesc);
- #ifdef CONFIG_SMP
- smp_init_cpus();
- #endif
- cpu_init();
- /*
- * Set up various architecture-specific pointers
- */
- init_arch_irq = mdesc->init_irq;
- system_timer = mdesc->timer;
- init_machine = mdesc->init_machine;
- #ifdef CONFIG_VT
- #if defined(CONFIG_VGA_CONSOLE)
- conswitchp = &vga_con;
- #elif defined(CONFIG_DUMMY_CONSOLE)
- conswitchp = &dummy_con;
- #endif
- #endif
- early_trap_init();
- }
- static int __init kernel_init(void * unused)
- {
- lock_kernel();
- /*
- * init can run on any cpu.
- */
- set_cpus_allowed_ptr(current, CPU_MASK_ALL_PTR);
- /*
- * 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.
- */
- init_pid_ns.child_reaper = current;
- cad_pid = task_pid(current);
- smp_prepare_cpus(setup_max_cpus);
- do_pre_smp_initcalls();
- start_boot_trace();
- smp_init();
- sched_init_smp();
- cpuset_init_smp();
- do_basic_setup();
- /*
- * check if there is an early userspace init. If yes, let it do all
- * the work
- */
- if (!ramdisk_execute_command)
- ramdisk_execute_command = "/init";
- if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
- ramdisk_execute_command = NULL;
- prepare_namespace();
- }
- /*
- * Ok, we have completed the initial bootup, and
- * we're essentially up and running. Get rid of the
- * initmem segments and start the user-mode stuff..
- */
- init_post();
- return 0;
- }
- static void __init do_basic_setup(void)
- {
- rcu_init_sched(); /* needed by module_init stage. */
- init_workqueues();
- usermodehelper_init();
- driver_init();
- init_irq_proc();
- do_initcalls();
- }
- void __init driver_init(void)
- {
- /* These are the core pieces */
- devices_init();
- buses_init();
- classes_init();
- firmware_init();
- hypervisor_init();
- /* These are also core pieces, but must come after the
- * core core pieces.
- */
- platform_bus_init();
- system_bus_init();
- cpu_dev_init();
- memory_dev_init();
- }
点击(此处)折叠或打开
- static void __init do_initcalls(void)
- {
- initcall_t *call;
- for (call = __early_initcall_end; call < __initcall_end; call++)
- do_one_initcall(*call);
- /* Make sure there is no pending stuff from the initcall sequence */
- flush_scheduled_work();
- }
点击(此处)折叠或打开
- static noinline int init_post(void)
- {
- /* need to finish all async __init code before freeing the memory */
- async_synchronize_full();
- free_initmem();
- unlock_kernel();
- mark_rodata_ro();
- system_state = SYSTEM_RUNNING;
- numa_default_policy();
- if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
- printk(KERN_WARNING "Warning: unable to open an initial console.\n");
- (void) sys_dup(0);
- (void) sys_dup(0);
- current->signal->flags |= SIGNAL_UNKILLABLE;
- if (ramdisk_execute_command) {
- run_init_process(ramdisk_execute_command);
- printk(KERN_WARNING "Failed to execute %s\n",
- ramdisk_execute_command);
- }
- /*
- * We try each of these until one succeeds.
- *
- * The Bourne shell can be used instead of init if we are
- * trying to recover a really broken machine.
- */
- if (execute_command) {
- run_init_process(execute_command);
- printk(KERN_WARNING "Failed to execute %s. Attempting "
- "defaults...\n", execute_command);
- }
- run_init_process("/sbin/init");
- run_init_process("/etc/init");
- run_init_process("/bin/init");
- run_init_process("/bin/sh");
- panic("No init found. Try passing init= option to kernel.");
- }
- MACHINE_START(SAAR, "PXA930 handheld Platform (SAAR)")
- .phys_io = 0x40000000,
- .boot_params = 0xa0000100,
- .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
- .map_io = pxa_map_io,
- .init_irq = pxa3xx_init_irq,
- .timer = &pxa_timer,
- .init_machine = saar_init,
- MACHINE_END
- #define MACHINE_START(_type,_name) \
- static const struct machine_desc __mach_desc_##_type \
- __used \
- __attribute__((__section__(".arch.info.init"))) = { \
- .nr = MACH_TYPE_##_type, \
- .name = _name,
- #define MACHINE_END \
- };
- static void (*init_machine)(void) __initdata;
- static int __init customize_machine(void)
- {
- /* customizes platform devices, or adds new ones */
- if (init_machine)
- init_machine();
- return 0;
- }
- arch_initcall(customize_machine);
- #define __define_initcall(level,fn,id) \
- static initcall_t __initcall_##fn##id __used \
- __attribute__((__section__(".initcall" level ".init"))) = fn
- /*
- * Early initcalls run before initializing SMP.
- *
- * Only for built-in code, not modules.
- */
- #define early_initcall(fn) __define_initcall("early",fn,early)
- /*
- * A "pure" initcall has no dependencies on anything else, and purely
- * initializes variables that couldn't be statically initialized.
- *
- * This only exists for built-in code, not for modules.
- */
- #define pure_initcall(fn) __define_initcall("0",fn,0)
- #define core_initcall(fn) __define_initcall("1",fn,1)
- #define core_initcall_sync(fn) __define_initcall("1s",fn,1s)
- #define postcore_initcall(fn) __define_initcall("2",fn,2)
- #define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s)
- #define arch_initcall(fn) __define_initcall("3",fn,3)
- #define arch_initcall_sync(fn) __define_initcall("3s",fn,3s)
- #define subsys_initcall(fn) __define_initcall("4",fn,4)
- #define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s)
- #define fs_initcall(fn) __define_initcall("5",fn,5)
- #define fs_initcall_sync(fn) __define_initcall("5s",fn,5s)
- #define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs)
- #define device_initcall(fn) __define_initcall("6",fn,6)
- #define device_initcall_sync(fn) __define_initcall("6s",fn,6s)
- #define late_initcall(fn) __define_initcall("7",fn,7)
- #define late_initcall_sync(fn) __define_initcall("7s",fn,7s)
- #define __initcall(fn) device_initcall(fn)
- #define __exitcall(fn) \
- static exitcall_t __exitcall_##fn __exit_call = fn
- static struct machine_desc * __init setup_machine(unsigned int nr)
- {
- struct machine_desc *list;
- /*
- * locate machine in the list of supported machines.
- */
- list = lookup_machine_type(nr);
- if (!list) {
- printk("Machine configuration botched (nr %d), unable "
- "to continue.\n", nr);
- while (1);
- }
- printk("Machine: %s\n", list->name);
- return list;
- }
阅读(1207) | 评论(0) | 转发(0) |