目录
实验八:理解进程调度时机跟踪分析进程调度与进程切换的过程
实验要求:
- 理解 Linux 系统中进程调度的时机,可以在内核代码中搜索 schedule()函数,看都是哪里调用了 schedule(),判断我们课程内容中的总结是否准确;
- 使用 gdb 跟踪分析一个 schedule()函数 ,验证您对 Linux 系统进程调度与进程切换过程的理解;推荐在实验楼 Linux 虚拟机环境下完成实验。
- 特别关注并仔细分析 switch_to 中的汇编代码,理解进程上下文的切换机制,以及与中断上下文切换的关系;
- 根据本周所学知识分析并理解 Linux 中进程调度与进程切换过程,撰写一篇署名博客,并在博客文章中注明“真实姓名(与最后申请证书的姓名务必一致) + 原创作品转载请注明出处 + 《Linux 内核分析》MOOC 课程 Linux内核分析 - 网易云课堂”,博客内容的具体要求如下:
- 题目自拟,内容围绕对进程调度的时机和进程切换进行;
- 可以结合关键代码、实验截图、堆栈状态、CPU 寄存器状态等;
- 博客内容中需要仔细分析进程的调度时机、switch_to 及对应的堆栈状态等;
- 总结部分需要阐明自己对“Linux 系统一般执行过程”的理解。
请提交博客文章 URL 到网易云课堂 MOOC 平台,编辑成一个链接可以直接点击打开。(学堂在线上的学员注意提交博客 URL 到学堂在线上)。
实验过程:
配置运行MenuOS系统
cd ~/LinuxKernel
rm menu -rf
git clone git://github.com/mengning/menu.git
cd menu
make rootfs
调试
cd ..
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -S -s
新建shell,进行gdb调试
gdb
file linux-3.18.6/vmlinux
target remote:1234
b schedule
b context_switch
b switch_to
b pick_next_task
c
运行到schedule处,它是进程调度的主体函数
context_switch函数实现进程切换。
pich_next_task函数负责根据调度策略和调度算法选择下一个进程
switch_to进行进程关键上下文切换。
实验总结:
Linux系统的一般执行过程。
正在运行的用户态进程X切换到用户态进程Y的过程,具体表述
(1)正在运行的用户态进程x.
(2)发生中断(包括异常、系统调用等),硬件完成以下动作。
save cs:eip/ss:esp/eflags:当前CPU上下文压入用户态进程X的内核堆栈。
load cs:eip(entry of a specific ISR) and ss:esp(point to kernel stack):加载当前进程内核堆栈相关信息,跳转到中断处理程序,即中断执行路径的起点。
(3) SAVE ALL, 保存现场,此时完成了中断上下文切换,即从进程x的用户态到进程X的内核态。
(4)中断处理过程中或中断返回前调用了schedule函数,其中的switch_to做了关键的进程上下文切换。将当前用户进程x的内核堆栈切换到选出的next进程(本例假定为进程Y)的内核堆栈,并完成了进程上下文所需的EIP等寄存器状态切换。
(5)标号1之后开始运行用户态进程Y (这里Y曾经通过以上步骤被切换出去,因此可以从标号1继续执行)。
(6) restore all,恢复现场,与(3)中保存现场相对应。
(7) iret-pop cs:eip/ss:esp/eflags.从Y进程的内核堆栈中弹出(2)中硬件完成的压栈内容。此时完成了中断上下文的切换,即从进程Y的内核态返回到进程Y的用户态。
(8)继续执行用户态进程Y。