Linux内核学习(四)—— 系统调用(基于Linux 2.6内核)

这篇具有很好参考价值的文章主要介绍了Linux内核学习(四)—— 系统调用(基于Linux 2.6内核)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在现代操作系统中,内核提供了用户进程与内核进行交互的一组接口,这些接口在应用程序和内核之间扮演了使者的角色。这些接口保证了系统的稳定可靠,避免应用程序肆意妄行。

一、与内核通信

系统调用在用户空间进程和硬件设备之间添加了一个中间层。有三个作用:

  • 第一,它为用户空间提供了一种硬件的抽象接口。举例来说,当需要读写文件的时候,可以不关心磁盘介质和类型,甚至不需要关心文件所在的文件系统。
  • 第二,系统调用保证了系统的稳定和安全。可以避免用户程序不正确的使用硬件设备,窃取其他进程的资源等危害系统的行为。
  • 第三,每个进程都运行在虚拟系统中,如果应用程序可以随意访问硬件而内核又对此一无所知,几乎就没法实现多任务和和虚拟内存。

在 Linux 中,系统调用是用户空间访问内核的唯一手段;除异常和陷入外,它们是内核唯一的合法入口。

二、API

应用编程接口(API,Application Programming Interface)定义了一组应用程序使用的编程接口,它可以使用系统调用实现,也可以不使用:

Linux内核学习(四)—— 系统调用(基于Linux 2.6内核),Linux内核设计与实现,linux,学习,运维

从程序员的角度来看,系统调用无关紧要,他们只需要和 API 打交道就行了。相反,内核只跟系统调用打交道。

三、系统调用

每个系统调用被赋予了一个系统调用号,通过这个独一无二的号就可以关联系统调用。

getpid() 返回的是 tgid(线程组 ID),对于普通的进程来说,TGID 和 PID 相等,对于线程来说,同一线程组内的所有线程及其 TGID 都相等。

Linux 系统调用实现十分简洁。

应用程序通过软中断来通知系统,告诉内核自己需要执行一个系统调用,希望系统切换到内核态,这样内核就可以代表应用程序在内核空间执行系统调用。软中断是通过引发一个异常来促使系统切换到内核态去执行异常处理程序。此时的异常处理程序实际上就是系统调用处理程序

在 x86 上,系统调用号是通过 eax 寄存器传递给内核的(系统调用的返回值也是通过 eax 寄存器传递给用户空间的)。除了系统调用号以外,还需要传入一些其他的参数给内核,同样也是通过寄存器来传递的,ebx、ecx、edx、esi、edi 按顺序存放前五个参数(当大于 6 个的时候就用一个单独的寄存器存放参数在内存中的地址)。

Linux内核学习(四)—— 系统调用(基于Linux 2.6内核),Linux内核设计与实现,linux,学习,运维

在接收一个用户空间的指针之前,内核必须保证:

  • 指针指向的区域属于用户空间。进程不能哄骗内核去读内核空间的数据。
  • 指针指向的内存区域在进程的地址空间里。进程绝不能哄骗内核去读其他进程的数据。
  • 用户必须有被指针访问的内容的相应访问权限。进程绝不能绕过内存访问限制。

内核提供了两个方法来完成必须的检查和内核空间和用户空间之间的数据拷贝:

  • 为了向用户空间写入数据,内核提供了 copy_to_user(),它需要三个参数。第一个参数为进程空间中的目的内存地址,第二个是内核空间内的源地址,最后一个参数为需要拷贝的数据长度(字节数)。
  • 为了从用户空间读数据,内核提供了 copy_from_user(),所需的参数和 copy_to_user() 类似

如果执行失败,这两个函数返回的都是没能完成拷贝的数据字节数。成功则返回 0。这两个函数都可能引起阻塞。当包含用户数据的页被换出到硬盘上而不是在物理内存上的时候,这种情况就会发生。此时进程会休眠,直到缺页处理程序将该页从硬盘重新换回物理内存。

用户可以使用 capable() 函数来检查是否有权能对指定的资源进行操作,返回非 0 值就有权进行操作,反之则无权。

四、系统调用上下文

内核在执行系统调用的时候处于进程上下文,current 指针指向当前任务,即引发系统调用的那个进程。

进程上下文中,内核可以休眠(比如在系统调用阻塞或显式调用 schedule() 的时候)并且可以被抢占。中断处理程序不可休眠。在进程上下文中可以被抢占。因为新的进程可以使用相同的系统调用,所以必须保证该系统调用是可重入的。

当系统调用返回的时候,控制权仍在 system_call() 中,它最终会负责切换到用户空间,并让用户进程继续执行下去。

ABI 为应用程序二进制接口。文章来源地址https://www.toymoban.com/news/detail-661471.html

