首先闡述一下我為什么想學(xué)習(xí)一下Linux kernel。最早是因?yàn)閷?duì)嵌入式的一時(shí)腦熱,我買(mǎi)了開(kāi)發(fā)板,買(mǎi)了不少資料,前前后后投進(jìn)去了1000多了。不過(guò)好歹還是有點(diǎn)回報(bào)的,雖然還沒(méi)有怎么著調(diào),但又似乎拓寬了不小的知識(shí)面。
慢慢的我發(fā)現(xiàn),對(duì)于從學(xué)軟件入手的我來(lái)說(shuō),硬件知識(shí)的薄弱是個(gè)不容忽視的缺陷,畢竟軟硬件間的代溝還是不小的,就像現(xiàn)在的老爹和fashion閨女一樣,鴻溝還是忽視不得的。這有點(diǎn)讓我望而卻步,不過(guò)多大的困難都無(wú)法阻擋我的前進(jìn)啊。我對(duì)策略稍作調(diào)整,因?yàn)槲野l(fā)現(xiàn),嵌入式無(wú)論是現(xiàn)在,還是未來(lái)一段時(shí)間都還是Linux的天下;另外是真正的做Linux的大牛們似乎也都有涉足embedded system 的經(jīng)歷。這就使得僅僅會(huì)管理Linux系統(tǒng)和服務(wù),簡(jiǎn)單的用幾個(gè)Shell commands ,編譯安裝幾個(gè)Linux應(yīng)用,讀懂幾個(gè)Makefile……根本滿(mǎn)足不了需求;另外也為了不讓學(xué)習(xí)的OS知識(shí)只是空洞的理論。這都要求著自己必須有編寫(xiě)自己Shell程序的能力;要求著可以在Linux做程序開(kāi)發(fā)的能力;要求著可以自己往kernel中附加自定義的系統(tǒng)調(diào)用、重組內(nèi)核、添加自寫(xiě)驅(qū)動(dòng)……的能力。這就要求著必須深入了解,正如任何一門(mén)技術(shù)一樣,接觸久了你就有種相地層實(shí)現(xiàn)挖掘的沖動(dòng)。
調(diào)整后的策略就是先把Linux這個(gè)OS的機(jī)制弄明白,才可以遷移定制滿(mǎn)足需求的系統(tǒng),才可以寫(xiě)出高效率的Linux應(yīng)用。整體路線(xiàn)就是農(nóng)村包圍城市,不斷補(bǔ)充必要知識(shí),循序漸進(jìn),最終呈現(xiàn)星星之火可以燎原之勢(shì)。額,扯得夠遠(yuǎn)。廢話(huà)不多說(shuō),下面開(kāi)始。
Kernel入門(mén),要選本好的入門(mén)書(shū)籍,我從網(wǎng)上download一本《Linux內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)》。這本書(shū)簡(jiǎn)單易讀,有OS基礎(chǔ)和Linux應(yīng)用基礎(chǔ)的人一讀即懂,我現(xiàn)已閱過(guò)3章,感覺(jué)很不錯(cuò),另外配合《Linux操作系統(tǒng)內(nèi)核實(shí)習(xí)》效果更佳。我想盡可能通過(guò)更加通俗的形式向你闡述kernel的機(jī)理,讓我們一起如喝涼水般拿下kernel。
首先介紹一下內(nèi)核源碼的根目錄描述:
arch(architecture) 特定體系結(jié)構(gòu)的源碼
crypto crypto API
Documention 內(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)
scripts 編譯內(nèi)核所用到的腳本
security Linux安全模塊
sound 語(yǔ)音子系統(tǒng)
usr 早期用戶(hù)空間代碼(所謂的initramfs)
這里只是簡(jiǎn)單闡述個(gè)目錄及系統(tǒng)模塊分布。隨著慢慢地學(xué)習(xí)我相信一定可以把它們搞明白是怎么一回事的。
另外,你需要明白一些Linux必備的一些常識(shí)性名詞解釋知識(shí),這里羅列一些名詞,不明白的不再一一闡述,自己百度,Google:管態(tài)、目態(tài)、內(nèi)核空間、用戶(hù)空間、POSIX、system V、GNU、GPL、GNOME、KDE、QT、GTK+、openGL、shell、awk、Makefile、CC、GCC、G++、GDB、Perl……
下面來(lái)介紹一下內(nèi)核開(kāi)發(fā)和應(yīng)用程序開(kāi)發(fā)的差別:
內(nèi)核編程時(shí)不能訪(fǎng)問(wèn)C庫(kù)(因?yàn)長(zhǎng)inux下很多C庫(kù)函數(shù)是對(duì)Linux系統(tǒng)調(diào)用的封裝,自身怎么可以調(diào)用自身呢?)
內(nèi)核編程時(shí)必須使用GNU C。
內(nèi)核編程時(shí)缺乏像用戶(hù)空間那樣的內(nèi)存保護(hù)機(jī)制。
內(nèi)核編程時(shí)浮點(diǎn)數(shù)很難使用。
內(nèi)核只有一個(gè)很小的定長(zhǎng)堆棧。
由于內(nèi)核支持異步中斷、搶占和SMP,因此必須時(shí)刻注意同步和并發(fā)。
要考慮可移植性的重要性。
對(duì)以上這幾點(diǎn)進(jìn)行描述。
1、首先就是內(nèi)核不能訪(fǎng)問(wèn)C庫(kù)的問(wèn)題,你想啊Linux下很多C庫(kù)函數(shù)是對(duì)Linux系統(tǒng)調(diào)用的封裝,自身怎么可以調(diào)用自身呢?這里的系統(tǒng)調(diào)用學(xué)過(guò)OS的應(yīng)該都清楚,是系統(tǒng)應(yīng)用給用戶(hù)提供的編程接口,注意這里的對(duì)象是用戶(hù)。注意啦,程序員也是分等級(jí)的,在kernel級(jí)別的編程(這里指純kernel編程),你已經(jīng)看不到系統(tǒng)調(diào)用,此時(shí)你的職責(zé)可能就是為系統(tǒng)添加一個(gè)系統(tǒng)調(diào)用(后邊會(huì)講到),且C庫(kù)是應(yīng)用層對(duì)底層系調(diào)(系統(tǒng)調(diào)用,為了便于我打字,后邊可能會(huì)多次出現(xiàn))的封裝,從邏輯的角度你也該明白了吧。那么問(wèn)題就出來(lái)了,沒(méi)有c庫(kù)怎么辦,還談什么模塊化,難不成都自己寫(xiě)?這就是接下來(lái)的問(wèn)題。
2、既然kernel不能調(diào)用C庫(kù),那么它就得擁有自己獨(dú)立的c語(yǔ)言庫(kù),這樣才能高內(nèi)聚低耦合,并且提升其安全性,所以就用了GNU C 。短小精悍效率高,畢竟是專(zhuān)才專(zhuān)用。這里需要注意一點(diǎn),內(nèi)核中沒(méi)有實(shí)現(xiàn)printf();但是有功能更為強(qiáng)大的printk();其實(shí)也談不上功能強(qiáng)大(因?yàn)閜rintf()本身就很強(qiáng)大,尤其是在調(diào)試時(shí),這里也顯出了printk的優(yōu)勢(shì)),它和printf()的顯著區(qū)別就是printk()允許通過(guò)指定一個(gè)標(biāo)志來(lái)設(shè)置優(yōu)先級(jí)。Syslog會(huì)根據(jù)這個(gè)優(yōu)先級(jí)標(biāo)志來(lái)決定什么地方顯示這條系統(tǒng)消息。如:
printk( KERN_ERR “This is an error!”); //不理解吧,我也不理解,后邊內(nèi)核調(diào)試時(shí)肯定還會(huì)將這東西,不怕。
3、內(nèi)核編程時(shí)缺乏像用戶(hù)空間那樣的內(nèi)存保護(hù)機(jī)制。
你在做什么??jī)?nèi)核好不好,這是一個(gè)OS的核心部分,控制著整個(gè)系統(tǒng)的運(yùn)轉(zhuǎn),自然要有處理協(xié)調(diào)整個(gè)系統(tǒng)的權(quán)利,在內(nèi)核coding的東西就是OS核心的一部分,是給別人或者自己在OS的上一層用的。既然你是把握這一切的,且又是在硬件基礎(chǔ)上的第一層抽象,另外還把握著全局,內(nèi)存的控制自然也不能束縛你,就像在公司工作一樣,領(lǐng)導(dǎo)要在可能的范圍內(nèi)盡可能的下放權(quán)力,下屬才能發(fā)揮他的極致,估計(jì)kernel也是這樣,內(nèi)存訪(fǎng)問(wèn),包括其他的內(nèi)核結(jié)構(gòu)都不對(duì)出于內(nèi)核的你進(jìn)行束縛,當(dāng)然也沒(méi)有進(jìn)行相應(yīng)的保護(hù)機(jī)制。因?yàn)檫@是的內(nèi)核是你的,你沒(méi)必要***到寫(xiě)程序讓自己的系統(tǒng)崩潰吧,哈哈。這也留了一個(gè)問(wèn)題,就是在coding過(guò)程中要斟酌好啊。
4、內(nèi)核編程時(shí)浮點(diǎn)數(shù)很難使用。這里你需要知道的是在用戶(hù)空間的進(jìn)程進(jìn)行浮點(diǎn)操作時(shí),kernel會(huì)完成從整數(shù)到浮點(diǎn)數(shù)的模式轉(zhuǎn)換,一般是通過(guò)捕獲陷阱并作相應(yīng)的處理的實(shí)現(xiàn)的。//陷阱可以算是一種特殊的異常,是從用戶(hù)態(tài)進(jìn)入內(nèi)核態(tài)的途徑,以后會(huì)進(jìn)一步介紹。
與用戶(hù)空間不同的是,kernel并不能完美的支持浮點(diǎn)操作,因?yàn)樽陨聿荒芟萑胱陨怼T趉ernel中使用浮點(diǎn)數(shù)時(shí),除了要人工保存和恢復(fù)浮點(diǎn)寄存器,還有很多瑣碎的事要做。直截了的說(shuō)就是:不要在kernel中使用浮點(diǎn)數(shù)!!!
5、內(nèi)核只有一個(gè)很小的定長(zhǎng)堆棧。在x86上,kernel的棧是在編譯時(shí)配置的,可為4k或者8k,且每個(gè)處理器都有自己的棧。為什么這么小呢?大了不可以么?我的理解是,現(xiàn)在都在追求微內(nèi)核,這是一方面原因,還有就是內(nèi)核也是一個(gè)軟件,只不過(guò)是包含了硬件抽象且富含大量系統(tǒng)管理功能的進(jìn)程,而其他功能的進(jìn)程(系統(tǒng)調(diào)用,其他內(nèi)核進(jìn)程),在調(diào)度是,存在內(nèi)核搶占和代替內(nèi)核執(zhí)行的情況,這是要將要執(zhí)行的進(jìn)程的上下文切換過(guò)來(lái),當(dāng)然這些數(shù)據(jù)都會(huì)出現(xiàn)在棧里邊,你想如果棧很大,那么操作時(shí)內(nèi)存訪(fǎng)問(wèn)地址會(huì)很長(zhǎng),訪(fǎng)問(wèn)時(shí)占內(nèi)存且費(fèi)時(shí)間,會(huì)降低效率,所以要盡可能的小且靈活……
6、由于內(nèi)核支持異步中斷、搶占和SMP,因此必須時(shí)刻注意同步和并發(fā)。這不僅僅是linux kernel ,是所有現(xiàn)有的多進(jìn)程/多線(xiàn)程并發(fā)OS都要注意的,包括多線(xiàn)程編程也一樣,你就把kernel想成是一個(gè)多線(xiàn)程的執(zhí)行程序就OK了,不難理解。
7、要考慮可移植性的重要性。這個(gè)更不用多說(shuō)了,因?yàn)檫@是linux的一個(gè)灰常顯著的特征,大到企業(yè)的服務(wù)器,小到嵌入式的android,IP camera……等很多東西不同平臺(tái)構(gòu)架的cpu……應(yīng)該是目前跑的平臺(tái)最多的OS了,所以他的內(nèi)核要有足夠的可移植性,似乎有點(diǎn)java的感覺(jué)......
-
嵌入式
+關(guān)注
關(guān)注
5198文章
20442瀏覽量
333976 -
內(nèi)核
+關(guān)注
關(guān)注
4文章
1467瀏覽量
42870 -
Linux
+關(guān)注
關(guān)注
88文章
11758瀏覽量
219006 -
Kernel
+關(guān)注
關(guān)注
0文章
50瀏覽量
12074
原文標(biāo)題:嵌入式未來(lái)一段時(shí)間還是Linux天下,一位嵌入式er初探Linux kernel經(jīng)驗(yàn)
文章出處:【微信號(hào):gh_c472c2199c88,微信公眾號(hào):嵌入式微處理器】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
學(xué)習(xí)嵌入式LINUX的筆記和體會(huì)
嵌入式開(kāi)發(fā)板的學(xué)習(xí)方法
作為新人要如何學(xué)習(xí)嵌入式Linux
如何通過(guò)網(wǎng)絡(luò)升級(jí)嵌入式系統(tǒng)的linux內(nèi)核
嵌入式Linux內(nèi)核實(shí)時(shí)性研究及改進(jìn)
嵌入式linux學(xué)習(xí)誤區(qū)
嵌入式Linux系統(tǒng)和驅(qū)動(dòng)開(kāi)發(fā)
嵌入式linux內(nèi)核的編譯步驟
嵌入式Linux內(nèi)核驅(qū)動(dòng)開(kāi)發(fā)學(xué)習(xí)路線(xiàn)圖
嵌入式LINUX系統(tǒng)內(nèi)核和內(nèi)核模塊調(diào)試
【嵌入式】構(gòu)建嵌入式Linux系統(tǒng)(uboot、內(nèi)核、文件系統(tǒng))
嵌入式Linux系統(tǒng)基礎(chǔ)概念
Linux嵌入式學(xué)習(xí)過(guò)程
嵌入式Linux的內(nèi)核編譯
學(xué)習(xí)嵌入式的開(kāi)發(fā)線(xiàn)路,新手怎么學(xué)習(xí)嵌入式?
嵌入式未來(lái)還是Linux的天下,并通過(guò)內(nèi)核學(xué)習(xí)來(lái)闡述kernel的機(jī)理
評(píng)論