本節書摘來自異步社群《linux核心修煉之道》一書中的第2章,第2.1節,作者:華清遠見嵌入式教育訓練中心 任橋偉著,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視
如果你對linux的興趣僅是止于上上網、聽聽歌、看看碟,那麼這裡的内容或許并不适合你。如果你稍微有那麼一點點的好奇心,希望能夠體驗一下新的特性、新的核心版本,懂得如何配置與編譯核心都是必須的。
linux核心修煉之道
編譯核心的第一步就是配置核心,這是增加或減少對一些核心特性的支援的必要步驟,比如,可以為核心添加對ipv6的支援。
2.1.1 幾種配置方式
為了完成核心的配置,必須切換到root使用者,然後轉入核心源碼目錄,比如:
然後執行下面的指令之一:
這些指令都可以用來配置核心,它們的配置方式各不相同,不過我們比較常用的還是“make oldconfig”和“make menuconfig”。
1.make config
基于文本的最為傳統的也是最為枯燥的一種配置方式,但是它可以适應任何情況。這種方式會為每一個核心支援的特性向使用者提問。如果使用者回答“y”,則把該特性編譯進核心;回答“m”,則該特性作為子產品進行編譯;回答“n”,則表示不對該特性提供支援。
回答每一個問題之前,使用者都需要考慮清楚,如果在配置過程中犯了錯誤給了錯誤的答案,就隻能按“ctrl+c”強行退出了。采用該方式時的配置界面如圖2.1所示。

