Chinaunix首页 | 论坛 | 博客
  • 博客访问: 82278
  • 博文数量: 28
  • 博客积分: 65
  • 博客等级: 民兵
  • 技术积分: 115
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-04 11:06
文章分类

全部博文(28)

文章存档

2014年(22)

2013年(5)

2012年(1)

我的朋友

分类: 嵌入式

2014-04-21 20:34:23

tatic noinline void __init_refok rest_init(void)
{
int pid;
rcu_scheduler_starting();
/*
* We need to spawn init first so that it obtains pid 1, however
* the init task will end up wanting to create kthreads, which, if
* we schedule it before we create kthreadd, will OOPS.
*/
/***********创建kernel_init进程**进程号为1********************************/

kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
numa_default_policy();
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
rcu_read_lock();
kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
创建kthreadd内核线程,它的作用是管理和调度其它内核线程。
它循环运行一个叫做kthreadd的函数,该函数的作用是运行kthread_create_list全局链表中维护的内核线程。
调用kthread_create创建一个kthread,它会被加入到kthread_create_list 链表中;
被执行过的kthread会从kthread_create_list链表中删除;
且kthreadd会不断调用scheduler函数让出CPU。此线程不可关闭。

rcu_read_unlock();
complete(&kthreadd_done);
/*
* The boot idle thread must execute schedule()
* at least once to get things moving:
*/
init_idle_bootup_task(current);
preempt_enable_no_resched();
schedule();
preempt_disable();
/* Call into cpu_idle with preempt disabled */
cpu_idle();
}
进入kernel_init进程

点击(此处)折叠或打开

  1. tatic int __init kernel_init(void * unused)
  2. {
  3.     /*
  4.      * Wait until kthreadd is all set-up.
  5.      */
  6.     wait_for_completion(&kthreadd_done);
  7.     /*
  8.      * init can allocate pages on any node
  9.      */
  10.     set_mems_allowed(node_states[N_HIGH_MEMORY]);
  11.     /*
  12.      * init can run on any cpu.
  13.      */
  14.     set_cpus_allowed_ptr(current, cpu_all_mask);
  15.     /*
  16.      * Tell the world that we're going to be the grim
  17.      * reaper of innocent orphaned children.
  18.      *
  19.      * We don't want people to have to make incorrect
  20.      * assumptions about where in the task array this
  21.      * can be found.
  22.      */
  23.     init_pid_ns.child_reaper = current;

  24.     cad_pid = task_pid(current);

  25.     smp_prepare_cpus(setup_max_cpus);

  26.     do_pre_smp_initcalls();
  27.     lockup_detector_init();

  28.     smp_init();
  29.     sched_init_smp();
  30. /*初始化设备驱动,完成其他驱动程序(直接编译进内核的模块)的初始化。
    内核中部分的启动数据输出出自这里。
    */
  31.     do_basic_setup();


  32.     /* Open the /dev/console on the rootfs, this should never fail */
  33.     if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
  34.         printk(KERN_WARNING "Warning: unable to open an initial console.\n");
  35. /*复制两次标准输入 一次作为输出 一次作为出错 */
  36.     (void) sys_dup(0);
  37.     (void) sys_dup(0);
  38.     /*
  39.      * check if there is an early userspace init. If yes, let it do all
  40.      * the work
  41.      */

  42.     if (!ramdisk_execute_command)
  43.         ramdisk_execute_command = "/init";

  44.     if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
  45.         ramdisk_execute_command = NULL;
  46.         prepare_namespace();
  47.     }

  48.     /*
  49.      * Ok, we have completed the initial bootup, and
  50.      * we're essentially up and running. Get rid of the
  51.      * initmem segments and start the user-mode stuff..
  52.      */
    1. /*准备执行用户应用程序*/
  53.     init_post();
  54.     return 0;
  55. }
内核初始化过程中,通过do_base_setup来完成驱动的初始化 注册加载进内核

