2023-2024-1 20232811《Linux内核原理与设计》第九周作业

202328 2023-11-19 10:35:10

目录

实验八-理解进程调度时机跟踪分析进程调度与进程切换的过程

1.实验准备

2. 进程调度与进程切换的过程

3. 实验小结

使用AI工具辅助学习


实验八-理解进程调度时机跟踪分析进程调度与进程切换的过程

1.实验准备

删除实验楼初始的menu并重新克隆编译

2. 进程调度与进程切换的过程

在当前文件夹下通过以下命令启动QEMU

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

另开一个终端,使用gdb进行调试 

cd ./LinuxKernel
gdb
file linux-3.18.6/vmlinux
target remote:1234

 

然后在schedulecontext_switchswitch_topick_next_task处设置断点 

b schedule
b context_switch
b switch_to
b pick_next_task

 

switch_to为宏定义,不能设置断点。

接着开始运行,观察断点情况。

pich_next_task函数负责根据调度策略和调度算法选择下一个进程。pich_next_task函数断点如下:

context_switch函数实现进程切换。context_switch函数断点如下: 

 switch_to为宏定义,不能设置断点,查看其内联汇编代码:

asm volatile(
             "pushfl\n\t"  //保存当前进程flags
             "pushl %%ebp\n\t"  //当前进程堆栈基址压栈
             "movl %%esp,%[prev_sp]\n\t"  //保存ESP,将当前堆栈栈顶保存起来
             "movl %[next_sp],%%esp\n\t"  //更新ESP,将下一栈顶保存到ESP中
                     // 完成内核堆栈的切换
             "movl $1f,%[prev_ip]\n\t"    //保存当前进程的EIP
             "pushl %[next_ip]\n\t"       //将next进程起点压入堆栈,即next进程的栈顶为起点
             __switch_canary              //next_ip一般为$1f,对于新创建的子进程是ret_from_fork      
             "jmp __switch_to\n"    //prve进程中,设置next进程堆栈,jmp与call不同,是通过寄存器传递参数(call通过堆栈),所以ret时弹出的是之前压入栈顶的next进程起点
             //完成EIP的切换
             "1:\t"            //next进程开始执行       
             "popl %%ebp\n\t"  //restore EBP
             "popfl\n"         //restore flags

             //输出量
             : [prev_sp] "=m" (prev->thread.sp),   //保存当前进程的esp
               [prev_ip] "=m" (prev->thread.ip),     //保存当前进仓的eip
               "=a" (last),

               //要破坏的寄存器
               "=b" (ebx), "=c" (ecx), "=d" (edx),
               "=S" (esi), "=D" (edi)

               __switch_canary_oparam

              //输入量
             : [next_sp]  "m" (next->thread.sp),   //next进程的内核堆栈栈顶地址,即esp
               [next_ip]  "m" (next->thread.ip),     //next进程的eip

               // regparm parameters for __switch_to(): 
               [prev]     "a" (prev),
               [next]     "d" (next)

               __switch_canary_iparam

             : //重新加载段寄存器
            "memory");

3. 实验小结

  • 为了控制进程的执行,内核必须有能力挂起正在CPU上执行的进程,并恢复以前挂起的某个进程的执行,这叫做进程切换、任务切换、上下文切换
  • 挂起正在CPU上执行的进程,与中断时保存现场是不同的,中断前后是在同一个进程上下文中,只是由用户态转向内核态执行
  • 进程上下文包含了进程执行需要的所有信息 - 用户地址空间: 包括程序代码,数据,用户堆栈等 - 控制信息 :进程描述符,内核堆栈等
  • 硬件上下文(注意中断也要保存硬件上下文只是保存的方法不同)
  • schedule()函数选择一个新的进程来运行,并调用context_switch进行上下文的切换,这个宏调用switch_to来进行关键上下文切换
  • next = pick_next_task(rq, prev);//进程调度算法都封装这个函数内部 - context_switch(rq, prev, next);//进程上下文切换
  • switch_to利用了prev和next两个参数:prev指向当前进程,next指向被调度的进程

使用AI工具辅助学习

 

 

...全文
75 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

39

社区成员

发帖
与我相关
我的任务
社区描述
北京电子科技学院 《Linux内核原理与分析》课程
linuxarm开发系统安全 高校 北京·丰台区
社区管理员
  • rocflytosky
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