Linux内核源码分析--内核启动之(6)Image内核启动(do_basic_setup函数)(Linux-3.0 ARMv7)【转】

简介:

原文地址:Linux内核源码分析--内核启动之(6)Image内核启动(do_basic_setup函数)(Linux-3.0 ARMv7) 作者:tekkamanninja

 转自:http://blog.chinaunix.net/uid-25909619-id-4938396.html

    在基本分析完内核启动流程的之后,还有一个比较重要的初始化函数没有分析,那就是do_basic_setup。在内核init线程中调用了do_basic_setup,这个函数也做了很多内核和驱动的初始化工作,详解如下:

  1. /*
  2.  * 好了, 设备现在已经初始化完成。 但是还没有一个设备被初始化过,
  3.  * 但是 CPU 的子系统已经启动并运行,
  4.  * 且内存和处理器管理系统已经在工作了。
  5.  *
  6.  * 现在我们终于可以开始做一些实际的工作了..
  7.  */
  8. static void __init do_basic_setup(void)
  9. {
  10.     cpuset_init_smp();

    点击(此处)折叠或打开

    1. 针对SMP系统,初始化内核control group的cpuset子系统。如果非SMP,此函数为空。
    2. cpuset是在用户空间中操作cgroup文件系统来执行进程与cpu和进程与内存结点之间的绑定。
    3. 本函数将cpus_allowed和mems_allwed更新为在线的cpu和在线的内存结点,并为内存热插拨注册了钩子函数,最后创建一个单线程工作队列cpuset。
  11.     usermodehelper_init();

    点击(此处)折叠或打开

    1. 创建一个单线程工作队列khelper。运行的系统中只有一个,主要作用是指定用户空间的程序路径和环境变量, 最终运行指定的user space的程序,属于关键线程,不能关闭。
  12.     init_tmpfs();

    点击(此处)折叠或打开

    1. 初始化内核tmpfs文件系统
  13.     driver_init();

    点击(此处)折叠或打开

    1. 初始化驱动模型中的各子系统,可见的现象是在/sys中出现的目录和文件
  14.     init_irq_proc();

    点击(此处)折叠或打开

    1. 在proc文件系统中创建irq目录,并在其中初始化系统中所有中断对应的目录。
  15.     do_ctors();

    点击(此处)折叠或打开

    1. 调用链接到内核中的所有构造函数,也就是链接进.ctors段中的所有函数。
    2. 在Linux-2.6.31开始内核启动增加了对构造函数的支持。
    3. git提交:

      点击(此处)折叠或打开

      1. commit b99b87f70c7785ab1e253c6220f4b0b57ce3a7f7
      2. Author: Peter Oberparleiter<oberpar@linux.vnet.ibm.com>
      3. Date: Wed Jun 17 16:28:03 2009 -0700
      4. kernel: constructor support
        内核:构造函数支持
      1. Call constructors (gcc-generated initcall-like functions) during kernel
      2. start and module load. Constructors are e.g. used for gcov data
      3. initialization.
      4. 在内核启动和模块挂载时,调用构造函数(gcc生成的类初始化函数)。构造函数就是
      5. 比如用于初始化gcov数据的函数
      6. Disable constructor support for usermode Linux to prevent conflicts with
      7. host glibc.
      8. 对于Linux的用户模式禁用构造函数支持,以避免和glibc冲突。
      9. Signed-off-by: Peter Oberparleiter<oberpar@linux.vnet.ibm.com>
      10. Acked-by: Rusty Russell<rusty@rustcorp.com.au>
      11. Acked-by: WANG Cong<xiyou.wangcong@gmail.com>
      12. Cc: Sam Ravnborg<sam@ravnborg.org>
      13. Cc: Jeff Dike<jdike@addtoit.com>
      14. Cc: Andi Kleen<andi@firstfloor.org>
      15. Cc: Huang Ying<ying.huang@intel.com>
      16. Cc: Li Wei<w.li@sun.com>
      17. Cc: Michael Ellerman<michaele@au1.ibm.com>
      18. Cc: Ingo Molnar<mingo@elte.hu>
      19. Cc: Heiko Carstens<heicars2@linux.vnet.ibm.com>
      20. Cc: Martin Schwidefsky<mschwid2@linux.vnet.ibm.com>
      21. Cc: Al Viro<viro@zeniv.linux.org.uk>
      22. Signed-off-by: Andrew Morton<akpm@linux-foundation.org>
      23. Signed-off-by: Linus Torvalds<torvalds@linux-foundation.org>
      $ git tag --contains b99b87f7
      v2.6.31
      v2.6.31-rc1
      v2.6.31-rc2
      v2.6.31-rc3
      v2.6.31-rc4
      v2.6.31-rc5
      v2.6.31-rc6
      v2.6.31-rc7
      v2.6.31-rc8
      v2.6.31-rc9
      v2.6.32
      v2.6.32-rc1
      v2.6.32-rc2
      v2.6.32-rc3
      v2.6.32-rc4
      v2.6.32-rc5
      v2.6.32-rc6
      v2.6.32-rc7
      v2.6.32-rc8
  16.     do_initcalls();

    点击(此处)折叠或打开

    1. 调用所有编译内核的驱动模块中的初始化函数。
    2. 这里就是驱动程序员需要关心的步骤,其中按照各个内核模块初始化函数所自定义的启动级别(1~7),按顺序调用器初始化函数。
    3. 对于同一级别的初始化函数,安装编译是链接的顺序调用,也就是和内核Makefile的编写有关。
      在编写内核模块的时候需要知道这方面的知识,比如你编写的模块使用的是I2C的API,那你的模块的初始化函数的级别必须低于I2C子系统初始化函数的级别(也就是级别数(1~7)要大于I2C子系统)。如果编写的模块必须和依赖的模块在同一级,那就必须注意内核Makefile的修改了。
      这方面的知识会在有空的时候总结下,网上也有相关的文章。
     
  17. }
