操作系统课程实验-linux-0-11系统调用
实验二 系统调用
一、一个系统调用的过程
wirite
函数的执行过程
1. write
声明及定义
/* include/unistd.h */ |
/* linux/lib/write.c */ |
此处的_syscall3
为宏定义,在include/unistd.h
文件中
/* include/unistd.h */ |
实际上write
函数的定义为:
int write(int fd, const char *buf, off_t count) |
这里的int 0x80
为关键。Linux
提供了主动进入内核的方法,使用中断。对于Linux
内核来说,中断信号通常分为两类:硬件中断和软件中断(异常)。每个中断是由0-255
之间的一个数字来标识,称为中断号。
INT0-INT31(0x00-0x1F)
由Intel
公司固定设定或保留用INT32-INT47(0x20-0x2F)
对应于8259A
中断芯片的IRQ0-IRQ15
INT128(0x80)
用户程序发出的软件中断,称为系统调用
2. 系统调用函数(int 0x80
中断处理函数)
当执行main
函数时,会初始化好int 0x80
的中断处理函数
执行过程
main()->sched_init()->set_system_gate(0x80,&system_call)
# kernel/system_call.s |
这里的system_call
便是int 0x80
的中断处理函数,调用set_system_gate
会设置IDT(中断描述符表)
最终会执行call sys_call_table(,%eax,4)
3. 实际执行函数
sys_call_table
为一个函数数组,存放着实际执行函数的地址(include/linux/sys.h
),使用系统调用号作为下标(__NR_write = 4
)调用函数。
system_call
会提前把参数(ebx
,ecx
,edx
)push
到堆栈中,当调用时pop
出来的就是当初设置的参数。
/* linux/fs/read_write.c */ |
上述才是我们调用write
函数时,实际执行的函数。
二、自定义系统调用(实验部分)
添加iam()
和whoami()
保存到内核
1. iam()
步骤
- 修改
include/linux/sys.h
参考write
函数,先向函数数组后中添加sys_iam
,以及extern int sys_iam()
- 修改
kernel/system_call.s
将nr_system_calls
加1
- 修改
include/unistd.h
添加功能号__NR_iam = 72
,作为下标访问函数数组 - 使用
iam()
需要定义函数,类似write
,_syscall1(int, iam, const char*, name)
2. whoami()
和iam
相同
3. 代码
相关推荐