嵌入式 Linux开发Kernel移植(二)——kernel内核配置和编译
本文选择linux 2.6.35.7版本kernel进行实践。
一、linux kernel源码目录分析
Kbuild,Kernel Build,管理内核编译的文件
Makefile,kernel工程的Makefile。
arch,体系架构,arch目录下的子目录存放的是不同种类的架构
block,块设备,一般是存储设备,存放的块设备管理的相关代码
crypto,加密相关,存放加密算法实现代码
Documentation,说明文档
drivers,设备驱动模块,存放各种设备类型驱动模块
firmware,固件
fs,文件系统,子目录存放各种文件系统
include,头文件,子目录存放通用的各种模块的头文件
init,kernel启动时初始化的代码
ipc,进程间通信机制的代码
kernel,kernel本身的代码
lib,通用的库函数
mm,内存管理
net,网络协议栈,子目录存放各种网络协议
scripts,辅助对kernel进行配置编译的脚本
security,kernel安全机制相关的代码
sound,音频相关的代码
tools,工具相关
usr,kernel启动相关
virt,虚拟机相关
二、kernel的配置体系
Linux kernel的配置体系由三部分构成,分别是:
Makefile:分布在 Linux 内核源代码根目录及各层目录中,定义Linux kernel的编译规则,依据.config中定义的CONFIG_xxxx=xxxxx确定xxx以何种方式编译进kernel。
Kconfig:配置选项的文件,各个子目录下的Kconfig定义了子目录的功能模块的配置选项。
配置工具:配置命令解释器(对配置脚本中使用的配置命令进行解释)和配置用户界面(提供基于字符界面、基于Ncurses 图形界面以及基于Xwindows图形界面的用户配置界面,各自对应于make config、make menuconfig和make xconfig)。通过对配置工具选项进行配置后生成配置文件.config,.config文件决定Kconfig中的配置项是否编译进入kernel。
1、工程Makefile的修改
ARCH?= arm
CROSS_COMPILE?= arm-linux-
2、配置文件.config文件的生成
A、默认配置文件的加载:
make xxx_defconfig:
HOSTCC scripts/basic/fixdep
HOSTCC scripts/basic/docproc
HOSTCC scripts/basic/hash
HOSTCC scripts/kconfig/conf.o
HOSTCC scripts/kconfig/kxgettext.o
SHIPPED scripts/kconfig/zconf.tab.c
SHIPPED scripts/kconfig/lex.zconf.c
SHIPPED scripts/kconfig/zconf.hash.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
arch\arm\configs目录下的相应开发板的xxxx_defconfig文件
3、配置工具的使用
A、配置工具的使用方式
make config(基于文本的最为传统的配置界面,不推荐使用)
make menuconfig (基于文本菜单的配置界面,需要安装ncurse)
make xconfig (基于QT的图形配置界面,要求QT被安装)
make gconfig (基于GTK+的图形配置界面,要求GTK+被安装)
make oldconfig (以现有的.config文件为基础来更新当前配置)
make silentoldconfig (与oldconfig相同,但不输出任何信息)
make randconfig (创建新的配置文件,其中包括所有配置选项的随机答案)
make defconfig (创建新的配置文件,其中包括所有配置选项的默认答案)
make allmodconfig (创建新的配置文件,尽可能地将选项配置成默认模块)
make allyesconfig (创建新的配置文件,将所有选项配置成yes)
make allnoconfig (创建新的配置文件,将所有选项配置成no,即最小化的配置)
以上make xxconfig使用方式中make menuconfig最为常用,使用说明如下:
make menuconfig:
scripts文件夹存放的是跟make menuconfig配置界面的图形绘制相关的文件,执行make menuconfig命令出时:
HOSTCC scripts/kconfig/lxdialog/checklist.o
HOSTCC scripts/kconfig/lxdialog/inputbox.o
HOSTCC scripts/kconfig/lxdialog/menubox.o
HOSTCC scripts/kconfig/lxdialog/textbox.o
HOSTCC scripts/kconfig/lxdialog/util.o
HOSTCC scripts/kconfig/lxdialog/yesno.o
HOSTCC scripts/kconfig/mconf.o
HOSTLD scripts/kconfig/mconf
scripts/kconfig/mconf arch/arm/Kconfig
mconf表示是menuconfig的解析程序,mconf解析处理arch/arm/Kconfig文件,最终mconf会把用户的选择保存到Linux源码树顶层目录的.config文件中。
xxconfig文件实际是开发板厂商移植的kernel的推荐配置,实际开发中可以根据开发板厂商提供的kernel的xxconfig结合产品需求进行剪裁配置,得到需要的kernel配置,即通过make menuconfig进行配置裁剪。
arch\arm\Kconfig用于生成整个配置界面选项(Kconfig是整个linux配置机制的核心),是配置界面的主菜单界面,经过设置、修改的选项的选择结果保存在根目录下的.config文件中。退出时,menuconfig会检查是否修改了配置选项,如果修改了配置选项会提示保存,否则会直接退出。保存时会将修改过的配置选项写入.config文件中。
B、Kconfig文件配置项的格式
menu/endmenu:可以将一部分配置选项分类为一个目录menu,menu与endmenu是一组指令,必须同时使用。menu和endmenu中包含的部分就是子目录中的配置项。
menuconfig:menuconfig是可以配置的目录menu,即可以修改menu选中或排除
config:config是构建Kconfig的基本单元,config的类型有5种,分别是bool(y/n),tristate(y/m/n),string(字符串),hex(十六进 制),integer(整数)。
tristate三种选项配置
bool两种选项配置
depends on/requires依赖于的配置项,如果依赖的配置选项没有选中,则当前选项也无法选中
---help---help信息
select反向依赖配置选项,如果当前选项选中,则也会自动选中select后的选项。
default选项默认值,可以有多个,但只有第一个定义的值有效
range:范围,用于hex和integer,range A B表示当前值不小于A,不大于B
comment:注释
choice/endchoice:多选一
source:将子目录的Kconfig引入到当前位置
C、Kconfig文件添加功能选项实例
menuconfig:
menuconfig NETDEVICES
default y if UML
depends on NET
bool "Network device support"
---help---
You can say N here if you don't intend to connect your Linux box to
any other computer at all.
menuconfig NETDEVICES表明菜单目录是可以修改配置的,并且菜单录有子目录,菜单选项在.config文件的选项为CONFIG_NETDEVICES,bool "Network device support"表明菜单目录的提示符是"Network device support"。depends on NET表名菜单目录依赖于NET选项。
菜单目录的子目录选项需要放在以下定义的范围内:
if NETDEVICES
......
子目录菜单选项
endif # NETDEVICES
menu:
if WIMAX
menu "WiMAX Wireless Broadband devices"
source "drivers/net/wimax/i2400m/Kconfig"
endmenu
endif
menu "WiMAX Wireless Broadband devices”表明菜单目录不具备修改属性,但具有子目录菜单,菜单提示符为"WiMAX Wireless Broadband devices”。子菜单的Kconfig来源source "drivers/net/wimax/i2400m/Kconfig"。if WIMAX表明菜单依赖于WIMAX选项。
D、make menuconfig使用
按Enter键进入子目录
按Y键选中当前选项
按N键排除当前选项
按M键将当前模块进行模块化编译
按ESC ESC将退出当前选项返回上一层目录
按?将显示当前选项的help信息
方向箭头可以将光标向上下左右移动
[*]:选中
[ ]:排除
< >:可以模块化编译
make menuconfig对目录树下Kconfig文件选项配置后选项的结果保存在.config文件中,文件内容如下:
CONFIG_ARM=y
CONFIG_HAVE_PWM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_ARCH_USES_GETTIMEOFFSET=y
.config文件中的选项的值将与目录树下Makefile文件结合,确保配置选中的功能模块选项会被编译,未被选中的不会被编译,以及功能模块是被编译进内核还是编译成模块.ko文件。
三、配置项添加实例
给内核增加一个功能,并且通过make menuconfig控制其生成过程,流程如下:
A、修改对应目录下的Kconfig文件,按照Kconfig语法增加对应的选项;
B、执行make menuconfig选择编译进内核或者不编译进内核,或者编译为模块,.config文件和autoconf.h文件会自动生成
C、修改对应目录下的Makefile文件完成编译选项的添加
D、编译内核make -j4
在drivers\net目录下添加TFTP的功能模块,流程如下:
1、修改drivers\net目录下的Kconfig文件,在网络设备支持代码块NETDEVICES内部添加TFTP的配置选项:
config TFTP
tristate "TFTP support"
depends on NET_CLS_ACT
---help---
This is an TFTP.
2、执行make menuconfig,将TFTP功能编译为模块
查看.config文件可知,CONFIG_TFTP定义在网络设备支持选项CONFIG_NETDEVICES后,以模块编译。
CONFIG_NETDEVICES=y
CONFIG_TFTP=m
3、修改drivers\net目录下Makefile文件
添加编译目标
obj-$(CONFIG_TFTP) +=tftp.o
4、编译kernel
make -j4
四、kernel编译
Kernel的配置编译过程如下:
make xxx_defconfig//生成.config文件
make memuconfig//修改配置选项
make -j2//编译