2.make oldconfig
make oldconfig與make config類似,但是它的作用是在現有核心設定檔案基礎上建立一個新的設定檔案,隻會向使用者提問有關新核心特性的問題。
在核心更新的過程中,make oldconfig非常有用。使用者可以将現有核心的設定檔案.config複制到新核心的源碼目錄中,執行make oldconfig,此時,使用者隻需要回答那些針對新增特性的問題。
3.make menuconfig
基于終端的一種配置方式,提供了文本模式的圖形使用者界面,使用者可以通過移動光标來浏覽核心所支援的各種特性。使用這種配置方式時,系統中必須已經安裝有ncurses庫,否則會顯示“unable to find the ncurses libraries.”的錯誤提示。make menuconfig運作時的界面如圖2.2所示。
4.make xconfig
基于x windows的一種配置方式,提供了漂亮的配置視窗,不過隻有能夠在x server上使用root使用者運作x應用程式時,才可以使用。它依賴于qt,如果系統中沒有安裝qt庫,則會出“unable to find the qt installation.”的錯誤提示。圖2.3所示為make xconfig運作時的配置界面。
5.make gconfig
與make xconfig類似,不同的是make gconfig依賴于gtk庫。圖2.4所示為make gconfig運作時的配置界面。
6.make defconfig
按照預設的配置檔案arch/i386/defconfig對核心進行配置,生成的.config可以用作初始配置,然後再使用make menuconfig進行定制化配置。
7.make allyesconfig
盡可能多地使用“y”設定核心選項值,生成的配置中包括了全部的核心特性。
8.make allmodconfig
盡可能多地使用“m”設定核心選項值來生成配置檔案。
2.1.2 .config檔案
不論采用哪種方式配置核心,最終的目的都是為了生成.config檔案,.config檔案位于核心源碼樹的頂層目錄,内容形式如下:
1.找一個舊的.config檔案作參考
核心配置選項衆多,即使使用漂亮的視窗界面去配置,也是相當的麻煩,是以我們最好找一個舊的.config檔案作為參考,在這個.config檔案的基礎上執行make menuconfig等配置指令進行調整,生成新的.config檔案。
當然,尋找這個作為參考的.config檔案時是需要有的放矢的,一般來說,可以有如下幾種途徑。
使用make defconfig得到參考.config檔案,它其實利用了arch/i386/defconfig檔案。
利用系統中/lib/modules/< kernel-version >/build目錄下的.config檔案,比如:
使用目前系統的配置檔案,一般位于/boot目錄中。
到網上搜尋下載下傳别人配置好的.config檔案。
使用某個發行版提供的.config檔案,比如slackware的.config。
2.直接修改.config檔案
如果隻是對核心所支援的特性進行微調,則可以直接修改現有的.config檔案而不需使用前面所述的配置方式。.config檔案中每個配置選項的值隻能取“y”和“m”兩者之一,如果這個特性不再支援,将其對應的選項注釋掉即可。
3.備份、重用.config檔案
通常我們需要将生成的.config檔案備份,以備後用。比如目前核心版本為2.6.23,将它的.config檔案備份為config-2.6.23。
如果打算将核心更新到2.6.24,則可以重用備份的.config檔案,因為這兩個核心之間的差別很小。
不過,僅僅複制了該檔案并不意味着馬上就可以編譯了。在編譯前,我們還必須首先執行make oldconfig,在執行過程中,如果新核心選項沒有出現在複制的.config檔案中,它會停下來等候選擇。
2.1.3 配置選項詳解
核心的配置選項有很多,通常情況下大部分選項都可以使用預設值,是以并不需要了解它們代表的具體意義。但是某些應用需要将核心裁剪得足夠小,這就需要我們知道各個選項所代表的特性,通過去掉不需要的特性,以及将部分特性編譯為可加載的子產品來減小核心的長度。
另外,即使不考慮核心裁剪的因素,當我們打算深入研究某一個子系統時,也需要首先從該子系統所涵蓋的配置選項入手(可以從該子系統代碼目錄下的各個kconfig檔案入手),掌握它的各部分實作代碼之間的分布關系,避重就輕地進行代碼的分析。
下面的内容僅是對部分比較常用的配置選項進行簡單介紹,讀者可以參考核心針對各個選項提供的幫助。
1.general setup(正常設定)
local version - append to kernel release:在核心版本後面加上自定義的版本字元串(小于64字元),可以使用“uname –a”指令看到。
automatically append version information to the version string:自動在版本字元串後面添加版本資訊,編譯時需要有perl以及git倉庫支援。
support for paging of anonymous memory (swap):允許使用交換分區(swap devices)或者交換檔案(swap files)來作為虛拟記憶體。
system v ipc:system v程序間通信(ipc)支援,許多程式需要這個功能,通常必選。
posix message queues:posix消息隊列,ipc的一部分。
export task/process statistics through netlink:通過netlink接口向使用者空間導出程序的統計資訊。netlink是一種在核心與使用者應用之間進行雙向資料傳輸的非常好的方式,使用者應用使用标準的socket api就可以使用netlink提供的強大功能。
auditing support:審計支援,某些核心子產品(例如selinux,security-enhanced linux)需要它。
kernel->user space relay support (formerly relayfs):在某些檔案系統上(比如debugfs)提供從核心空間向使用者空間傳遞大量資料的接口。
optimize for size (look out for broken compilers!):編譯時優化核心尺寸(使用“-os”而不是“-o2”作為gcc參數進行編譯)。
2.loadable module support(可加載子產品支援)
enable loadable module support:打開可加載子產品支援,需要執行make modules_install将核心子產品安裝在/lib/modules/< kernel-version >目錄下面。
module unloading:允許解除安裝已經加載的子產品。
forced module unloading:允許強制解除安裝正在使用中的子產品。
module versioning support:允許使用其他核心版本的子產品。
automatic kernel module loading:允許核心通過運作modprobe自動加載所需的子產品。
3.block layer(塊裝置層)
support for large block devices:支援大于2tb的塊裝置。
support for large single files:支援大于2tb的檔案。
io schedulers:i/o排程器選項。
anticipatory i/o scheduler:簡稱as排程器,anticipatory的中文含義“預料的,預想的”揭示了這個算法的特點,簡單地說,在一個個i/o發生的時候,如果又有程序請求i/o操作,則将産生一個猜測時間,猜測這個i/o請求是要幹什麼的。這會造成比較大的延時,對資料庫應用很糟糕,而對于web server等則會表現的不錯。這個算法也可以簡單了解為面向低速磁盤的,因為那個“猜測”實際上的目的是為了減少磁頭移動時間。
deadline i/o scheduler:提供了最小的延遲時間和尚佳的吞吐量,特别适合于讀取較多的環境(比如資料庫)。
cfq i/o scheduler:為系統内的所有任務配置設定相同的帶寬,提供一個公平的工作環境,它比較适合桌面環境。
no-op:是一個簡化的排程程式,它隻作最基本的合并與排序。與桌面系統的關系不是很大,主要用在一些特殊的軟體與硬體環境下,這些軟體與硬體一般都擁有自己的排程機制,對核心支援的要求很小,很适合一些嵌入式系統環境。
4.processor type and features(cpu類型及特性)
symmetric multi-processing support:對稱多處理器支援,如果系統中有多個cpu或者使用的是多核cpu就選上。
subarchitecture type:處理器的子架構,如果使用pc的話應當選“pc-compatible”。
processor family:處理器系列,按照實際使用的cpu選擇。
generic x86 support:通用x86支援。
hpet timer support:hpet是替代8254晶片的新一代定時器。
maximum number of cpus:支援的最大cpu數,每增加一個核心映像(image檔案)将增加大約8kb。
smt (hyperthreading) scheduler support:支援intel的超線程(ht)技術。
multi-core scheduler support:針對多核cpu進行排程政策優化。
preemption model:核心搶占模式,有3種模式可供選擇。“no forced preemption (server)”為适合伺服器環境的禁止核心搶占模式;“voluntary kernel preemption (desktop)”模式支援自願搶占,但此時核心仍然是不可搶占的,它僅僅是通過增加搶占點縮減了搶占延遲,适用于一些需要較好響應性的環境,如桌面環境;“preemptible kernel (low-latency desktop)”模式既包含了自願搶占,又使核心具有可搶占性,是以具有很好的響應延遲,主要适用于桌面和一些嵌入式系統。
preempt the big kernel lock:支援搶占大核心鎖,适用于桌面環境。
machine check exception:讓cpu檢測到系統故障時通知核心,以便核心采取相應的措施。
check for p4 thermal throttling interrupt:當p4的cpu過熱時顯示一條警告消息。
high memory support:支援的最大記憶體,總記憶體小于等于1gb的選“off”,大于4gb的選“64g”。
64 bit memory and io resources:适用64位的核心和i/o資源。
allocate 3rd-level pagetables from highmem:在記憶體很大的系統上将使用者空間的頁表放到高端記憶體區,以節約低端記憶體。
mtrr (memory type range register) support:mtrr規定了讀寫某段實體記憶體的政策,用于優化cpu資料傳送性能。例如,可将mttr設為在顯存的位址範圍上使用“write-combining”政策,cpu能夠在pci/agp總線上,将許多次少量的資料寫入集合成一次大的資料寫入,這樣能獲得 2.5倍以上圖像傳送速度的提升。詳細說明可參看核心文檔documentation/mtrr.txt。
boot from efi support:efi用于替代傳統的bios計數。
enable kernel irq balancing:打開中斷負載均衡。
timer frequency:核心時鐘頻率,桌面環境推薦使用1000 hz,伺服器環境推薦使用100 hz或250 hz。
kexec system call:提供kexec系統調用,可以不必重新開機系統而切換到另一個核心。
5.power management options(電源管理選項)
power management support:電源管理有apm和acpi兩種标準且不能同時使用。即使關閉該選項,x86上運作的linux也會在空閑時發出hlt指令将cpu進入睡眠狀态。
suspend to ram and standby:支援待機狀态,系統将目前的運作狀态等資料存放在記憶體,關閉硬碟、外設等裝置,進入等待狀态。此時記憶體仍然需要電力維持其資料,但整機耗電很少。恢複時計算機從記憶體讀出資料,回到挂起前的狀态,恢複速度較快。
hibernation(aka ‘suspend to disk’):支援休眠狀态,将目前的運作狀态等資料存放在硬碟上某個檔案或者某個特定的區域,關閉硬碟、外設等裝置,進入關機狀态。此時計算機完全關閉,不耗電。恢複時計算機從休眠檔案/分區中讀出資料,回到休眠前的狀态,恢複速度較慢。
acpi (advanced configuration and power interface) support:必須運作acpid守護程式acpi才能起作用。acpi是為了取代apm而設計的,是以應該盡量使用acpi而不是apm。
apm (advanced power management) bios support:apm支援。
cpu frequency scaling:允許動态改變cpu主頻,達到省電和降溫的目的。
6.bus options (pci, pcmcia, eisa, mca, isa)
pci support:pci支援,如果使用了pci或pci express裝置就必選。
pci access mode:pci通路模式,即通路pci的方式,可以有4個選擇,bios、mmconfig、direct、any。前三個選擇分别表示通過bios去通路、抛開bios直接(direct)去通路、通過mmconfig去通路。最後一個選擇“any”表示如果拿不準的話可以讓核心去選擇一種通路方式,當然,核心會按照一定的優先級,首先嘗試mmconfig,然後是direct,如果這兩種方式都不起效,最後再使用bios。
基于pci總線的特殊地位,bios中專門提供了針對pci總線的操作,這些操作裡就包括了總線枚舉的整個過程。在系統加電以後自檢時,就會完成對pci總線的枚舉,之後對pci裝置的通路就都是通過bios調用的形式進行,提供有這些功能和服務的bios就稱之為pci bios。這也是pci通路模式中的bios模式所表達的意思。
但是,一些舊的主機闆上,bios并不支援這麼做,還有一些嵌入式系統裡甚至于根本就沒有bios的存在,為了适應各種需要,linux就自己實作了包括總線枚舉在内的一整套pci總線操作,而不再去依賴bios,這就是direct通路模式的由來。當然在64位的平台上,是沒有什麼pci bios的,采用的總是direct方式,使用make menuconfig配置核心的時候也就根本看不到pci access mode這一項。
至于mmconfig模式,是pci express才用得上的。
message signaled interrupts (msi and msi-x):msi是pci spec v2.2中提出一種全新的中斷方式。msi通過向一個預定義的記憶體位址寫入一個已經預定義好的message來提出中斷請求,這個message到達pci主橋(host bridge)時,主橋會将它轉換為具體的中斷,發送到處理器。對pci裝置來說,這就消除了對中斷引腳電路的需要,但是pci spec裡還是要求支援msi的裝置最好同時也要具有中斷引腳。msi-x則是msi的增強。
interrupts on hypertransport devices:hypertransport是amd在1999年提出的一種總線技術。
isa support:isa裝置支援。
mca support:舊的ibm的桌上型電腦和筆記本上可能會有這種總線。
pccard (pcmcia/cardbus) support:pcmcia卡(主要用于筆記本)支援。
pci hotplug support:pci熱插拔支援。
7.executable file formats(可執行檔案格式)
kernel support for elf binaries:elf是linux下最常用的二進制檔案格式,必選。
kernel support for a.out and ecoff binaries:早期unix系統的可執行檔案格式,目前已經被elf格式取代。
kernel support for misc binaries:linux是第一個在核心級提供内建java解釋器的支援,進而執行java代碼的作業系統之一。這在2.2核心裡已經實作了。2.4核心又做了改進,将這種支援的方法改為對“misc”二進制類型的支援。通過使用這種類型的二進制代碼類型,使用者甚至可以利用dosemu(ms dos模拟器)或者wine(ms windows模拟器)來運作在dos/windows下的.exe或.com的程式。
8.networking
networking options:網絡選項。
packet socket:packet socket可以讓應用程式(比如tcpdump、iptables等)直接與網絡裝置通信,而不需通過核心中的中間網絡協定(intermediate networking protocol)。
tcp/ip networking:tcp/ip協定支援。
the ipv6 protocol:ipv6支援。
network packet filtering (replaces ipchains):netfilter可以對資料包進行過濾和修改,可以作為防火牆、網關、代理或網橋使用。
dccp configuration:資料報擁塞控制協定(datagram congestion control protocol)在udp的基礎上增加了流控和擁塞控制機制,适用于流媒體業務的傳輸。
sctp configuration:流控制傳輸協定(stream control transmission protocol)是一種新興的傳輸層協定。tcp協定一次隻能連接配接一個ip位址,而sctp協定一次可以連接配接多個ip位址,且可以自動平衡網絡負載,一旦某一個ip位址失效會自動将網絡負載轉移到其他ip位址上。
tipc configuration:透明内部程序間通信協定(the transparent inter process communication protocol)專門用于内部叢集通信(intra cluster communication)。
asynchronous transfer mode (atm):異步傳輸模式(atm)支援。
appletalk protocol support:與mac機器通信的協定。
amateur radio support:業餘無線電支援。
irda (infrared) subsystem support:紅外線支援,比如無線滑鼠。
bluetooth subsystem support:藍牙支援。
9.device drivers(裝置驅動)
memory technology devices (mtd):mtd(memory technology device)裝置支援,比如常用于數位相機或嵌入式系統的閃存卡。
plug and play support:即插即用支援。
block devices:塊裝置支援。
ata/atapi/mfm/rll support:通常是指ide硬碟和atapi光驅。
scsi device support:scsi裝置支援。
serial ata and parallel ata drivers:sata和pata裝置支援。
multi-device support (raid and lvm):raid和lvm支援。
network device support:網絡裝置支援。
input device support:輸入裝置支援。
character devices:字元裝置支援。
i2c support:i2c支援。
spi support:spi(serial peripheral interface)支援。
multimedia devices:音視訊多媒體裝置支援。
graphics support:圖形裝置以及顯示卡支援。
sound:聲霸卡支援(alsa和oss)。
usb support:usb支援。
mmc/sd card support:mmc/sd卡支援。
real time clock:rtc支援,rtc通常與cmos內建在一起,是以bios可以從中讀取目前時間。
dma engine support:dma将某些傳輸資料的操作從cpu轉移到專用硬體,進而可以進行異步傳輸并減輕cpu負載。
10.file systems(檔案系統)
second extended fs support:ext2檔案系統支援。
ext3 journalling file system support:ext3日志檔案系統支援。
ext4dev/ext4 extended fs support:最新的ext4檔案系統支援。
inotify file change notification support:檔案系統事件通知機制inotify支援,用于替代老的dnotify機制。
inotify support for userspace:使用者空間inotify支援。
quota support:磁盤限額支援,限制某個使用者或者某組使用者的磁盤占用空間。
filesystem in userspace support:fuse允許在使用者空間實作一個檔案系統,如果你打算開發一個自己的檔案系統或者使用一個基于fuse的檔案系統就選吧。
pseudo filesystems:/proc等僞檔案系統支援。
native language support:本地語言支援,使用fat/ntfs分區時需要選上。
11.instrumentation support(工具支援)
profiling support:打開profiling支援,用于對核心的性能進行分析。
oprofile system profiling:oprofile是linux的若幹種性能分析工具中的一種,能夠幫助使用者識别諸如循環的展開、高速緩存的使用率過低、低效的類型轉換和備援操作等問題。
kprobes:使用printk收集核心的調試資訊是一個衆所周知的方法,而使用了 kprobes,不需要經常重新開機和重新編譯核心就可以完成這一任務。
12.kernel hacking(核心hack選項)
show timing information on printks:在printk的輸出中包含時間資訊,可以用來分析核心啟動過程各步驟所用時間。
magic sysrq key:magic sysrq鍵是一種組合鍵,在系統無法響應時,可以進行一些基本的維護任務。
enable unused/obsolete exported symbols:導出無用和廢棄的符号,這将使核心不必要地增大。
run 'make headers_check' when building vmlinux:在編譯核心時運作“make headers_check”指令檢查核心頭檔案,當你修改了與使用者空間相關的核心頭檔案後建議啟用該選項。
use 4kb for kernel stacks instead of 8kb:如果配置該選項,則核心為程序提供的核心棧縮小為4kb,為此,每個cpu提供了一個4kb大小的中斷棧專供中斷服務程式使用。小的核心棧可以緩解系統的記憶體壓力。
13.security options(安全選項)
enable different security models:允許核心選擇不同的安全模型,如果未選中則核心将使用預設的安全模型。
socket and networking security hooks:允許安全模型通過security hook對socket與networking進行通路控制。
root plug support:一個簡單的linux安全子產品,在指定的usb裝置不存在時,它簡單地禁止所有egid為0的程序運作。
14.cryptographic api(加密api)
提供核心的加密api支援。