不,这不是必需的 – 代码将在没有操作系统的计算机上运行良好。这应该不会太令人惊讶,因为操作系统也是一个计算机程序。
几年前,我做了一个非常小的计算机程序(大约70字节),可以启动PC并运行一个非常简单的控制台:它允许您输入二进制文件并将其作为机器代码执行。仅在此基础上,我就构建了一个简单的文件系统,十六进制编辑器,反汇编器,调试器和汇编器,方法是直接在机器代码中编码所有这些。好吧,我手工编写汇编,将其转换为机器代码,然后使用这个简单的控制台键入它。随着时间的流逝,这变得越来越不简单,因为我很快就对二进制失去了耐心,:)。
因此,简而言之,可以在没有操作系统的情况下对计算机进行编程。虽然它变得有点乏味,但你必须真正知道你在做什么,因为没有GUI或精心设计的系统库来帮助你。
十六进制转储我作为本项目的一部分编写的汇编程序代码的一部分。红色圆圈内是被翻译成机器码的指令,右下角是8086汇编语言的一些关键字。十六进制编辑器也是我自己作为项目的一部分编写的。
“操作系统”往往意味着许多事情。简而言之,操作系统是以下各项的组合:
- 监控 – 将代码引导到硬件上,并提供控制系统的能力;有时这只是一个辅助引导,有时它有一个交互式控制台;它通常不提供在保持活动状态的同时运行其他任务的机制,尽管它可能会安装执行(见下文)并将控制权转移给它 – 有时您无法区分任何一个监视器,您可以将其视为可选。
- 执行 – 有时称为内核,提供一个抽象层,将应用程序软件与硬件细节(如中断/异常处理)隔离开来,通过提供上下文切换和一些低级资源控制来运行一个或多个任务或线程。处理任务和/或线程同步(互斥、信号量、关键部分),在大多数非嵌入式系统上,负责设置和拆卸任务和/或线程,并维护一组线程或任务与分配给它们的资源之间的关联。提供用户任务/线程可以将控制权移交给执行官以使其执行某些操作的接口(例如,启动新线程/任务,停止线程/任务,设置计时器,更改优先级,调用计划程序等)。这通常被称为“内核”,尽管内核也可能包括监视器和某些服务子集(见下文)
- 服务 – 如文件系统,网络等。有时这些作为执行程序的一部分运行,有时执行器在用户空间中调用它们以处理用户应用程序发出的请求。在许多系统上,将应用程序从辅助存储读取到RAM并在新任务中启动它是一种服务;该服务加载代码并重新定位它,然后进行执行调用以分配其他资源。
我对程序进行排名圭多·范登赫维尔被描述为,最多,一个监视器;它没有为通过陷阱或其他上下文切换机制输入的代码提供任何东西(例如,控制台I / O,文件服务,资源分配)。它最能描述一个独立的(“裸机”)程序。
我经常编写在裸机上运行的代码,最新的是 ARM Cortex-M 和 Xilinx 微喷子微控制器,但我也为 PowerPC、ARM Cortex-A 和一些 8 位微处理器(8051、8041、6509 等)编写过代码。某些应用(例如对复杂电路卡的上电和关断进行排序,以及为子系统执行电源和热管理)不会从多线程中受益,并且它们永远不需要加载和执行其他程序。带有中断的简单超级循环通常就足够了。
可以在没有正式操作系统甚至执行人员的情况下运行多个线程或任务;线程上下文切换器和基本调度程序并不难编写,但是当您添加特权与非特权处理器模式处理,同步基元和基于优先级的抢占式调度时,使用小型执行器通常是最好的方法,而不是滚动自己的方法。
在我从事该行业的40多年里,我设计和编写了至少4位不同的嵌入式实时高管,并帮助实施了其他一些高管。您通常需要有一个 tick 处理程序、基于优先级的抢占式调度程序、任务/线程创建、上下文切换、异常处理以及一个用户空间到内核空间陷阱机制,该机制允许应用程序线程从执行程序请求某些内容。有时,ISA 中为该 CPU 内核提供了特定的 CPU 异常和指令,其他时候,控制权的传输是对无法从用户空间读取或执行的内存的调用,并且至少在一种情况下,我使用了“非法指令”异常。
虽然我喜欢我自己创建的高管,但我不把它们用于工作项目,因为我是唯一一个可以支持它们的人,而且因为没有IDE为我的数据结构提供操作系统感知调试。我愿意忍受额外的开销,因为我的应用程序拥有我不想要或不需要的东西来获得可维护性优势。
—
__PS:原始帖子让我想起了我的大学时代,当时我会通过PDP-11 / 40上的前面板开关切换引导代码,后来当我使用F11 micro-ODT控制台输入引导代码的八进制值以从TU-58(DECTape II)驱动器加载操作系统时,因为我的Q总线系统上没有引导ROM板。我还通过IMSAI-8080的前面板开关进入了更复杂的程序,这是我们在1970年代后期就读的大学里拥有的。