张文俊 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

一、第二周学习内容总结

1、计算机工作“三大法宝”

首先,计算机工作原理最重要的三个内容就是:存储程序计算机工作模型、中断机制和函数调用堆栈。

存储程序计算机工作模型是计算机系统最最基础性的逻辑结构;

中断机制是多道程序操作系统的基点,没有中断机制程序只能从头一直运行结束才有可能开始运行其他程序;

函数调用堆栈是高级语言得以运行的基础,有了高级语言及函数后,堆栈成为了计算机的基础功能,函数参数传递机制和局部变量存储。

2、详细介绍函数调用堆栈

首先,堆栈是C语言程序运行时必须的一个记录调用路径和参数的空间,即CPU内已经集成好了很多功能。

堆栈含以下元素:

函数调用框架、传递参数、保存返回地址、提供局部变量空间、C语言编译器对堆栈的使用有一套的规则。

了解堆栈存在的目的和编译器对堆栈使用的规则是理解操作系统一些关键性代码的基础。

其次,堆栈相关的寄存器常用的共有四种,esp、ebp、push、pop。详细解释如下:

esp,堆栈指针,指向栈顶;

ebp,基址指针,指向栈底,在C语言中用作记录当前函数调用基址;

push,栈顶地址减少4个字节,从低地址向高地址;

pop,栈顶地址增加4个字节,从高地址向低地址;

最后,课程介绍了函数参数的传递与框架——

(1)建立框架,即call指令

相当于

push %ebp

movl %esp,%ebp

cs:eip原来的值指向call下一条指令,该值被保存到栈顶cs:eip的值指向function的入口地址

(2)执行函数主体代码

(3)拆除框架

相当于

movl %ebp,%esp

pop %ebp

ret

函数的返回值通过eax寄存器传递

3、参数传递

这里以老师在课堂上举出的例子:

#include <stdio.h>

void p1(char c)

{

printf("%c",c);

}

int p2(int x,int y)

{

return x+y;

}

int main(void)

{

char c ='a';

int x,y;

x =1;

y =2;

p1(c);

z = p2(x,y);

printf("%d = %d+%d",z,x,y);

}

首先,观察P2的堆栈框架:

这里,使用变址寻址方式,将x+y的值赋给eax。

然后,我们观察main是如何传递参数给P2的:

和main中的局部变量:

可以看到,汇编代码中用变址寻址把y的值和x的值存放到堆栈中,然后进行局部变量调用。

4、C代码中嵌入汇编代码

____asm____

(

汇编语句模板:

输入部分:

输出部分:

破坏描述部分:

);

二、实验二内容

本次实验内容是在mykernel基础上构造一个简单的操作系统内核。

首先我们cd进入LinuxKernel/linux-3.9.4文件,执行qemu -kernel arch/x86/boot/bzImage,可以看到窗口弹出如下:

然后,我们查看mymain.c和myinterrrupt.c文件:

可以发现,mymain是系统中唯一的进程,函数主要部分是my_start_kernel。每循环10万次,就打印一次my_start_kernel here.

myinterrupt是时间中断处理程序,每进行一次就会发生一次时钟处理中断,每次时钟中断都调用printk并输出。

程序分析:

mypcb.h

#define MAX_TASK_NUM 4

#define KERNEL_STACK_SIZE 1024*8

/* CPU-specific state of this task */

struct Thread {

unsigned long ip;//保存eip

unsigned long sp;//保存esp

};

typedef struct PCB{

//用于表示一个进程,定义了进程管理相关的数据结构

int pid;

volatile long state; /* 定义进程的状态:-1 不可运行, 0 可运行, >0 停止 */

char stack[KERNEL_STACK_SIZE];

//内核堆栈

struct Thread thread;

unsigned long task_entry; //指定进程入口

struct PCB *next;//进程链表

}tPCB;

void my_schedule(void);//调用了my_schedule,表示调度器

mymain.c

void my_timer_handler(void)

{

#if 1

if(time_count%1000 == 0 && my_need_sched != 1)//设置时间片的大小,时间片用完时设置一下调度标志。当时钟中断发生1000次,并且my_need_sched!=1时,把my_need_sched赋为1。当进程发现my_need_sched=1时,就会执行my_schedule。

{

printk(KERN_NOTICE ">>>my_timer_handler here<<<\n");

my_need_sched = 1;

}

time_count ++ ;

#endif return;

}

void my_schedule(void)

{

tPCB * next; //下一个进程

tPCB * prev; //当前进程

if(my_current_task == NULL //task为空,即发生错误时返回

|| my_current_task->next == NULL)

{

return;

}

printk(KERN_NOTICE ">>>my_schedule<<<\n");

/* schedule */

next = my_current_task->next; //将当前进程的下一个进程赋给next

prev = my_current_task;//当前进程为prev

if(next->state == 0)

/* -1 unrunnable, 0 runnable, >0 stopped */

{

//在两个正在执行的进程之间做上下文切换

asm volatile( "pushl %%ebp\n\t"

/* 保存当前进程的ebp */

"movl %%esp,%0\n\t" /* 保存当前进程的esp */

"movl %2,%%esp\n\t" /* 重新记录要跳转进程的esp,将下一进程中的sp放入esp中 */

"movl $1f,%1\n\t" /* $1f指标号1:的代码在内存中存储的地址,即保存当前的eip */

"pushl %3\n\t" //将下一进程的eip压入栈,%3为 next->thread.ip

"ret\n\t" /* 记录要跳转进程的eip */

"1:\t" /* 下一个进程开始执行 */

"popl %%ebp\n\t"

: "=m" (prev->thread.sp),"=m" (prev->thread.ip)

: "m" (next->thread.sp),"m" (next->thread.ip) );

my_current_task = next;

printk(KERN_NOTICE ">>>switch %d to %d<<<\n",prev->pid,next->pid);

}

else /* 与上一段代码不同的是如果下一个进程为新进程时,就运用else中的这一段代码。首先将这个进程置为运行时状态,将这个进程作为当前正在执行的进程。 */

{ next->state = 0;

my_current_task = next; printk(KERN_NOTICE ">>>switch %d to %d<<<\n",prev->pid,next->pid);

/* switch to new process */

asm volatile( "pushl %%ebp\n\t" /* 保存当前进程的ebp */ "movl %%esp,%0\n\t" /* 保存当前进程的esp */ "movl %2,%%esp\n\t" /* 重新记录要跳转进程的esp */

"movl %2,%%ebp\n\t" /* 重新记录要跳转进程的ebp */ "movl $1f,%1\n\t" /* 保存当前eip */ "pushl %3\n\t" "ret\n\t" /* 重新记录要跳转进程的eip */

: "=m" (prev->thread.sp),"=m" (prev->thread.ip)

: "m" (next->thread.sp),"m" (next->thread.ip) ); }

return; }

精简内核运行结果:

三、总结

操作系统是管理计算机系统的全部硬件资源包括软件资源及数据资源;控制程序运行;改善人机界面;为其它应用软件提供支持等,使计算机系统所有资源最大限度地发挥作用,为用户提供方便有效的服务界面。

Linux是一个多进程的操作系统,所以,其他的进程必须等到正在运行的进程空闲CPU后才能运行。

当正在运行的进程等待其他的系统资源时,Linux内核将取得CPU的控制权,并将CPU分配给其他正在等待的进程,这就是进程切换。

内核中的调度算法决定将CPU分配给哪一个进程。

进程是动态执行的实体,内核是进程的管理者。

进程不但包括程序的指令和数据,而且包括程序计数器和CPU的所有寄存器以及存储临时数据的进程堆栈。

所以,正在执行的进程包括处理器当前的一切活动。

进程既可以在用户态下运行,也能在内核下运行,只是内核提供了一些用户态没有的核心服务,

因此进程在访问这些服务时会产生中断,必须进行用户态与内核态的切换。

“Linux内核分析”实验二报告的更多相关文章

  1. 【MOOC EXP】Linux内核分析实验二报告

    程涵  原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000  [操作系统是如何工作的]   教学内 ...

  2. 【MOOC EXP】Linux内核分析实验八报告

    程涵  原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 进程的切换和系统的一般执行过程 知识点 ...

  3. 【MOOC EXP】Linux内核分析实验七报告

    程涵  原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 可执行程序的装载 知识点梳理 一.预处 ...

  4. 【MOOC EXP】Linux内核分析实验六报告

    程涵  原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 进程的描述和进程的创建 知识点梳理: ...

  5. “Linux内核分析”实验一报告

    张文俊 + 原创作品转载请注明出处 + <Linux 内核分析> MOOC 课程 实验要求: 1.总结部分要求阐明自己对“计算机是如何工作的”理解: 2.博客中需要使用实验截图: 实验内容 ...

  6. “Linux内核分析”实验三报告

    构造一个简单的Linux系统 张文俊+原创作品转载请注明出处+<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-10000290 ...

  7. 【MOOC EXP】Linux内核分析实验四报告

    程涵  原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 [使用库函数API和C代码中嵌入汇编代 ...

  8. 【MOOC EXP】Linux内核分析实验一报告

    程涵  原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000  [反汇编一个简单的C程序]   实验 ...

  9. 【MOOC EXP】Linux内核分析实验三报告

     程涵  原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 [跟踪分析Linux内核的启动过程] ...

随机推荐

  1. 【Alpha】团队课程展示

    团队展示报告 团队分工 陈涵 PM + 后端开发 ,统筹全队安排,完成了登录界面,以及一部分部门模块和课程中教室模块的编写. 张鹏 后端开发,主要完成了主界面和其他功能界面的编写,课程界面的编写,以及 ...

  2. 团队作业——Alpha冲刺 7/12

    团队作业--Alpha冲刺 冲刺任务安排 杨光海天 今日任务:将编辑界面与标题栏合并.与同队成员,讨论部分功能合并的问题. 明日任务:编辑界面与另一队员完成的字体设置弹窗合并. 郭剑南 今日任务:使用 ...

  3. JS中的防抖与节流

    什么是防抖?and什么是节流?一起来开心的学习下吧. 首先什么是防抖:就是在一定的时间内事件只发生一次,比如你点击button按钮,1秒内任你单身30年手速点击无数次,他也还是只触发一次.举个例子,当 ...

  4. 解决PC有道云笔记卸载重装后无法数据同步问题

    将客户端内容成功同步后,按键盘win键选择文件资源管理器,将以下路径一次粘贴到搜索框按回车搜索,将搜索到的所有内容(文件,文件夹)全部删除,再重启软件登录账户同步试试看 配置目录:%USERPROFI ...

  5. 3.Solr4.10.3目录结构

    转载请出自出处:http://www.cnblogs.com/hd3013779515/ 1.整个目录结构 (1)bin:是脚本的启动目录 (2)contrib:第三方包存放的目录 (3)dist:编 ...

  6. 如何弹出QQ临时对话框实现不添加好友在线交谈效果

    如何不添加好友弹出QQ临时对话框实现在线交谈效果,这样的一个需求,我们真的是太需要了,实现起来也很简单,一行代码即可搞定,需要的朋友可以参考下 其实这个很简单,在img我们加入一个a标签,然后 < ...

  7. win10系统上Python和pycharm的安装及配置

    1.https://www.python.org/downloads/windows/进入官网下载需要的Python安装包(以2.7版本为例) 2.http://www.jetbrains.com/p ...

  8. [GXOI/GZOI2019]逼死强迫症

    题目 设我们最后的答案是\(g_n\) 我们发现在最后竖着放一个\(2\times 1\)的,和横着放两个\(1\times 2\)的就可以区分开之前的方案了 所以如果仅仅使用\(1\times 2\ ...

  9. TDD&BDD

    BDD行为驱动开发的一种敏捷开发技术 TDD测试驱动开发

  10. 错误 ORA-01102: cannot mount database in EXCLUSIVE mode 的处理方法

    今天启动数据库时报错了! SQL> startup mount ORACLE instance started. Total System Global Area  608174080 byte ...