操作系统——内核雏形
操作系统——内核雏形
实验目的:
如何生成一个内核,能引导该内核,并进行扩展
实验内容:
- 汇编和C的互相调用方法
- ELF文件格式
- 使用Loader加载ELF文件
- 如何加载并扩展内核
- 设计题:修改启动代码,在引导过程中在屏幕上画出一个你喜欢的ASCII图案,并将第三章的内存管理功能代码、你自己设计的中断代码集成到你的kernel文件目录管理中,并建立makefile文件,编译成内核,并引导
实验环境:
VMware+Ubuntu32位
实验步骤:
1.汇编和C的互相调用方法
调用关系示意图如上,我们来看一下代码。
将foo.asm中定义的函数设为global模式,使得可以被调用,同时导入choose函数 int choose(int a ,int b)。
在bar.c中调用myprint函数,并定义choose函数。
编译,链接,运行:
可以发现调用是成功的!
2.ELF文件格式
格式图如上所示,其中我们来分别分析每一个部分的含义和数据结构。
ELF header:
Program header:
Program header描述的是一个段在文件中的位置、大小以及它被放进内存后所在的位置和大
小。如果我们想把一个文件加载进内存的话,需要的正是这些信息。
3.使用Loader加载ELF文件
我们的期望是使用Loader加载ELF文件,在之后肯定是要加载内核文件的。加载一个文件无非就是寻找文件、定位文件、读入内存三个步骤,所以在这次的loader中也是遵循这个步骤。
和之前实验的思路是类似的,只不过我们这次寻找的是kernel.bin文件。
在这里我们先随便写一个简单的kernel.asm文件来测试一下:
就是,现实一个字母K罢了。
我们来跑一跑这个loader程序
可以看见是成功的,因为出现了ready. 字符
4.如何加载并扩展内核
在上一步骤中,我们已经把kernel加载进了内存,但要想使内核运行并移交控制权,我们还需要先进入保护模式。
进入保护模式的代码已经很常见了,如下所示:
但与之前不一样的是,之前大多数描述符的段基址都是运行时计算后填入相应位置的,此时我们不需要这样了,因为我们自己加载了loader,已经确定了段地址并定义为了BaseOfLoader,所以在Loader中出现的变量的物理地址可以由下公式计算:
标号物理地址 = BaseOfLoader * 10h + 标号的偏移
于是我们将BaseOfLoader定义在一个文件里:
我们直接用了一个宏BaseOfLoaderPhyAddr来表示BaseOfLoader * 10h,当然是为了方便啦。
保护模式的代码如下,仅仅只是打印一个字符P
运行一下:
看到P,证明跳入保护模式成功。
成功跳入保护模式之后,我们获得内存信息、开启分页操作、最终整理内核并移交控制权。
获得内存信息是我们之前实验的内容,我们使用15h中断来完成,代码如下:
当然我们不能比之前的实验差,所以我们也把他加载进显存并打印:
和之前的代码基本就是从第三章中拿来直接使用的,别忘了将调用的函数DispInt,DispStr等包含在32位代码段中。
得到内存信息后,启动分页。
运行:
在之前的基础上出现了第三章那样的内存信息。
内存信息获取成功,分页开启成功,接下来我们将内存中的kernel程序整理,并移交控制权。
别忘了,我们的内核程序是一个elf程序,elf程序的program header table字段是有重要含义的,让我再来复习一下。
之前说到,我们要整理kernel程序,也就是说我们要把之前导入内存的代码整理到一个指定位置,这里我们需要使用memcpy函数。
具体实现如下:
但是,由于ld生成的可执行文件中p_vaddr的值较大,在这里超过我们的内存范围,所以我们需要修改一下ld指令时的参数。
解决了内存的问题之后,我们就可以向内核交出控制权了。
运行一下试试:
可以看到,出现了K字符。证明此时内核成功运行了!
接下来我们来进行内核扩展,先跑一下代码看看结果:
可以看到最下面一行出现一行字符串,但其实并没有那么简单。
首先,在Kliba.asm中定义了一个函数disp_str,用来打印字符串,并且将这个函数导出。
然后在kernel.asm中引入刚刚定义的函数,并将kernel,kliba,string,start链接成kernel.bin并挂载,作为真正的内核程序。
这个代码不仅定义了函数,还使用memcpy函数切换了堆栈和GDT,和之前仅仅打印一个字符的代码相比复杂了许多,但并没有花费很大精力,可见内核的扩展在C语言的帮助下已经简单了许多了。
5. 设计题:修改启动代码,在引导过程中在屏幕上画出一个你喜欢的ASCII图案,并将第三章的内存管理功能代码、你自己设计的中断代码集成到你的kernel文件目录管理中,并建立makefile文件,编译成内核,并引导
1)画出一个ASCII图案
在引导的时候,让他打印两个由字符构成的表情,调用一个打印函数打印如下定义的字符串:
函数还是使用的例子程序中提供的,结果如下:
打印其他的应该是差不多的,就是要记得构造好这个字符的形状。
2)Kernel扩展
扩展原理很简单,主要是中断处理程序的编写问题。之前我们的实验中有过类似的步骤,我们可以直接调用当时的函数。
当然,这里我们不再使用键盘中断,而是使用时钟中断,所以记得修改初始化的值:
其他地方与例子程序没什么很大差别,我们来看一下中断处理程序部分:
为了减少代码修改,我直接把整个函数复制进来了。。。
也就是说,遇到时钟中断的时候,我们的屏幕将根据时钟中断的“节奏”来打印字符串,在一段时间之后的截图如下:
看上去其实挺吓人的,但是从代码实现的角度来说应该是成功了吧。
实验问题:
1.汇编和C的调用方法是怎样的?
将汇编中定义的函数定义为global形式进行导出,将需要使用的函数进行导入;C语言在使用函数之前进行定义。在编译过程中先生成.o文件,并链接所有.o文件成为新文件,作为可执行程序,这个程序既包含汇编文件中的函数也包含C语言中的参数。
2.描述ELF文件格式以及作用
ELF header:用来定义ELF文件各信息,例如Program header table个数与偏移地址。
Program header table:
描述的是一个段在文件中的位置,位置、大小以及它被放进内存后所在的位置和大小。如果我们想把一个文件加载进内存的话,需要的正是这些信息。
3.如何从Loader引导ELF的原理
从Loader引导ELF文件需要经过几个步骤:寻找文件、定位文件、读入内存、转交控制权,其中前三个步骤与是否为ELF文件关系不大,对于要读入内存的文件来说都是需要经过这三个步骤的;最后一个步骤转交控制权则是根据ELF文件头与Program header table中的信息,将内存中的段进行整合并执行、转交控制权。
4.一个内核要能基本使用应该扩展哪些功能,怎么扩展
一个内核是在保护模式中被引导、运行,从实验的角度上说,内核需要接管电脑的控制权,管理计算机上运行的所有程序、进行的所有操作,所以至少应该具有中断管理,线程管理,地址空间和进程间通信等功能。
5.怎么管理内核文件目录?
在之前实验中我们的文件都是散落在一个文件夹里,编译生成的文件也是很混乱,最痛苦的是每次编译、挂载都有很多指令要打。所以我们需要使用make指令来管理内核文件目录。
目前为止我们可以整理成如下所示的结构:
然后,在a.img的路径下添加makefile文件,完成编译、链接、挂载的任务,最后启动bochs则可以达到目的。
Makefile如上所示,使用如上所述的方法和工具则可以很好的管理内核文件和目录。
操作系统——内核雏形相关推荐
- 【操作系统】Oranges学习笔记(四) 第五章 内核雏形
文章目录 5.1 在Linux下用汇编写HelloWord 5.2 再进一步,汇编和C同步使用 5.3 ELF(Executable and Linkable Format) 1. ELF Heade ...
- WINCE6.0操作系统---内核(kernel)学习
********************************LoongEmbedded******************************** 作者:LoongEmbedded(kandi ...
- 操作系统--内核级线程实现
五段论 `: 进入内核靠的是中断,fork是创建系统进程调用,进程由资源+执行序列组成,而创建执行序列其实就是创建线程. TSS:任务结构段 参考: 操作系统_哈尔滨工业大学_中 ...
- 0x300-从头开始写操作系统-内核
目录 回顾 今日目标 必要工具的安装及介绍 工具一览 工具介绍 GCC Hosted Environment Freestanding Environment Linker C 语言编译(gcc 的临 ...
- 1.操作系统——内核
计算机资源 计算机中资源分为软硬件两类: 其中,硬件资源有 总线:主要负责连接其他设备,是其他设备工作的基础. CPU:中央处理器,负责执行程序和处理数据运算. 内存:负责储存正在运行时的代码和数据. ...
- 【操作系统】浅谈OS内核
公众号「码农小奎」操作系统-内核篇 实际上,计算机体系在经过几十年的迭代更新之后,操作系统的内核离我们已经很遥远了. 无论是对普通用户还是上层软件开发者来说,内核之中有什么已经不太重要了,而用户更关心 ...
- 华为操作系统 28 年史
作者 | 老兵戴辉 本文经授权转自公众号最牛博弈(ID:zngame) 8月9日,东莞松山湖沸腾的一天,华为消费者业务CEO余承东发布了鸿蒙操作系统,中文来自山海经,英文叫HarmonyOS,不是以前 ...
- Linux是操作系统吗?GNU/Linux又是什么?
题记:这篇博文是在阅读Richard Stallman先生的<Linux and the GNU System>之后,并结合自己目前对Linux的认知写成的. 相信很多IT界的学习从业者, ...
- Linux内核源代码分析-第三章 内核体系结构概述-1
第3章 内核体系结构概述 本章从较高层次上对内核进行说明.从顺序上来说,本章首先介绍内核设计目标,接下来 介绍内核体系结构,最后介绍内核源程序目录结构. 3.1 内核设计目标 Linux 的内核展现出 ...
- Linux运维基础(硬件和操作系统)
VMware Workstation的使用: 虚拟机 虚拟计算机 在一个主机上,软件+硬件模拟出的硬件设备,然后在虚拟出来的设备上安装系统,等同于在物理机上的操作! 现代计算机设备的组成部分: 运算器 ...
最新文章
- leetcode中求subset、全排列等问题的回溯算法总结
- BZOJ 3195: [Jxoi2012]奇怪的道路 | 状压DP
- 【JUC系列】Future异步回调模式
- java jquery post_jquery js post变量set和get for post
- 大数据统计学直观图表(二)
- Android监视器概述
- (转载)Manacher'sAlgorithm: O(n)时间求字符串的最长回文子串
- Ruby设计模式透析之 —— 策略(Strategy)
- TMS320C55x的硬件结构
- yacc 简易计算机规则,YACC 使用说明——计算器实例.pdf
- 智慧园区弱电系统集成建设方案
- 《TR-069_Amendment-2》翻译
- matlabRC电路实验仿真
- 电脑死机,Word忘了保存怎么恢复?(编辑器是WPS)
- 虚拟服务器忘记密码,win7系统下VMware虚拟机忘记开机密码的解决方法
- DNS隧道通信的检测
- 微信公众号编辑菜单栏代码
- SQL触发器总结 - sql server 2012数据库基础-触发器及应用-实验报告
- 四川途志:抖音直播带货什么产品最好卖?
- 自动编解码器的训练与数据识别效果解析
热门文章
- 【风控策略】通过查全率和查准率确定cutoff
- java 中奖_java的if判断是否中奖了(21)
- android 设计psd,如何将PSD设计转换为Android xml?
- mysql超卖问题处理_mysql 解决超卖问题的锁分析
- 3种方法解决word文档无法编辑
- 计算机xp系统ie8,WinXP系统IE8安装失败的解决方法
- python描述数据维度的含义_NumPy中的维度(dimension)、轴(axis)、秩(rank)的含义
- 卫星高度角和方位角的计算
- 内外网数据交换方式有哪些?
- CPU卡一卡通解决方案