一、计算机的三大法宝

存储程序计算机、函数调用堆栈机制、中断机制

二、堆栈

堆栈的作用:记录函数调用框架、传递函数参数、保存返回值的地址、提供局部变量存储空间

堆栈操作:push栈顶地址减少四个字节、将操作数压入栈顶存储单元,pop栈顶地址增加四个字节、将栈顶存储的内容放回原寄存器。

堆栈相关寄存器:ESP堆栈指针、EBP基址指针、CS:EIP总是指向下一条指令地址

三、实验二

1、搭建虚拟的x86CPU实验平台

2、修改代码

mymain.c,这里是mykernel内核代码的入口,负责初始化内核的各个部分。

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

myinterrupt.c,主要增加了my_schedule(void)函数

  1. #include <linux/types.h>
  2. #include <linux/string.h>
  3. #include <linux/ctype.h>
  4. #include <linux/tty.h>
  5. #include <linux/vmalloc.h>
  6.  
  7. #include "mypcb.h"
  8.  
  9. extern tPCB task[MAX_TASK_NUM];
  10. extern tPCB * my_current_task;
  11. extern volatile int my_need_sched;
  12. volatile int time_count = 0;
  13.  
  14. void my_timer_handler(void)
  15. {
  16. if(time_count%1000 == 0 && my_need_sched != 1)
  17. {
  18. printk(KERN_NOTICE ">>>my_timer_handler here<<<\n");
  19. my_need_sched = 1;
  20. }
  21. time_count ++ ;
  22. return;
  23. }
  24.  
  25. void my_schedule(void)
  26. {
  27. tPCB * next;
  28. tPCB * prev;
  29.  
  30. if(my_current_task == NULL
  31. || my_current_task->next == NULL)
  32. {
  33. return;
  34. }
  35. printk(KERN_NOTICE ">>>my_schedule<<<\n");
  36. /* schedule */
  37. next = my_current_task->next;
  38. prev = my_current_task;
  39. if(next->state == 0)/* -1 unrunnable, 0 runnable, >0 stopped */
  40. {
  41. my_current_task = next;
  42. printk(KERN_NOTICE ">>>switch %d to %d<<<\n",prev->pid,next->pid);
  43. /* switch to next process */
  44. asm volatile(
  45. "pushl %%ebp\n\t" /* save rbp of prev */
  46. "movl %%esp,%0\n\t" /* save rsp of prev */
  47. "movl %2,%%esp\n\t" /* restore rsp of next */
  48. "movl $1f,%1\n\t" /* save rip of prev */
  49. "pushl %3\n\t"
  50. "ret\n\t" /* restore rip of next */
  51. "1:\t" /* next process start here */
  52. "popl %%ebp\n\t"
  53. : "=m" (prev->thread.sp),"=m" (prev->thread.ip)
  54. : "m" (next->thread.sp),"m" (next->thread.ip)
  55. );
  56. }
  57. return;
  58. }

运行结果如图:

2020-2021-1 20209307《Linux内核原理与分析》第三周作业的更多相关文章

  1. 20169212《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...

  2. 20169210《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...

  3. 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...

  4. 2017-2018-1 20179215《Linux内核原理与分析》第二周作业

    20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...

  5. 2019-2020-1 20199329《Linux内核原理与分析》第九周作业

    <Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...

  6. 2019-2020-1 20199329《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...

  7. 2019-2020-1 20209313《Linux内核原理与分析》第二周作业

    2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...

  8. 2018-2019-1 20189221《Linux内核原理与分析》第一周作业

    Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...

  9. 2020-2021-1 20209307 《Linux内核原理与分析》第九周作业

    这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)> 这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第九周作业> 这个作业的目标 & ...

  10. 《Linux内核原理与分析》第一周作业 20189210

    实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...

随机推荐

  1. 重闯Sqli-labs关卡第二天(5关)

    第五关(双注入GET单引号字符型注入-报错时间注入) 盲注盲注,Blind SQL Injection基于布尔SQL盲注基于时间的SQL盲注基于报错的SQL盲注 核心代码:(不会返回数据库中的数据) ...

  2. 使用Camtasia给视频课件添加自动聚焦的效果

    随着现在抖音与微课市场的大火,原来可能只是因为兴趣爱好而剪辑制作了一些视频为爱发电,现在却完全可以当作一个事业来做了. 但是课件录制的时候,大部分的录制屏幕软件都是全屏或者固定屏幕大小录制的,有些小细 ...

  3. Camtasia中如何自定义视频输出格式

    Camtasia Studio是一款功能全面.操作简单的视频录制和编辑软件,它是很多需要进行录屏操作,比如制作教学视频的用户的不错选择.Camtasia 2020还为用户提供了极大的便利的全面的服务, ...

  4. CSP2020 游记

    Day -28 后天就初赛了,考了一套模拟题,自闭,心态爆炸,感觉退役不远了 Day -26(初赛) 香农是谁??? 手写随机nth_element与O(n)的哈希表??? 阅读程序T2时间复杂度分析 ...

  5. ②SpringCloud 实战:引入Feign组件,完善服务间调用

    这是SpringCloud实战系列中第二篇文章,了解前面第一篇文章更有助于更好理解本文内容: ①SpringCloud 实战:引入Eureka组件,完善服务治理 简介 Feign 是一个声明式的 RE ...

  6. Docker安装基本命令操作,带你了解镜像和容器的概念!

    上一章节我们了解了Docker的基本概念,以及相关原理.这一章节进行实操. <Docker这么火爆.章节一:带你详尽了解Docker容器的介绍及使用> 一.Docker安装 声明:Dock ...

  7. 【CF600E】Lomsat gelral——树上启发式合并

    (题面来自luogu) 题意翻译 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. ci <= n <= 1e5 裸题.统计时先扫一遍得到出 ...

  8. go特性-defer

    1:后定义的defer先执行(可以理解为栈的方式) // 222 // 111 func Test1(t *testing.T) { defer fmt.Println("111" ...

  9. redis-cli 持久化,复制,哨兵,事务,流水线

    一.持久化: 快照文件RDB 保存"开始"创建新快照一刻的内存快照,创建过程的内存变化不会被记录 创建快照的办法有几种 1.客户端可以通过想Redis发送BGSAVE来创建一个快照 ...

  10. Steps 组件的设计与实现

    NutUI 组件源码揭秘 前言 本文的主题是 Steps 组件的设计与实现.Steps 组件是 Steps 步骤和 Timeline 组件结合的组件,在此之前他们是两个不同的组件,在 NutUI 最近 ...