Chinaunix首页 | 论坛 | 博客
  • 博客访问: 367488
  • 博文数量: 82
  • 博客积分: 1104
  • 博客等级: 少尉
  • 技术积分: 926
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-16 15:14
文章分类
文章存档

2012年(82)

分类: LINUX

2012-07-10 10:00:30

从start_kernel到开发板初始化

点击(此处)折叠或打开

  1. -->//板子上电启动后进入start_kernel( )
  2.     start_kernel( )
  3.         -->setup_arch(&command_line)
  4.         //command_line由内核传入
  5.             -->mdesc = setup_machine(machine_arch_type);
  6.                 -->list = lookup_machine_type(nr);
  7.                 //汇编实现查找机器码所定义的平台,找到后返回mdesc结构
  8.             -->init_machine = mdesc->init_machine;
  9.             //struct machine_desc *mdesc;machine_desc结构很重要,在saar.c中定义此结构
  10.             //machine_arch_type机器码,在UBOOT有定义,内核中也有定义定义
  11.         -->rest_init()
  12.             -->kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
  13.             //定义进程kernel_init,此进程pid=1,会在kthreadd进程创建好后调度运行
  14.                 -->kernel_init()
  15.                     -->do_basic_setup()
  16.                         -->driver_init()
  17.                             -->devices_init()
  18.                             -->buses_init()
  19.                             -->classes_init()
  20.                             -->platform_bus_init()
  21.                         -->do_initcalls()
  22.                         //此函数很重要,执行了initcall表中所有的函数,包含了init_machine(saar_init())函数
  23.                             -->saar_init()
  24.                     -->init_post()
  25.                     //调度用户空间程序,比如bash,在用户空间死循环执行程序
  26.             -->pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
  27.             //定义进程kthreadd

