内核分析

linux内核组成部分

linux内核主要由进程调度(SCHED)、内存管理(MM)、虚拟文件系统(VFS)、网络接口(NET)、进程间通信(IPC)5个子系统组成。

5个子系统依赖关系如下:

进程调度与内存管理之间的关系:这两个子系统相互依赖,在多程序环境下,程序要运行,则必须创建进程,而创建进程第一件事情就是将程序和数据装入内存。

进程间通信与内存管理的关系:进程间通信子系统要依赖内存管理支持共享内存通信机制,这种机制允许两个进程除了拥有自己的私有空间外,还可以存取共同的内存区域。

虚拟文件系统与网络接口之间的关系:虚拟文件系统利用网络接口支持网络文件系统(NFS),也利用内存管理支持RAMDISK设备。

内存管理与虚拟文件系统之间的关系:内存管理利用虚拟文件系统支持交换,交换进程定期由调度程序调度,这也是内存管理依赖于进程调度的原因。

详情参考

Makefile.txt文件翻译

内核Makefile分类

在Linux内核里,每个子目录都有一个makefile,它被称作Kbuilt-makefile,它将当前目录的文件编译成built-in.o、以及库文件、模块文件。然后顶层Makefile里指定这些built-in.o的路径,将它们连接在一起。

将makefile分为 5部分,Kernel Makefile、ARCH Makefile、KBuild Makefile、.config文件以及scripts/Makefile.

①kernel Makefile(Top Makefile)位于Linux内核源代码的顶层目录,主要编译Linux Kernel目标文件(vmlinux)和模块(module)路径。它根据.config文件决定了内核根目录下的那些文件、子目录被编译进内核,是所有文件核心,从总体控制内核编译、链接。

②ARCH Makefile文件,是系统对应平台的Makefile。Kernel Top Makefile 会包含这个文件来指定平台相关信息。ARCH Makefile同样根据.config文件,决定了ARCH/$(ARCH) 目录下 那些文件、子目录被编译进内核 只有平台开发人员会关心这个文件。

③Kbuild Makefile,从Linux 内核2.6 开始,Linux 内核的编译采用Kbuild 系统 ,这同过去的编译系统有很大的不同,Kbuild 系统使用Kbuild Makefile 来编译内核或模块。当Kernel Makefile 被解析完成后,Kbuild 会读取相关的Kbuild Makefile 进行内核或模块的编译。Kbuild Makefile 有特定的语法指定哪些编译进内核中、哪些编译为模块、及对应的源文件是什么等。内核及驱动开发人员需要编写这个Kbuild Makefile 文件。
④**scripts/Makefile.* ,Makefile共用的通用规则、脚本等

⑤**.config**,来自配置过程,生成 auto.conf 以及 autoconf.h,被顶层Makefile所包含

5大文件作用

首先是顶层Makefile决定内核根目录下的哪些子目录将被编进内核。

arch/$(ARCH)/Makefile决定arch/$(ARCH)目录下哪些文件、哪些目录被编进内核。

各级子目录下的Makefile决定所在目录下的哪些文件将被编进内核,哪些被编写成模块(驱动模块),进入哪些子目录继续调用它们的Makefile。

顶层Makefile和arch/$(ARCH)/Makefile设置了可以影响所有文件的编译、连接选项:CFLAGS、AFLAGS、LDFLAGS、ARFLAFGS。

各级子目录下的Makefile中可以设置成能够影响当前目录下所有文件的编译 、连接选项:EXTRA_CFLAGS、EXTRA_AFLAGS、EXTRA_LDFLAGS、EXTRA_ARFLAGS,还可以设置影响某个文件的编译选项。

顶层Makefile按照一定的顺序组织文件,根据连接脚本arch/$(ARCH)/kernel/vmlinux.lds生成内核镜像文件vmlinux。

