歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux資訊 >> 更多Linux >> 如何編譯一個內核 - Fedora方式

如何編譯一個內核 - Fedora方式

日期:2017/2/27 9:48:55   编辑:更多Linux

版本: 1.0
作者: Falko Timme <ft [at] falkotimme [dot] com>
翻譯: Ken Zhao <cn.zhaoke.com>
原文: http://www.howtoforge.com/kernel_compilation_fedora
中文: http://blog.zhaoke.com/5.Html
最後更新 11/10/2006
中文最後更新 11/16/2006

每一個Linux發行版都有自己專門的工具去構建自定義的內核. 本文主要介紹在Fedora平台上編譯內核, 如何從www.kernel.org(也叫vanilla kernel)獲得最新且未改動的內核源代碼來構建一個自定義的內核, 這樣你可以使用自己的內核而不是發行版的內核, 另外也介紹了如何給內核打補丁, 從而方便增加新的功能.

下面的工作我都在Fedora Core 6上經過了測試.

我想首先要說的是文章中構建自定義內核的方式不是唯一的, 還有許多其它的方式, 這不過是我習慣的方式. 我不能保證使用後不會出現任何問題.

1. 預備工作
本文我將描述在Fedora平台上構建自定義內核的兩種方式. 第一種是Fedora方式, 最後你將能獲得一個內核rpm包, 從而可以方便地與他人分享. 第二種是傳統方式, 適用於所有linux發行版, 不過最後你不會有一個rpm包.

我推薦使用root用戶做下面所有的步驟. 然而, 有時也需要使用非超級用戶(比如用戶tom)來運行一些命令, 所以你可能會使用visudo編輯器在/etc/sudoers文件中添加下面一行:
tom ALL=(ALL) ALL

現在無論什麼時候你需要用root權限運行命令, 比如:
yum install fedora-rpmdevtools unifdef

你都可以用下面的命令來替代:
sudo yum install fedora-rpmdevtools unifdef

請記住: 如果以root用戶身份運行所有命令, 你可以完全忘記sudo. 采用什麼方式, 看你自己的習慣.

2. 構建rpm內核包
這一小節介紹如何構建內核, 最終你可以得到一個rpm包, 這樣可以方便安裝或與他人分享.

2.1 創建你的rpmbuild目錄
按下面創建你的rpmbuild目錄:
cd ~
cp -a /usr/src/redhat/ rpmbuild
echo '%_topdir %(echo $HOME)/rpmbuild' >> .rpmmacros

然後安裝構建rpm包需要的應用軟件包
yum install fedora-rpmdevtools unifdef

然後運行
fedora-buildrpmtree

2.2 下載和安裝Fedora內核src.rpm包
接下來為我們的Fedora版本下載最新的內核src.rpm包. 針對Fedora Core 6, 你可以從接下來的網址獲得src.rpm包: http://download.fedora.redhat.com/pub/fedora/linux/core/6/source/SRPMS/, 針對Fedora Core 5, 你可以從下面的網址獲得src.rpm包: http://download.fedora.redhat.com/pub/fedora/linux/core/5/source/SRPMS/, 等等.

最新的Fedora Core 6內核src.rpm包是kernel-2.6.18-1.2798.fc6.src.rpm, 所以我們現在下載和安裝它:
cd /usr/src
wget http://download.fedora.redhat.com/pub/fedora/linux/core/6/source/SRPMS/kernel-2.6.18-1.2798.fc6.src.rpm
rpm -ivh kernel-2.6.18-1.2798.fc6.src.rpm

如果你看到這些警告:
warning: user brewbuilder does not exist - using root
warning: group brewbuilder does not exist - using root

你可以忽略它們.

我們已經成功安裝了最新的2.6.18.1內核源代碼包. 如果我們繼續構建內核源代碼包的話, 我們的內核版本將是2.6.18.1.

2.3 給內核打補丁

我想安裝新內核2.6.18.2來替代2.6.18.1. 系統已經安裝的src.rpm包是給2.6.18打過補丁的2.6.18.1. 而我們現在將使用打補丁的方式升級內核到2.6.18.2
cd ~/rpmbuild/SOURCES/



wget http://www.kernel.org/pub/linux/kernel/v2.6/patch-2.6.18.2.bz2

