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. 苏宁OLAP架构设计

    一. 功能综述 OLAP引擎为存储和计算二合一的引擎,自身内部涵盖了对数据的管理以及提供查询能力.底层数据完全规划在引擎内部,外部系统不允许直接操作底层数据,而是需要通过暴露出来的接口来读写引擎内部数 ...

  2. 经典Dialog插件Layer

    Github上只有一个test,所以最好还是到官网去学习,官网的示例写的很详尽,难得一见的设计思路和灵活性都极好的插件.下面是我自己test过的demo <!DOCTYPE html> & ...

  3. Centos7 设置静态IP后重启网络服务出错

    systemctl restart networkJob for network.service failed because the control process exited with erro ...

  4. [转载]内存的一些magic number和debug crt

    原文:http://www.360doc.com/content/13/0105/17/6295074_258392439.shtml 调试过debug版本的vc程序的人一定对0xCCCCCCCC和0 ...

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

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

  6. Is It A Tree? 挂着并查集的帽子招摇撞骗

    Description A tree is a well-known data structure that is either empty (null, void, nothing) or is a ...

  7. Xor Sum(HDU4825 + 字典树)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4825 题目: 题意: 先给你n个数,再进行q次查询,每次查询数s与原来给的n个数异或和最大的数. 思 ...

  8. HDU 1561 The more, The Better (有依赖背包 || 树形DP)

    题目链接 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物.但由于地理位 ...

  9. python 进程 线程 协程

    并发与并行:并行是指两个或者多个事件在同一时刻发生:而并发是指两个或多个事件在同一时间间隔内发生.在单核CPU下的多线程其实都只是并发,不是并行. 进程是系统资源分配的最小单位,进程的出现是为了更好的 ...

  10. 最短路径之迪杰斯特拉(Dijkstra)算法

    对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点为源点,最后一个顶点为终点.最短路径的算法主要有迪杰斯特拉(Dijkstra)算法和弗洛伊德(Floyd ...