對於用戶,編譯一個內核版本需要的不僅是升級內核和軟件那麼簡單。一般來說,編譯後的內核都能很好地工作,但是有些功能在初始化時(准確地說是在系統初始化階段,即init執行rc.sysini和rcx.d時)會失敗。失敗的情況因人而異,比如有些人在筆記本上安裝Red Hat 9.0的USB設備、Iptable和RPM就全部失敗,而有些人在安裝PCMCIA設備和FireWire設備時會失敗。 如果發現某些軟件包無法正常工作,可以嘗試下載最新的版本或重新編譯、安裝舊的版本,也可以通過進行一些相應的修改來解決問題。注意請在操作前備份文件。這裡將總結一些常見的錯誤。
典型問題及解決方法 RPM問題 進入編譯好的內核後,與RPM相關的命令有些不能使用,並出現下列錯誤: rpmdb: unable to join the environment error: db4 error(11) from dbenv->open: Resource temporarily unavailable error: cannot open Packages index using db3 - Resource temporarily unavailable (11) error: cannot open Packages database in /var/lib/rpm no packages 解決方法是執行“eXPort LD_ASSUME_KERNEL =2.2.25”命令,也可以將其寫入/etc/bashrc。
Glibc問題 用戶可以升級Glibc標准庫的軟件包來解決該問題。因為有些發行版,例如Red Hat 9.0上默認安裝的Glibc可能是被Red Hat內核小組修改過的。軟件包的下載地址是: FTP://ftp.rpmfind.net/Linux/redhat/updates/9/en/os/i386/glibc-2.3.2-27.9.i386.rpm。 可以連同以下幾個軟件包一起升級: ftp://ftp.rpmfind.net/linux/redhat/updates/9/en/os/i386/glibc-common-2.3.2-27.9.i386.rpm ftp://ftp.rpmfind.net/linux/redhat/updates/9/en/os/i386/glibc-devel-2.3.2-27.9.i386.rpm ftp://ftp.rpmfind.net/linux/redhat/updates/9/en/os/i386/glibc-utils-2.3.2-27.9.i386.rpm 如果使用“rpm -Uvh glibc*”失敗,請用命令“rpm -e”先刪除舊的Glibc,然後用命令“rpm -Uvh --force glibc*”強制安裝。
Hotplug(熱插拔)問題 內核對熱插拔功能的支持與KMOD內核線程有關。 解決方法是將/etc/rc.sysinit中所有的/proc/ksyms替換為/proc/kallsyms。執行如下命令: #mv /etc/rc.d/rc.sysinit /etc/rc.d/rc.sysinit.bak #sed -e 's/\/proc\/ksyms/\/proc\/kallsyms/g' /etc/rc.d/rc.sysinit.bak > /etc/rc.d/rc.sysinit
Sysfs問題 解決方法是: ◆ 建立目錄/sys:#mkdir /sys ◆ 在/etc/rc.d/rc.sysinit文件中找到“mount -f /proc”,在其下一行加入“mount -f /sys”。 ◆ 同樣在/etc/rc.d/rc.sysinit文件中找到“action $"Mounting proc filesystem: " mount -n -t proc /proc /proc”,在其下一行加入“action $"Mounting sysfs filesystem: " mount -n -t sysfs /sys /sys”。 ◆ 在/etc/fstab文件中加入“none /sys sysfs defaults 0 0”。 ◆ 在/etc/init.d/halt的halt_get_remaining函數中找到“awk '$2 ~ /^\/$^\/proc^\/dev/{next}”,改為“awk '$2 ~ /^\/$^\/proc^\/sys^\/dev/{next}”。
USB問題 新的2.6.0內核中使用的USB模塊大多數已經改名,因此需要修改/etc/rc.sysinit中對USB子系統初始化的代碼。將該文件中所有的“keybdev”改為“usbkbd”、“mousedev”改為“usbmouse”、“/proc/bus/usb”改為“/sys/bus/usb”,並在/etc/init.d/halt中進行同樣的修改。此外,還要在/etc/rc.sysinit中找到“needusbstorage”,做如下修改: needusbstorage= if [ $usb = "1" ]; then needusbstorage=`LC_ALL=C grep -e "^I.*Cls=08" /sys/bus/usb/devices 2>/dev/null` action $"Initializing USB 1.1 host controller: " modprobe ohci-hcd 2> /dev/null action $"Initializing USB HID interface: " modprobe hid 2> /dev/null action $"Initializing USB keyboard: " modprobe usbkbd 2> /dev/null action $"Initializing USB mouse: " modprobe usbmouse 2> /dev/null fi 如果USB總線是2.0的,還需將“ohci-hcd”改為“ehci-hcd”。
Sound問題 聲音部分的模塊名也改變了。我的筆記本原來的聲卡驅動是i810_audio,現在已改為snd-intel8x0。因此需要把下面的內容添加到/etc/modprobe.conf中: alias char-major-14 soundcore alias sound snd-intel8x0 alias sound-slot-0 snd-intel8x0 alias snd-card-0 snd-intel8x0 alias sound-service-0-0 snd-mixer-oss alias sound-service-0-1 snd-seq-oss alias sound-service-0-3 snd-pcm-oss alias sound-service-0-8 snd-seq-oss alias sound-service-0-12 snd-pcm-oss install snd-intel8x0 /sbin/modprobe --ignore-install sound-slot-0 && { /bin/aumix-minimal -f /etc/.aumixrc -L >/dev/null 2>&1; /bin/true; } remove snd-intel8x0 { /bin/aumix-minimal -f /etc/.aumixrc -S >/dev/null 2>&1; /bin/true; }; /sbin/modprobe -r --ignore-remove sound-slot-0 然後執行“modprobe sound”加載聲音模塊,並使用下列命令檢驗聲卡驅動: #cat /proc/asound/cards 顯示結果如下: 0 [SI7012]: ICH - SiS SI7012 SiS SI7012 at 0xdc00, irq 11
VMware問題 解決方法是: ◆ 將/usr/bin/vmware-config.pl中所有的“/proc/ksyms”替換為“/proc/kallsyms”。使用“sed”命令可以達到這個目的。 ◆ 重新運行該腳本,使用內核頭文件編譯新的內核模塊。在編譯過程中如發生錯誤,應該進入/usr/lib/vmware/modules/source,使用下面的命令將vmnet.tar解包: #tar xvf vmnet.tar ◆ 進入vmnet-only目錄修改bridge.c文件。將“atomic_add(skb->truesize, &sk->wmem_alloc);”修改為“atomic_add(skb->truesize, &sk->sk_wmem_alloc);”,並用類似的方式將“protinfo”改為“sk_protinfo”。 ◆ 再次把vmnet-only目錄用下面的命令重新打包為vmmon.tar: #tar cvf vmmon.tar vmnet-only。 如果按照上面的操作依舊失敗,另一解決方法是到http://ftp.cvut.cz/vmware/下載vmware-any-any-updateXX.tar.gz,將其解壓到任何目錄下,執行其中的runme.pl。
其它問題 大家也許還會遇到其它問題,但是無論遇上什麼問題都可以依照下列步驟嘗試解決: 1.內核組件盡可能編譯為模塊。執行如下命令可以快速重建內核: #make all modules_install install 2.軟件失敗的大多數情況是由於模塊名已被更改,而/etc/rc.d/rc.sysinit和/etc/rcX.d/*下的腳本卻沒有修改這些值而導致的。因此,依次修改相關條目可以改進,但是這也需要相當多的背景知識。如果覺得麻煩,可以把所有加載模塊的命令集中在/etc/rc.d/rc.local中。例如: modprobe eth0 modprobe isofs modprobe loop modprobe vfat 同時修改/etc/modoribe.conf文件。具體可參見“man modoribe.conf”獲得更多的幫助信息。 3.如果想知道某模塊變更後的名字,可以首先在“make menUConfig”時找到該選項,選擇Help找到它的配置名稱(CONFIG_*),然後到源代碼相關目錄下的makefile中尋找CONFIG_*。一般可以找到obj-$(CONFIG_*)一項,其值就是該模塊的名字。