第二周 内核进程调度

操作系统为了实现支持多任务处理的需要,一般都会支持多进程的机制,所以进程的的切换是内核当中一个非常重要的功能模块,其它几个功能模块主要有

  • 处理器管理
  • 内存管理
  • 磁盘管理
  • 输入输出管理
  • 进程管理

本次实验主要是模拟了内核中的进程切换机制,以便加深对内核进程切换的理解。其中本次实验主要涉及以下三个代码文件。

mypcb.h

 1 /*
 2  *  linux/mykernel/mypcb.h
 3  *
 4  *  Kernel internal PCB types
 5  *
 6  *  Copyright (C) 2013  Mengning
 7  *
 8  */
 9
10 #define MAX_TASK_NUM        4
11 #define KERNEL_STACK_SIZE   1024*8
12
13 /* CPU-specific state of this task */
14 struct Thread {
15     unsigned long        ip;
16     unsigned long        sp;
17 };
18
19 typedef struct PCB{
20     int pid;
21     volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */
22     char stack[KERNEL_STACK_SIZE];
23     /* CPU-specific state of this task */
24     struct Thread thread;
25     unsigned long    task_entry;
26     struct PCB *next;
27 }tPCB;
28
29 void my_schedule(void);

mymain.c

 1 /*
 2  *  linux/mykernel/mymain.c
 3  *
 4  *  Kernel internal my_start_kernel
 5  *
 6  *  Copyright (C) 2013  Mengning
 7  *
 8  */
 9 #include <linux/types.h>
10 #include <linux/string.h>
11 #include <linux/ctype.h>
12 #include <linux/tty.h>
13 #include <linux/vmalloc.h>
14
15
16 #include "mypcb.h"
17
18 tPCB task[MAX_TASK_NUM];
19 tPCB * my_current_task = NULL;
20 volatile int my_need_sched = 0;
21
22 void my_process(void);
23
24
25 void __init my_start_kernel(void)
26 {
27     int pid = 0;
28     int i;
29     /* Initialize process 0*/
30     task[pid].pid = pid;
31     task[pid].state = 0;/* -1 unrunnable, 0 runnable, >0 stopped */
32     task[pid].task_entry = task[pid].thread.ip = (unsigned long)my_process;
33     task[pid].thread.sp = (unsigned long)&task[pid].stack[KERNEL_STACK_SIZE-1];
34     task[pid].next = &task[pid];
35     /*fork more process */
36     for(i=1;i<MAX_TASK_NUM;i++)
37     {
38         memcpy(&task[i],&task[0],sizeof(tPCB));
39         task[i].pid = i;
40         task[i].state = -1;
41         task[i].thread.sp = (unsigned long)&task[i].stack[KERNEL_STACK_SIZE-1];
42         task[i].next = task[i-1].next;
43         task[i-1].next = &task[i];
44     }
45     /* start process 0 by task[0] */
46     pid = 0;
47     my_current_task = &task[pid];
48     asm volatile(
49         "movl %1,%%esp\n\t"     /* set task[pid].thread.sp to esp */
50         "pushl %1\n\t"             /* push ebp */
51         "pushl %0\n\t"             /* push task[pid].thread.ip */
52         "ret\n\t"                 /* pop task[pid].thread.ip to eip */
53         "popl %%ebp\n\t"
54         :
55         : "c" (task[pid].thread.ip),"d" (task[pid].thread.sp)    /* input c or d mean %ecx/%edx*/
56     );
57 }
58 void my_process(void)
59 {
60     int i = 0;
61     while(1)
62     {
63         i++;
64         if(i%10000000 == 0)
65         {
66             printk(KERN_NOTICE "this is process %d -\n",my_current_task->pid);
67             if(my_need_sched == 1)
68             {
69                 my_need_sched = 0;
70                 my_schedule();
71             }
72             printk(KERN_NOTICE "this is process %d +\n",my_current_task->pid);
73         }
74     }
75 }

myinterrupt.c

 1 /*
 2  *  linux/mykernel/myinterrupt.c
 3  *
 4  *  Kernel internal my_timer_handler
 5  *
 6  *  Copyright (C) 2013  Mengning
 7  *
 8  */
 9 #include <linux/types.h>
