数码资讯
在Linux下添加系统调用
对1.linux系统调用的基本原理 Linux系统调用兼容POSIX,也是一套C语言函数的名字。然而,Linux系统调用的内部实现类似DOC INT 21H。它进入国际0x80h软中断后,它是根据系统调用号分类。 从系统分析的角度来看,Linux系统调用涉及4个方面。 (1)与系统调用相关的数据结构
选购提示
关注价格、性能、续航、售后和真实使用场景,理性比较后再下单。
对1.linux系统调用的基本原理
Linux系统调用兼容POSIX,也是一套C语言函数的名字。然而,Linux系统调用的内部实现类似DOC INT 21H。它进入国际0x80h软中断后,它是根据系统调用号分类。
从系统分析的角度来看,Linux系统调用涉及4个方面。
(1)与系统调用相关的数据结构和功能
函数名是sys_第一,其次是系统调用的名称。例如,该系统调用fork的响应函数()()()是sys_fork(见核/叉。C),和出口的响应函数()是sys_exit()(见核 /叉C)。
文件: / / unisted ASM。H指定唯一的数量为每个系统调用。假设系统调用的名字所代表的名字,然后系统调用号和系统调用响应函数之间的关系是:用系统调用号_nr_name作为下标,我们可以找到系统调用表sys_call_table。
拱 / / /进入i386内核。S)的相应表项的内容,这正是对系统调用的响应函数的入口地址sys_name系统整定。
表sys_call_table用于表中记录每个sys_name功能定位,共有190项。这张表,很容易调用特定的系统
表中的偏移量查找相应的系统调用响应函数的入口地址。系统调用表由256个项目组成,其余的项目是系统调用空间,可以由用户自己添加。
(2)进程的系统调用命令转换为int 0x80中断处理
宏定义_syscalln()看到包括 / / unisted ASM。h)用于系统调用的格式转换和参数传递,以整数之间的0 ~ 5。
一个参数n负责格式转换和_syscalln参数传递()系统调用,系统调用号放在eax中登记,和int 0x80开始
之后,需要将返回值EAX登记。
(3)系统调用功能模块的初始化
系统调用的初始化也是int。
0x80的初始化,系统启动的时候,汇编子程序setup_idt(见弓 / / /头i386内核的)准备1 256项IDT表,
start_kernel()(参见初始化 /主。C),trap_init()(见
拱 / / /陷阱i386内核。C)的调用C语言的宏定义
set_system_gate(0x80,system_call)(见: / / ASM系统。H)设置0x80号软中断服务程序为system_call(见
拱 / / /进入i386内核的),system.call是所有系统的总入口调用。
(4)内核如何调用各种系统的服务
当一个进程需要进行系统调用时,系统调用命令必须以C语言函数的形式编写。
它是由相应的_syscalln扩大(),和用户程序必须包含文件。当进程执行用户程序的系统调用命令,它实际上是控股
一个函数的宏命令_syscalln扩大()执行,系统调用的参数都是由通用寄存器传递,那么int 0x80被执行,和内芯的状态进入。
入口地址system_call。
(5)ret_from_sys_call
与ret_from_sys_call入口汇编程序段中的Linux进程管理起着非常重要的作用。在所有系统结束电话和大部分的中断服务的回报,他们会跳到入口地址到这个地方。该程序不仅是服务的系统调用,它也处理中断嵌套,CPU调度、信号和其他交易。
2。通过修改内核源代码来添加系统调用
通过对linux系统调用过程的分析,
将自己的系统调用添加到内核很容易,下面描述了一个真正的系统调用。
并将其添加到内核的系统调用将增加:inttestsyscall(),其功能是在控制终端屏幕显示hello world。
当执行成功时,返回0。
1写inttestsyscall()系统调用
写一个系统调用方式为内核添加1的功能,把新的功能到文件内核/ sys.c.the新功能的代码如下:
asmlingkage sys_testsyscall()
{ console_print(你好世界);
返回0;
}
2连接新系统调用
在编写新的系统调用过程之后,下一个任务是让内核的其余部分知道程序的存在,然后重新构建包含新系统调用的内核:
1)。包括 / / unistd ASM。h文件中添加
# define_nr_testsyscall 191
2)。是 / / /进入i386内核。这个文件是用来初始化指针的数组,该文件中增加一行:
长symbol_name(_sys_tsetsycall)。
改变。报告nr_syscalls-190到nr_syscalls-191,然后奖励并再次运行新的内核。
3)。使用新的系统调用
在有保证的C语言库中,没有新的系统调用程序部分,您必须按照如下方式构建自己的代码
#分
_syscall0(int,testsyscall)
主要()
{
tsetsyscall();
}
这里我们使用_syscall0()宏指令。宏指令本身将扩大到()系统调用程序中的函数,它会调用内部的主要()函数。
在testsyscall()函数,预处理器产生所有必要的机器指令代码,包括加载相应的CPU寄存器和系统调用的参数值,然后执行int。
0x80中断指令。
三.使用内核模块添加系统调用
该模块是内核的一部分,但尚未编译到内核中,它们被编译并连接到一组目标文件中,这些文件可以插入到正在运行的内核中或从正在运行的内核中删除。内核模块必须至少有2个函数:
int_module和cleanup_module.the第一函数在模块插入内核。
在删除模块时,调用第二个函数,因为内核模块是内核的一部分,可以访问所有的内核资源,并在分析Linux系统调用机制的基础上,
如果你想增加系统调用,你可以编写你自己的函数来实现它,然后在sys_call_table表添加一个项目,所以在这项指针指向你写的函数。
系统调用可以实现。下面的方法用于对控制终端打印你好world系统调用testsyscall()。
1)编写系统调用内核模块
#包括(Linux /内核。H)
#包括(Linux /模块。H)
#包括(Linux / modversions。H)
#包括(Linux/sched。H)
#包括(ASM / uaccess。H)
# define_nr_testsyscall 191
外部空间* sys_call +表{ };
Asmlinkage int testsyscall()
{ printf(你好世界);
返回0;
}
init_module int()
{ sys_call_table { } = testsyscall _nr_tsetsyscall;
printf(系统调用testsyscall()加载successn );
返回0;
}
cleanup_module(无效)
{
}
2)使用新的系统调用#定义
# define_nr_testsyscall 191
_syscall0(int,testsyscall)
主要()
{
testsyscall();
}
3)编译内核模块并插入内核。
命令来编译内核是:GCC壁- 02 - dmodule - d_kernel_ C C系统调用。
-墙通知编译器显示警告信息;参数02是关于代码优化的设置,内核模块必须优化;
参数d_lernel通知单头文件向内核模块提供正确的定义;参数d_kernel_通知头文件,
这个程序的代码将运行在内核模式。经过编译成功,系统调用。0文件将生成,最后使用insmod
系统调用的命令将模块到内核使用添加系统调用。
通过以上两种方法的比较,作者认为使用核模块的方法比较好,节省了编译新内核和重新启动内核的麻烦。这种优势对于调试代码非常有价值,而且可以节省很多时间。
Linux系统调用兼容POSIX,也是一套C语言函数的名字。然而,Linux系统调用的内部实现类似DOC INT 21H。它进入国际0x80h软中断后,它是根据系统调用号分类。
从系统分析的角度来看,Linux系统调用涉及4个方面。
(1)与系统调用相关的数据结构和功能
函数名是sys_第一,其次是系统调用的名称。例如,该系统调用fork的响应函数()()()是sys_fork(见核/叉。C),和出口的响应函数()是sys_exit()(见核 /叉C)。
文件: / / unisted ASM。H指定唯一的数量为每个系统调用。假设系统调用的名字所代表的名字,然后系统调用号和系统调用响应函数之间的关系是:用系统调用号_nr_name作为下标,我们可以找到系统调用表sys_call_table。
拱 / / /进入i386内核。S)的相应表项的内容,这正是对系统调用的响应函数的入口地址sys_name系统整定。
表sys_call_table用于表中记录每个sys_name功能定位,共有190项。这张表,很容易调用特定的系统
表中的偏移量查找相应的系统调用响应函数的入口地址。系统调用表由256个项目组成,其余的项目是系统调用空间,可以由用户自己添加。
(2)进程的系统调用命令转换为int 0x80中断处理
宏定义_syscalln()看到包括 / / unisted ASM。h)用于系统调用的格式转换和参数传递,以整数之间的0 ~ 5。
一个参数n负责格式转换和_syscalln参数传递()系统调用,系统调用号放在eax中登记,和int 0x80开始
之后,需要将返回值EAX登记。
(3)系统调用功能模块的初始化
系统调用的初始化也是int。
0x80的初始化,系统启动的时候,汇编子程序setup_idt(见弓 / / /头i386内核的)准备1 256项IDT表,
start_kernel()(参见初始化 /主。C),trap_init()(见
拱 / / /陷阱i386内核。C)的调用C语言的宏定义
set_system_gate(0x80,system_call)(见: / / ASM系统。H)设置0x80号软中断服务程序为system_call(见
拱 / / /进入i386内核的),system.call是所有系统的总入口调用。
(4)内核如何调用各种系统的服务
当一个进程需要进行系统调用时,系统调用命令必须以C语言函数的形式编写。
它是由相应的_syscalln扩大(),和用户程序必须包含文件。当进程执行用户程序的系统调用命令,它实际上是控股
一个函数的宏命令_syscalln扩大()执行,系统调用的参数都是由通用寄存器传递,那么int 0x80被执行,和内芯的状态进入。
入口地址system_call。
(5)ret_from_sys_call
与ret_from_sys_call入口汇编程序段中的Linux进程管理起着非常重要的作用。在所有系统结束电话和大部分的中断服务的回报,他们会跳到入口地址到这个地方。该程序不仅是服务的系统调用,它也处理中断嵌套,CPU调度、信号和其他交易。
2。通过修改内核源代码来添加系统调用
通过对linux系统调用过程的分析,
将自己的系统调用添加到内核很容易,下面描述了一个真正的系统调用。
并将其添加到内核的系统调用将增加:inttestsyscall(),其功能是在控制终端屏幕显示hello world。
当执行成功时,返回0。
1写inttestsyscall()系统调用
写一个系统调用方式为内核添加1的功能,把新的功能到文件内核/ sys.c.the新功能的代码如下:
asmlingkage sys_testsyscall()
{ console_print(你好世界);
返回0;
}
2连接新系统调用
在编写新的系统调用过程之后,下一个任务是让内核的其余部分知道程序的存在,然后重新构建包含新系统调用的内核:
1)。包括 / / unistd ASM。h文件中添加
# define_nr_testsyscall 191
2)。是 / / /进入i386内核。这个文件是用来初始化指针的数组,该文件中增加一行:
长symbol_name(_sys_tsetsycall)。
改变。报告nr_syscalls-190到nr_syscalls-191,然后奖励并再次运行新的内核。
3)。使用新的系统调用
在有保证的C语言库中,没有新的系统调用程序部分,您必须按照如下方式构建自己的代码
#分
_syscall0(int,testsyscall)
主要()
{
tsetsyscall();
}
这里我们使用_syscall0()宏指令。宏指令本身将扩大到()系统调用程序中的函数,它会调用内部的主要()函数。
在testsyscall()函数,预处理器产生所有必要的机器指令代码,包括加载相应的CPU寄存器和系统调用的参数值,然后执行int。
0x80中断指令。
三.使用内核模块添加系统调用
该模块是内核的一部分,但尚未编译到内核中,它们被编译并连接到一组目标文件中,这些文件可以插入到正在运行的内核中或从正在运行的内核中删除。内核模块必须至少有2个函数:
int_module和cleanup_module.the第一函数在模块插入内核。
在删除模块时,调用第二个函数,因为内核模块是内核的一部分,可以访问所有的内核资源,并在分析Linux系统调用机制的基础上,
如果你想增加系统调用,你可以编写你自己的函数来实现它,然后在sys_call_table表添加一个项目,所以在这项指针指向你写的函数。
系统调用可以实现。下面的方法用于对控制终端打印你好world系统调用testsyscall()。
1)编写系统调用内核模块
#包括(Linux /内核。H)
#包括(Linux /模块。H)
#包括(Linux / modversions。H)
#包括(Linux/sched。H)
#包括(ASM / uaccess。H)
# define_nr_testsyscall 191
外部空间* sys_call +表{ };
Asmlinkage int testsyscall()
{ printf(你好世界);
返回0;
}
init_module int()
{ sys_call_table { } = testsyscall _nr_tsetsyscall;
printf(系统调用testsyscall()加载successn );
返回0;
}
cleanup_module(无效)
{
}
2)使用新的系统调用#定义
# define_nr_testsyscall 191
_syscall0(int,testsyscall)
主要()
{
testsyscall();
}
3)编译内核模块并插入内核。
命令来编译内核是:GCC壁- 02 - dmodule - d_kernel_ C C系统调用。
-墙通知编译器显示警告信息;参数02是关于代码优化的设置,内核模块必须优化;
参数d_lernel通知单头文件向内核模块提供正确的定义;参数d_kernel_通知头文件,
这个程序的代码将运行在内核模式。经过编译成功,系统调用。0文件将生成,最后使用insmod
系统调用的命令将模块到内核使用添加系统调用。
通过以上两种方法的比较,作者认为使用核模块的方法比较好,节省了编译新内核和重新启动内核的麻烦。这种优势对于调试代码非常有价值,而且可以节省很多时间。
声明:本文内容用于数码产品信息整理与选购参考,具体价格、库存、售后政策以官方渠道和电商页面实时信息为准。