第五章读书笔记——系统调用

时间:2022-06-12 16:54:32

第五章 系统调用

    内核提供了用户进程与内核进行交互的一组接口。这些接口让应用程序受限地访问硬件设备,提供了创建进程并与已有进程进行通信的机制,也提供了申请操作系统其它资源的能力。

 

5.1  内核通信

    中间层的作用:

    1.它为用户空间提供了一种硬件的抽象接口

    2.系统调用保证了系统的稳定和安全

    3.使进程运行在虚拟系统中

 

5.2  API,POSIX和C库

    应用程序通过在用户空间实现的API来编程,API并不需要与内核提供的系统调用对应。API可以在各种不同的操作系统上实现,给应用程序提供完全相同的接口,而它们本身在这些系统上的实现却可能迥异。

    应用编程接口是基于POSIX标准的。

    C库实现了Unix系统的主要API,包括标准C库函数和系统调用接口,C库提供了POSIX的绝大部分API

    Unix的系统调用抽象出了用于完成某种确定的目的的函数,这些函数怎么使用不需要内核关心。

 

5.3 系统调用

    要访问系统调用,通常通过C库中定义的函数调用来进行。系统调用最终有一种明确的操作。

    如何定义系统调用:

  • 编译指令 asmlinkage,通知编译器仅从栈中提取该函数的参数。所有的系统调用都需要这个限定词。
  • 函数返回long
  • sys_  命名规则

     系统调用号:在linux中,每个系统调用被赋予一个系统调用号,通过独一无二的号就可以关联系统调用。分配后不可变更,即使系统调用被删除,系统调用号也不能被回收利用。

    系统调用列表:sys_call_table。

    系统调用的性能:linux很短的上下文切换时间和简洁的系统调用

 

5.4系统调用处理程序

    应用程序通过软中断的方式通知内核自己要执行一个系统调用,希望系统切换到内核态。

    软中断:通过引发一个异常来促使系统切换到内核态去执行异常处理程序,此时的异常处理程序实质上就是系统调用处理程序。

    软中断的中断号是128,通过int 0x80指令来触发该中断。这条指令会触发一个异常导致系统切换到内核态并执行128号异常处理程序,而该程序正是系统调用处理程序system_call()。

    系统陷入内核空间时将系统调用号一并传给内核。在x86上,系统调用号是通过eax传给内核的。在陷入内核空间之前,用户空间就把相应系统调用所对应的号放入eax中,这样系统调用处理程序运行后可以从eax中得到数据。

    大部分系统调用需要外部参数传入。在x86-32系统上,ebx,ecx,edx,esi,edi按照顺序存放前五个参数,六个或六个以上时,用一个单独的寄存器存放指向所有这些参数在用户空间地址的指针。返回值存在eax中。

 

5.5 系统调用的实现

    注意可移植性和健壮性。

    验证参数是否合法有效:

  •     检查用户提供的指针是否有效
  •     在用户空间读写数据时检查是否会引起堵塞
  •     检查针对是否有合法权限

 

5.6系统调用上下文

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

    在进程上下文中,内核可以休眠并且可以被抢占。