【问题标题】:Understanding higher level call to systemcalls了解对系统调用的更高级别调用
【发布时间】:2017-09-02 07:14:21
【问题描述】:

我正在阅读 Galvin 关于 OS 的书。在第 2 章的末尾有一节,作者写到“向内核添加系统调用”。

他描述了如何使用 asmlinkage 创建一个包含函数的文件,并使其符合系统调用的条件。但在下一部分关于如何调用系统调用中,他写了以下内容:

" 不幸的是,这些是无法使用 C 语言语句执行的低级操作,而是需要汇编指令。幸运的是,Linux 提供了用于实例化包含适当汇编指令的包装函数的宏。例如,以下C 程序使用 _syscallO() 宏来调用新定义的系统调用:

基本上,我想了解 syscall() 函数的一般工作原理。现在,我对宏的理解是一个文本替换系统。 (如果我错了请纠正我) 宏如何调用汇编语言指令? 编译时是否将 syscallO() 转换为指令的地址(操作码)以执行陷阱?(但这不知何故不符合我所拥有的宏的概念或定义) 里面包含的包装函数到底是什么,它们也是用汇编语言编写的吗?

假设,我想创建一个自己的函数来执行系统调用,那么我需要做什么。是否,我需要编译它来生成执行Trap指令的机器码?

【问题讨论】:

    标签: operating-system system-calls


    【解决方案1】:

    伙计,你必须支付 156 美元才能读完这本书。您可能会以不到 30 美元的价格获得一本 VMS 内部结构和数据结构的书籍。

    也就是说,让我试着把那些乱七八糟的东西翻译成英文。

    系统调用不使用与其他函数相同的链接(即传递参数和调用函数的方法)。

    不是执行某种调用指令,而是执行系统服务,而是触发一个异常(在 Intel 中,它被称为中断)。 p>

    CPU 期望操作系统创建一个 DISPATCH TABLE 并将其位置和大小存储在一个特殊的硬件寄存器中。调度表是一个指向异常和中断处理程序的指针数组。

    异常和中断都有编号,因此,当异常或中断编号 #1 发生时,CPU 会在内核模式下调用调度表中的 2d 异常处理程序(不是 #0,而是 #1)。

    其中包含的包装函数到底是什么?它们也是用汇编语言编写的吗?

    操作系统通常为系统服务提供一个(但有时更多)异常。你需要用汇编语言做一些这样的事情来调用系统服务:

    INT $80 ; Explicitly trigger exception 80h 
    

    因为您必须执行特定指令,所以它必须是汇编语言。也许您的 C 编译器可以在线执行汇编语言来调用这样的系统服务。但即使可以,每次您想调用系统服务时都必须这样做,这将是一个皇家 PITA。

    另外我这里没有填写所有细节(只是对系统服务的实际调用)。通常,当您在 C(或其他)中调用函数时,参数会被压入程序堆栈。由于进入内核模式时堆栈通常会发生变化,因此系统调用的参数需要存储在寄存器中。

    另外,您需要确定要执行的系统服务。通常,系统服务有编号。系统服务的编号被加载到第一个寄存器中(例如,R0 或 AX)。

    需要调用系统服务时的完整流程是:

    1. 将要覆盖的寄存器保存在堆栈中。
    2. 将要传递给系统服务的参数加载到硬件寄存器中。
    3. 将系统服务的编号加载到最低的寄存器中。
    4. 触发异常进入内核模式。
    5. 从寄存器中卸载系统服务返回的参数
    6. 可能会做一些错误检查
    7. 恢复您之前保存的寄存器。

    操作系统不是每次调用系统服务时都这样做,而是为高级语言提供包装函数以供使用。您可以像通常调用函数一样调用包装器。包装器(用汇编语言)为您完成上述步骤。

    因为这些包装器几乎相同(通常唯一的区别是参数数量不同的结果),所以可以使用宏来创建包装器。一些汇编器具有强大的宏工具,允许单个宏定义所有包装器,即使参数数量不同。

    Linux 提供了多个创建包装器的 _syscall C 宏。每个参数数量都有一个。请注意,这些宏仅适用于操作系统开发人员。一旦有了包装器,每个人都可以使用它。

    宏如何调用汇编语言指令?

    这些 _syscall 宏必须生成行内汇编代码。

    最后,请注意,这些包装器并未定义实际的系统服务。这必须在调度表和系统服务异常处理程序中设置。

    【讨论】:

    • 3344003:前两个问题。“CPU 期望操作系统创建一个调度表。”。这是否意味着 CPU 的设计是在期望操作系统监督其上的进程的情况下完成的?这个调度表是否总是在运行时创建的?
    • @3344003 : 对 VMS INternals 书有什么建议吗?
    • 一个 PeeCee,bios 在启动时创建一个调度表。然后操作系统会构建一个新的并替换 bios 中的那个。该表是静态的。一个操作系统启动,它不会改变。
    • @user3334003 :您能否解释一下“内联”汇编代码的确切含​​义以及“C 编译器可以内联汇编语言以调用系统服务”这句话的含义?
    • 一些 C 编译器允许您在源文件中散布汇编语言。理论上,您可以使用此功能直接从 C 源代码调用系统服务。但是,这很容易出错,需要了解汇编语言,并且需要复制大量代码。
    猜你喜欢
    • 2014-03-26
    • 1970-01-01
    • 2023-03-18
    • 2020-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-08
    相关资源
    最近更新 更多