攥写人:李鹏举 学号:20179203

原创作品转载请注明出处

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

一、本周知识点提炼

1.1操作系统内核三大功能:

操作系统内核三大功能分别是进程管理,内存管理,文件系统。

其中最核心的是进程管理,而pid是系统区别进程的编号。

本周学习及实验重点就是学习和分析进程管理的重要性,所以接下来将对进程管理进行总结。

1.2进程管理总结:

首先我们应该了解到Linux通过复制父进程来创建一个新进程,下面以本周实验中用到的fork()函数进行具体分析。

fork函数,具体的过程:

1.复制一个PCB——task_struct.

2.要给新进程分配一个新的内核堆栈

ti = alloc_thread_info_node(tsk, node);
tsk->stack = ti;
setup_thread_stack(tsk, orig); //这里只是复制thread_info,而非复制内核堆栈

3.要修改复制过来的进程数据,比如pid、进程链表等,见copy_process内部。

*childregs = *current_pt_regs(); //复制内核堆栈
childregs->ax = 0; // 子进程的fork返回0 p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶
p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址

应当注意:系统调用内核处理函数sys_fork,sys_vfrok,sys_clone,其实最终执行的都是do_fork

do_fork里有:

 copy_process

      dup_task_struct // 复制pcb
      alloc_thread_info_node // 创建了一个页面,其实就是实际分配内核堆栈空间的效果。
      setup_thread_stack // 把thread_info的东西复制过来

之后初始化子进程

.

创建的新进程是从哪里开始执行的--》ret_from_fork(这是本周的重中之重)

*childregs = *current_pt_regs();  //复制内核堆栈(复制的pt_regs,是SAVE_ALL中系统调用压栈的那一部分。)
childregs->ax = 0; // 子进程的fork返回0 p->thread.sp = (unsigned long) childregs; // 调度到子进程时的内核栈顶
p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址

ip指向的是ret_from_fork,所以是从这里开始执行的。

二、本周实验

2.1实验要求

1.阅读理解task_struct数据结构http://codelab.shiyanlou.com/xref/linux-3.18.6/include/linux/sched.h#1235;

2.分析fork函数对应的内核处理过程sys_clone,理解创建一个新进程如何创建和修改task_struct数据结构;

3.使用gdb跟踪分析一个fork系统调用内核处理函数sys_clone ,验证您对Linux系统创建一个新进程的理解,推荐在实验楼Linux虚拟机环境下完成实验。

4.特别关注新进程是从哪里开始执行的?为什么从哪里能顺利执行下去?即执行起点与内核堆栈如何保证一致。

2.2 实验过程:

1.删除原来的menu,并clone新的menu,用test_fork.c覆盖test.c

2.make rootfs之后新的内核启动,测试fork功能

3.冷冻内核,准备单步跟踪,查看新的进程

4.用gdb进行单步跟踪的调试,首先进行断点的设置,依照fork进程的组成函数设置断点



5.单步跟踪程序,分析结果













2.3实验结果总结分析

本周的课程最重要的就是进程的管理,而do_fork就是其中一个最关键的宏。

do_fork处理了以下内容:

  1. 调用copy_process,将当期进程复制一份出来为子进程,并且为子进程设置相应地上下文信息。
  2. 初始化vfork的完成处理信息(如果是vfork调用)
  3. 调用wake_up_new_task,将子进程放入调度器的队列中,此时的子进程就可以被调度进程选中,得以运行。
  4. 如果是vfork调用,需要阻塞父进程,知道子进程执行exec。

进程创建的关键copy_process,其工作流程如下:

1.检查各种标志位(已经省略)

2.调用dup_task_struct复制一份task_struct结构体,作为子进程的进程描述符。

3.检查进程的数量限制。

4.初始化定时器、信号和自旋锁。

5.初始化与调度有关的数据结构,调用了sched_fork,这里将子进程的state设置为TASK_RUNNING。

6.复制所有的进程信息,包括fs、信号处理函数、信号、内存空间(包括写时复制)等。

7.调用copy_thread,这又是关键的一步,这里设置了子进程的堆栈信息。

