一 简介
CJ机顶盒项目中,内核定制的主要工作是定制一个可以快速启动且稳定的linux内核,下面是此项目的实现文档。
内核版本:2.6.20
机器平台:x86(VIA C7 cpu)
系统版本:NeoShine 4( Build30e )
二 需求
Ata硬盘支持
via 网络适配器支持
acpi支持
ext3,vfat,ntfs文件系统支持
usb点击设备和存储设备支持
无initrd支持
声音设备支持
显示设备和高清格式视频播放支持
三 内容目录
简介
需求
内核配置项分析
可以关掉的部分(如果没有此类设备时):
必需部分
可选部分
编译过程
准备编译环境
配置内核
编译新内核
安装新内核
总结
附录
如何把驱动模块加入到内核源码树
Kconfig文件的作用
内核源码的Makefile
加源码到源码树:
参考资料
四 分析
2.6.20内核配置共分15大部分,在此根据项目需求粗略分析每部分的裁剪
Code maturity level options --->
此配置管理内核源码树中没有经过大量测试的非稳定的源码(包括一些驱动和系统功能等)是否加入当当前内核中,所以我们在此保守点选择no
General setup --->
通用设置部分:需要裁剪的主要是取消initrd支持,审计支持(auditing support)
Loadable module support --->
可加载模块配置:保持内核模块支持和自动载入模块支持(此项保持默认就可)
Process debugging support --->
进程调试支持:可以关闭此项
Block layer --->
块设备配置:如果没有对2TB以上的分区和单个文件的支持需求,可以取消此两项
Processor type and features --->
处理器相关配置:如歌没有多核cpu,关闭smp支持;根据自己的cpu类型,在processor famliy 中选择对应型号(有具体的cpu的优化,但将不能在比此配置低的cpu运行);
选择Timer frequency的值为1000MHz(使桌面系统有快速的相应)。
Power management options (ACPI, APM) --->
电源管理:目前的cpu和其他硬件设备都可以支持acpi规范,可以选中对他的支持,同时有电池和AC电源时,选中对他们的支持。
Bus options (PCI, PCMCIA, EISA, MCA, ISA) --->
总线配置:pci支持选中,pcmcia支持一般在笔记本有,没有就不选,isa总线,一般现在的硬件都已没有,所以一般不选
Executable file formats --->
此部分保持默认
Networking --->
网络配置:确保tcp/ip支持,可以考虑取消ipv6的支持,还有类似ip转发和高级包过滤等可以考虑取消(至少一般的机顶盒项目用不到)。
Device Drivers --->
设备驱动部分:此部分是内核中最大的一块,配置后果会直接影响到系统中硬件的工作情况。
可以关掉的部分(如果没有此类设备时)
Parallel port support 并口打印机
Multi-device support (RAID and LVM) 磁盘阵列
IEEE 1394 (FireWire) support 1394数码设备接口
Macintosh device drivers 苹果电脑设备支持
ISDN subsystem 综合业务数字网--一种老的联网技术
MMC/SD Card support 读卡器支持
LED devices LED设备支持
Virtualization 虚拟化支持
必需部分
在下面子类中选择自己键鼠,网络卡,和磁盘等设备对应的驱动(注意:如果没有此部分,可能会导致系统无法使用甚至无法启动)
Misc devices --->
ATA/ATAPI/MFM/RLL support ---> (并口硬盘时,驱动一般在此)
SCSI device support --->
Serial ATA (prod) and Parallel ATA (experimental) drivers (串口硬盘驱动一般在此)
可选部分
下面设备可以根据自己的情况选择:
USB support
Multimedia devices (此部分包括usb 摄像头的支持)
Sound (声音支持,一般选上alsa就好了,oss架构是较老的技术,alsa可以和它向下兼容)
另外
要确保选中block divice支持,除非你不使用硬盘等其他存储设备。
File systems --->
文件系统配置:在此机顶盒中仅保留ext3文件系统的支持,另外就是选上对vfat,ntfs的支持
其他需求可以自行选择,比如可能有对aufs的支持(一种可以合并多个目录为一个目录的特殊文件系统)
Kernel hacking --->
内核配置:如果需要测试内核启动时间,可以打开打印时间支持(Show timing information on printks),如果没有调试内核需求,则关闭内核调试支持(Kernel debugging)。
Security options --->
安全配置:关闭selinux支持
Cryptographic options --->
可以保持默认
Library routines --->
该部分实现对crc校验支持,保留默认
五 编译过程
准备编译环境
开始之前,首先确认下面软件包已经安装(编译ND4.0时,直接全部安装CD3可保证此条件)
* rpmdevtools
* yum-utils
1. 生成一个rpmbuild开发目录,使用下面命令可以建立,也可以手动建立目录树,ND发行版 kernel源码默认的安装目录在/usr/src/neoshine/下
使用下面命令建立:
#rpmdev-setuptree
也可手动在/usr/src/neoshine下建立如下结构的目录树(没有此步此操作在安装kernel源码时可能会报错):
|-- BUILD
|-- BUILDROOT
|-- RPMS
| |-- i386
| `-- i686
|-- SOURCES
|-- SPECS
`-- SRPMS
3. 安装内核源码包需要的依赖组件(在此可以跳过此步操作)
su -c 'yum-builddep kernel-.src.rpm'
4.安装内核源码到系统,默认目录在/usr/src/neoshine:
rpm -Uvh kernel-.src.rpm
配置内核
下面将介绍如何解开源码包,并修改,配置和重新打包源码
1. 解开源码包并打上所有的补丁到BUILD目录
cd ~/rpmbuild/SPECS
rpmbuild -bp --target=`uname -m` kernel.spec
kernel源码将在这里找到:
/usr/src/neoshine/rpmbuild/BUILD/kernel-
/linux-. directory
配置内核源码
1. 进入内核源码:
cd ~/rpmbuild/BUILD/kernel-2.6.$ver/linux-2.6.$ver.$arch/
2. 复制/boot/config*配置文件到源码目录下,此config文件也可以是已经配好或者其他地方备份的kernel配置文件:
cp /boot/config2.6- 2.6.$ver.$arch .config
3. 先检查kernel配置中新增的选项:
make oldconfig
4. 定制内核功能,关闭initrd支持选项,执行图形化内核配置工具:
make menuconfig
注:在generic setup选项下找到initial RAM system and RAM disk(initramfs and initrd) support 项,取消编译。同时确保跟文件系统对应的驱动和系统所在存储器对应的驱动都已经编译到内核(否则会无法启动系统).
5. 在.config文件第一行改为下面内容(注意:没有此行时,后面的编译会报错)
# i386
6. 拷贝.config到SOURCES/:
cp .config ../SOURCES/config-$arch
六 编译新内核
1. 下面开始准备编译新的内核包
打开SPEC/kernel.spec
vim SPEC/kernel.spec
改变下面行内容,可以定制自己的内核扩展名(如fc10之类):
%define buildid .<自己内核的小版本名>
下一步将生成一个新内核的rpm包,此过程需要编译内核源码包
* 使用下面命令生成新的内核源码包
rpmbuild -bb --with baseonly --without debuginfo --target=`uname -m` kernel.spec
参数说明:bb表示只编译二进制包,即不生成源码包,without debuginfo 表示没有调试信息,
target=`uname -r`表示生成对应当前平台的内核包
如果上面的命令成功执行完成,那么会在BUILD/i686目录下生成新的内核安装包
七 安装新内核
rpm -ivh kernel-$ver-$arch.rpm
此步操作会自动安装内核到boot目录下,安装对应内核模块到/lib/modules/目录下,并且生成新内核对应的grub引导菜单。
修改grub引导菜单为以下格式
title new kernel
kernel /boot/vmlinuz-$ver-$arch root=/dev/sdax(hdax)
注意,此处不要使用uuid指定跟文件系统(可能会无法挂载根分区而导致内核死机),也不要再加和显示相关的参数(内核不支持对应设置时,只会看到一个黑黑的屏幕)。
至此一个禁用initrd的新内核配置安装完毕!
总结
内核是一个十分庞大的源代码集合,从1991年linus创造出来并共享给全球的开源爱好者后,
在这快20年的发展中,它已经汇聚了无数人类智慧的结晶,我们可以从中汲取无限的“营养物质”。
在此,我仅有皮毛的了解,如有不对,不妥之处,希望指正。
附录
如果编译信内核时,需要把第三方的源码加入到当前内核源码树,可以参考下面的方法实现此步操作,
如何把驱动模块加入到内核源码树
内核源码树的每个目录下都有两个文件Kconfig和Makefile。
分布到各目录的Kconfig构成了一个分布式的内核配置数据库,每个Kconfig分别描述了所属目录源文件相关的内核配置菜单。在内核配置make menuconfig(或xconfig等)时,从Kconfig中读出菜单,用户选择后保存到.config的内核配置文件中。在内核编译时,主Makefile调用这个.config,就知道了用户的选择。
附一 内核源码中Kconfig文件的作用
上面的内容说明了,Kconfig就是对应着内核的配置菜单。如果要想添加新的驱动到内核的源码中,可以修改Kconfig,这样就可以选择这个驱动,如果想使这个驱动被编译,要修改Makefile
so添加新的驱动时需要修改的文件有两种(注意不只是两个)
*Kconfig
*Makefile
要想知道怎么修改这两种文件,就要知道两种文件的语法结构
Kconfig
每个菜单都有一个关键字标识,最常见的就是config
语法:
config
symbol是一个新的标记的菜单项,options是在这个新的菜单项下的属性和选项
其中options部分有:
1、类型定义:
每个config菜单项都要有类型定义,bool布尔类型、 tristate三态:内建、模块、移除 string字符串、 hex十六进制、 integer整型
例如config HELLO_MODULE
bool "hello test module"
bool类型的只能选中或不选中,tristate类型的菜单项多了编译成内核模块的选项,如果选择编译成内核模块,则会在.config中生成一个CONFIG_HELLO_MODULE=m的配置,如果选择内建,就是直接编译成内核影响,就会在.config中生成一个CONFIG_HELLO_MODULE=y的配置.
2、依赖型定义depends on或requires
指此菜单的出现与否依赖于另一个定义
config HELLO_MODULE
bool "hello test module"
depends on ARCH_PXA
这个例子表明HELLO_MODULE这个菜单项只对XScale处理器有效。
3、帮助性定义
只是增加帮助用关键字help或者---help---
内核的Makefile
在linux2.6.x/Documentation/kbuild目录下有详细的介绍有关kernel makefile的知识。
内核的Makefile分为5个组成部分:
Makefile 最顶层的Makefile
.config 内核的当前配置文件,编译时成为定层Makefile的一部分
arch/$(ARCH)/Makefile 与体系结构相关的Makefile
s/ Makefile.* 一些Makefile的通用规则
kbuild Makefile 各级目录下的大概约500个文件,编译时根据上层Makefile传下来的宏定义和其他编译规则,将源代码编译成模块或者编入内核
顶层的Makefile文件读取 .config文件的内容,并总体上负责build内核和模块。Arch Makefile则提供补充体系结构相关的信息。 s目录下的Makefile文件包含了所有用来根据kbuild Makefile 构建内核所需的定义和规则。
(其中.config的内容是在make menuconfig的时候,通过Kconfig文件配置的结果。
附二 加源码到源码树
假设想把自己写的一个flash的驱动程序加载到工程中,而且能够通过menuconfig配置内核时选择该驱动该怎么办呢?可以分三步:
第一:将你写的flashtest.c 文件添加到/driver/mtd/maps/ 目录下。
第二:修改/driver/mtd/maps目录下的kconfig文件:
config MTD_flashtest
tristate “ap71 flash"
这样当make menuconfig时 ,将会出现 ap71 flash选项。
第三:修改该目录下makefile文件。
添加如下内容:obj-$(CONFIG_MTD_flashtest) += flashtest.o
这样,当你运行make menucofnig时,你将发现ap71 flash选项,如果你选择了此项。该选择就会保存在.config文件中。当你编译内核时,将会读取.config文件,当发现ap71 flash 选项为yes 时,系统在调用/driver/mtd/maps/下的makefile 时,将会把 flashtest.o 加入到内核中。即可达到你的目的。
参考资料
如何定制本地内核