筆記:《現代操作系統》第一章 引論

計算機科學和許多領域一樣,主要是由技術驅動的。古羅馬人缺少汽車的原因不是因爲他們非常喜歡步行,是因爲他們不知道如何造汽車。個人計算機的存在,不是因爲數以百萬計的人有着迫切的願望—擁有一臺計算機,而是因爲現在可以很便宜地製造它們。

1、關於什麼是操作系統

(1) 操作系統是一種運行在內核態的軟件。內核態是計算機的一種運行模式,在這種模式下,操作系統具有對所有硬件的完全訪問權,可以執行機器能夠運行的任何指令。還有一種運行模式是用戶態,在用戶態下,只使用了機器指令中的一個子集。

(2) 操作系統的任務是爲用戶程序提供一個更好、更簡單、更清晰的計算機模型,並管理計算機中的所有設備(處理器、主存、磁盤等等)。

(3) 操作系統運行在裸機之上,爲所有其他軟件提供基礎的運行環境。

(4) 操作系統的兩大作用:

作爲資源管理者,操作系統的任務是有效地管理系統的各個部分,在相互競爭的程序之間有序地控制對處理器、存儲器以及其他I/O接口設備的分配; 或是記錄哪個程序使用什麼資源、對資源請求進行分配,評估使用代價,並且爲不同的程序和用戶調解互相沖突的資源請求。

作爲擴展機器,操作系統的任務是爲用戶提供比實際機器更便於運用的抽象,這些抽象包括進程、地址空間以及文件等,也即隱藏硬件,呈現給程序(以及程序員)良好、清晰、優雅、一致的抽象。

2、關於第一臺計算機和第一位程序員

第一臺真正的數字計算機是英國數學家Charles Babbage(1792-1871)設計的。它是一臺純機械的數字計算機,Babbage認識到他的機器需要軟件,所以他僱傭了一個名爲Ada(艾達)的年輕婦女,她是世界上第一個程序員。程序設計語言Ada是以她命名的。

3、計算機硬件簡介

(1) 處理器(CPU)

處理器從內存中取出指令並執行。在每個CPU基本週期中,首先從內存中取出指令,解碼以確定其類型和操作數,接着執行,然後取指令、解碼並執行下一條指令。按照這一方式循環,直到程序被執行完成。

每個CPU都有一套可執行的專門指令集。由於用來訪問內存以得到指令或數據的時間比執行指令花費的時間長的多,因此,所有CPU內都有一些用來保存關鍵變量和臨時數據的寄存器。

幾種寄存器的介紹:

程序計數器:它保存了將要取出的下一條指令的內存地址。在指令取出後,程序計數器就被更新以便指向後繼的指令。

堆棧指針:它指向內存中當前棧的頂端。該棧包含了每個執行過程的棧幀,棧幀中保存了輸入參數、局部變量、臨時變量等信息。

程序狀態字(Program Status World, PSW):包含了CPU優先級、模式(用戶態或內核態),以及各種控制位等。在系統調用和I/O操作中,PSW的作用很重要。

爲了從操作系統獲得服務,用戶程序必須使用系統調用以陷入內核並調用操作系統。TRAP指令把用戶態切換成內核態,並啓用操作系統。當工作完成後,在系統調用後面的指令把控制權返回給用戶程序。

多線程允許CPU保持兩個不同的線程狀態,然後在納秒級的時間尺度內來回切換。多線程不提供真正的並行處理,在一個時刻只有一個進程運行,但是線程的切換時間則減少到納秒數量級。多線程對操作系統而言是有意義的,因爲每個線程在操作系統看來就像是單個的CPU。

GPU(Graphics Processing Unit): 指的是由成千上萬個微核組成的處理器,擅長處理大量並行的簡單計算,比如圖像渲染等。但是不適合串行任務。

(2)存儲器

理想情況下:存儲器應該極爲迅速(快於執行一條指令,這樣CPU不會受到存儲器的限制),充分大,並且非常便宜。

典型的存儲器層次結構爲:

 寄存器
 高速緩存
 主存
 磁盤

按照序號排列,訪問速度從快到慢,容量從小到大,價格從低到高。

寄存器:存儲器系統的頂層,與CPU的材料相同,所以和CPU一樣快。