10 #include <linux/string.h>
11 #include <linux/ctype.h>
12 #include <linux/tty.h>
13 #include <linux/vmalloc.h>
14
15 #include "mypcb.h"
16
17 extern tPCB task[MAX_TASK_NUM];
18 extern tPCB * my_current_task;
19 extern volatile int my_need_sched;
20 volatile int time_count = 0;
21
22 /*
23  * Called by timer interrupt.
24  * it runs in the name of current running process,
25  * so it use kernel stack of current running process
26  */
27 void my_timer_handler(void)
28 {
29 #if 1
30     if(time_count%1000 == 0 && my_need_sched != 1)
31     {
32         printk(KERN_NOTICE ">>>my_timer_handler here<<<\n");
33         my_need_sched = 1;
34     }
35     time_count ++ ;
36 #endif
37     return;
38 }
39
40 void my_schedule(void)
41 {
42     tPCB * next;
43     tPCB * prev;
44
45     if(my_current_task == NULL
46         || my_current_task->next == NULL)
47     {
48         return;
49     }
50     printk(KERN_NOTICE ">>>my_schedule<<<\n");
51     /* schedule */
52     next = my_current_task->next;
53     prev = my_current_task;
54     if(next->state == 0)/* -1 unrunnable, 0 runnable, >0 stopped */
55     {
56         /* switch to next process */
57         asm volatile(
58             "pushl %%ebp\n\t"         /* save ebp */
59             "movl %%esp,%0\n\t"     /* save esp */
60             "movl %2,%%esp\n\t"     /* restore  esp */
61             "movl $1f,%1\n\t"       /* save eip */
62             "pushl %3\n\t"
63             "ret\n\t"                 /* restore  eip */
64             "1:\t"                  /* next process start here */
65             "popl %%ebp\n\t"
66             : "=m" (prev->thread.sp),"=m" (prev->thread.ip)
67             : "m" (next->thread.sp),"m" (next->thread.ip)
68         );
69         my_current_task = next;
70         printk(KERN_NOTICE ">>>switch %d to %d<<<\n",prev->pid,next->pid);
71     }
72     else
73     {
74         next->state = 0;
75         my_current_task = next;
76         printk(KERN_NOTICE ">>>switch %d to %d<<<\n",prev->pid,next->pid);
77         /* switch to new process */
78         asm volatile(
79             "pushl %%ebp\n\t"         /* save ebp */
80             "movl %%esp,%0\n\t"     /* save esp */
81             "movl %2,%%esp\n\t"     /* restore  esp */
82             "movl %2,%%ebp\n\t"     /* restore  ebp */
83             "movl $1f,%1\n\t"       /* save eip */
84             "pushl %3\n\t"
85             "ret\n\t"                 /* restore  eip */
86             : "=m" (prev->thread.sp),"=m" (prev->thread.ip)
87             : "m" (next->thread.sp),"m" (next->thread.ip)
88         );
89     }
90     return;
91 }
时间: 2024-10-19 02:20:06

第二周 内核进程调度的相关文章

linux内核分析第二周

网易云课堂linux内核分析第二周 20135103                王海宁 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 操作系统的核心功能就是:进程调度和中断机制,通过与硬件的配合实现多任务处理,再加上上层应用软件的支持,最终变成可以使用户可以很容易操作的计算机系统, my_timer_handler 函数会被内核周期性的调用,每调用1000次,就去将全局变量my_need_sched的值修

20169217《Linux内核原理与分析》第二周作业

通过第二周的学习,我想把我的博客分为两部分,第一部分是实验楼linux内核分析实验一的实验报告,第二部分是看书第1,2,18章的内容和时间情况. 现在先说实验一 实验内容:将一段c语言程序反汇编成汇编程序. c语言程序代码:应实验要求我把其中部分数值进行了修改. int g(int x) { return x+6; } int f(int x) { return g(x); } int main(void) { return f(9)+3; } 实验过程: 首先创建一个main.c文件 将刚刚修