如果你想內核的名字結尾為2.6.19-rc5, 你也可以使用prepatch包http://www.kernel.org/pub/linux/kernel/v2.6/testing/patch-2.6.19-rc5.bz2. 請注意這項工作僅對prepaches有效. 比如. 內核補丁僅對最終發行的內核版本有效, 比如2.6.19內核. 你可以給2.6.18內核源代碼打補丁, 但不能是2.6.18.1或2.6.18.2, 等. 這個規則在接下來的網頁中注明: http://kernel.org/patchtypes/pre.html

prepatches等同於linux中的測試發行; 他們位於存檔的測試目錄中, 我們可以使用patch(1)工具對上一個完整發行版(版本號分三部分)打補丁(例如, 2.6.13-rc4 prepatch只可以給2.6.11內核源代碼打補丁, 而不是2.6.11.10.)

現在我們必須修改kernel-2.6.spec文件, 讓它知道我們使用了新的內核補丁:
cd ~/rpmbuild/SPECS/
vi kernel-2.6.spec

搜尋下面行
Patch1: patch-2.6.18.1.bz2

替換為下面的內容:
Patch1: patch-2.6.18.2.bz2

(或者其它你已下載的版本)

然後運行
rpmbuild -bp kernel-2.6.spec

(如果你想構建其它平台如i386, i586, i686或者x86_64的內核, 你可以通過運行下面的命令來實現:
rpmbuild -bp --target=i686 kernel-2.6.spec

我沒有在上面例子中指定為i386, 你的系統可能是其它的平台類型, 請記得填寫你的平台類型.)

現在我們進入到關鍵的部分. src.rpm有很多fedora專門的補丁, 其中一些不能與我們的2.6.18.2補丁很好的工作, 所以如果你在rpmbuild輸出看到下面狀況:

+ echo 'Patch #300 (linux-2.6-ppc-dac960-ipr-clash.patch):'
Patch #300 (linux-2.6-ppc-dac960-ipr-clash.patch):
+ patch -p1 -s
Reversed (or previously applied) patch detected! Assume -R? [n]
Apply anyway? [n]
1 out of 1 hunk ignored -- saving rejects to file drivers/block/DAC960.c.rej
error: Bad exit status from /var/tmp/rpm-tmp.46287 (%prep)

RPM build errors:
Bad exit status from /var/tmp/rpm-tmp.46287 (%prep)

這時候你必須再次編輯kernel-2.6.spec文件, 注解掉patch #300一行:
vi kernel-2.6.spec

[...]
#Patch300: linux-2.6-ppc-dac960-ipr-clash.patch
[...]
#%patch300 -p1
[...]

然後再運行rpmbuild命令, 比如:
rpmbuild -bp kernel-2.6.spec

注意: 你必須不斷重復上面過程直到不出現任何錯誤.

2.4 指定內核識別碼
現在我們將指定一個字符串方便以後區別內核版本. 因此我們需要做:
cd ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.i386
vi Makefile

在EXTRAVERSION一行, 你可以輸入一個內核識別碼. 我想最好是在字符串後附上內核的版本號, 這樣來操作:
EXTRAVERSION = -custom-2.6.18.2

2.5 配置內核
現在我們運行
make menUConfig

然後我們看到內核的配置菜單. 移動綠色光標到 Load an Alternate Configuration File 行後選擇.config文件做為配置文件:

然後浏覽內核配置菜單, 選擇你需要的功能. 完成配置後, 選擇Exit, 回答下面的問題(Do you wish to save your new kernel configuration? 你希望保存新的內核配置嗎?), 選擇Yes:

2.6 構建內核


現在我們簡單運行下面命令來構建內核:
make rpm

然後你將在~/rpmbuild/SRPMS/目錄發現一個新的src.rpm包, 比如. ~/rpmbuild/SRPMS/kernel-2.6.18custom2.6.18.2-1.src.rpm, 內核rpm包位於~/rpmbuild/RPMS/i386/ (或 ~/rpmbuild/RPMS/i586/, ~/rpmbuild/RPMS/i686/, 等. 看你的平台類型). 比如. ~/rpmbuild/RPMS/i386/kernel-2.6.18custom2.6.18.2-1.i386.rpm. 你看到內核識別碼已添加到軟件包的名字中.

2.7 安裝新內核
現在去新的rpm內核包存在的目錄(基於你的平台類型, 比如. ~/rpmbuild/RPMS/i386/)安裝rpm包:
cd ~/rpmbuild/RPMS/i386
rpm -ivh kernel-2.6.18custom2.6.18.2-1.i386.rpm

