diff --git a/source/appendix-e/index.rst b/source/appendix-e/index.rst index aecda61d..198df235 100644 --- a/source/appendix-e/index.rst +++ b/source/appendix-e/index.rst @@ -19,7 +19,7 @@ openEuler在具有通用的Linux系统架构,包括内存管理子系统、进 **名称** **特性说明** **网页链接** StratoVirt 轻量级虚拟机引擎 https://docs.openeuler.org/zh/docs/21.03/docs/StratoVirt/StratoVirtGuide.html -iSula 轻量级容器引擎 https://docs.openeuler.org/zh/docs/21.03/docs/Container/ /iSula容器引擎.html +iSula 轻量级容器引擎 https://docs.openeuler.org/zh/docs/21.03/docs/Container/iSula容器引擎.html A-Tune AI智能调优引擎 https://docs.openeuler.org/zh/docs/21.03/docs/A-Tune/A-Tune.html secGear 跨平台机密计算框架使 https://docs.openeuler.org/zh/docs/21.03/docs/secGear/secGear.html 可信计算 安全可信计算 https://docs.openeuler.org/zh/docs/21.03/docs/Administration/可信计算.html diff --git a/source/chapter1/0intro.rst b/source/chapter1/0intro.rst index fa20e089..e691a27b 100644 --- a/source/chapter1/0intro.rst +++ b/source/chapter1/0intro.rst @@ -21,9 +21,27 @@ .. chyyuu note - 在练习一节前面,是否有一个历史故事? + 在练习一节前面,是否有一个历史故事??? 在操作系统发展历史上,在1956年就诞生了有文字历史记录的操作系统GM-NAA I/O,并且被实际投入使用,它的一个主要任务就是"自动加载运行一个接一个的程序",并能以库函数的形式给应用程序提供基本的硬件访问服务。 + + +.. chyyuu https://en.wikipedia.org/wiki/Timeline_of_operating_systems https://en.wikipedia.org/wiki/Wheeler_Jump https://en.wikipedia.org/wiki/EDSAC +.. note:: + + + **最早的操作系统雏形就是程序库** + + 程序库一般由一些子程序(函数)组成。通过调用程序库中的子程序,应用程序可以更加方便的实现其应用功能。但在早期的软件开发中,还缺少便捷有效的子程序调用机制。 + + 根据维基百科的操作系统时间线 [#OSTIMELINE]_ 上的记录,1949-1951年,英国J. Lyons and Co.公司(一家包括连锁餐厅和食品制造的大型集团公司)开创性地引入并使用剑桥大学的EDSAC计算机,联合设计实现了 LEO I 'Lyons Electronic Office' 软硬件系统,利用计算机的高速度来高效地组织蛋糕和其他易腐烂的商品的分配。在软件编程中,由于硬件的局限性(缺少索引寄存器、保存函数返回地址的寄存器、栈寄存器、硬件栈等),早期的程序员不得不使用在程序中修改自身代码的方式来访问数组或调用函数。这在现在看来,具有自修改能力的程序是一种黑科技。 + + 参与EDSAC项目的David Wheeler发明了子程序的概念 -- **Wheeler Jump** 。Wheeler的方法是在子程序的最后一行添加 **“jump to this address”** 指令,并在指令后跟一个内存空间,这个内存空间通常被设置为 0,在子程序被调用后,这个内存空间的值会被修改为返回地址。当调用子程序是,调用者(Caller)的地址将被放置在累加寄存器中,然后代码将跳转到子程序的入口。子程序的第一条指令将根据累加寄存器中的值计算返回地址,通常是调用者地址的下一个内存位置,然后将计算出的返回地址写入先前预留的内存空间中。当子程序继续执行,自然会到达子程序的末尾,即 **“jump to this address”** 指令处,这条指令读取位于它之后的内存单元,获得返回地址,就可以正常返回了。 + + 在有了便捷有效的子程序概念和子程序调用机制后,软件开发人员在EDSAC计算机开发了大量的子程序库,其中就包括了检查计算机系统,加载应用软件,写数据到持久性存储设备中,打印数据等硬件系统相关功能的子程序库。这也是为何维基百科的的操作系统时间线 [#OSTIMELINE]_ 一文中,把LEO I 'Lyons Electronic Office' 软件系统(其实就是硬件系统相关的子程序库)定位为最早的操作系统的起因。 + + + 实践体验 --------------------------- @@ -136,3 +154,6 @@ 操作系统代码无法像应用软件那样,可以有方便的调试(Debug)功能。这是因为应用之所以能够被调试,也是由于操作系统提供了方便的调试相关的系统调用。而我们不得不再次认识到,需要运行在没有操作系统的裸机环境中,当然没法采用依赖操作系统的传统调试方法了。所以,我们只能采用 ``print`` 这种原始且有效的调试方法。这样,第二步就是让脱离了标准库的软件有输出,这样,我们就能看到程序的运行情况了。为了简单起见,我们可以先在用户态尝试构建没有标准库的支持显示输出的最小运行时执行环境,比较特别的地方在于如何写内嵌汇编完成简单的系统调用。具体可看 :ref:`构建用户态执行环境 ` 一节的内容。 接下来就是尝试构建可在裸机上支持显示的最小运行时执行环境。相对于用户态执行环境,同学需要能够做更多的事情,比如如何关机,如何配置软件运行所在的物理内存空间,特别是栈空间,如何清除 ``bss`` 段,如何通过 ``RustSBI`` 的 ``SBI_CONSOLE_PUTCHAR`` 接口简洁地实现信息输出。这里比较特别的地方是需要了解 ``linker.ld`` 文件中对OS的代码和数据所在地址空间布局的描述,以及基于RISC-V 64的汇编代码 ``entry.asm`` 如何进行栈的设置和初始化,以及如何跳转到Rust语言编写 ``rust_main`` 主函数中,并开始内核最小运行时执行环境的运行。具体可看 :ref:`构建裸机执行环境 ` 一节的内容。 + + +.. [#OSTIMELINE] https://en.wikipedia.org/wiki/Timeline_of_operating_systems \ No newline at end of file