设为首页 收藏本站
查看: 1186|回复: 0

[经验分享] 2017-2018-1 20179209《Linux内核原理与分析》第四周作业

[复制链接]
发表于 2017-11-18 12:47:34 | 显示全部楼层 |阅读模式
  本周学习内容为《跟踪分析MenuOS简单linux系统的启动过程》和教材中的进程调度及内核数据结构。
一.跟踪分析Linux内核的启动过程
  这个实验我是在实验楼环境中完成的,最初想在自己的环境中完成,可在make的时候出现了问题,原本需要很长时间的make过程只用了10几秒,而且报了错。经过我上网查资料发现可能是因为我的实验环境有问题(kali1-4.3.0)。所以我还是选择了实验楼,其实在实验楼上同样有问题,每次冻结程序进行调试时必然卡顿,然后崩溃。我怀疑是网速的问题,果然,换了流量之后流畅多了。
  水平分割终端,上面用来输入命令,下面用来调试。启动内核并冻结,然后进入gdb模式,设置函数断点,使启动过程断在start_kernel处:
DSC0000.png

  __init start_kernel(void)是最低限度的初始化系统。这里面的每一个函数都有其存在的意义,光本次实验的这个小型系统,它的初始化队列中就大概涵盖200多个函数,可想linux系统内核的庞大。
DSC0001.png

  这里我萌生了一个想法,我们都知道,启动linux后会出现一行一行的加载,我想是不是就跟start_kernel中的函数有关,所以打算验证一下这个猜测。
DSC0002.png

  从上图大家可以看到,我在509行也就是lockdep_init();函数处设置断点,继续运行后虚拟机中的启动过程并没有任何变化。
  紧接着,我又在511行(smp_setup_processor_id();)处设置断点,这里面的很多函数光靠名字很难猜出它对linux内核启动有什么样的作用,但这对实验没有太大的影响,因为它们的意义不是重点。运行后还是没有任何变化。如下图:
DSC0003.png

  两次跳跃大概10几个函数,竟然没有变化,所以下一个断点,我选择了在528行boot_cpu_init();又是boot,又是cpu的,应该很重要,即使初始化也应该先进行检查吧,但是仍然没有任何反应:
DSC0004.png

  断535setup_per_cpu_areas();依旧:
DSC0005.png

  trap_init(); 这是对中断机制的初始化,出于好奇,我s进了这个函数:
DSC0006.png

DSC0007.png

DSC0008.png

  出发点是好的,但结果总不尽人意,这里面的大部分内容我是不明白的。这时候我想退出这个函数了:
DSC0009.png

  从上图可以看出,程序的执行终于跳了出来,回到了start_kernel中。
  其实经过这么多次的断,我已经有点怀疑我的猜测了,有可能这些系统初始化的过程并不对应那些启动画面中的一条一条的检查。所以我直接断了619行(跨度将近60行):
DSC00010.png

  它终于出现了变化,证明了我的想法一样,返回去看619行是哪个函数的执行:
DSC00011.png

  可能最初的变化并不是在locking_selftest();函数,但肯定是在这60行中某一个函数开始。
  最后一个断点设置在了start_kernel中的最后一个函数rest_init(),而且我也跳进去看了看:
DSC00012.png

DSC00013.png

  finish后,start_kernel()结束:
DSC00014.png

  start_kernel函数相当于c程序中的main函数,我们都知道而且也这样做:在main函数中调用其他函数,而不直接把功能函数的实体写在main中;start_kernel一样,它的作用就是调用linux内核启动所需要的各类初始化。对于它里面这些函数的功能,见start_kernel函数分析。说实话,我觉得这个实验给我收获最大的不是对内核启动过程的分析,因为从最开始明白start_kernel的用途以及跳进初始化中断的那个函数开始,我就已经领悟到了内核启动的过程——对系统启动所需要的软硬件的初始化(这里的软硬件包括系统运行所需要的栈、内存、中断等),以及对0号和1号进程的启动。我想说的最大的收获是对gdb的理解,尽管在调试myod的时候就已经很熟练对gdb的使用,但经过对内核启动过程的分析,我发现其实gdb的功能远不止设置断点继续运行这么简单,所以我就上网查了查,发现这篇博客解释得比较完美。
二.教材内容总结
  其实本科所学的操作系统这门课已经详解了进程调度的原理和手段,而且链表作为数据结构的一种,也早已实现过多次,所以这里我不再做过多陈述。只是总结一下,我认为的新的、或者原来没学的内容。

  • Linux调度器是以模块方式提供的,这样做的目的是允许不同类型的进程可以有针对性地选择调度算法。这种模块化结构被称为调度器类,它允许多种不同的可动态添加的调度算法并存,调度属于自己范畴的进程。每个调度器都有一个优先级,基础的调度器代码定义在kernel/sched.c文件中,它会按照优先级顺序遍历调度类,拥有一个可执行进程的最高优先级的调度器类胜出,去选择下面要执行的那一个程序。这里我觉得调度器只存在于Linux操作系统中,Windows系统中没有。
  • 红黑树是一种自平衡的二叉树,与普通二叉树相比,它具有着色属性,或红色或黑色。它通过以下六个属性来维持半平衡二叉树:

    • 所有的节点不是红色,就是黑色
    • 叶子节点都是黑色
    • 叶子节点不包含数据
    • 所有非叶子节点都有两个子节点
    • 如果一个节点是红色,则它的子节点都是黑色
    • 在一个节点到其叶子节点的路径中,如果总是包含同样数目的黑色节点,则该路径相比其他路径是最短的。

  • 进程调度的主要入口点是函数schedule();其实在之前的《构建一个简单的Linux系统》实验中出现过,这个函数中嵌入汇编代码,实现进程的切换。
  •   其实在进程切换和调度中,还有一个很重要的概念就是加锁机制。由于系统资源的有限,为避免产生死锁,必须对临界区资源加锁。想到这一概念我特意翻了一下课本,发现在内核同步那一章有讲。
    总结:
      可能由于之前操作系统的学习,让我的思想有些固化,对于进程调度和管理这些概念性的内容,即使再看一遍也提不出什么实质性的问题,我除了对内核代码感兴趣之外,其他还是希望观看其他学生提出的问题,希望能帮助他们解决;即使解决不了,那也可以来当做自己的问题处理。相比抽象地学习理论,我还是希望多些代码方面的练习,当然也不是直接像Linux内核这样庞大的代码,起初看到start_kernel 函数时确实吓了一大跳,如果要是在这门课结束之前,我弄不明白这么多代码该怎么办?而且这还只是内核中一部分;而且这个函数中的每个函数还有具体的实现。这样想想,似乎我连入门都没有。还是希望老师多讲解一下我们对这门课应该有的整体把握和方向。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-408214-1-1.html 上篇帖子: linux上快速搭建宝塔面板来操作便捷功能 下篇帖子: 在linux下,怎么去查看一个运行中的程序, 到底是占用了多少内存
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表