2017-2018-1 20179209《Linux内核原理与分析》第七周作业
一.实验
1.1task_struct数据结构
Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程,这个结构体包含了一个进程所需的所有信息。它定义在linux-3.18.6/include/linux/sched.h文件中。
这个结构体定义非常庞大,目测有300多行代码,所以只摘录了部分关键定义:
struct task_struct {
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
void *stack; /*进程堆栈*/
atomic_t usage;
unsigned int flags; /* per process flags, defined below */
unsigned int ptrace;
pid_t pid;
pid_t tgid;
struct task_struct __rcu *real_parent; /* real parent process */
struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports */
/*
* children/sibling forms the list of my natural children
*/
struct list_head children; /* list of my children */
struct list_head sibling; /* linkage in my parent's children list */
}
用一张比较形象的图表可以说明进程描述符大体结构和其功能:

1.2分析sys_clone如何创建进程和修改task_struct
系统调用服务例程sys_clone, sys_fork, sys_vfork三者最终都是调用do_fork函数完成。这三者的区别详细见——Linux中fork,vfork和clone详解(区别与联系)。do_fork函数原型位于linux-3.18.6/kernel/fork.c。
单从do_fork这个函数的参数来看,创建一个新的进程需要传入的参数有:clone_flags,从字面意思这个参数是克隆的父进程的状态;stack_start,为要创建进程的堆栈的起始位置,联合下一个参数stack_size(堆栈大小)共同决定了该进程的堆栈区域;parent_tidptr和child_tidptr传入的目的是将该进程置于系统进程链表。下面从实现角度分析各个部分的功能(右边为do_fork流程):

1.3使用gdb跟踪分析fork调用内核函数sys_clone的过程
PS:继上次作业,我发现一个问题——在实验楼环境下使用gdb跟踪MenuOS启动后输入命令后会出现死机,然后只能重复之前步骤重新来一遍操作。本实验开始时有些头疼,因为要想完成对fork命令的追踪也必须在Qemu虚拟机中输入命令,果然在最开始时还是出现了同样的问题。不得已我决定将3.18.6的内核下载到自己的虚拟机,结果出现了尴尬的现象,就是我的Ubuntu64位虚拟机能开启,但却是黑屏,上网查资料后于事无补,很多方法试了都没用,所以一怒之下从磁盘中删去了该虚拟机(我之前的linux所有程序都在该虚拟机上,从linux内核原理与分析课一开始就用的这个虚拟机,可想而知里面有多少重要的东西)。如果我之前抓了快照恢复一下可能就好了,然而我重来没有抓取过快照,即使出了问题也直接把虚拟机扔了重新创建一个。所以抓拍快照很重要!抓拍快照很重要!抓拍快照很重要。然而等我新建虚拟机时候发现引导界面也是黑屏,这时我预感到我可能犯了愚蠢的错误,等我打开其他虚拟机,同样是黑屏!!!立刻重启实体机,好了,黑屏不存在了!数据恢复不了那个虚拟机,再怎么说它也是一个系统。所以我白白给自己创造了一个巨大的问题!接着重新建一个Ubuntu,等到我一步步把内核下载好,编译的时候又出现问题——我的Ubuntu是64位,实验要求32位!强忍内心的愤怒查资料下载了32位库,然而问题并没有解决(貌似它并没有找见我下载的32位库在哪,我也不知道在哪。。。)至此我再没有耐心又回到了实验楼!值得反思的一个事实是,很多时候在你跋山涉水经历万千磨难后最终发现你一开始要找的答案就在原点,然而一开始你却不知道它就在脚下!我想,明白这个道理比我做这个实验得到的理论知识更有意义!原来在进入Qemu虚拟机后必须按Ctrl+Alt后才能再回到桌面环境,这句话就写在:

解决“死机”问题后,仍旧选择实验楼环境:
基本命令如下:
cd LinuxKernel
rm menu -rf
git clone https://github.com/mengning/menu.git
cd menu
mv test_fork.c test.c //在makefile中编译命令用的是 test.c,这是改名的原因!
cd ..
qemu -kernel linux3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
gdb linux3.18.6/vmlinux
验证是否成功将fork添加:

在创建进程的关键函数上设置断点:

起初没解决PS中的难题时我是直接在内核启动时就设置了上图的断点,得出如下结论:
- 内核启动时创建过很多进程!
- 尽管创建过很多进程,但不会调用ret_from_fork函数!



从上面的图中大家可以看到,这时候MenuOS并没有完全启动,我同样追踪到了do_fork、dup_task_struct、copy_process和copy_thread。下面的截图是解决PS中“问题”后追踪到的ret_from_fork:


