POSIX 是系统调用的————操作系统的标准
程序只有通过门(gate)陷入(trap)到内核调用中去,实际上是通过0x80中断进入的
0)概念:
mode switch & context switch 前者简单,只是进行寄存器上下文切换
page, frame, segment
逻辑地址 = 选择子 : offset,选择子= 索引:TI:RPL GDT(Global Descriptor Table) & LDT
逻辑地址到线性地址的转换
中断,异常和陷入的区别
1)堆栈的切换 SAVE_ALL,RESTORE_ALL, eax的重要性(指明了那个系统调用)
2)sys_call_table,定义了系统调用的
3)ebx存储了核心栈的位置,-8192 就是task_struct的位置
4)两个用汇编语言写的函数:system_call 和restore_all
5)设置了中断门,陷入门,调用门
trap_init{
... ...
set_system_gate(SYSCALL_VECTOR,&system_call);
}
6)include/asm-i386/unistd.h定义了所有的系统调用
7)C语言的库函数定义了一些宏,把系统调用都展开了。变成了汇编语言的中断处理函数。这里需要提到的是,在gcc中如何加入汇编
asm volatile ( "movl %1, int 0x80"
:"=a" (resultvar)
:"i"(__NR##name)
8)系统调用的参数传递,都放入寄存器中,然后内核可以访问寄存器得到
9)glibc 会用到自己的函数展开
10)添加一个系统调用(需要在很多地方添加声明),如果传递的参数大于6个,可以传递地址,因为在内核中,所以可以访问用户区的内容。常用的函数:verfify_area(), memcpy_fromfs ...
C函数的头文件/usr/include/linux和/usr/include/asm,和内核的头文件/usr/src/include/linux和/usr/src/linux/include/asm是不一样的
注意开关中断的问题,copy_to_user都会sleep所以不要关闭中断