围绕两个问题:
- 用户应用程序调用系统函数能不能直接访问内核函数?
- 应用程序进行系统调用时,如何才能进入内核访问对应函数?
操作系统提供的系统函数和用户应用程序都在内存中
为什么要执行中断而不能直接访问?
因为在内存中应用程序和内核之间存在隔离,分有内核态和用户态;
如果没有隔离,应用程序就有可能会破坏底层数据,造成操作系统不安全。
当内核态被访问时,操作系统通过段寄存器判断特权级来决定访问权限
只有(DPL(Descriptor Privilege Level)>=CPL(Current Privilege Level)),才可以进入内核态。
内核态在操作系统初始化时DPL被置成0,用户态为3。数字越小特权级越大。
应用程序要访问内核时,它的CPL就为3,所以不能直接进入内核。
所以,在用户调用一个printf函数后,发生了什么事?
- 用户函数通过库函数展开成包含int指令(interrupt 中断)(int 0x80)的汇编指令进入内核态(改变DPL、CPL)
- 通过int 0x80执行系统初始化时设定好的中断处理程序system_call()
- 中断处理程序中查一个全局函数数组sys_call_table
- 对应调用函数下标_NR_write=4,调用数组中函数sys_write(功能实现)