第三周 构造一个简单的Linux系统MenuOS

计算机三个法宝:

1、存储程序计算机

2、函数调用堆栈

3、中断

操作系统两把宝剑:

1、中断上下文的切换:保存现场和恢复现场

2、进程上下文的切换

一、阅读Linux内核代码

本周我们要学习如何阅读Linux内核源代码,首先打开Lstest Stable Kernel:linux-3.18.6

arch/目录在Linux内核中占有相当庞大的代码量,因为Linux支持很多CPU,这个arch/x86目录下的代码是我们重要关注的代码

根目录中比较关键的目录:

  • Documentation/文档
  • fs/文件系统
  • init/内核启动相关的代码基本都在init目录下,里面的main.c是整个Linux内核启动的起点。它的起点是start_kernel

start_kernel函数相当于普通C程序的main函数

如上图所示,第500行这里就是初始化Linux内核的起点,之前的部分是汇编做硬件初始化。

  • ipc/进程间通信
  • kernel/Linux内核的核心代码在kernel目录中
  • lib/公用的库文件
  • mm/memmory management内存管理
  • net/与网络相关的代码
  • security/与安全相关的代码
  • scripts/脚本

以上加粗的部分为我们重点关注的。

二、构造一个简单的Linux系统MenuOS

方法一:使用实验楼的虚拟机打开shell

linux-3.18.6.tar就是内核源代码,rootfs里面有用menu编译好的init可执行文件,rootfs.img是它生成的。

该系统支持三条命令:help、version和quit

输入help会有以下三条命令

使用gdb跟踪调试内核

输入以下命令

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

-S表示:在CPU初始化之前,冻结CPU

-s表示在:1234端口上创建一个tcp接口

如图所示,是被冻结状态的。

水平分割,再打开一个shell窗口,输入gdb

这里注意:视频中孟老师是直接进入了LinuxKernel文件夹,我们要在实验楼中进入LinuxKernel再gdb,否则会显示找不到文件。

输入(gdb)file linux-3.18.6/vmlinux

在targe remote之前加载符号表

Reading后,连接到刚启动的被冻结的linux系统,设置断点,把内核启动的起点start_kernel设为断点,在init/main.c文件中,第501行

输入c,回车,系统从冻结状态开始执行,启动。

输入list,可以看见start_kernel代码上下的这段代码

再设一个断点rest_init,按c继续执行

系统已经执行到rest_init

输入list,看rest_init前后的代码

在start_kernel尾部被调用

方法二:使用自己的Linux系统环境搭建MenuOS

首先,下载内核源代码编译内核,大概几百M

接下来,make,大概会make20多分钟

下面,制作根文件系统,我首先尝试了孟老师的第一种方法,在GitHub上注册账号,登录,然而显示Error 403

之后,我用第二种办法,在课程的“课件”页面,底部单击“下载附件”

下载menu.zip,并共享到虚拟机中去

继而,gcc编译

在rootfs文件夹出现了编译出的镜像文件

由于自己的虚拟机缺少配置,不能进行下去了

三、简单分析一下start_kernel

首先设置全局变量init task,相当于手工创建的PCB,0号进程就是最终的idle进程,0号进程创建了1号进程和其他线程

trap_init();初始化一些中断向量

mm_init() 内存管理模块

sched_init() 调度模块

其中,在x86中,设置了很多中断门

还设计系统陷阱门,系统调用的,也是一种中断

rest_init

kernel_init里面的run_init_process就是linux系统的1号进程,第一个用户态进程,默认根目录下的init程序

kernel_init不仅创建了1号进程,还创建了kthreadd内核线程,来管理系统资源

系统进入了内核启动rest_init,call into cpu_idle

这里的cpu_idle_loop就是进入了while(0)的无限循环,就是idle0号进程。它一直存在在系统中,当没有进程需要执行时,就调度到idle进程。

总结:rest_init就是start_kernel内核启动时一直存在,即为0号进程。0号进程创建了1号进程kernel_init以及其他的服务线程。“道生一(start_kernel....cpu_idle)、一生二(kernel_init和kthreadd)、二生三(即前面0、1和2三个进程)、三生万物(1号进程是所有用户态进程的祖先,2号进程是所有内核线程的祖先)”,内核就启动了。

