《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 一.操作系统是如 ...
随机推荐
- js方法在iframe父子窗口
http://developer.51cto.com/art/201009/228891.htm http://developer.51cto.com/art/201009/228891.htm ht ...
- cf D. Vessels
http://codeforces.com/contest/371/problem/D 第一遍写的超时了,然后看了别人的代码,思路都是找一个点的根,在往里面加水的时候碗中的水满的时候建立联系.查询的时 ...
- 14.4.5 System Tablespace 系统表空间
14.4.5 System Tablespace 系统表空间 InnoDB 系统表空间包含InnoDB 数据目录(元数据 用于InnoDB相关对象)和是存储区域用于doublewrite buffer ...
- 2015第31周三Jetty
Jetty 的基本架构 Jetty 目前的是一个比较被看好的 Servlet 引擎,它的架构比较简单,也是一个可扩展性和非常灵活的应用服务器,它有一个基本数据模型,这个数据模型就是 Handler,所 ...
- 【模拟】HDU 5774 Where Amazing Happens
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5774 题目大意: 已知1946~2015每一年赢得人是谁,给n个名字,问赢了多少次. 题目思路: [ ...
- 在linux下文件转码
在linux下转码命令: iconv -f utf-8 a.txt > b.txt
- Purchase Document Open Interface(PDOI)
PO模块也有自己的接口表,多用于把其他业务系统在Oracle EBS系统生成采购订单记录. Table Name Description Type PO_HEADERS_INTERFACE This ...
- UIAlertController 的使用(NS_CLASS_AVAILABLE_IOS(8_0)iOS8以后有效)
iOS 8的新特性之一就是让接口更有适应性.更灵活,因此许多视图控制器的实现方式发生了巨大的变化.全新的UIPresentationController 在实现视图控制器间的过渡动画效果和自适应设备尺 ...
- Ionic文件目录说明
hooks //google之后这个目录应该是在编译cordova时自定义的脚本命令,方便整合到我们的编译系统和版本控制系统中 plugins //cordova插件的目录,插件的安装下一节详述 ...
- jquery append
将已经存在的一个dom对象A,通过jquery append插入另一个dom对象B,将会改变dom树结构--即A成为了B的子元素. 举个例子: js: $(".table-container ...