操作系统实验四

实验四 增加Linux系统调用

一、实验目的

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

所有的内核函数入口表集中在/user/src/linux/arch/i386/kernel/entrys.S中。系统调用是在sys_call_table中定义的,这样当增加一个新的系统调用是,就必须在这个表中增加一个新的表项。编辑该文件,增加自己的系统调用。

注意,Linux系统自身保留了221个系统调用。这就意味着,你自己增加的系统调用至少要在第222项以后开始,还要小于256。内核函数的实现体具有以下的形式:

asmlinkage <type> <func_name> (paramlist){}

其中,asmlinkage关键字指名了函数的参数的传递方式——必须使用堆栈进行。这里涉及到一个问题——int 80 到底做了些什么?事实上,它要完成一系列的动作:

  1. 在系统调用表中找出对应于系统调用号的表项;

  2. 确定系统调用的参数条目;

  3. 将参数从用户地址空间拷贝到u区;

  4. 保存当前进程的上下文;

  5. 调用内核中的系统调用代码;

  6. 返回用户进程。

如何在用户态调用内核系统函数呢?原则上只有使用致限引发0x80中断一种方法。例如:当你调在用一个具有两个参数的你同调用sys_xxx_call,若要传入参数param1param2并且将返回值存放在res中,就要采用如下方法:

long res;
asm volatile (“int $0x80” \:”=a”(res) \:”0” (__NR_sys_xxx_call), “b”((long)(param1)),\“c”((long)(param2)));
return res;

另外,系统定义了syscall0~syscall5这六个宏,分别封装对就有0个到5个参数的内核函数的调用。

最后要注意的是,在编译使用内和函数的C文件时要通知编译器把这些代码当作内和代码而不是普通的用户代码来编译,这可以通过向编译器传递__KERNEL__标志来实现,使用-W编译选项来向装载程序传递all。如下所示:

gcc –Wall –DKERNEL xxx.c

当然,如果你采用重新编译内核的方法,并不需要这样做——只要修改内核源码目录的Makefile,并将你的文件添加至O_OBJS列表中就可以了。因为MakefileFLAGS标志已经包含上述编译选项了。

二、实验内容

  • 添加一个新的内核系统调用,具体完成某个你希望实现的功能。

  • 重新编译内核,使你的系统调用可用。

  • 编写一个用户态的程序,验证你增加的系统调用。

三、实验步骤

  1. arch/i386/kernel/entry.S文件中的系统调用入口表中,找到某个空项:

    查看系统调用表,标注成sys_ni_syscall的就是暂时空闲的调用。

    .long SYMBOL_NAME(sys_ni_syscall)
    

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    修改为新加系统调用的入口项,本次实验使用第254号:

    .long SYMBOL_NAME(my_syscall)  
    

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    记住系统调用号(在系统调用入口表中的第几个入口)。

  2. 在核心文件kernel/sys.c中添加实现系统调用SYS_my_call()的代码段:

    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/sched.h> /* struct task_struct */
    asmlinkage int sys_my_syscall() { 
        printk("Hello, now my name DXH & my stu_number 20182640 are in the kernel");
        return 0;
    }
    

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  3. /usr/include/asm/unistd.h文件中增加:

    #define __NR_my_syscall  254
    

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  4. 进入相应的文件位置,生成和运行新内核

    首先进行编译的设置

    cd   /usr/src/linux-2.4.32
    make menuconfig
    

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    使用默认设置(直接ESC然后选择Yes即可)

    make   clean
    make   dep
    make   bzImage
    make   install
    

    然后重启计算机

    reboot
    
  5. 编写c程序使用新的系统调用(见“实验结果”小节)

四、实验结果

在应用程序中使用新添加的系统调用mycall,编写如下C程序 进行验证。

#define  __NR_my_syscall  254
int errno;
#include <linux/unistd.h> 
_syscall1(int, my_syscall);
int main(int argc, char *argv[]) { 
 my_syscall(); 
} 

编译该程序

gcc -o main main.c 

执行编译好的程序

./main 

读取系统日志文件

dmesg

输出内容如下所示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

五、实验心得

本次实验的主要内容是增加一个属于自己的系统调用。实验本的操作步骤相对较多,设计多个文件,需要厘清每个步骤的操作内容以及作用,才能顺利的完成本次实验。

实验完成后应当尽可能将内核恢复到原始状态,便于日后的使用。

  • 22
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值