关于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号进程是所有内核线程的祖先),从而又增加了自己学习的兴趣。

书上的内容

看书笔记:

  1. 多任务系统划分为两类:非抢占式多任务(主动挂起自己—让步)和抢占式多任务,Unix为抢先式的多任务。
  2. Linux进程调度:静态时间片算法和针对每一处理器的运行队列,它们帮助我们拜托了先前调度程序设计上的限制;进程分为:I/O消耗型(提交请求或等待请求)和处理器消耗型(执行代码);进程优先级:(1) nice值,范围-20到+19,默认为0,越大的nice值意味着越低的优先级;(2)实时优先级,默认范围是从0到99,数值越大优先级越高,而且任何实时进程优先级都高于普通进程。任何进程所获得的处理器时间是由它自己核其他所有可运行nice值的相对差值决定的;时间片:时间片过短过长都会产生一定的影响,I/O消耗型不需要长的时间片,处理器消耗性的进程则是希望越长越好。文字编辑程序属于I/O消耗型,视频编码程序属于处理器消耗型。
  3. Linux调度器是以模块的方式提供的,这样做的目的是允许不同类型的进程可以有针对的选择调度算法。这种模块化结构称为调度类,它允许不同的可动态添加的调度算法并存,调度属于自己范畴的进程。
  4. CFS完全公平调度,是一个针对普通进程的调度类,在Linux中称为SCHED_NORMAL,CFS算法实现定义在文件kernel/sched_fair.c中。出发点基于进程调度的效果应如同系统具备一个理想中的完美多任务处理器。
  5. 更高优先级的进程运行更频繁,而且也会被赋予更多的时间片。
  6. Linux调度实现的四个组成部分:

    时间记账:所有调度器都必须对进程时间做记账

    进程选择:CFS调度算法的核心为选择最小vruntime的任务

    调度器入口:主要入口点为schedule(),定义在kernel/sched.c中

    睡眠和唤醒:休眠的进程处于一个特殊的不可执行状态
  7. 上下文切换,也就是从一个可执行进程切换另一个可执行进程,由定义kernel/sched.c中的context_switch()函数负责处理。
  8. 抢占在以下情况时发生:从系统调返回用户空间时,从中断处理程序返回用户空间时.
  9. Linux提供了两种实时调度策略:SCHED_FIFO和SCHED_RR。
  10. 红黑树是一种自平衡二叉搜索树,具有特殊着色属性,或红或黑,有下面六个属性,维持半平衡结构:

    a.所有节点要么着红色,要么着黑色;

    b.叶子节点都是黑色

    c.叶子节点不包含数据;

    d.所有非叶子节点都有两个子节点;

    e.如果一个节点是红色,则它的子节点都是黑色;

    f.在一个节点到其叶子节点的路径中,如果总是包含同样数目的黑色节点,则该路径相比其他路径是最短的。

20169212《Linux内核原理与分析》第五周作业的更多相关文章

  1. 20169212《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...

  2. 20169210《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...

  3. 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...

  4. 2017-2018-1 20179215《Linux内核原理与分析》第二周作业

    20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...

  5. 2019-2020-1 20199329《Linux内核原理与分析》第九周作业

    <Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...

  6. 2019-2020-1 20199329《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...

  7. 2019-2020-1 20209313《Linux内核原理与分析》第二周作业

    2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...

  8. 2018-2019-1 20189221《Linux内核原理与分析》第一周作业

    Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...

  9. 《Linux内核原理与分析》第一周作业 20189210

    实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...

  10. 2018-2019-1 20189221《Linux内核原理与分析》第二周作业

    读书报告 <庖丁解牛Linux内核分析> 第 1 章 计算工作原理 1.1 存储程序计算机工作模型 1.2 x86-32汇编基础 1.3汇编一个简单的C语言程序并分析其汇编指令执行过程 因 ...

随机推荐

  1. 09A-独立按键消抖实验01——小梅哥FPGA设计思想与验证方法视频教程配套文档

    芯航线--普利斯队长精心奉献   实验目的: 1.复习状态机的设计思想并以此为基础实现按键消抖 2.单bit异步信号同步化以及边沿检测 3.在激励文件中学会使用随机数发生函数$random 4.仿真模 ...

  2. 电脑装的是office2013,右键新建却是2007,或者右键新建菜单中没有excel2013问题解决办法。

    我的office出现了两个问题,因为工作比较忙,也没有着急解决,今天实在受不了了,花费一下午才找到解决方法. 原来万恶之源都是可恶的wps,以后千万不安装kingsoft了. 第一个问题:excel打 ...

  3. [OSG]OpenSceneGraph FAQ 以及OSG资源

    1.地球背面的一个点,计算它在屏幕上的坐标,能得到吗? 不是被挡住了吗? 答:计算一个空间点的屏幕坐标,使用osgAPEx::GetScreenPosition函数.当空间点处于相机视空间内(不管它是 ...

  4. angularjs checkbox 框的操作

    前言:今天遇到一个问题,需要对多选按钮进行操作,作为js菜鸟,只能做自己慢慢琢磨了-- <label class="checkbox-inline custom-checkbox no ...

  5. Mac环境下JDK安装方法

    1.版本 MAC OS 10.10.3 JDK:jdk1.8.0_40 jdk下载mac版本的:http://www.oracle.com/technetwork/java/javase/downlo ...

  6. maven创建子项目(适用于多模块管理项目)

    在eclipse或者myeclipse下构建maven项目,该项目由多个子模块组成. 1.创建一个父项目 NEW -->project-->maven-->maven Project ...

  7. Python -- 数据加载、存储与文件格式

    标签(空格分隔): Python 读入读出通常可以划分为几个大类:读取文本文件和其他更高效的磁盘存储格式,加载数据库中的数据,利用Web API操作网络资源. 读写文本格式的数据 pandas提供了一 ...

  8. ucos中的三种临界区管理机制

    熟悉ucos,或者读过Jean.J.Labrosse写过的ucos书籍的人,一定会知道ucos中著名的临界区管理宏:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL(). 同样 ...

  9. this 的值到底是什么?

    你可能遇到过这样的 JS 面试题: var obj = { foo: function(){ console.log(this) } } var bar = obj.foo obj.foo() // ...

  10. MySQL环境部署

    阅读目录: 1.Windows下安装MySQL 2.Linux下安装MySQL 序章: MySQL是个小型的数据库,用来自己做小项目,做学习练习什么的再适合不过了,不过新手总会被一些莫名奇妙的问题难住 ...