(現在你甚至能夠拷貝到其它的Fedora系統, 通過上面的方式安裝. 你將不再需要編譯內核.)

接下來我們為新內核創建一個ramdisk, 否則系統將不能引導新內核:
mkinitrd /boot/initrd-2.6.18-custom-2.6.18.2.img 2.6.18-custom-2.6.18.2

然後編輯/boot/grub/menu.lst文件, 看一下你系統上已經存在(正在工作的)引導內核信息, 拷貝其中的一個實例, 替換為你新的內核和ramdisk:
vi /boot/grub/menu.lst

比如, 我的menu.lst, 在我添加新的內核信息前的情況:
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/VolGroup00/LogVol00
# initrd /initrd-version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.XPm.gz
hiddenmenu

title Fedora Core (2.6.18-1.2798.fc6)
root (hd0,0)
kernel /vmlinuz-2.6.18-1.2798.fc6 ro root=/dev/VolGroup00/LogVol00
initrd /initrd-2.6.18-1.2798.fc6.img

修改後的情況:

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/VolGroup00/LogVol00
# initrd /initrd-version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu

title Fedora Core (2.6.18-custom-2.6.18.2)
root (hd0,0)
kernel /vmlinuz-2.6.18-custom-2.6.18.2 ro root=/dev/VolGroup00/LogVol00
initrd /initrd-2.6.18-custom-2.6.18.2.img

title Fedora Core (2.6.18-1.2798.fc6)
root (hd0,0)
kernel /vmlinuz-2.6.18-1.2798.fc6 ro root=/dev/VolGroup00/LogVol00
initrd /initrd-2.6.18-1.2798.fc6.img

(你可以通過下面命令發現正確的vmlinuz和initrd文件:
ls -l /boot
)

現在重啟系統:
shutdown -r now

如果一切進展順利, 你的新內核正常工作. 你還可以通過運行下面命令來檢查新內核是否運行:
uname -r

這將會顯示如:
2.6.18-custom-2.6.18.2

如果系統沒有起來, 重啟一下, 你會看到:

按任意鍵進入GRUB菜單:

選擇你以前的內核啟動系統, 現在你能再次嘗試編譯新的工作內核. 不要忘記從/boot/grub/menu.1st文件中移去不需要的引導內核信息.

3. 構建內核的傳統方式


這個章節講述另一種適用於所有linux發行版的內核編譯方式. 跟Fedora編譯方式不同的是, 結果不會有rpm內核包.

