栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

操作系统是如何工作的 基础知识

1.计算机的三个法宝:存储程序计算机、函数调用堆栈机制、中断。
2.什么是堆栈?堆栈是c语言程序运行时必须使用的记录函数调用路径和参数存储的空间。其具体作用有:记录函数调用框架、传递函数参数、保存返回值的地址、提供函数内部局部变量的存储空间等。
3.中断机制:当一个中断信号发生时,CPU将当前所执行程序的EIP和ESP压入内核堆栈,然后使EIP指向中断处理程序入口,保存现场之后执行其他程序,执行完再恢复现场,恢复EIP和ESP,继续执行中断前的程序。
内嵌汇编常用限定符:

$ cd ~/LinuxKernel/linux-3.9.4
$ rm -rf mykernel
$ patch -p1 < ../mykernel_for_linux3.9.4sc.patch
$ make allnoconfig

$ make

运行上述代码块后:

$ qemu -kernel arch/x86/boot/bzImage


然后 cd mykernel ,可以看到 qemu 窗口输出的内容的代码 mymain.c 和 myinterrupt.c
查看 mymain.c 和 myinterrupt.c的内容

在makernel基础上构造一个很简单的操作系统内核 mypcb.h用来定义进程控制块,包括进程标识pid、进程状态state 和进程入口entry等。
#define MAX_TASK_NUM        4
#define KERNEL_STACK_SIZE   1024*2

struct Thread {
    unsigned long		ip;
    unsigned long		sp;
};

typedef struct PCB{
    int pid;
    volatile long state;	
    unsigned long stack[KERNEL_STACK_SIZE];
    
    struct Thread thread;
    unsigned long	task_entry;
    struct PCB *next;
}tPCB;

void my_schedule(void);
mymain.c是内核代码的入口,负责初始化内核的各个组成部分。
#include 
#include 
#include 
#include 
#include 
#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;
    
    task[pid].pid = pid;
    task[pid].state = 0;                               
    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];                  
                             
    for(i=1;ipid);
            if(my_need_sched == 1)
            {
                my_need_sched = 0;
                my_schedule();
            }
            printk(KERN_NOTICE "this is process %d +n",my_current_task->pid);
        }     
    }
}
myinterrupt.c增加了进程切换的代码 my_schedule(void)函数。
#include 
#include 
#include 
#include 
#include 
#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 1
    if(time_count%1000 == 0 && my_need_sched != 1)
    {
        printk(KERN_NOTICE ">>>my_timer_handler here<<next == NULL)
    {
        return;
    }
    printk(KERN_NOTICE ">>>my_schedule<<next;
    prev = my_current_task;
    if(next->state == 0)                  
    { 
        asm volatile(   
            "pushl %%ebpnt"          
            "movl %%esp,%0nt"     
            "movl %2,%%espnt"     
            "movl $1f,%1nt"            
            "pushl %3nt"                 
            "retnt"                           
            "1:t"                               
            "popl %%ebpnt"           
            : "=m" (prev->thread.sp),"=m" (prev->thread.ip)
            : "m" (next->thread.sp),"m" (next->thread.ip)
        ); 
        my_current_task = next; 
        printk(KERN_NOTICE ">>>switch %d to %d<<pid,next->pid);      
    }
    else                                         
    {
        next->state = 0;
        my_current_task = next;
        printk(KERN_NOTICE ">>>switch %d to %d<<pid,next->pid);
        
        asm volatile(   
            "pushl %%ebpnt"           
            "movl %%esp,%0nt"      
            "movl %2,%%espnt"      
            "movl %2,%%ebpnt"      
            "movl $1f,%1nt"              
            "pushl %3nt"                   
            "retnt"                             
            : "=m" (prev->thread.sp),"=m" (prev->thread.ip)
            : "m" (next->thread.sp),"m" (next->thread.ip)
        );          
    }   
    return; 
}

make:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/302962.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号