Fuchsia 中文文檔:Zircon 內核概念

本文爲 Fuchsia 中文文檔其中之一,歡迎關注 Fuchsia 中文文檔計劃,另外由於微信排版效果限制,以及勘誤無法修改,建議以 GitHub 和網站登載文檔爲準:

介紹

內核管理許多不同類型的對象。他們可以通過系統的調度器調用直接訪問。這些是在 kernel/object 中實現的。許多是自獨立的高級對象。有些包裝了較低層的 lk 。

系統調用

用戶空間通過系統調用(幾乎全部通過 Handles)與內核對象進行交互。在用戶空間中,句柄表示爲 32 位整數(類型 zx_handle_t)。當執行系統調用時,內核會檢查句柄參數是否引用了調用進程的句柄表中存在的已存在的句柄。內核進一步檢查該句柄的類型正確(當線程句柄傳遞給 syscall 的事件句柄時會導致錯誤),並且該句柄具有所請求操作的必需權限。

從訪問的角度來看,系統調用可分爲三大類:

  1. 沒有限制調用只有很少幾個,例如zx_clock_get_monotonic() and  zx_nanosleep()  可以由任何線程調用。

  2. 大多數調用都是以 Handle 作爲第一個參數的,例如zx_channel_write()zx_port_queue()

  3. 創建新對象的調用但不使用 Handle,例如 zx_event_create()zx_channel_create()。對它們的訪問(以及對它們的限制)由包含調用進程的 Job 控制。

系統調用由 libzircon.so 提供,libzircon.so 是 Zircon 內核提供給用戶空間的 “虛擬” 共享庫,詳情到 virtual Dynamic Shared Object or vDSO。它們是zx_noun_verb() 或者 zx_noun_verb_direct-object() 的 C ELF ABI 的函數

系統調用定義在 //zircon/vdso 是 FIDL 的自定義形式。這些定義首先由 fidlc 處理,然後由 kazoo 處理,kazoo 從 fidlc 獲取 IR 表示,最後輸出的形式是 VDSO,內核等。

句柄和權限

對象可能有多個句柄(在一個或多個進程中)引用它們。對於幾乎所有對象,當最後一個句柄引用的對象是關閉時,該對象要麼被銷燬,要麼處於可能無法撤消的最終狀態。通過將句柄寫入 Channel(zx_channel_write()),或使用 zx_process_start()將句柄作爲新進程中第一個線程的參數傳遞,可以將句柄從一個進程傳遞到另一個進程。

對句柄或其引用的對象可能採取的操作受與該句柄關聯的權限關聯。引用同一對象的兩個句柄可能具有不同的權限。

可以使用zx_handle_duplicate()zx_handle_replace()系統調用來獲取相關的句柄,並傳遞到同個對象的作爲引用,這時可選擇性的降低權限。如果該句柄是所引用的對象最後一個,通過zx_handle_close() 的調用使關閉並釋放它所引用的對象。zx_handle_close_many() 該方法可以關閉一組句柄。

內核對象 ID

每個對象在內核中都簡短的成爲 "kernel object id" 或者 "koid"。它是一個 64 位無符號整數,用於標識對象,並且在運行系統的生命週期內是唯一的。特別是,這意味着 koid 永遠不會重用。

有兩個特殊的 koid 值:

內核生成的 koid 僅使用 63 位(足夠多了)。通過設置最高有效位,可以爲人爲分配的 koid 留出空間。內核生成的 koid 分配的順序是不確定的,並且可能會發生變化。

人造 koids 是爲了支持如識別人造對象、虛擬線程的跟蹤,以供工具使用。每個程序如何分配人造 koids 在本文檔中沒有附加任何的規則和約定。

運行時:Jobs、進程和線程

線程代表執行線程(CPU 寄存器、堆棧等)存在所屬進程的地址空間內。進程屬於 Job,它定義了不同資源的限制。Job 又屬於上一層的父 Jobs,一直到根 Job,該內核在啓動的時候就傳遞到 userboot, 即開始執行的第一個用戶空間進程。

如果沒有 Job 句柄,它不可能由一個進程內的線程去創建另一個進程或 Job

程序加載 是由內核層上的用戶空間設施和協議所提供。

請參閱:zx_process_create(), zx_process_start()zx_thread_create()zx_thread_start()

消息傳遞:套接字 (Sockets) 和通道(Channels)

套接字和通道都是雙向和雙端的 IPC 對象。創建一個套接字或一個通道將返回兩個句柄,一個指向對象的每個端點。

