一、跟踪分析内核的启动过程实验 :

1.启动Menuos:

qemu仿真kernel:

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img

知识补充:

(1)bzImage 是 vmlinux 经过 gzip 压缩后的文件,是压缩的内核映像,“b”代表的是“big”(bzImage 适用于大内核,zImage 适用于小内核)。vmlinux 是编译出来的最原始的内核ELF文件;

(2)根文件系统包括虚拟根文件系统和真实根文件系统。initrd 是“initial ramdisk”的简写,boot loader 将存储介质中的 initrd 文件加载到内存,内核启动时先访问 initrd 文件系统(虚拟的文件系统),然后再切换到真实的文件系统。

2.调试跟踪:

-S  开始处冻结CPU,方便调试
-s 使用tcp端口1234来进行通讯,将进程信息传过去(在后面的调试中会用到)。若不想使用1234端口,可以使用-gdb tcp:xxxx来取代-s选项

启动gdb,把内核加载进来,建立连接:

file linux-3.18.6/vmlinux

target remote:1234

实践过程中出现以下错误:

连接超时应该是没连接上冻结的系统,检查后发现进入gdb调试前讲QEMU窗口关闭了,打开后得以解决:

在 start_kernel 处设置断点,继续执行,停在断点处:

在 rest_init 处设置断点,继续执行,停在断点处:

3.内核启动分析(自己的大致理解):

(1)start_kernel()

main.c 中没有 main 函数,start_kernel() 相当于是C中的main函数。start_kernel是一切的起点,在此函数被调用之前内核代码是用汇编语言写的,完成系统的初始化工作,为c代码的运行设置环境。由调试可得 start_kernel 在500行:

(2)init_task()

start_kernel() 函数几乎涉及到了内核的所有模块,如:trap_init()(中断向量的初始化)、mm_init()(内存管理的初始化)sched_init()(调度模块的初始化)等,首先是510行的init_task():

struct task_struct init_task = INIT_TASK(init_task);

可以看出 init_task(0号进程)是 task_struct 类型,是进程描述符,使用宏INIT_TASK对其进行初始化。接下来就是对各种模块的初始化:

            图片来源于分析Linux内核的启动过程

(3)rest_init()

通过rest_init()新建kernel_init、kthreadd内核线程:

403行代码 kernel_thread(kernel_init, NULL, CLONE_FS);,由注释得调用 kernel_thread()创建1号内核线程(在 kernel_init 函数正式启动):

注:对比 init_task 和 kernel_thread()

kernel_thread()是 fork 出了一个新进程来执行kernel_init 函数,而 init_task 是使用宏进行初始化的。也就是说0进程不是系统通过 kernel_thread 的方式(也就是 fork)创建的(init_task 是唯一一个没有通过 fork()产生的进程)。

405行代码 pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);1 调用 kernel_thread()执行 kthreadd函数,创建 PID=2的内核线程:

此函数的任务是管理和调度其他内核线程 kernel_thread。for 循环中运行 kthread_create_list 全局链表中维护的 kthread, 在create_kthread()函数中,会调用 kernel_thread 来生成一个新的进程并被加入到此链表中,因此所有的内核线程都是直接或者间接的以 kthreadd 为父进程。

4.总结:

(1)init_task()(PID=0)在创建了init进程后,调用 cpu_idle() 演变成了idle进程,执行一次调度后,init进程运行;

(2)1号内核线程负责执行内核的部分初始化工作及进行系统配置,最后调用do_execve执行 init 函数,演变成 init 进程(用户态1号进程),init 进程是内核启动的第一个用户级进程;

(3)kthreadd(PID=2)进程由0号进程创建,始终运行在内核空间, 负责所有内核线程的调度和管理 。

注:Linux下的进程类别(内核线程、轻量级进程和用户进程)以及其创建方式

参考:

Linux下0号进程的前世(init_task进程)今生(idle进程)

Linux下1号进程的前世(kernel_init)今生(init进程)

Linux下2号进程的kthreadd

二、课本笔记:

1.进程调度:

  进程调度程序是在可运行态进程之间分配有限的处理器时间资源的内核子系统。Linux提供了抢占式的多任务模式,在此模式下,由调度程序决定一个进程的运行,以便其他进程能得到执行机会(抢占:抢占的挂起动作)。进程在被抢占前能运行的时间叫做进程的时间片,即分配给每个可运行进程的处理器时间段。

  Linux内核将进程分成普通进程和实时进程。普通进程用nice值表示时间片的比例(CFS调度器将处理器的时间比划分给了进程,越大的nice值将被赋予低权重,丧失一小部分的处理器时间使用比);实时进程采用实时优先级,数值越高优先级越高(两种实时调度策略为SCHED_FIFO和SCHED_RR,SCHED_RR是带有时间片的SCHED_FIFO)。任何实时进程的优先级都高于普通进程。

  CFS虽没有时间片的概念,但必须维护每个进程运行的时间记账,它会挑一个具有最小vruntime(存放进程的虚拟运行时间)的进程(利用红黑树迅速找到最小vruntime值的进程)进行调度。休眠(被阻塞)进程把自己标记成休眠状态,从可执行红黑树中移出,放入等待队列,然后调用schedule()选择和执行其他进程,唤醒时被置成可执行状态,然后再从等待队列中移到可执行红黑树中。

  当内核即将返回用户空间时,内核会检查need_resched是否设置,如果设置,则调用schedule(),发生用户抢占。 内核抢占是指在内核态运行的进程在执行期间可能被另一个进程取代(没有读懂课本对内核抢占的解释,参照Linux用户抢占和内核抢占详解(概念, 实现和触发时机),如果内核处于相对耗时的操作中, 比如文件系统或者内存管理相关的任务, 其他进程无法执行, 无法调度, 这就造成了系统的延迟增加, 用户体验到”缓慢”的响应。比如如果多媒体应用长时间无法得到CPU, 则可能发生视频和音频漏失现象.启用内核抢占可解决此问题)

2.内核数据结构:

(1)Linux内核链表不同于传统链表,它不是将数据结构塞入链表,而是将链表结点塞入数据结构:

(2)Linux内核通用队列实现成为kfifo,提供enqueue和dequeue,kfifo对象维护入口偏移和出口偏移两个偏移量;

(3)Linux映射一个唯一的标识数(UID)到一个指针(有点像字典类型,每个唯一的id对应一个自定义的数据结构);

(4)红黑树和平衡二叉树的区别在于它使用颜色来标识结点的高度,它所追求的是局部平衡而不是平衡二叉树中的非常严格的平衡。(课本上对红黑树的描述我也没有看明白,查阅资料数据结构之红黑树,了解了红黑树的性质(根是黑色;所有叶子都是黑色(叶子是NIL节点);如果一个节点是红的,则它的两个儿子都是黑的;从任一节点到其叶子的所有简单路径都包含相同数目的黑色节点)及红黑树的插入删除。虽然红黑树追求的是局部平衡,但我感觉和平衡二叉树的插入删除还是难了点,也有可能是刚接触的原因QAQ)

三、小结:

  本周学习中遇到了很多不明白的指令和术语,一边实践一边查阅资料,在阅读资料中又会由此引出新的问题(如在搜索init进程中看到先是内核线程又是用户进程,然后如果不理解二者区别,就没法弄明白1号进程的前世今生,只能继续搜索内核线程和用户进程的区别)过程辛苦,但好在问题大部分得以解决,还有小部分需要再强化理解。

