Linux内核学习总结

作业一计算机是如何工作的进行http://www.cnblogs.com/zhengwei0712/p/5207299.html 

作业二操作系统是如何工作的进行http://www.cnblogs.com/zhengwei0712/p/5234622.html

作业三LINUX内核的启动过程http://www.cnblogs.com/zhengwei0712/p/5253703.html                         

作业四系统调用的工作机制http://www.cnblogs.com/zhengwei0712/p/5293565.html                                        

作业五分析system_call中断处理过程http://www.cnblogs.com/zhengwei0712/p/5317066.html 

作业六 分析Linux内核创建一个新进程的过程http://www.cnblogs.com/zhengwei0712/p/5329496.html 

作业七  Linux内核如何装载和启动一个可执行程序http://www.cnblogs.com/zhengwei0712/p/5352551.html   

作业八 进程的调度时机与进程的切换http://www.cnblogs.com/zhengwei0712/p/5384101.html


 第一章:计算机是如何工作的

计算机大部分都是用冯诺依曼体系结构,即存储程序计算机。

两个层面:

1.硬件: cpu(IP寄存器:指针,指向内存的某块区域)——总线——内存(代码与数据)

2.程序员:  内存存储指令与数据,
 CPU解释执行指令

   计算机在执行程序时须先将要执行的相关程序和数据放入内存储器中,
在执行程序时CPU根据当前程序指针寄存器的内容取出指令并执行指令,
然后再取出下一条指令并执行,如此循环下去直到程序结束指令时才停
止执行。其工作过程就是不断地取指令和执行指令的过程,最后将计算
的结果放入指令指定的存储器地址中。

 第二章:操作系统是如何工作的

通过内核源代码了解,从环境搭建起来,mystartkernerl开始初始化至完成,启动0号进程,
利用时间片,每个进程每隔1000万次,判断是否需要调度,调度使用myshedule()进行调度.
设置时间片的大小,时间片用完时,设置一下调度标识。 
if(timecount%1000==0&&myneedsched!=1) 当进程执行到的时候,发现
needsched==1,就执行myschedule,调度分两种情况,一种是下一个进程正在进行的,
另一种是从未调度过的,进程从未执行过,执行起来特殊点,将状态转成运行时状态,作为当
前执行的进程,esp,ebp指向同一位置两种汇编代码略有不同,是关键

 第三章:构造一个简单的Linux系统MenuOS

    Linux的启动过程:内核启动相关的代码基本在init目录下,init/main.c内核启动起点
    start_kernel函数相当于普通C程序中的main函数,搭建环境,启动内核。
    start_kernel的最后一句rest_init创建0号进程里的kernel_init创建1号进程,
    run_init_process创建1号进程,是第1个用户态进程。pid_kernel_thread(kthreadd,..)用内核线程管理系统资源(创建其他内核服务线程)。
    rest_init启动完后,call ..  cpu_idl , call_startup_entry,cpu_idle_loop里面while(1)0号进程,当系统无进程须执行时就调度到idle进程

课本第一章Linux的发展过程 与UNIX的关系 

课本第二章Linux内核源代码的获取、解压、配置、编译与安装 


 第四章:系统调用

C代码中嵌入汇编代码的写法

使用嵌入式汇编代码触发同一个系统调用

系统调用在内核代码中的处理过程
应用程序应该以某种方式(库函数或汇编代码)通知系统
告诉内核自己需要执行一个系统调用,希望系统切换到内核态。
内核就可以代表应用程序在内核空间执行系统调用。
通知内核的机制是靠软中断实现的:
通过引发异常将系统切换内核态执行异常处理程序(系统调用处理程序)。 

自学课本第五章 系统调用 系统调用与API的异同 系统调用触发过程、参数传递

自学课本第十八章 调试


 第五章 进程的描述和进程的创建

自学课本第三章 进程管理

进程提供两种虚拟机制:虚拟处理器和虚拟内存

PS:线程之间可以共享虚拟内存,但每个都拥有各自的虚拟处理器
1.fork()创建新进程,父进程用fork创建子进程。fork系统调用从内核返回两次:一次回到父进程,一次回到子进程。
2.exec()可以创建新的地址空间,把新的程序载入其中
3.在Linux内核中,fork()实际有clone()系统调用实现的。
4.程序通过exit()系统调用退出执行。最终中介进程并将其占用的资源释放掉。
5.父进程通过wait4()系统调用查询子进程是否终结,这使得进程拥有了等待特定进程执行
完毕的能力。

第六章:程序和进程

进程描述符PCB----task_struct数据结构

 操作系统:1.进程管理 2.内存管理 3 文件系统

新进程如何创建和修改task_struct数据结构

