1.在自己的linux系统中搭建实验环境;

2.使用GDB调试内核跟踪启动过程;

3.分析start_kernel的代码。



1.在自己的linux系统中搭建实验环境

1.1 下载linux-3.18.6的内核源码,并且编译

cd ~/LinuxKernel/  wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.18.6.tar.xz
xz -d linux-3.18.6.tar.xz
tar -xvf linux-3.18.6.tar
cd linux-3.18.6
make i386_defconfig
make # 一般要编译很长时间,少则20分钟多则数小时

1.2 制作根文件系统

cd ~/LinuxKernel/
mkdir rootfs
git clone https://github.com/mengning/menu.git
cd menu
gcc -o init linktable.c menu.c test.c -m32 -static –lpthread
cd ../rootfs
cp ../menu/init ./
find . | cpio -o -Hnewc |gzip -9 > ../rootfs.img

1.3 启动MenuOS

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

2.使用GDB调试内核跟踪启动过程。

在使用gdb跟踪调试内核之前需要先重新配置编译Linux使其携带调试信息。 由于make menuconfig需要ncurses-dev和tk4-dev库。 所以我们先输入命令sudo apt-get install ncurses-dev 和sudo apt-get install tk4-dev,然后输入make menuconfig进入Kernel Configuration界面 。

选择Kernel hacking进入

选择Compile-time checks and compilr options —>进入

按Y选择Compile the kernel with debug info 然后执行make重新编译内核。 编译完成之后输入以下的命令,让CPU冻结在开始的时候。

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S # 关于-s和-S选项的说明:
# -S freeze CPU at startup (use ’c’ to start execution)
# -s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项

然后打开GDB远程调试,另外开启一个终端 ,输入gdb

(gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加载符号表
(gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行
(gdb)break start_kernel # 断点的设置可以在target remote之前,也可以在之后

在start_kernel设上断点,然后 ,(gdb)c 继续执行到达断点处 ,输出(gdb)list显示出上下文

我们继续设置断点, break rest_init() ,然后输入c执行到断点处 ,然后输入list显示出上下文。

代码分析补充



3.分析start_kernel的代码

从 start_kernel 开始到 init 进程启动

set task stack end magic() #为了检测栈溢出

smp setup processor_id() #设置对称多处理器

cgroup init early () #初始化 Control Groups

page address init() #页地址初始化(属于内存管理部分)

setup log buf () #初始化log 缓冲区(kernel/printk/printk.c)

pidhash_init ()	#初始化 pid 哈希表

trap_init () #初始化中断向量

mm_init () #内存管理初始化

sched_init () #调度服务初始化

rest_init() #剩余初始化

- kernel_init:init进程
- kthreadd:内核线程
- cpu_idle进程:代码中一直循环,如果系统中没有可执行的进程时,执行 idle 进程

总结

在 start kernel执行到最后部分时,在 rest init 中 新建了kernel_init 进程, kernel_thread(kernel_init, NULL, CLONE_FS); ,init 进程是系统中的1号进程,是以后所有用户态进程的祖先,然后新建kthreadd进程, pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); ,kthreadd 作为2号进程,是所有内核线程的祖先,在 cpu_startup_entry(CPUHP_ONLINE) 中,是一个 while(1) 循环,始终有一个 idle 进程在执行,如果系统还总没有任何可以执行的进程时,idle 进程会执行。

最后引用孟宁老师的一段话:

道生一:(start kernel)

二生三:(即0,1,2号进程)

三生万物:(1号进程是所有用户态进程祖先,2号进程是所有内核线程祖先)

20169211《Linux内核原理与分析》第五周作业的更多相关文章

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

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

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

    <Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...

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

    2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...

  4. 2017-2018-1 20179215《Linux内核原理与分析》第二周作业

    20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...

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

    <Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...

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

    <Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...

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

    2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...

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

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

  9. 《Linux内核原理与分析》第一周作业 20189210

    实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...

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

    读书报告 <庖丁解牛Linux内核分析> 第 1 章 计算工作原理 1.1 存储程序计算机工作模型 1.2 x86-32汇编基础 1.3汇编一个简单的C语言程序并分析其汇编指令执行过程 因 ...

随机推荐

  1. java项目中Excel文件预览

    package com.linkonworks.df.busi.utils; import java.io.File; import java.io.FileInputStream; import j ...

  2. @Controller,@Service,@Repository,@Component详解

    @Controller 用来表示一个web控制层bean,如SpringMvc中的控制器. @Service 用来表示一个业务层bean. @Repository 用来表示一个持久层bean,即数据访 ...

  3. Android 动态添加线性布局(.java文件内) 实现控件按比例分割空间

    这里实现 两个 编辑框同一水平上 按1:1分割空间 这里的1:1 比例可以通过 lp1.weight :  1p2.weight  =m:n 实现 { LinearLayout l=new Linea ...

  4. 【BZOJ】2006: [NOI2010]超级钢琴

    [题意]给定长度为n的整数序列,求长度为[L,R]的前k大区间和的和.n,k<=500000. [算法]堆+贪心+RMQ [题解]考虑暴力是取所有长度为[L,R]的子串的前k大求和,复杂度O(n ...

  5. 【BZOJ】4559: [JLoi2016]成绩比较 计数DP+排列组合+拉格朗日插值

    [题意]n位同学(其中一位是B神),m门必修课,每门必修课的分数是[1,Ui].B神碾压了k位同学(所有课分数<=B神),且第x门课有rx-1位同学的分数高于B神,求满足条件的分数情况数.当有一 ...

  6. CodeForces - 1009B Minimum Ternary String

    You are given a ternary string (it is a string which consists only of characters '0', '1' and '2'). ...

  7. 【leetcode 简单】 第八十四题 两个数组的交集

    给定两个数组,编写一个函数来计算它们的交集. 示例 1: 输入: nums1 = [1,2,2,1], nums2 = [2,2] 输出: [2] 示例 2: 输入: nums1 = [4,9,5], ...

  8. 天梯赛 L2-013. (并查集) 红色警报

    题目链接 题目描述 战争中保持各个城市间的连通性非常重要.本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报.注意:若该国本来就不完全连通,是分裂的k个区域 ...

  9. 字典树&&01字典树专题&&对字典树的理解

    对于字典树和01字典树的一点理解: 首先,字典树建树的过程就是按照每个数的前缀来的,如果你要存储一个全小写字母字符串,那么这个树每一个节点最多26个节点,这样的话,如果要找特定的单词的话,按照建树的方 ...

  10. vue引入jquery的方法

    1.局部引入 通过命令下载jquery   npm install jquery --save-dev 在需要引入jquery的组件中通过import $ from 'jquery'引入即可 2.全局 ...