3.1 下載內核源代碼
我們下載需要的內核到/usr/src目錄(去www.kernel.org網站下載你需要的內核版本, 比如. linux-2.6.18.2.tar.bz2(你可以從這裡下載所有的2.6內核: http://www.kernel.org/pub/linux/kernel/v2.6/). 然後下載到/usr/src目錄:
cd /usr/src
wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.18.2.tar.bz2

然後解壓內核源代碼, 創建一個指向內核源代碼目錄的linux字符鏈接:
tar xjf linux-2.6.18.2.tar.bz2
ln -s linux-2.6.18.2 linux
cd /usr/src/linux

3.2 給內核源代碼打補丁(可選)
有時你的缺省內核不支持新買的設備, 你需要安裝新的驅動. 或者你需要使用虛擬技術或其它高級的技術, 而這些現有的內核都不支持. 這樣情況下你需要給給內核源代碼打補丁(當然補丁已經發布..)

現在我們假設你已經下載需要的補丁(以下例子我叫它patch.bz2)到/usr/src. 運行下面的命令給內核源代碼直接打上補丁(你的用戶必須位於/usr/src/linux目錄):
bzip2 -dc /usr/src/patch.bz2 patch -p1 --dry-run
bzip2 -dc /usr/src/patch.bz2 patch -p1

第一個命令用於測試, 對內核沒有任何影響. 如果沒有顯示錯誤, 你可以運行第二個命令給內核打補丁. 如果第一個命令有誤, 請務繼續的操作!

你也能夠通過內核的prepatches方式打補丁. 比如, 如果你需要一個功能, 而這個功能僅存在於2.6.19-rc5中, 正式完整的內核版本仍沒有發布, 而patch-2.6.19-rc5.biz2已經發布. 你可以把這個補丁打到2.6.18的內核源代碼中, 但請不要達到2.6.18.1或2.6.18.2, 等. 這個規則在接下來的網頁中注明: http://kernel.org/patchtypes/pre.html

prepatches等同於linux中的測試發行; 他們位於存檔的測試目錄中, 我們可以使用patch(1)工具對上一個完整發行版(版本號分三部分)打補丁(例如, 2.6.13-rc4 prepatch只可以給2.6.11內核源代碼打補丁, 而不是2.6.11.10.)

所以如果你想編譯2.6.19-rc5內核, 你必須在步驟3.1下載2.6.18(http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.18.tar.bz2)替代2.6.18.2內核源代碼!

下面是如何給2.6.18打上2.6.19-rc5補丁:
cd /usr/src
wget http://www.kernel.org/pub/linux/kernel/v2.6/testing/patch-2.6.19-rc5.bz2
cd /usr/src/linux
bzip2 -dc /usr/src/patch-2.6.19-rc5.bz2 patch -p1 --dry-run
bzip2 -dc /usr/src/patch-2.6.19-rc5.bz2 patch -p1

3.3. 配置內核
使用當前工作內核的配置文件做為新內核配置文件的基礎是一個很好的主意. 因此我們拷貝已存的配置文件到/usr/src/linux:
make mrproper
cp /boot/config-`uname -r` ./.config

然後運行
make menuconfig

然後我們看到內核的配置菜單. 移動綠色光標到 Load an Alternate Configuration File 行後選擇.config文件做為配置文件:

然後浏覽內核配置菜單, 選擇你需要的功能. 完成配置後, 選擇Exit, 回答下面的問題(Do you wish to save your new kernel configuration? 你希望保存新的內核配置嗎?), 選擇Yes:

更多的請看:http://www.QQread.com/windows/2003/index.html

3.4 構建和安裝新的內核

構建和安裝新的內核, 執行下面的3個命令:
make all
make modules_install
make install

保持耐心, 內核編譯需要一定時間, 主要看你的內核配置和處理器速度. 最後一個命令將自動創建一個ramdisk, 你將在/boot/grub/menu.lst用到.

現在編輯/boot/grub/menu.lst. 把你的新的內核信息放到列表的頂端, 確認新的內核已經替代老的內核, default值需要設為0.

vi /boot/grub/menu.lst

我的menu.lst是這樣的:

# grub.conf generated by anaconda


#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/VolGroup00/LogVol00
# initrd /initrd-version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu

title Fedora Core (2.6.18.2)
root (hd0,0)
kernel /vmlinuz-2.6.18.2 ro root=/dev/VolGroup00/LogVol00
initrd /initrd-2.6.18.2.img

title Fedora Core (2.6.18-1.2798.fc6)
root (hd0,0)
kernel /vmlinuz-2.6.18-1.2798.fc6 ro root=/dev/VolGroup00/LogVol00
initrd /initrd-2.6.18-1.2798.fc6.img

現在重新啟動系統:
shutdown -r now

如果一切進展順利, 你的新內核正常工作. 你可以通過運行下面命令來檢查你的新內核是否運行:
uname -r

這將會顯示如:
2.6.18.2

如果系統沒有起來, 重啟一下, 你會看到:

按任意鍵進入GRUB菜單:

選擇你以前的內核啟動系統, 現在你能再次嘗試編譯新的工作內核. 不要忘記從/boot/grub/menu.1st文件中移去不需要的引導內核信息.

原文鏈接:http://blog.zhaoke.com/5.html#more-5



原文鏈接:http://blog.zhaoke.com/5.html#more-5



hiddenmenu

title Fedora Core (2.6.18.2)
root (hd0,0)
kernel /vmlinuz-2.6.18.2 ro root=/dev/VolGroup00/LogVol00
initrd /initrd-2.6.18.2.img

title Fedora Core (2.6.18-1.2798.fc6)
root (hd0,0)
kernel /vmlinuz-2.6.18-1.2798.fc6 ro root=/dev/VolGroup00/LogVol00
initrd /initrd-2.6.18-1.2798.fc6.img

現在重新啟動系統:
shutdown -r now

如果一切進展順利, 你的新內核正常工作. 你可以通過運行下面命令來檢查你的新內核是否運行:
uname -r

這將會顯示如:
2.6.18.2

如果系統沒有起來, 重啟一下, 你會看到:

按任意鍵進入GRUB菜單:

選擇你以前的內核啟動系統, 現在你能再次嘗試編譯新的工作內核. 不要忘記從/boot/grub/menu.1st文件中移去不需要的引導內核信息.

原文鏈接:http://blog.zhaoke.com/5.html#more-5



Copyright © Linux教程網 All Rights Reserved