作者:刘世鹏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和详细函数
Linux内核分析第五周 扒开系统调用的三层皮(下) (20135304 刘世鹏)
Make rootfs
Linux内核分析第五周 扒开系统调用的三层皮(下) (20135304 刘世鹏)

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

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

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

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

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

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

system_call到iret之间的主要代码:

Linux内核分析第五周 扒开系统调用的三层皮(下) (20135304 刘世鹏)
SAVE_ALL //保存现场
call *sys_call_table(,%eax,4) //调用了系统调度处理函数,eax存的是系统调用号,是实际的系统调度程序。
sys_call_table //系统调用分派表
syscall_after_all//保存返回值
sys_exit_work  //详见解释
restore all //恢复现场(因为系统调用也是一种特殊的“中断”)
INTERRUPT RETURN //也就是iret,系统调用到此结束    
Linux内核分析第五周 扒开系统调用的三层皮(下) (20135304 刘世鹏)

对sys_exit_work的解释:

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

相关文章:

  • 2021-08-11
  • 2021-11-22
  • 2021-07-22
  • 2021-07-18
  • 2021-11-05
  • 2022-02-03
  • 2022-02-06
  • 2022-01-17
猜你喜欢
  • 2021-11-07
  • 2021-06-12
  • 2021-10-10
  • 2021-05-23
  • 2022-03-02
  • 2021-05-06
相关资源
相似解决方案