没有合适的资源?快使用搜索试试~ 我知道了~
首页EOS操作系统实战教程:源代码解析与实验指南
EOS操作系统实战教程:源代码解析与实验指南
需积分: 0 4 下载量 53 浏览量
更新于2024-07-01
1
收藏 4.27MB PDF 举报
《EOS操作系统实验教程_2.11》是由北京英真时代科技有限公司编著的一本针对操作系统原理的实践教材。该教程旨在将理论知识与实际操作相结合,帮助读者深入理解操作系统的核心概念。书中特别强调了操作系统原理在计算机科学教育中的核心地位,它是计算机科学专业学生的基石课程。 教程内容围绕EOS操作系统展开,选取其源代码进行详细剖析。作者通过丰富的代码实例和大量图示图表,引导读者逐步分析源代码,这种实践性的教学方式让读者能够在动手操作中学习,从而深化对操作系统原理的理解。全书共分为8章,包含了14个实验题目和6个课程设计题目,充分体现了动手实践的重要性。 本书的最大特色在于它的实验设计,不仅注重理论讲解,还鼓励读者亲自参与,通过实际操作来巩固和应用所学知识。它不仅是高等院校操作系统课程的理想教材,也适合广大程序开发者和操作系统爱好者作为自学工具使用。 版权方面,北京英真时代科技有限公司拥有本书的独家权益,读者可以免费获取电子版用于个人学习和研究,但禁止未经许可的传播、复制或抄袭。如果需要更多信息,可以通过提供的公司联系方式联系,包括地址、电话、QQ、邮箱以及网址。 《EOS操作系统实验教程_2.11》是一部理论与实践并重,注重动手能力培养的教材,对于提升读者的操作系统技能和理论认知具有很高的价值。通过跟随教程,读者不仅能掌握操作系统的基本原理,还能提升解决实际问题的能力。
资源详情
资源推荐
![](https://csdnimg.cn/release/download_crawler_static/86278623/bg10.jpg)
EOS 操作系统实验教程
北京英真时代科技有限公司 http://www.engintime.com
16
第 2 章 EOS 编程基础
本章主要介绍在 EOS 源代码中涉及到的 C 语言、汇编语言、数据结构等一些基础知识,并在最后简要
介绍了使用工具来提高阅读 EOS 源代码效率的方法。学习本章内容对阅读并理解 EOS 源代码有很大帮助,
建议读者先通读本章内容,尽量掌握本章的知识。如果有一些知识暂时理解不了也没关系,在读者学习后
面章节的过程中,可以随时再回到本章学习相关的内容。
2.1 EOS 内核源代码的结构
使用 OS Lab 打开 EOS 内核项目后,在“项目管理器”窗口中可以看到如图 2-1 所示的树结构,在此
树结构中可以浏览 EOS 内核的所有源代码文件。树的根节点表示项目(项目名称为“kernel”),根节点的
子节点是项目包含的文件夹或者文件。展开文件夹,可以浏览文件夹所包含的文件。EOS 内核的源代码文
件按照其所属的模块或其实现的功能,组织在不同的文件夹中,详细的说明可以参见表 2-2。
图 2-1:EOS 内核源代码的树结构
文件夹或文件
说明
api/ 此文件夹包含了一个源文件 eosapi.c。EOS 导出的 API 函数都是在此文件中定义的。
bochs/ 此文件夹中包含的文件用于启动 bochs 虚拟机并加载 EOS 操作系统。
boot/
此文件夹只包含了两个汇编文件 boot.asm 和 loader.asm。这两个文件生成的二进制
文件 boot.bin 和 loader.bin 会被写入软盘镜像文件。参见图 1-5。
inc/
此文件夹包含的三个公共头文件 eos.h、eosdef.h 和 error.h,会被复制到 SDK 文件
夹的 INC 子文件夹中,参见图 1-5、1-6 和 1-7。此文件夹还包括了各个模块用于公开
其信息的头文件,通过包含这些头文件,各个模块间可以相互提供服务。
io/
此文件夹包含了 IO 管理器以及各种设备驱动程序的源代码文件。此模块公开的信息
在 inc/io.h 头文件中声明,供其它模块使用。
ke/
此文件夹包含了 EOS 内核管理功能和系统进程的源代码文件。内核 管理功能包括了内
核初始化、中断管理、时钟管理和系统进程等。其中的 start.c 文件包含了内核的入
口函数 KiSystemStartup 的源代码,sysproc.c 文件包含了系统进程的源代码。此模
块公开的信息在 inc/ke.h 头文件中声明,供其它模块使用。
![](https://csdnimg.cn/release/download_crawler_static/86278623/bg11.jpg)
EOS 操作系统实验教程
北京英真时代科技有限公司 http://www.engintime.com
17
mm/
此文件夹包含了内存管理器的源代码文件。此模块公开的信息在 inc/mm.h 头文件中
声明,供其它模块使用。
ob/
此文件夹包含了内核对象管理器的源代码文件。此模块公开的信息在 inc/ob.h 头文
件中声明,供其它模块使用。
ps/
此文件夹包含了进程、线程管理器的源代码文件。此模块公开的信息在 inc/ps.h 头
文件中声明,供其它模块使用。
rtl/
此文件夹包含了内核运行时库的源代码文件。内核运行时库为内核各个模块提供了一
些常用函数和数据结构算法,例如 C 运行时库中的字符串函数在源文件 crt.c 中实现,
链表数据结构算法在源文件 list.c 中实现。此模块公开的信息在 inc/rtl.h 头文件
中声明,供其它模块使用。
Floppy.img
软盘镜像文件。由 EOS 内核源代码文件生成的二进制文件会被写入此软盘镜像文件中,
然后虚拟机就可以执行软盘中的 EOS 操作系统,参见图 1-5 和 1-7。直接双击此文件,
可以使用 Floppy Image Editor 工具打开此文件,并编辑软盘中的内容。
License.txt 《EOS 核心源代码协议》文件。
表 2-2:EOS 内核源代码组织方式的详细说明
另外,有些文件夹中还包含了名称为“i386”的 子文件夹,这些子文件夹中包含了和本模块相关的 X86
硬件平台特有功能的源代码。在后面的内容中,为了能够向读者准确说明源代码文件的位置,会使用路径
格式来表示,例如,ke/start.c 就是指在 ke 文件夹中的 start.c 文件。
2.2 预定义的 C 数据类型
由于 C 语言标准中并没有具体规定 int、short、long 等基本数据类型的字节长度,只是规定了 short
类型不长于 int 类型,int 类型不长于 long 类型。所以各个厂商提供的编译器,会根据不同的硬件平台为
这些基本数据类型选择适合的字节长度。例如,在基于 DOS 的 Turbo C 中,int 和 short 类型长度为 2 字
节,long 类型长度为 4 字节;而在 Microsoft Visual Studio 和 GCC 中,short 类型长度为 2 字节,int
和 long 类型长度为 4 字节。
EOS 内核为了避免由于基本数据类型的字节长度不同所带来的影响,在 inc\eosdef.h 中定义了自己的
数据类型,如下:
typedef char CHAR, *PCHAR, *PSTR;
typedef const char *PCSTR;
typedef unsigned char UCHAR, *PUCHAR;
typedef unsigned char BYTE;
typedef short SHORT, *PSHORT;
typedef unsigned short USHORT, *PUSHORT;
typedef int INT, *PINT;
typedef unsigned int UINT, *PUINT;
typedef long LONG, *PLONG;
typedef unsigned long ULONG, *PULONG;
typedef long long LONGLONG, *PLONGLONG;
typedef unsigned long long ULONGLONG, *PULONGLONG;
typedef int BOOL, *PBOOL;
typedef char BOOLEAN, *PBOOLEAN;
typedef float FLOAT, *PFLOAT;
typedef double DOUBLE, *PDOUBLE;
![](https://csdnimg.cn/release/download_crawler_static/86278623/bg12.jpg)
EOS 操作系统实验教程
北京英真时代科技有限公司 http://www.engintime.com
18
typedef void *PVOID;
typedef void *HANDLE;
typedef HANDLE *PHANDLE;
在为 EOS 编写 C 代码时,所有的变量都应该使用 EOS 自己的数据类型来进行定义,这样就可以不用考
虑系统平台的影响。可以永远认为 SHORT 类型长度为 2 字节,INT 类型长度为 4 字节。当需要在不同的系
统平台上编译 EOS 时, 只 需要修改 EOS 自己定义的数据类型即可,而其它的源代码就不需要被修改。例如 ,
在 16 位平台上可将 INT 类型定义为等同于 long 类型,从而保证 INT 类型的长度仍然为 4 字节,如下:
typedef long INT, *PINT;
另外,为了方便编写更加规范的代码,EOS 定义了各种类型对应的指针类型,整型对应的无符号类型
以及 BOOL 类型等多种类型。读者应该已经从上面的定义看出了一些规律,凡是以字母“P”开头的类型都
是对应类型的指针类型,例如 PCHAR 是指向字符的指针类型,等同于“char*”。读者在定义两个指向字符
的指针变量时,可写成“PCHAR p1,p2;”,效果等同于“char *p1, *p2;”。而凡是以字母 U 开头的类
型都是无符号类型。
这里需要特别说明的是 PCHAR、PSTR 和 PCSTR 数据类型。在 C 语言中,定义字符串指针和字符指针的
语句是一样的,都是 char*,这就造成在阅读代码时必须根据上下文来理解 char*的意思。为了解决这个
问题,EOS 分别定义了 PCHAR 和 PSTR 数据类型,虽然它们都等同于 char *,但是在编写代码时,使用 PCHAR
定义字符指针变量,使用 PSTR 定义字符串指针变量。这样一来,在阅读代码时就能够很容易的分辨出哪
些是字符指针类型,哪些是字符串指针类型了。而且,EOS 还将常用的字符串常量指针类型 const char*
定义为 PCSTR 类型,其中的字母 C 代表关键字 const。
2.3 链表的使用
EOS 内核中维护了大量的内核数据,为了方便、高效的管理这些数据,它们必须以某种合适的方式组
织起来。根据已有的数据结构方面的知识,可以使用多种方式来组织数据,例如数组、链表、队列等。考
虑到 EOS 内核中的很多数据经常需要动态的调整(插入、删除等),所 以 EOS 内核广泛使用了链表,特别
是双向链表。
在详细讨论 EOS 内核使用的双向链表之前,先来回顾一下通常情况下我们是如何使用双向链表的。我
们一般会在结构体中定义两个指向此结构体的指针变量,用于组织双向链表,像下面的样子:
typedef struct _FOO
{
…// 其它成员
struct _FOO *Next; // 指向后一项
struct _FOO *Prev; // 指向前一项
…// 其它成员
}FOO, *PFOO;
然后再编写一组用于管理此链表的函数,可能包括创建、插入、删除等操作。但是,如果 EOS 中需要使用
双向链表来组织的各种结构体都像上面的样子定义,并且为每种结构体都编写一组操作链表的函数,这种
设计方法为 EOS 增加的复杂度是绝对无法容忍的。显然,需要为 EOS 设计一种新的方法,这种方法能够使
![](https://csdnimg.cn/release/download_crawler_static/86278623/bg13.jpg)
EOS 操作系统实验教程
北京英真时代科技有限公司 http://www.engintime.com
19
用统一的方式来定义 EOS 中那些需要使用双向链表来组织的结构体,而且只需定义一组操作链表的函数就
可以管理各种结构体的链表。
EOS 使用了与 Linux 和 Windows 类似的、在结构体中嵌入链表项结构体成员的方式。首先,EOS 在文
件 inc/rtl.h 中定义了一个双向链表项结构体:
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Next;
struct _LIST_ENTRY *Prev;
} LIST_ENTRY, *PLIST_ENTRY;
然后,在需要使用双向链表组织的结构体中嵌入一个使用该链表项结构体定义的成员。此外,还需要使用
链表项结构体定义一个变量(通常为全局变量)来做为链表头。可以参考下面的例子:
typedef struct _FOO
{
…// 其它成员
LIST_ENTRY ListEntry; // 嵌入的链表项结构体成员
…// 其它成员
}FOO, *PFOO;
LIST_ENTRY ListHead; // 链表头
EOS 还在文件 rtl/list.c 中定义了一组用于操作双向链表的函数。注意,这些函数总是使用链表头或
者嵌入在结构体中的链表项做为参数和返回值,而不是包含链表项的结构体本身。假设有一个 FOO 结构体
变量的指针 pFoo,为了把这个变量插入到链表的尾部(就是将变量中嵌入的链表项插入链表的尾部),应
该像下面这样引用变量中嵌入的链表项:
ListInsertTail(&ListHead, &pFoo->ListEntry);
这样就可以由 FOO 结构体中的 ListEntry 成员和链表头 ListHead 组成一个双向循环链表,如图 2-3。
...
...
...
...
FOO FOO
ListEntry
ListEntry
ListHead
图 2-3:由嵌入的链表项和链表头链接而成的双向循环链表
从图中可以很明显的看出,双向链表是由链表头和链表项链接而成的,这就造成双向链表本质上并不
关心其中的链表项是嵌入在哪种类型的结构体当中。所以,在使用链表时,应该尽量保持链表中所链接的
是相同结构体类型的项,避免增加复杂度。另外,当从链表中提取一个项时,得到的地址是链表项的地址,
为了得到其所嵌入的外层结构体的地址,可以根据链表项在结构体中的偏移位置计算出外层结构体的地址。
EOS 在文件 inc/eosdef.h 中定义了一个宏函数 CONTAINING_RECORD 来完成此功能。可以参考下面的例子:
![](https://csdnimg.cn/release/download_crawler_static/86278623/bg14.jpg)
EOS 操作系统实验教程
北京英真时代科技有限公司 http://www.engintime.com
20
PLIST_ENTRY pListEntry = ListRemoveHead(&ListHead);
PFOO pFoo = CONTAINING_RECORD(pListEntry, FOO, ListEntry);
上面的代码中,首先调用 ListRemoveHead 函数将链表中的第一项从链表中移除,pListEntry 保存了被移
除的链表项的地址。然后调用 CONTAINING_RECORD 宏函数根据链表项的地址,获取链表项所嵌入的 FOO 结
构体变量的地址。关于宏函数 CONTAINING_RECORD 的详细说明,请参见 2.9 节。
现在可以尝试讨论一种稍微复杂一点情况。假设 FOO 结构体的变量可以同时存在于两个不同的双向链
表中,编写的代码可以是下面的样子:
typedef struct _FOO
{
…// 其它成员
LIST_ENTRY ListEntry1; // 用于链表 1 的链表项
LIST_ENTRY ListEntry2; // 用于链表 2 的链表项
…// 其它成员
}FOO, *PFOO;
LIST_ENTRY ListHead1; // 链表 1 的链表头
LIST_ENTRY ListHead2; // 链表 2 的链表头
由 FOO 结构体中的 ListEntry1、ListEntry2 成员和链表头 ListHead1、ListHead2 组成的两个双向循环链
表可以如图 2-4 所示。
...
ListEntry2
...
...
...
...
FOO FOO
ListEntry1
ListEntry1
ListHead1
ListEntry2
ListHead2
ListEntry2
...
FOO
ListEntry1
图 2-4:由嵌入的链表项和链表头链接而成的复杂的双向循环链表
所以,可以通过在结构体中嵌入多个链表项的方式,使结构体变量同时存在于多个不同的链表中。EOS
内核中即存在此种情况,请读者通过图 2-4 仔细体会。此外,注意代码中使用的命名规则,链表头使用“Head”
后缀,链表项使用“Entry”后缀,EOS 源代码也遵守同样的规则。表 2-5 列出了定义在文件 rtl/list.c
中的,用于操作双向链表的所有函数。这些函数在文件 inc/rtl.h 中都进行了声明,供 EOS 内核的其它模
块使用。
函数
描述
ListInitializeHead
初始化链表头,将链表初始化为空链表。
ListIsEmpty
判断链表是否为空。
剩余240页未读,继续阅读
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://profile-avatar.csdnimg.cn/3be06f59ba094c62afbf0b9c6e85c290_weixin_35779370.jpg!1)
赵小杏儿
- 粉丝: 25
- 资源: 314
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助
![](https://csdnimg.cn/release/wenkucmsfe/public/img/voice.245cc511.png)
最新资源
- 计算机人脸表情动画技术发展综述
- 关系数据库的关键字搜索技术综述:模型、架构与未来趋势
- 迭代自适应逆滤波在语音情感识别中的应用
- 概念知识树在旅游领域智能分析中的应用
- 构建is-a层次与OWL本体集成:理论与算法
- 基于语义元的相似度计算方法研究:改进与有效性验证
- 网格梯度多密度聚类算法:去噪与高效聚类
- 网格服务工作流动态调度算法PGSWA研究
- 突发事件连锁反应网络模型与应急预警分析
- BA网络上的病毒营销与网站推广仿真研究
- 离散HSMM故障预测模型:有效提升系统状态预测
- 煤矿安全评价:信息融合与可拓理论的应用
- 多维度Petri网工作流模型MD_WFN:统一建模与应用研究
- 面向过程追踪的知识安全描述方法
- 基于收益的软件过程资源调度优化策略
- 多核环境下基于数据流Java的Web服务器优化实现提升性能
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
![](https://img-home.csdnimg.cn/images/20220527035711.png)
![](https://img-home.csdnimg.cn/images/20220527035711.png)
![](https://img-home.csdnimg.cn/images/20220527035111.png)
安全验证
文档复制为VIP权益,开通VIP直接复制
![](https://csdnimg.cn/release/wenkucmsfe/public/img/green-success.6a4acb44.png)