Linux内核分析第五周 扒开系统调用的三层皮(下) (20135304 刘世鹏)

作者:刘世鹏20135304  《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

一、给MenuOS增加time和time-asm命令

1. 通过内核的方式(跟踪调试系统调用)来理解并使用系统调用。

rm menu -rf //强制删除当前menu

git clone http://github.com/mengning/menu.git   //重新克隆新版本的menu

cd menu

ls

make rootfs //rootfs是事先写好的一个脚本,自动编译自动生成根文件系统,同时自动启动MenuOS

 

2. 将上周选择的系统调用添加到MenuOS中

vi test.c  //进入test.c文件
添加新功能
make rootfs //编译

 

 

 

 

3. 给MenuOS增加time和time_asm命令的步骤:

  • 更新menu代码到最新版
  • test.c中main函数里,增加MenuConfig()
  • 增加对应的Time函数和TimeAsm函数
  • make rootfs

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

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S 

gdb

(gdb)file linux-3.18.6/vmlinux

(gdb)target remote:1234 //连接到需要调试的MenuOS

(gdb)b start_kernel //设置断点

(gdb)c //执行,可见程序在start_kernel处停下

list //可查看start_kernel的代码

(gdb)b sys_time //sys_time是13号系统调用对应的内核处理函数,在该函数处设置断点

(gdb)c

//如果这里一直按n单步执行,会进入schedule函数。sys_time返回后进入汇编代码处理,gdb无法继续进行追踪

执行int 0x80后执行system call对应的代码(system call不是函数,是一段特殊的汇编代码,gdb还不能进行跟踪)。

 

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

1. 系统调用在内核代码中的工作机制和初始化

int 0x80——>system call:通过中断向量匹配

system call——>sys_xyz():通过系统调用号匹配

1.1 系统调用机制的初始化

一旦执行int 0x80后立刻跳转到system_call执行

2. 理解的system_call伪代码(总结上有流程)

  • int 0x80后的下一条指令从此处的ENTRY(system_call)开始
  • 系统调用返回之前可能会发生进程调度(call schedule)
  • 当前进程可能有信号需要处理(work_notifysig)
  • 进程调度中会发生中断上下文切换和进程上下文的切换,这是个连贯的过程
  • 内核可以抽象成多种不同中断处理过程的集合

实验

在main函数中增加MenuConfig和详细函数

Make rootfs


设置断点


进行单步调试

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

  • main.c中start_kernel函数:trap_init()
  • trap_gate函数中,涉及到了系统调用的中断向量和system_call的汇编代码入口
    • SYSCALL_VECTOR:系统调用的中断向量
    • &system_call:汇编代码入口
  • 执行int 0x80,系统直接跳转到system_call

system_call到iret之间的主要代码:

复制代码
SAVE_ALL //保存现场
call *sys_call_table(,%eax,4) //调用了系统调度处理函数,eax存的是系统调用号,是实际的系统调度程序。
sys_call_table //系统调用分派表
syscall_after_all//保存返回值
sys_exit_work  //详见解释
restore all //恢复现场(因为系统调用也是一种特殊的“中断”)
INTERRUPT RETURN //也就是iret,系统调用到此结束    
复制代码

对sys_exit_work的解释:

  • 若有sys_exit_work,则进入sys_exit_work:会有一个进程调度时机。
    • work_pending -> work_notifysig,用来处理信号
      • 可能call schedule:进程调度代码
      • 可能跳转到restore_all,恢复现场。
  • 若无sys_exit_work,就执行restore_all恢复,返回用户态。

posted @ 2016-03-27 21:20  刘世鹏  阅读(242)  评论(0编辑  收藏  举报