《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 一.操作系统是如 ... 
随机推荐
- 构建高可用web站点学习(二)
			web站点的缓存学习 缓存在web应用里面十分常见,也有各种各样的缓存,从请求开始一直到代码处理的阶段都可以采取缓存.下面就逐一介绍: 一.客户端缓存(浏览器和http方面) 前端页面缓存主要遵循ht ... 
- SQLSERVER一个比较不错的分页存储过程p_splitpage
			CREATE procedure p_splitpage @sql nvarchar(4000), --要执行的sql语句 @page int=1, --要显示的页码 @pageSize int, - ... 
- RSS新闻阅读器
			1.RSS格式结构 http://rss.sina.com.cn/blog/tech/kj.xml <?xml version="1.0" encoding="ut ... 
- 启动Activity但不显示其界面
			最近在工作中做了一个很简单的任务,制作一个apk,点击该app链接到某一个网站. 代码很简单,只有如寥寥几行: (browser.java) package com.test.browser; ... 
- 查找最小的K个元素,使用最大堆。
			查找最小的K个元素,使用最大堆,具体代码如下: #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace st ... 
- Floyd 算法 打印路径模板
			#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> ... 
- 【转】Linux I2C设备驱动编写(一)
			原文网址:http://www.cnblogs.com/biglucky/p/4059576.html 在Linux驱动中I2C系统中主要包含以下几个成员: I2C adapter 即I2C适配器 I ... 
- (转载)python多行注释
			(转载)http://www.cnblogs.com/pylemon/archive/2011/05/23/2054090.html python本身不带多行注释,编辑时每行敲一个“#”相当的不方便, ... 
- SQL - 添加外键
			不解释: ---先创建外键的column ALTER TABLE tblLicenses ADD ProductID int not null; ---添加外键 ALTER TABLE tblLice ... 
- Ensures there will be no 'console is undefined' errors
			很早之前项目中遇到过这种bug, 当时没有多留意,只是暂时把笔记留了下来,今天整理笔记的时候,看到了,故先整理在此,具体用法下次遇到再好好理解理解.如果有筒子遇到过,麻烦留言说一下,先谢谢啦. //E ... 
