Linux系统调用------追踪系统调用的执行过程
2017-03-14 20:30
351 查看
王雪 原创作品转载请注明出处 《Linux内核分析》MOOC课程 http://mooc.study.163.com/course/USTC-1000029000
一、基础知识
关于系统调用
系统调用号:内核为每个系统调用定义了一个唯一的编号,这个编号定义在…/include/asm/unisd.h中(最大为NR_syscall)
系统调用表:同时在内核中保存了一张记录系统调用号和其对应服务例程的表,与系统调用表一一对应
在系统调用陷入内核之前,需要把系统调用号一起传入内核,这个标号就是系统调用表的sys_call _ table 下标,这个传递的动作是通过int 0x80实现的,在执行int 0 x80前,将系统调用号保存到eax的寄存器中
系统调用表记录了各个系统调用的服务例程的入口地址,以系统调用号为偏移量找到对应的处理函数地址,执行处理函数。
处理函数结束后,转入ret _ from _ sys _ call ()例程,系统调用返回到用户态
以上便是系统调用的处理过程。
如果我们想在自己的系统里添加自己的自定义的系统调用需要4步:
(1
a59a
)添加系统调用号(unistd.h中)
(2)在系统调用表中添加对应表项
(3)实现系统调用的服务例程
(4)重新编译内核,启动新内核
二、实验内容
(1)向实验楼下Linux-3.18.6的MenuOS菜单中添加time系统调用
为什么open失败呢,因为!在qemu模拟器中,没有文件!!!
(2)跟踪系统调用的过程
进入gdb调试:
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S 冻结qemu,已将cpu冻结
另开一个shell窗口:
(gdb)file linux-3.18.6/vmlinux
(gdb)target remote:1234
(gdb)break start_kernel
(gdb)c
可以看见系统启动时停止在start_kernel处
在系统调用time的内核处理函数sys_time处添加断点,执行n,将MenuOS系统启动起来,这时我们执行time,系统停在断点sys _time处。
我们并不能利用gdb跟踪到sys_time里面的具体执行过程
(3)查看系统调用的实现代码
1.系统调用机制是什么时候初始化的:
在系统启动时执行start_kernel,start _kernel中会调用trap _init()函数, 用于硬件中断向量初始化,这个函数被定义在/arch/x86/kernel/trap.c中,
SYSCALL_VECTOR系统中断向量
system_call:系统调用入口,
当发生中断或系统调用,直接找到system_call入口地址去执行。
2.系统调用的处理过程:
系统调用的定义在/arch/x86/kernel/entry_32.S中,有一个入口
ENTRY(system_call),是int $0x80后的下一条执行地址,
大致流程:
system _ call->sys call _table ->syscall exit(是否处理syscall _ exit _ work) ->restort _all -> irq _return,work _notifying用于处理信号
在系统调用返回前有可能进行进程调度,有可能需要处理当前进程的信号
进行进程调用在work_resched中call schedule;
中断结束后,从内核态返回用户态!
二、实验总结
这次实验主要是分析了系统是怎么响应一个系统调用的,系统调用的执行过程,代码的执行过程等知识,是理解操作系统工作的重要步骤!
一、基础知识
关于系统调用
系统调用号:内核为每个系统调用定义了一个唯一的编号,这个编号定义在…/include/asm/unisd.h中(最大为NR_syscall)
系统调用表:同时在内核中保存了一张记录系统调用号和其对应服务例程的表,与系统调用表一一对应
在系统调用陷入内核之前,需要把系统调用号一起传入内核,这个标号就是系统调用表的sys_call _ table 下标,这个传递的动作是通过int 0x80实现的,在执行int 0 x80前,将系统调用号保存到eax的寄存器中
系统调用表记录了各个系统调用的服务例程的入口地址,以系统调用号为偏移量找到对应的处理函数地址,执行处理函数。
处理函数结束后,转入ret _ from _ sys _ call ()例程,系统调用返回到用户态
以上便是系统调用的处理过程。
如果我们想在自己的系统里添加自己的自定义的系统调用需要4步:
(1
a59a
)添加系统调用号(unistd.h中)
(2)在系统调用表中添加对应表项
(3)实现系统调用的服务例程
(4)重新编译内核,启动新内核
二、实验内容
(1)向实验楼下Linux-3.18.6的MenuOS菜单中添加time系统调用
为什么open失败呢,因为!在qemu模拟器中,没有文件!!!
(2)跟踪系统调用的过程
进入gdb调试:
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S 冻结qemu,已将cpu冻结
另开一个shell窗口:
(gdb)file linux-3.18.6/vmlinux
(gdb)target remote:1234
(gdb)break start_kernel
(gdb)c
可以看见系统启动时停止在start_kernel处
在系统调用time的内核处理函数sys_time处添加断点,执行n,将MenuOS系统启动起来,这时我们执行time,系统停在断点sys _time处。
我们并不能利用gdb跟踪到sys_time里面的具体执行过程
(3)查看系统调用的实现代码
1.系统调用机制是什么时候初始化的:
在系统启动时执行start_kernel,start _kernel中会调用trap _init()函数, 用于硬件中断向量初始化,这个函数被定义在/arch/x86/kernel/trap.c中,
SYSCALL_VECTOR系统中断向量
system_call:系统调用入口,
当发生中断或系统调用,直接找到system_call入口地址去执行。
2.系统调用的处理过程:
系统调用的定义在/arch/x86/kernel/entry_32.S中,有一个入口
ENTRY(system_call),是int $0x80后的下一条执行地址,
大致流程:
system _ call->sys call _table ->syscall exit(是否处理syscall _ exit _ work) ->restort _all -> irq _return,work _notifying用于处理信号
在系统调用返回前有可能进行进程调度,有可能需要处理当前进程的信号
进行进程调用在work_resched中call schedule;
中断结束后,从内核态返回用户态!
二、实验总结
这次实验主要是分析了系统是怎么响应一个系统调用的,系统调用的执行过程,代码的执行过程等知识,是理解操作系统工作的重要步骤!
相关文章推荐
- linux0.11系统调用的执行过程是怎样的?
- linux 系统调用执行过程
- linux 系统调用执行过程
- LINUX下系统调用执行过程
- linux0.11系统调用的执行过程是怎样的?
- Linux系统调用------通过time系统调用理解系统调用的执行过程
- linux 系统调用执行过程
- 《Linux内核分析》(五)——Linux系统调用的执行过程
- linux下的系统调用函数到内核函数的追踪
- linux修改内核、添加系统调用过程
- linux-0.11调试教程,系统调用sys_write的调用过程
- 转载_linux下的系统调用函数到内核函数的追踪
- Linux 中用 strace 追踪系统调用和信号值
- linux文件系统初始化过程(6 完结)---执行init程序
- linux下系统启动时,几个配置文件 /etc/profile、~/.bash_profile 等几个文件的执行过程,先后顺序
- Java调用linux系统shell执行命令
- fork和exec系统调用在内核中的执行过程
- Linux操作系统调用执行过程<转>
- linux系统调用mount全过程分析
- Linux系统调用过程