读薄《Linux 内核设计与实现》(3) - 系统调用

这篇文章是《读薄「Linux 内核设计与实现」》系列文章的第 III 篇,本文主要讲了以下问题:系统调用的概念、系统调用的实现原理与过程以及如何在 Linux 中增加一个系统调用。

0x00 系统调用的概念

系统调用是为了和用户空间上的进程进行交互,内核提供的一组界面。

  • 应用程序通过这组界面访问硬件和其他操作系统资源
  • 完成对硬件和资源的访问控制
  • 硬件设备的抽象(提供设备的独立性)

0x01 系统调用简介

I 常用系统调用

  • fork(), exec(), open(), read(), write(), close(),……
  • 目前 Linux 系统调用 300 多个

II 应用程序及系统调用的层次关系

应用程序通过在用户空间实现的 API 而不是直接通过系统调用来编程

例:调用 printf() 函数时,应用程序、C 库和内核的关系:

应用程序调用 printf() -> C 库中的 printf() -> C 库中的 write() -> 内核中的 write() 系统调用

0x02 Linux 系统调用实现原理

I 相关概念

  • int 80H:软中断,通知内核的机制是靠软中断实现的,第128号中断处理程序
  • IVT(Interrupt Vector Table):中断向量表,包括所有中断程序入口地址,它固定存放于内存中(实模式下应用)
  • IDT(Interrupt Descriptor Table):中断描述符表,不固定内存位置,通过 IDTR 寄存器定位该表(保护模式下应用,int 80H 占据其中一项)
  • syscall table:系统调用表
  • 系统调用号: 在 Linux 中,每个系统调用被赋予一个系统调用号,表示它在表中的编号

II 系统调用的加载

操作系统在加载时做的有关系统调用的加载:

  • int 80H 处理程序地址的加载:start_kernel()中的 trap_init()和 set_system_gate()
  • 各系统调用处理程序的加载(entry.s)

III 系统调用过程(以 x86 为例)

首先,通过软中断陷入到 int 80h 中断中,促使系统切换到内核态去执行异常处理程序(系统调用处理程序);之后,系统通过读取 eax 寄存器的值来获取系统调用号;之后,系统通过读取寄存器来获取传递的参数(ebx, ecx, edx, esi, edi)按照顺序存放前五个参数,如果参数为6个或以上,则将其中一个寄存器的值指向内存空间;最后,执行相应系统调用代码,完成系统调用

IV 系统调用的参数验证

系统调用必须仔细检查他们所有参数是否合法有效,如果用户将不合法的参数传递给内核,那么系统的安全和稳定将面临极大考验。

  • 权限验证:系统调用的调用者可以使用 capable() 函数来检查是否有权能对制定的资源进行操作
  • 指针合法性验证:在接受一个用户空间的指针之前,内核需要验证:
    • 指针指向的内存区域属于用户空间
    • 指针指向的内存区域在进程的地址空间里
    • 如果是读,该内存应被标记为可读;如果是写,该内存应被标记为可写;如果是可执行,进程决不能绕过内存访问限制

0x03 如何增加一个系统调用

  • 增加系统调用函数(/kernel/sys.c)
  • 把系统调用函数入口添加到 sys_call_table(entry.s)
  • 添加系统调用号

0x04 系统调用的意义

  • 它为用户提供了一种硬件的抽象接口
  • 在保证系统稳定和安全的前提下提供服务,避免应用程序恣意横行

本文的版权归作者 罗远航 所有,采用 Attribution-NonCommercial 3.0 License。任何人可以进行转载、分享,但不可在未经允许的情况下用于商业用途;转载请注明出处。感谢配合!

时间: 2024-08-07 21:20:37

读薄《Linux 内核设计与实现》(3) - 系统调用的相关文章

Linux内核设计第四周——扒开系统调用三层皮

