從頭開始編寫操作系統(tǒng)(3) 第2章:基本理論 收藏
第2 章:基本理論
by Mike, 2009
本系列文章旨在向您展示并說明如何從頭開發(fā)一個(gè)操作系統(tǒng)。
介紹
歡迎來到有趣又瘋狂的操作系統(tǒng)是世界!
在前面的章節(jié)中,我們定義了操作系統(tǒng)是什么。操作系統(tǒng)是用戶和計(jì)算機(jī)系統(tǒng)之間的基本接口(界面)。它提供了系統(tǒng)的基本外觀和感覺。
我們也看到了一些對(duì)我們有幫助的工具。匯編器、編譯器、連接器、PartCopy 、 MagicISO 和Bochs 。
對(duì)于那些正在閱讀本文卻又沒有編程經(jīng)驗(yàn)的人來說(我知道有一些)抱歉,請(qǐng)返回到第1 章“讀者需要了解的知識(shí)”一節(jié)。為什么你還在看呢?來吧,繼續(xù)!
在這篇文章中,我們將會(huì)從不同的視角來看操作系統(tǒng)。我們首先要Back in Time(tm) 看看操作系統(tǒng)的歷史。你會(huì)發(fā)現(xiàn)這些操作系統(tǒng)有很多相似之處。這些相似之處后來變成了操作系統(tǒng)所具有的基本的東西,并且也將成為你的操作系統(tǒng)的一部分。
Blast from the Past (想起過去)
現(xiàn)在大多數(shù)的操作系統(tǒng)都是圖像化的。這些圖像用戶界面(graphical user interfaces (GUI) )是對(duì)操作系統(tǒng)真正在做的事情的一種抽象。
大多數(shù)的操作系統(tǒng)概念要追溯到程序還在磁帶上的時(shí)候,這些概念現(xiàn)在依然活躍。
史前——對(duì)操作系統(tǒng)的需求
追溯到20 世紀(jì)50 年代,所以的程序都在卡片上。這些卡片代表著一些指令,這些指令控制著計(jì)算機(jī)硬件的每一個(gè)開關(guān)。每一段軟件都完整控制著整個(gè)系統(tǒng)。多數(shù)情況下,每一個(gè)軟件都各不相同,即使是同一個(gè)軟件的不同版本。
問題是每一個(gè)程序都完全不同。它們必須簡(jiǎn)化,因?yàn)樗鼈儽仨殢念^重寫。沒有對(duì)軟件的通用支持,所以軟件必須直接與硬件交互。這樣也使兼容變得不可能。
在大型機(jī)中,創(chuàng)建代碼庫更為科可行。雖然這解決了部分問題,同一個(gè)軟件的不同版本完全不同,每一個(gè)軟件完全控制硬件。
如果更換了新的硬件,軟件就變得不再可用。如果軟件崩潰,就得使用控制面板上的小開關(guān)來調(diào)試。
這種在軟硬件之間設(shè)置接口的想法來源于大型機(jī)領(lǐng)域。通過一個(gè)硬件之上的抽象層,程序不再完全控制硬件,相反的,它們使用一個(gè)單獨(dú)的公用的接口來控制硬件。
這個(gè)酷斃了的接口是什么?什么,這個(gè)甜美可愛(有時(shí)是令人生厭)的東西,我們把它叫做操作系統(tǒng)!?
1950s ——是的,操作系統(tǒng)來了
根據(jù)wiki 百科,第一個(gè)真正的操作系統(tǒng)是 GM-NAA I/O 。SHARE 操作系統(tǒng)的GM-NAA I/O 的后繼者。SHARE 提供共享程序、緩沖區(qū)管理,并且是第一個(gè)可以執(zhí)行由匯編語言編寫的出現(xiàn)的操作系統(tǒng)。在20 世紀(jì)50 年代SHARE 是IBM 計(jì)算機(jī)的標(biāo)準(zhǔn)操作系統(tǒng)。
SHARE 操作系統(tǒng)(SOS) 是第一個(gè)提供緩沖區(qū)管理和共享程序的操作系統(tǒng),并可以執(zhí)行匯編語言程序。
“緩沖區(qū)管理”類似于“內(nèi)存管理”。“共享程序”類似于不同的程序使用庫文件。
從開始(不是真的 J )的時(shí)候,操作系統(tǒng)的兩個(gè)重要任務(wù)是管理內(nèi)存和管理程序。
因?yàn)槲覀儾⒉皇窃诿枋稣嬲模ㄓ?jì)算機(jī))歷史,讓我們跳到老DOS 吧。
1964 ——DOS/360 和 OS/360
DOS/360 (或簡(jiǎn)稱“DOS ”)是一個(gè)磁盤操作系統(tǒng),IBM 最初宣稱在1964 年末推出。因?yàn)橐恍﹩栴},被迫延遲到1966 年6 月IBM 推出了DOS/360 的3 個(gè)版本。
它們是:
BOS/360 - 8KB
DOS/360 - 16KB 配有磁盤
TOS/360 - 16KB 配有磁帶
要注意的是DOS/360 沒有多任務(wù),也沒有內(nèi)存保護(hù)。OS/360 大約在同一時(shí)間在IBM 開發(fā)。OS/360 使用“OS/MFT ”(Multiple Fixed Transactions) 支持多任務(wù)。使用固定基地址(Fixed Base Address )和OS/MVT (Multiple Variable Transaction) ,支持可變程序尺寸。
現(xiàn)在我們有了幾個(gè)有錢的詞——多任務(wù)(Multitasking )、內(nèi)存保護(hù)( Memory Protection )和 固定基地址(Fixed Base Address ),加上前面的我們有了程序執(zhí)行(Program execution )和內(nèi)存管理(Memory Management )
1969 ——Unix!
Unix 操作系統(tǒng)原本用C 語言編寫。C 語言和Unix 都是AT&T 創(chuàng)造的。Unix 和C 對(duì)于政府和教育部門自由分發(fā),這使得它被引入到了多種設(shè)備和操作系統(tǒng)之中。
Unix 是一個(gè)多用戶(multiuser )、多任務(wù)(Multitasking )的操作系統(tǒng) 。
Unix 包含一個(gè)內(nèi)核(Kernel )、文件系統(tǒng)(File System )和一個(gè)命令殼(Comm 和 Shell )。有大量的圖形用戶接口(Graphical User Interfaces (GUI) ) 使用命令殼(Comm 和 Shell ) 與操作系統(tǒng)交互,并提供更友好更漂亮的外觀。
1982 ——Commodore DOS
Commodore DOS (CBM DOS) 在Commodore's 8 位計(jì)算機(jī)上使用。不像前面提到的那些在啟動(dòng)時(shí)由磁盤引導(dǎo)內(nèi)存的計(jì)算機(jī),CBM DOS 在驅(qū)動(dòng)器內(nèi)部執(zhí)行——內(nèi)部有ROM 芯片,被一個(gè)MOS 6502 CPU 執(zhí)行。
1985 ——Microsoft Windows 1.0
第一個(gè)Windows 是一個(gè)DOS 應(yīng)用程序。它的“MSDOS Executive ”程序可以運(yùn)行程序“窗口(Windows )”不能覆蓋,所以每個(gè)“窗口”都顯示在一邊。它不怎么流行。
1987 ——Microsoft Windows 2.0
Windows 的第二個(gè)版本依然是一個(gè)DOS 圖形殼(Graphical Shell ),但是支持窗口覆蓋,以及更多的顏色。然而,受限于DOS ,它為被廣泛使用。
注釋:DOS 是一個(gè)16 位操作系統(tǒng),使用線性地址訪問內(nèi)存,使用LBA(Linear Block Addressing 線性塊地址) 訪問磁盤。因?yàn)閤86 平臺(tái)向后兼容,當(dāng)PC 引導(dǎo)時(shí)處在位(實(shí)模式)使用LBA ,更多內(nèi)容,后文詳述。
受限于16 位模式,DOS 不能訪問超過1 MB 的內(nèi)存?,F(xiàn)在它通過打開鍵盤控制器上的第20 號(hào)地址線被解決了,我們?cè)诤筮呍敿?xì)討論。
因?yàn)? MB 內(nèi)存的限制Windows 很慢,這也是它無法流行的另一個(gè)主要原因。
1987 ——Microsoft Windows 3.0
Windows 2.0 被完全重寫,Windows 3.0 還是一個(gè)DOS 圖形殼,但它包含一個(gè)“DOS 擴(kuò)展”以允許使用多達(dá)16 MB 的內(nèi)存,跨越了DOS 的1 MB 限制。它支持多任務(wù)(multitasking )。
正是這個(gè)Windows 使得Microsoft 做大。它支持可調(diào)整大小的窗口和窗口移動(dòng)。
操作系統(tǒng)開發(fā)與Windows 的關(guān)系
我很少見到有操作系統(tǒng)的初級(jí)開發(fā)者會(huì)想要做下一代Windows 。雖然這是可能的,但是相當(dāng)困難,并且對(duì)于只有一個(gè)人的團(tuán)隊(duì)來說這似乎是不可能的??纯辞懊娴膱D片吧,記住圖形殼在命令殼之上,都被內(nèi)核執(zhí)行。同樣,記住,Windows 必須從這里開始。命令殼是DOS ,圖形殼是“Windows ”。
基本概念
看看我們這個(gè)短暫的旅程,它給我們帶來一些重要的新條目。開始的時(shí)候,我們只給出了關(guān)于操作系統(tǒng)的簡(jiǎn)單定義。前一節(jié)中的信息使我們能夠得到更好更準(zhǔn)確的操作系統(tǒng)定義。
為了得到一個(gè)更好的定義,讓我們把前面加粗的詞列在下面:
內(nèi)存管理Memory Management
程序管理Program Management
多任務(wù)Multitasking
內(nèi)存保護(hù)Memory Protection
固定基地址Fixed Base Address
多用戶Multiuser
內(nèi)核Kernel
文件系統(tǒng)File System
命令殼Comm 和 Shell
圖像用戶界面Graphical User Interface (GUI)
圖像殼Graphical Shell
線性塊地址Linear Block Addressing (LBA)
引導(dǎo)加載器Bootloader (來自前一章)
有更多需要考慮的,不是嗎?——上面的列表也是對(duì)自己的抽象。
讓我們看得更仔細(xì)些。
內(nèi)存管理Memory Management
內(nèi)存管理是:
動(dòng)態(tài)的根據(jù)抽象的要求分配或收回內(nèi)存。
實(shí)現(xiàn)分頁(Paging )或虛擬存儲(chǔ)器(Virtual Memory )。
確保操作系統(tǒng)內(nèi)核不讀或?qū)懳粗幕蚴欠欠ǖ膬?nèi)存。
監(jiān)視并管理內(nèi)存碎片(Memory Fragmentation )。
程序管理Program Management
與內(nèi)存管理相似。程序管理的任務(wù)是:
確保程序不覆蓋另一個(gè)程序。
確保程序不損害系統(tǒng)數(shù)據(jù)。
控制程序請(qǐng)求以完成任務(wù)(比如分配和回收內(nèi)存)。
多任務(wù)Multitasking
多任務(wù)是:
在多個(gè)程序之間切換,并給出時(shí)間片以使其執(zhí)行。
提供一個(gè)任務(wù)管理器(Task Manager )允許切換任務(wù)(就像Windows 的任務(wù)管理器)。
TSS (Task State Segment 任務(wù)棧段)切換。新條目!
同時(shí)執(zhí)行多個(gè)任務(wù)。
內(nèi)存保護(hù)Memory Protection
它是:
在保護(hù)模式下訪問非法描述符(或非法段地址)。
覆蓋程序本身。
覆蓋在內(nèi)存中的其他文件的一部分或幾部分。
固定基地址Fixed Base Address
“基地址”就是程序加載到內(nèi)存中位置。在同城的應(yīng)用程序編程中,你不需要它,但在操作系統(tǒng)開發(fā)中,你需要。
“固定”基地址簡(jiǎn)而言之就是程序每次加載到內(nèi)存的基地址都是一樣的,兩個(gè)例子是BIOS 和引導(dǎo)加載器。
多用戶Multiuser
它是:
注冊(cè)及安全保護(hù)。
使多個(gè)用戶在這臺(tái)計(jì)算機(jī)上工作。
在保證數(shù)據(jù)不丟失,不損壞的前提下,切換用戶。
內(nèi)核Kernel
內(nèi)核是操作系統(tǒng)的核心。它提供基本功能、內(nèi)存管理、文件系統(tǒng)、程序執(zhí)行等等。我們很快會(huì)詳細(xì)了解內(nèi)核,別著急?。
文件系統(tǒng)File System
在操作系統(tǒng)開發(fā)中,沒有一個(gè)叫做“文件”的東西。從一開始(引導(dǎo)加載器)所有的東西都是純二進(jìn)制代碼。
文件系統(tǒng)簡(jiǎn)單來說就是對(duì)文件信息的描述。多數(shù)情況下,這表示簇、段、段地址、根目錄等。使得操作系統(tǒng)可以找到文件的確定起始并按順序加載它。
文件系統(tǒng)也描述文件名。有外部(external )文件名和內(nèi)部(internal )文件名。比如FAT12 定義文件名必須是11 個(gè)字符,不能多,也不能少,也就是說,比如文件名“KRNL.sys ”的內(nèi)部文件名是:
"KRNL SYS"
我們會(huì)使用FAT12 并且在后面詳細(xì)討論。
命令殼Comm 和 Shell
命令殼是內(nèi)核之上的一個(gè)獨(dú)立程序。命令殼通過鍵入命令來提供一個(gè)基本的輸入輸出功能。命令殼使用內(nèi)核來幫助其完成底層任務(wù)。
圖形用戶界面(GUI)
圖形用戶界面(GUI) 即是圖形殼和用戶之間的接口。
圖形殼Graphical Shell
圖形殼提供視頻程序及底層圖像功能。一般的它會(huì)被命令殼執(zhí)行(就像Windows 1.0 、2.0 和3.0 )。然而現(xiàn)在它們會(huì)自動(dòng)執(zhí)行。
線性塊地址 (LBA)
操作系統(tǒng)能控制內(nèi)存的每一個(gè)字節(jié) 。線性地址直接訪問線性內(nèi)存,比如
mov ax, [09000h] ; 在操作系統(tǒng)開發(fā)中,沒有訪問違規(guī)
這既是好事也壞事,比如:
mov bx, [07bffh] ; 或者其他比7c00h 小的地址
mov cx, 10
.loop1:
mov [bx], 0h ; 清空bx
inc bx ; 下一個(gè)地址
loop .loop1 ; 循環(huán)知道cx=0
上面的代碼看似無害,但是,如果這段代碼出現(xiàn)在引導(dǎo)加載器中,它會(huì)將自己用十個(gè)字節(jié)覆蓋。呀,這是因?yàn)橐龑?dǎo)加載器被固定的加載到地址0x7c00:0 處,而上面的代碼從 07bffh ( 07c00h 前一字節(jié))開始寫數(shù)據(jù)。
引導(dǎo)加載器Bootloader
引導(dǎo)加載器,我們從上一章就見到這個(gè)條目,從上一章我們知道,引導(dǎo)加載器被BIOS 加載,并且是操作系統(tǒng)中執(zhí)行的第一個(gè)程序。
引導(dǎo)加載器被BIOS 加載到絕對(duì)地址0x7c00:0 處, 加載后,CS:IP 被設(shè)置為引導(dǎo)加載器的入口點(diǎn),并且引導(dǎo)加載器獲得全部控制權(quán)。
一個(gè)軟盤扇區(qū)只有512 字節(jié)。記住引導(dǎo)加載器必須放到一個(gè)扇區(qū)中。這意味著什么?引導(dǎo)加載器的大小十分受限,不能超過512 字節(jié)。
大多數(shù)情況下,引導(dǎo)加載器要么加載并執(zhí)行內(nèi)核,要么加載并執(zhí)行第二段引導(dǎo)加載器(Second Stage Bootloader )。
我們會(huì)很快會(huì)深入了解引導(dǎo)步驟。
總結(jié)
我們看了看過去,并且學(xué)習(xí)了列表中的新條目。在歷史課之后,我們提取條目,并展開討論每一個(gè)是如何工作的。我們甚至還見到了一些代碼,盡管很少。
之后,我們能夠得到一個(gè)關(guān)于我們要做的事情的更簡(jiǎn)明的定義。
“一個(gè)提供給用戶和支持程序的接口環(huán)境;提供一個(gè)穩(wěn)健安全的環(huán)境;一個(gè)系統(tǒng)服務(wù)和硬件之間的接口層”
是的,這是我對(duì)“操作系統(tǒng)的”新定義,你的呢?
下一章,我們將詳細(xì)描述引導(dǎo)步驟,換言之,我們將創(chuàng)建和匯編真正的引導(dǎo)加載器。
下次見。