2023-2024-1 20232820 陈彦霖《Linux内核原理与分析》第九周作业

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

理解 Linux 系统中进程调度的时机

询问chatGTP

启动MenuOS


首先进入LinuxKernel 文件夹,删除menu目录,然后git clone克隆一个新版本的menu,进入menu之后,运行make rootfs脚本自动编译生成根目录系统。

cd LinuxKernel

rm -rf menu

git config --global http.sslverify false

git clone https://github.com/mengning/menu.git

cd menu

make rootfs

调试MenuOS


通过增加-s -S启动参数打开调试模式。

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

gdb

file linux-3.18.6/vmlinux

target remote:1234

b schedule

c

gdb调试

按C往下执行,跟踪到schedule(),调用了__schedule()函数。

进入__schedule()函数内部如图所示

__schedule()函数内部有一句判断是否需要进行上下文切换的语句。context_switch()是进程上下文切换调用的函数。

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系统的一般执行过程,可以分为以下几个步骤:
1. 启动:Linux系统在启动时,会按照顺序执行以下步骤:
   - BIOS自检和硬件初始化
   - 加载操作系统内核镜像到内存
   - 内核自我加载和初始化
   - 切换到内核态,执行内核代码

2. 内核初始化:内核在启动后,会进行一系列的初始化操作,包括:
   - 初始化内存管理单元(MMU)
   - 初始化进程管理单元(PMU)
   - 初始化文件系统
   - 初始化网络栈
3. 创建初始进程:内核会创建一个初始进程(通常是root用户),作为系统的第一进程(PID 1)。
4. 启动用户空间:内核将控制权切换到用户空间,执行初始进程。此时,操作系统开始接收和处理用户输入的命令。
5. 命令执行:用户空间中的进程(如shell)读取用户输入的命令,然后将其转换为系统调用,传递给内核。内核接收命令后,调用相应的系统调用处理程序执行命令。
6. 进程管理:内核负责调度和管理进程,包括进程的创建、终止、调度等。此外,内核还负责处理进程间的同步和互斥操作。
7. 文件系统操作:内核提供文件操作接口,允许进程读取和写入文件。文件操作通过文件系统驱动实现,如EXT2、FAT32等。
8. 网络操作:内核提供网络操作接口,允许进程进行网络通信。网络操作通过网络协议栈实现,如TCP/IP、IPX/SPX等。
9. 系统调用:内核提供一系列系统调用,供用户空间进程使用。这些系统调用涵盖了内存管理、文件操作、网络通信等各个方面。
10. 进程间通信:内核支持进程间通过管道、信号、共享内存等方式进行通信。
11. 退出:当用户空间进程执行完毕或遇到异常时,内核会将其终止,并回收资源。然后,内核重新切换到初始进程,继续执行。
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值