操作系统是如何工作的

本章目标是在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. SQL优化————Insert

    1.如果是非生产环境,可以先将索引和约束删掉,等数据插入完之后,再建立索引和约束. 2.如果一次性插入数据较大,可以使用游标,每次小批量的插入数据. 3.如果数据表太大,可以构建历史表,老数据通常不会 ...

  2. Asp.Net Core 调用第三方Open API查询物流数据

    在我们的业务中不可避免要与第三方的系统进行交互,调用他们提供的API来获取相应的数据,那么对于这样的情况该怎样进行处理呢?下面就结合自己对接跨越速运接口来获取一个发运单完整的物流信息为例来说明如何在A ...

  3. 《Mysql - 为什么只查一行的数据,也这么慢?》

    概念 - 在某些情况下,“查一行”,也会执行得特别慢. - 下面分析在什么情况下,会出现这个现象. - 基础工作(构建数据库环境) - 建立 t 表,并写入 10W 的数据. CREATE TABLE ...

  4. kafka 集群环境搭建 java

    简单记录下kafka集群环境搭建过程, 用来做备忘录 安装 第一步: 点击官网下载地址 http://kafka.apache.org/downloads.html 下载最新安装包 第二步: 解压 t ...

  5. Python3之字符串格式化format函数详解(下)

    格式限定符 format通过丰富的的“格式限定符”(语法是 {}中带:号)对需要格式的内容完成更加详细的制定. 进制转换 我们可以再限定符中制定不同的字符对数字进行进制转换的格式化,进制对应的表格: ...

  6. (三)spring Security 从数据库中检索用户名和密码

    文章目录 配置 Druid 数据源 数据库 Mapper 文件 自定义 `UserDetailsService` 自定义登陆校验器 `AuthenticationProvider ` 配置 secur ...

  7. Web基础和servlet基础

    TomCat的目录结构 Bin:脚本目录(存放启动.关闭这些命令) Conf:存放配置文件的目录 Lib:存放jar包 Logs: 存放日志文件 Temp: 临时文件 Webapps: 项目发布目录 ...

  8. C++ 中的 多态性

    一 .多态性 1.多态性概述:多态是指同样的消息被不同类型的对象接受时导致不同的行为 2.多态实现:编译时的多态:在编译的过程中确定了同名操作的具体对象.   运行时的多态:在程序运行过程中动态地确定 ...

  9. Java两整数相除保留两位小数

    int num1 = 7; int num2 = 9; // 创建一个数值格式化对象 NumberFormat numberFormat = NumberFormat.getInstance(); / ...

  10. svn: E230001: Server SSL certificate verification failed: certificate issued

    svn: E230001: Server SSL certificate verification failed: certificate issued 今天在使用svn时候发现出现这个问题,这个是因 ...