20169212《Linux内核原理与分析》第五周作业
关于linux内核源码
两个很关键的目录,一个是arch(architecture),支持不同cpu体系架构的源代码,其中最重要的就是x86(一般把x86留下,其他的目录删掉),另一个是init(其中的main.c是整个linux内核启动的起点,不过这里面不是main()函数,而是一个叫start_kernel的函数),linux内核的核心代码在kernel目录中。上一节中的命令make allnoconfig
就是关闭所有的可选项,目的是可以让之后的编译更快的完成。
实验分析
由于这一周自己的电脑坏了,暂时借了一个电脑,所以不能用自己动手去构建一个简单的linux系统,就直接用实验楼的吧。使用实验楼的虚拟机打开shell,输入命令
cd LinuxKernel/
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
就启动了自己构建(实验楼里已经构建好了)的简单linux的内核的启动,如图
输入help命令,发现这个系统支持三个命令:help、version、quit
接下来使用gdb跟踪调试内核
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
其中关于 -s -S # 关于-s和-S选项的说明:
-S freeze CPU at startup (use ’c’ to start execution)意思就是开始的时候先将CPU冻结起来,目的是阻止cpu执行接下来的指令
-s shorthand for -gdb tcp::1234 这个开了个端口号是为了待会儿用gdb调试使用,若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项
bzImage:压缩的内核映像
initrd:是在系统引导过程中挂载的一个临时根文件系统
使用这个命令之后,发现系统开始启动,但是什么操作都没进行,qemu显示stopped,即表明cpu被成功冻结。如图所示
然后再另外打开一个shell窗口(可以在原shell窗口上右键->水平分割),然后输入gdb
命令,启动gdb来跟踪调试。进入gdb之后,我们还需要输入几条命令:
file linux-3.18.6/vmlinux
这条命令的意思是加载符号表,不过具体这个vmlinux是什么意思,我又去查了下,它是是未压缩的内核,即编译出来的最原始的文件,用于kernel调试,产生system.map符号表,不能用于直接加载。附带一张linux内核映像生成过程图解:
接下来是命令
target remote:1234
通过刚刚设置的端口号建立gdb和gdbserver之间的连接,在这个过程我们可以通过按c,让qemu上的linux继续运行
接下来就是通过设置断点,来详细跟踪linux内核的启动过程了。比如我们现在在内核启动的起点start_kernel函数处设置一个断点,那么命令就是
break start_kernel
我们在start_kernel函数处设置一个断点之后按c,来让其运行,可以发现qemu虚拟机中的系统执行了一些命令之后便又停住了,感觉像是内核要准备开始启动了,说明我们在start_kernel函数处设置的那个断点是有效的。如图
s进入函数,n单步跟踪:
在跟踪过程中如果对函数有兴趣,可以s进入函数,然后继续跟踪。
我们也可以使用list
命令,可以看到start_kernel这句代码上下的代码(显示前后十行,也可以使用list 5,10来显示第5行到第10行的代码),如图
掌握了方法我们还可以设置更多的断点来跟踪内核的启动过程。
认识start_kernel()
接下来,我们要认识下start_kernel这个最关键的函数,但是整个内核中,这个函数颇为复杂,所以我也尽力去学习,简单分析下自己的理解。观察刚刚的实验,我们发现start_kernel这个函数的开始在init/main.c这个文件中的第501行,于是我们用gedit打开init/main.c,找到对应的代码,果然是从501行开始的,如图
继续往下翻可以看到,在start_kernel还进行了一大堆的初始化操作。
所以,整个start_kernel,就完成调用一系列的初始化函数,完成内核本身的设置:设置与体系结构相关的环境、进程调度器初始化、内存初始化等各种初始化。在Start_kernel函数的最后调用了rest_init()函数,在rest_init中建立了init线程,并在最后调用cpu_idle()函数。可以这样理解:start_kernel最后clone出一个新的进程,也就是init进程,然后原来的进程就去执行cpu_idle()函数了,也就变成了idle进程(相当于windows系统中systemidle这个进程),当发生一次进程调度后,init进程被调度运行。
总结
此次学习让我比较系统的了解了linux内核的启动过程,自己一边学习,一边上网查询自己不太理解的知识点和专业的名词术语。但是整个内核启动复杂而又庞大,学习理解起来有困难,需要进一步加强学习。
内核启动过程包括start_kernel之前和之后,之前全部是做初始化的汇编指令,之后开始C代码的操作系统初始化,最后执行第一个用户态进程init。学习了之后感觉整个内核启动真的就应了中国传统文化里的“道生一,一生二,二生三,三生万物”,即道生一(start_kernel产生reset_init这个0号进程),一生二(kernel_init(1号)和kthreadd(2号)),二生三(即前面0、1和2三个进程),三生万物(1号进程是所有用户态进程的祖先,2号进程是所有内核线程的祖先),从而又增加了自己学习的兴趣。
书上的内容
看书笔记:
- 多任务系统划分为两类:非抢占式多任务(主动挂起自己—让步)和抢占式多任务,Unix为抢先式的多任务。
- Linux进程调度:静态时间片算法和针对每一处理器的运行队列,它们帮助我们拜托了先前调度程序设计上的限制;进程分为:I/O消耗型(提交请求或等待请求)和处理器消耗型(执行代码);进程优先级:(1) nice值,范围-20到+19,默认为0,越大的nice值意味着越低的优先级;(2)实时优先级,默认范围是从0到99,数值越大优先级越高,而且任何实时进程优先级都高于普通进程。任何进程所获得的处理器时间是由它自己核其他所有可运行nice值的相对差值决定的;时间片:时间片过短过长都会产生一定的影响,I/O消耗型不需要长的时间片,处理器消耗性的进程则是希望越长越好。文字编辑程序属于I/O消耗型,视频编码程序属于处理器消耗型。
- Linux调度器是以模块的方式提供的,这样做的目的是允许不同类型的进程可以有针对的选择调度算法。这种模块化结构称为调度类,它允许不同的可动态添加的调度算法并存,调度属于自己范畴的进程。
- CFS完全公平调度,是一个针对普通进程的调度类,在Linux中称为SCHED_NORMAL,CFS算法实现定义在文件kernel/sched_fair.c中。出发点基于进程调度的效果应如同系统具备一个理想中的完美多任务处理器。
- 更高优先级的进程运行更频繁,而且也会被赋予更多的时间片。
- Linux调度实现的四个组成部分:
时间记账:所有调度器都必须对进程时间做记账
进程选择:CFS调度算法的核心为选择最小vruntime的任务
调度器入口:主要入口点为schedule(),定义在kernel/sched.c中
睡眠和唤醒:休眠的进程处于一个特殊的不可执行状态 - 上下文切换,也就是从一个可执行进程切换另一个可执行进程,由定义kernel/sched.c中的context_switch()函数负责处理。
- 抢占在以下情况时发生:从系统调返回用户空间时,从中断处理程序返回用户空间时.
- Linux提供了两种实时调度策略:SCHED_FIFO和SCHED_RR。
- 红黑树是一种自平衡二叉搜索树,具有特殊着色属性,或红或黑,有下面六个属性,维持半平衡结构:
a.所有节点要么着红色,要么着黑色;
b.叶子节点都是黑色
c.叶子节点不包含数据;
d.所有非叶子节点都有两个子节点;
e.如果一个节点是红色,则它的子节点都是黑色;
f.在一个节点到其叶子节点的路径中,如果总是包含同样数目的黑色节点,则该路径相比其他路径是最短的。
20169212《Linux内核原理与分析》第五周作业的更多相关文章
- 20169212《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...
- 20169210《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...
- 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业
2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...
- 2017-2018-1 20179215《Linux内核原理与分析》第二周作业
20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...
- 2019-2020-1 20199329《Linux内核原理与分析》第九周作业
<Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...
- 2019-2020-1 20209313《Linux内核原理与分析》第二周作业
2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...
- 2018-2019-1 20189221《Linux内核原理与分析》第一周作业
Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...
- 《Linux内核原理与分析》第一周作业 20189210
实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...
- 2018-2019-1 20189221《Linux内核原理与分析》第二周作业
读书报告 <庖丁解牛Linux内核分析> 第 1 章 计算工作原理 1.1 存储程序计算机工作模型 1.2 x86-32汇编基础 1.3汇编一个简单的C语言程序并分析其汇编指令执行过程 因 ...
随机推荐
- C语言-Hello, world
你好, 世界 --1-- 语言的编写准备 1.1 C语言源文件的编译执行过程 1.2 常见文件的拓展名 1.3 常用的命令行指令 1.4 环境及运行方法 --2--编写代码 2.1练习 --3-- ...
- sqlite嵌入式数据库C语言基本操作(2)
:first-child{margin-top:0!important}img.plugin{box-shadow:0 1px 3px rgba(0,0,0,.1);border-radius:3px ...
- 我的第一个WebAPI程序
最近在小武哥的带领下,我去接触了一下WebAPI,虽然说有点晚了,但是我还是学了一下,有点心得吧! 步骤: 1:在Visual Studio 2012中新建MVC4项目,在App_Start目录下有一 ...
- UIScrollView,UIPageControl,UIImageView 实现图片轮播的效果
上一篇博客介绍了如何将XCode创立的项目提交到Git版本控制,这次就直接做一个图片轮播的展示demo,刚好可以把UIScrollView.UIPageControl.UIImageView这三个控件 ...
- Other linker flags
-ObjC:加了这个参数后,链接器就会把静态库中所有的Objective-C类和分类都加载到最后的可执行文件中-all_load:会让链接器把所有找到的目标文件都加载到可执行文件中,但是千万不要随便使 ...
- MVC JS中非表单元素路由传值
<span id="a" onclick="aaa(111)" style="cursor:pointer;">跳</sp ...
- 【Splay】bzoj3223-Tyvj1729文艺平衡树
一.题目 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 ...
- Ubuntu 16.04 LTS 安装 Nginx/PHP 5.6/MySQL 5.7 (LNMP) 与Laravel
Ubuntu 16.04 LTS 安装 Nginx/PHP 5.6/MySQL 5.7 (LNMP) 与Laravel 1.MySQL安装[安装 MariaDB]MariaDB是MySQL的一个分支首 ...
- 安卓解析json,使用BaseAdapter添加至ListView中,中间存储用JavaBean来实现
这是一个小练习,要求解析一个提供的json文件.并将其中的id,title值获取,以ListView形式展示出来.(开发工具是android studio) 下面开始: 首先我想到的是先把json文件 ...
- codeforces 85D D. Sum of Medians 线段树
D. Sum of Medians time limit per test 3 seconds memory limit per test 256 megabytes input standard i ...