Linux 0.11 系统调用学习
通过增加一个系统调用来了解系统调用的实现原理。(增加 int fun(void))
1.在Include->unistd.h 中加入 #define __NR_fun 72;
加入系统函数调用声明‘ int fun(void);
2. 在Include->Linux->sys.h 加入系统函数声明extern int sys_ fun ();
在指针数组fn_ptr sys_call_table[]初试化中加入sys_ fun项
3.int sys_ fun ()可在任意文件中实现。
4.在需要调用int fun(void)的地方声明static inline _syscall0(int, fun)
然后就可以调用fun();
补充:
1.Typedef int (*fn_ptr)();
2.sched.c中的sched_ini中set_system_gate(0x80,&system_call);设置系统调用0x80中断。
其它的一些中断设置在traps.c中的void trap_init(void)中。例set_trap_gate(0,÷_error);
3.C与汇编(AT&T)混合编程
1)在汇编中定义C函数。
例如在traps.c中声明int nmi(void)中 , set_trap_gate(0,& nmi);
在asm.s中实现:
_nmi:
pushl $_do_nmi
jmp no_error_code\
2) 在汇编中调用C函数。
先将C函数需要的参数压栈,然后CALL、JMP函数。函数名前面也要_.
pushl %ecx
call _do_signal
3)在C中嵌入汇编
#define _syscall0(type,name) \
type name(void) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name)); \
if (__res >= 0) \
return (type) __res; \
errno = -__res; \
return -1; \
}
3.在每次系统调用处理函数(通过call _sys_call_table(,%eax,4)调用)执行完后,、
a. 检查当前进程是否就绪,时间片是否用完,否则执行_schedule(重新调度)
b. 检查是否有信号,若有,则调用_do_signal(将信号处理函数地址和其他AX值放到用户堆栈中),待中断退出后立即执行信号处理程序。
阅读(1501) | 评论(0) | 转发(0) |