Linux内核分析——系统调用(下)

pianogirl 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

一、给MenuOS增加自定义fork菜单

1、增加菜单

移植一下其他菜单的创建过程:
Linux内核分析——系统调用(下)_第1张图片

2、用qemu启动这个新的MenuOS

本地虚拟机环境:
Linux内核分析——系统调用(下)_第2张图片
【Makefile中有几个地方需要因地制宜地改动一下】
1. qemu命令
2. 本地虚拟机实际使用的内核及路径
启动结果:
Linux内核分析——系统调用(下)_第3张图片

二、使用gdb跟踪系统调用内核函数sys_time

实验楼环境:
Linux内核分析——系统调用(下)_第4张图片
本地虚拟机环境(遇到了问题)
Linux内核分析——系统调用(下)_第5张图片

三、系统调用在内核代码中的处理过程

system_call代码在 arch/x86/kernel/entry_32.S中,入口是ENTRY(system_call)
Linux内核分析——系统调用(下)_第6张图片
SAVE_ALL:保存现场
call *sys_call_table(,%eax,4)调用了系统调度处理函数,eax存的是系统调用号,是实际的系统调度程序。

sys_call_table:系统调用分派表

syscall_after_all:保存返回值
若有sys_exit_work,则进入sys_exit_work:会有一个进程调度时机。

work_pending -> work_notifysig,用来处理信号
    可能call schedule:进程调度代码
    可能跳转到restore_all,恢复现场。

若无sys_exit_work,就执行restore_all恢复,返回用户态。

INTERRUPT_RETURN <=> iret,结束
借用一下同学做的图:
Linux内核分析——系统调用(下)_第7张图片

四、总结

1、系统调用一般步骤:

  1. 用户代码触发一次int0x80中断
  2. 通过SAVE_ALL宏语句,使寄存器保存当前用户态上下文
  3. 通过中断向量表,启动对应中断服务程序,再转而查询系统调用表sys_call_table
  4. 完成系统调用服务例程后检查是否需要调度等其他工作
  5. RESTORE_ALL恢复现场,从内核态返回用户态代码
    整个过程严谨有序,滴水不漏。
    如下图:
    Linux内核分析——系统调用(下)_第8张图片

2、不能遗忘的问题

本机gdb调试出了问题:
make breakpoint pending on future libaray?

参考资料:http://www.cnblogs.com/hyq20135317/p/5312542.html
《Linux操作系统原理》

你可能感兴趣的:(Linux)