Linux内核分析——期末总结
Linux内核学习总结
首先非常感谢网易云课堂这个平台,让我能够在课下学习,课上加强,体会翻转课堂的乐趣。孟宁老师的课程循序渐进,虽然偶尔我学习地不是很透彻,但能够在后续的课程中进一步巩固学习,更加深刻。上个学期学习了Linux基本的指令与操作方法,这学期的课程中终于运用上了,感觉到收获知识的满足感。课程的步骤是先建立起内核的大体框架,让我们理解各个子系统的设计理念和构建思想,这些理念让我有一个清晰的脉络,然后,给我们一项一项讲解、实践具体的实现方法、函数,我们就了解到这些函数,针对的是哪些设计思想,实现了什么样的功能,达成了什么样的目的,运用起来也就更加得心应手。
一、博客列表
第一周 计算机是如何工作的
- 冯·诺依曼结构模型:冯·诺依曼结构也称普林斯顿结构,是一种将程序指令存储器和数据存储器合并在一起的存储器结构。程序指令存储地址和数据存储地址指向同一个存储器的不同物理位置,因此程序指令和数据的宽度相同。
几个重要的汇编指令:push、pop、call、ret
、pushl %eax 把eax压栈到堆栈栈底 即首先把esp减4 esp表示堆栈栈顶 ebp表示堆栈基址 、popl %eax 把eax从堆栈栈顶取32位,放在寄存器eax中 即首先把栈顶esp的数值放在eax中,再把栈顶加4 、call 0x12345 调用该地址 即将当前的eip(当前CPU执行命令的指针)压栈,赋给eip一个新值(CPU下一条执行的指令) 、ret 即将call时保存的eip还原到eip寄存器,return call之前的那条指令 eip(*)这个*指程序员不能直接修改eip
第二周 操作系统是如何工作的
- 计算机“三宝”:存储程序计算机、函数调用堆栈和中断机制。
•cs : eip:总是指向下一条的指令地址 • 顺序执行:总是指向地址连续的下一条指令 • 跳转/分支:执行这样的指令的时候,cs : eip的值会 根据程序需要被修改 • call:将当前cs : eip的值压入栈顶,cs : eip指向被 调用函数的入口地址 • ret:从栈顶弹出原来保存在这里的cs : eip的值,放 入cs : eip中
第三周 构造一个简单的Linux系统MenuOS
操作系统两把宝剑:
1、中断上下文的切换:保存现场和恢复现场
2、进程上下文的切换
使用gdb跟踪调试内核
输入以下命令
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -S -s
-S表示:在CPU初始化之前,冻结CPU
-s表示在:1234端口上创建一个tcp接口
第四周 扒开系统调用的“三层皮”
如何区分用户态、内核态
CPU每条指令的读取都是通过cs:eip(代码段选择寄存器:偏移量寄存器)这两个寄存器,由硬件完成判断。
内核态时,cs与eip的值可以访问任意地址
用户态时,cs与eip只可以访问0x00000000—0xbfffffff的地址空间
系统调用的三层皮
一层皮:API
二层皮:中断向量对应的中断服务程序
三层皮:系统调用对应的很多不同种类的服务程序
第五周 扒开系统调用的“三层皮”(下)
三)系统调用在内核代码中的处理过程
系统调用在内核代码中的工作机制和初始化
整个系统调用过程中,时间很重要。
以system_call为例,int 0x80指令与systemcall是通过中断向量联系起来的,而API和对应的sys是通过系统调用号联系起来的
用户态时,系统调用xyz()使用int 0x80,它对应调用system_call
右边的处理过程(汇编代码)非常重要,通过系统调用号匹配起来
分析system_call中断处理过程
执行rm menu -rf,强制删除原有的menu文件夹,使用git命令更新menu代码至最新版。
在test.c中添加C函数、汇编函数
make rootfs,输入help,可以看到qemu中增加了之前添加的命令
进入gdb调试
设置断点
c运行
单步执行
第六周 进程的描述和进程的创建
操作系统三大功能
- 进程管理
- 内存管理
- 文件系统
0号进程是手工写入它的进程描述符数据,1号进程的创建是复制了0号进程的PCB,根据1号进程的需要,修改PID,加载一个init可执行程序。
创建一个新进程在内核中的执行过程
fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建。
Linux通过复制父进程来创建一个新进程,那么这就给我们理解这一个过程提供一个想象的框架:
- 复制一个PCB——task_struct
- 要给新进程分配一个新的内核堆栈
- 要修改复制过来的进程数据,比如pid、进程链表等等都要改改,见copy_process内部。
- 从用户态的代码看fork();函数返回了两次,即在父子进程中各返回一次,父进程从系统调用中返回比较容易理解,子进程从系统调用中返回。那它在系统调用处理过程中的哪里开始执行的呢?这就涉及子进程的内核堆栈数据状态和task_struct中thread记录的sp和ip的一致性问题,这是在哪里设定的?copy_thread in copy_process
第七周 可执行程序的装载
可执行程序是怎么来的
C代码—>预处理—>汇编代码—>目标代码—>可执行文件
- ELF中三种目标文件
- 一个可重定位(relocatable)文件保存着代码和适当的数据,用来和其他的object文件一起来创建一个可执行文件或者是一个共享文件。(主要是.o文件)
- 一个可执行(executable)文件保存着一个用来执行的程序;该文件指出了exec(BA_OS)如何来创建程序进程映象。
- 一个共享object文件保存着代码和合适的数据,用来被下面的两个链接器链接。第一个是连接编辑器[请参看ld(SD_CMD)],可以和其他的可重定位和共享object文件来创建其他的object。第二个是动态链接器,联合一个可执行文件和其他的共享object文件来创建一个进程映象。(主要是.so文件)
execve和fork都是特殊的系统调用
- 正常的系统调用:陷入到内核态,返回到用户态,执行系统调用的下一条指令。
- fork:进入到内核态,两次返回:第一次返回到父进程的位置,继续执行。第二次,在子进程中从ret_from_fork开始执行然后返回用户态。
- execve:当前的可执行程序执行到execve时,陷入到内核态,用execve加载的可执行文件将当前的可执行程序覆盖掉,当execve系统调用返回时,返回的不是原来的系统调用,而是新的可执行程序的执行起点,即main函数的位置。
第八周 进程的切换和系统的一般执行过程
进程分类
- 第一种分类
- I/O-bound:等待I/O
- CPU-bound:大量占用CPU进行计算
- 第二种分类
- 交互式进程(shell)
- 实时进程
- 批处理进程
- 第一种分类
- 调度策略:是一组规则,它们决定什么时候以怎样的方式选择一个新进程运行
Linux的调度基于分时和优先级。
- Linux的进程根据优先级排队
- 根据特定的算法计算出进程的优先级,用一个值表示
- 这个值表示把进程如何适当的分配给CPU
- Linux进程中的优先级是动态的
- 调度程序会根据进程的行为周期性地调整进程的优先级
- 例如:
- 较长时间未被分配到cpu的进程,通常↑
- 已经在cpu上运行了较长时间的进程,通常↓
- Linux的进程根据优先级排队
- 内核中的调度算法相关代码使用了类似OOD中的策略模式
- 分析schedule函数
- schedule()函数选择一个新的进程来运行,并调用context_switch进行上下文的切换,这个宏调用switch_to来进行关键上下文切换
next = pick_next_task(rq, prev);//进程调度算法都封装这个函数内部
context_switch(rq, prev, next);//进程上下文切换
switch_to利用了prev和next两个参数:prev指向当前进程,next指向被调度的进程
二、课本同步自学笔记
《Linux内核设计与实现》
第一章 Linux内核简介 http://www.cnblogs.com/bonjourvivi/p/5281471.html
第二章 从内核出发 http://www.cnblogs.com/bonjourvivi/p/5281825.html
第三章 进程管理 http://www.cnblogs.com/bonjourvivi/p/5340542.html
第四章 进程调度 http://www.cnblogs.com/bonjourvivi/p/5380584.html
第五章 系统调用 http://www.cnblogs.com/bonjourvivi/p/5297783.html
第十八章 调试 http://www.cnblogs.com/bonjourvivi/p/5330939.html
《深入理解计算机系统》
第七章 http://www.cnblogs.com/bonjourvivi/p/5355861.html
三、收获与不足
最大的收获:
这是我采用翻转课堂学习方式的第三个学期,在逐渐了适应了这种学习方式的同时,这门课程也一个向导,伴随着之前学习的Linux知识的基础,把我带入Linux内核的世界。这门课不仅教会了我知识,还教会了我学习地方法。从结构入手,就像一个去除了枝枝叶叶的大树的主干,一目了然。继而分析一个个函数,调试跟踪,分析问题的时候更有针对性,更便于找到原因。
最大的遗憾:
由于我的编程功底比较弱造成了一些知识上理解的困难,例如对汇编嵌入C语言代码的写法理解不到位,还有调试的时候只是做到了很浅显的步骤,并没有深入。归根到底还是我之前学习的部分知识有欠缺,所以导致现在学习中会有吃力的现象。我会努力补上之前的短板,更好的学习深入的课程。
20135308原创作品转载请注明出处
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
Linux内核分析——期末总结的更多相关文章
- Linux内核分析 期末总结
Linux内核分析 期末总结 一.知识概要 1. 计算机是如何工作的 存储程序计算机工作模型:冯诺依曼体系结构 X86汇编基础 会变一个简单的C程序分析其汇编指令执行过程 2. 操作系统是如何工作的 ...
- LINUX内核分析期末总结
韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.课程总结 1 ...
- 网易云课堂-----Linux内核分析-----期末主观题
姚歌 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 下面是对8个课题的 ...
- 《Linux内核分析》期末总结
Linux内核设计期中总结 版权声明:本文为博主原创文章,未经博主允许不得转载. 前八周博客汇总及总结 Linux内核设计第一周——从汇编语言出发理解计算机工作原理 我们学习了汇编语言的基础知识,这一 ...
- 期末总结:LINUX内核分析与设计期末总结
朱国庆原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一,心得体会 关于网上听课这 ...
- 《Linux内核分析》期末总结及学习心得
[洪韶武 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ] 一.学习心得 本学 ...
- 期末总结20135320赵瀚青LINUX内核分析与设计期末总结
赵瀚青原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 对LINUX内核分析与设计这 ...
- linux内核分析作业8:理解进程调度时机跟踪分析进程调度与进程切换的过程
1. 实验目的 选择一个系统调用(13号系统调用time除外),系统调用列表,使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用 分析汇编代码调用系统调用的工作过程,特别是参数的传递的方 ...
- Linux内核分析作业7:Linux内核如何装载和启动一个可执行程序
1.可执行文件的格式 在 Linux 平台下主要有以下三种可执行文件格式: 1.a.out(assembler and link editor output 汇编器和链接编辑器的输出) ...
随机推荐
- java集合 之 Collection和Iterator接口
Collection是List,Queue和Set接口的父接口,该接口里定义的方法即可用于操作Set集合,也可以用于List和Queue集合.Collection接口里定义了如下操作元素的方法. bo ...
- onmousedown,onmouseup,onclick同时应用于一个标签节点Element
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- 强制IE使用最高版本引擎渲染页面,避免默认使用IE7引擎导致的页面布局混乱及其它问题
背景 基于Asp.net MVC的一个Intranet web application, 现象 Application发布到服务器端后,在客户端IE访问页面布局混乱,并有javascript报错 原因 ...
- Visual Studio发布Web项目报错:Unable to add 'xxx' to the Web site. Unable to add file 'xxx'. The specified file could not be encrypted.
背景 Visual Studio下的Web项目 现象 发布时遇到Unable to add 'xxx' to the Web site. Unable to add file 'xxx'. The ...
- System.nanoTime()的使用
纳秒 ns(nanosecond):纳秒, 时间单位.一秒的10亿分之一,即等于10的负9次方秒.常用作 内存读写速度的单位. 1纳秒=0.000001 毫秒 1纳秒=0.00000 0001秒 ja ...
- nginx 配置wordpress固定链接(自定义)
今天在wordpress 下配置文章固定链接的时候,遇到了404的错误.我首先在wordpress下的设置里的“固定链接”配置页面,自定义链接的结构 “http://www.haozi8.com/%p ...
- 怎么直接让火狐输入json数据,而不是弹出文件保存对话框?
一.问题再现: 我需要浏览器输出的是json数据,但是浏览器弹出的是一个文件保存的对话框,这样的体验有点差.所以想怎么让浏览器直接输出到浏览器的页面上面,并且格式的输出,还可以编辑. 测试数据: ht ...
- 烂泥:KVM与kickstart集成
本文由秀依林枫提供友情赞助,首发于烂泥行天下. KVM与kickstart集成在这里我要说明下,因为在前面有关CentOS无人值守安装的文章中,我提到过如果要使用网卡PXE功能的话,内网中必须有DHC ...
- 烂泥:centos安装及配置DHCP服务器
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 有关DHCP服务器的配置一直打算学习,这几天终于抽出时间来专门学习这个知识点. DHCP:动态主机配置协议,在此就不多做介绍.不清楚的童鞋,可以去百度下 ...
- c# 常用正则
"^\d+$" //非负整数(正整数 + 0) "^[0-9]*[1-9][0-9]*$" //正整数 "^((-\d+)|(0+))$" ...