2017-2018-1 20179203 《Linux内核原理与分析》第四周作业
攥写人:李鹏举 学号: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内核原理与分析》第四周作业的更多相关文章
- 2019-2020-1 20199303<Linux内核原理与分析>第二周作业
2019-2020-1 20199303第二周作业 1.汇编与寄存器的学习 寄存器是中央处理器内的组成部份.寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令.数据和位址.在中央处理器的控制部件中 ...
- 20169219 linux内核原理与分析第二周作业
"linux内核分析"的第一讲主要讲了计算机的体系结构,和各寄存器之间对数据的处理过程. 通用寄存器 AX:累加器 BX:基地址寄存器 CX:计数寄存器 DX:数据寄存器 BP:堆 ...
- 2019-2020-1 20199314 <Linux内核原理与分析>第二周作业
1.基础学习内容 1.1 冯诺依曼体系结构 计算机由控制器.运算器.存储器.输入设备.输出设备五部分组成. 1.1.1 冯诺依曼计算机特点 (1)采用存储程序方式,指令和数据不加区别混合存储在同一个存 ...
- Linux内核原理与分析-第一周作业
本科期间,学校开设过linux相关的课程,当时的学习方式主要以课堂听授为主.虽然老师也提供了相关的学习教材跟参考材料,但是整体学下来感觉收获并不是太大,现在回想起来,主要还是由于自己课下没有及时动手实 ...
- 2019-2020-1 20199314 <Linux内核原理与分析>第一周作业
前言 本周对实验楼的Linux基础入门进行了学习,目前学习到实验九完成到挑战二. 学习和实验内容 快速学习了Linux系统的发展历程及其简介,学习了下的变量.用户权限管理.文件打包及压缩.常用命令的和 ...
- Linux内核原理与分析-第二周作业
写之前回看了一遍秒速五厘米:如果
- 20169219linux 内核原理与分析第四周作业
系统调用 系统调用是用户空间访问内核的唯一手段:除异常和陷入外,它们是内核唯一的合法入口. 一般情况下,应用程序通过在用户空间实现的应用编程接口(API)而不是直接通过系统调用来编程. 要访问系统调用 ...
- 2018-2019-1 20189221《Linux内核原理与分析》第一周作业
Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...
- 20169212《Linux内核原理与分析》课程总结
20169212<Linux内核原理与分析>课程总结 每周作业链接汇总 第一周作业:完成linux基础入门实验,了解一些基础的命令操作. 第二周作业:学习MOOC课程--计算机是如何工作的 ...
- 20169212《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...
随机推荐
- WCF基础之会话、实例和并发
这篇笔记是一些概念性的东西. 会话,借用百科上的描述就是一个客户与服务器之间的不中断的请求响应序列.wcf的会话模式是通过服务契约的SessionModel进行设置的,其值为枚举,分别为:Allowe ...
- 九度OJ 1252:回文子串 (字符串处理、DP)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:387 解决:224 题目描述: 输入一个字符串,输出该字符串中对称的子字符串的最大长度. 比如输入字符串"google" ...
- appium报'Command 'D\:\\android-sdk-windows\\platform-tools\\adb.exe -P 5037 -s “adb device” shell pm clear appPackage' exited with code 1'
解决方法:是因为手机开发者模式没有允许USB调试(安全模式),打开即可
- [转】IIS:Do not nest virtual directories
原文:https://msdn.microsoft.com/en-us/library/ms178685.aspx#Anchor_6 Configuration settings for virtua ...
- Android异步载入全解析之使用AsyncTask
Android异步载入全解析之使用AsyncTask 概述 既然前面提到了多线程,就不得不提到线程池,通过线程池,不仅能够对并发线程进行管理.更能够提高他们运行的效率.优化整个App.当然我们能够自己 ...
- Linux软件包分类
源代码包 优点: 1.给你的就是源代码 2.可以修改源代码 3.可以自由选择所需的功能 4.软件是在自己电脑上编译安装,所以更加稳定高效 5.卸载方便(直接删了你安装软件的那个目录就好了) 缺点: 1 ...
- Oracle数据库获取uuid函数
Oracle新建系统表时,要求主键为32位uuid,推測Oracle肯定会提供相关的函数. 翻阅相关文档,果然发现Oracle提供的函数 sys_guid() 用于获取32位uuid,简单使用为 se ...
- mongodb 的注意点
昨天同事安装mongodb遇到了些问题,问了下我,后拉发现都是些细节没注意(讲道理这应该是很简单,一顿操作就ok的事情) 首先,下载 mongo包, 然后 ,解压安装, 启动之. 问题就出现在他后台启 ...
- Android Studio 1.1 使用介绍及导入 jar 包和第三方依赖库
导入 jar 包 导入 jar 包的方式非常简单,就是在项目中的 libs 中放入你需要导入的 jar 包,然后右键你的 jar 文件,选择“add as a library”即可在你的项目中使用这个 ...
- c的详细学习(8)指针学习(二)
(1)指针与二维数组 一个数组的名字代表该数组的的首地址,是地址常量(作为形式参数的数组名除外),这一规定对二维数组或更高维数组同样适用. 在c语言中定义的任何一个二维数组实际上都可以看做是一个一维数 ...