我正在阅读高尔文在操作系统上的这本书。在第2章末尾有一节,作者写了关于"添加系统调用"到了内核。
他描述了如何使用asmlinkage我们可以创建一个包含函数的文件,并使其符合系统调用的条件。但在接下来的部分中,关于如何调用系统调用,他写了以下内容:
" 不幸的是,这些是使用C语言语句无法执行的低级操作,而是需要汇编指令。幸运的是,Linux提供了用于实例化包含适当汇编指令的包装函数的宏。例如,以下C程序使用_syscallO()宏来调用新定义的系统调用:
基本上,我想了解syscall()函数通常如何工作。现在,我对Macros的理解是一个文本替换系统。 (如果我错了,请纠正我) 宏如何调用汇编语言指令? 这样编译时的syscallO()是否被转换为执行陷阱的指令的地址(操作码)?(但这不符合我所拥有的宏的概念或定义) 包含在内部的包装函数究竟是什么,它们也是用汇编语言编写的?
假设,我想创建一个自己的函数来执行系统调用,那么我需要做些什么。我需要编译它来生成用于执行陷阱指令的机器代码吗?
答案 0 :(得分:0)
男人,你必须支付156美元,然后你实际上必须阅读它。您可能会以低于30美元的价格获得VMS内部和数据结构书。
那就是说,让我试着将那些胡言乱语翻译成英文。
系统调用不使用其他函数使用的相同类型的链接(即传递参数和调用函数的方法)。
执行系统服务时,不是执行某种类型的调用指令,而是触发异常(在英特尔中奇怪地称为 中断 )。
CPU期望操作系统创建DISPATCH TABLE并将其位置和大小存储在特殊的硬件寄存器中。 dispatch表是指向异常和中断的处理程序的指针数组。
异常和中断有数字,当发生异常或中断号#1时,CPU在内核模式下调度表中调用2d异常处理程序(不是#0,但是#1)。
内部包含的包装函数究竟是什么?它们也是用汇编语言编写的?
操作系统通常将一个(但有时更多)的例外用于系统服务。你需要在汇编语言中做一些这样的事情来调用系统服务:
INT $80 ; Explicitly trigger exception 80h
因为您必须执行特定指令,所以必须使用汇编语言。也许你的C编译器可以在线调用汇编语言来调用系统服务。但即使可能,每次你想打电话给系统服务时,都必须要做皇家PITA。
另外,我还没有在这里填写所有细节(只是对系统服务的实际调用)。通常,当您使用C(或其他)调用函数时,参数将被推送到程序堆栈中。因为当你进入内核模式时堆栈通常会改变,所以系统调用的参数需要存储在寄存器中。
PLUS您需要确定要执行的系统服务。通常,系统服务有数字。系统服务的编号被加载到第一个寄存器中(例如,R0或AX)。
需要调用系统服务时的完整过程是:
每次调用系统服务时,操作系统都会提供高级语言的包装函数,而不是这样做。您可以像调用函数一样调用包装器。包装器(使用汇编语言)为您执行上述步骤。
因为这些包装器几乎相同(通常唯一的区别是不同数量的参数的结果),所以可以使用宏创建包装器。一些汇编程序具有强大的宏功能,允许单个宏定义所有包装器,即使使用不同数量的参数。
Linux提供了多个创建包装器的_syscall C宏。每个参数都有一个。请注意,这些宏仅适用于操作系统开发人员。包装器出现后,每个人都可以使用它。
宏如何调用汇编语言指令?
这些_syscall宏必须在行汇编代码中生成。
最后,请注意这些包装器不定义实际的系统服务。必须在调度表和系统服务异常处理程序中设置它。