点击(此处)折叠或打开

  1. /*
  2.  * Ok, the machine is now initialized. None of the devices
  3.  * have been touched yet, but the CPU subsystem is up and
  4.  * running, and memory and process management works.

  5.  * Now we can finally start doing some real work..
  6.  */
  7. static void __init do_basic_setup(void)
  8. {
  9. cpuset_init_smp();
  10. usermodehelper_init();
  11. init_tmpfs();
  12. driver_init();
  13. init_irq_proc();
  14. do_ctors();
  15. do_initcalls();
  16. }
driver_init()函数分析:

点击(此处)折叠或打开

  1. /**
  2.  * driver_init - initialize driver model.
  3.  *
  4.  * Call the driver model init functions to initialize their
  5.  * subsystems. Called early from init/main.c.
  6.  */
  7. void __init driver_init(void)
  8. {
  9.     /* These are the core pieces */
  10. 初始化devtmpfs文件系统,驱动核心设备将在这个文件系统中添加它们的设备节点。
    这个文件系统可以由内核在挂载根文件系统之后自动挂载到/dev下,
  11. 也可以在文件系统的启动脚本中手动挂载
  12.     devtmpfs_init();
  13.      创建一些设备 char Blok 结点
  14.     devices_init();
  15. 初始化驱动模型中的bus子系统
  16.     buses_init();
  17.     classes_init();
  18.     firmware_init();

  19.     hypervisor_init();

  20.     /* These are also core pieces, but must come after the
  21.      * core core pieces.
  22.      */
  23.    bus/platform子系统
  24.     platform_bus_init();
  25. 初始化驱动模型中的system子系统
  26.     system_bus_init();
  27. 初始化驱动模型中的devices cpu子系统
  28.     cpu_dev_init();
  29.     memory_dev_init();
  30. }
do_initcalls()函数:
调用所有编译内核的驱动模块中的初始化函数。
其中按照各个内核模块初始化函数所自定义的启动级别(1~7),按顺序调用器初始化函数。
对于同一级别的初始化函数,安装编译是链接的顺序调用,也就是和内核Makefile的编写有关。
 在编写内核模块的时候需要知道这方面的知识,
 如果编写的模块必须和依赖的模块在同一级,那就必须注意内核Makefile的修改了。

点击(此处)折叠或打开

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

  4.     for (fn = __early_initcall_end; fn < __initcall_end; fn++)
  5.         do_one_initcall(*fn);
  6. }
  7. 比如:board中初始化函数的调用
  8. static int __init customize_machine(void)
    {
    /* customizes platform devices, or adds new ones */
    if (machine_desc->init_machine)
    machine_desc->init_machine();
    return 0;
    }
    arch_initcall(customize_machine);

    点击(此处)折叠或打开

    1. #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)
    2. #define arch_initcall(fn) __define_initcall("3",fn,3)
    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)


    4. #define INITCALLS                            \
    5.     *(.initcallearly.init)                        \
    6.     VMLINUX_SYMBOL(__early_initcall_end) = .;            \
    7.       *(.initcall0.init)                        \
    8.       *(.initcall0s.init)                        \
    9.       *(.initcall1.init)                        \
    10.       *(.initcall1s.init)                        \
    11.       *(.initcall2.init)                        \
    12.       *(.initcall2s.init)                        \
    13.       *(.initcall3.init)                        \
    14.       *(.initcall3s.init)                        \
    15.       *(.initcall4.init)                        \
    16.       *(.initcall4s.init)                        \
    17.       *(.initcall5.init)                        \
    18.       *(.initcall5s.init)                        \
    19.     *(.initcallrootfs.init)                        \
    20.       *(.initcall6.init)                        \
    21.       *(.initcall6s.init)                        \
    22.       *(.initcall7.init)                        \
    23.       *(.initcall7s.init)

    24. #define INIT_CALLS                            \
    25.         VMLINUX_SYMBOL(__initcall_start) = .;            \
    26.         INITCALLS                        \
    27.         VMLINUX_SYMBOL(__initcall_end) = .;










阅读(1711) | 评论(0) | 转发(0) |
0

上一篇:看void __init setup_arch(char **cmdline_p)函数

下一篇:没有了

给主人留下些什么吧!~~