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