栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

2021-2022-1 20212819《Linux内核原理与分析》第三周作业

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

2021-2022-1 20212819《Linux内核原理与分析》第三周作业

完成一个简单的时间片轮转多道程序内核代码 1 实验过程

使用实验楼的虚拟机打开 shell

输入如下代码

# 注意路径是区分大小的
$ 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

运行结果如图

查看mymain.c和myinterrupt.c代码

2 mykernel时间片轮转代码分析

新增mypcb.h

#define MAX_TASK_NUM        4
#define KERNEL_STACK_SIZE   1024*8
 

struct Thread {
    unsigned long       ip;   //对应eip
    unsigned long       sp;   //对应esp
};
 
typedef struct PCB{
    int pid;                 //定义进程id
    volatile long state;     //-1 unrunnable, 0 runnable, >0 stopped
    char 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

#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后执行
qemu-system-x86_64 -kernel arch/x86/boot/bzImage

3 总结

计算机工作的三个法宝是存储程序计算机、函数调用堆栈、中断机制。本次通过实验楼的实验,了解学习了操作系统是如何工作原理。

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

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

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