操作系统是如何工作的
上章重点回顾:
计算机是如何工作的?(总结)——三个法宝
- 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构;
- 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算机来说并不那么重要,但有了高级语言及函数,堆栈成为了计算机的基础功能;
- enter
- pushl %ebp
- movl %esp,%ebp
- leave
- movl %ebp,%esp
- popl %ebp
- 函数参数传递机制和局部变量存储
- 中断,多道程序操作系统的基点,没有中断机制程序只能从头一直运行结束才有可能开始运行其他程序。
本章操作系统是如何工作的主要针对的是函数调用堆栈。
一、函数调用堆栈
1.堆栈
2.堆栈寄存器和堆栈操作
3.函数的堆栈框架
4.函数堆栈框架的形成
5.关于一个小例子
p2函数的调用详解:
main中的局部变量:
6.C代码中嵌入汇编代码 内嵌式语法
二、一个简单的时间轮转多道程序实验
1.进入实验楼,进入指定文件夹,运行程序
2.打开mymain.c myinterrupt.c
3.对核心代码分析
1 mymain.c 2 3 void __init my_start_kernel(void) //操作系统的入口 启动操作系统 4 { 5 int i = 0; 6 while(1) 7 { 8 i++; 9 if(i%100000 == 0) //每循环10万次打印一次 10 printk(KERN_NOTICE "my_start_kernel here %d \n",i); 11 12 } 13 }
1 myinterrupt.c 2 3 4 5 #include <trace/events/timer.h> 6 7 /* 8 * Called by timer interrupt. 9 */ 10 void my_timer_handler(void)//每一次中断都执行一次 11 { 12 printk(KERN_NOTICE "\n>>>>>>>>>>>>>>>>>my_timer_handler here<<<<<<<<<<<<<<<<<<\n\n"); 13 }
时间轮转多道程序就是在这个函数的基础上,加入自己的要求,下面是多进程时间片轮转代码
1 myinterrupt.c 2 3 4 #include <linux/vmalloc.h> 5 6 #include "mypcb.h" 7 + 8 extern tPCB task[MAX_TASK_NUM]; 9 extern tPCB * my_current_task; 10 -extern int task_count; 11 - 12 +extern volatile int my_need_sched; 13 +volatile int time_count = 0; 14 15 /* 16 * Called by timer interrupt. 17 @@ -25,21 +26,33 @@ extern int task_count; 18 */ 19 void my_timer_handler(void) 20 { 21 +#if 1 22 + if(time_count%1000 == 0 && my_need_sched != 1) 23 + { 24 + printk(KERN_NOTICE ">>>my_timer_handler here<<<\n"); 25 + my_need_sched = 1; 26 + } 27 + time_count ++ ; 28 +#endif 29 + return; 30 +} 31 + 32 +void my_schedule(void) 33 +{ 34 tPCB * next; 35 tPCB * prev; 36 - printk(KERN_NOTICE ">>>my_timer_handler here<<<\n"); 37 38 if(my_current_task == NULL 39 || my_current_task->next == NULL) 40 { 41 return; 42 } 43 + printk(KERN_NOTICE ">>>my_schedule<<<\n"); 44 /* schedule */ 45 next = my_current_task->next; 46 prev = my_current_task; 47 if(next->state == 0)/* -1 unrunnable, 0 runnable, >0 stopped */ 48 { 49 - printk(KERN_NOTICE ">>>switch %d to %d<<<\n",prev->pid,next->pid); 50 /* switch to next process */ 51 asm volatile( 52 "pushl %%ebp\n\t" /* save ebp */ 53 @@ -53,9 +66,27 @@ void my_timer_handler(void) 54 : "=m" (prev->thread.sp),"=m" (prev->thread.ip) 55 : "m" (next->thread.sp),"m" (next->thread.ip) 56 ); 57 - my_current_task = next; 58 + my_current_task = next; 59 + printk(KERN_NOTICE ">>>switch %d to %d<<<\n",prev->pid,next->pid); 60 } 61 - 62 + else 63 + { 64 + next->state = 0; 65 + my_current_task = next; 66 + printk(KERN_NOTICE ">>>switch %d to %d<<<\n",prev->pid,next->pid); 67 + /* switch to new process */ 68 + asm volatile( 69 + "pushl %%ebp\n\t" /* save ebp */ 70 + "movl %%esp,%0\n\t" /* save esp */ 71 + "movl %2,%%esp\n\t" /* restore esp */ 72 + "movl %2,%%ebp\n\t" /* restore ebp */ 73 + "movl $1f,%1\n\t" /* save eip */ 74 + "pushl %3\n\t" 75 + "ret\n\t" /* restore eip */ 76 + : "=m" (prev->thread.sp),"=m" (prev->thread.ip) 77 + : "m" (next->thread.sp),"m" (next->thread.ip) 78 + ); 79 + } 80 return; 81 }
1 mymain.c 2 3 4 tPCB task[MAX_TASK_NUM]; 5 tPCB * my_current_task = NULL; 6 -int task_count = 0; 7 +volatile int my_need_sched = 0; 8 9 void my_process(void); 10 11 @@ -26,20 +26,25 @@ void __init my_start_kernel(void) 12 { 13 int pid = 0; 14 int i; 15 - for(i=0;i<MAX_TASK_NUM;i++) 16 - { 17 - task[i].pid = -1; 18 - } 19 /* Initialize process 0*/ 20 task[pid].pid = pid; 21 task[pid].state = 0;/* -1 unrunnable, 0 runnable, >0 stopped */ 22 task[pid].task_entry = task[pid].thread.ip = (unsigned long)my_process; 23 task[pid].thread.sp = (unsigned long)&task[pid].stack[KERNEL_STACK_SIZE-1]; 24 task[pid].next = &task[pid]; 25 + /*fork more process */ 26 + for(i=1;i<MAX_TASK_NUM;i++) 27 + { 28 + memcpy(&task[i],&task[0],sizeof(tPCB)); 29 + task[i].pid = i; 30 + task[i].state = -1; 31 + task[i].thread.sp = (unsigned long)&task[i].stack[KERNEL_STACK_SIZE-1]; 32 + task[i].next = task[i-1].next; 33 + task[i-1].next = &task[i]; 34 + } 35 /* start process 0 by task[0] */ 36 pid = 0; 37 my_current_task = &task[pid]; 38 - task_count = task_count + 1; 39 asm volatile( 40 "movl %1,%%esp\n\t" /* set task[pid].thread.sp to esp */ 41 "pushl %1\n\t" /* push ebp */ 42 @@ -56,9 +61,15 @@ void my_process(void) 43 while(1) 44 { 45 i++; 46 - if(i%10000 == 0) 47 + if(i%10000000 == 0) 48 { 49 - printk(KERN_NOTICE "this is process %d \n",my_current_task->pid); 50 + printk(KERN_NOTICE "this is process %d -\n",my_current_task->pid); 51 + if(my_need_sched == 1) 52 + { 53 + my_need_sched = 0; 54 + my_schedule(); 55 + } 56 + printk(KERN_NOTICE "this is process %d +\n",my_current_task->pid); 57 } 58 } 59 }
总结:
郭皓原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
时间: 2024-10-24 09:58:50