点击(此处)折叠或打开

  1. /******************start_kernel() @ /init/main.c *************************/

  2. asmlinkage void __init start_kernel(void)
  3. {
  4.     char * command_line;
  5.     extern struct kernel_param __start___param[], __stop___param[];

  6.     smp_setup_processor_id();

  7.     /*
  8.      * Need to run as early as possible, to initialize the
  9.      * lockdep hash:
  10.      */
  11.     lockdep_init();
  12.     debug_objects_early_init();
  13.     cgroup_init_early();

  14.     local_irq_disable();
  15.     early_boot_irqs_off();
  16.     early_init_irq_lock_class();

  17. /*
  18.  * Interrupts are still disabled. Do necessary setups, then
  19.  * enable them
  20.  */
  21.     lock_kernel();
  22.     tick_init();
  23.     boot_cpu_init();
  24.     page_address_init();
  25.     printk(KERN_NOTICE);
  26.     printk(linux_banner);
  27.     setup_arch(&command_line);
  28.     mm_init_owner(&init_mm, &init_task);
  29.     setup_command_line(command_line);
  30.     setup_per_cpu_areas();
  31.     setup_nr_cpu_ids();
  32.     smp_prepare_boot_cpu();    /* arch-specific boot-cpu hooks */

  33.     /*
  34.      * Set up the scheduler prior starting any interrupts (such as the
  35.      * timer interrupt). Full topology setup happens at smp_init()
  36.      * time - but meanwhile we still have a functioning scheduler.
  37.      */
  38.     sched_init();
  39.     /*
  40.      * Disable preemption - early bootup scheduling is extremely
  41.      * fragile until we cpu_idle() for the first time.
  42.      */
  43.     preempt_disable();
  44.     build_all_zonelists();
  45.     page_alloc_init();
  46.     printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);
  47.     parse_early_param();
  48.     parse_args("Booting kernel", static_command_line, __start___param,
  49.          __stop___param - __start___param,
  50.          &unknown_bootoption);
  51.     if (!irqs_disabled()) {
  52.         printk(KERN_WARNING "start_kernel(): bug: interrupts were "
  53.                 "enabled *very* early, fixing it\n");
  54.         local_irq_disable();
  55.     }
  56.     sort_main_extable();
  57.     trap_init();
  58.     rcu_init();
  59.     /* init some links before init_ISA_irqs() */
  60.     early_irq_init();
  61.     init_IRQ();
  62.     pidhash_init();
  63.     init_timers();
  64.     hrtimers_init();
  65.     softirq_init();
  66.     timekeeping_init();
  67.     time_init();
  68.     sched_clock_init();
  69.     profile_init();
  70.     if (!irqs_disabled())
  71.         printk(KERN_CRIT "start_kernel(): bug: interrupts were "
  72.                  "enabled early\n");
  73.     early_boot_irqs_on();
  74.     local_irq_enable();

  75.     /*
  76.      * HACK This is early. We're enabling the console before
  77.      * we've done PCI setups etc, and console_init() must be aware of
  78.      * this. But we do want output early, in case something goes wrong.
  79.      */
  80.     console_init();
  81.     if (panic_later)
  82.         panic(panic_later, panic_param);

  83.     lockdep_info();

  84.     /*
  85.      * Need to run this when irqs are enabled, because it wants
  86.      * to self-test [hard/soft]-irqs on/off lock inversion bugs
  87.      * too:
  88.      */
  89.     locking_selftest();

  90. #ifdef CONFIG_BLK_DEV_INITRD
  91.     if (initrd_start && !initrd_below_start_ok &&
  92.      page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
  93.         printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
  94.          "disabling it.\n",
  95.          page_to_pfn(virt_to_page((void *)initrd_start)),
  96.          min_low_pfn);
  97.         initrd_start = 0;
  98.     }
  99. #endif
  100.     vmalloc_init();
  101.     vfs_caches_init_early();
  102.     cpuset_init_early();
  103.     page_cgroup_init();
  104.     mem_init();
  105.     enable_debug_pagealloc();
  106.     cpu_hotplug_init();
  107.     kmem_cache_init();
  108.     debug_objects_mem_init();
  109.     idr_init_cache();
  110.     setup_per_cpu_pageset();
  111.     numa_policy_init();
  112.     if (late_time_init)
  113.         late_time_init();
  114.     calibrate_delay();
  115.     pidmap_init();
  116.     pgtable_cache_init();
  117.     prio_tree_init();
  118.     anon_vma_init();
  119. #ifdef CONFIG_X86
  120.     if (efi_enabled)
  121.         efi_enter_virtual_mode();
  122. #endif
  123.     thread_info_cache_init();
  124.     cred_init();
  125.     fork_init(num_physpages);
  126.     proc_caches_init();
  127.     buffer_init();
  128.     key_init();
  129.     security_init();
  130.     vfs_caches_init(num_physpages);
  131.     radix_tree_init();
  132.     signals_init();
  133.     /* rootfs populating might need page-writeback */
  134.     page_writeback_init();
  135. #ifdef CONFIG_PROC_FS
  136.     proc_root_init();
  137. #endif
  138.     cgroup_init();
  139.     cpuset_init();
  140.     taskstats_init_early();
  141.     delayacct_init();

  142.     check_bugs();

  143.     acpi_early_init(); /* before LAPIC and SMP init */

  144.     ftrace_init();

  145.     /* Do the rest non-__init'ed, we're now alive */
  146.     rest_init();
  147. }
  148. /******************start_kernel() end **********************/

点击(此处)折叠或打开

  1. void __init setup_arch(char **cmdline_p)
  2. {
  3.     struct tag *tags = (struct tag *)&init_tags;
  4.     struct machine_desc *mdesc;
  5.     char *from = default_command_line;

  6.     setup_processor();
  7.     mdesc = setup_machine(machine_arch_type);
  8.     machine_name = mdesc->name;

  9.     if (mdesc->soft_reboot)
  10.         reboot_setup("s");

  11.     if (__atags_pointer)
  12.         tags = phys_to_virt(__atags_pointer);
  13.     else if (mdesc->boot_params)
  14.         tags = phys_to_virt(mdesc->boot_params);

  15.     /*
  16.      * If we have the old style parameters, convert them to
  17.      * a tag list.
  18.      */
  19.     if (tags->hdr.tag != ATAG_CORE)
  20.         convert_to_tag_list(tags);
  21.     if (tags->hdr.tag != ATAG_CORE)
  22.         tags = (struct tag *)&init_tags;

  23.     if (mdesc->fixup)
  24.         mdesc->fixup(mdesc, tags, &from, &meminfo);

  25.     if (tags->hdr.tag == ATAG_CORE) {
  26.         if (meminfo.nr_banks != 0)
  27.             squash_mem_tags(tags);
  28.         save_atags(tags);
  29.         parse_tags(tags);
  30.     }

  31.     init_mm.start_code = (unsigned long) _text;
  32.     init_mm.end_code = (unsigned long) _etext;
  33.     init_mm.end_data = (unsigned long) _edata;
  34.     init_mm.brk     = (unsigned long) _end;

  35.     memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
  36.     boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
  37.     parse_cmdline(cmdline_p, from);
  38.     paging_init(mdesc);
  39.     request_standard_resources(&meminfo, mdesc);

  40. #ifdef CONFIG_SMP
  41.     smp_init_cpus();
  42. #endif

  43.     cpu_init();

  44.     /*
  45.      * Set up various architecture-specific pointers
  46.      */
  47.     init_arch_irq = mdesc->init_irq;
  48.     system_timer = mdesc->timer;
  49.     init_machine = mdesc->init_machine;

  50. #ifdef CONFIG_VT
  51. #if defined(CONFIG_VGA_CONSOLE)
  52.     conswitchp = &vga_con;
  53. #elif defined(CONFIG_DUMMY_CONSOLE)
  54.     conswitchp = &dummy_con;
  55. #endif
  56. #endif
  57.     early_trap_init();
  58. }