1.4实验总结
本次实验最为关心的问题就是新的进程从哪开始执行?上面两张图足以说明这个问题。ret_from_fork中跳转到syscall_exit后面的代码虽然追踪不到,但在它结束时,子进程创建完成。syscall_exit属于系统调用中的一个环节,从上次实验的结果来看,接下来的步骤还有syscall_exit_work!这也从侧面证实上次实验结果中的一个问题,那就是在work_pending中有一个判断,是否发生进程调度!所以在syscall_exit的时候会发生进程调度,最起码可能会创建一个新的进程!
二.课本十一、十二章
2.1相对时间与绝对时间
如果某个事件在5s后被调度执行,那么系统所需要的不是绝对时间,而是相对时间(比如,相对现在起5s后);相反,如果要求管理当前日期和当前时间,则内核不但要计算流逝的时间而且还要计算绝对时间。系统定时器以某种频率自行触发(经常被称为击中或射中)时钟中断,该频率可以通过编程预定,称作节拍率。当时钟中断发生时,内核就通过一种特殊的中断处理程序对其进行处理。
2.2jiffies
全局变量jiffies用来记录系统启动以来产生的节拍总数。启动时,内核将该变量初始化为0,此后,每次时钟中断处理程序就会增加该变量的值。jiffies的定义:
extern unsigned long volatile jiffies和extern u64 jiffies_64
jiffies回绕是指当jiffies达到最大值时,它的值变回0重新开始。
2.3实时时钟
实时时钟是用来持久存放系统时间的设备,即使系统关闭后,它也可以靠主板上的微型电池供电保持系统的计时。在PC体系结构中,RTC和CMOS集成在一起,而且RTC的运行和BIOS的保存设置都是同一个电池供电。
2.4延迟执行——schedule_timeout()
最理想的延迟执行方法是使用schedule_timeout()函数,该方法会让需要延迟执行的任务睡眠到指定的延迟时间耗尽后再重新运行。当指定时间到期后,内核唤醒被延迟的任务并将其重新放回运行队列,用法:set_current_state(TASK_INTERRUPTIBLE);schedule_timeout(s*HZ)
2.5slab
slab层(slab分配器)把不同的对象划分为告诉缓存组,其中每个高速缓存组存放不同类型对象(这好像与普通的高速缓存有区别?)。每种对象类型对应一个高速缓存;高速缓存又被划分为slab。slab由一个或多个物理连续的页组成。每个高速缓存可以由多个slab组成。slab描述符如下:
struct slab{
struct list_head list; //满、部分满或空链表
unsigned long colouroff; //slab着色的偏移量
void *s_mem; //在slab中的第一个对象
undigned int inuse; //slab中已经分配的对象数
keme_bufctl_t free; //第一个空闲对象
}
一个新的告诉缓存通过以下函数创建:
struct kmem_cache *kmem_cache_create(const char *name,size_t size,size_t align,unsigned long flags, woid(*ctor)(void *));。
读完课本,我觉得slab就是cache的一种实现类型。
2017-2018-1 20179209《Linux内核原理与分析》第七周作业的更多相关文章
- 20169212《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...
- 20169210《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...
- 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业
2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...
- 2017-2018-1 20179215《Linux内核原理与分析》第二周作业
20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...
- 2019-2020-1 20199329《Linux内核原理与分析》第九周作业
<Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...
- 2019-2020-1 20209313《Linux内核原理与分析》第二周作业
2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...
- 2018-2019-1 20189221《Linux内核原理与分析》第一周作业
Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...
- 《Linux内核原理与分析》第一周作业 20189210
实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...
- 2018-2019-1 20189221《Linux内核原理与分析》第二周作业
读书报告 <庖丁解牛Linux内核分析> 第 1 章 计算工作原理 1.1 存储程序计算机工作模型 1.2 x86-32汇编基础 1.3汇编一个简单的C语言程序并分析其汇编指令执行过程 因 ...
随机推荐
- 某考试 T1 fair (18.5.1版)
转化一下模型:每天可以选1也可以选0,但是任意前i天(i<=n)1的个数都必须>=0的个数,求总方案数/2^n. 然后可以发现这是一个经典题,随便推一下公式发现等于 C(n,n/2)/2 ...
- 2.搭建配置最简单的spring mvc 工程-基础版
目标:用最少的东西,搭建可以运行的最最基础的springMvc登陆校验项目! spring 4 1.首先配置pom.xml引入spring 相关jar, 引用都有注释, 无关的可以暂时不引用. < ...
- 2016集训测试赛(十八)Problem C: 集串雷 既分数规划学习笔记
Solution 分数规划经典题. 话说我怎么老是忘记分数规划怎么做呀... 所以这里就大概写一下分数规划咯: 分数规划解决的是这样一类问题: 有\(a_1, a_2 ... a_n\)和\(b_1, ...
- Java Servlet Filter
做web开发的人对于Filter应该不会陌生,一直在很简单的使用,但是一直没有系统的总结一下,随着年纪的慢慢长大,喜欢总结一些事情,下面说说我对Filter的理解,官方给出的Filter的定义是在请求 ...
- 缺少 Google API 秘钥,因此 Chromium 的部分功能将无法使用
获取密钥(ID)教程: https://www.chromium.org/developers/how-tos/api-keys 获取密钥(ID)地址: https://cloud.google.co ...
- iOS 5的文件存储策略应对
苹果在iOS 5系统时,对app的文件存储提出了新的要求.从它的guildline来看,是推荐开发者尽量把app生成的文件放在Caches目录下的.原文如下: Only user-generated ...
- php 列出当前目录
$path="."; //初使化用户所操作目录 $prevpath=dirname($path); //初使化当前脚本所在目录 $dir_handle=opendir($path) ...
- HDU 1041 Computer Transformation 数学DP题解
本题假设编程是使用DP思想直接打表就能够了. 假设是找规律就须要数学思维了. 规律就是看这些连续的0是从哪里来的. 我找到的规律是:1经过两次裂变之后就会产生一个00: 00经过两次裂变之后也会产生新 ...
- MySQL -进阶
一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用 SELECT * FROM(SELE ...
- C 语言学习 3
[程序3] 题目:一个整数,它加上100后是一个全然平方数.再加上168又是一个全然平方数.请问该数是多少? 1.程序分析:在10万以内推断.先将该数加上100后再开方,再将该数加上268后再开方,假 ...