在嘗試內核開發之前,需要對內核有個整體的瞭解。
###主要內容:
獲取內核源碼
內核源碼的結構
編譯內核的方法
內核開發的特點
內核是開源的,所有獲取源碼特別方便,參照以下的網址,可以通過git或者直接下載壓縮好的源碼包。
http://www.kernel.org
目錄 | 說明 |
arch | 特定體系結構的代碼 |
block | 塊設備I/O層 |
crypo | 加密API |
Documentation | 內核源碼文檔 |
drivers | 設備驅動程序 |
firmware | 使用某些驅動程序而需要的設備固件 |
fs | VFS和各種文件系統 |
include | 內核頭文件 |
init | 內核引導和初始化 |
ipc | 進程間通信代碼 |
kernel | 像調度程序這樣的核心子系統 |
lib | 同樣內核函數 |
mm | 內存管理子系統和VM |
net | 網絡子系統 |
samples | 示例,示範代碼 |
scripts | 編譯內核所用的腳本 |
security | Linux 安全模塊 |
sound | 語音子系統 |
usr | 早期用戶空間代碼(所謂的initramfs) |
tools | 在Linux開發中有用的工具 |
virt | 虛擬化基礎結構 |
還未實際嘗試過手動編譯內核,只是用yum更新過內核。這部分等以後手動編譯過再補上。
安裝新的內核後,重啟時會提示進入哪個內核。當多次安裝新的內核後,啟動列表會很長(因為有很多版本的內核),顯得不是很方便。
下面介紹3種刪除那些不用的內核的方法:(是如何安裝的就選擇相應的刪除方法)
rpm -qa | grep kernel* (查找所有linux內核版本)
rpm -e kernel-(想要刪除的版本)
yum remove kernel-(要刪除的版本)
刪除/lib/modules/目錄下不需要的內核庫文件
刪除/usr/src/kernel/目錄下不需要的內核源碼
刪除/boot目錄下啟動的核心檔案禾內核映像
更改grub的配置,刪除不需要的內核啟動列表
###4.1 無標準C庫
為了保證內核的小和高效,內核開發中不能使用C標準庫,所以連最常用的printf函數也沒有,但是還好有個printk函數來代替。
因為使用GNU C,所有內核中常使用GNU C中的一些擴展:
###4.2.1 內聯函數 內聯函數在編譯時會在它被調用的地方展開,減少了函數調用的開銷,性能較好。但是,頻繁的使用內聯函數也會使代碼變長,從而在運行時佔用更多的內存。
所以內聯函數使用時最好要滿足以下幾點:函數較小,會被反覆調用,對程序的時間要求比較嚴格。
內聯函數示例:static inline
void sample();
###4.2.2 內聯彙編 內聯彙編用於偏近底層或對執行時間嚴格要求的地方。示例如下:
unsigned int low, high;
asm volatile("rdtsc" : "=a" (low), "=d" (high));
/* low 和 high 分別包含64位時間戳的低32位和高32位 */
###4.2.3 分支聲明 如果能事先判斷一個if語句時經常為真還是經常為假,那麼可以用unlikely和likely來優化這段判斷的代碼。
/* 如果error在絕大多數情況下為0(假) */
if (unlikely(error)) {
/* ... */
}
/* 如果success在絕大多數情況下不為0(真) */
if (likely(success)) {
/* ... */
}
因為內核是最低層的程序,所以如果內核訪問的非法內存,那麼整個系統都會掛掉!!所以內核開發的風險比用戶程序開發的風險要大。
而且,內核中的內存是不分頁的,每用一個字節的內存,物理內存就少一個字節。所以內核中使用內存一定要謹慎。
內核不能完美的支持浮點操作,使用浮點數時,需要人工保存和恢復浮點寄存器及其他一些繁瑣的操作。
內核棧的大小有編譯內核時決定的,對於不用的體系結構,內核棧的大小雖然不一樣,但都是固定的。
查看內核棧大小的方法:
ulimit -a | grep "stack size"
##4.6 同步和併發 Linux是多用戶的操作系統,所以必須處理好同步和併發操作,防止因競爭而出現死鎖。
Linux內核可用於不用的體現結構,支持多種硬件。所以開發時要時刻注意可移植性,儘量使用體系結構無關的代碼。