Linux2.6内核编译裁剪记录(Kernel panic

来源:互联网 发布:php工程师中国 编辑:程序博客网 时间:2024/06/10 05:58

昨天到今天,我在VMware12虚拟机里的CentOS6.5上编译并裁剪Linux2.6.35内核,折腾了一天时间,最后将整个内核和模块的编译时间从几十分钟降为10分钟左右。期间编译内核至少几十次,遇到的最多的问题是新编译的内核无法成功启动,报如下错误:


细心观察就会发现,无法启动时,CentOS6.5启动的进度条非常慢,比正常启动时慢很多。

在网上搜索这个错误,有说要添加内核启动参数,我试了也不管用(出现这个报错的原因有很多种)。现在我才知道,这里出现上述的报错是内核启动必需的一些功能模块无法加载。我在裁剪内核时,去除了很多不需要的驱动模块,而其中有些模块恰好是内核启动需要的,因此内核无法启动,报上述错误。我在这里记录下编译内核的过程和裁剪内核时的要点,后面要裁剪内核的同学看到我这篇文章,就不会像我一样浪费很多时间。

一. 编译安装内核

编译内核很简单,最好你使用的发行版的内核版本和你要编译的内核版本比较接近,这样内核配置简单些。就拿我在CentOS6.5(内核版本为2.6.32)上编译Linux2.6.35.3内核来举例,需要经过如下步骤:

1. 取得内核源代码linux-2.6.35.3.tar.bz2,解压后出现一个目录linux-2.6.35.3

        tar xjf linux-2.6.35.3.tar.bz2

    cd linux-2.6.35.3

2. 直接使用发行版内核的配置文件配置内核,这个配置文件一般放在boot目录。

    cp /boot/config-2.6.32-431.el6.x86_64 .config

    make menuconfig

    出现如下的内核配置界面,选择“Load an Alternate Configuration File”。

  

    然后按“OK”确认,又回到上面的界面。按TAB键选“EXIT”退出,再按“YES”。配置就导入成功。

3. 编译并安装内核

    make

    make modules

    make modules_install

    make install

4. 重启后在grub界面选择相应的内核版本。正常情况下都会启动成功,内核版本已经变成了2.6.35.3。

二、裁剪内核

什么叫裁剪内核?裁剪内核就是修改内核默认的配置,去除内核一些不需要的功能和模块。

为什么要裁剪内核?按上面的步骤编译一次内核非常慢,至少几十分钟,时间太长了,而大部分编译时间都花费在我们根本不需要的驱动模块上,所以我们需要裁剪内核,减少内核编译时间。另一方面,裁剪内核过程中我们能够了解内核支持的所有功能和特性,对我们了解内核有很大的帮助。

裁剪内核的主要工作就是配置“Device Drivers”项,里面包含了内核绝大多数的驱动模块。经过裁剪后,我的配置项如下:

Generic Driver Options  ---> 
{*} Connector - unified userspace <-> kernelspace linker  ---> //子项无配置
-*- Plug and Play support  ---> //子项无配置
[*] Block devices  --->
    SCSI device support  --->
<*> Serial ATA and Parallel ATA drivers  --->
[*] Multiple devices driver support (RAID and LVM)  ---> 
[*] Fusion MPT device support  ---> 
[*] Network device support  ---> 

    Input device support  --->  //鼠标、键盘、触摸屏、游戏遥感等
    Character devices  ---> // 主要包含串口驱动、硬件随机数生成器等
-*- Power supply class support  --->//子项无配置
-*- Generic Thermal sysfs driver  --->//子项无配置
[*] Watchdog Timer Support  ---> //看门狗,可不选
[*] EDAC (Error Detection And Correction) reporting  --->//CPU错误检测
<*> Real Time Clock  --->
[*] DMA Engine support  --->

没有列出的项,都是我没有配置的,比如显卡驱动、声卡驱动、USB驱动、LED显示驱动、I2C、SPI、GPIO等。在上述我已选的配置中比较重要,有些也是必须的配置如下:

--- Block devices
<*>   Loopback device support
<M>     Cryptoloop Support
<*>   RAM block device support
(16)    Default number of RAM disks
(16384) Default RAM disk size (kbytes)

-*- SCSI device support  
<M> SCSI target support
    *** SCSI support type (disk, tape, CD-ROM) ***
<M> SCSI disk support
<M> SCSI tape support
<M> SCSI OnStream SC-x0 tape support
<M> SCSI CDROM support
[*]   Enable vendor-specific extensions (for SCSI CDROM)
<M> SCSI generic support
<M> SCSI media changer support
[*] Probe all LUNs on each SCSI device
[*] Verbose SCSI error reporting (kernel size +=12K)
[*] SCSI logging facility
[*] Asynchronous SCSI scanning
    SCSI Transports  --->
[*] SCSI low-level drivers  --->  //这里面只需选择“BusLogic SCSI support”。

--- Serial ATA and Parallel ATA drivers
[*]   Verbose ATA error reporting
[*]   ATA ACPI Support
[*]   SATA Port Multiplier support
      *** Controllers with non-SFF native interface ***
[*]   ATA SFF support
        *** SFF controllers with custom DMA interface ***
[*]     ATA BMDMA support
          *** SATA SFF controllers with BMDMA ***
<M>       Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support
   *** Generic fallback / legacy drivers ***
<M>     ACPI firmware driver for PATA
<M>     Generic ATA support

--- Multiple devices driver support (RAID and LVM)
<M>   RAID support
<M>     Linear (append) mode
<M>     RAID-0 (striping) mode
<M>     RAID-1 (mirroring) mode
<M>     RAID-10 (mirrored striping) mode
<M>     RAID-4/RAID-5/RAID-6 mode
<M>   Device mapper support
<M>     Mirror target
<M>       Mirror userspace logging (EXPERIMENTAL)

--- Fusion MPT device support
<M>   Fusion MPT ScsiHost drivers for SPI
<M>   Fusion MPT ScsiHost drivers for FC
<M>   Fusion MPT ScsiHost drivers for SAS  
(128) Maximum number of scatter gather entries (16 - 128)  
<M>   Fusion MPT misc device (ioctl) driver

--- Network device support //VMware网卡驱动

[*]   Ethernet (10 or 100Mbit)  --->

--- Ethernet (10 or 100Mbit)

{M}   Generic Media Independent Interface device support

[*]   EISA, VLB, PCI and on board controllers

<M>     AMD PCnet32 PCI support

[*]   Ethernet (1000 Mbit)  --->

--- Ethernet (1000 Mbit)

<M>   Intel(R) PRO/1000 Gigabit Ethernet support

--- Real Time Clock
[*]   Set system time from RTC on startup and resum
(rtc0)  RTC used to set the system time
[ ]   RTC debug support
      *** RTC interfaces ***
[*]   /sys/class/rtc/rtcN (sysfs)
[*]   /proc/driver/rtc (procfs for rtc0)
[*]   /dev/rtcN (character devices)

--- DMA Engine support
      *** DMA Devices ***
<M>   Intel I/OAT DMA support
      *** DMA Clients ***

三、要点

如何确定哪些模块是内核必需的?为了确保我们裁剪后的内核能够正常启动,我们先看看当前CentOS6.5的内核 (2.6.32)加载了哪些驱动模块。

[root@localhost ~]# lsmod
Module                  Size  Used by
nf_conntrack_ipv4       9506  1
nf_defrag_ipv4          1483  1 nf_conntrack_ipv4
xt_conntrack            2776  1
iptable_filter          2793  1
ip_tables              17831  1 iptable_filter
ip6t_REJECT             4628  2
nf_conntrack_ipv6       8748  2
nf_defrag_ipv6         11182  1 nf_conntrack_ipv6
xt_state                1492  2
nf_conntrack           79758  4 nf_conntrack_ipv4,xt_conntrack,nf_conntrack_ipv6,xt_state
ip6table_filter         2889  1
ip6_tables             18732  1 ip6table_filter
ipv6                  317340  273 ip6t_REJECT,nf_conntrack_ipv6,nf_defrag_ipv6

snd_ens1371            21587  0
snd_rawmidi            23017  1 snd_ens1371
snd_ac97_codec        124967  1 snd_ens1371
ac97_bus                1452  1 snd_ac97_codec
snd_seq                55727  0
snd_seq_device          6500  2 snd_rawmidi,snd_seq
snd_pcm                87409  2 snd_ens1371,snd_ac97_codec
snd_timer              22443  2 snd_seq,snd_pcm
snd                    70569  7 snd_ens1371,snd_rawmidi,snd_ac97_codec,snd_seq,snd_seq_device,snd_pcm,snd_timer
soundcore               7958  1 snd
snd_page_alloc          8856  1 snd_pcm

e1000                 170646  0
vmware_balloon          7199  0
sg                     29350  0
i2c_piix4              12608  0
i2c_core               31084  1 i2c_piix4
shpchp                 32778  0
ext4                  374902  2
jbd2                   93427  1 ext4
mbcache                 8193  1 ext4
sd_mod                 39069  3
crc_t10dif              1541  1 sd_mod
sr_mod                 15177  0
cdrom                  39085  1 sr_mod
mptspi                 16603  2
mptscsih               36700  1 mptspi
mptbase                93615  2 mptspi,mptscsih
scsi_transport_spi     25863  1 mptspi
pata_acpi               3701  0
ata_generic             3837  0
ata_piix               24601  0
dm_mirror              14384  0
dm_region_hash         12085  1 dm_mirror
dm_log                  9930  2 dm_mirror,dm_region_hash
dm_mod                 84209  8 dm_mirror,dm_log

红色部分是netfilter模块和IPv6模块,这些模块是可选的,不会影响内核启动。

黄色部分是声卡驱动,很显然这些模块也是可选的。

绿色部分那么多?我怎么知道哪些是内核启动必须需要的?很简单,当你编译完裁剪后内核,到最后make install安装时,安装程序会比较你make modules_install安装的内核模块和当前系统加载的内核模块,如果找不到需要的模块(或者模块代码被编译进内核),则会有如下的提示:


根据上面的分析,与内核启动相关的只有最后的几项。当你内核无法启动,也就是报“Kernel panic - not syncing: Attempted to kill init!”时,你就知道你缺少了dm_mirror、dm_region_hash、dm_log、dm_mod模块。

然后你可以在make menuconfig中,按‘/’键搜索模块的名字,比如“dm_mirror”,你就可以找到它的配置项。如果搜索不到,比如“dm_mod”,你可以直接去这个模块的驱动目录driver/md下查看Makefile,就知道关联的配置项了。然后配置这些选项,重新编译安装内核,没有这些错误信息时就OK了!

四、总结

之前我就是忽略了最后一步make install报的错误信息,错误地认为这些驱动模块(dm_mod等)与内核启动没有关系,而是去修改其他的配置项,结果浪费了许多时间。所以,在裁剪内核时,我们一定不能忽略这些错误信息!!!希望我花费两小时写的这篇文章能帮到一些同学。

原创粉丝点击