獲取、編譯、安裝內核
- 1 獲取內核源碼
- 安裝內核源代碼
- 何處安裝源碼
- 使用補丁
- 2 內核源碼樹
- 3 編譯內核
- 減少編譯的垃圾信息
- 衍生多個編譯作業
- 安裝內核
- 啟用指定內核作為引導
- 4 內核開發的特點
- 沒有libc庫
- 頭文件
- 沒有內存保護機制
- 容積小而固定的棧
1 獲取內核源碼
在linux內核官方網站http://www.kernel.org,可以獲得當前最新版本Linux源碼碼。如果想找一些老版本的源代碼,可以:https://mirrors.edge.kernel.org/pub/linux/kernel/下載。
安裝內核源代碼
內核壓縮以GNU zip(gzip)和bzip2兩種形式發布。以bzip2形式發布的Linux內核叫做linux-x.y.z.tar.bz2,這里x.y.z是內核源碼的具體版本。如果壓縮形式是bzip2,則運行:
tar rvjf linux-x.y.z.tar.bz2
如果壓縮形式是GNU的zip,則運行:
tar xvzf linux-x.y.z.tar.gz
何處安裝源碼
內核源碼一般安裝在/usr/src/具體linux版本 目錄下。不要以root身份對內核進行修改,而應當是,建立自己的主目錄。僅以root身份安裝新內核,即使在安裝新內核時,/usr/src/linux目錄都應當原封不動。
使用補丁
在linu內核社區中,補丁是通用語。你可以以補丁的形式發布對代碼的修改,也可以以補丁的形式接收其他人所做的修改。內核版本不斷更新,增量補丁可以作為版本轉移的橋梁。你不在需要下載內核源碼的全部壓縮,而只需給舊版本打上一個增量補丁,讓其舊貌換新顏,更新內核版本。只需運行:
patch-p1 < ../patch-x.y.z
一般來說,一個給定版本的內核補丁總是打在前一個版本上。
2 內核源碼樹
內核源碼樹由很多目錄組成,而大多數目錄又包含更多子目錄。源碼樹的根目錄及其子目錄如下表:
目錄 | 描述 |
---|---|
arch | 特定體系結構的源碼 |
crypto | Crypto API |
Documentation | 內核源碼文檔 |
drivers | 設備驅動程序 |
fs | VFS和各種文件系統 |
include | 內核頭文件 |
init | 內核引導和初始化 |
ipc | 進程間通信代碼 |
kernel | 像調度程序這樣的核心子系統 |
lib | 通用內核函數 |
mm | 內存管理子系統和VM |
net | 網絡子系統 |
scrripts | 編譯內核所用的腳本 |
security | Linux安全模塊 |
sound | 語音子系統 |
usr | 早期用戶空間代碼 |
在源碼樹根目錄中,COPYING是內核許可證,CREDITS是開發者列表。MAINTAINERS是維護者列表,維護內核子系統和驅動程序。最后,Makefile是Makefile內核的基礎
3 編譯內核
在編譯內核之前,首先你必須配置它。可以配置的各種選項,以CONFIG_FEATURE形式表示,其前綴為CONFIG。例如,對稱處理器(SMP)的配置選項為CONFIG_SMP。如果設置了該選項,則SMP啟用,否則,SMP不起作用。
這些配置項要么是二選一,要么是三選一。二選一就是yes或no。三選一可以是yes、no或module。module意味著該配置項被選定了,但編譯的時候這部分功能的實現代碼是以模塊(一種可以動態安裝的獨立代碼段)的形式生成。在三選一的情況下,yes表示把代碼編譯進內核映射中,而不是作為一個模塊。
內核提供了各種不同的工具來簡化內核配置。最簡單的一種是基于文本的命令行工具:
make config
該工具會挨個遍歷所有配置項,要求用戶選擇yes、no或module。
如果該命令不能執行,說明沒有安裝一些工具,可以根據提示安裝,我的需要安裝make、gcc、bison、flex
sudo apt-get install make gcc bison flex
這個過程很耗費時間,所以,除非你的工作是按小時計費的,否則你應該多利用基于ncuse編譯的圖形界面工具。
make menuconfig
或者基于X11的圖形工具
make xconfig
或用基于gtk+圖形工具
make gconfig
這三種工具將所有配置項分門別類放置,比如按處理器類別和特點,你可以按類移動、瀏覽內核選項,當然也可以修改其值。
命令:
make defconfig
通過這條命令為你的體系結構創建一個默認的配置。盡管這些默認值有點隨意性,但是,如果你從未配置過內核,那就會提供一個良好的開端。
執行完,幫我配置的是x86_64_defconfig。這些配置項會存放在內核代碼樹根目錄下的.config文件中,我們也可修改它,打開看看
再修改過配置文件之后,或者在用舊的配置文件配置新的代碼樹的時候,應該驗證和更新配置:
make oldconfig
一旦內核配置好了,就可以編譯它了,執行命令:
make
減少編譯的垃圾信息
我們希望在編譯時看到錯誤和警告消息,但對匆匆掠過屏幕的垃圾信息不感興趣,可以使用如下命令
make > /dev/null
就可以把無用的輸出信息重定向到永無返回值的黑洞/dev/null
衍生多個編譯作業
多個作業獨立并發運行,可以提高處理器系統上的編譯過程。默認情況下,make只衍生一個作業。為了可以以多個作業編譯內核,使用一下命令:
make -jn
n是要衍生的作業數,在實際中,每個處理器一般衍生一個或者兩個作業。例如,在一個雙處理器上,可以輸入如下命令:
make -j4
安裝內核
在內核編譯好了之后,還需要安裝它。怎么安裝就和體系架構以及啟動引導工具(boot loader)息息相關了—查閱啟動引導工具的說明,按照它的指導將內核映像拷貝到合適的位置,并且按照啟動要求安裝它。一定要保證隨時有一個或兩個可以啟動的內核,以放新編譯的內核出現問題。
安裝命令:
sudo make install
模塊的安裝是自動的,也是獨立于體系結構的。以root身份,只要運行:
sudo make modules_install
就可以把所有編譯號的模塊安裝到正確的主目錄/lib下
可以看到,編譯的內核版本號是5.0.0
同時也列出了還有那個內核
查看現在使用的內核版本
啟用指定內核作為引導
輸入下列命令將內核作為引導,將數字更改為你自己編譯的版本號:
sudo update-initramfs -c -k 5.0.0
跟新一下grub:
sudo update-grub
之后重啟即可在啟動界面選擇需要重啟的內核。如果看不到重啟選擇界面,執行以下操作。
輸入命令:
sudo vim /etc/default/grub
注釋掉hidden那一行,將timeout更改為較大值,這里改為了10
之后執行
sudo update-grub
重啟即可看到下面此單,選擇高級選項,進入后選擇編譯安裝好的內核進入即可,
選擇我們剛剛編譯好的內核,5.0.0,倒數第二個
可以看到是我們編譯的內核
4 內核開發的特點
沒有libc庫
與用戶空間的應用程序不同,內核不能鏈接使用標準C函數庫。最主要的原因是對于內核來說,完整的C庫太大了,影響速度和大小。
大部分常用的C庫函數在內核中都已經得到了實現。比如說操作字符串的函數組就位與lib/string.c文件中。只要包含<linux/string.h>頭文件就可以使用。
頭文件
內核源代碼文件不能包含外部頭文件,所說的頭文件是指組成內核源代碼樹的內核頭文件。
在沒有實現的函數中,最著名的就數printf()函數了。內核代碼雖然無法調用printf(),但它可以調用printk()函數。printk()函數負責把格式化好的字符串拷貝到內核日志緩存區上,這樣,syslog程序就可以通過讀取緩沖區來獲取內核信息。
沒有內存保護機制
如果一個用戶程序試圖進行一次非法的內存訪問,內核會出現這個錯誤,發送SIGSEGV,并結束整個進程。然而,如果是內核自己非法訪問了內存,那后果就很難控制了。內核中發生的內存錯誤會導致oops,這是內核中常見的一類錯誤。
此外,內核中的內存都不分頁,也就是說,每用掉一個字節,物理內存就減少一個字節。所以,在你想往內核加入什么新功能的時候,要記住這一點。
容積小而固定的棧
內核棧的準確大小隨體系結構而變,但都是兩頁。每個處理器都有自己的棧