編譯安裝 Linux 4.2.6 內(nèi)核
實(shí)驗(yàn)環(huán)境
阿里云服務(wù)器 Centos_7_03 64 位
本次實(shí)驗(yàn)使用最基本的方法對(duì)內(nèi)核進(jìn)行編譯安裝,所有操作均在 root 用戶(hù)權(quán)限下施行。可使用 su 命令切換到 root 權(quán)限。
環(huán)境準(zhǔn)備
1.準(zhǔn)備 Linux 4.2.6 源碼:
可以在官網(wǎng) http://www.kernel.org 上下載,這里我們下載4.2.6版本。
不過(guò)阿里提供了 http://mirrors.aliyun.com ,也可以在這里面下載,速度更快。下載鏡像的命令如下:
cd /tmp
wget http://mirrors.aliyun.com/linux-kernel/v4.x/linux-4.2.6.tar.xz

2.準(zhǔn)備安裝需要的環(huán)境:
更新軟件源
yum update
安裝需要的環(huán)境
xz -d linux-4.2.6.tar.xz
tar –xvf linux-4.2.6.tar
把內(nèi)核目錄 Linux-4.2.6 復(fù)制到 /usr/src 目錄下,并進(jìn)入 /usr/src
準(zhǔn)備編譯
如圖所示,當(dāng)前系統(tǒng)內(nèi)核版本為 3.10.0-693.5.2.el7.x86_64,進(jìn)入之前內(nèi)核的文件目錄,拷貝 .config 文件到 Linux-4.2.6 目錄中。

進(jìn)入 Linux-4.2.6 目錄,然后執(zhí)行 make menuconfig 指令.
在配置界面,選擇 64bits-kernel 的配置文件為我們剛剛復(fù)制的 .config 文件。

編譯內(nèi)核
1.編譯啟動(dòng)鏡像
make bzImage -j2
值得一提的是這里的 -j2 參數(shù),表示的是 CPU 數(shù)目*2,由于我的阿里云服務(wù)器是單核的,所以是 -j2,如果是雙核服務(wù)器則可以改為 -j4。
當(dāng)然,直接使用 make bzImage 也可以直接編譯
2.編譯模塊
make modules -j2
同樣,也可以直接執(zhí)行 make modules
編譯的過(guò)程比較的緩慢,如果是正常的 ubuntu 系統(tǒng)可能會(huì)用上1-2小時(shí),而輕量級(jí)的阿里云主機(jī)需要花上半小時(shí)左右的時(shí)間。
安裝內(nèi)核
先安裝模塊: make modules_install
在安裝內(nèi)核: make install
更改啟動(dòng)的內(nèi)核引導(dǎo)順序
CentOS 7 系統(tǒng)使用 grub2 作為引導(dǎo)程序,需進(jìn)行如下操作:
1.查看系統(tǒng)內(nèi)部有多少個(gè)內(nèi)核:
cat /boot/grub2/grub.cfg |grep menuentry
2.配置從默認(rèn)內(nèi)核啟動(dòng),下面命令的內(nèi)核名稱(chēng)根據(jù)系統(tǒng)內(nèi)部查到的實(shí)際名稱(chēng)來(lái)替換:
grub2-set-default 'Linux 4.2.6 7 (Core)'
3.驗(yàn)證是否配置成功:
grub2-editenv list

驗(yàn)證結(jié)果
現(xiàn)在,重新啟動(dòng)服務(wù)器,再次查看服務(wù)器的內(nèi)核版本號(hào):
系統(tǒng)版本已經(jīng)是 linux 4.2.6

添加系統(tǒng)調(diào)用
實(shí)驗(yàn)流程
- 在下載的 4.2.6 內(nèi)核中添加一個(gè) hellosys 系統(tǒng)調(diào)用,其功能為打印一條由調(diào)用者傳入的一行字符串;
- 重新編譯、安裝內(nèi)核;
- 編寫(xiě)用戶(hù)測(cè)試程序,測(cè)試 hellosys 系統(tǒng)調(diào)用。
分配系統(tǒng)調(diào)用號(hào)
先去查看一下系統(tǒng)的調(diào)用號(hào)使用到多少了, 查找一下系統(tǒng)調(diào)用表
/usr/src/linux-4.2.6/arch/x86/entry/syscalls/syscall_64.tbl
我的版本使用到了322, 所以我新的系統(tǒng)調(diào)用用323號(hào)。注意文件里要看屬于x64的系統(tǒng)調(diào)用號(hào)。
然后我們修改 /usr/include/asm-generic/unistd.h 設(shè)置系統(tǒng)調(diào)用號(hào),添加系統(tǒng)調(diào)用并修改系統(tǒng)調(diào)用的總數(shù)

修改系統(tǒng)調(diào)用表
修改系統(tǒng)調(diào)用表 /usr/src/linux-4.2.6/arch/x86/entry/syscalls/syscall_64.tbl
關(guān)聯(lián)調(diào)用號(hào)與調(diào)用的服務(wù)例程地址

編寫(xiě)調(diào)用程序
在 /usr/src/linux-4.2.6/include/linux/syscalls.h 中添加一個(gè)函數(shù)聲明
asmlinkage long sys_hellosys(long uid, const char __user *content);
打開(kāi) /usr/src/linux-4.2.6/kernel/sys.c 并在結(jié)尾添加這段函數(shù)
asmlinkage long sys_hellosys(long uid, const char __user *content){
printk("%d wants to say hello, and %s", uid, content);
return 1;
}
確認(rèn)保存函數(shù)的聲明、實(shí)現(xiàn),按照上文所述重新編譯安裝內(nèi)核映像。
使用系統(tǒng)調(diào)用
測(cè)試程序:
#include <sys/syscall.h>
#include <stdio.h>
#include <unistd.h>
int main(){
long ret = syscall(323, 100, "this is a new system call!");
//syscall 參數(shù)1 調(diào)用號(hào) 之后為系統(tǒng)調(diào)用的參數(shù)列表
printf("result is %ld\n", ret);
return 0;
}
編譯、執(zhí)行 test.c,并查看內(nèi)核輸出的信息
g++ test.c -o test
./test
dmesg | grep "hello"
內(nèi)核輸出信息,說(shuō)明系統(tǒng)調(diào)用成功的獲取了用戶(hù)的信息。