Linux内核设计第二周学习总结 完成一个简单的时间片轮转多道程序内核代码
陈巧然 原创作品 转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
一、使用实验楼的虚拟机, 观察只有一个死循环的mykernel与时钟中断的关系
步骤:
cd LinuxKernel/linux-3.9.4
qemu -kernel arch/x86/boot/bzImage
执行效果如下图
现在查看mymain.c:
再查看myinterrupt.c:
从执行效果看,my_timer_handler 与 my_start_kernel 中死循环确实是交替执行的,每循环约100,000次会执行一次timer_handler。
二、为只有死循环的mykernel加入时间片功能并重新编译,观察新的mykernel的行为
首先clone mengning/mykernel,替换mymain.c 和 myinterrupt.c, 增加mypcb.h:
cd ~/LinuxKernel/linux-3.9.4git clone https://github.com/mengning/mykernel.git mykernel_newcd mykernel_newcp mymain.c myinterrupt.c mypcb.h ../mykernelcd ..
然后运行make 重新编译mykernel, 如图:
然后再运行qemu -kernel arch/x86/boot/bzImage:
不难观察到新的mykernel的行为, 总共有0 1 2 3 共四个process, 新的mykernel 执行n号process一定时间后,会换到(n+1)%4号process继续执行,
在替换时时会打印>>> my_schedule <<<, 和>>> switch n to (n+1)%4 <<<
如下图:
3号进程切到0号的瞬间:
1号进程切到2号的瞬间:
知道了mykernel的行为,下面来分析mymain.c 和 myinterrupt.c 是如何做到这些的:
首先可以在mypcb.h的第10行看到一个常量定义
#define MAX_TASK_NUM 4
再观察mykernel执行入口函数 my_start_kernel 在 mymain.c 从第36行开始的循环
for(i=1;i<MAX_TASK_NUM;i++)
{
memcpy(&task[i],&task[0],sizeof(tPCB));
task[i].pid = i;
task[i].state = -1;
task[i].thread.sp = (unsigned long)&task[i].stack[KERNEL_STACK_SIZE-1];
task[i].next = task[i-1].next;
task[i-1].next = &task[i];
}
/* start process 0 by task[0] */
pid = 0;
my_current_task = &task[pid];
asm volatile(
"movl %1,%%esp\n\t" /* set task[pid].thread.sp to esp */
"pushl %1\n\t" /* 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*/
);
}
结合代码注释,可以得出:36行以上的代码初始化了0号process的pcb,并将进程设为runnable,而且将执行入口设为my_process 在36行开始的循环中,依次初始化了1 2 3号,设为unrunnable,并将0 1 2 3 号process的next指针 分别设为 1 2 3 0的地址,(形成一个单循环链表), 并设置各自thread.sp指针为各自内核栈的起始地址。然后在L48到L55的汇编代码中,先将当前esp设为task[0].thread.sp,并入栈保存,
然后通过push/ret的方式,间接call了0号process的thread.ip地址处的my_process函数。之后的pop %ebp是下一个被调度到的process第一个执行的代码
到了my_process函数中, 每循环10000000此后,先判断my_need_sched, 若之前my_timer_handler中将my_need_schedule置1了(每1000次时钟中断一次),则进入my_schedule并将my_need_sched置0;
现在到了负责调度了my_schedule函数:
若next process第一次执行(state == -1),则按else 分支中的流程:
入栈ebp, 保存当前esp 到prev->thread.sp, eip到 prev->thread.ip, 然后将ebp, esp设置为next->thread.sp, 然后与0号process同样的方法(push thread.ip; ret)来call my_process函数。
若next process 又一次被调度(state == 0), 则按56至69行执行。
总结:调度的实现需要保存当前task/process的现场(ebp/eip),然后配合时钟中断,对第一次被调度和再次被调度分情况处理。
Linux内核设计第二周学习总结 完成一个简单的时间片轮转多道程序内核代码的更多相关文章
- Linux内核分析:完成一个简单的时间片轮转多道程序内核代码
PS.贺邦 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 1.m ...
- Linux内核分析—完成一个简单的时间片轮转多道程序内核代码
---恢复内容开始--- 20135125陈智威 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-10 ...
- 20135202闫佳歆--week2 一个简单的时间片轮转多道程序内核代码及分析
一个简单的时间片轮转多道程序内核代码及分析 所用代码为课程配套git库中下载得到的. 一.进程的启动 /*出自mymain.c*/ /* start process 0 by task[0] */ p ...
- Linux内核分析第二周学习博客——完成一个简单的时间片轮转多道程序内核代码
Linux内核分析第二周学习博客 本周,通过实现一个简单的操作系统内核,我大致了解了操作系统运行的过程. 实验主要步骤如下: 代码分析: void my_process(void) { int i = ...
- linux内核分析第二周-完成一个简单的时间片轮转多道程序内核代码
中断时计算机运行的一个非常重要的功能.之所以重要,是因为由于种种原因,计算机不能将一个程序从头执行到尾不间断,而是可能会出现很多像等待输入设备输出设备的过程,如果没有中断系统,CPU只能等待,造成资源 ...
- linux内核分析作业:操作系统是如何工作的进行:完成一个简单的时间片轮转多道程序内核代码
计算机如何工作 三个法宝:存储程序计算机.函数调用堆栈.中断机制. 堆栈 函数调用框架 传递参数 保存返回地址 提供局部变量空间 堆栈相关的寄存器 Esp 堆栈指针 (stack pointer) ...
- Linux内核分析——第二周学习笔记20135308
第二周 操作系统是如何工作的 第一节 函数调用堆栈 存储程序计算机:是所有计算机基础的框架 堆栈:计算机中基础的部分,在计算机只有机器语言.汇编语言时,就有了堆栈.堆栈机制是高级语言可以运行的基础. ...
- 三20135320赵瀚青LINUX内核分析第二周学习笔记
赵瀚青原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.计算机的三个法宝 存储程 ...
- Linux内核设计第二周——操作系统工作原理
Linux内核设计第二周 ——操作系统工作原理 作者:宋宸宁(20135315) 一.实验过程 图1 执行效果 从图中可以看出,每执行my_ start_ kernel函数两次或一次,my_ time ...
随机推荐
- nginx基础配置加基础实战演示
目录 基本配置 设置用户 工作衍生进程数 错误日志存放路径 pid文件存放路径 设置最大连接数 http->server gzip 字符编码 nginx的基本格式 实战配置 虚拟主机配置 开始配 ...
- 【转】在Android Studio中下载Android SDK的两种方式(Android Studio3.0、windows)
在Android Studio中下载Android SDK的两种方式(Android Studio3.0.windows) 方式一.设置HTTP Proxy1. 打开Settings2. 点击HTTP ...
- header field token is not allowed by Access-Control-Allow-Headers in preflight response问题解决
今天下午,本来打算使用aioxs在header里传一个token给后台服务器,如下图所示: 结果,控制台报了如下的错: 然后,我不停地百度,不停的改后台express的header设置,一直没有效果: ...
- Query类型_JDBC的方法_JAVA方法_Loadrunner脚本
数据库查询压力测试脚本 jdbc_java_查询类型接口测试 package com.test; import java.sql.Connection; import java.sql.DriverM ...
- 33.[LeetCode] Search in Rotated Sorted Array
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...
- 最全的NB-IoT芯片厂商、模组厂商信息
NB-IoT作为LPWAN(低功耗广域网)的新兴技术,因为具有低功耗.低成本.广覆盖.海量节点等优势,并且在授权频段可以与2G.3G无缝连接而被运营商所青睐且接受.特别是到了2017年,据统计全球有5 ...
- ViewController 视图控制器的常用方法
ViewController 视图控制器 ,是控制界面的控制器,通俗的来说,就是管理我们界面的大boss,视图控制器里面包含了视图,下面举个例子,让视图在两个视图上调转. 定义一个视图控制器: MyV ...
- HDFS shell命令行常见操作
hadoop学习及实践笔记—— HDFS shell命令行常见操作 附:HDFS shell guide文档地址 http://hadoop.apache.org/docs/r2.5.2/hadoop ...
- 【第八周】【新蜂】新NABCD
由小组成员宫成荣撰写 一.小组项目申请时提交的NABCD: 痛点:普通的俄罗斯方块是不现实距离下一级有多远的,我们的游戏能显示距离下一等级游戏有多远.方便玩家体验. nabc: n:能满足大多数玩家的 ...
- 【week9】psp
本周psp 项目 内容 开始时间 结束时间 中断时间 净时间 2016/11/14 看论文 蛋白质甲基化位点预测 9:30 13:00 15 195 讨论班 组内讨论班 13:30 17:00 0 2 ...