《Linux内核分析》 week2作业-时间片轮转
一.基于时间片轮转调度代码的解读
代码结构主要由三个文件组成:
1.mypcb.h
2.myinterrupt.c
3.mymain.c
1.进程控制块(mypcb.h)
/* CPU-specific state of this task */
struct Thread{
unsigned long ip; //eip,程序入口地址
unsigned long sp; //堆栈esp栈顶地址
}; typedef struct PCB{
int pid; //进程pid号
volatile long state; //进程运行状态,-1 unrunnable,0 runnable,>0 stopped
char stack[KERNEL_STACK_SIZE]; //进程的栈空间
/* CPU-specific state of this task */
struct Thread thread; //CPU的相关状态
unsigned long task_entry; //进程运行对应的函数
struct PCB *next; //下一个进程块地址
}tPCB; void my_schedule(void);
这里进程控制块(PCB)是采用链表的形式链接起来的。
2.进程的切换(myinterrupt.c)
extern tPCB task[MAX_TASK_NUM]; //进程控制块数组
extern tPCB *my_current_task; //当前对应的进程控制块
extern volatile int my_need_sched; //标志字段,来表示是否需要对进程进行调度 //时钟中断,周期性调用这个函数
void my_timer_handler(void){
#if 1
if(time_count%== && my_need_sched!=){
printk(KERN_NOTICE">>>my_timer_handler here<<<\n");
my_need_sched=;
} time_count++;
#endif
return;
}
接下来是进程上下文切换最关键的代码(my_schedule函数),采用的是内嵌汇编代码
当下一个进程的状态是正在运行时,则
if(next->state==){// -1 unrunnable,0 runnable,>0 stopped
/*switch to next process */
asm volatile(
"pushl %%ebp\n\t" //保存当前进程的栈基址指针 ebp
"movl %%esp,%0\n\t" //保存当前进程的栈顶指针 esp
"movl %2,%%esp\n\t" //回复下一个进程的栈顶指针 esp
"movl $1f,%1\n\t" //将当前进程的下一个指令地址保存到thread.ip中
"pushl %3\n\t" //将下一个进程的指令执行地址入栈
"ret\n\t" //ip出栈,
"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)
);
}
若下一个进程是新的进程,还没有执行过,基本方式与上面差不多,也是基于内嵌汇编方式实现上下文切换。
3.内核代码运行(mymain.c)
内核从my_start_kernel开始执行,my_start_kernel主要是进行进程控制块的初始化,同时启动0号进程。
void __init my_start_kernel(void)
{
int pid = ;
int i;
/* Initialize process 0*/
task[pid].pid = pid;
task[pid].state = ;/* -1 unrunnable, 0 runnable, >0 stopped */
task[pid].task_entry = task[pid].thread.ip = (unsigned long)my_process;
task[pid].thread.sp = (unsigned long)&task[pid].stack[KERNEL_STACK_SIZE-];
task[pid].next = &task[pid];
/*fork more process */
for(i=;i<MAX_TASK_NUM;i++)
{
memcpy(&task[i],&task[],sizeof(tPCB));
task[i].pid = i;
task[i].state = -;
task[i].thread.sp = (unsigned long)&task[i].stack[KERNEL_STACK_SIZE-];
task[i].next = task[i-].next;
task[i-].next = &task[i];
}
/* start process 0 by task[0] */
pid = ;
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*/
);
}
然后0号进程开始执行my_process函数。
4.程序运行的结果
二.实验总结
通过完成这个简单的时间片轮转多道程序的实验,让我更加深刻的理解了进程上下文切换的原理,以及内核启动的初始化过程。
《Linux内核分析》 week2作业-时间片轮转的更多相关文章
- 《linux内核分析》作业一:分析汇编代码
通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的(王海宁) 姓名:王海宁 学号:20135103 课程:<Linux内核分析& ...
- Linux内核分析
通过分析汇编代码理解计算机是如何工作的 网易云课堂<Linux内核分析>作业 实验目的: 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的 实验过程: 登陆实验楼虚拟机h ...
- 分析Linux内核中进程的调度(时间片轮转)-《Linux内核分析》Week2作业
1.环境的搭建: 这个可以参考孟宁老师的github:mykernel,这里不再进行赘述.主要是就是下载Linux3.9的代码,然后安装孟宁老师编写的patch,最后进行编译. 2.代码的解读 课上的 ...
- linux内核分析作业:操作系统是如何工作的进行:完成一个简单的时间片轮转多道程序内核代码
计算机如何工作 三个法宝:存储程序计算机.函数调用堆栈.中断机制. 堆栈 函数调用框架 传递参数 保存返回地址 提供局部变量空间 堆栈相关的寄存器 Esp 堆栈指针 (stack pointer) ...
- Linux内核分析—完成一个简单的时间片轮转多道程序内核代码
---恢复内容开始--- 20135125陈智威 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-10 ...
- Linux内核启动分析过程-《Linux内核分析》week3作业
环境搭建 环境的搭建参考课件,主要就是编译内核源码和生成镜像 start_kernel 从start_kernel开始,才真正进入了Linux内核的启动过程.我们可以把start_kernel看做平时 ...
- Linux内核分析作业 NO.2
操作系统是如何工作的 于佳心 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ...
- Linux内核分析:完成一个简单的时间片轮转多道程序内核代码
PS.贺邦 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 1.m ...
- Linux内核分析作业第二周
操作系统是如何工作的 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.函数调用堆栈 1.计算机工作三 ...
- Linux内核分析作业二
贾瑗 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.操作系统是如 ...
随机推荐
- Extjs4 自定义组件
Ext.onReady (function () { Ext.define ('MydesktopIcon', { /* Begin Definitions */ alias: 'widget.des ...
- 【HDOJ】 七百题留念
- 【转】Java基础笔记 – 枚举类型的使用介绍和静态导入--不错
原文网址:http://www.itzhai.com/java-based-notes-introduction-and-use-of-an-enumeration-type-static-impor ...
- Javascript 操作select控件大全(新增、修改、删除、选中、清空、判断存在等)
1判断select选项中 是否存在Value="paraValue"的Item 2向select选项中 加入一个Item 3从select选项中 删除一个Item 4删除selec ...
- 几何学中的欧拉公式:V-E+F = 2
几何学中的欧拉公式:V-E+F = 2,V.E.F表示简单几何体的顶点数.边数.面数. 证明: 它的证明有多种,这里呈现一种递归证法. 对于任意简单几何体(几何体的边界不是曲线),我们考察这个几何体的 ...
- selenium webdriver python 操作浏览器
新建driver driver=webdriver.Firefox() driver=webdriver.Ie() driver=webdriver.Chrome() 打开一个链接 driver. ...
- Appium 环境搭建
1.安装nodejs 下载地址: http://nodejs.org/download/ 下载之后一路next就好. 验证是否安装成功: node -v
- eclipse 错误: 找不到或无法加载主类
在src文件夹上移除Source Folder,再点右键-Build Path-Use as Source Folder,重新进行编译,一切正常了.
- 点击按钮弹出div,留用
<input type="button" onclick="document.getElementById('div').style.display=(docume ...
- TeamViewer或者向日葵等无法成功远程登录
之前一直能正常远程的两台电脑,今天不知道什么原因,莫名其妙的就无法登录了. 更悲催的时,今天早上走的时候,忘把TeamViewer或者向日葵软件启动了. 还好,我登录向日葵官网,在管理中心设置里面开启 ...