Linux操作系统分析
Linux操作系统分析
SA20225534——闫东辉
一、冯诺依曼体系结构
冯诺依曼体系结构如图所示,其中运算器、存储器、控制器、输入设备和输出设备5大基本类型部件组成了计算机硬件。
计算机内部采用二进制来表示指令和数据,将其存入存储器中,然后启动计算机工作,这就是存储程序的基本含义。CPU从内存中不断取下一条指令来执行,CPU负责解释和执行这些指令,它们通过总线连接起来。
二、Linux系统
Linux系统一般有4个主要部分:内核、shell、文件系统和应用程序。内核、shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序、管理文件并使用系统。
三、进程管理
在Linux内核中用一个数据结构struct task_struct来描述进程。struct task_struct的数据结构非常庞大,其中state是进程状态,stack是堆栈等,因为涉及的内容过于庞杂,我们可以通过如图所示的进程描述符的结构示意图从总体上看清struct task_struct的结构关系,比如进程的状态、进程双向链表的管理,以及控制台tty、文件系统fs的描述、进程打开文件的文件描述符files、内存管理的描述mm,还有进程间通信的信号signal的描述等。
进程调度策略:
- SCHED_OTHER:普通进程的时间片轮转算法
- SCHED_FIFO:实时进程的先进先出算法
- SCHED_RR:实时进程的时间片轮转算法
普通进程按照SCHED_OTHER调度策略进行进程调度。 实时进程按照SCHED_FIFO或SCHED_RR策略进行调度。 SCHED_FIFO是按先进先出方法选择下一个使用CPU的进程。 SCHED_RR是实时进程的时间片轮转法策略(Round Robin)。
四、中断和异常
如果发生了一个中断或异常,那么CPU控制单元执行下列操作:
1,确定与中断或者异常关联的向量i(0~255)
2,读idtr寄存器指向的IDT表中的第i项
3,从gdtr寄存器获得GDT的基地址,并在GDT中查找,以读取IDT表项中的段选择符所标识的段描述符
4,确定中断是由授权的发生源发出的。
5,检查是否发生了特权级的变化,一般指是否由用户态陷入了内核态。
6,若发生的是故障,用引起异常的指令地址修改cs 和eip寄存器的值,以使得这条指令在异常处理结 束后能被再次执行
7,在栈中保存eflags、cs和eip的内容
8,如果异常产生一个硬件出错码,则将它保存在栈中
9,装载cs和eip寄存器,其值分别是IDT表中第i项门描述符的段选择符和偏移量字段。这对寄存器值给出中断或者异常处理程序的第一条指定的逻辑地址
中断/异常处理完后,相应的处理程序会 执行一条iret汇编指令,这条汇编指令让CPU控制单元做如下事情:
1,用保存在栈中的值装载cs、eip和eflags寄 存器。如果一个硬件出错码曾被压入栈中, 那么弹出这个硬件出错码 2,检查处理程序的特权级是否等于cs中最低 两位的值(这意味着进程在被中断的时候是 运行在内核态还是用户态)。若是,iret终止 执行;否则,转入3
3,从栈中装载ss和esp寄存器。这步意味着返 回到与旧特权级相关的栈
4,检查ds、es、fs和gs段寄存器的内容,如 果其中一个寄存器包含的选择符是一个段描 述符,并且特权级比当前特权级高,则清除 相应的寄存器。这么做是防止怀有恶意的用 户程序利用这些寄存器访问内核空间
五、时间管理
Linux内核提供两种主要的定时测量:
- 获得当前的时间和日期 系统调用:time(), ftime()以及gettimeofday()
- 维持定时器 settimer(), alarm()
Linux的计时体系结构
- 更新自系统启动以来所经过的时间
- 更新时间和日期
- 确定当前进程的执行时间,考虑是否要抢占
- 更新资源使用统计计数
- 检查到期的软定时器
计时体系结构中的关键数据结构和变量
- 计时时钟源clocksource
- 相对时间:记录从系统启动直到当前时刻的系 统时钟产生的滴答数,存储于系统核心变量 jiffies(jiffies_64)
- 墙上时间:系统的当前时间xtime
六、文件管理
虚拟文件系统实现了操作系统对其它各种不同文件系统的支持,将对各种不同文件系统的操作和管理纳入到一个统一的框架中。对用户程序隐去各种不同文件系统的实现细节,为用户程序提供一个统一的、抽象的、虚拟的文件系统界面。
1.第一层为文件系统接口层,如open、write、close等系统调用接口。
2.第二层为VFS (Virtual File System)接口层。该层有两个接口:一个是与用户的接口;一个是 与特定文件系统的接口。VFS与用户的接口将所有对文件的操作定向到相应的特定文件系统函数 上。VFS与特定文件系统的接口主要是通过vfs-operations来实现的。
3.第三层是具体文件系统层,提供具体文件系统的结构和实现,包括网络文件系统,如NFS (network file system)。
七、实例分析
以打开文件操作为例,open系统调用的服务例程是sys_open()函数,它接受三个参数:要打开文件的路径名filename, 访问模式的表示flags和文件权限掩码mode。在内核中,sys_open实际调用do_sys_open函数来完成所有操作。
do_sys_open主要执行如下操作:
1,通过getname()从进程地址空间获取该文件的路径名
2,调用get_unused_fd_flags(flags)函数从current->files结构中分配一个空闲的fd。
3,调用do_filep_open(dfd, pathname, flags, mode, 0)找到文件对象的指针struct file* f。
4,调用fd_install(fd, f),将f与fd关联起来。实际是将f保存在current->files->fdtab->fd数组的第fd位置处。
八、应用程序性能分析
对于Linux整体而言,影响程序性能执行的因素有CPU,内存,磁盘I/O和应用程序等。
CPU:同一程序在单处理器和多处理器的性能有着很大的不同,可以在条件允许的情况下尽量使程序在多核环境下运行。提高并行性也是提高程序性能的较好途径,它通过将运算分解位两个互不影响的运算组合从而减少主要路径上的运算。
内存:内存的大小、不同的内存分配方式以及对内存的读写都对应用程序的执行性能有着很大的影响。
应用程序:程序本身的时间复杂度和空间复杂度会极大影响应用程序的性能。应用程序开发者应该尽力针对各种情况做好代码优化,做好测试工作,是整个应用程序能够以更高的效率执行。
使用Linux性能分析工具如perf、netstat、vmstat、gprof、top等,分析程序运行过程中是由于进程频繁调度、IO占用过高或是各种原因对应用程序的性能产生影响。