套接字是面向流的,數據可以以一個或多個字節爲單位寫入或讀出。可以進行短寫(如果 Socket 的緩衝區已滿)和短讀(如果請求的數據多於緩衝區)。

通道是面向數據包的,並且最大消息大小由 ZX_CHANNEL_MAX_MSG_BYTES 給出, ZX_CHANNEL_MAX_MSG_HANDLES 是通道獲取最大的消息句柄。它們不支持短讀或寫。

將句柄寫入通道後,會將其從發送過程中刪除。從通道讀取帶有句柄的消息時,句柄將添加到接收進程中。在這兩個事件之間,句柄將繼續存在(確保它們所引用的對象繼續存在),除非關閉了已寫入它們的通道的末尾 - 在那一刻,傳遞給該端點的消息將被丟棄,並且它們包含的所有句柄都是關閉的。

參考: zx_channel_create(), zx_channel_read(), zx_channel_write(), zx_channel_call(), zx_socket_create(), zx_socket_read(), zx_socket_write().

對象和信號

對象最多可以具有 32 個信號(由 zx_signals_t 類型和 ZX_ **SIGNAL** 定義表示),這些信號代表有關其當前狀態的一條信息。例如,通道和套接字可以是 READABLE 或 WRITABLE。進程或線程可能被終止等等。

線程可能會等待當一個或多個對象激活的時候,有關更多信息,請參見信號。

等待:等待一個,等待多個和端口

線程可以使用zx_object_wait_one()等待信號在單個句柄上處於活動狀態或 zx_object_wait_many() 等待多個句柄上的信號。這兩個調用都允許超時,即使沒有信號待處理,它們也會在超時後返回。

超時可能會由於計時器鬆弛而偏離指定的期限。有關更多信息,請參見 timer slack。

如果線程要等待大量的句柄,則使用端口更爲有效,該端口是其他對象可能綁定的對象,因此當在其上聲明信號時,端口會接收包含信息的數據包關於待處理的信號。

參見:zx_port_create(), zx_port_queue(),zx_port_wait(), 和  zx_port_cancel()

事件,事件對

事件是最簡單的對象,除了其活動信號的集合外沒有其他狀態。

事件對是信號相互的事件中的一對。事件對的一個有用特性是,當事件中消失時(全部的句柄已經關閉),另外一個邊就會出現 PEER_CLOSED (同時關閉) 信號。

詳情請參閱:zx_event_create(), and zx_eventpair_create()

共享內存:虛擬內存對象(VMOs)

虛擬內存對象代表內存中物理頁的集合,或 “潛在” 頁(按需創建)。

它可以通過zx_vmar_map() 映射到進程的地址空間,通過zx_vmar_protect() 可調整映射頁面的權限。

VMOs 可以通過zx_vmo_read()zx_vmo_write() 來直接讀取和寫入。因此,對於 “創建 VMO,將數據集寫入 和 處理它到另外一個進程使用” 這樣的一次性操作,可避免應色號到內存空間的開銷。

地址空間管理

虛擬內存地址區域(VMARs)抽象出了管理進程地址空間。在進程創建時,會將根 VMAR 提供給進程創建者。該句柄會指向跨越整個地址空間的 VMAR。該地址空間可以通過 zx_vmar_map()zx_vmar_allocate() 接口劃分, zx_vmar_allocate() 常用於創建新的 VMARs (調用子區域),地址空間的部分組合在一起。

詳情參見: zx_vmar_map(), zx_vmar_allocate(), zx_vmar_protect(), zx_vmar_unmap(), 和 zx_vmar_destroy()

Futexes

Futures 是與用戶空間原子操作一起使用的內核基元,用於實現高效的同步基元。例如,互斥鎖,在競爭情況下僅需要進行 syscall。通過它僅對實現標準庫的實現者有意義。Zircon's libc 和 libc++ 提供了針對 Futexes 互斥鎖,條件變量等的 C11,C++ 和 pthread APIs。

Futex 是與用戶空間原子操作一起使用的內核原語,用於實現高效的同步原語 - 例如 Mutex,在競爭情況下僅需要進行 syscall。通常,它們僅對標準庫的實現者有意義。Zircon 的 libc 和 libc ++ 提供了針對 Futex 的互斥體,條件變量等的 C11,C ++ 和 pthread API。

詳情參見:zx_futex_wait(), zx_futex_wake(), and zx_futex_requeue().

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/5Z3PkH27MSTbfa--lhj-tw