20189220 余超《Linux内核原理与分析》第六周作业

系统调用的三层机制

实验过程

1.克隆MenuOS

rm menu -rf //强制删除当前menu
git clone http://git.shiyanlou.com/mengning/menu.git //重新克隆新版本的menu
cd menu
ls

1505483-20181113200003851-911233208.png

2.打开test.c并在里面添加上次实验所用的getpid的c函数和汇编代码
1505483-20181113200319286-1740043747.png

3.在main函数中加入MenuConfig
1505483-20181113200426129-1701287081.png

4.make rootfs
1505483-20181113200457928-107558132.png

5.使用hellp命令可以看到qemu中增加了我们先前添加的命令:
1505483-20181113200538390-2132482522.png

6.执行新增加的命令getpid getpid_asm可得:
1505483-20181113200653170-2101698500.png

7.gdb跟踪分析一个系统调用内核函数
1505483-20181113202032230-178969770.png

8.在start_kernel处设置断点,继续执行,在qemu窗口的结果:
1505483-20181113202128592-1649936788.png

9.查看我所选用的系统调用的函数:
1505483-20181113202436764-1177387826.png

10.设置断点在sys_getpid处,发现执行命令getpid时并没有停下,在执行getpid_asm时停下了:
1505483-20181113202920746-343129798.png

11.直接结束若干次单步执行,然后继续往下单步执行,发现出现了进程调度函数,返回了进程调度中的一个当前进程任务的值。
1505483-20181113203146162-599934309.png

12.设置断点于system_call处。发现可停,而继续执行时,刚才停下的getuid_asm也返回了值。
1505483-20181113203526403-1173986154.png

实验分析
  1. 系统调用在内核代码中的工作机制和初始化
  • main.c中start_kernel函数:trap_init()
  • set_system_trap_gate(SYSCALL_VECTOR,&system_call)
  • SYSCALL_VECTOR:系统调用的中断向量
  • &system_call:汇编代码入口——执行int 0x80,系统直接跳转到system_call。

2.系统调用——一个特殊的中断
1505483-20181113214039524-825646297.png

  • 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,结束。
在系统调用返回之前,可能发生进程调度,进程调度里就会出现进程上下文的切换。
进程间通信可能有信号需要处理。
可以将内核视为一系列中断指令的集合。

3.system_call的流程示意图
1505483-20181113215836959-1197355488.jpg

遇到的问题

在进行gdb调试的时候,我导入文件的时候出现了下面的问题
1505483-20181113220003777-1612734592.png
原因:是因为我进入到了menu里面去了,应该退出来回到LinuxKernel的目录下面来执行调试。
1505483-20181113220248469-1137069228.png
回到上面的目录下载进行调试就可以导入文件了
1505483-20181113220328691-1344640787.png

本章总结
  • 通过本章的学习和实验,我首先明白了系统调用是一种特殊的中断,初步理解了系统调用的过程。
  • 在系统调用时,我们需要SAVE_ALL,用于保存系统调用时的上下文。同样,中断处理的第一步应该也要保存中断程序现场。目的:在中断处理完之后,可以返回到原来被中断的地方,在原有的运行环境下继续正确的执行下去。
  • 在系统调用时,我们需要将系统调用号通过eax传入,通过sys_call_table查询到调用的系统调用,然后跳转到相应的程序进行处理。同样,中断处理时系统也需要有一个中断号,通过检索中断向量表,了解中断的类型和设备。
  • 系统调用时最后要restore_all恢复系统调用时的现场,并用iret返回用户态。同样,执行完中断处理程序,内核也要执行特定指令序列,恢复中断时现场,并使得进程回到用户态。

在实验部分我学到了:给menuOS增加命令的方法:
强制删除menu (rm menu -rf)
更新menu代码至最新版本(git clone https://github.com/mengning/menu.git
在test.c中main函数中增加MenuConfig,以及增加上周自己选择Getegid,GetegidAsm的代码
Make roofts自动编译,生成,和启动根文件系统

使用gdb跟踪调试内核的方法:
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
gdb
(gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加载符号表
(gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行
(gdb)break start_kernel # 断点的设置,注意寻找对应的系统调用函数名字,例如time命令对应sys_time

转载于:https://www.cnblogs.com/yuchao123/p/9955137.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值