2023-2024-1 20232826《Linux内核原理与分析》第九周作业

20232826王朝昆 2023-11-16 15:40:58

一. 《庖丁解牛Linux分析》第九章AI问答 

                                      

 

                                      

 

二. 实验过程及分析

1. schedule函数介绍

schedule() 是 linux 调度器中最重要的一个函数,就像 fork 函数一样优雅,它没有参数,没有返回值,却实现了内核中最重要的功能,当需要执行实际的调度时,直接调用 shedule(),进程就这样神奇地停止了,而另一个新的进程占据了 CPU。

schedule主要完成的工作内容如下:
(1)sched_submit_work用于检测当前进程是否有plugged io需要处理,由于当前进程执行schedule后,有可能会进入休眠,所以在休眠之前需要把plugged io处理掉放置死锁。
(2)执行__schedule()这个函数是调度的核心处理函数,当前CPU会选择到下一个合适的进程去执行了。
(3)need_resched()执行到这里时说明当前进程已经被调度器再次执行了,此时要判断是否需要再次执行调度。

2. 使用 gdb 跟踪分析一个 schedule()函数 

(1)在内核代码中搜索schedule函数

通过查找可以发现,schedule函数定义在在内核的kernel/sched/core.c文件中

(2)将menu目录删除,利用git命令克隆一个新的menu目录,并运行MenuOS。

                               

 (3)配置gdb

cd ..
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
gdb  # 打开另一个终端,使用gdb调试
file linux-3.18.6/vmlinux
target remote:1234

                                

 

(4)在schedule、context_switch、switch_to、pick_next_task设置断点

b schedule
b context_switch
b switch_to
b pick_next_task

                              

(5)开始运行

      可以看到,程序停在schedule函数断点处,发现调用了schedule(),即发生了进程调度。

                             

    继续执行到pick_next_task断点处:发现在这里使用了某种调度策略选择下一个进程来切换

                          

(6)switch_to汇编代码部分 

#define switch_to(prev, next, last)                    
do {                                 
  /*                              
   * Context-switching clobbers all registers, so we clobber  
   * them explicitly, via unused output variables.     
   * (EAX and EBP is not listed because EBP is saved/restored  
   * explicitly for wchan access and EAX is the return value of   
   * __switch_to())                     
   */                                
  unsigned long ebx, ecx, edx, esi, edi;                
                                  
  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进程的栈顶为起点*/    
         
            //完成EIP的切换
             __switch_canary    
            //next_ip一般是$1f,对于新创建的子进程时ret_from_fork               
           "jmp __switch_to\n"  /*prev进程中,设置next进程堆栈*/ 
            //jmp不同于call是通过寄存器传递参数
           "1:\t"                //next进程开始执行
           "popl %%ebp\n\t"       
           "popfl\n"         
                                  
           /*输出变量定义*/                
           : [prev_sp] "=m" (prev->thread.sp),     //[prev_sp]定义内核堆栈栈顶
             [prev_ip] "=m" (prev->thread.ip),     //[prev_ip]当前进程EIP  
             "=a" (last),                 
                                  
             /* 要破坏的寄存器: */     
             "=b" (ebx), "=c" (ecx), "=d" (edx),      
             "=S" (esi), "=D" (edi)             
                                       
             __switch_canary_oparam                
                                  
            /* 输入变量: */                
           : [next_sp]  "m" (next->thread.sp),     //[next_sp]下一个内核堆栈栈顶    
             [next_ip]  "m" (next->thread.ip),     
           //[next_ip]下一个进程执行起点,,一般是$1f,对于新创建的子进程是ret_from_fork 
   
             /* regparm parameters for __switch_to(): */  
             [prev]     "a" (prev),              
             [next]     "d" (next)               
                                  
             __switch_canary_iparam                
                                 
           : /* 重新加载段寄存器 */           
          "memory");                  
} while (0)

       Linux调度的核心函数为schedule,schedule函数封装了内核调度的框架。细节实现上调用具体的调度类中的函数实现。schedule函数主要流程为:将当前进程从相应的运行队列中删除,计算和更新调度实体和进程的相关调度信息;将当前进重新插入到调度运行队列中,根据具体的运行时间进行插入而对于实时调度插入到对应优先级队列的队尾,从运行队列中选择运行的下一个进程,进程调度信息和上下文切换。当进程上下文切换后,调度就基本上完成了,当前运行的进程就是切换过来的进程了。
 

