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

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

一、与内核通信

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

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

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

二、API

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

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

三、系统调用

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

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

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

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

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

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

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

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

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

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

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

四、系统调用上下文

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

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

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

ABI 为应用程序二进制接口。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/76405.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ModStartBlog v8.0.0 博客归档页面,部分组件升级

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用,支持后台一键快速安装,让开发者能快的实现业务功能开发。 系统完全开源,基于 Apache 2.0 开源协议。 功能特性 丰富的模块市场,后台一键快速安装会…

Harvard transformer NLP 模型 openNMT 简介入门

项目网址: OpenNMT - Open-Source Neural Machine Translation logo: 一,从应用的层面先跑通 Harvard transformer GitHub - harvardnlp/annotated-transformer: An annotated implementation of the Transformer paper. ​git clone https…

在思科(Cisco)路由器中使用 SNMP

什么是SNMP SNMP,称为简单网络管理协议,被发现可以解决具有复杂网络设备的复杂网络环境,SNMP 使用标准化协议来查询网络上的设备,为网络管理员提供保持网络环境稳定和远离停机所需的重要信息。 为什么要在思科设备中启用SNMP S…

使用docker-maven-plugin插件构建镜像并推送至私服Harbor

前言 如下所示,建议使用 Dockerfile Maven 插件,但该插件也停止维护更新了。因此先暂时使用docker-maven-plugin插件。 一、开启Docker服务器的远程访问 1.1 开启2375远程访问 默认的dokcer是不支持远程访问的,需要加点配置,开…

docker的资源控制及docker数据管理

目录 一.docker的资源控制 1.CPU 资源控制 1.1 资源控制工具 1.2 cgroups有四大功能 1.3 设置CPU使用率上限 1.4 进行CPU压力测试 1.5 设置50%的比例分配CPU使用时间上限 1.6 设置CPU资源占用比(设置多个容器时才有效) 1.6.1 两个容器测试cpu 2&…

使用python读Excel文件并写入另一个xls模版

效果如下: 原文件内容 转化后的内容 大致代码如下: 1. load_it.py #!/usr/bin/env python import re from datetime import datetime from io import BytesIO from pathlib import Path from typing import List, Unionfrom fastapi import HTTPExcep…

vue3组件多个根节点报错

打开扩展商店搜索下载 vetur 打开设置命令面板 搜索eslint 将下面的勾选取消

Maven之Servlet 版本问题

maven-archetype-webapp 骨架的 Servlet 版本问题 通过 maven-archetype-webapp 骨架去创建 java web 项目时,自动生成的 web.xml 配置文件所使用的 Servlet 的版本比较低(2.3),而在低版本的 Servlet 中 EL 表达式默认是关闭的。…

计算机竞赛 python的搜索引擎系统设计与实现

0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 python的搜索引擎系统设计与实现 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:5分创新点:3分 该项目较为新颖&#xff…

快速学会创建uni-app项目并了解pages.json文件

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 前言 创建 uni-app 项目 通过 HBuilderX 创建 pages.json pages style globalStyle tabBar 前言…

AD域控制器将辅域控制器角色提升为主域控制器

背景 域控服务器迁移,已将新机器添加为该域的辅域控制器。 主域控制器:test-dc-01 辅域控制器:test-dc-02 需求将主辅域的角色进行互换,test-dc-01更换为辅域,test-dc-02更换为主域。 操作步骤 方法1 命令行修改AD域…

Java版本工程项目管理系统源码-全面的工程项目管理

​ ​工程项目管理系统是指从事工程项目管理的企业(以下简称工程项目管理企业)受业主委托,按照合同约定,代表业主对工程项目的组织实施进行全过程或若干阶段的管理和服务。 如今建筑行业竞争激烈,内卷严重,…