【原创】
精简Linux内核编译的简单方法
关于Linux内核的编译
采用先make defconfig、make menuconfig再make localmodconfig,并将后2者反复应用的过程。最后能达到比较简单的过程。基本上采取了做加法(将硬件驱动或模块依次加上,逐步改进)的思路。
简述如下:
1、下载源代码并建立编译工作目录和编译目标目录
简单点,按照源码中的README文件中所述完成:
编译工作目录:/usr/src/linux-2/6.34.1
编译目标目录:/home/abc/build/kernel 这里/home/abc即主文件夹
将下载的源码放到/usr/src下解压,则源码所在工作目录是/usr/src/linux-2.6.34.1
2、编译配置(重要工作)
可以有3种比较简单的方式对要编译进内核核心或模块的源代码进行配置。难易程度不一(需要投注的精力和时间不一样,编译生成的initrd.img-2.6.34.1、vmlinuz-2.6.34.1和System.map-2.6.34.1
这3个主要文件的大小也不一样)。采用何种方式也可以根据需要选择如下3种方式之一对内核进行编译前的配置。
目标:建立并得到“/home/abc/build/kernel”目录下的“.config”文件。
(1)最简单的方式:
将/boot下的配置文件拷贝过来使用,作为编译目标目录下的.config文件。这样对内核没有精简。
cp /boot/config-2.6.32-21-generic ~/build/kernel/.config
这样产生的initrd.img-2.6.34.1大概达到17M左右。不知Ubuntu采用这个配置文件怎样做到了将近8M。
(2)中等难度方式:在拷贝配置文件的基础上,使用make localmodconfig命令自动精简
从linux-2.6.32开始可以使用make localmodconfig自动精简内核了。命令如下:
cp /boot/config-2.6.32-21-generic ~/build/kernel/.config
sudo make O=/home/abc/build/kernel localmodconfig
一般说法:在运行第二条命令前,将系统的各种硬件都用一遍,以便你的系统中的模块均被调用了一次,使用“make localmodconfig”命令时,才能将你的系统将调用的模块包含进来。比方说:摄像头、U盘、光驱、SD卡等。
如果忘了,没关系,先将上述硬件依次用一遍,再运行第二条命令一次(呵呵,重新精简,不确定的话,就将上述2条命令重新执行一遍)。
哦,有点忘了,在第二条命令之前是否要先从.config文件中去掉一项,再使用make localmodconfig命令自动精简配置文件。如果在运行make localmodconfig命令后需要回答一些问题,而不是系统自动完成,那就按下Ctrl+c中断当前配置工作,再按照如下命令序列完成配置:
(a)拷贝配置文件
cp /boot/config-2.6.32-21-generic ~/build/kernel/.config
(b)去掉“Prompt for development and/or incomplete code/drivers”项
sudo make O=/home/abc/build/kernel menuconfig
进入图形界面后,选择倒数第二项(Load an Alternate Configuration File)回车,弹出窗口中提示输入欲调入的配置文件名。这里默认是~/build/kernel/.config文件,无须输入任何字符,按回车即可。
使用光标键上移到“Linux Kernel Configuration”窗口中的第一项(General Setup--->)”,按下回车,选择General setup窗口下第一项(Prompt for development and/or incomplete code/drivers),按下“N”字符键去掉这一项(将其前*去掉)。
用向右光标键选择选项,按回车键退出当前窗口;再按向右光标键选择选项,按回车键退出当前窗口;在选择是否保存时选择“Yes”。
(c)使用“make localmodconfig”命令自动精简内核
sudo make O=/home/abc/build/kernel localmodconfig
因为添加了第二个步骤(b),这时应该没什么选择了。
使用这样配置产生的.config进行编译比配置方式(1)要精简许多,但是内核相关的3个文件还是较大。
(3)最难(相对繁复)方式:
先make defconfig、make menuconfig再make localmodconfig,并将后2者反复应用的过程。最后能达到比较简单的过程。
这个过程较繁,但可望得到较简的内核。很难达到最简(除非对自己系统的硬件情况非常熟悉,并勇于实践,我们购买机器后,相对长时间内不会更换或升级硬件,所以这样的花费时间精力还是值得的),只有更简。闲话少说,上命令:
(a)建立默认的.config文件。
sudo make O=/home/abc/build/kernel defconfig
本命令在文件夹“/home/abc/build/kernel”下建立一个“.config”文件。
按照i386建立,据说是linus的配置。呵呵,还是需要对它进行增删的。以 config-2.6.32-21-generic为基础进行增删工作也可得到.config文件,但删的工作太多,容易删除不该删除的选项(再恢复就很难了,记不住也很难确定哪些该恢复)。以“make defconfig”命令建立的.config为基础增删就相对简单多了。
(b)去掉“Prompt for development and/or incomplete code/drivers”项
操作同2(2)(b)。
一般说法:在运行第二条命令前,将系统的各种硬件都用一遍,以便你的系统中的模块均被调用了一次,使用“make localmodconfig”命令时,才能将你的系统将调用的模块包含进来。比方说:摄像头、U盘、光驱、SD卡等。
如果忘了,没关系,先将上述硬件依次用一遍,再运行第二条命令一次(呵呵,重新精简,不确定的话,就将上述2条命令重新执行一遍)。
(c)使用“make localmodconfig”命令自动精简内核
sudo make O=/home/abc/build/kernel localmodconfig
一般说法:在运行第二条命令前,将系统的各种硬件都用一遍,以便你的系统中的模块均被调用了一次,使用“make localmodconfig”命令时,才能将你的系统将调用的模块包含进来。比方说:摄像头、U盘、光驱、SD卡等。
如果忘了,没关系,先将上述硬件依次用一遍,再运行第二条命令一次(呵呵,重新精简,不确定的话,就将上述2条命令重新执行一遍)。
(d)编辑“~/build/kernel/.config”文件,添加缺失模块
在上面(c)执行命令时,肯定会出现一些类似如下内容的信息:
module lp did not have configs CONFIG_PRINTER
module vgastate did not have configs CONFIG_VGASTATE
先将它们复制粘贴到文本文件中,呵呵,然后寻找“~/build/kernel/.config”文件中对应项,例如“CONFIG_VGASTATE”,可能“~/build/kernel/.config”文件中对应的信息为:
# CONFIG_VGASTATE is not set
将它改为:
CONFIG_VGASTATE=m
表示将这个模块包含进来。依次处理,如果找不到,没关系,先放在那儿。将上述信息中对应项都改完后保存,退出。
(e)再次运行“make localmodconfig”命令,将(d)步骤的修改带来的变化包含进内核
sudo make O=/home/abc/build/kernel localmodconfig
这时系统会有一些提问。别嫌麻烦,仔细回答(如果嫌麻烦,可以全部回答m,没“m”选项时,就回答“y”。毕竟无法一次就做到非常精简---没有最简)。
这正是本文的精彩之处,多次重用“gedit”和“make localmodconfig”命令,当然,还有后面再次使用的“make menuconfig”命令。
(f)将(e)步骤再次出现(d)中显示的未包含模块添加进来
如果(e)步骤中再次出现(d)中没有包含某些模块的选项,不要气馁。在编辑“~/build/kernel/.config”文件时,将相应项改为“=y”而不是“=m”。然后回到步骤(e),直到在没有模块没有包含进来的信息,或者你已经无法再减少这些信息。
我这样做到最后,还是有如下信息:
ricoh_mmc config not found!!
(g)使用“make menuconfig”命令对上面得到的“~/build/kernel/.config”文件中的选项进行增删
使用现在的.config文件进行编译,无法得到可正常运行的内核。需要注意的问题如下:
(I)Device Drivers->Generic Driver Options--->下的2项必须选择为“y”:
Matain a devtmpfs filesystem to mount at /dev
Automount devtmpfs at /dev, after the kernel mounted the rootfs
否则,出现“Can not mount /dev”的错误。
(II)File systems->FUSE (Filesystem in Userspace) support必须选择为“y”,否则,无法读取光驱和Windows下的分区和盘。点击Windows下的盘符时,出现如下提示信息:
FATAL: Module fuse not found.
fuse: device not found, try 'modprobe fuse' first
(III)某些经验文档可能说了如下选项应该去掉,千万不要相信
Enable the block layer->support for large (2TB+) block devices and files (一定要选y,否则无法读入启动文件)
这反映了“尽信书不如无书”这句话的正确性。如果不信,实践可检验。如果此时到步骤3开始编译,得到的内核文件已经能够运行。如果还存在问题,就需要到步骤6了解有关你的机器硬件的相关信息后,再使用“make menuconfig”命令对.config文件进行增删修改,再编译安装内核。
我的机器这样处理之后,还无法使用摄像头、访问SD卡。除此之外,如访问键盘鼠标的使用、网络、声音、显示器、U盘、Windows下的盘的访问等操作已经没有问题。
3、编译内核
编译内核非常简单:
sudo make O=/home/abc/build/kernel
如果是双核,想要加快编译速度,还可做相关设置。
4、安装内核
sudo make O=/home/abc/build/kernel modules_install install
这个操作将编译的内核安装到/boot下。在Ubuntu 10.04下,会在/boot目录下产生如下文件:
config-2.6.34.1
System.map-2.6.34.1
vmlinuz-2.6.34.1
还会在/lib/modules目录下产生一个新的目录“2.6.34.1”以及其下的若干子文件夹和文件。
但是,没有启动内核还需要的一个文件:
initrd.img-2.6.34.1
“initrd.img-2.6.34.1”文件通过“mkinitramfs”命令产生:
sudo mkinitramfs -o /boot/initrd.img-2.6.34.1 /lib/modules/ 2.6.34.1
5、修改/boot/grub/grub.cfg文件,以便启动编译好的新内核
此时你一定急于检验编译好的内核是否能够正常启动和工作,且慢,先修改启动项:
sudo gedit /boot/grub/grub.cfg
将“### BEGIN /etc/grub.d/10_linux ###”下的如下信息复制并粘贴一份,然后将粘贴信息中的“2.6.32-21-generic”全部改为“2.6.34.1”即可(不要不好意思,复制粘贴就足够了)。
menuentry 'Ubuntu, with Linux 2.6.32-21-generic' --class ubuntu --class gnu-linux --class gnu --class os {
recordfail
insmod ext2
set root='(hd0,7)'
search --no-floppy --fs-uuid --set 4b836918-3471-4fa7-85f6-79bee5970506
linux /boot/vmlinuz-2.6.32-21-generic root=UUID=4b836918-3471-4fa7-85f6-79bee5970506 ro quiet splash
initrd /boot/initrd.img-2.6.32-21-generic
}
重启机器,回车,用你刚才编译好的内核启动机器了。如果还有问题,你需要看步骤6、7。
6、硬件信息的搜集
如果想充分调动硬件并将内核精简到自己比较满意的程度,还是有必要了解自己机器的硬件信息的。
用于了解硬件信息的命令:
lshw 显示你的硬件以及所需的模块
dmidecode 查看硬件信息,包括bios、cpu、内存等信息
dmesg 查看硬件信息
lspci -v lspci (比cat /proc/pci更直观)
/proc文件夹下的若干文件:
cat /proc/cpuinfo 查看CPU信息
cat /proc/meminfo 查看内存信息
cat /proc/bus/input/devices 查看键盘和鼠标
cat /proc/pci 查看板卡信息
cat /proc/bus/usb/devices 查看USB设备
cat /proc/interrupts 查看各设备的中断请求(IRQ)
uname -a 查看系统体系结构
例子: lspci |grep Ethernet 查看网卡型号
dmesg | more
dmidecode | grep -i 'serial number'
dmidecode -t processor
7、再次精简内核
按照某些经验文档,对 linux-2.6.34.1.tar.bz2 内核源文件还可如下配置,可能将来的版本应该做一些变化。
(1')General setup->kernel compression mode改为bzip2
(2')如果是笔记本,将General setup->kernel log buffer size改为15
(3')去掉General setup->Control group support (按下n)
(4')去掉Processor type and features->Enable MPS table
(5')去掉Processor type and features->Support for extended (non-pc) x86 platforms
(6')将Processor type and features->Processor family改为自己的处理器类型(双核均可选择core 2/newer xeon)
(7')如果做了(6')的操作,那么去掉Processor type and features->Generic x86 support
(8')将Processor type and features->Maximum number of CPUs改为4(双核改为4,单核改为2)
(9')去掉Processor type and features->SMT (Hyperthreading) scheduler support
(10')如果是笔记本,将Processor type and features->Preemption model改为“Preemptible kernel (Low-Latency Desktop)”
(11')去掉Processor type and features->AMD MCE features
(12')去掉Processor type and features->Enable x86 board specific fixups for reboot
(13')去掉Processor type and features->/dev/cpu/microcode-microcode support
(14')如果内存是2G,将Processor type and features->High Memory support改为4G
(15')只要是家用,将Processor type and features->Timer frequency改为1000HZ
(16')将Power management and ACPI options->CPU Frequency scaling->选项下:
如果是笔记本,将Default CPUfreq governor改为conservative
将“powersave” governor、“userspace” governor for userspace frequency scaling、“ondemand” cpufreq policy governor这3项均选上。
如果是Intel的CPU,将有关AMD和VIA的选项全删除。
点击打开链接
(17')去掉Networking support->Networking options->The Ipv6 protocol
现在上网都使用IP v4,IP v6尚处于实验阶段或在某些校园网内使用。
(18')去掉Networking support->Networking options->Asynchronous Transfer mode (ATM)
(19')去掉Networking support->Amateur Radio support
(20')去掉Networking support->IrDA (infrared) subsystem support
(21')去掉Networking support->Bluetooth subsystem support
(22')选上File systems->The extended 4 (ext4) filesystem
(23')去掉File systems->Dnotify support
(24')去掉File systems-> DOS/FAT/NT Filesystems-->MSDOS fs support
(25')去掉File systems-> DOS/FAT/NT Filesystems-->Default iocharset for FAT改为“CP936”
(26')选上File systems-> DOS/FAT/NT Filesystems->NTFS file system support
(27')选上File systems-> DOS/FAT/NT Filesystems->NTFS write support
(28')去掉File systems->Miscellaneous filesystems-->
(29')去掉File systems->Network filesystems-->
(30')选上File systems->Native language support-->Simplified Chinese charset (CP936, GB2312)
(31')选上File systems->Native language support-->Traditional Chinese charset (Big5)
下面重点谈Device Drivers--->下的选择(直接驱动硬件的相关选项,步骤7搜集的信息用到这里)
这部分根据自己的硬件,可以大刀阔斧地去掉很多,在一个大的选项下,与自己的机器对应的通常只有一、两个。
(1')去掉SCSI device support--->SCSI tape support
(2')去掉Multiple devices driver support (RAID and LVM)--->
(3')去掉ISDN support--->
(4')去掉Telephone support--->
(5')去掉Auxiliary Display support--->
(6')去掉X86 Platform Specifis Device Drivers--->
其它,只能根据自己的机器选择了。例如:
我的网卡是千兆网卡和无线网卡,只选这两样足够了:
Network device support--->Ethernet (1000 Mbit)--->Broadcom Tigon3 support
Network device support--->Intel Wireless Wifi--->
Network device support--->Intel Pro/Wireless 3945ABG/BG Network connection (iwl3945)
相关话题
用户评论
m57091003
谢谢,学习了
dreamfly_cg
多谢楼主,学习学习
2351671421
不错!学习了
chunhui204
那使用make localmodconfig就意味着只能在要运行的机器上编译内核了吗?
chunhui204
比如说要编译arm的内核,就要在arm上执行这条命令了