走進(jìn)內(nèi)核第一步(XNU內(nèi)核簡述)

目錄

  • 簡述
  • Mach
    • 任務(wù)與線程
    • 端口
    • 虛擬地址
    • 任務(wù)地址空間
  • BSD
  • I/O kit

簡述

XNU內(nèi)核是iOS的核心,與OS X版本幾乎沒有區(qū)別,是由三個(gè)主要部分組成的一個(gè)分層體系結(jié)構(gòu)。大致結(jié)構(gòu)如圖所示,畫得有點(diǎn)丑。


該內(nèi)核的內(nèi)環(huán)是Mach層,該層僅僅提供了例如調(diào)度、IPC等基礎(chǔ)服務(wù)。這些服務(wù)都是為內(nèi)核提供的。

第二個(gè)部分是BSD層,BSD層主要是為用戶層面提供一些接口,為一些操作提供支持,網(wǎng)絡(luò)、進(jìn)程管理、文件系統(tǒng)。

最后一個(gè)部分就是I/O Kit,顧名思義,為設(shè)備的驅(qū)動程序提供面向?qū)ο蟮目蚣堋?/p>

由于作者知識有限,只能把一些知道的知識點(diǎn)陳述出來,因此知識點(diǎn)看起來會有一些零散難以理解。另文章難免會出現(xiàn)一些錯漏的地方,還望指出以便于及時(shí)更改防止誤導(dǎo)他人。

Mach

Mach前面已經(jīng)說過了,為高層提供底層服務(wù)。關(guān)于Mach的官方文檔在這里(建議翻墻打開)

Mach提供了一組簡單又強(qiáng)大的抽象用于實(shí)現(xiàn)基礎(chǔ)服務(wù)。

  • 任務(wù)(Task).每一個(gè)任務(wù)都包含著一個(gè)虛擬空間、一個(gè)端口命名空間以及一個(gè)或多個(gè)線程,跟進(jìn)程類似。(下文的進(jìn)程和任務(wù)可能有些混亂,但不耽誤理解)
  • 線程(Thread).CPU執(zhí)行最小單位。
  • 地址空間(Address space).Mach使用地址空間與內(nèi)存管理器,實(shí)現(xiàn)了不連續(xù)的虛擬地址空間以及共享內(nèi)存的概念。
  • 內(nèi)存對象(Memory object).它是內(nèi)存管理的內(nèi)部單元。
  • 端口(Ports).單工通信通道,只能發(fā)送或者通過端口權(quán)限訪問。
  • IPC
  • 時(shí)鐘(Time)

下面就講一下Mach中經(jīng)常被提及的一點(diǎn)概念,IPC與消息可以移步這里

任務(wù)與線程

OS X進(jìn)程,POSIX thread(pthread)都是基于Mach中任務(wù)與線程實(shí)現(xiàn)的。任務(wù)為線程提供資源,這種靠任務(wù)劃分的方式大大提高了資源的共享性。

對于一個(gè)線程來說,它

  • 是任務(wù)的控制流點(diǎn)。
  • 可以訪問任務(wù)中所有的元素。
  • 可以與同任務(wù)中另一線程并行執(zhí)行。
  • 有自己的狀態(tài),包括處理器狀態(tài)以及自己的棧。

對于任務(wù)來說,它

  • 是一個(gè)資源的集合體,它的資源除了地址空間以外,可以通過端口獲取。如果另一個(gè)任務(wù)需要訪問該資源,它直接傳遞端口權(quán)限就好。
  • 提供一個(gè)不連續(xù)的地址空間。這個(gè)空間的部分可以通過繼承或者外部內(nèi)存管理器來共享出去。
  • 包含一個(gè)或多個(gè)線程。

端口

端口是請求服務(wù)的客戶端與提供服務(wù)的服務(wù)器之間單向通信的端點(diǎn),除了任務(wù)地址空間以外,所有其他Mach資源都可以通過端口訪問。一個(gè)端口可以接收多個(gè)發(fā)送者的消息,但每個(gè),端口只能有一個(gè)接收器。換句話說就是禁止群發(fā)。

