【读书笔记】Linux内核设计与实现(第五章)

5.1 内核通信

系统调用在用户空间和硬件设备之间添加了一个中间层.

该层主要作用:

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

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

3.每个进程都运行在虚拟系统中.

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

 

5.2 APIPOSIXC

一般情况下,应用程序通过在用户空间实现的应用编程接口,而不是直接通过系统调用来编程。

一个API定义了一组应用程序使用的编程接口。

 

 

1.Unix世界中,最流行的应用编程接口是基于POSIX标准的。

POSIX是由IEEE的一组标准组成。

2.C库实现了Unix系统的主要API,包括标准C库函数和系统调用接口。所有的C程序都可以使用C库,而其他语言也可以把他们封装起来使用。

3.Unix接口设计中,“提供机制而不是策略”,Unix系统调用抽象出了完成某种确定目的的函数。

 

5.3系统调用

要访问系统调用,通常通过C库中定义的函数调用来进行。它们通常都需要定义零个、一个或几个参数(输入)而且可能产生一些副作用。

系统调用还会通过一个long类型的返回值来表示成功或者错误。

通常,也不绝对,用一个负的返回值来表明错误。返回一个0值通常表明成功。

系统调用在出现错误的时候C库会把错误码写入error全局变量。通过调用perror()库函数,可以把该量编译成用户可以理解的错误字符串。

 

 

如何定义系统调用?

1.限定词。

2.函数返回。注意返回值类型。

3.系统调用在内核中被定义时有命名规则。Get_pid()sys_getpid()

 

5.3.1 系统调用号

指明要执行哪个系统调用,进程不会提及系统调用的名称。

一旦分配就不能再有变更,否则编译好的程序就会崩溃。

如果一个系统调用被删除,它所占用的系统调用号也不允许被回收利用。

Sys_ni_syscall():除了返回-ENOSYS外不做任何其他工作,这个错误号专门针对无效的系统调用而设的。

 

5.3.2 系统调用的性能

为什么Linux系统调用执行快?

1.Linux的上下文切换时间很短。

2.系统调用处理程序和每个系统调用本身也非常简洁。

 

5.4 系统调用处理程序

用户空间的程序无法直接执行内核代码。

软中断:应用程序通知系统的机制。通过引发一个异常来促使系统切换到内核态去执行异常处理程序。

5.4.1 指定恰当的系统调用

X86中,系统调用号是通过eax寄存器传递给内核的。

5.4.2 参数传递

 

 

x86-32系统上,ebx\ecx\edx\esiedi按照顺序存放前五个参数。

给用户空间的返回值存放在eax寄存器中。

 

5.5 系统调用的实现

5.5.2 参数验证

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

 

内核无论何时都不能轻率的接受来自用户空间的指针!

 

5.6 系统调用上下文

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

 

posted @ 2016-03-24 11:06  ClareOhno  阅读(159)  评论(0编辑  收藏  举报