在ubuntu12.04下编译linux内核写这个东西的时候,想起07年第一次编译内核,想起06年开始看内核代码,想起那段,生命中最灰暗的日子。
那时,经常在校内写读内核的心得,只因发现,你目录前言 (2)一、编译前的准备工作 (2)二、内核的配置 (2)三、内核的生成和安装 (3)四、启动新内核 (4)五、修改默认的配置文件 (4)5.1修改默认配置添加软件功能 (4)5.2修改默认配置添加pci和usb设备驱动 (5)5.3修改默认配置添加杂类设备驱动 (7)前言编译内核和编译其它软件相比,除了配置之外,没有什么特别的地方。
既然编译内核这么简单,网上也能找到很多介绍的文章,我为什么还要写呢?因为看到有些文章源自不断抄袭旧东西,导致抄了些没用的东西,而且基本都对内核配置避而不谈,这样实际上一定会有人遇到问题。
所以,写点吧,给初学者。
一、编译前的准备工作编译软件需要先安装编译环境,主要的就是工具链(toolchain)。
由于安装包需要下载的数据量较大,所以如果软件源建议还是换成国内的吧。
我用163的源,source.list文件在这里,覆盖/etc/apt/source.list就行了。
替换源后,执行如下命令:apt-get updateapt-get install build-essential p7zip-full后面的7z工具供下载了xz后缀文件的同学使用。
下载内核源码的网站是,版本随意,源码包名字是linux-3.x.x.tar.gz,有很多版本提供.xz结尾的压缩版本,压缩比较高,看自己网络情况定吧。
我这里下载的版本是3.6.6,名为linux-3.6.6.tar.gz。
接着解压源码,假设我们的编译目录为/home/sb/,解压命令为:tar xf linux-3.6.6.tar.gz-C/home/sb这样/home/sb/下出现一个linux-3.6.6的目录。
二、内核的配置内核支持很多的设备和功能,这些设备驱动和功能的开关主要通过内核的配置文件确定。
编译时,内核使用的配置文件是内核源码树根目录下一个名为.config的隐藏文件。
x86电脑默认内核配置文件可直接使用arch/x86/config/i386_defconfig,如下命令:cp arch/x86/config/i386_defconfig.configmake menuconfig默认的配置文件对于启动系统足够了,但是不同的机器硬件配置不同,默认的配置可能不支持你机器的部分硬件,火鹤缺少一些你需要的功能。
所以实际上,你会需要修改默认配置文件,重新编译来达到你的需求,关于配置文件修改见后续“修改默认的配置文件”一章。
make menuconfig后有个蓝白界面弹出来,就是内核的配置界面,如下:三、内核的生成和安装配置完成之后,用左右键和回车退出配置界,按照提示保存操作即可。
编译之前,说下编译的时间长度。
现在默认内核配置文件的模块非常少,少到几乎没有,所以编译时间较短。
如果用ubuntu的配置文件(/boot/下config开头的就是),由于需要支持的模块非常多,编译时间的确很长,这时建议减少模块的编译数量。
由于自己编译的内核一般使用场景确定,可以减少文件系统的支持数量和设备驱动中明显不需要的。
比如你电脑就一个以太网卡,其余的网卡的驱动都不要选。
类似的方式去掉你认为不用的文件系统。
当然,减少模块的编译需要修改内核配置文件。
编译就一条命令:make-j nn是个数字,默认是1。
编译的机子如果是双核建议make-j3,4核make-j7。
如果是8和以上,make-j10吧,据说比较合适的数值是cpu的核数乘以2加1,这个我自己实验过,发现没有那么玄乎,基本8核用10个进程就行了。
编译一般20分钟内能完成。
于是,内核有了,模块也有了(如果有的话)。
内核源码树根目录下生成vmlinux文件,这个是未压缩的内核,压缩的内核是arch/x86/boot/bzImage,一般启动都用压缩的内核,因为加载时间少。
接着安装编译的内核,命令如下:make modules_install这个命令安装所有模块(*.ko)到/lib/modules/的对应内核版本下。
然后,启用新内核,命令为:make install这个命令拷贝(压缩的)内核到/boot目录,并改名为vmlinuz-版本号。
然后生成initrd.img-版本号。
最后在grub.cfg中添加使用新内核grub项(实际是两项)。
对grub有了解的,可以手动修改grub.cfg,其实不麻烦,也是必须掌握的。
四、启动新内核一切就绪,重启后在grub选择界面的时候选择新条目启动,启动后新内核在我的电脑上出现了几个问题;一、启动的时候报了一个devtmpfs的错误,导致/dev下的设备节点无法创建解决方法:重新编译把CONFIG_DEVTMPFS和CONFIG_DEVTMPFS_MOUNT选上二、NTFS文件系统不识别解决方法:重新编译把NTFS的支持选上三、无线网卡不可用解决方法:重新编译,把我机子对应的无线网卡驱动选上。
可见,默认配置还是或多或少会遇到些问题的,但除非文件系统不识别,否则启动应该没有问题。
下面介绍配置文件的修改。
五、修改默认的配置文件从上面我遇到的三个问题看,默认配置文件是不能满足所有需求,需要手动修改。
由于默认的配置文件的模块非常非常少,这里只需要关心添加什么就够了。
常见情况下,修改配置主要是增加设备的支持和某些软件功能得支持,下面都做介绍。
顺便提一下,内核中的配置选项都是大写的。
5.1修改默认配置添加软件功能软件功能的支持添加相对比较简单,只要知道那个功能,比如上面说的NTFS文件系统的支持对应的配置选项名,选上即可。
一般初学者按照最常规的步骤来,先make menuconfig,然后搜索配置选项的关键字。
make menuconfig的界面出来后,打’/’(斜杠)后出现一个输入框。
输入NTFS,出现如下对话框:有时匹配的项超过一页,就需要上下翻,看哪个名字比较像,这里明显是NTFS_FS这个选项,现在默认是n,表示没有编译。
这时按空格选择编译进内核或者编译成模块,为'*'表示编入内核,'M'表示模块,建议变成*吧,反正也不大。
选上后一步步退出保存,然后编译即可。
5.2修改默认配置添加pci和usb设备驱动本来,pci和usb的设备驱动分开描述,因为很不一样。
但是考虑到大部分人(包括我)都无法准确区分一个设备到底是pci设备还是usb设备,所以就放在一起。
下面就假设用默认配置启动后,有设备不工作,因为驱动没有编译。
两种情况,一种是ubuntu内核可以工作,一种是本来就不能工作。
用ubuntu的内核都不工作的,因为设备驱动没有编译的概率不大,因为ubuntu的驱动支持还是比较全面的。
万一遇到了,要么搜索,要么用设备id号去源码查找,或者上厂家的网站下载linux驱动。
如果ubuntu的内核支持,而用默认配置文件编出的内核不支持,就基本是驱动没有编译的问题了。
要添加设备驱动,首先得知道你的硬件设备的基本信息。
用lspci和lsusb这两条命令就够了。
比如现在我的有线网卡不工作,ubuntu行的(有线网卡一般是pcie设备,3G、无线网卡一般是usb设备。
如果lspci没看到网卡,那么就lsusb去找。
这个多少需要懂点英文单词。
),那么就到ubuntu下输入:lspci-k-k表示显示出内核使用的驱动名。
lspci-k后找Eehernet这个单词,看到如下:04:00.0Ethernet controller:Marvell Technology Group Ltd.88E8039PCI-E Fast Ethernet Controller(rev14)Subsystem:QUANTA Computer Inc Device0761Kernel driver in use:sky2最后一行是kernel driver in use:sky2,说明内核中这个网卡驱动的名字叫做sky2。
那默认内核配置文件是否包含了这个sky2的驱动呢?cat.config|grep SKY输出为:CONFIG_SKY2=y#CONFIG_SKY2_DEBUG is not set可见,默认内核中有这个驱动,而且是编译进内核。
假如没有,会显示:#CONFIG_SKY2is not set我们假设默认没有编译,那么在make menuconfig后打一个’/’,然后输入SKY,回车,出现如下对话框:看到第6行有个Location,提示了如何找到CONFIG_SKY2选项。
先进入Device Drivers,然后Network device support,如此一层层下去。
最后找到对应的名称是Prompt:Marvell Yukon2support的那项,选择编译到内核,保存并编译即可。
无线网卡的驱动不支持概率挺大,而且无线驱动的名字找起来麻烦一些,我认为标准做法是先执行lsusb命令:看到如下一行:Bus001Device002:ID148f:2573Ralink Technology,Corp.RT2501/RT2573 Wireless Adapter是的,我的网卡是Ralink牌子的。
中间有个148f:2573是设备的厂商号和设备号,可作为设备的类别标志。
查找内核中ubuntu内核中这款无线网卡的支持驱动名:cat/lib/modules/3.2.0-23-generic-pae/bmap|grep2573|grep148f输出为:rt73usb0x00030x148f0x25730x0000(后面省略)输出说明支持这个无线网卡的驱动叫做rt73usb,有时会出现一个设备有多个驱动支持的情况,此时可以搜索下或随便选一个。
这个驱动默认配置没有支持,按照上面说的make menuconfig找配置的方法找到位置,编入内核。
5.3修改默认配置添加杂类设备驱动除了pci和usb设备之外,一定会有人遇到其它小设备不能用的情况,或者有些usb 接口的设备但是不在lsusb中出现的。
比如鼠标,usb转串口线等。
这里以鼠标为例介绍找杂七杂八设备驱动的方法,实际就是看ubuntu下的内核打印,猜测驱动的名字。
要是3年前,如果鼠标如果不支持,说起来还挺复杂的,但现在的默认配置比较好,USB控制器的驱动都编译到内核了,所以就容易处理了。
还是那句话,ubuntu下应该支持吧,不支持就悬了。
ubuntu下如果行,但是你自己编译的内核不行,看下ubuntu调用了哪个内核驱动。
为了使信息更清晰,先清空dmesg的内容,命令为:dmesg-c然后插入鼠标,查看打印:dmesg看后面的打印是什么,现在手头只有无线的鼠标,看到的打印如下:[4081.871505]usbhid6-1:1.0:looking for a minor,starting at96[4081.871635]hid-generic0003:09DA:054F.0007:input,hiddev0,hidraw0:USB HID v1.11Keyboard[A4TECH USB Device]on usb-0000:00:1d.1-1/input0 [4081.871997]usb6-1:adding6-1:1.1(config#1,interface1)[4081.872731]usbhid6-1:1.1:usb_probe_interface[4081.872739]usbhid6-1:1.1:usb_probe_interface-got id[4081.875412]input:A4TECH USB Device as/devices/pci0000:00/0000:00:1d.1/usb6/6-1/6-1:1.1/input/input14[4081.875610]hid-generic0003:09DA:054F.0008:input,hidraw1:USB HID v1.11 Mouse[A4TECH USB Device]on usb-0000:00:1d.1-1/input1[4081.875691]hub6-0:1.0:state7ports2chg0000evt0002看到有A4TECH吧,这个的就是鼠标的牌子,双飞燕。