為了保證端口安全,防止資源外泄,端口還有保護(hù)機(jī)制,稱之為端口權(quán)限。為了與端口交互,任務(wù)必須要有正確的端口權(quán)限。端口權(quán)限與任務(wù)相關(guān),因此,任務(wù)里的所有線程都共享相同的端口權(quán)限。權(quán)限還可以在任務(wù)之間復(fù)制和移動,但有一點(diǎn),如果在父進(jìn)程中fork出子進(jìn)程,那么子進(jìn)程是沒有和父進(jìn)程一樣的權(quán)限的。關(guān)于端口的權(quán)限,定義在mach/port.h中,用xcode就能看到。

typedef natural_t mach_port_right_t;

#define MACH_PORT_RIGHT_SEND        ((mach_port_right_t) 0)//允許發(fā)送消息
#define MACH_PORT_RIGHT_RECEIVE     ((mach_port_right_t) 1)//允許接收消息
#define MACH_PORT_RIGHT_SEND_ONCE   ((mach_port_right_t) 2)//允許發(fā)送消息一次
#define MACH_PORT_RIGHT_PORT_SET    ((mach_port_right_t) 3)//面向一組端口接收或發(fā)送消息
#define MACH_PORT_RIGHT_DEAD_NAME   ((mach_port_right_t) 4)//無效或銷毀的權(quán)限
#define MACH_PORT_RIGHT_LABELH          ((mach_port_right_t) 5)
#define MACH_PORT_RIGHT_NUMBER      ((mach_port_right_t) 6)

虛擬地址

要說虛擬地址,得先從虛擬內(nèi)存講起,虛擬地址指向的內(nèi)存就是虛擬內(nèi)存。由于計(jì)算機(jī)系統(tǒng)的RAM資源有限,當(dāng)系統(tǒng)分配的內(nèi)存太多時(shí),RAM很有可能不夠用,因此現(xiàn)代操作系統(tǒng)都使用一種虛擬內(nèi)存技術(shù)來解決RAM不夠的問題。

虛擬內(nèi)存,顧名思義就是虛擬的內(nèi)存,這樣進(jìn)程就可以分配和使用比系統(tǒng)RAM還要多的內(nèi)存,它把超過RAM的地址空間放入到外部存儲器(硬盤)上??墒菃栴}又來了,CPU不能直接訪問外部存儲器的地址。因此,操作系統(tǒng)必須在外部存儲器和RAM之間交換數(shù)據(jù),以便于CPU能訪問外部存儲器的數(shù)據(jù)。一般來說,進(jìn)程只需要使用分配的總內(nèi)存的一小部分,我們把這部分分為工作集。由于硬盤的讀取速度遠(yuǎn)遠(yuǎn)小于RAM的讀取速度,因此,為了忽略虛擬內(nèi)存給執(zhí)行速度帶來的影響,如果進(jìn)程需要訪問硬盤地址,操作系統(tǒng)會將硬盤存儲的數(shù)據(jù)先讀取到RAM中,如果RAM已經(jīng)滿了,沒有空間可以放入數(shù)據(jù),那么系統(tǒng)會先把RAM的一些數(shù)據(jù)放入到硬盤中,騰出空間再讀取。

談到虛擬內(nèi)存,那就不得不談起分頁。上文說到RAM會與硬盤的數(shù)據(jù)會進(jìn)行交換。分頁技術(shù)將物理內(nèi)存(RAM+硬盤)分成固定長度的塊,稱為頁幀,將虛擬內(nèi)存也劃分成固定長度的塊,稱為頁。每頁與每幀的大小相同,這樣就可以將每頁映射到每幀中。


如圖所示,虛擬內(nèi)存中的每一頁都對應(yīng)著物理內(nèi)存的每一幀。既然將進(jìn)程分配的空間"打散"了,那么進(jìn)程分配的物理空間就可以不連續(xù),進(jìn)程分配的空間只需要在虛擬空間中連續(xù)就好,虛擬空間映射成的物理空間可以七零八落分配在各個(gè)地方,這樣做就解決了物理空間碎片化的的問題,提高了物理空間的利用率。

