操作系统的接口
- 什么是操作系统接口:
操作系统接口的实现:
为什么不能直接访问,内核中的代码:不安全
内存被分程内核态和用户态对应内核段和用户段
如何不让进去:通过权限检查的方式
_syscall3(int ,write,int,fd,const char* buf,off_t,count)解释:3表示有三个参数,括号中第一个空表示返回值类型,第二个空表示系统调用为哪个,第三个空表示第一个参数的类型,第四个空表示第一个参数的名字
将上面的_syscall3(int ,write,int,fd,const char* buf,off_t,count)展开
int write(int fd,const char* buf,off_t,count){
long _res;定义一个变量
__asm__volatile("int 0x80":"=a"(_res):"a"(_NR_write),"b"((long),(a)),"c"((long),(b)),"d"((long),(c)));
if(_res>=0) return (int) _res);
errno=-_res; return -1;
}
执行0x80中断,返回值eax存放在_res中,调用的是_NR_write这个中断存放到eax中,
后面就是参数的赋值,如果返回值大于0就将返回值返回,否则就将errno置为_res的绝对值,
这个是一个全局变量,
存放了调用x86中断错误后的错误码,再return -1,也就是c语言常见的返回-1表示该函数使用失败。
通过c语言宏展开来实现具体的write函数
int指令查询idt表:
在系统的_ init _中使用了set_system_gate(0x80,&system_call);这样的设置表示在Idt表中将0x80对应的中断处理函数地址写入对应表项。调用了 _set_gate(&idt[n],15,3,addr)函数
对于_set_gate()函数的定义是也就是填写对应的idt表,将段选择符置为0x0008,将处理函数入口填好,将DPL置为3,这也让加入内核变成可能。
因此,当我们调用了一个api,cs变为了idt中的段选择符,ip变成了处理函数入口偏移。也就是中断处理程序
内核数据表示使用了内核的数据段。在_sys_call_table来找对应系统调用号对应的函数入口地址。