课程学习总结报告

课程学习总结报告
请您根据本课程所学内容总结梳理出一个精简的Linux系统概念模型,最大程度统摄整顿本课程及相关的知识信息,模型应该是逻辑上可以运转的、自洽的,并举例某一两个具体例子(比如读写文件、分配内存、使用I/O驱动某个硬件等)纳入模型中验证模型。谈谈您对课程的心得体会,改进建议等。
产出要求是发表一篇博客文章,长度不限,只谈自己的思考,严禁引用任何资料造成文章虚长。


精简的Linux系统概念模型:Linux系统从应用角度来看,分为内核空间和用户空间两个部分。内核空间是Linux操作系统的主要部分,但是仅有内核的操作系统是不能完成用户任务的。丰富并且功能强大的应用程序包是一个操作系统成功的必要条件。
从用户空间转换到内核空间通过系统调用实现。

主要实现方式为:
其实系统调用实质上就是一种特殊的中断。通过特定的软件中断(陷阱 trap)向内核发出服务请求,int $0x80和syscall指令的执⾏就会触发⼀个系统调⽤、并使用EAX寄存器传递系统调用号,然后根据系统调用号执行相应的内核处理函数。因为是中断因此也伴随着中断上下文的切换。

Linux系统的一般执行过程为:

1). 正在运⾏的⽤户态进程X。
2). 发⽣中断(包括异常、系统调⽤等),CPU完成load cs:rip(entry of a specific ISR),即跳转到中断处理程序⼊⼝。
3). 中断上下⽂切换,具体包括如下⼏点:

  • swapgs指令保存现场,可以理解CPU通过swapgs指令给当前CPU寄存器状态做了⼀个快照。

  • rsp point to kernel stack,加载当前进程内核堆栈栈顶地址到RSP寄存器。快速系统调⽤是由系统调⽤⼊⼝处的汇编代码实现⽤户堆栈和内核堆栈的切换。

  • save cs:rip/ss:rsp/rflags:将当前CPU关键上下⽂压⼊进程X的内核堆栈,快速系统调⽤是由系统调⽤⼊⼝处的汇编代码实现的。

此时完成了中断上下⽂切换,即从进程X的⽤户态到进程X的内核态。
4). 中断处理过程中或中断返回前调⽤了schedule函数,其中完成了进程调度算法选择next进程、进程地址空间切换、以及switch_to关键的进程上下⽂切换等。
5). switch_to调⽤了__switch_to_asm汇编代码做了关键的进程上下⽂切换。将当前进程X的内核堆栈切换到进程调度算法选出来的next进程(本例假定为进程Y)的内核堆栈,并完成了进程上下⽂所需的指令指针寄存器状态切换。之后开始运⾏进程Y。
6). 中断上下⽂恢复,与(3)中断上下⽂切换相对应。注意这⾥是进程Y的中断处理过程中,⽽(3)中断上下⽂切换是在进程X的中断处理过程中,因为内核堆栈从进程X切换到进程Y了。
7). iret - pop cs:rip/ss:rsp/rflags,从Y进程的内核堆栈中弹出(3)中对应的压栈内容。此时完
成了中断上下⽂的切换,即从进程Y的内核态返回到进程Y的⽤户态。
8). 继续运⾏⽤户态进程Y。

Linux的内核主要的功能有进程管理、内存管理、文件系统。
1 . 进程管理
进程管理主要包括进程创建、进程切换和进程调度。

  1. 进程创建

    • 1号和2号进程的创建
      1号和2号进程的创建是start_kernel初始化到最后由rest_ init通过kernel_thread创建了两个内核线程:⼀个是kernel_init,最终把⽤户态的进程init给启动起来,是所有⽤户进程的祖先;另⼀个是kthreadd内核线程,kthreadd内核线程是所有内核线程的祖先,负责管理所有内核线程。
    • 系统调用fork创建一个进程最终都是通过_do_fork来完成的

      copy_process函数主要完成了调⽤dup_task_struct复制当前进程(⽗进程)描述符task_struct、信息检查、初始化、把进程状态设置为TASK_RUNNING(此时⼦进程置为就绪态)、采⽤写时复制技术逐⼀复制所有其他进程资源、调⽤copy_thread_tls初始化⼦进程内核栈、设置⼦进程pid等。其中最关键的就是dup_task_struct复制当前进程(⽗进程)描述符task_struct和copy_thread_tls初始化⼦进程内核栈。
      ⼦进程创建好了进程描述符、内核堆栈等,就可以通过wake_up_new_task(p)将⼦进程添加到就绪队列,使之有机会被调度执⾏,进程的创建⼯作就完成了,⼦进程就可以等待调度执⾏,⼦进程的执⾏从这⾥设定的ret_from_fork开始。
  2. 进程切换
    为了简便,假设系统只有两个进程,分别是进程0和进程1。进程0由内核启动时初始化执⾏,然后需要进程调度和进程切换,然后开始执⾏进程1。进程切换过程中进程0和进程1的堆栈和相关寄存器的变化过程⼤致如下:

    • pushq %%rbp 保存进程0当前RBP寄存器的值到堆栈;
    • movq %%rsp,%0 保存进程0当前RSP寄存器的值到prev->thread.sp,这时RSP寄存器指向进程的栈顶地址,实际上就是将进程0的栈顶地址保存。
    • movq %2,%%rsp 将进程1的栈顶地址next->thread.sp放⼊RSP寄存器,即RSP改为指向进程1的栈顶地址,完成了进程0和进程1的堆栈切换。
    • movq $1f,%1 保存进程0当前RIP寄存器值到prev->thread.ip,这⾥$1f是指标号1。
    • pushq %3 把即将执⾏的进程1的指令地址next->thread.ip⼊栈,完成pc寄存器值的切换
    • ret 就是将压⼊栈中的next->thread.ip放⼊RIP寄存器,因此CPU开始执行进程1,完成进程的切换
    • popq %%rbp 将进程1堆栈基地址从堆栈中恢复到RBP寄存器中。
  3. 进程调度
    进程调度策略就是从就绪队列中选择⼀个进程的策略⽅法。Linux下的进程调度有2种策略:SCHED_FIFO和SCHED_RR。

    • SCHED_FIFO是针对运行的实时性要求比较高、运行时间短的进程调度策略。这种策略中,系统按照进入队列的先后进行进程的调度。
    • SCHED_RR是针对实时性要求比较高、运行时间比较长的进程调度策略。系统分配给SCHED_RR进程时间片,然后轮循运行这些进程,将时间片用完的进程放入队列的末尾。