Linux内核设计第四周--扒开系统调用三层皮 by苏正生 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.知识点整理 1.用户态 内核态和中断处理程序 我们一般使用系统调用一般通过库函数的方式 用户态和内核态的区分: [CPU有不同的执行级别,高执行级别下,代码可以执行特权指令,访问任何的物理地址:低执行级别下,就会受到一定的限制.(处于系统安全和稳定的目的)Intel X86 C

linux内核设计与实现--进程调度 系统调用

进程可以分为I/O消耗型和处理器消耗型. I/O消耗型指,进程的大部分时间用来提交I/O请求或者等待I/O请求. 处理器耗费型进程把时间大多用在执行代码上. linux采用了两种不同的优先级范围: 第一种:用nice值,范围为-20到+19.默认值为0,值越大意味着优先级越低. 第二种:实时优先级,其值是可配置的,默认情况下它的范围是从0到99.与nice值的意义相反,值越高优先级越高. asmlinkage限定词,这是一个编译指令,通知编译器仅从栈中提出该函数的参数.所有的系统调用都需要这个限

读薄「Linux 内核设计与实现」(2) - 进程管理和调度

这篇文章是<读薄「Linux 内核设计与实现」>系列文章的第 II 篇,本文主要讲了以下问题:进程管理的任务.进程管理与其他模块的依赖关系.进程描述符和任务队列.进程的创建.线程的实现.进程的终止.进程调度. 0x00 进程管理的任务 进程能创建新的进程(通过复制现有进程) 确定哪个进程能拥有 CPU 接受中断并将中断导向相应的内核子系统 管理时钟硬件 当一个进程结束时释放其资源 动态装载执行模块 0x01 进程管理与其他模块的依赖关系 I 进程模块的内外界面 对用户进程提供了一组简单的系统调

读薄《Linux 内核设计与实现》(4) - 中断与同步

这篇文章是<读薄「Linux 内核设计与实现」>系列文章的第 IV 篇,本文主要讲了以下问题:中断和中断处理程序的概念与实现原理.Linux 中的下半部以及内核同步方法. 0x00 中断和中断处理程序 I 中断 中断是一种特殊的电信号,由硬件发向处理器,处理器接收到中断时,会马上箱操作系统反映,由操作系统进行处理.中断随时可以产生,因此,内核随时可能因为新到来的中断而被打断. 不同的设备对应的中断不同,每个中断通过一个唯一的数字标识,这些中断值通常被称为中断请求(IRQ)线. II 中断处理程

linux内核设计与实现 系统调用

系统调用的实现过程:触发软终端,调用系统调用处理函数:在处理函数中,从寄存器中读取系统调用号以及参数,根据系统调用号,读取系统调用表:系统调用号就是系统调用函数的位置,取该位置值,就找到真正的系统调用函数,最后执行. arm系统调用:r0-r5传递参数 r0保存返回值 系统调用的绑定过程: 1.系统调用函数asmlinkage 2.在系统调用表中添加系统调用 3.在asm/unistd.h中添加系统调用号 4.编译内核 即可 系统调用使用:1.包含系统调用实现文件 或者2._syscallN()

读薄「Linux 内核设计与实现」(1) - 从内核出发

这篇文章是<读薄「Linux 内核设计与实现」>系列文章的第一篇,本文主要讲了两个问题:内核编程的特点以及 GNU C 在内核开发中的特点. 0x00 内核编程特点 无 libc 库,不能访问标准 C 文件 使用 GNU C 无内存保护机制 慎用浮点数计算 注意同步和并发 可移植性考虑:保持字节顺序.64位对齐.不假定字长和页面长度 0x01 GNU C 内联函数:将函数展开至调用位置,省却函数调用代价 内联汇编:在确定体系结构的情况下,在 C 代码中直接嵌入汇编代码 分支声明:分支时可根据预

linux及安全《Linux内核设计与实现》第一章——20135227黄晓妍

<linux内核设计与实现>第一章 第一章Linux内核简介: 1.3操作系统和内核简介 操作系统:系统包含了操作系统和所有运行在它之上的应用程序.操作系统是指整个在系统中负责完成最基本功能和系统管理的那些部分.这些部分包括内核.设备驱动程序.启动应到程序.命令行shell或者其他种类的用户界面.基本的文件管理系统工具. 内核:如果说用户界面是操作系统的外在表像,那么内核就是操作系统的内在核心. 内核空间:系统态和保护起来的内存空间. 内核的组成: 1.中断服务程序(响应中断) 2.调度程序(

把握linux内核设计思想系列(未完待续......)

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 把握linux内核设计思想(一):系统调用 把握linux内核设计思想(二):硬中断及中断处理 把握linux内核设计思想(三):下半部机制之软中断 把握linux内核设计思想(四):下半部机制之tasklet 把握linux内核设计思想(五):下半部机制之工作队列及几种机制的选择 把握linux内核设计思想(六):内核时钟中断 把握linux内核设计思想(七):内核定时器和

《Linux内核设计与实现》 Chapter4 读书笔记

<Linux内核设计与实现> Chapter4 读书笔记 调度程序负责决定将哪个进程投入运行,何时运行以及运行多长时间,进程调度程序可看做在可运行态进程之间分配有限的处理器时间资源的内核子系统. 一.多任务 多任务操作系统就是能同时并发地交互执行多个进程的操作系统. 多任务系统可以划分为两类: 非抢占式多任务 进程会一直执行直到自己主动停止运行 抢占式多任务 Linux/Unix使用的是抢占式的方式:强制的挂起进程的动作就叫做抢占. 像所有unix的变体和许多其他现代操作系统一样,Linux提