1.复制当前进程(创建新进程通过复制当前进程来实现)
2.给新进程分配新的内核堆栈
3.修改复制过来的进程数据(如pid,状态链表,内核堆栈,ip,sp) 

进程:处于执行期的程序以及相关的资源的总称。

1.fork()创建新进程,父进程用fork创建子进程。fork系统调用从内核返回两次:一次回到父进程,一次回到子进程。
2.在Linux内核中,fork()实际有clone()系统调用实现的。
3.程序通过exit()系统调用退出执行。最终中介进程并将其占用的资源释放掉。

进程上下文

一般程序在用户空间执行。当一个程序调执行了系统调用或者触发了某个异常,就陷入了内核空间。成内核“代表进程执行”,并处于进程上下文中。

Linux系统创建一个新进程的理解

1.fork实际开销是复制父进程的页表以及给子进程创建唯一的进程描述符**

2.Linux通过clone()系统调用实现fork()**

3.fork(),vfork(),和clone()库函数都是根据各自需要的参数标志去调用clone(),然后由clone()调用do_fork**

do_fork函数调用了copy_process()函数,然后让进程执行



  Linux通过复制父进程创建新进程,fork、vfork、clone都是通过do_exit实现进程的创建。
 -A.复制一个PCB
 -B.给新进程分配一个新的内核堆栈(复制了thread_info,不是复制了内核堆栈)    
 -C.修改复制的数据,即子进程初始化。

 从用户态代码看父进程和子进程各返回一次,而子进程从ret_from_fork函数开始执行,从函数中跳转到syscall_exit,即system_call中的语句。   

自学 《深入理解计算机系统》第七章 链接 

第七章 进程的切换和执行过程概览 

  • 用户态堆栈和内核态堆栈
  • 进程上下文的保存和恢复
  • 进程切换的关键代码switch_to分析
内核是各种中断处理过程和内核线程的集合
 
(1)中断处理过程(包括时钟中断、I/O中断、系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule();
 
(2)内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度;
 
(3)用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度。
中断和中断返回:有一个CPU上下文的切换
进程调度过程中:有一个进程上下文的切换,从一个进程的内核态堆栈切换到另一个进程的内核态堆栈。

自学课本第四章 进程调度 


学习总结 

    

1.Linux通过引导区,启动相应的内核,使用qemu指令,启动相应内核。

2.现在的计算机系统使用的是冯诺依曼结构,通过cs:ip指向内存相应指令的代码。

3.当内核启动完成之后,我们开始手工创建0号进程。0号进程创建了1号进程和2号进程。

1号进程是所有用户态的祖先,2号进程是所有内核线程的祖先。

4.在创建进程的过程中,涉及到了新进程的复制,新进程堆栈的初始化,
以及一些相应的cs,ip值得修改。

还有创建的子进程从哪句代码开始执行,从内核态返回用户态是否会发生进程调度。

5.在了解了进程的创建过程后,我们又对进程的调度时机以及调度的过程,
相应的上下文切换进行了学习。

并对上下文切换的汇编代码,分析了随每一步代码的执行,
两个进程的堆栈之间的变化。

这里的重点需要注意的是,

哪部分代码是对当前进程执行的,哪部分代码是为下一个新进程切换做准备的。

在变化的过程中ebp,esp分别指向哪里,cs,ip的值又如何变化。

 此外,还要区分切换进程的时候,切换成普通进程和切换成一个新的进程的起点代码在哪里。

 6.然后是对可执行文件格式的分析,以及可执行程序的装载等问题

  

学习感想

          

1.在这为数不长的几周学习里,对Linux系统的工作,有了一些初步的了解(不能说太过深入,好像是心中有了一个框架),

  在学习的过程中,还在课下看了一些相应书籍帮助自己理解Linux内核,如《Linux内核设计与分析》(第三版)和《深入理解计算机系统》。
这样可以在补充一下自己知识储备不足的地方。如了解了一些调度策略等。

2.最大的遗憾就是觉得课程突然结束了,还有种没有反应过来,不敢说对Linux内核有很深的了解吧,
但是我觉得可以通过在这几周网课的学习里,可以进一步去了解Linux内核。而且感觉各种操作系统都有相应类似的地方。
就像孟老师说的,要举一反三。

3.在源代码的分析上,主要通过调试源代码进行分析,我觉得在今后的学习里,
我将在Linux内核的分析里,进行一些更深入的学习,如进行一些实践,编一个系统调用以便更好地了解Linux内核,并加深知识点对自己的印象。

4.最后,谢谢孟老师这几周来的辛勤教导,老师辛苦了!

 

 “郑伟 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”

          

 

原文地址:https://www.cnblogs.com/zhengwei0712/p/5426479.html