2 . 内存管理
内存管理是多个进程间的内存共享策略。在Linux系统中,内存管理的主要概念是虚拟内存。
虚拟内存可以让进程拥有比实际物理内存更大的内存,可以是实际内存的很多倍。每个进程的虚拟内存有不同的地址空间,多个进程的虚拟内存不会冲突。
虚拟内存的分配策略是每个进程都可以公平地使用虚拟内存。虚拟内存的大小通常设置为物理内存的两倍。

3 . 文件系统
在Linux中,一切都是文件,通过对文件的定义和操作来控制设备的执行和数据的存储。目前Linux下最常用的文件格式是ext2和ext3。ext2文件系统用于固定文件系统和可活动文件系统,是ext文件系统的扩展。ext3文件系统是在ext2上增加日志功能后的扩展,它兼容ext2。两种文件系统之间可以互相转换,ext2不用格式化就可以转换为ext3文件系统,而ext3文件系统转换为ext2文件系统也不会丢失数据。

文件打开流程:
  1、打开文件即使用 open 函数,它首先通过按名查找,看在高速缓存中有没有查找的 inode,如果有那么对其进行引用并加 1。如果没有将创建新的 vfs的 inode 对象和目录项对象等。

  2、 Open 函数调用的系统服务例程是 sys_open 函数,其接受的参数为文件目录和访问的模式。如果文件存在则返回一个文件描述符fd,如果不存在则返回-1.

  3、 Read 和write 函数分调用的服务例程是 sys_read 和 sys_write,接受三个参数。分别是一个文件描述符 fd,一个对数据缓存的地方buf,和需要传输的数据的多少 count。Read 对将文件读入缓存区。Write 则相反。

文件关闭流程:

  1、用户程序通过close ( )系统调用关闭打开的文件,该函数接收的参数为要关闭文件的文件描述符。

  2、内核调用sys_close ( )函数。

4 .一个例子:ls命令执行过程

如图左侧为主线,右侧则是涉及的各种操作系统知识的汇总。
1. CPU在运⾏其他进程时,Shell进程在等待获取⽤户输⼊,处于阻塞等待状态。当⽤户输⼊ls回⻋后,导致键盘控制器向CPU发出中断信号。
2. CPU检测到键盘中断信号,转去中断处理程序,中断处理程序将Shell进程由等待状态转为就绪状态,被唤醒置于就绪队列。
3. CPU从键盘中断处理程序返回前,检测是否需要进程调度,交互式进程被唤醒后vruntime较低,被优先调度的Shell进程很可能会恢复执⾏,Shell程序会调⽤fork系统调⽤和exec系统调⽤。
4. CPU执⾏Shell进程调⽤fork系统调⽤,结果是创建了⼀个⼦进程,这期间可能进程调度Shell进程被挂起,⼦进程得以执⾏,在⼦进程中调⽤exec系统调⽤加载了ls可执⾏程序,exec系统调⽤返回CPU开始执⾏⼦进程中的ls程序。
5. CPU执⾏ls进程的效果就是输出当前⽬录下的⽬录和⽂件,这时ls进程终⽌,Shell进程⼜进⼊等待⽤户输⼊的状态,系统发⽣进程调度CPU去执⾏其他进程。

5 .心得体会
通过这门课的学习,我对Linux操作系统有了一个深入的认识。之前只是知道Linux的基本操作命令,现在对Linux操作系统底层的实现机制已经有了一定的认识,这让我受益良多。当然在以后的工作中使用Linux是必不可少的,这也对我以后的工作有了一定的帮助,再此非常感谢2位老师的细心教导。

posted @ 2020-07-08 14:41  浅安时光~  阅读(161)  评论(0编辑  收藏  举报