首先讓我們腦補一下什么是系統(tǒng)調用柏靶,個人理解系統(tǒng)調用就是調用系統(tǒng)函數(shù)(內核狀態(tài)下的函數(shù))。在linux系統(tǒng)中溃论,用戶通過執(zhí)行一條訪管指令(int$0x80)來實現(xiàn)系統(tǒng)調用屎蜓。(說白點就是你在自己的代碼中調用這個““syscall()”函數(shù))就會出發(fā)一個訪管中斷,系統(tǒng)就會去執(zhí)行你需要的系統(tǒng)函數(shù)钥勋。其實中間還有一些過程炬转,筆者為了便于大家理解控汉,在此忽略了。如需詳細了解系統(tǒng)調用過程返吻,請讀者自行百度吧姑子。
那么開始進入正題吧,內核編譯啊测僵,其實是一個很漫長的過程,一步弄錯街佑,哈哈哈,很酸爽....
首先我們需要一臺linux系統(tǒng)的電腦或者裝好了linux系統(tǒng)的虛擬機捍靠,大部分人還是用虛擬機的沐旨。筆者這里使用的是VMware12,虛擬機的安裝榨婆,筆者這里就不介紹了
要進行內核編譯磁携,我們得去http://www.kernel.org下載linux源代碼
這里注意下,開始編譯前良风,確保自己是root用戶(好處是可以省去添加sudo)
我編譯的時候是用的4.13.7的版本谊迄,大家可以和我的不一樣。
打開終端烟央,切換到Downloads目錄
接下來將源碼復制到/home/src(筆者之前已經(jīng)在home目錄下創(chuàng)建了src目錄统诺,其實在哪里都可以。)
這時使用 xz -d linux-4.13.7.tar.xz 后會生成linux-4.13.7.tar
再使用tar -xvf linux-4.13.7.tar 便可以得到解壓后的源碼linux-4.13.7
進入源碼目錄后疑俭,我所用過的linux系統(tǒng)基本上要安裝nurses
使用 apt-get install libncurses5-dev 安裝
筆者是用的是kalilinux(一款滲透測試系統(tǒng)的)在進行編譯時發(fā)現(xiàn) 還需要 安裝bc粮呢,使用 apt-get install bc就可以了
接下來就是編譯前的清理工作了,使用make mrproper或者是make clean 命令钞艇,第一次編譯的話是不需要執(zhí)行的啄寡,如果是失敗后再次編譯就要執(zhí)行清理工作了,make mrproper 會清理掉殘留的.config 和.o文件哩照,make clean 會保留 .config文件挺物,如果你不想再次配置.config文件 就是用make clean吧。
內核的配置工作:
使用make menuconfig命令
會出現(xiàn)一個界面
選擇Device Drivers 這項
進入scsi 配置界面葡秒,將下面幾項全部設成*
回退到上一個界面姻乓,設置Fusion MPT,設置為 *
選擇exit保存就好了
接下來就是激動人心的時候了
輸入以下命令make bzImage 生成映像文件
筆者大概用了30分鐘左右(沒辦法虛擬機就這樣)
開始編譯模塊 輸入以下命令make modules
大概4個多小時吧(可以玩好幾把lol了~)
安裝模塊:make modules_install,這個很快哦。 輸入mkinitramfs - o /boot/initrd-4.13.7.img -v 4.13.7 即可建立載入ramdisk的映像文件
安裝內核:make install
配置引導程序:update-grub2
最后:reboot
等待它重啟
開機后查看內核版本
內核編譯就到此為止了眯牧,接下來是添加系統(tǒng)調用蹋岩。
這里我添加一個系統(tǒng)函數(shù) int mysetnice(pid_t,int flag,int nicevalue,void __user *prio,void __user * nice);
實現(xiàn)對指定進程的nice值的修改讀取和prio值得讀取,并將值從內核態(tài)返回到用戶態(tài)
參數(shù)含義
pid:進程ID
flag:若flag為o功能是讀取nice值学少,是1的話就是修改nice值
nicevalue:要修改的nice值
void __user * 指針類型(其實就是用戶態(tài)的普通指針了剪个,例如int *p)
添加系統(tǒng)調用首先要分配系統(tǒng)調用號,切換到/home/serc/linux-4.13.7/arch/x86/entry/syscalls/使用 vim syscall_64.tbl
在332下面添加一條版确,如圖所示
切換到/usr/include/asm-generic/下 vim unistd.h
加入#define __NR_mysetnice 333
__SYSCALL(__NR_mysetnice,sys_mysetnice)
切換到/home/src/linux-4.13.7/kernel/
vim sys.c
寫入以下代碼
注意這里是不能直接&task_nice(p),個人的理解是task_nice(p)返回的是一個字面值扣囊,不能直接取地址乎折,通過另外的變量將這個值暫存起來,取變量的地址(這個坑侵歇,筆者踩了很久才跳出來)骂澄,copy_to_user 是將內核的值拷貝到用戶狀態(tài)
系統(tǒng)調用的函數(shù)已經(jīng)寫好了,接下就是編譯安裝了惕虑,步驟跟編譯是一樣的了坟冲,這里不再講述。
這里我寫了一個demo測試系統(tǒng)調用是否成功的溃蔫,代碼如下
這里我打開了火狐瀏覽器使用top命令可以看到該進程的pid是6252
gcc -o testsyscall testsyscall.c 生成可執(zhí)行文件后輸入
./testsyscall
筆者的測試如下圖
成功讀取nice 和 prio的值健提,并且也成功修改了nice值