Linux内核设计(第二周)——操作系统工作原理

Linux内核设计(第二周)--操作系统工作原理 by苏正生 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.学习笔记总结 1.函数调用堆栈 (1).函数调用堆栈. 堆栈是C语言程序运行时必须的一个记录调用路径和参数的空间. cpu内部已经集成好的功能,pop,push,enter-- 函数调用构架 传递参数,通过堆栈 保存返回值,%eax 提供局部变量空间 -- C语言编译器对堆栈

魏昊卿——《Linux内核分析》第二周作业:了解操作系统是怎样工作的

魏昊卿——<Linux内核分析>第二周作业:了解操作系统是怎样工作的 一.实验部分 使用实验楼的虚拟机打开shell cd LinuxKernel/linux-3.9.4 qemu -kernel arch/x86/boot/bzImage 然后cd mykernel 您可以看到qemu窗口输出的内容的代码mymain.c和myinterrupt.c 使用自己的Linux系统环境搭建过程参见mykernel,其中也可以找到一个简单的时间片轮转多道程序内核代码 mymain.c myinterr

20145311 《信息安全系统设计基础》第二周学习总结

20145311 <信息安全系统设计基础>第二周学习总结 教材学习内容总结 重新学习了一下上周的一部分命令:grep main wyx.c(grep的全文检索功能)ls > ls.txt :ls内容输出到文本find pathname -mtime -n/+nfind -size -n/+n (find的功能还是比较强大) 简单地学习了一下vim编辑器,跟着vimtutor简单地学了一些,在linux bash中使用vim能够极大地提高效率, vim的用法比较多,只学习了其中简单的一部分

Linux2.6内核--进程调度理论

从1991年Linux的第1版到后来的2.4内核系列,Linux的调度程序都相当简陋,设计近乎原始,见0.11版内核进程调度.当然它很容易理解,但是它在众多可运行进程或者多处理器的环境下都难以胜任. 正因为如此,在Linux2.5开发系列的内核中,调度程序做了大手术.开始采用了一种叫做O(1)调度程序的新调度程序——它是因为其算法的行为而得名的.它解决了先前版本Linux调度程序的许多不足,引入了许多强大的新特性和性能特征.O(1)调度程序虽然对于大服务器的工作负载很理想,但是在有很多交互程序要

20172328《程序设计与数据结构》第二周学习总结

20172328李馨雨<程序设计与数据结构>第二周学习总结 又到周五,李馨雨同学要开始写博客了.让我们开始吧!(????) 教材学习内容总结 1.首先是String类定义的字符串,然后是print和println的区别.转义字符的学习.(让我印象深刻的\b[回车符]在字符串结尾不显示哈哈,及其更新的\t[换行符],还有在课堂上真正明白了什么是回车.) 2.了解变量.常量.赋值语句.变量:保存数据的内存单元.常量:坚定自己不会变的数据!除非你用java的反射(有点复杂,改权限.去修饰符等等.没实

第二周Linux重点内容

第4天3A认证 授权 审计authentication authorization accouting aduition root :管理员Linux 组: groupname gid 管理员组 root other Linux安全上下文进程(process) 进程访问资源的权限取决于运行者的身份管理员 (root) /bin/cat (所有用户都能使用) /root/.bashrc判断:1使用工具 2 使用文件 [[email protected] ~]#ll /bin/cat-rwxr-xr

2014025670(12)《嵌入式系统程序设计》第二周学习总结

这周学习了gcc和gdb的使用还有makefile. 教材学习内容总结 教材内容开始看的有些吃力,很多地方都不太懂,网上查询和询问同学和老师之后,了解了很多,但是具体操作和实现方面还是比较难. 教材学习中问题和解决过程 对于gcc的操作在实验楼的学习中还是比较顺利,gdb的操作感觉有些村存在问题-----gdb的调试方面有些吃力,应该是自己没努力的结果,打算把问题汇总一下,再试试实验. 课后作业中的问题和解决过程 应用实验楼的第二周,第一周的内容感觉简单,消化很快,没想到第二周就感觉有些吃力,不