操作系统简介

操作系统介绍

一个正在运行的程序会做一件非常简单的事情:执行指令。处理器从内存中获取(fetch)一条指令,对其进行解码(decode)(弄清楚这是哪条指令),然后执行(execute)它(做它应该做的事情,如两个数相加、访问内存、检查条件、跳转到函数等)。完成这条指令后,处理器继续执行下一条指令,依此类推,直到程序最终完成。

实际上,有一类软件负责让程序运行变得容易(甚至允许你同时运行多个程序),允许程序共享内存,让程序能够与设备交互,以及其他类似的有趣的工作。这些软件称为操作系统(Operating System,OS),因为它们负责确保系统既易于使用又正确高效地运行。

也就是说,操作系统将物理(physical)资源(如处理器、内存或磁盘)转换为更通用、更强大且更易于使用的虚拟形式。因此,我们有时将操作系统称为虚拟机(virtual machine)

当然,为了让用户可以告诉操作系统做什么,从而利用虚拟机的功能(如运行程序、分配内存或访问文件),操作系统还提供了一些接口(API),供你调用。实际上,典型的操作系统会提供几百个系统调用(system call),让应用程序调用。由于操作系统提供这些调用来运行程序、访问内存和设备,并进行其他相关操作,我们有时也会说操作系统为应用程序提供了一个标准库(standard library)。

最后,因为虚拟化让许多程序运行(从而共享CPU),让许多程序可以同时访问自己的指令和数据(从而共享内存),让许多程序访问设备(从而共享磁盘等),所以操作系统有时被称为资源管理器(resource manager)。每个CPU、内存和磁盘都是系统的资源(resource),因此操作系统扮演的主要角色就是管理(manage)这些资源,以做到高效或公平,

1.1 虚拟化CPU

将单个CPU(或其中一小部分)转换为看似无限数量的CPU,从而让许多程序看似同时运行,这就是所谓的虚拟化CPU(virtualizing the CPU),这是本书第一大部分的关注点。

1.2 虚拟化内存

内存就是一个字节数组。要读取(read)内存,必须指定一个地址(address),才能访问存储在那里的数据。要写入(write)或更新(update)内存,还必须指定要写入给定地址的数据。

不要忘记,程序的每个指令都在内存中,因此每次读取指令都会访问内存

1.3 并发

关键问题: 如何构建正确的并发程序如果同一个内存空间中有很多并发执行的线程,如何构建一个正确工作的程序?操作系统需要什么原语?硬件应该提供哪些机制?我们如何利用它们来解决并发问题?

1.4 持久性

在系统内存中,数据容易丢失,因为像DRAM这样的设备以易失(volatile)的方式存储数值。如果断电或系统崩溃,那么内存中的所有数据都会丢失。因此,我们需要硬件和软件来持久地(persistently)存储数据。这样的存储对于所有系统都很重要,因为用户非常关心他们的数据。

硬件以某种输入/输出(Input/Output,I/O)设备的形式出现。在现代系统中,硬盘驱动器(hard drive)是存储长期保存的信息的通用存储库,尽管固态硬盘(Solid-State Drive,SSD)正在这个领域取得领先地位。

操作系统中管理磁盘的软件通常称为文件系统(file system)。因此它负责以可靠和高效的方式,将用户创建的任何文件(file)存储在系统的磁盘上。

关键问题: 如何持久地存储数据文件系统是操作系统的一部分,负责管理持久的数据。持久性需要哪些技术才能正确地实现?需要哪些机制和策略才能高性能地实现?面对硬件和软件故障,可靠性如何实现?

