`

Android培训班(104)start_kernel函数1

 
阅读更多

经历了跟体系结构密切相关的汇编代码之后,就可以进入C语言编写的结构无关的代码了。这个入口的函数是start_kernel函数,它主要更进一步地初始化系统相关的内容,以便系统进入一种服务状态,提供一种虚拟机的服务,提供各种API调用的服务。在start_kernel函数里,需要非常注意的是里面初始化函数的顺序,这些初始化函数不能随便调换初始化顺序,否则就会导致系统运行出错。由于这个函数的内容非常多,涉及的内容也非常广泛,每个函数都有一个比较大的概念,一种原理,一种想法。因此,对于这个函数的学习需要很多时间,需要有漫长学习的心理准备。由于本书基于ARM体系的一种结构学习,其它与此体系结构无关的代码,就不再分析介绍。好了,现在就来开始学习第一节的内容,代码如下:

asmlinkage void__init start_kernel(void)

{

char * command_line;

看了这段代码,首先发现asmlinkage__init与一般开发C语言的应用程序有着明显的差别,导致看不懂这两个宏到底是用来做干什么用的。其实这两个宏是写内核代码的一种特定表示,一种尽可能快的思想表达,一种尽可能占用空间少的思路。asmlinkage是一个宏定义,它的作用主要有两个,一个是让传送给函数的参数全部使用栈式传送,不用寄存器来传送。因为寄存器的个数有限,使用栈可以传送更多的参数,比如在X86CPU里只能使用6个寄存器传送,只能传送4个参数,而使用栈就没有这种限制;另外一个用处是声明这个函数是给汇编代码调用的。不过在ARM体系里,并没有使用栈传送参数的特性,原因何在?由于ARM体系的寄存器个数比较多,多达13个,这样绝大多数的函数参数都可以通过寄存器来传送,达到高效的目标。因此,看到文件kernel/include/linux/linkage.h里的asmlinkage宏定义如下:

#ifdef __cplusplus

#defineCPP_ASMLINKAGE extern "C"

#else

#defineCPP_ASMLINKAGE

#endif


#ifndef asmlinkage

#define asmlinkageCPP_ASMLINKAGE

#endif

在这里可以看到asmlinkage,其实没有定义,所以ARM体系里还是通过寄存器来传送参数的。如果看一下X86下的代码,就会定义如下:

#ifdef CONFIG_X86_32

#define asmlinkageCPP_ASMLINKAGE __attribute__((regparm(0)))

这里定义asmlinkage为通过栈传送参数。

由此可见,不同的体系结构对代码的优化细节是不一样的,设计的理念不一样。接着来看另外一个宏定义__init,这个宏定义主要用来标志这个函数编译出来的目标代码放在那一段里。对于应用程序的编译和连接,不需要作这样的考虑,但是对于内核代码来说,就需要了,因为不同的段代码有着不同的作用,比如初始化段的代码,当系统运行正常以后,这段代码就没有什么用了,聪明的做法就是回收这段代码占用的内存,让内核的代码占最少的内存。还有另外一个作用,比如同一段的代码都是编译在一起,让相关联的代码尽可能同在一片内存里,这样当CPU加载代码到缓存时,就可以一起命中,提高缓存的命中率,这样就大大提高代码的执行速度。宏__init定义在文件kernel/include/linux/init.h里,代码如下:

#define__init __section(.init.text) __cold notrace

使用这个宏声明的函数,编译时就会把目标代码放到段.init.text里,这段都是放置初始化的代码。


最后看到声明一个字符的指针command_line,这个指针是指向命令行参数的指针,主要用来指向引导程序传送给内核的命令行参数,在后面的函数setup_arch和函数setup_command_line就会对它进行处理。

分享到:
评论

相关推荐

    Linux内核函数Start_kernel()的功能

    Linux内核函数Start_kernel()中调用了一系列初始化函数,以完成kernel本身的设置。这些动作有的是公共的,有的则是需要配置的才会执行的。本文介绍了在start_kernel()函数中的一些功能。

    分析linux start_kernel函数

    Daniel Jslin教授分析linux kernel 中的start_kernel详细过程。by the way.可以关注我在csdn上关于linux kernel的课程https://edu.csdn.net/course/detail/9089

    arm linux 从入口到start_kernel 代码分析

    Arm Linux 内核的启动过程是一个复杂的过程,从POWER ON 到进入 start_kernel 函数,涉及到多个阶段和多个组件的交互。在本文中,我们将从 Arm Linux 内核的入口开始,逐步分析到进入 start_kernel 函数的过程。 一...

    linux内核从start_kernel到init.pdf

    1. 锁定内核:kernel_init 函数首先调用 lock_kernel 函数,以获取大内核锁,这样可以防止其他线程干扰内核的初始化工作。 2. 设置 CPU mask:kernel_init 函数接着调用 set_cpus_allowed_ptr 函数,以设置当前进程...

    arm linux 从入口到start_kernel 代码分析发(4)

    在ARM Linux系统启动的过程中,从入口到`start_kernel`阶段,有一个至关重要的步骤就是创建页表,这使得CPU能够正确地映射物理内存到虚拟内存,从而访问和管理内存资源。本文将深入分析ARM架构下的页表创建过程,...

    linux kernel 从入口到start_kernel 的代码分析.rar

    很好的linux启动代码分析 LINUX , start_kernel , 启动代码 linux kernel 从入口到start_kernel 的代码分析.rar 104.59 KB, 下载次数: 31 , 下载积分: 资产 -2 信元, 下载支出 2 信元

    arm linux 从入口到start_kernel 代码详细分析.doc

    在 ARM Linux 系统启动过程中,从内核入口到`start_kernel`的流程涉及到多个关键...`start_kernel`是Linux内核的主要初始化函数,它负责调度器、设备驱动、文件系统等核心组件的初始化,标志着内核启动过程的正式开始。

    arm linux 从入口到start_kernel 代码分析 (7)

    最后,通过一个无条件跳转指令`b start_kernel`,程序控制权传递给`start_kernel`函数,标志着内核初始化的正式开始。 `start_kernel`是Linux内核的主入口点,它负责调用一系列的初始化函数来设置系统环境,如内存...

    linux 内存管理 start_kernel

    该文档描述了linux 内核内存管理部分的相关分析,从start_kernel入手,注重代码分析。

    arm linux 从入口到start_kernel 代码分析 (3)

    一旦 `__lookup_machine_type` 完成机器类型的查找,后续的 `start_kernel` 函数将启动更高级别的系统初始化,包括内核模块的加载、初始化子系统、调度器的启动等。 总结起来,`arm linux` 从入口到 `start_kernel`...

    start_kernel.xmind

    start_kernel流程图 linux2.6 内核支持两种格式的 initrd,一种是 image-initrd,其核心文件就是 /linuxrc。另外一种是cpio-initrd,使用 cpio 工具生成,其核心文件不再是 /linuxrc,而是 /init。尽管 linux2.6...

    arm linux 从入口到start_kernel 代码分析 (6)

    《ARM Linux 从入口到start_kernel的代码分析(六):开启MMU详解》 在Linux内核启动过程中,开启MMU(Memory Management Unit)是一个至关重要的步骤,它负责将虚拟地址转换为物理地址,从而实现内存管理和保护。...

    arm linux 从入口到start_kernel 代码分析(5)

    在ARM Linux系统启动过程中,从入口到`start_kernel`的代码分析是一个关键环节,这涉及到内核初始化的核心步骤。本篇分析主要关注在MMU(内存管理单元)启用之前的准备工作,特别是调用平台特定的`__cpu_flush`函数...

    boot memory内核源代码情景分析

    第一部分从Linux系统程序入口地址_start开始直到调用start_kernel函数;第二部分从start_kernel函数开始直到使用kernel_thread函数创建init进程。 本文件的代码分析将从第二次引导,即start_kernel()开始,直到mem_...

    start_kernel()代码分析

    分析明确内核中断向量表的初始化; 分析明确内核的根文件系统挂载过程; 分析明确内核页表的建立过程; 分析明确init进程创建和执行过程;

Global site tag (gtag.js) - Google Analytics