我需要建立一個自設的內核
英文版本由 RalphAngenendt 建立。現在由 AlanBartlett 及 AkemiYagi 維護。
- 你肯定嗎?CentOS 被設計以一個完整的環境去運作。如果你替換一個最要的元件,它很可能會影響系統其它部份的運作。
你絕對肯定嗎?說真的,99.9% 的用戶已經不再須要重建自己的內核:你可以單單建立一個模塊。若是這樣,你可參考「建立你自己的內核模塊」。
你所需的功能可否透過安裝 ELRepo 計劃的某個內核模塊來提供?
- 你所需的功能是否由現有內核的一個獨立模塊所提供?
你所需的功能是否由 CentOSPlus 軟件庫內的 plus 內核所提供?
- 最後警告……如果你損壞你的內核或者系統,你除了要承擔一切後果,你亦要獨個兒解決問題,及埋怨自己令系統無法啟動。
為 CentOS 建立自設的內核有兩個方法:第一個是利用加了自設選項的 CentOS 源代碼;另一個是利用來自 Linux Kernel Archive的主流內核源代碼。
這份教學文檔教授如何利用你自己的選項或改動,配合 CentOS 的源代碼來建立一個內核。它主要是針對 CentOS-5 而寫成。請留意由
符號所標示、關於在其它版本 CentOS 上建立內核的備註。
(如果你希望建立一個主流的內核,切勿依照 How To Compile A Kernel 內的指引。這個網站不被認可,因為它不安全地教導以 root 建立內核,方法本身就有毛病。詳細理由請參閱 Building Source RPM as non-root under CentOS。建立主流內核的一個良好參考指南是 Linux Kernel in a Nutshell 這本書。)
這些行動都只供你個人使用。開發小組並不支援自設的內核,因為他們無法控制你的編譯環境、選取項目等。如果你選擇建立自設的內核,當有安全性更新、新發行、或任何須要進行維護的情況出現,你要獨力肩負起這個責任。 |
1. 編譯前的準備
要成功地建立一個內核,你須要安裝下列套件:
yum groupinstall "Development Tools" # 這樣做會確定你擁有編譯時所需的一切工具。
yum install ncurses-devel # 你必須這樣才能讓 make *config 這個指令正確地執行。
yum install qt-devel # 如果你打算用 make xconfig 而不是 make gconfig 或 make menuconfig,才須要這樣做。
yum install hmaccalc zlib-devel binutils-devel elfutils-libelf-devel # 建立 CentOS-6 內核時需要它們。
整個內核的源代碼樹。 請跟從「我需要內核代源碼」第 2 部份內的指引。
當上述 yum 指令執行時,請留意有否套件被排除。假若 yum 設定檔內存有保護內核及相關套件的 exclude 項目,它們亦必須被刪除。
請注意,為不想損失的內容建立最新及已測試的備份永遠是個明智的做法。縱使 CentOS 計劃普遍並不鼓勵有這類 exclude 規限,要是你真的如上述所說有被排除的套件,請明白某些發行商不允許未經修改的內核在他們的環境上運行。有關這個主題的詳盡資料,請參閱 不健全的虛擬伺服器這篇文章的第三節。
如果你想加入任何內核的修正,請於現在複製它們到 SOURCES 目錄內。
2. 設定內核
如果你在建立一個 CentOS-6 內核,請在整份教學文檔內用 2.6.32 取代 2.6.18。
|
如果你不打算修改發行內核的設定檔,你可以忽略這部份。你只需進行最後一步: |
|
建立好編譯用的目錄後,現在是時候修改內核的設定。請進到 ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.`uname -m`/ 目錄,然後將以下其中一個檔案複製成為這個目錄內的 .config 檔。
複製 ./configs/ 目錄內的正確類型設定檔(CentOS-5:base、xen、PAE 如果是 32 位元架構;CentOS-4:base、smp、xenU、hugemen 如果是 32 位元架構、largesmp 如果是 64 位元架構),或者複製現有內核在 /boot/config-`uname -r` 的設定檔。
你可選擇從 ./configs/ 目錄複製正確類型的設定檔:
針對 CentOS-6:只需 base(不用定義類型)
- 針對 CentOS-5:base、xen、或(假若是 32 位元架構)PAE
或者從 /boot 目錄複製現有內核的設定檔。
請參考下面的範例:
[user@host]$ cd ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.`uname -m`
你可選用 —
[user@host]$ cp configs/kernel-2.6.18-`uname -m`[-type].config .config
— 或 —
[user@host]$ cp /boot/config-`uname -r` .config
首先執行 make oldconfig。現在你應該執行 make menuconfig、make gconfig 或 make xconfig 來自訂內核的設定。當你完成後,請記得儲存你的改動。
|
如果你安裝了整個內核的源代碼來建立一個內核模塊,你應該在這裡停手。請你現在便參考「建立你自己的內核模塊」教學文檔。 |
|
接著,在你將設定檔複製回 configs/ 目錄前,請先將註釋了的硬件平台(相等於 uname -i 指令的輸出)的一行加在設定檔的頂部。這個在 32 位元架構上是 i386,在 64 位元架構上是 x86_64。這個字串必須以 # 符號來註釋,而且必需是檔案的頭一行。請留意 # 符號與硬件平台的描述中間必須有一個空格。
請在 .config 檔案的頂部加入以下一行:
# i386
— 或 —
# x86_64
現在將 .config 檔複製回 configs/ 目錄內。這基本上與先前的複製指令剛剛相反:
[user@host]$ cp .config configs/kernel-2.6.18-`uname -m`-[類型].config
最後一步就是將 configs/ 目錄內的所有內容複製到 ~/rpmbuild/SOURCES/ 目錄內。
[user@host]$ cp configs/* ~/rpmbuild/SOURCES
3. 內核的 ABI
CentOS 內核的其中一個特色就是它的應用程式二進制介面(ABI)會在整個產品生效期內保持一樣。ABI 維持不變的好處,就是外置的內核模塊在建立時不必與內核版本掛鈎 —— 因此它們不必在新內核發行時被重新建立。這是追踪 ABI 內核模塊套件的基礎 —— 它們可以提供更新的驅動程式及其它檔案系統等支援。
為了維繫 ABI 的一致性,原先的內核的 ABI 會被記錄及儲存在一個檔案內。這個檔案會在建立每個新內核時用來檢查 kABI。如果新的內核被設定或修改至一個地步令它的 ABI 與先前的有差別,編譯將會失敗,並且會有信息表示 kABI 的一致性已被破壞。這時,內核建立者有兩個選擇:(一)重新設定新的內核,讓它的 ABI 與原有的能互相吻合,因而可繼續享受一致 ABI 所提供的好處;(二)在建立的過程中停止檢查 kABI。在這兩個選擇之間,前者較為可取,但有時後者是唯一可行的方法。
要停止檢查內核的 ABI,你只須在 rpmbuild 指令行上加入一個選項及它的參數:
--without kabichk
4. 更改內核的 spec 檔案
|
這個部份所提及的行數只對應現有 CentOS 內核的 spec 檔案。 |
|
現在你須要更改內核的 spec 檔案。
[user@host]$ cd ~/rpmbuild/SPECS [user@host SPECS]$ cp kernel.spec kernel.spec.distro [user@host SPECS]$ vi kernel.spec
在第 74 行(CentOS-5)或第 18 行(CentOS-6),buildid 的定義本來是一個註釋。它必須被取消註釋及賦予一個數值,好避免與你現時安裝了的內核互相抵觸。這將這行更改如下列樣子般:
%define buildid .your_identifier
|
"%" 與 "define" 這個字之間不可以有空格。 |
|
以下一步只須在建立 CentOS-5 內核時執行。
由第 698 行起,有一段 25 行的代碼需要被改為註釋來建立自定的 CentOS-5 內核:
#if a rhel kernel, apply the rhel config options
#%if 0%{?rhel}
# for i in %{all_arch_configs}
# do
# mv $i $i.tmp
# $RPM_SOURCE_DIR/merge.pl $RPM_SOURCE_DIR/config-rhel-generic $i.tmp > $i
# rm $i.tmp
# done
#%ifarch x86_64 noarch
# for i in kernel-%{kversion}-x86_64*.config
# do
# mv $i $i.tmp
# $RPM_SOURCE_DIR/merge.pl $RPM_SOURCE_DIR/config-rhel-x86_64-generic $i.tmp > $i
# rm $i.tmp
# done
#%endif
#%ifarch ppc64 noarch
# #CONFIG_FB_MATROX is disabled for rhel generic but needed for ppc64 rhel
# for i in kernel-%{kversion}-ppc64.config
# do
# mv $i $i.tmp
# $RPM_SOURCE_DIR/merge.pl $RPM_SOURCE_DIR/config-rhel-ppc64-generic $i.tmp > $i
# rm $i.tmp
# done
#%endif
#%endif
最後假若你有任何修正,你必須在兩個地方提及它們。首先,針對 CentOS-5,在第 426 行,也就是接近修正申報的尾部,請以 40000 這數目開始加入你的申報,以免你的修正與 RHEL/CentOS 的內核修正產生衝突。例如:
Patch40000: my-custom-kernel.patch
針對 CentOS-6,請在含有 "# empty final patch file ..." 的第 604 行之上加入此行。
其次,針對 CentOS-5,請在 682 行之下加入應用你的修正的語句。你只需要加入你先前申報的修正編號,然後 rpmbuild 便會自動地為你進行修正。例如:
%patch40000 -p1
針對 CentOS-6,請在含有 "ApplyOptionalPatch ..." 的第 904 行之上,選擇加入應用於 CentOS-5 的那一行或採用下列格式:
ApplyOptionalPatch my-custom-kernel.patch
以下對 spec 檔的改動只需在 CentOS-6 下採用。
- 請把第 898 行:
cp $RPM_SOURCE_DIR/config-* .
改為:
cp $RPM_SOURCE_DIR/kernel-*.config .
刪除第 902 行。它含有:
make -f %{SOURCE20} VERSION=%{version} configs
5. 編譯新內核
開始編譯:
[user@host SPECS]$ rpmbuild -bb --target=`uname -m` kernel.spec 2> build-err.log | tee build-out.log
針對 >= 2.6.18-53.el5 的內核,你可以透過 --with 及/或 --without 這些選項及相關的引數在 rpmbuild 指令內加入一些有用的選項。值得留意的選項包括:
--with baseonly --with xenonly --without up --without xen --without debug --without debuginfo --without fips --without kabichk
舉個例說,單要建立基本內核套件,請使用:
--with baseonly --without debug --without debuginfo
單要建立 xen 內核套件,請使用:
--with xenonly --without debug --without debuginfo
單要建立 PAE 內核套件,請使用:
--without up --without xen --without debug --without debuginfo
當編譯完成後,你的自設內核的 rpm 檔案可以在 ~/rpmbuild/RPMS/`uname -m`/ 目錄內找到。切記要以 root 的身份,利用 rpm -ivh kernel-*.rpm 這個指令來安裝這些檔案。註:如果你建立了一個內核比現時安裝的版本還要舊,你還須要在 rpm 指令裡使用 --oldpackage 這個選項。
無論如何,切勿使用 rpm -Uvh 這個指令來安裝你的內核,因為這樣做會更新(取替)你現時安裝了的版本。假如你自設的內核有問題,你將會無法返回原先能正常運作的版本。
Translation of revision 163
