linux0.11嵌入汇编,Linux 0.11 系统调用学习

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

你可能感兴趣的:(linux0.11嵌入汇编)