Chinaunix首页 | 论坛 | 博客
  • 博客访问: 680046
  • 博文数量: 183
  • 博客积分: 9166
  • 博客等级: 中将
  • 技术积分: 1920
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-31 16:17
文章分类

全部博文(183)

文章存档

2010年(159)

2009年(24)

分类:

2009-11-06 20:26:24

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值放到用户堆栈中),待中断退出后立即执行信号处理程序。

 
阅读(1496) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~