1    #include <stdio.h>
2    #include <unistd.h>
3    #include <assert.h>
4    #include <fcntl.h>
5    #include <sys/types.h>
6
7    int
8    main(int argc, char *argv[])
9    {
10       int fd = open("/tmp/file", O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
11       assert(fd > -1);
12       int rc = write(fd, "hello world\n", 13);
13       assert(rc == 13);
14       close(fd);
15       return 0;
16   }

为了完成这个任务,该程序向操作系统发出3个调用。第一个是对open()的调用,它打开文件并创建它。第二个是write(),将一些数据写入文件。第三个是close(),只是简单地关闭文件,从而表明程序不会再向它写入更多的数据。这些系统调用(system call)被转到称为文件系统(file system)的操作系统部分,然后该系统处理这些请求,并向用户返回某种错误代码。

你可能想知道操作系统为了实际写入磁盘而做了什么。文件系统必须做很多工作:首先确定新数据将驻留在磁盘上的哪个位置,然后在文件系统所维护的各种结构中对其进行记录。这样做需要向底层存储设备发出I/O请求,以读取现有结构或更新(写入)它们。所有写过设备驱动程序(device driver)的人都知道,让设备代表你执行某项操作是一个复杂而详细的过程。它需要深入了解低级别设备接口及其确切的语义。幸运的是,操作系统提供了一种通过系统调用来访问设备的标准和简单的方法。因此,OS有时被视为标准库(standard library)。

1.5 设计目标

一个最基本的目标,是建立一些抽象(abstraction),让系统方便和易于使用。抽象对我们在计算机科学中做的每件事都很有帮助。抽象使得编写一个大型程序成为可能,将其划分为小而且容易理解的部分,用C这样的高级语言编写这样的程序不用考虑汇编,用汇编写代码不用考虑逻辑门,用逻辑门来构建处理器不用太多考虑晶体管

其他目标也是有道理的:在我们日益增长的绿色世界中,能源效率(energy-efficiency)非常重要;安全性(security)(实际上是保护的扩展)对于恶意应用程序至关重要,特别是在这高度联网的时代。随着操作系统在越来越小的设备上运行,移动性(mobility)变得越来越重要。根据系统的使用方式,操作系统将有不同的目标,因此可能至少以稍微不同的方式实现。

1.6 简单历史

一开始,操作系统并没有做太多事情。基本上,它只是一组常用函数库。例如,不是让系统中的每个程序员都编写低级I/O处理代码,而是让“OS”提供这样的API,这样开发人员的工作更加轻松。
通常,在这些老的大型机系统上,一次运行一个程序,由操作员来控制。这个操作员完成了你认为现代操作系统会做的许多事情(例如,决定运行作业的顺序)

超越库:保护

在超越常用服务的简单库的发展过程中,操作系统在管理机器方面扮演着更为重要的角色。其中一个重要方面是意识到代表操作系统运行的代码是特殊的。它控制了设备,因此对待它的方式应该与对待正常应用程序代码的方式不同。为什么这样?好吧,想象一下,假设允许任何应用程序从磁盘上的任何地方读取。因为任何程序都可以读取任何文件,所以隐私的概念消失了。因此,将一个文件系统(file system)(管理你的文件)实现为一个库是没有意义的。实际上,还需要别的东西。

因此,系统调用(system call)的概念诞生了,它是Atlas计算系统[K+61,L78]率先采用的。不是将操作系统例程作为一个库来提供(你只需创建一个过程调用(procedure call)来访问它们),这里的想法是添加一些特殊的硬件指令和硬件状态,让向操作系统过渡变为更正式的、受控的过程。

系统调用和过程调用之间的关键区别在于,系统调用将控制转移(跳转)到OS中,同时提高硬件特权级别(hardware privilege level)。用户应用程序以所谓的用户模式(user mode)运行,这意味着硬件限制了应用程序的功能。例如,以用户模式运行的应用程序通常不能发起对磁盘的I/O请求,不能访问任何物理内存页或在网络上发送数据包。在发起系统调用时 [通常通过一个称为陷阱(trap)的特殊硬件指令],硬件将控制转移到预先指定的陷阱处理程序(trap handler)(即预先设置的操作系统),并同时将特权级别提升到内核模式(kernel mode)。在内核模式下,操作系统可以完全访问系统的硬件,因此可以执行诸如发起I/O请求或为程序提供更多内存等功能。当操作系统完成请求的服务时,它通过特殊的陷阱返回(return-from-trap)指令将控制权交还给用户,该指令返回到用户模式,同时将控制权交还给应用程序,回到应用离开的地方。

多道程序时代

操作系统不是一次只运行一项作业,而是将大量作业加载到内存中并在它们之间快速切换,从而提高CPU利用率。这种切换非常重要,因为I/O设备很慢。在处理I/O时让程序占着CPU,浪费了CPU时间。

在I/O进行和任务中断时,要支持多道程序和重叠运行。这一愿望迫使操作系统创新,沿着多个方向进行概念发展。内存保护(memory protection)等问题变得重要。我们不希望一个程序能够访问另一个程序的内存。了解如何处理多道程序引入的并发(concurrency)问题也很关键。在中断存在的情况下,确保操作系统正常运行是一个很大的挑战

早期的操作系统,如DOS(来自微软的磁盘操作系统),并不认为内存保护很重要。因此,恶意程序(或者只是一个编程不好的应用程序)可能会在整个内存中乱写乱七八糟的东西。第一代macOS(V9及更早版本)采取合作的方式进行作业调度。因此,意外陷入无限循环的线程可能会占用整个系统,从而导致重新启动。

参考文献《操作系统导论》

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值