20135327郭皓——Linux内核分析第二周 操作系统是如何工作的

操作系统是如何工作的

上章重点回顾:

计算机是如何工作的?(总结)——三个法宝

  • 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构;
  • 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算机来说并不那么重要,但有了高级语言及函数,堆栈成为了计算机的基础功能;
    • 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

20135327郭皓——Linux内核分析第二周 操作系统是如何工作的的相关文章

20135327郭皓--Linux内核分析第九周 期中总结

Linux内核分析第九周 期中总结 一.知识概要 1. 计算机是如何工作的 存储程序计算机工作模型:冯诺依曼体系结构 X86汇编基础 会变一个简单的C程序分析其汇编指令执行过程 2. 操作系统是如何工作的 函数调用堆栈 模拟存储程序计算机工作模型和时钟中断 在mykernel基础构建一个简单的操作系统 3.构造一个简单的Linux系统 Linux内核源代码 构造一个简单的Linux系统 跟踪调试Linux内核的启动过程 4. 系统调用 用户态.内核态和中断 系统调用概述 使用库函数API和C代码

20135327郭皓--Linux内核分析第三周 构造一个简单的Linux系统MenuOS

Linux内核分析第三周  构造一个简单的Linux系统MenuOS 前提回顾 1.计算机是如何工作的三个法宝 1.存储程序计算机 2.函数调用堆栈 3.中断 2.操作系统的两把宝剑 中断上下文的切换 进程上下文的切换 第一讲  Linux内核源代码介绍 arch目录包括了所有和体系结构相关的核心代码.它下面的每一个子目录都代表一种Linux支持的体系结构,例如i386就是Intel CPU及与之相兼容体系结构的子目录.PC机一般都基于此目录. init目录包含核心的初始化代码(不是系统的引导代

20135327郭皓--Linux内核分析第七周 可执行程序的装载

第七周 可执行程序的装载 郭皓 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 一.预处理,编译,链接和目标文件格式 1.可执行程序是怎么得来的 c代码->预处理->汇编代码->汇编器->目标代码->链接成可执行文件->加载到内核执行 2.目标文件的格式ELF 符号修饰标准.变量内层布局.函数调用方式等这些跟可执行代码二进制兼容性相关的内容称为ABI

20135327郭皓--Linux内核分析第四周 扒开系统调用的三层皮(上)

Linux内核分析第四周 扒开系统调用的三层皮(上) 郭皓 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 一.用户态.内核态和中断 用户态:当进程在执行用户自己的代码时,则称其处于用户态,即此时处理器在特权级最低的(3级)用户代码中运行. 内核态:当一个进程执行系统调用而陷入内核代码中执行时,我们就称进程处于内核态,此时处理器处于特权级最高的(0级)内核代码中执行. PS:CPU指令

20135327郭皓--Linux内核分析第六周 进程的描述和进程的创建

进程的描述和进程的创建 一.进程的描述 操作系统三大功能: 进程管理 内存管理 文件系统 进程描述符task_struct数据结构 task _ struct:为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息. 进程的状态:Linux进程的状态(就绪态.运行态.阻塞态) 进程的标示pid:用来标示进程 进程描述符task_struct数据结构(重要部分): 1 struct task_struct { 2 volatile long state; /* 进程

linux内核分析第二周

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

Linux内核分析第一周——计算机是如何工作的

Linux内核分析第一周——计算机是如何工作的 李雪琦 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 冯诺依曼体系结构结构,就是存储程序计算机. 1.数字计算机的数制采用二进制: 2.计算机通常是顺序执行一条一条的指令,如果有必要就通过寄存器跳转到特定的地址,再执行,然后通过一系列机制返回原有的地址,继续顺序执行. 实验部分:

LINUX内核分析第二周学习总结:操作系统是如何工作的?

马启扬 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.函数调用堆栈 1. 小结:计算机是怎样工作的 三个法宝:存储程序计算机.函数调用堆栈.中断机制. 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构. 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算机来说并不那么重要,但有了高级语言及函数,堆栈成为了计算机的基础功能.(函数参数传递

Linux内核分析——第二周学习笔记

20135313吴子怡.北京电子科技学院 chapter 1 知识点梳理 (一)计算机是如何工作的?(总结)——三个法宝 ①存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: ②函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算机来说并不那么重要,但有了高级语言及函数,堆栈成为了计算机的基础功能: enter pushl %ebp movl %esp,%ebp leave movl %ebp,%esp popl %ebp 函数参数传递机制和局部变量存储 ③中