上面的函数调用了driver_init函数,作用是驱动模型子系统的初始化,对于内核驱动工程师来说比较重要,详解如下:
drivers/base/init.c:
  1. /**
  2.  * driver_init - 初始化驱动模型.
  3.  *
  4.  * 调用驱动模型初始化函数来初始化它们的子系统。
  5.  * 由早期的init/main.c中调用。
  6.  */
  7. void __init driver_init(void)
  8. {
  9.     /* 它们为核心部件 */
  10.     devtmpfs_init();

    点击(此处)折叠或打开

    1. 初始化devtmpfs文件系统,驱动核心设备将在这个文件系统中添加它们的设备节点。
    2. 这个文件系统可以由内核在挂载根文件系统之后自动挂载到/dev下,也可以在文件系统的启动脚本中手动挂载。
  11.     devices_init();

    点击(此处)折叠或打开

    1. 初始化驱动模型中的部分子系统和kobject:
    2. devices
    3. dev
    4. dev/block
    5. dev/char
  12.     buses_init();

    点击(此处)折叠或打开

    1. 初始化驱动模型中的bus子系统
  13.     classes_init();

    点击(此处)折叠或打开

    1. 初始化驱动模型中的class子系统
  14.     firmware_init();

    点击(此处)折叠或打开

    1. 初始化驱动模型中的firmware子系统
  15.     hypervisor_init();

    点击(此处)折叠或打开

    1. 初始化驱动模型中的hypervisor子系统
  16.     /* 这些也是核心部件, 但是必须
  17.      * 在以上核心中的核心部件之后调用。
  18.      */
  19.     platform_bus_init();

    点击(此处)折叠或打开

    1. 初始化驱动模型中的bus/platform子系统
  20.     system_bus_init();

    点击(此处)折叠或打开

    1. 初始化驱动模型中的devices/system子系统
  21.     cpu_dev_init();

    点击(此处)折叠或打开

    1. 初始化驱动模型中的devices/system/cpu子系统
  22.     memory_dev_init();

    点击(此处)折叠或打开

    1. 初始化驱动模型中的devices/system/memory子系统
    2. 虽然从代码上看这样,但是我在实际的系统中并没有找到/sys/devices/system/memory这个目录
  23. }











本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sky-heaven/p/4847416.html,如需转载请自行联系原作者

