1. 实验目的
向现有 Linux 内核加入一个新的系统调用从而在内核空间中实现对用户空间的读写。 例如,设计并实现一个新的内核函数 mycall(),此函数通过一个引用参数的调用返回 当前系统时间,功能上基本与gettimeofday()相同。 也可以实现具有其它功能的系统调用。
2. 实验内容与步骤
1. 获取 Linux 内核源代码
从http://www.kernel.org下载Linux最新内核源代码(本文示例为4.10.9)拷贝至/usr/src文件夹并解压
tar -zxvf linux-4.10.9.tar.gz
su
cp -r linux-4.10.9 /usr/src
cd /usr/src/linux-4.10.9
2. 添加新调用的源代码
在 kernel/sys.c 尾部中添加相应的调用代码sys_mycall
asmlinkage int sys_mycall(struct timeval *tv)
{
struct timeval ktv;
do_gettimeofday(&ktv);
// 将内核空间的数据拷贝至用户空间
if (copy_to_user(tv,&ktv,sizeof(ktv))) {
return -EFAULT;
}
return 0;
}
3. 修改系统调用表
在 arch/x86/entry/syscalls/syscall_64.tbl中添加调用名和函数名
332 common mycall sys_mycall
4. 编译内核
安装编译所需的工具
apt-get install ncurses-dev libssl-dev
编译
make mrproper #清除内核中不稳定的目标文件夹,附属文件及内核配置文件
make clean #清除以前生成的目标文件和其他文件
make menuconfig #配置内核,采用默认配置即可,选择exit
make -j8 #同时开启8条线程
make modules_install
make install
reboot #重启
5.查看内核
6.编写测试程序
#include <sys/time.h>
#include <zconf.h>
#include<stdlib.h>
#include<stdio.h>
#define MYCALL 332
int main()
{
struct timeval gettime;
struct timeval mycalltime;
gettimeofday(&gettime,NULL);
syscall(MYCALL, &mycalltime);
printf("gettimeofday:%lu %lu\n",
gettime.tv_sec,gettime.tv_usec);
printf("mycall:%lu %lu\n",
mycalltime.tv_sec,mycalltime.tv_usec);
return 0;
}
gcc -o test test.c -Wformat=0
./test
网友评论