高速緩存:多數由硬件控制。主存被分割爲高速緩存行(cache line),其典型大小爲64字節,地址0至63對應高速緩存行0,地址64至127對應高速緩存行1,以此類推。最常用的高速緩存行放置在CPU內部或者非常接近CPU的高速緩存中。

高速緩存命中:當某個程序需要讀取一個存儲字時,高速緩存硬件檢查所需要的的高速緩存行是否在高速緩存中。如果是,稱爲高速緩存命中,緩存滿足了請求,就不需要通過總線把訪問請求送往主存。

高速緩存命中通常需要兩個時鐘週期。高速緩存未命中就必須訪問內存,這樣會付出大量的時間代價。

現代CPU中設計兩個緩存:

第一級或稱爲L1緩存:常駐CPU中,通常用來將已解碼的指令調入CPU的執行引擎。對於頻繁使用的數據字,多數芯片安排有第二個L1緩存,典型的L1緩存大小爲16KB。

L2緩存:用來存放近來使用過的若干兆字節的內存字。

L1緩存和L2緩存之間的差別在於時序,對於L1緩存的訪問,不存在任何時延;而對L2緩存的訪問,則會時延1或2個時鐘週期。

主存:又稱爲隨機訪問存儲器(Random Access Memory, RAM) ,易失性隨機訪問存儲器,斷電後存儲內容不保存。

只讀存儲器(Read Only Memory, ROM): 非易失性隨機訪問存儲器,不會丟失其內容。在計算機中,用於啓動計算機的引導加載模塊就存放在ROM中。

閃存(Flash Memory): 非易失性,可擦除和重寫。

(3)磁盤

磁盤驅動器的組成:讀/寫頭(每個盤面1個)、磁盤臂、盤面

磁盤唯一的問題是隨機訪問數據時間大約慢了三個數量級。其低速的原因是因爲磁盤是一種機械裝置。

固態硬盤: 不是磁盤,並沒有可移動的部分,數據是存儲在閃存中的,與磁盤唯一的相似之處就是它也存儲量大量即使在電源關閉時也不會丟失的數據。

虛擬內存:通過在RAM和磁盤中反覆移動信息塊的方式,提供了運行比機器物理內存大的程序的能力。即將程序放在磁盤上,而將主存作爲一種緩存,用來保存最頻繁使用的部分程序。這種機制需要快速地映像內存地址,以便把程序生成的地址轉換爲有關字節在RAM中的物理地址,這種映像由CPU中的一個稱爲存儲器管理單元(Memory Management Unit, MMU)的部件來完成。

上下文切換:在多道程序系統中,從一個程序切換到另一個程序,稱爲上下文切換。此時會對於來自緩存的所有修改的塊進行寫回磁盤操作,並修改存儲器管理單元中的映像寄存器。這種操作帶來的時間消耗是比較大的。

(4)I/O設備

I/O設備一般包括兩個部分:設備控制器和設備本身。

設備控制器是插在電路板上的一塊芯片或一組芯片,這塊電路板物理地控制設備。控制器的任務是爲操作系統提供一個簡單的接口(其實仍然是比較複雜的),它從操作系統接收命令。

爲了完成一些工作,在控制器中經常安裝一個小的嵌入式計算機,該嵌入式計算機運行爲執行這些工作而專門編好的程序。

每類設備控制器都是不同的,所以,需要不同的軟件進行控制。專門與控制器對話,發出命令並接受響應的軟件,稱爲設備驅動程序(device driver)。每個控制器廠家必須爲所支持的操作系統提供相應的設備驅動程序。

熱插拔設備,諸如USB等,需要動態可裝載設備驅動程序,即操作系統能夠在運行時接收新的設備驅動程序並且立即將其安裝好,無須重啓系統。

實現輸入/輸出的三種方式

第一種:用戶程序發出一個系統調用,內核將其翻譯成一個對應設備驅動程序的過程調用。然後設備驅動程序啓動I/O並在一個連續不斷的循環中檢查該設備,看該設備是否完成工作。若設備可用,則設備驅動程序把數據送到指定的位置,並返回。然後操作系統將控制返回給調用者。因爲需要不斷檢查設備是否可用,會一直佔據CPU,輪詢設備直到對應的I/O操作完成。這種方式稱爲忙等待(busy waiting)

