Zircon 核心概念

簡介

核心會管理多種不同類型的物件。這些是 可透過系統呼叫直接存取,是 C++ 類別來實作 調度器介面。系統會在 kernel/object。許多都是獨立的較高層級的物件。 部分低階環繞 lk 以及一些基本問題

系統呼叫

使用者空間程式碼透過系統呼叫與核心物件互動,而且幾乎可以 只能透過帳號代碼使用。在使用者空間中,帳號代碼會顯示為 32 位元整數 (類型 zx_handle_t)。執行 Syscall 時,核心會檢查 ,該處理參數參照了呼叫中存在的實際控制代碼 處理程序的控點資料表。核心會進一步檢查帳號代碼是否 類型正確 (將 Thread 控件傳遞給需要事件控制代碼的 sys 呼叫 將會導致錯誤),而帳號代碼擁有 所要求作業。

從存取的角度來看,系統呼叫大致分為三個類別:

  1. 沒有限制的呼叫,只有極少數、 範例 zx_clock_get_monotonic() 且任何執行緒都可能呼叫 zx_nanosleep()
  2. 使用控點做為第一個參數的呼叫,代表執行該動作的物件。 是絕大多數流量,例如 zx_channel_write()zx_port_queue()
  3. 這類呼叫會建立新物件,但不會使用帳號代碼,例如 zx_event_create()zx_channel_create().存取這些限制和限制 ) 由包含呼叫程序的工作所控制。

系統呼叫是由 libzircon.so 提供,後者是「虛擬」共用 Zircon 核心為使用者空間提供的程式庫。 虛擬動態共用物件或 vDSO。 這些是格式為 zx_noun_verb()zx_noun_verb_direct-object()

系統呼叫在 //zircon/vdso 中以自訂形式 FIDL 定義。 這些定義會先由 fidlc 處理,再由 zither 處理,後者會使用 IR fidlc 的表示法並輸出各種格式,在 VDSO、核心 依此類推

帳號代碼權利

物件可能會在一或多個處理程序中,有多個參照這些帳號代碼的帳號代碼。

在幾乎所有物件中,上次與物件有關的開放式控點關閉時 物件已被刪除,或處於無法復原的狀態。

如要將帳號代碼變更為其他程序,你可以將帳號寫在頻道中 (使用 zx_channel_write()),或 zx_process_start() 用於將帳號代碼做為引數傳遞 產生新程序第一個執行緒中的部分

帳號代碼或參照的物件可能採取的操作,均以帳號代碼為準 相關的權利。參照相同物件的兩個帳號代碼 可能有不同的權利。

zx_handle_duplicate()zx_handle_replace() 系統呼叫可能會用於 取得其他控點,所參照的物件與傳入的控點相同。 並視情況縮減權利。zx_handle_close() 系統呼叫會關閉帳號代碼,釋放參照的物件 (如果該控點為 最後一個則是該物件zx_handle_close_many() 系統呼叫同樣也會關閉帳號代碼陣列

核心物件 ID

核心中的每個物件都有一個「核心物件 ID」或「koid」短句 這是一個 64 位元的無正負號整數,可用來識別物件 且在運作系統的生命週期內都是獨一無二的 具體來說,變數一律不得重複使用。

有兩個特殊的 koid 值:

ZX_KOID_INVALID 的值為 0,用來當做「空值」使用Sentinel

ZX_KOID_KERNEL 只有一個核心,並且有自己的 koid。

核心產生的 Kotlin 語言只能使用 63 位元 (非常大量)。 以人工分配的培養物 已相當可觀核心產生的 Kids 的分配順序。 且隨時可能變更。

人工智慧的存在,主要用來識別人為物體 例如追蹤中的虛擬執行緒,以及由工具取用 人工兒少的受如何分配至每項計畫 本文件不含任何規則或慣例。

執行程式碼:工作、程序和執行緒。

執行緒代表 Google Cloud 中執行的執行緒 (CPU 暫存器、堆疊等) 以及這些位址空間所屬的程序。程序 則會定義多項資源限制工作擁有者: 父項工作,到根工作為止,根工作是由位於 啟動並傳遞至 userboot,這是開始執行的第一個使用者空間程序

如果沒有工作控點,處理中的執行緒可能無法再建立 處理或其他工作。

程式載入是由使用者空間設施提供, 核心層上方的通訊協定

請參閱:zx_process_create()zx_process_start()zx_thread_create()、 和 zx_thread_start()

訊息傳遞:通訊端與通道

通訊端和通道都是雙向和雙重的 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_signalst 類型和 ZXSIGNAL) 定義),代表與目前狀態相關的部分資訊。通道和通訊端 例如 READABLE 或 WRITABLE。處理程序或執行緒可能會終止。依此類推。

執行緒可能會等待一或多個物件的訊號生效。

詳情請參閱「信號」一文。

等待中:等待一、等待多次及通訊埠

Thread 可能會使用 zx_object_wait_one() 在單一帳號代碼上等待訊號,或 zx_object_wait_many():等待 多個帳號代碼的信號這兩項呼叫會在之後逾時 即使沒有待處理的信號 也會傳回

逾時時間可能會因為設定的期限而有所不同 slack。詳情請參閱計時器滑桿

如果 Thread 需要等待大量帳號代碼,使用效率會提升 通訊埠,即其他物件在發出訊號時可能會繫結的物件 否則通訊埠會收到封包,其中包含 待比對信號

請參閱:zx_port_create()zx_port_queue()zx_port_wait()、 和 zx_port_cancel()

「事件」、「事件配對」。

事件是最簡單的物件,且沒有其他收集的有效信號狀態。

事件配對是一組事件,用來發出信號。實用的屬性是 事件配對是指配對的其中一側消失時 (所有帳號代碼都消失了) 則封閉式信號),另一端已聲明 PEER_CLOSED 信號。

請參閱:zx_event_create()、 和 zx_eventpair_create()

共用記憶體:虛擬記憶體物件 (VMO)

虛擬記憶體物件代表記憶體的一組實體頁面,或稱「可能」 網頁 (隨需建立/填寫)。

這些字串可對應至處理程序中的 zx_vmar_map() 且未與 zx_vmar_unmap().「 」的權限 可使用 zx_vmar_protect() 調整對應的頁面。

也可透過 zx_vmo_read()zx_vmo_write()。 因此,進行一次性作業時,請避免將地圖對應至位址空間 例如「建立 VMO,在當中寫入資料集,然後交給其他處理序使用」。

管理位址空間

虛擬記憶體位址地區 (VMAR) 為 輸出的位址空間建立程序時,根 VMAR 的控制代碼 提供給程序建立者該控點是指涵蓋多種區域的 VMAR 整個位址空間。這個空間可透過 zx_vmar_map()zx_vmar_allocate() 介面。 zx_vmar_allocate() 可用於產生新的 可用於分組的 VMAR (稱為子區域或子項) 地址部分

請參閱:zx_vmar_map()zx_vmar_allocate()zx_vmar_protect()zx_vmar_unmap()、 和 zx_vmar_destroy()

Futexes

Futexe 是核心基元,可以搭配使用者空間不可分割作業來實作 有效率的同步處理基本功能,例如 Mutex,只需要進行 在不良情況下發出 syscall這類項目通常只涉及 標準程式庫Zircon 的 libc 和 libc++ 為 依據 Futexes 實作的互斥鎖、條件變數等。

請參閱:zx_futex_wait()zx_futex_wake()、 和 zx_futex_requeue()