Problem
在系統自動安裝部屬時,可能有以下原因需要更新驅動:
- 安裝光碟搭載的kernel版本不支援新硬體。
- 安裝光碟搭載的kernel版本過舊。
最常遇到的問題,莫過於在更新網卡或磁碟陣列驅動了。如果使用kickstart自動部屬,在發生硬體找不到時,應會出現如下圖錯誤:
本篇主要分享我解決此問題的方法,有以下幾個步驟:
- 準備driver rpm。
- 製作driverdisk。
- 指定driverdisk。
- 調整kickstart檔案。
準備driver rpm
準備rpm目前我試了兩種方法:
- 直接透過rpmbuild打包Intel下載的驅動包。
- 自行撰寫rpm spec檔案去產生rpm檔。
透過Intel驅動包產生rpm
最初使用這方法產生的rpm包裝driverdisk,卻發現一直無法正常載入:
在使用方法二與檢查driverdisk程式碼後,發現原因主要有二:
因此針對Intel驅動包內的.sepc,我做了以下修改(以ixgbe驅動為例):
# 原本為Provides: %{name},修改為以下 Provides: kernel-modules >= 2.6.32-220 # 原本為將ixgbe.ko改名為ixgbe.ko.new,我改為複製並放入檔案清單中 find lib -name "ixgbe.*o" -exec cp {} {}.new \; \ -fprintf %{_builddir}/%{name}-%{version}/file.list "/%p.new\n/%p\n"
修改後再重新產生的rpm與driverdisk就能夠正常載入驅動。
自行撰寫rpm spec去產生rpm
一開始使用方法一失敗後,並沒足夠時間追究原因,後來是學網路上教學自己寫。
製作driverdisk
我所產生的driverdisk,以iso為主;driverdisk的內容,會長這樣:
rhdd3 rpms/ rpms/x86_64 rpms/x86_64/ixgbe-4.3.15-1.el6.x86_64.rpm rpms/x86_64/repodata rpms/x86_64/repodata/0521246c6369e8276fa1f75fa71187e6e81d1009551529a7f0ca97846e2ec278-primary.xml.gz rpms/x86_64/repodata/32927a3988d99cbfaa3f710208c326b544154adab3a01510e90649b03e6b2a88-other.sqlite.bz2 rpms/x86_64/repodata/8222113261bc634eb8373e6c036e7f3ff2081607836c9818372dd43be048dbc6-other.xml.gz rpms/x86_64/repodata/a81432fe5d910a52559ed3f66b0b89a8b21b45fd1cf6d80a227fe77f0932c29e-filelists.sqlite.bz2 rpms/x86_64/repodata/b94224988823cc79f0a28e8d2ace4fe6f7d58c2d2f86e138b69858632825421e-primary.sqlite.bz2 rpms/x86_64/repodata/caee3a920c6960f597ebb405912500080b18c83b804f2e00f81f6a2e661537f8-filelists.xml.gz rpms/x86_64/repodata/repomd.xml
在使用上有兩個種類
- 讀立的driverdisk。
- 與安裝光碟包一起。
讀立的driverdisk
假如你是獨立的driverdisk,可以透過此連結所提供的腳本,輸入rpm並產生iso:
./mkdriverdisk.sh ixgbe-4.3.15-1.el6.x86_64.rpm
與安裝光碟包一起
假如你想要與安裝光碟包一起,有幾個步驟要做:
- 解開iso。
- 在光碟根目錄產生rhdd3檔案,內容隨便給。
- 在光碟根目錄產生rpms/x86_64資料夾,並將rpm給丟進去。
- 到rpms/x86_64目錄中,執行createrepo -p -d ./,就會產生repodata。
- 重新打包iso。
你也可以選擇將mkdriverdisk.sh產生的iso解開後,丟到安裝光碟的iso中。至於解開iso與打包iso,要自行去網路上找方法,非本篇重點。
指定driverdisk
從driverdisk程式碼中可以得知,可以使用nfs、ftp、http存取driverdisk。但如果你需要的是載入網卡驅動呢? 因此我是在boot參數中,加入dd或driverdisk:
default linux ksdevice=link ip=dhcp loglevel=debug ks=cdrom:/ks.cfg dd=path:/dev/sr0
如果你在有兩台光碟機以上的機器,必須明確知道是使用sr0或sr1;也許你會問,那怎不用dd=cdrom呢? 這我也試過,會出現以下訊息等待確認:
還有另外一個方式是在kickstart answer file中設定driverdisk位置:driverdisk --source=path:/dev/sr0
比起修改boot config內容,使用answer file的方式比較有彈性。
調整kickstart檔案
在通過no driver found後,接著很可能會出現以下錯誤:
雖然透過ifconfig可以看到網卡已找到,但檢查syslog會發現找不到網卡設定檔:這錯誤會在執行kickstart安裝動作前,因此你可以在%pre區塊中,去產生預設的設定檔:
network_devices=($(ls -I lo /sys/class/net)); for device in ${network_devices[@]}; do config=/etc/sysconfig/network-scripts/ifcfg-$device if [ ! -e "$config" ]; then logger "$device config doesn't exist! Setup $device config." cat << EOF > "$config" BOOTPROTO="dhcp" DEVICE="${device}" IPV6INIT="yes" IPV6_AUTOCONF="yes" ONBOOT="yes" EOF fi fi
而在安裝完成重新啟動後,你可能就會遇到更新後的驅動沒被載入的問題。針對載入網卡驅動的問題,網路上有些做法;首先是編輯modprobe conf,在你知道有幾張網卡的前提下,你可以在/etc/modprobe.d/anaconda.conf中加入類似以下內容:
alias eth0 ixgbe alias eth1 ixgbe
假如你不管網卡名稱或數量,你也不曉得更新的模組是不是網卡,另外一個選擇是新增/etc/sysconfig/modules/anaconda.modules檔案,在裡面載入那些ko檔:
#!/bin/sh /sbin/modprobe ixgbe
然而在使用第二個方法時,我又想到一些問題:
- 不同版本驅動可能會不同位置,我要去覆蓋掉原本的嗎?
- 假如新的驅動在原本的系統就不存在,使用modprobe不會有問題嗎?
我認為應交由kernel本身自行去判別驅動狀態,包含驅動相依性;因此我透過了depmod指令,讓系統自行去判別目前kernel modules狀態。我在answer file中,加入一個post區塊,並讓它在chroot下去執行depmod:
%post DD=/root/DD if [ -e "${DD}" ]; then logger "setup update drivers" cp -r ${DD}/lib/* /lib /sbin/depmod -r fi %end
按照以上流程,就能夠更新驅動並安裝完成系統。這部分試驗過ko來源與原本相同與不同兩種案例,都可以正常使用到最新版本驅動。
其它
我的測試環境是在CentOS6.6上。為了方便建置測試環境,撰寫了以下腳本。
#!/bin/bash REPO_URL=http://archive.kernel.org/centos-vault/6.6/os/x86_64/Packages/ KERNEL_DEVEL=kernel-devel-2.6.32-504.el6.x86_64.rpm KERNEL_HEADERS=kernel-headers-2.6.32-504.el6.x86_64.rpm mkdir /opt/rpms cd /opt/rpms yes | yum -y install wget wget ${REPO_URL}${KERNEL_DEVEL} wget ${REPO_URL}${KERNEL_HEADERS} #yum -y remove kernel-devel #yum -y remove kernel-headers rpm -ivh *.rpm yum -y install rpm-build gcc createrepo mkisofs
Reference
- anaconda source code - driverdisk.c
- RHEL6 User Guide - Use a Boot Option to Specify a Driver Update Disk
- RHEL6 User Guide - Creating a driver update disc on CD or DVD
- mkdriverdisk.sh
- How to build a driver disk for an anaconda install (CentOS 6)
- Load kernel modules on boot CentOS6
- How do I configure modprobe to find my module?
留言
張貼留言