(7)进程上下文的切换机制,以及与中断上下文切换的关系

       进程上下文切换是操作系统在多任务环境下管理进程的重要机制。当操作系统决定暂停当前运行的进程并开始执行另一个进程时,它必须保存当前进程的状态(称为上下文),包括程序计数器、寄存器的值、内存映像以及其他关键信息,然后加载下一个即将执行的进程的状态,以便让它继续执行。这个过程被称为进程上下文切换。而中断上下文切换是发生在处理器响应硬件中断时的过程。当发生硬件中断时,处理器会暂停当前执行的任务,保存当前任务的上下文,并转而执行中断处理程序。这个中断处理程序在处理完中断请求后,会将之前被中断的任务的上下文恢复,让其继续执行。因此,中断上下文切换也涉及到保存和恢复任务的状态。

       两者的关系在于:进程上下文切换是由操作系统控制的,它涉及到在不同进程之间切换,而中断上下文切换是在处理器响应硬件中断时发生的,涉及到从用户态切换到内核态执行中断处理程序,然后再切换回之前的任务执行状态。两者都需要保存和恢复任务或进程的上下文信息,但触发的原因和所涉及的上下文不同。

...全文
592 回复 打赏 收藏 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
源码下载地址: https://pan.quark.cn/s/07e7935aff27 在Android应用开发过程中,`ImageView`作为一个基础组件被广泛运用,其主要功能是展示各种图像资源,这些资源可以来源于本地存储或通过网络获取。本文将详细阐述如何动态地变更`ImageView`所显示的图片内容,并借助自定义监听机制来监控和干预图片的加载流程。此类技术在应用开发中具有很高的实用价值,特别是在处理网络用户头像、商品展示图以及实时数据更新的场景下。 我们首先需要明确`ImageView`的基本操作方式。在Android平台,我们常通过`setImageResource()`、`setImageBitmap()`以及`setImageDrawable()`等函数来设定`ImageView`的图像内容。然而,这些方法主要适用于已加载至内存中的图像文件,对于网络图片,则需要借助更为复杂的处理逻辑。 在实现动态下载并更新`ImageView`中的图像时,我们普遍采用`AsyncTask`或`Loader`来执行后台任务,以此防止主线程被阻塞。本文将重点介绍自定义监听器的构建方法。自定义监听器能够让我们依据图片加载的进程或状态来执行特定的任务,例如显示加载进度指示器或处理加载失败的情况。 自定义监听器通常定义为一个接口,其中包含了若干个回调方法,例如`onStart()`、`onProgressUpdate()`、`onSuccess()`、`onError()`等。以下是一个示例接口定义: ```java public interface ImageDownloaderListener { void onStart(); void onProgress(int ...
代码转载自:https://pan.quark.cn/s/8e8053c4e35c uni-app是由DCloud(即海豚浏览器背后的公司)设计的一款基于Vue.js技术的跨平台前端框架。其核心思想是让开发者仅需编写一次代码,就能达成多平台的兼容性,涵盖了iOS、Android、H5、小程序以及快应用等多个不同的终端设备。这种“编写一次,随处运行”的特性显著提升了开发效能,减少了维护开销,特别适用于构建规模庞大且结构复杂的应用程序。 【Vue.js基础】 uni-app的开发根基是Vue.js,这是一款具备轻量级MVVM(Model-View-ViewModel)架构的前端框架。Vue.js借助声明式的数据结合以及组件化机制,简化了前端构建过程。在uni-app环境中,Vue的模板语法、计算属性、指令、组件等要素均被保留并应用于开发跨平台应用。开发者需要充分掌握Vue的基础概念和操作方法,例如数据绑定(v-bind、v-model)、条件性渲染(v-if、v-else)、循环(v-for)、事件处理(v-on)等。 【uni-app组件系统】 uni-app配备了一套内容丰富的原生组件集合,这些组件依托于各平台的原生API,能够实现接近原生应用的交互效果。比如,按钮(button)、图像(image)、列表(list)、导航栏(navigator)、滑动视图(swiper)等。开发者可以通过设定配置属性、响应事件来调整组件的功能表现和视觉样式,达成自定义功能的目标。 【uni-app插件市场】 在具备内置组件之外,uni-app还拥有一个功能强大的插件市场,其中提供了众多第三方组件和API,覆盖了地图、支付、推送、广告等多种功能范畴。开发者可以便捷地集成这些...

39

社区成员

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

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