相关文章
|
20天前
|
存储 Linux 数据处理
探索Linux操作系统的内核与文件系统
本文深入探讨了Linux操作系统的核心组件,包括其独特的内核结构和灵活的文件系统。文章首先概述了Linux内核的主要功能和架构,接着详细分析了文件系统的工作原理以及它如何支持数据存储和检索。通过比较不同的文件系统类型,本文旨在为读者提供一个关于如何根据特定需求选择合适文件系统的参考框架。
|
25天前
|
安全 算法 网络协议
探索Linux操作系统的内核管理
【5月更文挑战第31天】本文将深入探讨Linux操作系统的内核管理机制,包括其设计原则、主要组件以及它们如何协同工作以提供高效的系统性能。通过分析Linux内核的关键特性和功能,我们将揭示这一开源操作系统如何在各种计算环境中保持其稳定性和灵活性。
|
26天前
|
机器学习/深度学习 人工智能 负载均衡
深度解析:Linux内核调度策略的演变与优化
【5月更文挑战第30天】 随着计算技术的不断进步,操作系统的性能调优成为了提升计算机系统效率的关键。在众多操作系统中,Linux因其开源和高度可定制性而备受青睐。本文将深入剖析Linux操作系统的内核调度策略,追溯其历史演变过程,并重点探讨近年来为适应多核处理器和实时性要求而产生的调度策略优化。通过分析比较不同的调度算法,如CFS(完全公平调度器)、实时调度类和批处理作业的调度需求,本文旨在为系统管理员和开发者提供对Linux调度机制深层次理解,同时指出未来可能的发展趋势。
|
6天前
|
Linux
查看linux内核版本
在Linux中查看内核版本可使用`uname -r`、`cat /proc/version`、`lsb_release -a`(若安装LSB)、`/etc/*release`或`/etc/*version`文件、`dmesg | grep Linux`、`cat /sys/class/dmi/id/product_name`、`hostnamectl`、`kernrelease`(如果支持)、`rpm -q kernel`(RPM系统)和`dpkg -l linux-image-*`(Debian系统)。
21 4
|
7天前
|
安全 Linux 数据处理
探索Linux的kmod命令:管理内核模块的利器
`kmod`是Linux下管理内核模块的工具,用于加载、卸载和管理模块及其依赖。使用`kmod load`来加载模块,`kmod remove`卸载模块,`kmod list`查看已加载模块,`kmod alias`显示模块别名。注意需有root权限,且要考虑依赖关系和版本兼容性。最佳实践包括备份、查阅文档和使用额外的管理工具。
|
19天前
|
Linux C++
Linux C/C++ main函数
Linux C/C++ main函数
|
19天前
|
运维 NoSQL Ubuntu
深入理解Linux中的"crash"命令:内核崩溃的调试利器
`crash`是Linux内核崩溃调试工具,用于分析内核崩溃转储文件,提供GDB-like的交互式CLI。通过加载`vmcore`文件和内核映像,管理员可以查看系统状态、调用栈、内存布局等。安装`crash`可使用包管理器,如`apt-get`或`yum/dnf`。尽管有学习曲线且依赖转储文件,但`crash`在系统故障排查中极其重要。
|
26天前
|
Linux
探索Linux操作系统的内核模块
本文将深入探讨Linux操作系统的核心组成部分——内核模块,揭示其背后的工作机制和实现方式。我们将从内核模块的定义开始,逐步解析其加载、卸载以及与操作系统其他部分的交互过程,最后探讨内核模块在系统性能优化中的关键作用。
|
13天前
|
Linux 编译器 C语言
编译Linux内核:基础、重要性和交叉编译方法
Linux内核作为操作系统的心脏,负责管理计算机的硬件资源,同时也是运行所有其他程序的基础。理解如何编译Linux内核对于系统管理员、开发者乃至高级用户来说都是一项极其宝贵的技能。本文将介绍编译Linux内核的基本知识、编译的重要性、具体步骤以及交叉编译的概念。
23 0
|
27天前
|
缓存 算法 安全
探索Linux内核的虚拟内存管理
【5月更文挑战第29天】 在现代操作系统中,虚拟内存是支持多任务处理和内存保护的关键组件。本文深入分析了Linux操作系统中的虚拟内存管理机制,包括其地址空间布局、分页系统以及内存分配策略。我们将探讨虚拟内存如何允许多个进程独立地访问它们自己的地址空间,同时由操作系统管理物理内存资源。此外,文章还将涉及虚拟内存所带来的性能影响及其优化方法。