基于mykernel 2.0编写一个操作系统内核
Posted lc120798654
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于mykernel 2.0编写一个操作系统内核相关的知识,希望对你有一定的参考价值。
按照https://github.com/mengning/mykernel 的说明配置mykernel 2.0,熟悉Linux内核的编译:
依次执行:
窗口:
基于mykernel 2.0编写一个操作系统内核,参照https://github.com/mengning/mykernel 提供的范例代码:
定义pcb头文件
修改mymain.c
修改myinterrupt.c
代码分析:
在mypcb.h头文件中定义最大进程数为4,每个进程栈大小为2048个unsigned long长度,定义pcb结构体,其中pid为进程id,state为进程状态,是否可以执行,stack为进程堆栈,thread结构体包含ip和sp,分别表示进程保存的ip和sp的值,用于保存现场和恢复现场,task_entry指向进程代码的开头,next指针指向下一个进程。
在mymain.c中定义进程初始化,初始化id,state变为0,可执行,thread.ip和task_entry指向进程代码开头,thread.sp指向栈底,next指针指向下一个进程,将进程循环连接,从进程0开始执行,将my_current_task指向进程0,将thread.sp的值给rsp,保存rbp的值到进程0的栈中,保存thread.ip到栈中,通过ret将thread.ip出栈给rip,指向0进程的代码。
在mymain.c的my_process中为循环执行的进程的代码,其中通过循环增加i,使得每隔一段时间输出当前进程id,判断my_need_sched的值,若为1则需要切换进程,将其置为0,转到myinterrupt.c中my_schedule中进行进程切换,在myinterrupt.c中定义的my_timer_handler模拟时间片,决定是否需要切换进程,不停的增加time_count,每1000个time_count将my_need_sched从0置为1,正在运行的进程发现my_need_sched变为1,则通过my_schedule进行进程切换,分为先前进程和下一进程,my_schedule中将现在的rbp保存在先前进程栈中,将现在rsp保存在先前进程的thread.sp中,将rsp的值变为下一进程thread.sp保存的位置,使其指向下一进程的栈,将先前进程要执行的下一条指令地址保存在先前进程的thread.ip中,通过将下一进程thread.ip中保存的地址压入栈中,再ret,使rip变为下一进程要执行的下一条指令的地址,下一进程thread.sp指向的位置保存了下一进程的rbp,将其出栈给rbp,整个过程保存了先前进程的rbp,rsp,rip并将rbp,rsp,rip都变为了下一进程之前所保存的值,完成了进程切换。
运行结果:
简要分析操作系统内核核心功能及运行工作机制:
内核指的是一个提供硬件抽象层、磁盘及文件系统控制、多任务等功能的系统软件。直接对硬件操作是非常复杂的,所以内核通常提供一种硬件抽象的方法来完成这些操作。内核常驻内存,包括进程调度,中断处理,时钟管理,原语操作,资源管理(进程,设备,内存)硬件抽象隐藏了复杂性,为应用软件和硬件提供了一套简洁,统一的接口,使程序设计更为简单。
以上是关于基于mykernel 2.0编写一个操作系统内核的主要内容,如果未能解决你的问题,请参考以下文章