到了这里,关于Linux内核学习(四)—— 系统调用(基于Linux 2.6内核)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 调试linux内核(2): poll系统调用的实现

    linux内核为用户态进程提供了一组IO相关的系统调用: select/poll/epoll, 这三个系统调用功能类似, 在使用方法和性能等方面存在一些差异. 使用它们, 用户态的进程可以\\\"监控\\\"自己感兴趣的文件描述符, 当这些文件描述符的状态发生改变时, 比如可读或者可写了, 内核会通知进程去处

    2024年02月11日
    浏览(35)
  • Linux--2.6内核调度和环境变量

    📘北尘_ :个人主页 🌎个人专栏 :《Linux操作系统》《经典算法试题 》《C++》 《数据结构与算法》 ☀️走在路上,不忘来时的初心 上图是Linux2.6内核中进程队列的数据结构,之间关系也已经给大家画出来,方便大家理解 如果有多个CPU就要考虑进程个数的负载均衡问题 普通

    2024年02月05日
    浏览(58)
  • Linux内核源码分析 (B.4) 深度剖析 Linux 伙伴系统的设计与实现

    Linux内核源码分析 (B.4) 深度剖析 Linux 伙伴系统的设计与实现 在上篇文章 《深入理解 Linux 物理内存分配全链路实现》 中,笔者为大家详细介绍了 Linux 内存分配在内核中的整个链路实现: image.png 但是当内核执行到 get_page_from_freelist 函数,准备进入伙伴系统执行具体内存分配

    2024年02月07日
    浏览(45)
  • 【Linux 内核源码分析笔记】系统调用

    在Linux内核中,系统调用是用户空间程序与内核之间的接口,它允许用户空间程序请求内核执行特权操作或访问受保护的内核资源。系统调用提供了一种安全可控的方式,使用户程序能够利用内核功能而不直接访问底层硬件。 系统调用: 通过系统调用,用户程序可以请求内核

    2024年02月03日
    浏览(40)
  • 【Linux C】Linux如何执行一个程序(程序存储空间、系统调用、内核调用)

    本节说的空间主要是指内存空间,即程序如何分配和使用内存。 可执行程序,而不是源代码。 C语言程序的存储空间包括以下几个主要部分: 代码段(Text Segment): 也称 正文段 , 代码段是存储C程序的机器代码的区域。它包含了程序的指令集,这些指令由编译器生成,并且

    2024年02月08日
    浏览(47)
  • 《Linux内核源码分析》(2)进程原理及系统调用

    操作系统的作用 :作为硬件的使用层,提供使用硬件资源的能力, 进程的作用 :作为操作系统使用层,提供使用操作系统抽象出的资源层的能力 进程、线程和程序的区别 :进程指计算机中已运行的程序。进程本身不是基本的运行单位,而是线程的容器。 程序本身只是指令

    2024年02月07日
    浏览(47)
  • Linux内核模块vmalloc和kmalloc系统调用的代码实战

    当设备长时间运行后,内存碎片化,很难找到连续的物理页。在这种情况下,如果需要分配长度超过一页的内存块,可以使用不连续页分配器,分配虚拟地址连续但是物理地址不连续的内存块。在 32 位系统中不连分配器还有一个好处:优先从高端内存区域分配页,保留稀缺的

    2023年04月16日
    浏览(36)
  • 杭电操作系统实验一 --- Linux内核编译及添加系统调用(arm架构华为云)

    掌握Linux 内核的编译与安装 掌握Linux 系统调用基本概念 设计和添加linux系统调用         (1)修改或返回指定进程的优先级(nice值和prio值)(详见教材P328)提示:可能参考的内核函数:set_user_nice().         (2)改变主机名称为自定义字符串(自选题目)   1、 L

    2023年04月20日
    浏览(41)
  • 操作系统实验 2.3系统调用:linux-0.11-lab “为版本0内核增加一个系统调用getjiffies” 和 “在用户程序中使用新增的系统调用”

    打开 vscode ,在如图所示位置打开 ~/os/linux-0.11-lab/0 文件夹 1.定义getjiffies系统调用 题目中给的提示:进入到 unistd.h 文件中 阅读代码,可以发现上图划线处有个系统调用名为 getpid :返回当前进程号——这与我们期望实现的功能类似:通过系统调用返回jiffies值。 于是此时希望

    2023年04月08日
    浏览(97)
  • 《Linux 内核设计与实现》10. 内核同步方法

    原子操作:可以保证指令以原子的方式执行,即执行过程不被打断。 原子整数操作 整数的原子操作只针对 atomic_t 类型。因为: 让原子函数只接收 atomic_t 类型的操作数,可以确保原子操作只与这种特殊类型数据一起使用。同时这也保证了该类型的数据不会被传递给任何非原

    2024年02月04日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包