關於Unix根本強大的緣由:linux
正由於以上策略和機制分離的設計理念,確保了Unix系統具有清晰的層次化結構git
現在的Unix已發展成:編程
一個支持搶佔式多任務,多線程,虛擬內存,換頁,動態連接和TCP/IP網絡的現代化操做系統
Linux並無拋棄Unix的設計目標並保證了應用程序編程接口的一致。服務器
關於操做系統和內核網絡
1)操做系統是值在整個系統中負責完成最近本功能和操做系統管理的那些部分。多線程
2)系統包含了操做系統和全部運行在她之上的應用程序。併發
3)內核有時候被稱爲管理者和操做核心。
一般由:異步
負責響應中斷的中斷服務程序 負責管理多個進程從而分享處理器時間的調度程序 負責管理進程地址空間的內存管理程序 網絡、進程間通訊等系統服務程序
共同組成。分佈式
系統中運行的應用程序經過系統調用來與內核通訊。模塊化
這種交互關係——應用程序經過系統調用界面陷入內核——是應用程序完成其工做的基本行爲方式。
內核負責管理系統的硬件設備:
當硬件設備想和系統通訊時,先發出一個異步中斷信號去打斷處理器的執行,繼而打斷內核的執行。
中斷一般對應着一箇中斷號,內核經過這個中斷號來查找相應的中斷服務程序,並調用這個程序響應和處理中斷。
許多系統的中斷服務程序(包括Linux)都不在進程上下文中執行。它們在一個與進程無關的 專門的中斷上下文中運行。——爲了保證中斷服務可以在第一時間響應和處理中斷請求,而後快速退出。
LInux內核與Unix內核的比較
Unix內核幾乎毫無例外的都是一個不可分割的靜態可執行庫。
Unix內核一般須要硬件系統提供頁機制(MMU)以管理內存。
關於頁機制(MMU),它能夠增強對內存空間的保護,並保證每一個進程均可以運行不一樣的虛地址空間上。
操做系統可分:單內核和微內核
單內核(Linux就是):
從總體上做爲一個單獨的大過程來實現,同時也運行一個單獨的地址空間上。——簡單,性能高
微內核:
被分紅多個獨立的進程,每一個過程叫作一個服務器。理想狀態下只有特權服務的服務器才運行在特權模式下,其餘服務器都運行在用戶空間。(不過全部服務器都保持獨立並運行在各自的地址空間上) 所以——須要經過消息傳遞處理內核通訊:系統採用進程間通訊(IPC)機制(服務器的各自獨立有效的避免了一個服務器的失效禍及另外一個) 一樣,模塊化的系統容許一個服務器爲了另外一個服務器換出
IPC機制開銷多用於函數調用,又因用戶空間的上下文切換,消息傳遞須要必定的週期。
Lnux內核與Unix內核的顯著差別:
關於Linux的內核版本:
命名機制:用三個或四個點分隔的數字來表明不一樣的內核版本:
第一個數字是主版本號,第二個數字是從版本號,第三數字是修訂版本號,第四個數字爲穩定版本號:副版本號數字爲偶數,則爲穩定版,若是是奇數,就是開發版。
獲取Linux內核官網http://www.kernel.org
使用Git管理Linux內核源代碼,Git是分佈式的。
保持與內核官方代碼一致:
獲取最新提交到linus版本樹的一個副本:
$ git clone git://git.kernel.org/pub/scm/Linux/kernel/git/torvarlds/linux-2.6.git
更新分支:
$ git pull
解壓源代碼:
1)壓縮形式bzip2
$ tar xvjf linux-x.y.z.tar.bz2
2) 壓縮形式GNU的zip:
$ tar xvzf linux.x.y.z.tar.gz
(若是是使用git,不須要下載壓縮文件)
*不要以root身份對內核進行修改,而應該創建本身的主目錄,僅以root身份安裝新內核
打補丁的方法(一個給定版本的內核補丁老是打在前一個版本上):
$ patch -p1 < ../patch-x.y.z
編譯內核
1)配置內核
這些配置有
二選一:是否開啓 三選一:yes(代碼編譯進主內核映像,而不是做爲一個模塊),no,module(配置被選定)
*驅動程序通常都是三選一的配置選項。
配置選項也能夠是字符串或者整數。這些選項並不控制編譯過程,而只是指定內核源碼能夠訪問的值,通常以預處理宏的形式表示。
簡化內核配置命令行工具:
1)逐一配置,不推薦
$ make config
2)基於ncurse庫編制的圖形界面工具:
$ make menucofig
3)gtk+圖形工具
$ make gconfig
這三種工具將全部配置分門別類放置。
這條命令會基於默認的配置爲你的體系結構建立一個配置:
$ make deconfig
這些配置選項會被存放在內核代碼樹根目錄下.config文件中。
在修改配置文件後或者在用配置文件配置新的代碼樹的時候,應該更新和驗證:
$ make oldconfig
配置選項CONFIG_IKCONFIG_PROC把完整的壓縮過的內核配置文件存放在/proc/config.gz——方便克隆當前的配置,啓用此選項後,能夠從/proc下複製出配置文件並用來編譯一個新內核:
$ zcat /proc/config.gz > .config $ make oldconfig
配置好後進行:
make
減小編譯垃圾的方法
1)儘可能少地看到垃圾信息,不但願錯過錯誤報告或警告信息
$ make > .. /detritus
2)把無用輸出信息重定向到永無返回值的黑洞/dev/null
衍生多個編譯做業
多個做業編譯內核:
$ make -jn(n是要衍生出的做業數)
安裝新內核
必定要保證隨時有一個兩個啓動的內核,以防新編譯的內核出現問題。
模塊的安裝時自動的,也是獨立於體系結構的
以root身份運行:
% make modules_intsall
編譯時會在內核樹的根目錄下建立System.map文件。是一份符號對照表,用以將內核符號和它們的起始地址對應起來。調試的時候,若是須要內存地址翻譯成容易理解的函數名以及變量名,這會頗有用。
內核開發的獨特之處
1)無libc庫或無標準頭文件
內核不能鏈接使用標準C函數庫
體系結構相關的頭文件集中在內核源代碼樹的arch/
*printf和printk之間的一個顯著區別在於:
printk容許你經過一個指定一個標誌來設置優先級。syslogd會根據這個優先級來決定在什麼地方顯示這條系統信息。
1)內核函數
inline函數會在它調用的位置上展開(這麼作會消除函數調用和返回鎖帶來的開銷)。
定義一個內核函數的時候,須要使用static做爲關鍵字,並用inline限定它。
2)內核彙編
linux的內核混合使用了c語言和彙編語言,在偏近體系結構的底層或對執行時間嚴格要求嚴格的地方,通常使用的是彙編語言。
3)分支聲明
條件選擇語句:
if(error){ /*...*/ }
絕少發生的分支:
/*咱們認爲error絕大多數時間都會爲0*/ if(unlikely(error)){ /*...*/ }
一般爲真的分支:
/*咱們認爲success絕大多數時間都會爲0*/ if(likely(success)){ /*...*/ }
內核中很容易產生競爭,要保證不出現競爭的時候: