操作系统是如何工作的

本章目标是在mykernel的基础上编写一个简单的内核

一、学习笔记

1.计算机的三个法宝:a.存储程序计算机;b.函数调用堆栈;c.中断

  • 存储程序计算机(所有计算机的基础性的逻辑框架);
  • 函数调用堆栈(C语言程序运行时必须使用的记录函数调用路径和参数存储的空间);
    • 堆栈具体的作用:

      • 记录函数调用框架
      • 传递函数参数
      • 保存返回值的地址
      • 提供函数内部局部变量的存储空间
    • 堆栈相关的寄存器:
      • ESP:堆栈指针
      • EBP:基址指针
    • 堆栈操作:
      • push:栈顶地址减少4个字节,并将操作数放进栈顶存储单元
      • pop:栈顶地址增加4个字节,并将栈顶存储单元的内容放入操作数
    • 其他关键寄存器:

      - CS:EIP:总是指向地址连续的下一条指令

      - 跳转/分支:执行这样的命令时,CS:EIP的值会根据程序需要被修改

      - call:将当前CS:EIP的值压入栈顶,CS:EIP指向被调用函数的入口地址

      - ret:从栈顶弹出原来保存在这里CS:EIP的值,放入CS:EIP



      - 堆栈特别关键的就是函数调用堆栈框架

二、实验

  • LinuxKernel/linux-3.9.4/mykernel目录下可以看到qemu窗口

    • 代码
cd LinuxKernel/linux-3.9.4
qemu -kernel arch/x86/boot/bzImage

- QEMU窗口

- 查看mymain.c



每循环10 000次,打印一句话。

- 查看myinterrupt.c



每执行一次,都会执行一次时钟中断。

下面是简单的时间片轮转机制内核代码:

mypcb.h

#define MAX_TASK_NUM 4

#define KERNEL_STACK_SIZE 1024*8

/* CPU-specific state of this task */

struct Thread {

unsigned long	ip;

unsigned long	sp;

};

typedef struct PCB{

int pid;

volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */

char stack[KERNEL_STACK_SIZE];
/* CPU-specific state of this task */ struct Thread thread; unsigned long task_entry; struct PCB *next; }tPCB; void my_schedule(void);
- 定义一个进程控制块pcb结构体
- task_entry:进程入口函数
- thread:保存eip和esp
- state:进程状态,用于判断是否调度

mymain.c

主要功能是让程序从0号进程开始运行,只列下面这段代码是核心。

asm volatile(

//%0表示参数thread.ip,%1表示参数thread.sp。

"movl %1,%%esp\n\t"     /* set task[pid].thread.sp to esp 把参数thread.sp放到esp中*/

"pushl %1\n\t"    /* push ebp 由于当前栈是空的,esp与ebp指向相同,所以等价于push ebp*/

"pushl %0\n\t"     /* push task[pid].thread.ip */

"ret\n\t"     /* pop task[pid].thread.ip to eip */

"popl %%ebp\n\t"

:

: "c" (task[pid].thread.ip),"d" (task[pid].thread.sp)     /* input c or d mean %ecx/%edx*/

);

myinterrupt.c

主要功能是用于时钟中断处理和进程调度算法。

asm volatile(

"pushl %%ebp\n\t" /* save ebp 保存当前进程的ebp*/

"movl %%esp,%0\n\t" /* save esp 把当前进程的esp赋给%0(指的是thread.sp),即保存当前进程的esp*/

"movl %2,%%esp\n\t" /* restore esp 把%2(指下一个进程的sp)放入esp中*/

"movl $1f,%1\n\t" /* save eip $1f是接下来的标号“1:”的位置,把eip保存下来*/

"pushl %3\n\t" /*把下一个进程eip压栈*/

"ret\n\t" /* restore eip 下一个进程开始执行*/

"1:\t" /* next process start here */

"popl %%ebp\n\t"

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

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

);

三、总结

(1)进程和中断在操作系统是是非常重要的两个部分,需要熟练掌握。

(2)EIP寄存器储存着当前执行的代码,可以通过更改EIP寄存器的值来更改当前执行的代码,从而实现进程切换。出于安全考虑,EIP寄存器的值不能被直接改变,但可以通过压栈+ret指令来间接改变。

(3)进程在执行过程中,当时间片用完之后需要进程切换时,需要保存当前的执行上下文环境,下次被调度的时候,需要回复进程的上下文环境。

操作系统是如何工作的?

操作系统通过存储程序计算机机制依次执行程序的指令,堆栈为程序运行时录调用路径和参数提供空间,中断用于异常处理和进程调度。

2019-2020-1 20199301《Linux内核原理与分析》第三周作业的更多相关文章

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

    <Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...

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

    <Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...

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

    <Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...

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

    <Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...

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

    2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...

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

    20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...

  7. 2019-2020-1 20209313《Linux内核原理与分析》第二周作业

    2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...

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

    Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...

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

    实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...

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

    读书报告 <庖丁解牛Linux内核分析> 第 1 章 计算工作原理 1.1 存储程序计算机工作模型 1.2 x86-32汇编基础 1.3汇编一个简单的C语言程序并分析其汇编指令执行过程 因 ...

随机推荐

  1. Linux下安装redis以及常用命令

    https://blog.csdn.net/zgf19930504/article/details/51850594 安装: 1.获取redis资源 wget http://download.redi ...

  2. C++ 三大特性 继承(转载)

    继承 继承:类的继承,就是新的类从已有类那里得到已有的特性.原有的类称为基类或父类,产生的新类称为派生类或子类. 基本语法 派生类的声明: class 派生类名:继承方式 基类名1, 继承方式 基类名 ...

  3. Jira 自定义工作流并设置触发器

    一.添加修改工作流 打开 设置--问题--工作流 复制一个工作流,然后进去编辑页面 添加状态 增加转换动作 切换到文本,设置跳转过程中的事件 针对Stop Progress事件,修改跳转界面(界面需先 ...

  4. Python/C++ in Visual Studio: An Alternative to Matlab/MEX

    来自Andrew Delong的博客 http://andrewdelong.wordpress.com/2012/11/03/pythonc-in-visual-studio-an-alternat ...

  5. LeetCode 429. N叉树的层序遍历(N-ary Tree Level Order Traversal)

    429. N叉树的层序遍历 429. N-ary Tree Level Order Traversal LeetCode429. N-ary Tree Level Order Traversal 题目 ...

  6. django使用pyecharts(1)----django加入echarts

    Django 中使用 pyecharts.一.普通django加入echarts Django 模板渲染 Step 0: 新建一个 Django 项目 $ django-admin startproj ...

  7. Arraylist的遍历方式、java反射机制

    先定义ArrayList再添加几条数据:         ArrayList arr=new ArrayList(); //往arrList中增加几条数据 arr.add(1); arr.add(2) ...

  8. 雷达无线电系列(三)经典CFAR算法门限因子alpha计算(matlab)

    前言 本文汇集CA.SO.GO.OS.杂波图等恒虚警算法的门限因子求解方法及其函数 1,CA-CFAR [非常简单,可以直接求解] %% 均值恒虚警_门限因子计算公式 %% 版本:v1 %% 时间:2 ...

  9. 最全的ADB命令行大全(转)

    基本用法 命令语法 adb 命令的基本语法如下: adb [-d|-e|-s ] 如果只有一个设备/模拟器连接时,可以省略掉 [-d|-e|-s ] 这一部分,直接使用 adb . 为命令指定目标设备 ...

  10. 《阿里巴巴 Java 开发规约》自动化检测插件安装及体验

    2017 开春之际,有助于提高行业编码规范化水平的<阿里巴巴 Java 开发手册>首次面世.汇聚阿里集团近万名技术精英的经验知识,这套高含金量的手册一经公开,便引起业界普遍关注和学习. 历 ...