基于mykernel 2.0编写一个操作系统内核
一、配置mykernel 2.0,熟悉Linux内核的编译
1、实验环境:VMware 15 Pro,Ubuntu 18.04.4
2、配置环境
1)在电脑上先下载好以下两个文件,之后通过共享文件夹,将它们导入虚拟机。

2)在虚拟机中解压linux-5.4.34.tar.xz文件得到如下文件夹

3)进入该文件夹,打开终端,输入以下命令
patch -p1 < ../mykernel-2.0_for_linux-5.4.34.patch
sudo apt install build-essential libncurses-dev bison flex libssl-dev libelf-dev qemu
make defconfig
make -j$(nproc)
qemu-system-x86_64 -kernel arch/x86/boot/bzImage
上述命令的涵义是:配置mykernel、安装依赖包、编译、使用qemu运行mykernel
4)命令执行结果如下

5)此时,在Linux-5.3.34内核源代码根目录下进入mykernel目录,可以看到QEMU窗口输出内容的源代码mymain.c和myinterrupt.c,内容如下
/* mymain.c */
void __init my_start_kernel(void)
{
int i = 0;
while(1)
{
i++;
if(i%100000 == 0)
printk(KERN_NOTICE "my_start_kernel here %d \n",i);
}
}
/* myinterrupt.c */
void my_timer_handler(void)
{
printk(KERN_NOTICE "\n>>>>>>>>>>>>>>>>>my_timer_handler here<<<<<<<<<<<<<<<<<<\n\n");
}
程序执行的内容是:mymain.c中的代码在不停地被CPU执行。同时程序能够触发myinterrupt.c中的代码,周期性地产生的时钟中断信号。
二、基于mykernel 2.0编写一个操作系统内核
1、修改相关文件
1)在mykernel目录下添加mypcb.h文件,用于定义进程控制块,内容如下

2)修改mymain.c文件,添加my_process函数,用来模拟CPU执行的进程,内容如下

3)修改myinterrupt.c文件,修改my_timer_handler函数用来记录时间片,增加进程切换函数my_schedule(void),内容如下

2、重新编译并运行
运行结果如下:

