64位Linux系统调用的添加以及系统调用的原理
用户地址空间和内核地址空间每个进程都会有一个固定大小的虚拟地址空间,大小较固定,视操作系统位数而定(位数同时也决定物理地址的大小)。例如32位操作系统,其物理地址也就是32位,表示的空间也就是2的32次方,即4GB。大家都知道系统内核事关操作系统的稳定与否,我们普通程序不应该直接访问或操作的。但每个程序又会因系统调用或中断而陷入内核执行内核的操作。为了安全,我们就把虚拟地址空间划分出一块独立的部
用户地址空间和内核地址空间
每个进程都会有一个固定大小的虚拟地址空间,大小较固定,视操作系统位数而定(位数同时也决定物理地址的大小)。例如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)