為什么要使用操作系統(tǒng)
- 使用操作系統(tǒng)的主要原因是為了實現(xiàn) CPU 多進程分時復用以及內存隔離
- 如果沒有操作系統(tǒng),應用程序會直接與硬件進行交互,這時應用程序會直接使用 CPU,比如假設只有一個 CPU 核,一個應用程序在這個 CPU 核上運行,但是同時其他程序也需要運行,因為沒有操作系統(tǒng)來幫助切換,就需要應用程序時不時釋放 CPU 資源,但是如果這個程序的某個函數(shù)有一個死循環(huán),那它就永遠也不會釋放 CPU,甚至沒辦法做到運行第三方程序來停止或者殺死這個死循環(huán)程序,這種情況下就沒辦法實現(xiàn) CPU 多進程的分時復用
- 還有從內存的角度來看,如果應用程序直接運行在硬件上,則程序的數(shù)據(jù)代碼都直接保存到物理內存中,這樣不同程序的內存之間沒有明確邊界,就可能會造成一個程序存儲在本來屬于另外一個程序的內存空間,覆蓋另外一個程序中的內容
操作系統(tǒng)的隔離性需要隔離用戶程序和操作系統(tǒng),也需要隔離不同的進程
系統(tǒng)調用與隔離性
- 可以認為
exec
抽象了內存。當我們在執(zhí)行 exec 系統(tǒng)調用的時候,我們會傳入一個文件名,而這個文件名對應了一個應用程序的內存鏡像。內存鏡像里面包括了程序對應的指令,全局的數(shù)據(jù)。應用程序可以逐漸擴展自己的內存,但是應用程序并沒有直接訪問物理內存的權限,例如應用程序不能直接訪問物理內存的 1000-2000 這段地址。不能直接訪問的原因是,操作系統(tǒng)會提供內存隔離并控制內存,操作系統(tǒng)會在應用程序和硬件資源之間提供一個中間層。exec 是這樣一種系統(tǒng)調用,它表明了應用程序不能直接訪問物理內存。
-
files
基本上是抽象了磁盤。應用程序不會直接讀取磁盤,在 Unix 中它與存儲系統(tǒng)交互的唯一方式就是通過files
。操作系統(tǒng)會決定如何將文件與磁盤中的塊對應,確保一個磁盤塊只出現(xiàn)在一個文件中,并保證用戶 A 不能操作用戶 B 的文件。files 實現(xiàn)了不同用戶之間以及同一用戶不同進程之間的文件隔離。
硬件實現(xiàn)強隔離性
實現(xiàn)強隔離性的硬件支持包括了兩部分:
-
user/kernel mode:處理器有兩種操作模式:user mode 和 kernel mode:
- 當運行在 kernel model 時,CPU 能運行特定權限的指令(直接操作硬件的指令和設置保護的指令,如設置 page table 寄存器、關閉時鐘中斷)
- 當運行在 user mode 時,CPU 只能運行普通權限的指令
RISC-V 實際上有三種權限:user/kernel/machine mode
-
在 RISC-V 中,如果你在用戶空間(user space)嘗試執(zhí)行一條特殊權限指令,用戶程序會通過系統(tǒng)調用來切換到 kernel mode。當用戶程序執(zhí)行系統(tǒng)調用,會通過 ECALL 觸發(fā)一個軟中斷(software interrupt),軟中斷會查詢操作系統(tǒng)預先設定的中斷向量表,并執(zhí)行中斷向量表中包含的中斷處理程序。中斷處理程序在內核中,這樣就完成了 user mode 到 kernel mode 的切換,并執(zhí)行用戶程序想要執(zhí)行的特殊權限指令
-
虛擬內存:每個進程都有自己獨立的 page table,page table 將虛擬內存地址和物理內存地址做了對應
ECALL 指令
- 在 RISC-V 中,
ECALL
指令可以讓用戶程序將控制權轉移給內核,并傳入一個數(shù)字,這個數(shù)字表示了應用程序想要調用的 System Call -
ECALL
會跳轉到內核中一個特定的位置,在內核側,有一個位于syscall.c
的函數(shù)syscall
,每一個從應用程序發(fā)起的系統(tǒng)調用都會調用到這個syscall
函數(shù),syscall
函數(shù)會檢查ECALL
的參數(shù)
內核是如何奪回控制權
- 內核會通過硬件設置一個定時器,定時器到期之后會將控制權限從用戶空間轉移到內核空間,之后內核就有了控制能力并可以重新調度 CPU 到另一個進程中
宏內核 vs 微內核
宏內核
XV6 中,所有的操作系統(tǒng)服務都在 kernel mode 中,這種形式被稱為宏內核
- 從安全的角度來說,這種方式不太好,在一個宏內核中,任何一個操作系統(tǒng)的 Bug 都有可能成為漏洞,如果有許多行代碼運行在內核中,那么出現(xiàn)嚴重 Bug 的可能性也變得更大
- 宏內核的優(yōu)勢在于可以將文件系統(tǒng)、虛擬內存、進程管理這些實現(xiàn)特定功能的子模塊緊密地集成在一起,這樣可以提供很好的性能
微內核
微內核模式下,在內核中只有非常少的模塊,將內核中的其他部分作為普通的用戶程序來運行文章來源:http://www.zghlxwxcb.cn/news/detail-855123.html
- 這樣做的好處是內核中的代碼數(shù)量較小,降低了 bug 出現(xiàn)的可能
- 如果用戶程序想要使用內核的功能,但由于內核的程序作為普通的用戶程序,比如說某個系統(tǒng)想要使用文件系統(tǒng),需要完成從用戶空間到內核空間,再從內核到用戶空間來訪問文件系統(tǒng),文件系統(tǒng)也需要經(jīng)過同樣的路徑將消息返回給用戶系統(tǒng),使得在微內核從用戶到內核的跳轉是宏內核的兩倍,而反復跳轉帶來了性能的損耗,且微內核的內核程序被隔離開,難以實現(xiàn)共享,降低了系統(tǒng)的性能。
XV6 代碼結構
代碼主要由三部分組成:文章來源地址http://www.zghlxwxcb.cn/news/detail-855123.html
-
kernel
:包含了基本上所有的內核文件 -
user
:這基本上是運行在 user mode 的程序 -
mkfs
:會創(chuàng)建一個空的文件鏡像,將這個鏡像存在磁盤上,就可以直接使用一個空的文件系統(tǒng)
kernel 編譯過程
-
Makefile
讀取一個 C 文件,比如proc.c
,然后調用 gcc 編譯器,生成一個叫proc.s
的文件,這是 RISC-V 匯編語言文件,然后再走到匯編解釋器,生成proc.o
,這是匯編語言的二進制格式,Makefile
會為所有內核文件做相同的操作 - 系統(tǒng)加載器收集所有的.o 文件,將它們鏈接在一起并生成內核文件
到了這里,關于MIT6.S081 - Lecture3: OS Organization and System Calls的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!