就是用户空间应用程序和内核提供的服务之间的一个插口。因为服务是在内核中提供的,因而未能执行直接调用;相反,您必须使用一个进程来跨越用户空间与内核之间的界限。在特定构架中实现此功能的方式会有所不同。为此,本文将着眼于最通用的构架——i386。
在本文中,我将探究LinuxSCI,演示怎么向2.6.20内核添加一个系统调用,之后从用户空间来使用这个函数。我们还将研究在进行系统调用开发时十分有用的一些函数,以及系统调用的其他选择。最后,我们将介绍与系统调用有关的一些辅助机制,例如在某个进程中跟踪系统调用的使用情况。
SCI
Linux中系统调用的实现会依照不同的构架而有所变化,但是虽然在某种给定的体构架上也会不同。诸如,初期的x86处理器使用了中断机制从用户空间迁移到内核空间中,不过新的IA-32处理器则提供了一些指令对这些转换进行优化(使用sysenter和sysexit指令)。因为存在大量的方式,最终结果也十分复杂,因而本文将着力于插口细节的表层讨论上。
要对Linux的SCI进行改进,您不须要完全理解SCI的内部原理,为此我将使用一个简单的系统调用进程(请参看图1)。每位系统调用都是通过一个单一的入口点多路传入内核。eax寄存器拿来标示应该调用的某个系统调用,这在C库中做了指定(来自用户空间应用程序的每位调用)。当加载了系统的C库调用索引和参数时,都会调用一个软件中断(0x80中断),它将执行system_call函数(通过中断处理程序)linux内核空间访问用户空间linux重启命令,这个函数会根据eax内容中的标示处理所有的系统调用。在经过几个简单测试以后,使用system_call_table和eax中包含的索引来执行真正的系统调用了。从系统调用中返回后,最终执行syscall_exit,并调用resume_userspace返回用户空间。之后继续在C库中执行,它将返回到用户应用程序中。
图1.使用中断方式的系统调用的简化流程
SCI的核心是系统调用多路分解表。这个表如图2所示,使用eax中提供的索引来确定要调用该表中的那个系统调用(sys_call_table)。图中还给出了表内容的一些样例,以及那些内容的位置。(有关多路分解的更多内容,请参看侧栏“系统调用多路分解”)
图2.系统调用表和各类链接
添加一个Linux系统调用
添加一个新系统调用主要是一些程序性的操作,但应当注意几件事情。本节将介绍几个系统调用的构造linux内核空间访问用户空间,进而展示它们的实现和用户空间应用程序对它们的使用。
向内核中添加新系统调用redhat linux 9.0下载,须要执行3个基本步骤:
添加新函数。更新头文件。针对这个新函数更新系统调用表。
注意:这个过程忽视了用户空间的需求,我将稍后介绍。
最常见的情况是,您会为自己的函数创建一个新文件。不过,为了简单起见,我将自己的新函数添加到现有的源文件中。清单1所示的前两个函数,是系统调用的简单示例。清单2提供了一个使用表针参数的稍稍复杂的函数。
清单1.系统调用示例的简单内核函数
asmlinkage long sys_getjiffies( void )
{
return (long)get_jiffi
文章评论