zoukankan      html  css  js  c++  java
  • 2020-2021-1 20209307《Linux内核原理与分析》第三周作业

    一、计算机的三大法宝

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

    二、堆栈

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

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

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

    三、实验二

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

         2、修改代码

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

    
    #include <linux/types.h>
    #include <linux/string.h>
    #include <linux/ctype.h>
    #include <linux/tty.h>
    #include <linux/vmalloc.h>
    #include "mypcb.h"
    
    tPCB task[MAX_TASK_NUM];
    tPCB * my_current_task = NULL;
    volatile int my_need_sched = 0;
    
    void my_process(void);
    
    void __init my_start_kernel(void)
    {
        int pid = 0;
        int i;
        /* Initialize process 0*/
        task[pid].pid = pid;
        task[pid].state = 0;/* -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-1];
        task[pid].next = &task[pid];
        /*fork more process */
        for(i=1;i<MAX_TASK_NUM;i++)
        {
            memcpy(&task[i],&task[0],sizeof(tPCB));
            task[i].pid = i;
            task[i].thread.sp = (unsigned long)(&task[i].stack[KERNEL_STACK_SIZE-1]);
            task[i].next = task[i-1].next;
            task[i-1].next = &task[i];
        }
        /* start process 0 by task[0] */
        pid = 0;
        my_current_task = &task[pid];
        asm volatile(
            "movl %1,%%esp
    	"     /* set task[pid].thread.sp to rsp */
            "pushl %1
    	"             /* push rbp */
            "pushl %0
    	"             /* push task[pid].thread.ip */
            "ret
    	"                 /* pop task[pid].thread.ip to rip */
            : 
            : "c" (task[pid].thread.ip),"d" (task[pid].thread.sp)    /* input c or d mean %ecx/%edx*/
        );
    } 
    
    int i = 0;
    
    void my_process(void)
    {    
        while(1)
        {
            i++;
            if(i%10000000 == 0)
            {
                printk(KERN_NOTICE "this is process %d -
    ",my_current_task->pid);
                if(my_need_sched == 1)
                {
                    my_need_sched = 0;
                    my_schedule();
                }
                printk(KERN_NOTICE "this is process %d +
    ",my_current_task->pid);
            }     
        }
    }

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

    #include <linux/types.h>
    #include <linux/string.h>
    #include <linux/ctype.h>
    #include <linux/tty.h>
    #include <linux/vmalloc.h>
    
    #include "mypcb.h"
    
    extern tPCB task[MAX_TASK_NUM];
    extern tPCB * my_current_task;
    extern volatile int my_need_sched;
    volatile int time_count = 0;
    
    void my_timer_handler(void)
    {
        if(time_count%1000 == 0 && my_need_sched != 1)
        {
            printk(KERN_NOTICE ">>>my_timer_handler here<<<
    ");
            my_need_sched = 1;
        } 
        time_count ++ ;  
        return;      
    }
    
    void my_schedule(void)
    {
        tPCB * next;
        tPCB * prev;
    
        if(my_current_task == NULL 
            || my_current_task->next == NULL)
        {
            return;
        }
        printk(KERN_NOTICE ">>>my_schedule<<<
    ");
        /* schedule */
        next = my_current_task->next;
        prev = my_current_task;
        if(next->state == 0)/* -1 unrunnable, 0 runnable, >0 stopped */
        {        
            my_current_task = next; 
            printk(KERN_NOTICE ">>>switch %d to %d<<<
    ",prev->pid,next->pid);  
            /* switch to next process */
            asm volatile(    
                "pushl %%ebp
    	"         /* save rbp of prev */
                "movl %%esp,%0
    	"     /* save rsp of prev */
                "movl %2,%%esp
    	"     /* restore  rsp of next */
                "movl $1f,%1
    	"       /* save rip of prev */    
                "pushl %3
    	" 
                "ret
    	"                 /* restore  rip of next */
                "1:	"                  /* next process start here */
                "popl %%ebp
    	"
                : "=m" (prev->thread.sp),"=m" (prev->thread.ip)
                : "m" (next->thread.sp),"m" (next->thread.ip)
            ); 
        }  
        return;    
    }

    运行结果如图:

  • 相关阅读:
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    block的是发送信号的线程,又不是处理槽函数的线程
  • 原文地址:https://www.cnblogs.com/wzyxiaowang/p/13872438.html
Copyright © 2011-2022 走看看