2017-2018-1 20179202《Linux内核原理与分析》第四周作业的更多相关文章

  1. 2019-2020-1 20199303<Linux内核原理与分析>第二周作业

    2019-2020-1 20199303第二周作业 1.汇编与寄存器的学习 寄存器是中央处理器内的组成部份.寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令.数据和位址.在中央处理器的控制部件中 ...

  2. 20169219 linux内核原理与分析第二周作业

    "linux内核分析"的第一讲主要讲了计算机的体系结构,和各寄存器之间对数据的处理过程. 通用寄存器 AX:累加器 BX:基地址寄存器 CX:计数寄存器 DX:数据寄存器 BP:堆 ...

  3. 2019-2020-1 20199314 <Linux内核原理与分析>第二周作业

    1.基础学习内容 1.1 冯诺依曼体系结构 计算机由控制器.运算器.存储器.输入设备.输出设备五部分组成. 1.1.1 冯诺依曼计算机特点 (1)采用存储程序方式,指令和数据不加区别混合存储在同一个存 ...

  4. Linux内核原理与分析-第一周作业

    本科期间,学校开设过linux相关的课程,当时的学习方式主要以课堂听授为主.虽然老师也提供了相关的学习教材跟参考材料,但是整体学下来感觉收获并不是太大,现在回想起来,主要还是由于自己课下没有及时动手实 ...

  5. 2019-2020-1 20199314 <Linux内核原理与分析>第一周作业

    前言 本周对实验楼的Linux基础入门进行了学习,目前学习到实验九完成到挑战二. 学习和实验内容 快速学习了Linux系统的发展历程及其简介,学习了下的变量.用户权限管理.文件打包及压缩.常用命令的和 ...

  6. Linux内核原理与分析-第二周作业

    写之前回看了一遍秒速五厘米:如果

  7. 20169219linux 内核原理与分析第四周作业

    系统调用 系统调用是用户空间访问内核的唯一手段:除异常和陷入外,它们是内核唯一的合法入口. 一般情况下,应用程序通过在用户空间实现的应用编程接口(API)而不是直接通过系统调用来编程. 要访问系统调用 ...

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

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

  9. 20169212《Linux内核原理与分析》课程总结

    20169212<Linux内核原理与分析>课程总结 每周作业链接汇总 第一周作业:完成linux基础入门实验,了解一些基础的命令操作. 第二周作业:学习MOOC课程--计算机是如何工作的 ...

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

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

随机推荐

  1. 即时通信系统Openfire分析之一:Openfire与XMPP协议

     引言 目前互联网产品使用的即时通信协议有这几种:即时信息和空间协议(IMPP).空间和即时信息协议(PRIM).针对即时通讯和空间平衡扩充的进程开始协议SIP(SIMPLE)以及XMPP.PRIM与 ...

  2. 枚举工具类 EnumUtils

    这是一个枚举工具类,有时候一个枚举自身为空,我们程序在调用他的方法时(如:name(),ordinal()),就会报空指针异常:下面写这个工具类就是为了来避免这些问题的,有些外部引用的没有贴出来,不过 ...

  3. HDU 4704 欧拉定理

    题目看了很久没看懂 就是给你数n,一种函数S(k),S(k)代表把数n拆成k个数的不同方案数,注意如n=3,S(2)是算2种的,最后让你求S(1~n)的和模1e9+7,n<=1e100000.那 ...

  4. 重构改善既有代码设计--重构手法05:Introduce Explaining Variable (引入解释性变量)

      发现:你有一个复杂的表达式. 解决:将该复杂的表达式(或其中的部分)的结果放进一个临时变量,并以此变量名称来解释表达式用途. //重构前 if((platform.toUpperCase().in ...

  5. 【BZOJ】1040: [ZJOI2008]骑士 环套树DP

    [题意]给定n个人的ai和bi,表示第i个人能力值为ai且不能和bi同时选择,求能力值和最大的选择方案.n<=10^6. [算法]环套树DP(基环树) [题解]n个点n条边——基环森林(若干环套 ...

  6. 微信小程序开发(一)准备开发环境

    1.成为微信公众平台开发者 成为微信公众平台的开发者,是小程序开发的首要条件.只有成为微信公众平台的开发者,才可以使用公众平台的各种开发接口.如果你已经是开发者,则可以跳过本章. (1)进入微信公众平 ...

  7. composer 上提交自己的包

    先在github上复制自己的地址在 https://packagist.org/packages/submit ->check->submit

  8. 【洛谷 P3648】 [APIO2014]序列分割 (斜率优化)

    题目链接 假设有\(3\)段\(a,b,c\) 先切\(ab\)和先切\(bc\)的价值分别为 \(a(b+c)+bc=ab+bc+ac\) \((a+b)c+ab=ab+bc+ac\) 归纳一下可以 ...

  9. 使用OpenCV和Python进行人脸识别

    介绍 人脸识别是什么?或识别是什么?当你看到一个苹果时,你的大脑会立刻告诉你这是一个苹果.在这个过程中,你的大脑告诉你这是一个苹果水果,用简单的语言来说就是识别.那么什么是人脸识别呢?我肯定你猜对了. ...

  10. php查询mysql返回大量数据结果集导致内存溢出的解决方法

    web开发中如果遇到php查询mysql返回大量数据导致内存溢出.或者内存不够用的情况那就需要看下MySQL C API的关联,那么究竟是什么导致php查询mysql返回大量数据时内存不够用情况? 答 ...