西南交通大学【操作系统实验6】

实验目的

学习如何产生一个系统调用,以及怎样通过往内核中增加一个新函数,从而在内核空间中实现对用户空间的读/写。学习重建内核。

实验内容

  1. (1)设计并实现一个新的系统调用pedagogictime() ,该函数通过使用一个引用参数的调用返回当前的系统时间。
  2. (2)编写一个用户空间程序来测试pedagogictime()。

实验环境

系统版本:Ubuntu 14.04 LTS

内核版本: Linux 3.2.0.29-generic

欲编译内核:Linux-2.6.32.60

实验步骤

解压内核:

内核文件在文件目录Documents下,将压缩包解压到/usr/src/目录下。

  1. oslinux@oslinux-virtual-machine:~$ cd Documents

//进入Documents目录下

  1. oslinux@oslinux-virtual-machine:~/Documents$ sudo cp linux-2.6.32.60.tar. bz2 /usr/src/

//将压缩包拷贝到/usr/src/目录下

  1. oslinux@oslinux-virtual-machine :~/Documents$ cd /usr/src/

//进入 /usr/src/目录下

  1. oslinux@oslinux-virtual-machine:/usr/src$ sudo tar -jxvf linux-2.6.32.60.tar.bz2

//解压压缩包

2.添加系统调用:

(1)编写系统调用服务例程

编写加到内核中的源程序,即将要加到一个内核文件中去的一个函数,该函数的名称应该是新的系统调用名称前面加上sys_标志。

注意要在/usr/src/linux-2.6.32.60/kernel/sys.c文件中添加源代码。

//用编辑器打开sys.c文件添加系统调用pedagogictime的代码

oslinux@oslinux-virtual-machine:~$ sudo gedit /usr/src/linux-2.6.32.60/kernel/sys.c

//添加到sys.c的最后一行,代码如下:

asmlinkage long sys_pedagogictime(struct timeval *tv)

{

if(likely(tv)) {

struct timeval ktv;

do_gettimeofday(&ktv);

if(copy_to_user(tv,&ktv, sizeof(ktv)))

return -EFAULT;

}

return 0;

}

(2)添加系统调用号

为了从已有的内核程序中增加到新的函数的连接,需要编辑两个文件:

在/usr/src/linux-2.6.32.60/arch/x86/include/asm/unistd_32.h中增加新的系统调用号

同时还要将宏变量NR_syscalls的值加1 ;

oslinux@oslinux-virtual-machine:~$ sudo gedit/usr/src/linux-2.6.32.60/arch/x86/include

/asm/unistd_32.h

(3)修改系统调用表

在/usr/src/linux-2.6.32.60/arch/x86/kernel/syscall_table_32.S中增加新的内核函数的指针。

oslinux@oslinux-virtual-machine:~$ sudo gedit /usr/src/linux- 2.6.32.60/arch/x86/kernel

/syscall_table_32.S

(4)重新编译Linux内核

在当前工作目录(/usr/src/linux-2.6.32.60)进入超级用户,才可以重建内核。

oslinux@oslinux-virtual-machine:~$ cd /usr/src/linux-2.6.32.60

oslinux@oslinux-virtual-machine:/usr/src/linux-2.6.32.60$ sudo –s

现在开始编译内核。编译内核的基本过程为:

root@oslinux-virtual-machine:/usr/src/linux-2.6.32.60# make mrproper

//清除依赖

root@oslinux-virtual-machine:/usr/src/linux-2.6.32.60#cp /boot/config-3.2.0-29-generic-pae .config

root@oslinux-virtual-machine:/usr/src/linux-2.6.32.60# make oldconfig

//更改配置(一直回车)

root@oslinux-virtual-machine:/usr/src/linux-2.6.32.60# make clean

//清除中间文件

root@oslinux-virtual-machine:/usr/src/linux-2.6.32.60# make bzImage

 //编译内核

root@oslinux-virtual-machine:/usr/src/linux-2.6.32.60# make modules

//编译内核模块

root@oslinux-virtual-machine:/usr/src/linux-2.6.32.60# make modules_install

//安装内核模块

root@oslinux-virtual-machine:/usr/src/linux-2.6.32.60# make install

 //安装内核

(5)启用新内核

重新启动ubuntu,开机时长按shift键直到进入启动加载页面,选择新编译的内核版本,按回车键确认选择并进入系统。

查看内核版本,是否为新内核版本:oslinux@oslinux-virtual-machine:~$ uname –a

(6)测试

编写测试程序,测试新的系统调用是否添加成功。

5.实验结果

结果展示

查看版本结果

在新版本内核下运行代码结果

结果解读

查看内核版本为新内核版本,说明内核切换成功。

运行测试程序调用新添加的函数,返回当前的系统时间。

核心代码

#include <sys/syscall.h>

#include <linux/unistd.h>

#include <stdio.h>

#include <sys/time.h>

#include <time.h>

main(){

    struct timeval tv;

    long tmp;

    tmp = syscall(337, &tv);

    if(tmp != -1){

        printf("First, user get tv_sec:%d\n", (int)tv.tv_sec);

    }

}

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

还有糕手

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值