Google Fuchsiaについて調べてみた
本記事は 自作OS Advent Calendar
の14日目の記事となります(狙ったわけではないですが偶然にも昨年と同じ14日目の登場となりました)。
みなさま、ご無沙汰しております。
自作OSに復帰する
みたいなことを去年のAdvent Calendarに書いたものの、今年は昨年と同様かそれ以上に忙しくなかなかOS自作に取り組む時間を捻出できませんでした。。
まずは自作OSもくもく会に復帰したいなと思いつつ、今年のAdvent CalendarもOS自作と関係ないようで関係ありそうなトピックにしました。
今回のテーマは Google Fuchsia
です。今回は、この謎の多いGoogleの新OSについて色々と調べてみました。
余談ですが、GIZMODOの記事によれば、Fuchsia
は フューシャ
と読むみたいですが、Google翻訳でFuchsiaの記事を翻訳すると フクシア
と出ますね。
目次
Google Fuchsiaの概要
Google Fuchsiaとは
Google Fuchsia(以下 Fuchsia
と略して記載します)は2016年8月に何の前触れもなく突然現れました。
※当時の記事
登場から2年以上経過していますが、当時と状況はあまり変わっておらず、2016年から今に至るまで、公式に発表されているプロダクトではありません(私の方でも改めて調べてみましたが、Googleからの公式発表は結局見つからず)。公式の情報源はGoogleのFuchsiaリポジトリにあるドキュメント群と下記Githubリポジトリ(リポジトリ名にmirrorと入っているのでGoogleのFuchsiaリポジトリのミラーと思われます)しかない、未だ謎の多きプロジェクトです。
余談ですが、Fuchsiaのロゴって富士通のロゴの鏡写しみたいなデザインですね。
Google Fuchsiaの特徴
公式発表すらされていないFuchsiaですが、公式リポジトリのドキュメントや各種紹介記事やプレゼン資料を総合すると、下記のような特徴をもったOSです。
- マイクロカーネルである (Linuxはモノリシックカーネル)
- 全くの新規で開発されている (AndroidはLinuxカーネルの上に各種フレームワークを構築しているのに対して、Fuchsiaは新規開発のカーネルを使用している)
- 非POSIX互換のシステムコールインタフェース *1
- C++ベースで実装されている
ところで、Fuchsiaは私自身の感覚としてはOS開発というよりはモバイルアプリケーション開発の文脈で話が出ることが割と多い気がしています。とりわけAndroidからFuchsiaへ置き換えるといった噂は盛んに報じられています。下記の記事もそういった噂を報じた記事の1つです。
それは、ひとえにFuchsiaのGUIアプリケーション開発にFlutterというモバイルアプリ開発で最近話題のフレームワークを使えることが主な理由なのではないかと思います。
Google Fuchsiaのアーキテクチャ
The Fuchsia layer cake
公式ドキュメントによれば、Fuchsiaは下記4つのレイヤ(The Fuchsia layer cake)から構成されています。
- Zircon
- レイヤーの最下層に位置する、Fuchsiaのカーネル
- Garnet
- ネットワーク、メディア、グラフィックスサービスなどのシステムサービスが属するレイヤー
- Peridot
- Topaz
- レイヤーの最上層に位置する
- UIやシェルを提供する
Zirconカーネルについて
Zircon
はFuchsiaのカーネルです。昔は Magenta
と呼ばれていました。
Zirconはマイクロカーネルで、システムコールの他に、スレッド、ソケット、仮想メモリマネージャ、割り込みなどの標準的なカーネルの機能を提供します。 *4 *5 ただし、ファイルシステムはカーネルには含まれず、またユーザ空間で実行されます。ファイルシステムの扱いについてはLinuxなどはカーネル空間でファイルシステムを扱っており、この点はZirconの大きな特徴といえるのではないでしょうか。
Zircon Kernel Concepts によれば、カーネルの各種機能はカーネルオブジェクトとして実装されています(ドキュメントでもZircon is a object-based kernel.
と記載されているほどで、Zirconの大きな特徴です)。ユーザ空間のプログラムは、システムコールを介してこれらのカーネルオブジェクトにアクセスすることができます。
Zirconのシステムコールは libzircon.so
によって提供されます。libzircon.so は vDSO
と呼ばれています。また、Zirconのシステムコールは非POSIX互換です。 *6
ファイルシステム
Filesystem Architectureによれば、Fuchsiaのファイルシステムはユーザ空間内に存在します。これにより、Fuchsiaではカーネルの再コンパイル無しにファイルシステムを柔軟に変更することができます。
Fuchsiaでのファイルシステムにあたるものはファイルシステムサービスとなっており、クライアントアプリはこのファイルシステムサービスに処理の要求を出すことによってファイルの読み書きを実現します。
また、Fuchsiaのファイルシステムでは Namespace
と呼ばれるクライアントごとのファイルシステムを持ちます。クライアントは任意のルート(ディレクトリハンドル)を設定することになります。そのため、Linuxのようなグローバルのルートファイルシステムは持たず、クライアントごとにアクセス範囲を制限することができます。
別なNamespaceへアクセスしたい場合には、別なNamespaceの特定のディレクトリへのマッピングという形でアクセスことになります。 *7
Google Fuchsiaのビルドと実行
※ 本項の内容は公式リポジトリのgetting_started.md、および下記記事とほぼ同じ内容になります(一部元記事にないところで詰まった箇所があったので、そこだけは役に立つかもしれません)。
本当なら、ちょっとしたGUIアプリでも作ってみようかと思ったのですが、残念ながらそこまで到達できませんでした。。ただ、OSの実行まではできたので、macOSでFuchsiaをビルドして動かす方法について紹介します。
なお、ここでの解説内容は公式リポジトリにあるソースのビルド方法となります。公式リポジトリのビルド方法とGithubにあるミラーリポジトリのビルド方法は少し異なるのでご注意ください。
ビルドに必要なツールのインストール
※ Xcodeインストール済みの人は無視してください。
macOSの場合はコマンドラインツールをインストールしてください。下記コマンドでインストールすることができます。
xcode-select --install
プロジェクト一式のダウンロード
それでは、ソースコードとツール一式が含まれたプロジェクトをダウンロードしましょう。ただし、ソースコードのダウンロード方法が少し特殊です。下記コマンドを実行してダウンロードしてください。
curl -s "https://fuchsia.googlesource.com/scripts/+/master/bootstrap?format=TEXT" | base64 --decode | bash
fxのセットアップ
ビルドやFuchsiaの起動には fx
というツールを使います。fxが使えるようシェル周りを設定していきましょう。まず、ダウンロードしてできた fuchsia
というディレクトリのルートに .jiri_root
という名前のディレクトリがあるので、これを ~/
へコピーしましょう。
cd fuchsia cp -r .jiri_root ~/
コピーできたら、 .jiri_root/bin/
の中にfxがあるので、PATHを設定しましょう。
私は今年からfish shellを使っているのですが、fish shellの場合は ~/.config/fish/config.fish
に下記1行を追加してください。
set -x PATH $HOME/.jiri_root/bin $PATH
bashをお使いの方は .bashrcに下記を追加します。
export PATH="$HOME/.jiri_root/bin:$PATH"
zircon/prebuilt/prebuilt/downloadの内容をダウンロードする ※必要に応じて
ひょっとするとこの手順は環境によっては必要ないかもしれませんが、私の環境ではzirconのビルド時に zircon/prebuilt/download
が無いためにビルドエラーが発生しました。
私の環境の場合は zircon/scripts/download-prebuilt
を実行することでビルドに必要なバイナリをダウンロードすることができました。コマンドとしては下記のとおりに実行します。
./zircon/scripts/download-prebuilt
Fuchsiaのビルド
ビルドをはじめる前に、ターゲットのCPUアーキテクチャを設定します。
Fuchsiaが現在サポートしているCPUは x64
arm64
です。ここではターゲットを x64 として解説します。
ターゲットの設定は下記コマンドで行います。
fx set x64
なお、上記コマンドだとデバッグビルドになります。リリースビルドにしたい方は下記コマンドを実行してください。
fx set x64 --release
ここまでできたら、あとは実際にビルドを実行するだけです。下記コマンドでビルドを開始しましょう。
fx full-build
ビルドに使うマシンによりますが、結構な時間がかかりますので気長に待ちましょう。
Fuchsiaの起動
ダウンロードしたプロジェクト一式の中にQEMUが既に含まれており、下記コマンド1つでビルドしたFuchsiaを実行できてしまいます(とてつもなく楽です)。
fx run
なお、GUIを有効にした状態で起動する際には -g
オプションを付加して起動します。
fx run -g
ただし、起動すればわかるとおり、カッコいいUIが出てくるわけではなく、下記のようにコマンドラインしか表示されません。
実は、FuchsiaのGUIは Vulkan というグラフィックスAPIのサポートが必須なのですが、残念ながらQEMUの方がVulkan未サポートなので、カッコいいUIにはお目にかかれなさそうです。。
余談ですが、Pixelbookで起動した猛者がいて、その際の画面の様子を見たい方は下記動画を見てみると、実際のGUIのイメージがつかめると思います。
dmコマンド
Fuchsiaのシェルでは ls
や pwd
などのLinuxなどで使えるコマンドも普通に使えます。
ただ、Fuchsiaのシャットダウンや各種デバッグ、デバイス情報を確認したい場合は dm
コマンドを使います。
$ dm help dump - dump device tree poweroff - power off the system shutdown - power off the system suspend - suspend the system to RAM reboot - reboot the system reboot-bootloader - reboot the system into bootloader reboot-recovery - reboot the system into recovery kerneldebug - send a command to the kernel ktraceoff - stop kernel tracing ktraceon - start kernel tracing devprops - dump published devices and their binding properties drivers - list discovered drivers and their properties
Fuchsiaをシャットダウンしたい場合は shutdown
または poweroff
オプションを使います。
dm shutdown
また、 dump
オプションを使うと、デバイストレースを確認することができます。Fuchsiaの構成が垣間見えるようでおもしろかったので、付録2として実行結果を掲載しておきます。
まとめ
公式発表されていないために情報源が少なく、調査に苦労しましたが、自作OSを嗜む者として、Fuchsiaは面白そうな題材だなという感想を改めて持ちました。
また、LinuxやUNIX系の多くのOSはC言語で実装されたモノリシックカーネルであるのに対し、FuchsiaはC++で実装されたマイクロカーネルであることも、コードが読めるOSの実装例として、とても貴重だと思います。
各種ドキュメントやソースコードの解読が進んで、多くの知見が自作OS界隈にもたらされると良いなと思いつつ、私も時間を見つけて解読を進めたいなと思いました。
付録1:Fuchsiaの情報源
- Googleのリポジトリ
- 公式リポジトリです。
- Githubリポジトリ
- 公式リポジトリのミラーです。コードやドキュメントの検索はこちらの方が良いかもしれません。
- Fuchsia Friday
- 9to5GoogleはFuchsiaの情報が最も多く掲載されている情報源だと思います。特にFuchsia Fridayの各記事はFuchsiaのアーキテクチャ解説記事としては現時点で最も詳しいと思います。
Fuchsia概略その1
プレゼン資料- 日本語で閲覧可能な数少ないFuchsiaに関する資料の1つです。続編を期待しています!
- Fuchsia: a new operating system
- ZirconがMagentaと呼ばれた頃の記事なので少し古いですが、Fuchsiaにおけるカーネルの役割がコンパクトにまとまっていると思います。
付録2:dm dumpの実行結果
※ コマンド実行結果の見方については Zircon Device Modelに記載されています。
$ dm dump [root] <root> pid=2058 [null] pid=2058 /boot/driver/builtin.so [zero] pid=2058 /boot/driver/builtin.so [misc] <misc> pid=2126 [console] pid=2126 /boot/driver/console.so [demo-fifo] pid=2126 /boot/driver/demo-fifo.so [dmctl] pid=2126 /boot/driver/dmctl.so [tapctl] pid=2126 /boot/driver/ethertap.so [hidctl] pid=2126 /boot/driver/hidctl.so [ktrace] pid=2126 /boot/driver/ktrace.so [ptmx] pid=2126 /boot/driver/pty.so [nand-ctl] pid=2126 /boot/driver/ram-nand.so [ramctl] pid=2126 /boot/driver/ramdisk.so [sysinfo] pid=2126 /boot/driver/sysinfo.so [sys] <sys> pid=1990 /boot/driver/bus-acpi.so [cpu-trace] pid=1990 /boot/driver/bus-acpi.so [acpi] pid=1990 /boot/driver/bus-acpi.so [acpi-pwrbtn] pid=1990 /boot/driver/bus-acpi.so [hid-device-000] pid=1990 /boot/driver/hid.so [rtc] pid=1990 /boot/driver/bus-acpi.so [rtc] pid=1990 /boot/driver/intel-rtc.so [i8042] pid=1990 /boot/driver/bus-acpi.so [i8042-keyboard] pid=1990 /boot/driver/pc-ps2.so [hid-device-001] pid=1990 /boot/driver/hid.so [i8042-mouse] pid=1990 /boot/driver/pc-ps2.so [hid-device-002] pid=1990 /boot/driver/hid.so [pci] pid=1990 /boot/driver/bus-acpi.so [00:00.0] pid=1990 /boot/driver/bus-pci.so [00:01.0] pid=1990 /boot/driver/bus-pci.so <00:01.0> pid=2531 /boot/driver/bus-pci.proxy.so [bochs_vbe] pid=2531 /boot/driver/simple.bochs.so [display-controller] pid=2531 /boot/driver/display.so [00:02.0] pid=1990 /boot/driver/bus-pci.so <00:02.0> pid=2581 /boot/driver/bus-pci.proxy.so [ahci] pid=2581 /boot/driver/ahci.so [sata0] pid=2581 /boot/driver/ahci.so [block] pid=2581 /boot/driver/block.so [fvm] pid=2581 /boot/driver/fvm.so [blobfs-p-1] pid=2581 /boot/driver/fvm.so [block] pid=2581 /boot/driver/block.so [minfs-p-2] pid=2581 /boot/driver/fvm.so [block] pid=2581 /boot/driver/block.so [00:1f.0] pid=1990 /boot/driver/bus-pci.so [00:1f.2] pid=1990 /boot/driver/bus-pci.so <00:1f.2> pid=2657 /boot/driver/bus-pci.proxy.so [ahci] pid=2657 /boot/driver/ahci.so [00:1f.3] pid=1990 /boot/driver/bus-pci.so [test] <test> pid=2023 [test] pid=2023 /boot/driver/test.so [wlantapctl] pid=2023 /system/driver/wlantap.so