編譯安裝 Linux 內(nèi)核并添加系統(tǒng)調(diào)用

編譯安裝 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
下載 Linux 4.2.6 源碼

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 目錄中。

查看內(nèi)核版本

進(jìn)入 Linux-4.2.6 目錄,然后執(zhí)行 make menuconfig 指令.

在配置界面,選擇 64bits-kernel 的配置文件為我們剛剛復(fù)制的 .config 文件。


選擇內(nèi)核配置文件

編譯內(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
更改 grab2

驗(yàn)證結(jié)果

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

成功安裝內(nèi)核

添加系統(tǒng)調(diào)用

實(shí)驗(yàn)流程

  1. 在下載的 4.2.6 內(nèi)核中添加一個(gè) hellosys 系統(tǒng)調(diào)用,其功能為打印一條由調(diào)用者傳入的一行字符串;
  2. 重新編譯、安裝內(nèi)核;
  3. 編寫(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)用表

修改系統(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ù)例程地址

圖9

編寫(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ù)的信息。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容