8.为子进程分配一个pid

9.设置子进程与其他进程的关系,以及pid、tgid等。这里主要是对线程做一些区分。

copy_thread函数为子进程准备了上下文堆栈信息,其工作流程如下:

  1. 获取子进程寄存器信息的存放位置
  2. 对子进程的thread.sp赋值,将来子进程运行,这就是子进程的esp寄存器的值。
  3. 如果是创建内核线程,那么它的运行位置是ret_from_kernel_thread,将这段代码的地址赋给thread.ip,之后准备其他寄存器信息,退出
  4. 将父进程的寄存器信息复制给子进程。
  5. 将子进程的eax寄存器值设置为0,所以fork调用在子进程中的返回值为0.
  6. 子进程从ret_from_fork开始执行,所以它的地址赋给thread.ip,也就是将来的eip寄存器。

三、第三周测试分析总结

本周课堂测试重点是为了让大家学习c语言中嵌套汇编程序的方法。本次测试中要求将之前编写的sum文件进行反汇编,观察其反汇编的结果,并将其在main.c中通过汇编调用sum。

首先展示一下我的sum函数

int  sum(int N,int sum )
{
sum=sum+N;
return sum;
}

3.1汇编观察分析

由于编程方法的不同,我的sum函数没有传入数组,而是通过循环将所有输入的数字进行累加。

接着通过objdum -d sum.o指令反汇编sum.o,并观察其反汇编之后的汇编语句。



首先这些语句是不能直接当作汇编语句嵌套进c语言的,因为在尝试之后发现c语言中嵌套的汇编语句无法识别rbp,edi等寄存器,因此一定要理解语句当中的意思并且用嵌套语言写出来。

首先我们看到的两句是函数调用时做到的压栈保存现场的操作。



这部分函数调用的时候程序已经执行,不需要我们进行操作。

接着看到的是取立即数分别放入rbp栈的不同地址空间之中



然后通过eax寄存器将两个数加到了同一个空间之中



最后又将计算好的数传回了eax寄存器

3.2嵌套中出现的问题

在实现嵌套的时候我最大的问题就是在我所写的c语言函数之中有return sum;的语句,根据汇编语言分析相加的语句相对容易完成,但是return语句应当如何设计却毫无头绪。为此我写了几个不同版本的c语言函数进行反汇编研究:

结尾无return语句:



结尾仅为return,也就是说不写返回值



通过对比可以看出三者之间的区别,有无最后的返回值主要在于有没有将最后计算的结果存入eax寄存器之中



所以依据这一点我进行了c语言中汇编语句的嵌套设计

int  sum(int N, int sum )
{
asm volatile( "addl %1, %0;\n\t"
:"=a"(sum)
:"b"(N),"a"(sum)
:"1" ); }

3.3完整代码及运行结果展示

运行结果:



完整代码:

#include<stdio.h>
int sum(int N, int sum )
{
asm volatile( "addl %1, %0;\n\t"
:"=a"(sum)
:"b"(N),"a"(sum)
:"1" ); }
int main(int argc,char *argv[])
{
int f,summ=0;
for(f=0;f<argc;f++)
summ=sum(atoi(argv[f]),summ);
printf("sum is :%ld\n",summ);
}

不过不知道我这个c语言汇编嵌套做的是否符合老师要求,如果不对请老师指出。

