一.下载内核源码
1.检查内核版本
uname -r
2.查看源内的内核源码类表
sudo apt-cache search linux-source
3.下载安装内核源码
sudo apt-get install linux-source-2.x.x
4.等待。。。
下载完成后,在/usr/src下会有一个压缩文件linux-source-2.x.xx.tar.bz2
5.解压
tar jxvf linux-source-2.x.xx.tar.bz2
二.安装依赖库
sudo apt-get install libncurses5-dev //如果没有ncurses库,则安装
三.添加系统调用
1.在/usr/src/目录
在linux-3.2.0/kernel下创建sys_mysyscall.c文件,
sudo gedit sys_mysyscall.c
内容如下:
#include <linux/kernel.h> asmlinkage long sys_mysyscall(void){ printk(KERN_ALERT "This is my sys call test!\n"); return 0; }
2.
sudo gedit Makefile
在linux-3.2.0/kernel/Makefile中加入:
obj-y += sys_mysyscall.o
3. 在linux-3.2.0/include/linux/syscalls.h中加入:
asmlinkage long sys_mysyscall(void);
4. 在linux-3.2.0/arch/x86/kernel/syscall_table_32.S(如果你编译的是64位机器则32替换为64)中加入:
.long sys_mysyscall
在linux-3.2.0/arch/x86/ia32/ia32entry.S中加入:
.quad sys_mysyscall
5. 在/usr/src/linux-source-3.2.0/arch/x86/include/asm
sudo gedit unistd_32.h
在linux-3.2.0/arch/x86/include/asm/unistd_32.h中加入:
#define __NR_sys_mysyscall 349
并将
#define NR_syscalls 349
替换为
#define NR_syscalls 350
(这里根据实际情况,__NR_mysyscall为现有最大值,NR_syscalls加一即可)
编辑arch/x86/include/asm/unistd_64.h加入:
#define __NR_foo 312 __SYSCALL(__NR_mysyscall, sys_mysyscall)
编辑linux-source-2.x.xx/include/asm-generic/unistd.h加入:
#define __NR_mysyscall 272 __SYSCALL(__NR_mysyscall, sys_mysyscall) #define __NR_syscalls 273
6.重新编译、安装、重启
1).sudo make mrproper 2).sudo make clean 3).sudo make menuconfig
在make menuconfig 做如下修改:
Device drivers ---
Staging drivers--
中把 [*] 改为 [ ](按空格), 即不编译成模块
4).sudo make & 5).sudo make modules 6).sudo make modules_install 7).sudo make install 8).reboot
7.测试
查看/proc/kallsyms中是否有mysyscall,如果有,表示符号已经导出。
grep -A 1 mysyscall /proc/kallsyms
编写测试程序:
#include <sys/syscall.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main(){ printf("%d\n", syscall(349)); return 0; }
编译运行,输出0即为正确,-1为错误。
若运行正确,用dmesg查看,末尾有输出:This is my sys call!
注意以下编译也成功了
#include <sys/syscall.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #define __NR_sys_mysyscall 349 int main(){ printf("%d\n", syscall(__NR_sys_mysyscall)); /*printf("%d\n", syscall(349)); */ return 0; }