Linux内核学习总结

来源:互联网 发布:cmd查询数据库 编辑:程序博客网 时间:2024/06/17 23:52

张备 原创作品转载请注明出处《Linux内核分析》

MOOC课程http://mooc.study.163.com/course/USTC-1000029000

1、从进程出发了解Linux内核

计算机工作的基础是冯诺依曼体系结构,由系统总线将CPU和主存以及IO设备连接起来,并由操作系统来对硬件进行管理。我们可以把操作系统看成是应用程序和硬件之间插入的一层软件,所有应用程序对硬件的操作尝试都应该经过操作系统。 像实验中的main程序在现代操作系统上运行时,操作系统会提供一种假象,就好像系统上只有这个程序在运行,处理器看上去在不间断地一条接一条地执行程序中的指令。

这些假象是通过进程的概念来实现的——进程是操作系统对一个正在运行的程序的一种抽象,在一个系统上可以同时运行多个进程,而每个进程都好像在独占地使用硬件,这是通过处理器在进程间切换来实现的,这种机制称为“上下文切换”。每个进程所看到的是一致的存储器,被称为虚拟地址空间。虚拟存储器的运作需要硬件和操作系统软件之间的精密复杂的交互,包括对处理器生成的每个地址的硬件翻译。​


2.进程的假象

通过分析源码,我们了解到时间片轮转算法的具体方法,即每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。调度程序所要做的就是维护一张就绪进程列表,当进程用完它的时间片后,它被移到队列的末尾。这是一种最古老,最简单,最公平且使用最广的算法。通过这样的方法,产生了所有进程似乎同时运行的假


3.启点

最初执行的进程启点即是0号进程init_task,它是被静态产生的,内存栈的位置固定,执行一些初始化的工作。一直到start_kernel开始调用执行sched_init(),0号进程被init_idle(current, smp_processor_id())进程初始化成为一个idle task,变成上一次实验中的进程一样的,通过一个while循环不断执行,只要运行栈里没有别的进程它就执行,循环中不断检测运行栈里是否有其他进程并通过schedule函数进行调度。


4.中断

无论是系统调用,或是中断,其原理相同,即对进程提供一种透明执行的系统功能,执行系统调用时,先保存现场,准备调用参数,接着执行系统调用,保存调用结果。处理必需的调度、信号等,恢复现场,返回调用函数,这便是系统调用和中断处理的大概过程。


5.新生

除了Linux系统中最开始启动时,创建的第一个始祖进程外,从init进程开始,其他所有的进程的创建方式均是通过fork,clone,vfork的方式,而他们又能够有归结到do_fork。

fork()在用户态用于创建一个子进程的系统调用,fork系统调用在父进程和子进程各返回一次,在父进程的返回值是子进程中的id,在子进程的返回值是0,在shell命令行下两个都输出了是因为两个进程,子进程copy了父进程所有的信息。fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建。而创建新进程是通过复制当前进程来实现的。


6.运转

我们平常编写的源文件(.C文件)是不能直接放到机器上运行的,它只不过是一个带”.c”后缀的文本文件而已,需要经过一定的处理才能转换成机器上可运行的可执行文件。

这里写图片描述

整个代码的编译过程分为编译和链接两个过程,其中编译过程又分为两个阶段:编译和汇编。由汇编程序生成的目标文件并不能立即就被执行,可能在程序中调用了某个库文件中的函数(比如printf)等等,这就是链接程序的工作了。链接程序将有关的目标文件彼此相连接,也即将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够按操作系统装入执行的统一整


7.以进程结束了解Linux内核


操作系统最重要的功能还得落实到进程调度,诸多的进程调度算法从实现的角度看仅仅是从运行队列中选择一个新进程,选择的过程中运用了不同的策略而已。对于理解操作系统的工作机制,反而是进程的调度时机与进程的切换机制更为关键。schedule()函数用来选择一个新的进程来运行,并调用context_switch()进行上下文的切换,这个宏调用switch_to()来进行关键上下文切换,其中pick_next_task()函数封装了进程调度算法。
中断处理过程(包括时钟中断、I/O中断、系统调用和异常)中,常直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule();内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度;用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度。
正是这种被动的调度机制,使得操作系统看起来尤为强大,通过中断保存进程的上下文,以及利用Linux的内存管理机制,共同造就了一种假象--所有的进程同时运行,并且都拥有所有的系统资源,使得进程无需为系统的资源分配,尤其是时间和空间的分配进行管理,极大的增加了计算机系统资源的利用率。











0 0
原创粉丝点击