攥写人:李鹏举 学号:20179203

原创作品转载请注明出处

( 学习课程:《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 )

一、linux内核源代码

首先来看一下这次实验中用到的Linux内核源代码:

http://codelab.shiyanlou.com/xref/linux-3.18.6/

根据电子课堂的讲述,我从中看到了一些值得注意的几个关键目录

/arch

  • 该目录中包含和硬件体系结构相关的代码,每种平台占一个相应的目录。
  • 和32位PC相关的代码存放在x86目录下。
  • 每种平台至少包含3个子目录:kernel(存放支持体系结构特有的特征实现)、lib(存放体系结构特有的对通用函数的实现)、mm(存放体系结构特有的内存管理程序的实现),除了这3个子目录之外,大多数体系结构在必要的情况下还有一个boot子目录,包含了在这种硬件平台上启动内核所使用的部分或全部平台特有代码。

/init

  • 内核启动相关代码 -> main.c
  • Linux内核启动初始化的起点就位于main.c中的函数start_kernel,相当于普通程序的main函数。

/kernel

  • 存放linux内核最核心的代码,用于实现系统的核心模块,包括进程管理、进程调度器、中断处理、系统时钟管理、同步机制等。
  • 该目录中的代码实现这些核心模块的主体框架,独立于具体的平台和系统架构。
  • 核心模块与平台相关的代码放在arch/中。

(这些是我看了觉得重要,从网上找到的具体注解,还有一些其他的目录项,会随着今后使用慢慢展开)

二、实验过程

首先使用实验楼的虚拟机打开shell

1.cd LinuxKernel/

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

完成启动内核的操作:



其中用到的语句的用处就是启动linux的内核。

qemu -kernel (该版本的Kernel所在路径) -initrd (rootfs.img)**

qemu :相当于打开一个虚拟机

kernel:启动一个内核,位置由其后的文件名指定。

initrd指令:挂了一个ramdisk虚拟硬盘,是内核的重要补充,rootfs.img就是这个虚拟硬盘,内有分区,然后启动其中的init.init是由之前编译而成,gcc -o命名为init。

三、详细分析从start_kernel到init进程启动的过程

start_kernel()函数,相当于C中的main:

void start_kernel(void)
{
………………
page_address_init();
// 内存相关的初始化
trap_init();
mm_init();
………………
// 调度初始化
sched_init();
………………
rest_init(); //其他初始化函数
}

rest_init() 函数:

void rest_init(void)
{
int pid;
………………
kernel_thread(kernel_init, NULL, CLONE_FS);
numa_default_policy();
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
rcu_read_lock();
kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
rcu_read_unlock();
complete(&kthreadd_done); init_idle_bootup_task(current);
schedule_preempt_disabled();
cpu_startup_entry(CPUHP_ONLINE);
}

rest_init()这个函数调用系统函数 kernel_thread() 创建 1 号进程,即 init 进程,是用户态所有进程的父亲。然后,新建 kthreadd 进程,是内核态所有进程的父亲。最后,通过 cpu_startup_entry 函数启动 0 号进程。

分析过程:

           首先,几乎所有的内核模块均会在start_kernel进行初始化。在start_kernel中,会对各项硬件设备进行初始化,包括一些page_address、tick等等,直到最后需要执行的rest_init中,会开始让系统跑起来。那rest_init这个过程中,会调用kernel_thread()来创建内核线程kernel_init,它创建用户的init进程,初始化内核,并设置成1号进程,这个进程会继续做相关的系统初始化。然后,start_kernel会调用kernel_thread并创建kthreadd,负责管理内核中得所有线程,然后进程ID会被设置为2。最后,会创建idle进程(0号进程),不能被调度,并利用循环来不断调号空闲的CPU时间片,并且从不返回。

四、使用gdb跟踪调试内核

在刚刚的基础后进行本次实验:

1.qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S # 关于-s和-S选项的说明:

2.# -S freeze CPU at startup (use ’c’ to start execution)

3.# -s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项

另开一个shell窗口:

1.gdb

