- 论坛徽章:
- 0
|
第四章
内核初探
一、关于版本
1. Linux的版本
什么是主线版本:主线版本是指我们在kernel.ORG上下载下来的版本
2. 版本号组成:主版本号+次版本号+序号
3. 实验版与产品版:在2.6版本以前,实验板的此版本号为奇数,成熟板的为偶数,2.6版本以后这个规则不再使用。
4. 从那里可以知道内核的版本号?
在顶层目录下的MAKEFILE中就能找到,如下所示:
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 14
EXTRAVERSION = .1
NAME=Affluent Albatross
下面这个宏用来生成版本号
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)$(LOCALVERSION)
在INCLUDE/LINUX/VERSION.H下也有相应的宏:
#define UTS_RELEASE "2.6.14.1"
#define LINUX_VERSION_CODE 132622
#define KERNEL_VERSION(a,b,c) (((a)
另外我们可以从/PROC/VERSION中检测到我们内核的版本号,执行如下命令
Cat /proc/version
还需要注意的一点是EXTRAVERSION 项可以让用户自定义来区分在开发过程中由于对内核某些特性更新或改进的特征
二、获取内核
1、主线内核版本我们在官网上可以获得。
2、对于一些特定硬件平台的内核,我们由专门的网站下载特定平台的内核,这些特定平台的内核更新速度比主线内核要快,尽管特定平台的开发者尽量保持与主线内核同步更新,但还是有滞后的。(MIPS的内核官网为www.linux-mips.org),相应的也有arm(
www.linux-arm.org
)的官网,里面的内容很不错,可以多浏览一下。
三、编译内核
对于LINUX这个盘然大物来说,走读代码是见很困难的事情,设置定位内核第一行执行那的代码也是件不容易的事情。下面我们通过理解内核镜像文件的结构来理解内核的各个部件。
内核编译后生成一下三个文件:
System.MAP:用于内核调试,这个文件中包括许多可以读懂的内核符号以及相应的地址
c0004000 A swapper_pg_dir
c0008000 T __init_begin
c0008000 T _sinittext
c0008000 T stext
c0008000 T _stext
c000802c t __switch_data
c0008050 t __mmap_switched
c0008094 t __enable_mmu
VMLINUX:这是一个与平台相关的ELF可执行文件,如果内核编译时把符号调试信息编译进去了,也会包含调试信息。尽管这是一个可执行文件,但不能用来直接启动。
下面的信息揭露了这个文件的生成过程
其中head.s文件是个平台相关的文件,执行了一个内核最底层的初始化,内核的第一行代码就可以在这个文件中找到。
Init_task.O初始化内核所需要的线程和任务结构。
需要注意的是,VMLINUX是一个压缩的镜像文件,bootloader需要对其进行加压。我们在后面的章节中会详细讲解这个过程。
四、内核编译系统
对于一个有着600万行代码的内核来说,编译起来是件复杂的事情。整个内核中的MAKEFILE文件有800多个,这其中包括了编译时的说明性文档,不过当我们了解了编译系统的结构和构架,这也就不是一件难的事情了。下面就我们开始揭开的Kbuild系统的神秘面纱。
1、.CONFIG文件
. .CONFIG文件在顶层目录下,是个隐藏文件,他指引这整个内核的编译过程,需要特别注意的是,如果执行make mrproper命令,.CONFIG文件就会在没有任何提示的情况下被删除,所以当你用这个命令的时候,要特别下心,否则你辛辛苦苦修改的.config文件就会不翼而飞。因此最后是备份好这个文件。
2. 下面是网络设备支持的片段
CONFIG_NETDEVICES=y表示网络设备会被编译到VMLINUX(内核镜像容器)中去,如果选项是=m则会作为模块动态加载,不会被直接静态编译到内核中。
# Network device support
#
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
#
# PHY device support
#
# CONFIG_PHYLIB is not set
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
CONFIG_ARM_CS8900=y
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
#
# Ethernet (1000 Mbit)
#
#
# Ethernet (10000 Mbit)
#
3 配置方法
对于目前庞大的内核,早期内核的命令行式的编译方式显然不再实用。目前内核配置方式大概有10种,当然包含很多图形界面,通过make help命令显示如下:
config
menuconfig
gconfig
。。。。
需要说明的一点是,配置文件最终是通过一个叫做AUTOCONF.H的头文件传递给GCC的。你可以比较一下.CONFIG文件与AUTOCONF.H,中间很多条目都是一一对应的。
* Network device support
*/
#define CONFIG_NETDEVICES 1
#undef CONFIG_DUMMY
#undef CONFIG_BONDING
#undef CONFIG_EQUALIZER
#undef CONFIG_TUN
/*
* PHY device support
*/
#undef CONFIG_PHYLIB
/*
* Ethernet (10 or 100Mbit)
*/
#define CONFIG_NET_ETHERNET 1
#undef CONFIG_MII
#define CONFIG_ARM_CS8900 1
#undef CONFIG_SMC91X
#undef CONFIG_DM9000
4、Makefile 目标
每个具体的板子都需要相应的.Config文件,我们的建议是更具你的板子的体系结构类型在相应的目录下找到一个和自己目标板最匹配的默认配置文件,比方说如果你的目标板是S3C2410,则你可以将/ARCH/ARM/CONFIGS/下的s3c2410_defconfig拷贝下来改名后作为.config文件。
接下来需要考虑的是我们需要生成什么样的最终的目标文件,对于大多数系统来说,zImage文件是比较通用的压缩型的内核镜像文件。bZimage则只对于X86结构的cpu才有用。当然我们执行MAKE命令后zImage是一个默认的生成项目。
5、KCONFIG
执行完make gconfig后,我们会发现如下的配置目录,这些目录是怎么生成的呢,这就涉及到我们的KCONFIG文件了,在我们的内核包中大概有300多个这样的konfig文件,这些文件共同作用,最后生成了我们的配置菜单。
配置工具是从那里开始读kconfig文件呢,是从对应体系结构下的kconfig文件开始读,在/ARCH/ARM下,kconfig的内容如下
config ARCH_OMAP
bool "TI OMAP"
config ARCH_VERSATILE
bool "Versatile"
select ARM_AMBA
select ICST307
help
This enables support for ARM Ltd Versatile board.
config ARCH_IMX
bool "IMX"
config ARCH_H720X
bool "Hynix-HMS720x-based"
help
This enables support for systems based on the Hynix HMS720x
config ARCH_AAEC2000
bool "Agilent AAEC-2000 based"
help
This enables support for systems based on the Agilent AAEC-2000
endchoice
source "arch/arm/mach-clps711x/Kconfig"
source "arch/arm/mach-epxa10db/Kconfig"
source "arch/arm/mach-footbridge/Kconfig"
我们只筛选了一小部分,其中最关键的是source命令,他又包含了下一个目录下的KCONFIG,而每个KCONFIG对应一个子菜单项以及菜单中的选项,就是通过这种嵌套关系,最后生成了我们的配置菜单。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/69999/showart_1871914.html |
|