第二種:設備驅動程序啓動設備並且讓該設備在操作完成時發出一箇中斷。設備驅動程序在這個時刻返回。操作系統接着在需要時阻塞調用者並安排其他工作進行。當設備驅動程序檢測到該設備的操作完畢時,它發出一箇中斷通知操作完成。

中斷處理過程:一旦CPU決定處理中斷,通常程序計數器和PSW(程序狀態字)就被入壓入到當前堆棧中,並且CPU被切換到內核態。中斷控制器把設備的編號放在總線上,CPU可以讀總線,並且知道那個設備完成了操作。設備編號可以成爲部分內存的一個引用,用於尋找該設備中斷處理程序的地址。這部分內存稱爲中斷向量。當中斷處理程序(中斷設備的設備驅動程序的一部分)開始後,它取走已入棧的程序計數器和PSW,並保存,然後查詢設備的狀態。在中斷處理程序全部完成之後,它返回到先前運行的用戶程序中尚未執行的頭一條指令。

中斷處理過程簡化:

 中斷 
 進入內核態 
 操作系統將I/O操作分派給處理程序(即中斷處理程序)
 I/O操作完成
 返回用戶態
 繼續執行下一條指令

第三種:爲I/O使用一種特殊的直接存儲器訪問(Direct Access Memory,DMA)芯片,它可以控制在內存和某些控制器之間的位流,而無須持續的CPU干預。CPU對DMA進行設置,說明需要傳送的字節數、有關的設備和內存地址以及操作方向,接着啓動DMA。當DMA芯片完成時,它引發一箇中斷,中斷處理過程如上所述。

如果有多個設備發出了中斷信號,中斷控制器會決定先處理哪個中斷,者通常取決於事先賦予每個設備的靜態優先級。最高優先級的設備贏得競爭並且首先獲得服務,其他設備必須等待。

4、計算機啓動過程簡述

每臺計算機上有一塊雙親板,板上有一個稱爲基本輸入輸出系統(Basic Input Output System, BIOS)的程序。在BIOS內有底層I/O軟件,包括讀鍵盤、寫屏幕等其他過程。BIOS放在一塊閃存(非易失性)中,操作系統可以更新或升級BIOS程序。

在計算機啓動後,BIOS開始運行,它首先檢查所安裝RAM數量,鍵盤和其他設備是否安裝並正常相應。接着,掃描總線並找出連在上面的設備。如果現有的設備和系統上一次啓動時的設備不同,則新的設備將被配置。

然後,BIOS讀取存儲在CMOS存儲器彙總的設備清單決定啓動設備。用戶可以在系統剛啓動時,進入BIOS配置程序,對設備清單進行修改。啓動設備上的第一個扇區被讀入內存並執行。這個扇區中包含一個對保存在啓動扇區末尾的分區表檢查的程序,以確定哪個分區是活動的。然後,從該分區讀入第二個啓動裝載模塊。來自活動分區的這個裝載模塊讀入操作系統,並啓動之。

操作系統啓動後,操作系統會詢問BIOS,以獲得配置信息,對於每種設備,系統檢查對應的設備驅動程序是否存在。如果沒有,系統要求用戶提供驅動程序,一旦有了全部的設備驅動程序,操作系統就將它們調入內核。然後初始化有關表格,創建需要的任何背景進程,並在每個終端上啓動登錄程序或GUI(圖形用戶界面)

5、操作系統概念

(1)進程

進程本質上是正在執行的一個程序。

進程的地址空間:一個存儲位置的列表。進程可以讀寫該地址空間。該地址空間中存放有可執行程序程序的數據以及程序的堆棧

與每個進程相關的還有資源集,通常包含寄存器(程序計數器和堆棧指針)、打開的文件清單、突出的報警、有關進程清單,以及運行該程序所需要的所有其他信息。進程基本上是容納運行一個程序所需要的所有信息的容器。

在許多操作系統當中,與一個進程有關的所有信息, 除了該進程自身地址空間的內容以外,均存放在操作系統的一張表中,稱爲進程表,進程表是數組(或鏈表)結構,當前存在的每個進程都要佔用其中的一項。

一個掛起的進程包括:進程的地址空間,以及對應的進程表項(其中包括寄存器以及稍後重啓動該進程所需要的許多其他信息)。

(2)文件

