【OS Pintos】Pintos 内核库基本数据结构 | 运行测试用例 alarm-multiple

简介: 【OS Pintos】Pintos 内核库基本数据结构 | 运行测试用例 alarm-multiple

💭 写在前面

Pintos 是操作系统课程下的一项动手实践,简单来说就是让你撸出一个操作系统。本篇博客是第一篇,先带着大家了解了解 Pintos 内核基本的数据结。随后我草草记录了一些我们配置 Pintos 的过程,且可能并不适用所有人,过程并不完整!配置Pintos环境请参考别处!作为斯坦福操作系统项目实践的 Pintos,难度极大,需要很多时间去做,工程浩大。Pintos 非常有价值,可以从中学到很多东西。


Ⅰ.  Pintos 内核库基本数据结构

0x00 引入:介绍

在我们在学习 Pintos 之前,我们将练习 Pintos 数据结构。

Pintos提供了内核和用户库,你可以在 pintos/src/lib/kernel 和 pintos/src/lib/user 中找到它。

在这个项目中,我们将介绍 Pintos 内核库的数据结构:List, Hash table and Bitmap.

0x01 链表(List)

Pintos 中的链表是一个双链表。

它不同于我们常见的链表结构,它是将链表元素的指针和数据分开的。

struct list_elem:

  • 每个将成为链表项的结构都必须嵌入一个 struct list_elem 成员。
  • 所有的链表函数都在 list_elem 上操作,而不是在链表项上。
  • 源代码中只给出了 list_elem 结构。
  • 你必须实现由 list_elem 和数据组成的新结构。

* 源代码中没有给出 'struct list_item' ,你需要自己实现!

📚 链表函数分析:

void list_init(struct list *list)
  • 将 LIST 初始化为一个空链表。
  • 应该在 LIST 中插入一个元素之前被执行。
struct list_elem* list_begin(struct list *list)
  • 返回链表的首元素
  • 通常用于链表的遍历(遍历的起始位置)
struct list_elem* list_next(struct list_elem *elem)
  • 返回 ELEM 的下一个元素。
  • 通常用于遍历链表或在链表中搜索 ELEM。
struct list_elem* list_end(struct list *list)
  • 返回 LIST 中的最后一个 ELEM。
  • 通常用于链表的遍历(遍历的终点位置)
#define list_entry(list_elem, struct, member)
  • 将 list_elem 的指针转换成 list_elem 所嵌入的 struct 的指针。
  • 通常用于获取嵌入list_elem 的 struct 的地址。

/* Assume that there already exists a list, sample_list */
struct list_elem *e;
e = list_begin (&sample_list);
struct list_item *temp = list_entry(e, struct list_item, elem)
int temp_data = temp->data
By using list_elem, we can get address of list_item

0x02 哈希表(Hash Table)

哈希表是一种将键与值关联的数据结构,主要操作是查找,给定一个键,找到相应的值。

它是通过使用 hash function 将 key 转换为散列工作的。

📚 哈希表函数分析:

void hash_init (
    struct hash *h, 
    hash_hash_func *hash, 
    hash_less_func *less, 
    void *aux
    )
  • 初始化哈希表H,设置哈希函数 HASH 和比较函数 LESS。
  • 你可以看到哈希函数的例子,如 hash_int,hash_bytes 和 hash_string(你必须使用 hash_int 函数才能通过测试)
  • 比较函数LESS是用来比较两个哈希元素的。
void hash_apply (
    struct hash *h, 
    hash_action_func *action
    )
  • 你可以将你制作的任何 ACTION 函数应用于哈希表 H。
  • 用于将特定的函数应用于哈希表的所有元素,例如:平方函数。
  • 你可以从 tester 目录下的 "hash_apply.in" 和 "hash_apply.out " 中了解它的用法。
#define hash_entry(hash_elem, struct, member)
  • 将 hash_elem 的指针转换成 hash_elem 所嵌入的 struct 的指针。
  • 通常用于获取嵌入 hash_elem 的 struct 的地址。
struct hash_elem {
    struct list_elem list_elem;
};

0x03 位图(Bitmap)

bit array(位数组),在某些情况下或称为位图(bitmap)。

位图是一个存储单个位(布尔值)的阵列,位图(bitmap)可以减少内存空间的浪费。

📚 位图函数分析:

struct bitmap *bitmap_create(size_t bit_cnt)

初始化一个 BIT_CNT 位的位图,并将其所有位设置为 False。

void bitmap_set (struct bitmap *b, size_t idx, bool value)

原子化式地将 b 中编号为 idx 的位设置为 value。

size_t bitmap_count (
    const struct bitmap *b, 
    size_t start, 
    size_t cnt, 
    bool value
    )

