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

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. Windows下的包管理器Chocolatey

    参考文档: https://www.jianshu.com/p/831aa4a280e7 https://www.jianshu.com/p/abaa0e8c261f

  2. org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'sessionFactory' is defined

    请检查你在web.xml中加载spring.xml文件的时候没有加载成功,看你的路径是否正确 <context-param>  <param-name>contextConfi ...

  3. 前端PHP入门-021-重点日期函数之日期验证函数

    checkdate可以判断一个输出的日期是否有效. 在实际的工作中,我们需要经常用于检测常用于用户提交表单的数据验证. 函数的语法格式如下: bool checkdate ( int month,in ...

  4. linux下开放端口

    /sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT 将该设置添加到防火墙的规则中 /etc/rc.d/init.d/iptables save

  5. [USACO07FEB] Lilypad Pond

    https://www.luogu.org/problem/show?pid=1606 题目描述 FJ has installed a beautiful pond for his cows' aes ...

  6. 【BZOJ】2243 [SDOI2011]染色

    [算法]树链剖分+线段树 [题解] 树链剖分算法:http://www.cnblogs.com/onioncyc/p/6207462.html 定义线段树结构体有l,r,lc,rc,sum,data. ...

  7. centOS7 vsftp ExecStart=/usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf (code=exited, status=0/SUCCESS) 启动失败问题?

    [root@localhost c]# systemctl status vsftpd.service ● vsftpd.service - Vsftpd ftp daemon Loaded: loa ...

  8. 【洛谷 P2865】 [USACO06NOV]路障Roadblocks(最短路)

    题目链接 次短路模板题. 对每个点记录最短路和严格次短路,然后就是维护次值的方法了. 和这题一样. #include <cstdio> #include <queue> #in ...

  9. 基于Node的Web聊天室

    1 项目名称 Web聊天室(<这是NodeJs实战>第二章的一个案例,把整个开发过程记录下来)

  10. ubuntu永久修改主机名

    1.查看主机名 在Ubuntu系统中,快速查看主机名有多种方法:其一,打开一个GNOME终端窗口,在命令提示符中可以看到主机名,主机名通常位于“@”符号后:其二,在终端窗口中输入命令:hostname ...