操作系統的一項主要功能是隱藏磁盤和其他I/O設備的細節特性,提供給程序員一個良好、清晰的獨立於設備的抽象文件模型。

爲了提供保存文件的地方,大多數操作系統支持目錄的概念。

在讀寫文件之前,首先要打開文件,檢查其訪問權限。若權限許可,系統將返回一個小整數,稱作文件描述符(file descriptor),供後續操作使用。若禁止訪問,系統則返回一個錯誤碼。

UNIX系統中,mount系統調用允許把CD-ROM上的文件系統連接到程序所希望的根文件系統上。

UNIX中的特殊文件:

塊特殊文件(block special file):由可隨機存取的塊組成的設備,如磁盤等。程序可以直接訪問設備的任意位置,而不必考慮存放該文件的文件系統結構。

字符特殊文件:用於打印機、調制解調器和其他接收或輸出字符流的設備。

提供特殊文件是爲了使得I/O設備看起來像文件一般。這樣,就像使用系統調用讀寫文件一樣,I/O設備也可通過同樣的系統調用進行讀寫。

6、系統調用

任何單CPU計算機一次只能執行一條指令。如果一個進程正在用戶態運行一個用戶程序,並且需要一個系統服務,比如從一個文件中讀取數據,那麼它就必須執行一個陷阱(TRAP)或系統調用指令,將控制轉移給操作系統。操作系統接着通過參數檢查找出所需要的調用過程。然後,它執行系統調用,並把控制返回給在系統調用後面跟隨着的指令。

在某種意義上,進行系統調用就像進行一個特殊的過程調用,但是隻有系統調用可以進入內核,而過程調用不能。

TRAP指令與過程指令的差別:首先,TRAP指令的副作用是,切換到內核態。而過程調用指令並不改變模式。其次,TRAP指令不能跳轉到任意地址上。根據機器的體系結構,或者跳轉到一個單固定地址上,或者指令中有一8位長的字段,它給定了內存中一張表格的索引,這張表格含有跳轉地址。

在UNIX中,fork是唯一可以在POSIX中創建進程的途徑。

在UNIX中,進程將其存儲空間劃分爲三段:正文段、數據段、以及堆棧段。數據向上增長而堆棧向下增長,夾在中間的是未使用的地址空間。堆棧在需要時自動地向中間增長。

7、操作系統結構

客戶端-服務器模式是一種可以應用在單機或者網絡機器上的抽象。其中服務器提供某種服務,客戶端使用這些服務。客戶端和服務器之間的通信是消息傳遞。

虛擬機:裸機硬件的精確複製品。這個複製品包含了內核態/用戶態,I/O功能、中斷以及其他真實硬件所應該具有的全部內容。由於每臺虛擬機都與裸機相同,所以在每臺虛擬機上都可以運行一臺裸機所能夠運行的任何類型的操作系統。

在某些CPU上,試圖在用戶態執行特權指令時,會被忽略掉。這種特性使得在這類硬件中無法實現虛擬機。

內核中的機制與策略分離原則:考慮一個進程調度的例子,對每個進程賦予一個優先級,並讓內核執行具有最高優先級的進程。這裏,機制(在內核中)就是尋找最高優先級的進程並運行之。而策略(賦予進程優先級)可以由用戶態中的進程完成。在這種方式中,機制和策略是分離的,從而使系統內核變得更小。

操作系統的運行模型:在操作系統二進制代碼鏈接完成後,計算機就可以重新啓動,新的操作系統開始運行。一旦運行,系統會動態調入那些沒有靜態包括在二進制代碼中的模塊,如設備驅動和文件系統。在運行過程中,操作系統可能由若干段組成,有文本段(程序代碼)、數據段和堆棧段。文本段通常是不可改變的,在運行過程中不可修改。數據段開始時有一定的大小,並用確定的值進行初始化,但是隨後就被修改了,其大小隨需要增長。堆棧段初始化爲空,但是隨着對函數的調用和從函數返回,堆棧段時時刻刻在增長和縮小。通常文本段放置在接近內存底部的位置,數據段在其上面,這樣可以向上增長。而堆棧段處於高位的虛擬地址,具有向下增長的能力,不過不同系統的工作方式各有差別。

在所有情形下,操作系統代碼都是直接在硬件上運行的。

整理的大多數是書中的重點知識。

謝謝閱讀。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章