设计实现 helloworld unikernel

通常,我们在学习一门新的编程语言时,接触的第一个示例程序就是 helloworld,当一名新的程序员清除完一切障碍顺利抵达 helloworld 时,他的内心体验到的不仅仅是一种成功的喜悦,更重要的是,他正在亲身经历一个跨越历史的时刻。各位,你还记得你第一次写的 helloworld 吗?

这一章,我们将沿袭前人之路,以 helloworld 来开启沟通 ArceOS 世界的历程。我们将通过从零开始设计实现一个 helloworld unikernel,来直接感受 ArceOS 的理念、特性。

1 回顾 ArceOS

ArceOS 是一个实验性的,基于 unikernel 的组件化操作系统,具有以下特性:

  1. 组件化:以组件粒度组装适应各种应用需求的操作系统。
  2. 以应用为中心(unikernel):面向应用,依照依赖链,选出最小的必要组件集合,构造操作系统。
  3. 组件区分系统相关和系统无关:识别具有通用功能的组件,可以为其它操作系统所复用。
  4. 利用 Rust 机制:以 crate 对应组件,trait 对应接口,dependencies+features 的方式对组件进行组织。

2 helloworld unikernel 功能需求分析

首先,我们一起来看一下即将实现的 helloworld unikernel 到底是什么?与我们往常学习编程语言的 helloworld 示例程序有什么区别?

#include <stdio.h>

int main()
{
	printf("hello world!");
    return 0;
}

以这个 C 语言编写的 helloworld 程序为例,可以发现,无论是这个 helloworld 示例程序,还是现在的 helloworld unikernel,核心功能都是向屏幕打印 ”hello world“ 字符串。

不同的是,在绝大多数情况下(不考虑嵌入式系统),如果我们尝试把c语言程序编译好的二进制程序直接放在一个裸机环境上是不能够运行的,因为缺少它依赖的各种服务和资源,缺乏和硬件交互的能力。也就是说,如果要在一台裸机上部署这个应用,至少需要安装一个操作系统,然后才能令这个 helloworld 成功运行。

而对于 helloworld unikernel 来讲,它是一个 helloworld 应用+最小支撑运行环境的集合,在一台裸机上进行烧录,就可以执行 helloworld 程序。

总结一下,helloworld unikernel 是一个能够运行 helloworld 程序的 unikernel image。再进一步,结合 unikernel 的定义来讲,helloworld unikernel 是通过打包必要的 ArceOS 组件,专门用来支撑 helloworld 程序运行的单地址空间机器镜像。具备如下功能:

  1. 首先,作为 unikernel,或称为 libOS,能够引导本系统运行(在裸机上搭建 helloworld 应用所需的必要运行环境);
  2. 其次,具备 helloworld 的基本功能,能够输出如下信息到屏幕:

Hello, world!I am arceOS!

接下来,我们将结合 ArceOS 的特性,从简单到复杂,将 helloworld unikernel 功能逐步分解,从单个组件到三个组件,然后引入分层和 feature 的概念,最终向用户呈现一个简洁、规范的实现过程。