三、简要分析操作系统内核核心功能及运行工作机制
1、mymain.c核心汇编代码分析
asm volatile(
"movq %1,%%rsp\n\t"
"pushq %1\n\t"
"pushq %0\n\t"
"ret\n\t"
:
: "c" (task[pid].thread.ip), "d" (task[pid].thread.sp)
);
分析:1) 将进程原堆栈的栈顶地址存入RSP寄存器,而task[pid].thread.sp初始值即为进程0的堆栈栈顶;
2) 将当前RBP寄存器的值压栈,因为是空栈,所以RSP与RBP相同。此时,RSP = RSP - 8;
3) 将当前进程的RIP压栈,值为初始化的my_process(void)函数的位置,此时,RSP = RSP - 8;
4) 将栈顶位置的task[0].thread.ip,也就是my_process(void)函数的地址放入RIP寄存器中。此时,RSP = RSP + 8;
5) 完成进程0的启动,执行my_process(void)函数。
2、myinterrupt.c核心代码分析
asm volatile(
"pushq %%rbp\n\t"
"movq %%rsp,%0\n\t"
"movq %2,%%rsp\n\t"
"movq $1f,%1\n\t"
"pushq %3\n\t"
"ret\n\t"
"1:\t"
"popq %%rbp\n\t"
: "=m" (prev->thread.sp),"=m" (prev->thread.ip)
: "m" (next->thread.sp),"m" (next->thread.ip)
);
分析:1)将当前RBP寄存器的值压入到进程0的堆栈;
2)RSP寄存器指向进程的栈顶地址,即保存进程0的栈顶地址;而%0、%1是指汇编代码下面输入输出部分的编号;
3)将进程1的栈顶地址存入RSP寄存器,完成进程0和进程1的堆栈切换;
4)保存进程0当前RIP寄存器值,这里$1f是指标号1;
5)将进程1的指令地址入栈,这时的next->thread.ip,在第一次执行时为进程1的起点my_process(void)函数,其余的情况均为$1f;
6)将栈中的next->thread.ip放入RIP寄存器;
7)标号1是一个特殊的地址位置,该位置的地址是$1f;
8)将进程1堆栈的基地址从堆栈中弹出到RBP寄存器中;
9)开始进程1,若进程1执行的过程中发生了进程调度和进程切换,进程0被会重新调度执行。
基于mykernel 2.0编写一个操作系统内核的更多相关文章
- 基于mykernel2.0编写一个操作系统内核
基于mykernel2.0编写一个操作系统内核 一. 实验准备 详细要求 基于mykernel 2.0编写一个操作系统内核 按照https://github.com/mengning/mykernel ...
- 编写和运行简单的"Hello World"操作系统内核
通常编写一个操作系统内核是一项浩大的工程.但我今天的目标是制作一个简单的内核,用比较方便的方法在虚拟机上验证它能够被grub装载和运行,并且可通过gdb进行调试,为接下去的工作创造一个基础环境. 首先 ...
- 用java做操作系统内核:软盘读写
在前两节,我们将一段代码通过软盘加载到了系统内存中,并指示cpu执行加入到内存的代码,事实上,操作系统内核加载也是这么做的.只不过我们加载的代码,最大只能512 byte, 一个操作系统内核,少说也要 ...
- JAVA WEB快速入门之从编写一个基于SpringBoot+Mybatis快速创建的REST API项目了解SpringBoot、SpringMVC REST API、Mybatis等相关知识
JAVA WEB快速入门系列之前的相关文章如下:(文章全部本人[梦在旅途原创],文中内容可能部份图片.代码参照网上资源) 第一篇:JAVA WEB快速入门之环境搭建 第二篇:JAVA WEB快速入门之 ...
- 基于Qt5.5.0的sql数据库、SDK_tts文本语音朗读的CET四六级单词背诵系统软件的编写V1.0
作者:小波 QQ:463431476 请关注我的博客园:http://www.cnblogs.com/xiaobo-Linux/ 我的第二款软件:CET四六级单词背诵软件.基于QT5.5.0.sql数 ...
- 基于Qt5.5.0的sql,C++备忘录软件的编写
我的第一个软件. 基于Qt5.5.0的 sql ,C++备忘录软件version1.0的编写 我用的Qt版本是5.5.0免配置编译器的版本,这里附上我使用的软件下载地址:http://download ...
- 基于vue2.0的一个豆瓣电影App
1.搭建项目框架 使用vue-cli 没安装的需要先安装 npm intall -g vue-cli 使用vue-cli生成项目框架 vue init webpack-simple vue-movie ...
- Asp.Net Core 2.0 项目实战(11) 基于OnActionExecuting全局过滤器,页面操作权限过滤控制到按钮级
1.权限管理 权限管理的基本定义:百度百科. 基于<Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员.后台管理员同时登录>我们做过了登录认证, ...
- 从0开始的Python学习013编写一个Python脚本
通过之前的学习我们已经了解了Python的很多基础运用了,现在我们尝试着做一个有使用价值的小脚本. 问题 需求: 我想要一个可以给我备份重要文件的程序. 需求分析: 首先文件是有存储路径,文件的路径和 ...
随机推荐
- C# 基础知识系列- 11 委托和事件
0. 前言 事件和委托是C#中的高级特性,也是C#中很有意思的一部分.出现事件的地方,必然有委托出现:而委托则不一定会有事件出现.那为什么会出现这样的关系呢?这就需要从事件和委托的定义出发,了解其中的 ...
- sqli-labs通关教程----21~30关
第二十一关 第二十一关我们正常登陆后看到,uname后面变成了一堆字母 这是经过base64编码之后的样子,所以就照葫芦画瓢,将我payload的uname后面的部分转码成base64,这里可以用正常 ...
- E2. Send Boxes to Alice (Hard Version)
秒的有点难以理解:https://blog.csdn.net/weixin_42868863/article/details/103200132 #include<bits/stdc++.h&g ...
- jmeter json path espressions学习
jsonpath表达式可以使用点或者括号来取值 管方详细介绍:https://goessner.net/articles/JsonPath/ $ :表示根对象 @:表示当前对象 . 或者[]:表示子运 ...
- Blazor WebAssembly 3.2.0 已在塔架就位 将发射新一代前端SPA框架
最美人间四月天,春光不负赶路人.在充满无限希望的明媚春天里,一路风雨兼程的.NET团队正奋力实现新的突破. 根据计划,新一代基于WebAssembly 技术研发的前端SPA框架Blazor 将于5月1 ...
- 实战 | 将Apache Hudi数据集写入阿里云OSS
1. 引入 云上对象存储的廉价让不少公司将其作为主要的存储方案,而Hudi作为数据湖解决方案,支持对象存储也是必不可少.之前AWS EMR已经内置集成Hudi,也意味着可以在S3上无缝使用Hudi.当 ...
- 用Java代码来校验QQ号
校验qq号码: 1.要求必须是5-15位数字 2.0不能开头 分析: A:键盘录入一个qq号码 B:写一个功能实现校验 C:调用功能,输出结果. 代码实现:public class RegexDemo ...
- 笔记本安装ubuntu18.08,解决过程中出现的各种问题
笔记本安装ubuntu18.08,解决过程中出现的各种问题 1.做启动U盘 在官网下载要安装的镜像,使用软碟通制作U盘安装盘 文件 -- 打开 然后 启动 -- 写入硬盘映像 -- 选择你的u盘 -- ...
- <algorithm>中sort()函数的用法
先说一下,本篇文章我没有讲sort()实现排序的原理,我写在另一篇文章中了,如果想了解的话,可以看一下,附上链接:https://www.cnblogs.com/buanxu/p/12772700.h ...
- 2019-2020-1 20199303《Linux内核原理与分析》第九周作业
进程的切换和一般执行过程 知识总结 操作系统原理中介绍了大量进程调度算法,这些算法从实现的角度看仅仅是从运行队列中选择一个新进程,选择的过程中运用了不同的策略而已. 对于理解操作系统的工作机制,反而是 ...