Linux 核心原始碼龐大複雜,初學者常不知從何下手。本文不探討深奧機制,而是提供一套入門閱讀方法:先理解原始碼目錄架構,再透過「新增一個系統呼叫」的完整實作,掌握核心分析的基本脈絡。
核心原始碼通常位於 /usr/src/linux,版本號慣例:偶數為穩定版(如 2.2.5),奇數為開發版。主要頂層目錄說明:
i386 對應 x86 平台。include/linux 為架構無關,include/asm-i386 為 x86 專用。main.c、Version.c),研究核心運作的最佳切入點。sched.c 為排程器核心。block、char、net 等)。各目錄下的 Makefile 與 .depend 有助於理解檔案相依關係,README 則提供目錄用途說明。
arch/i386/kernel/setup.S(保護模式初始化) → arch/i386/kernel/head.S(建立 IDT 表,含系統呼叫總入口 system_call)。start_kernel()(init/main.c)呼叫 trap_init()(arch/i386/kernel/traps.c),透過 set_system_gate(SYSCALL_VECTOR, &system_call) 將系統呼叫掛在中斷 0x80。arch/i386/kernel/entry.S 以組合語言實作,負責保存狀態、驗證呼叫號、依 sys_call_table 跳轉至對應服務例程、恢復狀態返回用戶空間。include/asm-i386/unistd.h,sys_call_table 定義於 arch/i386/kernel/entry.S。kernel/sys.c):asmlinkage int sys_addtotal(int numdata) {
int i = 0, enddata = 0;
while (i <= numdata) enddata += i++;
return enddata;
}
arch/i386/kernel/entry.S):.long SYMBOL_NAME(sys_sendfile)
.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
.long SYMBOL_NAME(sys_vfork) /* 190 */
/* add by I */
.long SYMBOL_NAME(sys_addtotal)
.rept NR_syscalls-191
.long SYMBOL_NAME(sys_ni_syscall)
.endr
include/asm-i386/unistd.h),分配新的系統呼叫編號。透過具體實作,不僅學會新增系統呼叫,更掌握了核心原始碼分析的核心方法論:理解目錄架構 → 追蹤關鍵函數呼叫鏈 → 實際修改驗證。這份艱辛的投入將換取對作業系統底層運作的深度洞見與專業程式設計素養。