可能到這里有人會問了,進(jìn)程怎么知道自己分配的內(nèi)存是在RAM中還是在硬盤中。在進(jìn)程啟動的時(shí)候,操作系統(tǒng)會給它創(chuàng)建一個(gè)表,用于保存進(jìn)程的虛擬空間地址以及其對應(yīng)的物理地址的映射關(guān)系,這個(gè)表被稱為分頁表。這個(gè)表中的每一項(xiàng)對應(yīng)進(jìn)程地址空間中的每一頁,換句話說它也和物理空間幀一一對應(yīng)。這個(gè)分頁表的項(xiàng)還包含著訪問控制位(判斷是否只讀)與標(biāo)志位(在RAM還是硬盤)。也就是說,有了進(jìn)程的虛擬地址,系統(tǒng)就可以根據(jù)分頁表中的映射關(guān)系找到它的物理地址,無論它在哪。

其實(shí)上面扯了那么多,iOS根本就不支持外部存儲器(硬盤),但是這種內(nèi)存分配方式(虛擬映射物理)還是有好處的,把虛擬內(nèi)存化整為零可以大大的減少物理內(nèi)存的碎片的產(chǎn)生。另一個(gè)好處就是進(jìn)程可以完全使用自己的虛擬內(nèi)存空間,不用在乎物理空間,當(dāng)然這只是理論上的完全使用,具體原因見下文。

任務(wù)地址空間

在用戶每一個(gè)進(jìn)程的虛擬內(nèi)存中,都有一段空間是專門為內(nèi)核保留的。具體原因見巨內(nèi)核優(yōu)點(diǎn)
在64-bit架構(gòu)中,內(nèi)核預(yù)留的空間跟32-bit不太一樣。64-bit理論上的地址空間可以使用0-0xffffffffffffffff(2^64)。但是由于當(dāng)時(shí)硬件并不能支持64位尋址空間,因此用戶只能使用48位的尋址空間,后來就一直延續(xù)下來了。既然在64-bit下只能使用48位尋址空間,那么必須要用一些規(guī)范來對地址進(jìn)行約束。約定地址第48-63位必須與47位相等。這就是規(guī)范形式地址,因此64位的地址空間被分為了兩個(gè)部分。0-0x00007fffffffffff,0xffff800000000000-0xffffffffffffffff。這兩個(gè)部分每一個(gè)部分都是128T,高128T字節(jié)預(yù)留給內(nèi)核,低128T字節(jié)屬于用戶自己使用的,用戶如果意圖訪問虛擬空間中的內(nèi)核地址,則會報(bào)錯。如果訪問了中間非規(guī)范形式的地址,硬件會報(bào)錯。映射關(guān)系如圖所示。

BSD

BSD層位于Mach上層,但還是處于內(nèi)核之中。它實(shí)現(xiàn)了很多操作系統(tǒng)的核心功能,這些功能的實(shí)現(xiàn)都建立在Mach提供的服務(wù)之上。BSD層提供了如下服務(wù):

  • 進(jìn)程和用戶管理
  • 文件管理
  • 安全
  • 內(nèi)存管理
  • 驅(qū)動程序
  • 網(wǎng)絡(luò)連接
  • 系統(tǒng)調(diào)用

I/O Kit

I/O Kit是一個(gè)面向?qū)ο蟮目蚣?,用于編寫設(shè)備驅(qū)動程序及其他內(nèi)核擴(kuò)展。I/O Kit對系統(tǒng)硬件進(jìn)行了抽象,提前定義了許多類型的硬件基類,可以讓新的驅(qū)動程序去繼承這些基類,從而實(shí)現(xiàn)代碼的高度重用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • linux資料總章2.1 1.0寫的不好抱歉 但是2.0已經(jīng)改了很多 但是錯誤還是無法避免 以后資料會慢慢更新 大...
    數(shù)據(jù)革命閱讀 13,345評論 2 33
  • Mach 虛擬內(nèi)存 在內(nèi)核管理最重要的資源中,出了CPU本身,就是內(nèi)存了。Mach 和所有內(nèi)核一樣,代碼中有很大一...
    CoderKo1o閱讀 5,547評論 0 4
  • 如果你看完書中的所有例子,你很可能已經(jīng)做完你的實(shí)驗(yàn)和在已經(jīng)越獄的iPhone上的研究。因?yàn)楹驮S多人一樣,幾乎所有的...
    fishmai0閱讀 17,438評論 2 42
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,874評論 11 349
  • 一路開車一路落淚,怎么也快樂不起來。 心情若可以美麗,世界變化如此美好!若總是牽掛,若虛度如愚,心靈空蕩蕩~ 美麗...
    wangLily閱讀 317評論 0 0

友情鏈接更多精彩內(nèi)容