64位Linux系统调用的添加以及系统调用的原理

来源:互联网 发布:iphone视频调色软件 编辑:程序博客网 时间:2024/05/29 18:43

用户地址空间和内核地址空间

每个进程都会有一个固定大小的虚拟地址空间,大小较固定,视操作系统位数而定(位数同时也决定物理地址的大小)。例如32位操作系统,其物理地址也就是32位,表示的空间也就是2的32次方,即4GB。
大家都知道系统内核事关操作系统的稳定与否,我们普通程序不应该直接访问或操作的。但每个程序又会因系统调用或中断而陷入内核执行内核的操作。为了安全,我们就把虚拟地址空间划分出一块独立的部分,称为内核态虚拟地址空间。这段内核空间大小固定,32位的为1GB,一般在虚拟地址空间的高位。另外它对应的物理地址空间范围也是固定的。

64位Linux系统调用的添加

前言:系统调用属于内核态的程序开发,因此要慎重。另外不像模块加载,系统调用的添加必须重新编译内核,因此很耗时(30——60min不等)。另外系统调用一般真的没必要再添加了,系统中有的系统调用就够用了,我们自己加一般都是冗余的画蛇添足的。

第一步:确定新的系统调用的名字例如sayDafanzi,并准备好一个linux内核源代码,自行下载并解压到相应目录即可
我确定的系统调用名字叫sayDafanzi.然后我下的linux-2.6.32.27的内核源代码,并解压在/usr/src/kernels/linux-2.6.32.27
文件夹中。下面步骤中,缺省的根目录就以这个目录为值。
第二步:添加系统调用号,并将系统调用号和内核函数对上。
64位不同于32位。64位在内核源代码中的arch/x86/include/asm/unisted_64.h这个头文件中添加适当处添加如下代码:

#define __NR_sayDafanzi                         299  //299是相对于之前的最后一个值加了1__SYSCALL(__NR_sayDafanzi,sys_sayDafanzi)

第二步:实现系统调用

我把系统调用使用的内核函数放在kernel/sys.c下,这个内核还可以放在其他位置。代码如下:

SYSCALL_DEFINE0(sayDafanzi)  /*这是后序版本添加的一个宏,可替换为诸如asmlinkage int      sys_sayDafanzi(void){}的形式*/{     printk("dafanzi23333333333333");     return 0;}

第四步:重新编译内核
回到第一步所假设的根目录make mrproper,make olfconfig(一直回车),make,make modules,make modules_install,make install
此步骤很耗费时间

第五步:测试测试

#include <stdio.h>int main(){        syscall(299);  /*在2.6.19之前使用的注入__syscallx7个宏,不过在此之后,这几个宏被废除了,因为传递参数有些麻烦*/        return 0;}
0 0