返回 start 和 start + cnt 之间的 b 中设置为 value 的位数。

Ⅲ.  Pintos 环境配置

0x00 介绍 (Pintos & Emulator)

📚 Pintos 是基于 80x86 架构的简易 OS 框架,它利用系统模拟器模拟 80x86 CPU 及其外设。

📃 项目类别:

  • 用户程序(User Programs)
  • 内核线程(Kernel Threads)
  • 虚拟内存(Virtual Memory)
  • 文件系统(File Systems)

💡 项目特点:

  • 支持用户(user)和内核线程(kernel thread)
  • 允许运行用户程序,使用基本的 UNIX 命令,譬如 echo, ls, cat, pwd…
  • 支持简单的文件系统
  • 它是用纯C实现的
  • 能很好地记录项目 & 拥有评分系统

我们将利用 QEMU 作为 Pintos 的仿真器!

KVM 和 Qemu 都是 Linux 操作系统的虚拟化解决方案。之所以把 KVM 和 Qemu 捆绑安装在一起,是因为 KVM 和 Qemu 存在着互补的关系。

👻 虚拟化(Virtualization):通过管理程序提供内核转换和资源分配等功能,以运行一个可以使用虚拟机中硬件的操作系统。

🐴 仿真(Emulation):在软件中实现硬件,从而提供一个特定的执行环境。

 

0x01  安装 Pintos

Step1:下载 Pintos 文件

🔗 资源链接:点击 snapshot 下载

或直接获取最新的 Pintos,git clone git://pintos-os.org/pintos-anon

Step2:安装 QUMU

sudo apt-get install qemu

Step3:把压缩文件 ftp 传输到云服务器上,并解压文件。

$ tar -xvf pintos_modified.tar.gz

Step4:运行前准备

运行 Pintos 前,我们需要进入 home 目录设置 .bashrc 文件:

这里我们可以用记事本打开它:

nano ~/.bashrc

在文件末尾处添加下列信息:

export PATH=/sogang/under/<你的学号>/pintos/src/utils:$PATH

当然这里也可以使用 vim 打开, i 进入插入模式,编辑完后   :wq   退出即可。

0x02 运行 Pintos

Step1:构建Pintos(默认已经解压完毕了)

$ cd ~/pintos/src/threads    # 跳转至pintos的threads目录
$ make                       # Makefile

这么做是为了在当前目录(src/threads)下创建 "build" 目录。

① cd 至 thread 目录:

② Makefile:

…… 此处省略一万字

完毕。

Step2:运行 Pintos

Pintos 提供了 "Pintos"  utility ,用于帮助 QEMU 运行 Pintos。

"Pintos" utility 位于 src/utils

转到 src/threads 目录下并运行以下命令(应该在 threads 目录下运行而不是在 utils 目录 )

可能当前你已经在这个目录了, pwd 看一下在不在,不在就 cd

$ cd ~/pintos/src/threads

src/threads 路径下输入:

$ ../utils/pintos -v -- -q run alarm-multiple

(注意,要在 -v(关闭VGA)、-- 和 -q(执行后退出)之间输入一个空格)

📌 注意:如果遇到如下错误,请自行 pwd 检查运行 pintos 的当前目录。

如果当前目录是 src/utils ,Pintos 就无法找到其内核,从而导致错误。

如果在 src/threads 中执行 Pintos,Pintos 将在 src/threads/build/kernel.bin 中成功找到内核。

0x03 项目测试

每个项目都有自己专属的测试程序,测试程序在 src/tests 中。

你可以使用这些测试程序去测试自己实现的项目。

例如在 Project3 中,您可以通过在 src/threads 目录下输入 make check 进行测试。

~/pintos/src/threads $ make check

每个测试用例都能一目了然地显示 PASS 或 FAIL。

📌 [ 笔者 ]   王亦优
📃 [ 更新 ]   2022.9.17
❌ [ 勘误 ]   /* 暂无 */
📜 [ 声明 ]   由于作者水平有限,本文有错误和不准确之处在所难免,
              本人也很想知道这些错误,恳望读者批评指正!

📜 参考资料 

Remzi H. Arpaci-Dusseau and Andrea C. Arpaci-Dusseau, Operating Systems: Three Easy Pieces

A. Silberschatz, P. Galvin, and G. Gagne,

Operating System Concepts, 9th Edition, John Wiley & Sons, Inc., 2014, ISBN 978-1-118-09375-7.

Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .

百度百科[EB/OL]. []. https://baike.baidu.com/.