点击(此处)折叠或打开

  1. static int __init kernel_init(void * unused)
  2. {
  3.     lock_kernel();
  4.     /*
  5.      * init can run on any cpu.
  6.      */
  7.     set_cpus_allowed_ptr(current, CPU_MASK_ALL_PTR);
  8.     /*
  9.      * Tell the world that we're going to be the grim
  10.      * reaper of innocent orphaned children.
  11.      *
  12.      * We don't want people to have to make incorrect
  13.      * assumptions about where in the task array this
  14.      * can be found.
  15.      */
  16.     init_pid_ns.child_reaper = current;

  17.     cad_pid = task_pid(current);

  18.     smp_prepare_cpus(setup_max_cpus);

  19.     do_pre_smp_initcalls();
  20.     start_boot_trace();

  21.     smp_init();
  22.     sched_init_smp();

  23.     cpuset_init_smp();

  24.     do_basic_setup();

  25.     /*
  26.      * check if there is an early userspace init. If yes, let it do all
  27.      * the work
  28.      */

  29.     if (!ramdisk_execute_command)
  30.         ramdisk_execute_command = "/init";

  31.     if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
  32.         ramdisk_execute_command = NULL;
  33.         prepare_namespace();
  34.     }

  35.     /*
  36.      * Ok, we have completed the initial bootup, and
  37.      * we're essentially up and running. Get rid of the
  38.      * initmem segments and start the user-mode stuff..
  39.      */

  40.     init_post();
  41.     return 0;
  42. }

点击(此处)折叠或打开

  1. static void __init do_basic_setup(void)
  2. {
  3.     rcu_init_sched(); /* needed by module_init stage. */
  4.     init_workqueues();
  5.     usermodehelper_init();
  6.     driver_init();
  7.     init_irq_proc();
  8.     do_initcalls();
  9. }

点击(此处)折叠或打开

  1. void __init driver_init(void)
  2. {
  3.     /* These are the core pieces */
  4.     devices_init();
  5.     buses_init();
  6.     classes_init();
  7.     firmware_init();
  8.     hypervisor_init();

  9.     /* These are also core pieces, but must come after the
  10.      * core core pieces.
  11.      */
  12.     platform_bus_init();
  13.     system_bus_init();
  14.     cpu_dev_init();
  15.     memory_dev_init();
  16. }


点击(此处)折叠或打开

  1. static void __init do_initcalls(void)
  2. {
  3.     initcall_t *call;

  4.     for (call = __early_initcall_end; call < __initcall_end; call++)
  5.         do_one_initcall(*call);

  6.     /* Make sure there is no pending stuff from the initcall sequence */
  7.     flush_scheduled_work();
  8. }


点击(此处)折叠或打开

  1. static noinline int init_post(void)
  2. {
  3.     /* need to finish all async __init code before freeing the memory */
  4.     async_synchronize_full();
  5.     free_initmem();
  6.     unlock_kernel();
  7.     mark_rodata_ro();
  8.     system_state = SYSTEM_RUNNING;
  9.     numa_default_policy();

  10.     if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
  11.         printk(KERN_WARNING "Warning: unable to open an initial console.\n");

  12.     (void) sys_dup(0);
  13.     (void) sys_dup(0);

  14.     current->signal->flags |= SIGNAL_UNKILLABLE;

  15.     if (ramdisk_execute_command) {
  16.         run_init_process(ramdisk_execute_command);
  17.         printk(KERN_WARNING "Failed to execute %s\n",
  18.                 ramdisk_execute_command);
  19.     }

  20.     /*
  21.      * We try each of these until one succeeds.
  22.      *
  23.      * The Bourne shell can be used instead of init if we are
  24.      * trying to recover a really broken machine.
  25.      */
  26.     if (execute_command) {
  27.         run_init_process(execute_command);
  28.         printk(KERN_WARNING "Failed to execute %s. Attempting "
  29.                     "defaults...\n", execute_command);
  30.     }
  31.     run_init_process("/sbin/init");
  32.     run_init_process("/etc/init");
  33.     run_init_process("/bin/init");
  34.     run_init_process("/bin/sh");

  35.     panic("No init found. Try passing init= option to kernel.");
  36. }