①、 vmlinux 是编译出来的最原始的内核文件,是未压缩的,比如正点原子提供的 Linux 源码编译出来的 vmlinux 差不多有 16MB,
②、 Image 是 Linux 内核镜像文件,但是 Image 仅包含可执行的二进制数据。 Image 就是使用 objcopy 取消掉 vmlinux 中的一些其他信息,比如符号表什么的。但是 Image 是没有压缩过的, Image 保存在 arch/arm/boot 目录下,其大小大概在 12MB 左右相比 vmlinux 的 16MB, Image 缩小到了 12MB。
③、 zImage 是经过 gzip 压缩后的 Image,经过压缩以后其大小大概在 6MB 左右

内核的配置

1、Makefile:分布在 Linux 内核源代码根目录及各层目录中,定义 Linux 内核的编译规则;
2、配置文件(config.in(2.4内核,2.6内核)):给用户提供配置选择的功能;
3、配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释)和配置用户界面

make menuconfig过程:

1、scripts文件夹存放的是跟make menuconfig配置界面的图形绘制相关的文件,我们作为使用者无需关心这个文件夹的内容
2、读取arch/arch/$ARCH/Kconfig以及各子目录下的Kcondig文件,生成配置条目。
$ARCH由linux内核根目录下的makefile文件决定
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-
Kconfig文件中为配置信息的宏定义,与我们在make menuconfig图形界面看到的信息一致。
例如:
config CPU_S3C2410_DMA
bool
depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442)
default y if CPU_S3C2410 || CPU_S3C2442
help
DMA device selection for S3C2410 and compatible CPUs
因此,Kconfig文件很重要的作用就是:定义配置宏、相关依赖关系、帮助信息
3、读取内核根目录下.config文件,生成配置选项:[*]编译进内核 [M]编译为模块 [ ]不编译
arch/arm/configs/文件夹下存放了一些配置模板
我们可以通过cp /arch/arm/configs/xx_defconfig .config来使用这些配置模板
通过图形界面变更配置选项会自动更新到.config文件中
make disclean 会删除.config
4、编译过程根据.config生成 Linux内核根目录下的 include/config/auto.conf文件
CONFIG_EEPROM_93CX6=m
CONFIG_DM9000=y
根目录Makefile以及子目录的Makefile根据auto.conf生成编译条件
obj-$(CONFIG_DM9000) += dm9000.o //obj-m += dm9000.o
5、编译过程根据.config生成Linux内核根目录下的 include/linux/autoconf.h文件
.config 或 auto.conf 中定义要编译为 m 模块的项,如:
CONFIG_DEBUG_NX_TEST=m
在 autoconf.h 中会被定义为:
#define CONFIG_DEBUG_NX_TEST_MODULE 1

​ .config或auto.conf 中定义为编译为 y 的选项,如:
​ CONFIG_DM9000= y
​ 在 autoconf.h 中会被定义为:
​ #define CONFIG_DM9000 1
​ autoconf.h中是.config或者auto.conf中配置信息的另一种体现形式,它是站在源码的角度,供源码使用的C语言宏定义。
6、总结
​ 我们在使用make menuconfig时,首先会确定架构arch,然后读取arch目录的Kconfig中的配置宏定义,生成编译条目,然后读取Linux内核根目录下的.config选项, 将.config中的配置信息显示在图形界面上[*] [M] or []。我们在图形界面中更改配置选项会自动保存到.config文件中。编译过程根据.config随后生成auto.conf文件,它决定了makefile中各个文件的编译类型,静态编译进内核、编译成模块、不编译;同时生成autoconf.h,它以C语言宏定义的形式表达了 各个文件是否被编译,源码中会判断某文件是否被编译进行不同的处理。

内核启动流程

linux启动前要求:

①、关闭 MMU。
②、关闭 D-cache。
③、 I-Cache 无所谓。
④、 r0=0。
⑤、 r1=machine nr(也就是机器 ID)。
⑥、 r2=atags 或者设备树(dtb)首地址。