如下操作后
wget https://raw.github.com/mengning/mykernel/master/mykernel-2.0_for_linux-5.4.34.patch sudo apt install axel axel -n 20 https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.34.tar.xz xz -d linux-5.4.34.tar.xz tar -xvf linux-5.4.34.tar cd linux-5.4.34 patch -p1 < ../mykernel-2.0_for_linux-5.4.34.patch sudo apt install build-essential libncurses-dev bison flex libssl-dev libelf-dev make defconfig make -j sudo apt install qemu-system-x86_64
qemu-system-x86_64 -kernel arch/x86/boot/bzImage
qemu启动内核,一个简单的my_start_kernel在执行,同时my_timer_handler时钟中断处理程序周期性执行
如下图
在github上下载mypcb.h,myinterrupt.c以及mymain.c三个文件后,可以让该系统拥有进程调度功能
mypcb.h是是数据结构的定义,里面包含了一个进程所需要用到的的资源和控制信息,主要字段为进程id、进程状态、函数调用栈、代码入口以及thread结构体(ip、sp)以及用于指示链表的next字段
myinterrupt.c 的主要代码就是my_schedule函数,该函数也是是实现进程调度及上下文切换的核心。
也就是下面这段代码
printk(KERN_NOTICE ">>>switch %d to %d<<<\n",prev->pid,next->pid); /* switch to next process */ asm volatile( "pushq %%rbp\n\t" /* save rbp of prev */ "movq %%rsp,%0\n\t" /* save rsp of prev */ "movq %2,%%rsp\n\t" /* restore rsp of next */ "movq $1f,%1\n\t" /* save rip of prev */ "pushq %3\n\t" "ret\n\t" /* restore rip of next */ "1:\t" /* next process start here */ "popq %%rbp\n\t" : "=m" (prev->thread.sp),"=m" (prev->thread.ip) : "m" (next->thread.sp),"m" (next->thread.ip) );
简单描述就是:
保存当前运行进程的的bp值
保存当前运行进程的sp值
更新寄存器sp为需要切换进程的sp值
保存当前运行进程的ip值
更新寄存器ip为需要切换进程的ip值
最后就是mymain.c文件,可以看到my_process函数在一个循环里不停的调用my_schedule函数
当检测到my_need_sched=1时,就会进行进程切换,可以看到4个PCB进程在循环执行
而中断处理定期改变my_need_sched的值为1,进程切换时再改变为0
最终运行结果:
原文:https://www.cnblogs.com/qwertyue/p/12867139.html