Linux内核分析——第三周学习笔记20135308的更多相关文章

  1. Linux内核分析第三周学习笔记

    linux内核分析第三周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...

  2. 20135320赵瀚青LINUX内核分析第三周学习笔记

    赵瀚青原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 概述 本周是学习的主要是构造 ...

  3. Linux内核分析——第三周学习笔记

    20135313吴子怡.北京电子科技学院 chapter1 知识点梳理 一.Linux内核源代码简介 (视频中对目录下的文件进行了简介,记录如下) arch目录 占有相当庞大的空间 arch/x86目 ...

  4. Linux内核分析——第七周学习笔记20135308

    第七周 可执行程序的装载 一.预处理.编译.链接和目标文件的格式 1.可执行程序是怎么来的 C代码—>预处理—>汇编代码—>目标代码—>可执行文件 .asm汇编代码 .o目标码 ...

  5. Linux内核分析——第八周学习笔记20135308

    第八周 进程的切换和系统的一般执行过程 一.进程切换的关键代码switch_to分析 1.进程调度与进程调度的时机分析 (1)进程分类 第一种分类 I/O-bound:等待I/O CPU-bound: ...

  6. Linux内核分析——第六周学习笔记20135308

    第六周 进程的描述和进程的创建 一.进程描述符task_struct数据结构 1.操作系统三大功能 进程管理 内存管理 文件系统 2.进程控制块PCB——task_struct 也叫进程描述符,为了管 ...

  7. 《Linux内核分析》第二周学习笔记

    <Linux内核分析>第二周学习笔记 操作系统是如何工作的 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/ ...

  8. linux内核分析第五周学习笔记

    linux内核分析第五周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...

  9. Linux内核分析第六周学习笔记——分析Linux内核创建一个新进程的过程

    Linux内核分析第六周学习笔记--分析Linux内核创建一个新进程的过程 zl + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...

随机推荐

  1. apache 虚拟主机及phpmyadmin 配置

    NameVirtualHost *:80 <VirtualHost *:80> ServerName www.ly.comDocumentRoot E:/mywww </Virtua ...

  2. Gold Point Game~~

    黄金点游戏 1. 队友博客链接 GitHub链接 2.过程总结 (1)俩人各自所做工作?对方编程习惯总结(是否遵照代码规范.是否关注算法效率.是否做了代码复审.界面设计是否关注美观实用等等): 这次作 ...

  3. C++课堂作业_02_PAT1025.反转链表

    The 1st classwork of the C++ program 题目:PAT.1025.反转链表 github链接:Click Here mdzz,做完题目的第一感受= = 这道题的题意就是 ...

  4. Universal-Image-Loader源码分析(一)——ImageLoaderConfiguration分析

    UIl与Volley一样是非常古老的框架,UIL实现了从网络获取图片,对图片进行缓存,以及根据个性化的设置来将图片加载到ImageView上. 这篇文章 主要分析UIl在初始化配置的源码 UIL初始化 ...

  5. Scala学习之路 (八)Scala的隐式转换和隐式参数

    一.概念 Scala 2.10引入了一种叫做隐式类的新特性.隐式类指的是用implicit关键字修饰的类.在对应的作用域内,带有这个关键字的类的主构造函数可用于隐式转换. 隐式转换和隐式参数是Scal ...

  6. post请求体过大导致ngx.req.get_post_args()取不到参数体的问题

    http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size 该地址对于client_body_buf ...

  7. PAT B1005 继续(3n+1)猜想 (25 分)

    卡拉兹(Callatz)猜想已经在1001中给出了描述.在这个题目里,情况稍微有些复杂. 当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数.例如对 n=3 进行验证的时 ...

  8. [笔记] ubuntu下添加windows的字体

    方法如下: 第一步:将windows下喜欢的字体文件copy到一个文件夹中,例如将XP里WINDOWS/FONTS中的字体文件(本人比较贪心,把整个文件夹copy了过来……),在linux中命名为xp ...

  9. Multi account chang login with multi -thread

    void worker_DoWork(object sender, DoWorkEventArgs e) { isBussy = true; if (Common.isChangingAccount) ...

  10. MFC 如何为控件关联变量

    所关联的变量常见有两种,一种就是控件变量,一种就是数字变量. 为控件关联变量的方法也有两种,一种是通过软件工具添加,一种是手动添加代码. 软件工具添加,方便简单,但是根据软件的版本不同,以及不同的空间 ...