20169219《linux内核原理与分析》第九周作业
网易云课堂学习
可执行程序的装载
可执行程序的产生过程:预处理-----> 编译 ----> 汇编 ----> 链接
以hello.c文件为例进行分析,编译步骤如下
vi hello.c
gcc -E -o hello.cpp hello.c -m32
vi hello.cpp
gcc -x cpp-outout -S -o hello.s hello.cpp -m32
vi hello.s
gcc -x assembler -c hello.s -o hello.o -m32
vi hello.o
gcc -o hello hello.o -m32
vi hello
gcc -o hello.static hello.o -m32 -static
结果如下图
编程使用exec*库函数加载一个可执行文件.
静态链接和动态链接的区别
动态库链接时,会在运行时选择需要的部分进行编译,生成的可执行文件会比较小,而且容易后续的更新。静态编译会把所有的函数等都嵌入到可执行文件中,可以直接在任何电脑上直接运行.在静态连接程序中,所有的程序代码包好在一个可执行模块中。因为库程序静态连接到应用程序中,库的引用效率更高。静态连接增加应用程序文件的大小,如果系统同时还运行其他的应用程序时,静态连接也会增加内存中代码的大小。
加载方式上:
1.静态库只能使用静态加载方式,静态加载就是编译、链接的时候把静态库代码拷贝到程序中。
2.动态库可以使用“静态加载”和“动态加载”,静态加载就是在程序启动的时候把库所有的内容加载到内存,动态加载就是用到哪个函数所在的模块就加载对应的库就行。(这是因为,动态库可能也很大,一口气全部加载也是非常耗时,所以运行时用到谁就加载谁,就是动态加载)。
静态库、共享库以及动态加载库
(1) 静态库
静态库是一些目标文件的集合,库文件以”.a”结尾,连接器会将应用程序所需要用到的代码拷贝到应用程序中.
静态库的优缺点:
静态库增加了应用程序的大小,另外在处理静态库更新问题上需要花费更多的重编译代价(recompile),但是理论上,静态库应该比共享库或者动态加载库运行更快(1-5%),因为它减少了在程序运行才去加载库的开销。
(2) 共享库:
与静态库不同的是,共享库在链接阶段并不需要拷贝所需使用的代码,而只是做些参考标记,然后在程序启动时加载所需要的库文件,因此,对比静态库,链接共享库的应用程序小得多。
共享库的优缺点:
对比静态库,共享库在链接阶段只是对所需代码做些标识,在程序启动时才会加载,这样减少了目标应用程序的大小,通过soname,可以做到多版本的兼容,这样每次升级也不需要将原代码全部重新编译,免除了在升级过程中重编译带来的开销;但是,因为需要在程序运行阶段加载共享库,这样势必需要付出运行期间的库加载代价。
(3)动态加载库 (Dynamically loaded libraries)
是指在程序运行过程中可以加载的函数库,而不像共享库是在程序启动的时候加载。DLL对实现插件和模块非常实用,因为它们运行程序在允许时等待插件的加载,动态加载库有自己的一套API接口去完成打开、查找符号,处理出错、关闭加载库等功能。
进程的切换和系统的一般执行过程
不同类型的进程有不同的调度需求
第一种分类:
(1)I/O-bound
- 频繁的进行I/O
- 通常会话费很多时间等待I/O操作完成
(2)CPU-bound- 计算密集型
- 需要大量的CPU时间进行运算
第二种分类:
(1)批处理进程
- 不必与用户交互,通常在后台运行
- 不必很快响应
- 典型的批处理程序:编译程序、科学计算
(2)实时进程- 有实时需求,不必被低优先级的进程阻塞
- 响应时间要短、要稳定
- 典型实时进程:视频/音频、机械控制等
(3)交互式进程- 需要经常与用户交互,因此要花很多时间等待用户输入操作
- 相应时间要快,平均延迟要低于50-150ms
- 典型的交互式进程:shell、文本编辑程序、图形应用程序等
进程调度算法
(1)先进先出算法:
算法总是把处理机分配给最先进入就绪队列的进程,一个进程一旦分得处理机,便一直执行下去,直到该进程完成或阻塞时,才释放处理机。
(2)短进程优先
最短CPU运行期优先调度算法(SCBF--Shortest CPU Burst First)
该算法虽可获得较好的调度性能,但难以准确地知道下一个CPU执行期,而只能根据每一个进程的执行历史来预测。
(3)轮转法:
前几种算法主要用于批处理系统中,不能作为分时系统中的主调度算法,在分时系统中,都采用时间片轮转法。
简单轮转法:系统将所有就绪进程按FIFO规则排队,按一定的时间间隔把处理机分配给队列中的进程。这样,就绪队列中所有进程均可获得一个时间片的处理机而运行。
多级队列方法:将系统中所有进程分成若干类,每类为一级。
(4)多级反馈队列
多级反馈队列方式是在系统中设置多个就绪队列,并赋予各队列以不同的优先权。
Linux中进程的优先级是动态的,较长时间未分配到CPU的进程,优先级会升高;已经在CPU上运行了较长时间的进程,优先级会下降。
进程的调度时机与进程的切换
操作系统原理中介绍了大量进程调度算法,这些算法从实现的角度看仅仅是从运行队列中选择一个新进程,选择的过程中运用了不同的策略而已。
对于理解操作系统的工作机制,反而是进程的调度时机与进程的切换机制更为关键。
进程调度的时机
- 中断处理过程(包括时钟中断、I/O中断、系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule();
- 内核线程(特殊的进程,只有内核态没有用户态)可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度;
- 用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度。
进程的切换
- 为了控制进程的执行,内核必须有能力挂起正在CPU上执行的进程,并恢复以前挂起的某个进程的执行,这叫做进程切换、任务切换、上下文切换;
- 挂起正在CPU上执行的进程,与中断时保存现场是不同的,中断前后是在同一个进程上下文中,只是由用户态转向内核态执行;
- 进程上下文包含了进程执行需要的所有信息
- 用户地址空间:包括程序代码,数据,用户堆栈等
- 控制信息:进程描述符,内核堆栈等
- 硬件上下文(注意中断也要保存硬件上下文只是保存的方法不同)
- schedule()函数选择一个新的进程来运行,并调用context_switch进行上下文的切换,这个宏调用switch_to来进行关键上下文切换
- next = pick_next_task(rq, prev);//进程调度算法都封装这个函数内部
- context_switch(rq, prev, next);//进程上下文切换
- switch_to利用了prev和next两个参数:prev指向当前进程,next指向被调度的进程
使用gdb跟踪调用schedule函数
在time系统调用返回前,调用schedule(),在schedule设置断点:
Linux系统的一般执行过程
最一般的情况:正在运行的用户态进程X切换到运行用户态进程Y的过程
- 正在运行的用户态进程X
- 发生中断——save cs:eip/esp/eflags(current) to kernel stack,then load cs:eip(entry of a specific ISR) and ss:esp(point to kernel stack).
- SAVE_ALL //保存现场
- 中断处理过程中或中断返回前调用了schedule(),其中的switch_to做了关键的进程上下文切换
- 标号1之后开始运行用户态进程Y(这里Y曾经通过以上步骤被切换出去过因此可以从标号1继续执行)
- restore_all //恢复现场
- iret - pop cs:eip/ss:esp/eflags from kernel stack
- 继续运行用户态进程Y
几种特殊情况
- 通过中断处理过程中的调度时机,用户态进程与内核线程之间互相切换和内核线程之间互相切换,与最一般的情况非常类似,只是内核线程运行过程中发生中断没有进程用户态和内核态的转换;
- 内核线程主动调用schedule(),只有进程上下文的切换,没有发生中断上下文的切换,与最一般的情况略简略;
- 创建子进程的系统调用在子进程中的执行起点及返回用户态,如fork;
- 加载一个新的可执行程序后返回到用户态的情况,如execve;
虚拟文件系统
虚拟文件系统中(VFS)有四个主要的对象类型
超级块对象:代表一个具体的已安装文件系统;
索引节点对象:代表一个具体文件;
目录项对象:代表一个目录项,是路径的一个组成部分;
文件对象:代表由进程打开的文件
块I/O层
块设备中最小的可寻址单元是扇区。扇区是设备的最小寻址单元;块是文件系统的最小寻址单元。块包含一个或多个扇区,但大小不能超过一个页面,所以一个页面可以容纳一个或多个内存的块。
目前内核中块I/O操作的基本容器由bio结构体表示,它代表了正在现场的(活动的)以片段链表形式组织的块I/O操作。
磁盘寻址是整个计算机系统中最慢的操作之一,所以尽量缩短寻址时间是提高系统性能的关键。
I/O调度程序通过两种方法减少磁盘寻址时间:合并和排序。
出现的问题
在使用gdb跟踪分析一个execve系统调用内核处理函数sys_execve的过程中,需要在执行exec命令的时候同时输出“hello world!”,需要修改Makefile文件里面的代码,使系统在执行exec命令的时候同时执行hello.c文件。
只需要把Makefile文件里的“cp hello ../rootfs/”这行代码去掉就能解决问题,但是我还是不理解具体原因。!
20169219《linux内核原理与分析》第九周作业的更多相关文章
- 20169219 linux内核原理与分析第二周作业
"linux内核分析"的第一讲主要讲了计算机的体系结构,和各寄存器之间对数据的处理过程. 通用寄存器 AX:累加器 BX:基地址寄存器 CX:计数寄存器 DX:数据寄存器 BP:堆 ...
- 2019-2020-1 20199303<Linux内核原理与分析>第二周作业
2019-2020-1 20199303第二周作业 1.汇编与寄存器的学习 寄存器是中央处理器内的组成部份.寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令.数据和位址.在中央处理器的控制部件中 ...
- 2019-2020-1 20199314 <Linux内核原理与分析>第二周作业
1.基础学习内容 1.1 冯诺依曼体系结构 计算机由控制器.运算器.存储器.输入设备.输出设备五部分组成. 1.1.1 冯诺依曼计算机特点 (1)采用存储程序方式,指令和数据不加区别混合存储在同一个存 ...
- Linux内核原理与分析-第一周作业
本科期间,学校开设过linux相关的课程,当时的学习方式主要以课堂听授为主.虽然老师也提供了相关的学习教材跟参考材料,但是整体学下来感觉收获并不是太大,现在回想起来,主要还是由于自己课下没有及时动手实 ...
- 2019-2020-1 20199314 <Linux内核原理与分析>第一周作业
前言 本周对实验楼的Linux基础入门进行了学习,目前学习到实验九完成到挑战二. 学习和实验内容 快速学习了Linux系统的发展历程及其简介,学习了下的变量.用户权限管理.文件打包及压缩.常用命令的和 ...
- Linux内核原理与分析-第二周作业
写之前回看了一遍秒速五厘米:如果
- 2020-2021-1 20209307 《Linux内核原理与分析》第九周作业
这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)> 这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第九周作业> 这个作业的目标 & ...
- 2018-2019-1 20189221《Linux内核原理与分析》第一周作业
Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...
- 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业
2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第九周作业
<Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...
随机推荐
- 学习动态性能表(22)V$resource_limit
学习动态性能表 第20篇--V$resource_limit 2007.6.15 就一条SQL语句供你参考: select * from V$RESOURCE_LIMIT where resourc ...
- 前端HTML5介绍
1.为什么学习HTML5? 跨平台要求低 硬件要求低 flash之外的选择(尤其手机端) 2什么是HTML5? HTML是用来描述网页的一种语言 HTML指超文本标记语言 HTML不是变成语言,是一种 ...
- java继承实例基础
总结:多态.重写.构造方法调用 package com.a; public class fsd { int a = 23; public fsd() { System.out.println(4444 ...
- 杂项:DCloud.io
ylbtech-杂项:DCloud.io 1.返回顶部 1. DCloud.io,数字天堂(北京)网络技术有限公司. 国内HTML5产业的领军企业,W3C会员,HTML5中国产业联盟发起单位Dclou ...
- [Python]python CGI脚本在apache服务器上运行时出现“Premature end of script headers”错误
在测试自己的python CGI脚本时, 当html网页中的表单form内容传送到服务器python脚本时, 总是出现Premature end of script headers错误, 网页显示是服 ...
- hibernate 单元测试
单元测试 测试 dao service action package com.kaishengit.test; import org.hibernate.Session; import com.ka ...
- C语言生成程序问题
问题: 我用VS2013写好C语言程序调试运行后就在debug文件夹下生成了EXE文件,可以在本机运行.但是这个EXE文件在别的没装过VS2013的电脑上就不能直接运行,说丢失MSVCR120D.dl ...
- Python之函数目录(自定义函数,内置函数,装饰器,迭代器,生成器)
1.初始函数 2.函数嵌套及作用域 3.装饰器 4.迭代器和生成器 6.内置函数 7.递归函数 8.匿名函数 9.函数相关定义 10.三元表达式.列表推导式.生成器表达式 11.函数与方法的区别
- Android 4学习(2):概述 - AndroidManifes.xml
Android应用程序包含下面这几个部分: 程序的前后台: Activities Services 存储: Content Providers 消息传递: Intents Broadcast Rece ...
- JS中,日期对象(获取当前现在的年份,星期,时间)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...