点击(此处)折叠或打开

  1. MACHINE_START(SAAR, "PXA930 handheld Platform (SAAR)")
  2.     .phys_io = 0x40000000,
  3.     .boot_params = 0xa0000100,
  4.     .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
  5.     .map_io = pxa_map_io,
  6.     .init_irq = pxa3xx_init_irq,
  7.     .timer = &pxa_timer,
  8.     .init_machine = saar_init,
  9. MACHINE_END


  10. #define MACHINE_START(_type,_name)            \
  11. static const struct machine_desc __mach_desc_##_type    \
  12.  __used                            \
  13.  __attribute__((__section__(".arch.info.init"))) = {    \
  14.     .nr        = MACH_TYPE_##_type,        \
  15.     .name        = _name,

  16. #define MACHINE_END                \
  17. };



  18. static void (*init_machine)(void) __initdata;

  19. static int __init customize_machine(void)
  20. {
  21.     /* customizes platform devices, or adds new ones */
  22.     if (init_machine)
  23.         init_machine();
  24.     return 0;
  25. }
  26. arch_initcall(customize_machine);



  27. #define __define_initcall(level,fn,id) \
  28.     static initcall_t __initcall_##fn##id __used \
  29.     __attribute__((__section__(".initcall" level ".init"))) = fn

  30. /*
  31.  * Early initcalls run before initializing SMP.
  32.  *
  33.  * Only for built-in code, not modules.
  34.  */
  35. #define early_initcall(fn)        __define_initcall("early",fn,early)

  36. /*
  37.  * A "pure" initcall has no dependencies on anything else, and purely
  38.  * initializes variables that couldn't be statically initialized.
  39.  *
  40.  * This only exists for built-in code, not for modules.
  41.  */
  42. #define pure_initcall(fn)        __define_initcall("0",fn,0)

  43. #define core_initcall(fn)        __define_initcall("1",fn,1)
  44. #define core_initcall_sync(fn)        __define_initcall("1s",fn,1s)
  45. #define postcore_initcall(fn)        __define_initcall("2",fn,2)
  46. #define postcore_initcall_sync(fn)    __define_initcall("2s",fn,2s)
  47. #define arch_initcall(fn)        __define_initcall("3",fn,3)
  48. #define arch_initcall_sync(fn)        __define_initcall("3s",fn,3s)
  49. #define subsys_initcall(fn)        __define_initcall("4",fn,4)
  50. #define subsys_initcall_sync(fn)    __define_initcall("4s",fn,4s)
  51. #define fs_initcall(fn)            __define_initcall("5",fn,5)
  52. #define fs_initcall_sync(fn)        __define_initcall("5s",fn,5s)
  53. #define rootfs_initcall(fn)        __define_initcall("rootfs",fn,rootfs)
  54. #define device_initcall(fn)        __define_initcall("6",fn,6)
  55. #define device_initcall_sync(fn)    __define_initcall("6s",fn,6s)
  56. #define late_initcall(fn)        __define_initcall("7",fn,7)
  57. #define late_initcall_sync(fn)        __define_initcall("7s",fn,7s)

  58. #define __initcall(fn) device_initcall(fn)

  59. #define __exitcall(fn) \
  60.     static exitcall_t __exitcall_##fn __exit_call = fn

  61. static struct machine_desc * __init setup_machine(unsigned int nr)
  62. {
  63.     struct machine_desc *list;

  64.     /*
  65.      * locate machine in the list of supported machines.
  66.      */
  67.     list = lookup_machine_type(nr);
  68.     if (!list) {
  69.         printk("Machine configuration botched (nr %d), unable "
  70.          "to continue.\n", nr);
  71.         while (1);
  72.     }

  73.     printk("Machine: %s\n", list->name);

  74.     return list;
  75. }





阅读(6076) | 评论(0) | 转发(3) |
给主人留下些什么吧!~~