第三章
这一章接触内核源代码,对内核源码进行编译和调试跟踪
一、预备知识:
内核:整个操作系统的最底层,它负责了整个硬件的驱动以及提供各种系统所需的内核功能。内核实质上是系统上面的一个文件而已,这个文件包含了驱动主机各项硬件的检测程序与驱动模块。当系统读完BIOS并加载MBR内的引导装载程序后,就能够加载内核到内存当中。然后内核开始检测硬件,挂载根目录并取得内核模块来驱动所有的硬件,之后调用/sbin/init就能依序启动多有系统所需要的服务了。
Qemu :以GPL许可证分发源码的模拟处理器,能启动那些为不同中央处理器编译的Linux程序。

二、构造一个简单的Linux内核
构造的MenuOS系统是由Linux内核镜像和根文件系统集成起来的。
Linux内核在PC上以文件的形式存在(保存成磁盘文件形式),就是所谓的“映像文件”。内核编译(make)之后会生成两个文件,一个Image,一个zImage,其中Image为内核映像文件,而zImage为内核的一种映像压缩文件,Image大约为4M,而zImage不到2M。为了能使用zImage这个压缩版本,必须在它的开头加上解压缩的代码,将zImage 解压缩之后才能执行,因此它的执行速度比Image要慢。但考虑到嵌入式系统的存储空容量一般都比较小,内核要常驻内存,采用zImage可以占用较少的存储空间,因此牺牲一点性能上的代价也是值得的,所以一般嵌入式系统均采用压缩的内核映像文件,即zImage。
根文件系统首先是一种文件系统,该文件系统不仅具有普通文件系统的存储数据文件的功能,但是相对于普通的文件系统,它的特殊之处在于,它是内核启动时所挂载(mount)的第一个文件系统,内核代码的映像文件保存在根文件系统中,系统引导启动程序会在根文件系统挂载之后从中把一些初始化脚本(如rcS,inittab)和服务加载到内存中去运行。先将/dev/ram0挂载,而后执行/linuxrc.等其执行完后。切换根目录,再挂载具体的根文件系统.根文件系统执行完之后,也就是到了Start_kernel()函数的最后,执行init的进程,也就第一个用户进程。对系统进行各种初始化的操作。

在实验楼中的虚拟机里,直接进入LinuxKernel目录使用如下命令就可以运行Linux内核源码和跟文件系统

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

其中bzImage是vmlinux经过gzip压缩后的文件,适用于大内核;vmLinux是编译出来的最原始的内核ELF文件;initrd是内存根文件系统,只创建了一个rootfs.img,其中只有一个init的功能,用menu程序替代init, 内核启动完成后进入menu程序。

三、跟踪调试Linux内核的启动过程
Qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rotes.img -s -S

-S CPU初始化之前将其冻结起来

-s 是默认在tcp::1234端口上创建了一个gdb-server

再打开一个窗口,启动gdb,把内核加载进来,建立连接
file linux-3.18.6/vmlinux #把带有符号表的内核镜像加载进来
target remote:1234 #用tcp:1234端口来链接gdb server

然后在start_kernel函数和rest_init处设置端点,调试运行

四、对于start_kernel( )和rest_init( )的分析
start_kernel( )相当于main.c中的main函数,是首先运行的,在此函数调用之前,内核代码主要是汇编语言编写的,用于完成硬件系统的初始化工作,为C代码的运行设置环境。这个函数主要进行各个模块初始化工作,trap_init()(中断向量的初始化)、mm_init()(内存管理的初始化)sched_init()(调度模块的初始化)等。
init_task() :0号进程,初始化的起点
struct task_struct init_task = INIT_TASK(init_task);
可以看出 init_task(0号进程)是 task_struct 类型,是进程描述符,使用宏INIT_TASK对其进行初始化,并且init_task是唯一没有通过fork方式产生的进程。

rest_init( ):
在此函数中调用kernel_thread进程来创建kernel_init和kthreadd内核线程

kernel_init()内核线程为1号内核线程,负责执行内核的部分初始化工作及进行系统配置,最后调用do_execve加载init程序,最后演变成用户态1号进程——init进程。
kthreadd()函数的任务是管理和调度其他内核线程 kernel_thread。for 循环中运行 kthread_create_list 全局链表中维护的 kthread, 在create_kthread()函数中,会调用 kernel_thread 来生成一个新的进程并被加入到此链表中,因此所有的内核线程都是直接或者间接的以 kthreadd 为父进程。
小结:
本周学习了Linux内核源代码,对于内核的源代码目录,编译过程有了进一步的了解,但在学习中总会遇到新的问题,例如kernel_thread进程是由init零号进程fork出来的,以及idle进程与0号进程的关系,内核线程与用户进程的区别,这些问题在CSDN论坛中大部分都以解决,但发现内核内部的知识非常高深,还需多多查阅资料

2018-2019-1 20189210 《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. 2019-2020-1 20199329《Linux内核原理与分析》第十三周作业

    <Linux内核原理与分析>第十三周作业 一.本周内容概述 通过重现缓冲区溢出攻击来理解漏洞 二.本周学习内容 1.实验简介 注意:实验中命令在 xfce 终端中输入,前面有 $ 的内容为 ...

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

    <Linux内核原理与分析>第十二周作业 一.本周内容概述: 通过编程理解 Set-UID 的运行机制与安全问题 完成实验楼上的<SET-UID程序漏洞实验> 二.本周学习内容 ...

随机推荐

  1. Maven安装及配置

    第1部分 准备 1.1 安装JDK和Eclipse: 1.2 下载Maven(https://maven.apache.org/download.cgi) 第2部分 2.1 安装Maven 2.1.1 ...

  2. AS中的minSdkVersion、compileSdkVersion、targetSdkVersion、buildTools及tools关系和区别

    1.参考文章关于compileSdk.minSdk.targetSdk的文章 http://chinagdg.org/2016/01/picking-your-compilesdkversion-mi ...

  3. 过滤器实现 (cookie认证)

    cookie用来做身份认证,非常好用,只需要设置Authentication和Authorization就行了. 但是 ,如果cookie不能用了,怎么办?  不要紧,我们也可以用过滤器进行身份认证. ...

  4. lucene学习的小结

    pom.xml设置 <dependency> <groupId>junit</groupId> <artifactId>junit</artifa ...

  5. 题解-CodeChef IOPC14L Sweets Problem

    Problem CodeChef-IOPC14L 题目概要:给定 \(n\) 种糖果且给定每种糖果的数量 \(A_i\),\(Q\) 组询问,每次问选出 \(S\) 个糖果的方案数(模\(10^9+7 ...

  6. unity setactive的使用

    1.可以用本身移出布局来实现隐藏 2.RawImage的texture的设置生成的一定要及时消除,避免内存泄漏

  7. CentOS7上部署taiga项目管理软件

    作者:waringid 一.简介 Taiga 是一个免费开源,而且功能非常强大的项目管理平台,用于初创企业和敏捷开发团队.提供一个简单.漂亮的项目管理工具.Taiga 采用 Python Django ...

  8. linear-gradient 纯CSS3项目价格表切换代码

    <!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8&qu ...

  9. KNN与K-Means的区别

    KNN(K-Nearest Neighbor)介绍 Wikipedia上的 KNN词条 中有一个比较经典的图如下: KNN的算法过程是是这样的: 从上图中我们可以看到,图中的数据集是良好的数据,即都打 ...

  10. kali linux networking scanning Cookbok (第三章结尾笔记)

    1.Zombie Scanning with Nmap Zombie scans can also be performed with an option in Namp ,  we can find ...