2017-2018-1 20179203 《Linux内核原理与分析》第七周作业及第三周测试总结的更多相关文章

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

    2018-2019-1 20189221<Linux内核原理与分析>第四周作业 教材学习:<庖丁解牛Linux内核分析> 第 3 章 MenuOS的构造 计算机三大法宝:存储程 ...

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

    20169211<Linux内核原理与分析>第四周作业内容列表 1.教材第3.5章节知识学习总结: 2.实验楼配套实验二实验报告: 1.<linux内核设计与实现>教材第3.5 ...

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

    <Linux内核原理与分析>第四周作业 一.上周问题总结: 虚拟机环境缺少部分库文件 书本知识使用不够熟练 二.本周学习内容: 1.实验楼环境使用gdb跟踪调试内核 1.1 在该环境下输入 ...

  4. 2019-2020-1 20199328《Linux内核原理与分析》第四周作业

    <Linux内核原理与分析>第四周作业 步骤一 首先我们指定一个内核并指定内存根文件系统,这里的bzImage是vmLinux经过gzip压缩的内核,"b"表示&quo ...

  5. 2017-2018-1 20179203 《Linux内核原理与分析》第四周作业

    攥写人:李鹏举 学号:20179203 ( 原创作品转载请注明出处) ( 学习课程:<Linux内核分析>MOOC课程http://mooc.study.163.com/course/US ...

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

    本次的实验是使用gdb跟踪调试内核从start_kernel到init进程启动,并分析启动的过程. 1.首先是在实验楼虚拟机上进行调试跟踪的过程. cd LinuxKernel qemu -kerne ...

  7. 2017-2018-1 20179209《Linux内核原理与分析》第四周作业

    本周学习内容为<跟踪分析MenuOS简单linux系统的启动过程>和教材中的进程调度及内核数据结构. 一.跟踪分析Linux内核的启动过程 这个实验我是在实验楼环境中完成的,最初想在自己的 ...

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

    Linux第四周作业 1. 堆栈知识 首先回顾了下堆栈相关的知识,堆栈机制是高级语言可以运行的一个基础,这一块需要重点掌握.函数发生调用时,如图 call指令:将eip的按顺序执行的下一条指令(因为在 ...

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

    网易云课堂学习: 在实验楼的学习中,这次的实验是利用mykernel实验模拟计算机硬件平台 首先进入linux-3.9.4, $cd LinuxKernel/linux-3.9.4 如下图所示 接下来 ...

随机推荐

  1. XML使用总结(一)

    XML使用总结(一): XML是一种可拓展的标记语言,被设计用来描写叙述.存储及传递数据的语言体,而它的标签没有被提前定义,须要用户自行定义,是W3C推荐的数据存储和传递的标准标记语言. ·      ...

  2. BI测试

    BI概念: 商业智能(Business Intelligence 简称BI),指数据仓库相关技术与应用的通称.指利用各种智能技术,来提升企业的商业竞争力.是帮助企业更好地利用数据提高决策质量的技术,包 ...

  3. java jdk和android sdk的安装以及环境变量的配置

    安卓环境变量设置 (烦)http://wenku.baidu.com/link?url=QRwpFhP8d0yJorhcvuZPrz3lNFQW-uwYg6TlZtv6uen6_SVsvRrzf0UJ ...

  4. (比赛)A - Simple String Problem

    A - Simple String Problem Time Limit:10000MS     Memory Limit:65536KB     64bit IO Format:%lld & ...

  5. 九度OJ 1204:农夫、羊、菜和狼的故事 (遍历、BFS)

    时间限制:1 秒 内存限制:32 兆 特殊判题:是 提交:744 解决:502 题目描述: 有一个农夫带一只羊.一筐菜和一只狼过河. 果没有农夫看管,则狼要吃羊,羊要吃菜. 但是船很小,只够农夫带一样 ...

  6. Linux入门基础(四)——磁盘管理

  7. Gradle-jar-aar

    Ref:Android Studio系列教程 Ref:Android Studio系列教程四--Gradle基础 Ref:Intellij IDEA 14.x 中的Facets和Artifacts的区 ...

  8. 使用inotify实现linux系统下的目录变化监控

    近期,有个项目须要及时删除Nginx服务生成的缓存文件,因为不是非常了解Nginx缓存生成的策略,在网上也沒有细致找,经过大家讨论,终于希望引入liunx的inotify功能,监控某个liunx文件夹 ...

  9. ThinkPHP 3.2.2 事务

    手册里说得非常清楚 : 5.3.19 事务支持 ThinkPHP提供了单数据库的事务支持,如果要在应用逻辑中使用事务,可以参考下面的方法: 启动事务: PHP代码 $User->startTra ...

  10. HDU - 5703 Desert 【找规律】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5703 题意 给出一杯容量为N的水 每次至少喝1个单位 有多少种不同的方式喝完 比如 给出3 就有4种方 ...