2.(gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加载符号表

3.(gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行

4.(gdb)break start_kernel # 断点的设置可以在target remote之前,也可以在之后

实验时的截图使用gdb跟踪调试内核从start_kernel到init进程启动

用b设置断点,用c继续运行到下一个断点:

五、实验总结:

     这次实验有很多不满意的地方,首先我没有成功的在自己的计算机上搭出环境,仍然用的课程中所给的实验楼。当然没有搭出环境的一个重要原因就是我的Linux非常容易崩溃,经常输入密码进入之后就只显示蓝屏,而不显示界面,这其中貌似有我操作不当的原因,还有就是通过查询,发现我所下载版本的Linux与虚拟机选定的环境存在不兼容导致的,之后我下载了其他版本的Linux,目前还未崩溃过,不过本次实验没能来得及在自己的电脑上完成环境的搭建工作;
经过课上老师的讲解,以及多次的实践让我对于gdb的调试过程有了一个较为详细的了解,其中下图是我找到的有关gdb调试相关的基础操作,程序的调试某种程度上说比程序的编写所占比重更大,因此我们应当对于调试的相关步骤熟练掌握,不要总通过在程序中写printf("a")这种方式来找到程序中的问题,而是应当通过设置断点,条件断点等方式,找到程序的问题,对于程序中变量值输出方面的练习做的相对较少,接下来我会重点熟悉这方面,真正做到编程调试工作的熟练掌握。

六、教材笔记

     本周重点关注了教材中第4章和第6章的内容,主要讲述了Linux的进程调度方式和内核的数据结构。
进程的调度来讲整体与过去所学的操作系统中的内容近似,将进程分为了就绪,阻塞,执行多种状态对进程进行相应的操作,并且对不同的进程标明不同的优先级,按照相应的调度算法去执行相应的进程。其中时间片的分配是进程调度最重要需要做完善的地方,如果为每个进程分配固定的时间片,就要注意时间片的大小,时间片过大就会造成进程的大量等待,感受不到多个进程并发执行,而时间片过短又会造成进程调度耗时过长,影响进程的正常运转。而书中重点讲述了Linux的调度实现所采用的CFS调度算法,它重点的采用了选择运行最少的进程作为下一个运行的进程,而不再采用分配给每个进程时间片的做法,每个进程都按其权重在全部可运行进程中所占比例的“时间片”来运行。
而在Linux内核的数据结构的讲述中我看到了相应的一些常见的数据结构:链表、队列、映射、二叉树。其中数据结构的具体实现和描述对于我来说还是相对熟识的,而其中新了解的就是大o符号和大Ɵ符号的使用。大o符号用来描述函数的增长率,我们通过这样的一种函数计算的方式去找到一个算法的执行上限;而大Ɵ符号描述的则更为具体,它所寻找的是最小的上限,虽然我们在大多时候将大o理解为相同的功能,但是实际上大Ɵ符号描述的才是最小上限。这两个函数及其重要,我们通过其评价算法和内核组件在多用户、处理器、进程、网络连接,以及其他环境下伸缩度的重要指标。

2017-2018-1 20179203 《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. PHP fsockopen模拟POST/GET方法

    原文链接:http://www.nowamagic.net/academy/detail/12220214 fsockopen 除了前面小节的模拟生成 HTTP 连接之外,还能实现很多功能,比如模拟  ...

  2. maven;cargo;仓库

    [说明]又到晚上九点了,不得不加快进度,首先就是日报.今天上午在服务器搭建maven,下午完成了一个maven web项目,晚上改错找maven配置问题(因为想装jetty和cargo) 一:今日完成 ...

  3. Spring标签@Aspect-实现面向方向编程(@Aspect的多数据源自动加载)——SKY

    从Spring 2.0开始,可以使用基于schema及@AspectJ的方式来实现AOP.由于@Aspect是基于注解的,因此要求支持注解的5.0版本以上的JDK. 环境要求:    1. mybit ...

  4. 九度OJ 1201:二叉排序树 (二叉树)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:4894 解决:2062 题目描述: 输入一系列整数,建立二叉排序数,并进行前序,中序,后序遍历. 输入: 输入第一行包括一个整数n(1< ...

  5. python基础-第六篇-6.4模块混战

    我们之前接触多的编程方式就是函数式编程,而且喜欢就一个文件里写完所有的程序代码,这样做在前期感觉还不错,不过一旦你的程序变复杂,在易读性和排错方面就感觉好吃力,功能界限不明显,那今天我们就来讲讲怎么用 ...

  6. Maven下载、安装和配置(转发:http://blog.csdn.net/jiuqiyuliang/article/details/45390313)

    准备工作 java开发环境(JDK) maven下载地址:http://maven.apache.org/release-notes-all.html 安装 安装maven超级简单,总共分四步: 下载 ...

  7. Python中PIL及Opencv转化

    转载:http://blog.sina.com.cn/s/blog_80ce3a550102w26x.html Convert between Python tuple and list a = (1 ...

  8. c语言操作mysql数据库

    c语言操作Mysql数据库,主要就是为了实现对数据库的增.删.改.查等操作,操作之前,得先连接数据库啊,而连接数据库主要有两种方法.一.使用mysql本身提供的API,在mysql的安装目录中可可以看 ...

  9. 【LeetCode】数组排列问题(permutations)(附加next_permutation解析)

    描述 Given a collection of distinct integers, return all possible permutations. Example: Input: [1,2,3 ...

  10. 【leetcode刷题笔记】Set Matrix Zeroes

    Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. 题解:因为题 ...