相关文章
|
1月前
|
存储 调度
探索操作系统的心脏:内核与用户空间的交互
在数字世界的每一次呼吸中,操作系统扮演着至关重要的角色。本文将深入探讨操作系统的核心组件——内核与用户空间之间的神秘舞蹈。通过直观的比喻和生动的代码片段,我们将一窥这场幕后的交响曲,了解它们是如何协同工作以支持我们的计算需求的。从简单的文件读写到复杂的网络通信,每一个操作背后都隐藏着内核与用户空间之间精妙的互动。准备好跟随我们的脚步,一起揭开操作系统的神秘面纱。
32 3
|
25天前
|
安全 Linux 开发者
探索操作系统的心脏:内核与用户空间的交互
在数字世界的每一次点击和命令背后,隐藏着一个复杂而精妙的操作系统世界。本文将带你走进这个世界的核心,揭示内核与用户空间的神秘交互。通过深入浅出的解释和直观的代码示例,我们将一起理解操作系统如何协调硬件资源,管理进程和内存,以及提供文件系统服务。无论你是编程新手还是资深开发者,这篇文章都将为你打开一扇通往操作系统深层原理的大门。让我们一起开始这段旅程,探索那些支撑我们日常数字生活的技术基石吧!
37 6
|
24天前
|
存储 缓存 网络协议
Linux操作系统的内核优化与性能调优####
本文深入探讨了Linux操作系统内核的优化策略与性能调优方法,旨在为系统管理员和高级用户提供一套实用的指南。通过分析内核参数调整、文件系统选择、内存管理及网络配置等关键方面,本文揭示了如何有效提升Linux系统的稳定性和运行效率。不同于常规摘要仅概述内容的做法,本摘要直接指出文章的核心价值——提供具体可行的优化措施,助力读者实现系统性能的飞跃。 ####
|
25天前
|
缓存 监控 网络协议
Linux操作系统的内核优化与实践####
本文旨在探讨Linux操作系统内核的优化策略与实际应用案例,深入分析内核参数调优、编译选项配置及实时性能监控的方法。通过具体实例讲解如何根据不同应用场景调整内核设置,以提升系统性能和稳定性,为系统管理员和技术爱好者提供实用的优化指南。 ####
|
30天前
|
存储 Linux 开发者
探索操作系统的内核——从理论到实践
操作系统是计算机科学的核心,它像一位默默无闻的指挥官,协调着硬件和软件之间的复杂关系。本文将深入操作系统的心脏——内核,通过直观的解释和丰富的代码示例,揭示其神秘面纱。我们将一起学习进程管理、内存分配、文件系统等关键概念,并通过实际代码,体验内核编程的魅力。无论你是初学者还是有经验的开发者,这篇文章都将带给你新的视角和知识。
|
28天前
|
机器学习/深度学习 人工智能 物联网
操作系统的心脏——深入理解内核机制
在本文中,我们揭开操作系统内核的神秘面纱,探索其作为计算机系统核心的重要性。通过详细分析内核的基本功能、类型以及它如何管理硬件资源和软件进程,我们将了解内核是如何成为现代计算不可或缺的基础。此外,我们还会探讨内核设计的挑战和未来趋势,为读者提供一个全面的内核知识框架。
|
29天前
|
消息中间件 安全 Linux
深入探索Linux操作系统的内核机制
本文旨在为读者提供一个关于Linux操作系统内核机制的全面解析。通过探讨Linux内核的设计哲学、核心组件、以及其如何高效地管理硬件资源和系统操作,本文揭示了Linux之所以成为众多开发者和组织首选操作系统的原因。不同于常规摘要,此处我们不涉及具体代码或技术细节,而是从宏观的角度审视Linux内核的架构和功能,为对Linux感兴趣的读者提供一个高层次的理解框架。
|
1月前
|
存储 调度 开发者
探索操作系统的心脏:内核与用户空间的交互之旅
在数字世界的无限广阔中,操作系统扮演着枢纽的角色,连接硬件与软件,支撑起整个计算生态。本篇文章将带领读者深入操作系统的核心——内核,揭示其与用户空间的神秘交互。我们将透过生动的例子和易于理解的比喻,深入浅出地探讨这一复杂主题,旨在为非专业读者揭开操作系统的神秘面纱,同时为有一定基础的读者提供更深层次的认识。从进程管理到内存分配,从文件系统到设备驱动,每一个环节都是精确而优雅的舞蹈,它们共同编织出稳定而高效的计算体验。让我们开始这场奇妙之旅,一探操作系统背后的科学与艺术。
30 5
|
30天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
62 1
|
1月前
|
缓存 并行计算 Linux
深入解析Linux操作系统的内核优化策略
本文旨在探讨Linux操作系统内核的优化策略,包括内核参数调整、内存管理、CPU调度以及文件系统性能提升等方面。通过对这些关键领域的分析,我们可以理解如何有效地提高Linux系统的性能和稳定性,从而为用户提供更加流畅和高效的计算体验。
32 2