应用程序--------------+
vi/emacs/tftp/firefox |
| |
标准库、 第三方库 |
C/C++ Qt/X11 |
| |
系统调用<------------+
brk/sbrk/mmap/munmap
1、Linux系统内核提供了一套用于实现各种系统功能的子程序,谓之系统调用。程序编写者可以像调用普通C语言函数一样调用这些系统调用函数,以访问系统内核提供的各种服务。
2、系统调用函数在形式上与普通C语言函数并无差别。二者的不同之处在于,前者工作在内核态,而后者工作在用户态。
3、在Intel的CPU上运行代码分为四个安全级别:Ring0、Ring1、Ring2和Ring3。Linux系统只使用了Ring0和Ring3。用户代码工作在Ring3级,而内核代码工作在Ring0级。一般而言用户代码无法访问Ring0级的资源,除非借助系统调用,使用户代码得以进入Ring0级,使用系统内核提供的功能。
4、系统内核内部维护一张全局表sys_call_table,表中的每个条目记录着每个系统调用在内核代码中的实现入口地址。
5、当用户代码调用某个系统调用函数时,该函数会先将参数压入堆栈,将系统调用标识存入eax寄存器,然后通过int 80h指令触发80h中断。
6、这时程序便从用户态(Ring3)进入内核态(Ring0)。
7、工作系统内核中的中断处理函数被调用,80h中断的处理函数名为system_call,该函数先从堆栈中取出参数,再从eax寄存器中取出系统调用标识,然后再从sys_call_table表中找到与该系统调用标识相对应的实现代码入口地址,挈其参数调用该实现,并将处理结果逐层返回到用户代码中。