[Fuchsia] Zircon Kernel

Kurun
11 min readJun 14, 2020

Introduction

In this article, I have summarized the contents of my research of Zircon, which is the kernel of Fuchsia OS.
本記事では、Fuchsia OSのカーネルであるZirconについて、調査した内容をまとめています。

Fuchsia OSの概要については、以下のページにまとめています。
The outline of Fuchsia OS is summarized on the following page.

I will update it as needed, such as what I learned later, so please let me know in the comments if there are any mistakes.
後から分かったことなど、必要に応じて随時更新をしていますので、間違い等がありましたらコメントでお知らせください。

Overview

Fuchsia OS 中核のカーネル部分は Zirconと呼ばれています。

ユーザ空間のプロセスやスレッド管理やプロセス間通信、仮想メモリ、デバイスドライバなどの基本的な OS の機能を実現し、それらの システムコールを API として提供します。

Linuxカーネルとは全くの別物の新規のカーネルです。機能性の観点では、Linux > Zircon > microkernel / RTOS (Real Time OS) という機能順序でしょうか (今時点では) 。

Zircon started as a fork from the Little Kernel

Zircon は Little Kernel (LK)と呼ばれる組み込み向けの RTOS (リアルタイムOS) からフォークした OS です。

Zirconの多くが LK ベースになっていると言われていますが、C++で全て書き直されていることや、上位レイヤは Zircon 独自のコンセプトが導入されているなど、ぱっと見てもLKの面影がありません。

ちなみに、RTOS の代表例として、TOPPERS や eT-Kernel, NuttX, FreeRTOS などが挙げられます。これらは、 RAM や CPUパワーなどのハードウェアリソースが限られたマイコン上で動作することを前提として作られており、仮想メモリがなかったり、タスク (プロセス) がシングルタスクだったりと、機能的には必要最低限のレベルであることが一般的だと思います。

一方、Zircon は以下に述べられているように、スマホに利用されているような SoC (System On Chip) をターゲットとした組み込み OS です。

Zircon targets modern phones and modern personal computers with fast processors, non-trivial amounts of ram with arbitrary peripherals doing open ended computation.

Difference between Zircon and Little Kernel

Zircon と LK の大きな違いは以下です。その他、スケジューラが LK から改良されているなど、細かな変化点が多くあります。

  • 64bit CPU のみサポート (LK は 32bit CPU のみ)
  • カーネルモードとユーザモードを持つ ( LK は区別なし)
  • 仮想メモリのサポート
  • マルチプロセスのサポート
  • 多くのシステムコールをサポート
  • 仮想化技術のサポート など

Is Zircon a microkernel?

明確に記載があり、マイクロカーネルではなく、モノリシックカーネルを目指している様子です。

Kernel Mode / User Mode

Zirconカーネル自体はKernelモードで動作しますが、Zirconカーネルが利用する機能以外は、基本的にUserモードで動作します。例えば、Linuxでは当たり前の各種デバイスドライバやファイルシステム関連は、Kernel側での実装ではなく、Userland側の実装・動作となります。つまり、それらはUserモードで動作します。

System Call

Zirconは多くのシステムコールを提供しています。しかし、これらの API は POSIX とは全くの別物で、互換性もありません (一部は POSIX 互換のAPIもある様です) 。

Kernel Object

Zirconは、 Kernel Objectを管理します。

Kernel Objectには、例えば以下のようなものがあります。

  • IPC
    Channel, Socket, FIFO
  • Signal
    Event, Event Pair, Futex
  • Task
    Process, Thread, Job, Task

ユーザランドのプログラムは、System CallのAPI経由を経由してKernel Objectのハンドルを取得します。そのハンドルに対して、各種操作を行うことで、カーネルの機能を利用することが可能です。

参考までに、Thread作成のサンプルを以下に示します。zx_handle_t型の変数がハンドルです。基本的に、System CallのAPIを利用する場合は、取得したハンドルを引数で指定することになります。

LifeCycle

Kernel Objectのライフサイクルについてです。

カーネルが管理している各種Kernel Objectは、参照カウンタの方式で参照先が今どれだけあるかを管理しています。つまり、参照先がなくなる (カウンタ値が0になる) と、そのKernel Objectは破棄されます。

Security

Rightsという、ハンドルに対してセキュリティ権限を付与するオプションのようなものがあります。

しかしこれは、System Callで取得したハンドルに対して、オプション的にRead操作のみ, Write操作のみ, Handleの複製不可などの権限を付与するものであり、厳密なセキュリテイの機能ではありません。そのため、System CallのAPIレベルでは、セキュリティ機能は基本的になく、利用するUserland側の対応に委ねられます。

なお、Fuchsiaの場合は、Userland側で構築されているFramework似て、各種アプリケーションをSandbox化するため、ユーザアプリケーションレベルでのセキュリティは確保されています。

vDSO

System Callは vDSO(virtual Dynamic Shared Object)と呼ばれるelf形式のファイルにまとめられています。

soファイルと言いつつも、名前にvirtualと付いている通り、各ユーザプログラムにDynamic Linkされるわけではありません。それは、Kernel自体の領域に配置され、Userlandのプログラムは FIDLを経由してvDSOのライブラリを間接的に参照します。FIDL (Fuchisaが提供するフレームワークとしてのIPC機能) については、別途解説したいと思います。

libc

前述の通り、System CallはPOSIX非互換ですが、C/C++のプログラムの標準ライブラリ等が使えるようにlibcは提供されています。しかし、forkやpthreadの一部機能が使えないないなど、POSIX非互換であるが故に、制約はありそうです。

Virtualization

Zirconには、Linuxカーネルの KVMのようなHypervisor (仮想化技術) が組み込まれています。

Hypervisor-related APIs

関連API自体はそれほど多くないので、ベアメタルのソフトウェアを動かす程度であれば、割と簡単に使えそうな雰囲気があります。

Linux Runner

すでにFuchsiaパッケージの中に、Linuxのプログラムを動かすRunnerがあります。ただ、実際に動かしてみましたが、その時は正常動作しませんでした… (使ったバージョンが悪かったかな?)

--

--

Kurun

Software Engineer / Embedded Linux, Android, Firmware, Embedded Software, Flutter / Like: C/C++, Java, Dart