.NET 7 と C# を用いて OS を開発する事はできるのか?
Copyright (C) 2022 Takym.
(この記事は元々別のリポジトリで公開していたものを移動してきたものです。)
目的
- この記事は「自作OS Advent Calendar 2022」の12月25日に向けて執筆した。
対象読者
- UEFI の仕組みをある程度理解している。
- .NET の仕組みをある程度理解している。
動機
- オペレーティングシステム(以下、OS)は C/C++ や Rust などの事前コンパイル型言語(Ahead-Of-Time Compiled Language; AOT Compiled Language)を用いて開発する事が多い。
- C# は実行時コンパイル型言語(Just-In-Time Compiled Language; JIT Compiled Language)である為、OS 開発には向かないと考えられてきた。
- .NET 7 から Native AOT が正式にサポートされたため、C# でも UEFI 向けのアプリケーションを生成できる様になった。
- C# の様な高機能オブジェクト指向プログラミング言語を用いてより効率的に OS 開発を行えるのではないかと考えた。
- また、.NET 7 の膨大なランタイムライブラリを使えば、車輪の再発明をせずに新規の OS を開発できるのではないかと考えた。
- 本記事では .NET 7 及び C# を用いた OS 開発の手法の利点と欠点を考察する。
Native AOT を使う方法
- 冒頭でも説明した Native AOT を使う方法の利点と欠点を考察する。
- Native AOT を用いた UEFI アプリケーションの実装例は zerosharp/efi-no-runtime がある。
利点
- 他の方法よりも直観的である。
- UEFI の API を直接触る事ができる。
欠点
- UEFI アプリケーションの制約で、ライブラリを動的にリンクする事ができない。
- ランタイムライブラリを使用できない。
System.Object
やSystem.String
等の基本的な型も定義する必要がある。- 定義しなければならない基本型の数は多い。
- ビルド時に解析ツールが型情報の互換性に関するエラーを発生させる場合がある。
.NET 7 ランタイムを移植する方法
- 次に .NET 7 ランライムそのものを UEFI に移植する方法を考察する。
- .NET 7 ランタイムはオープンソースである為、自力で移植する事ができる。
利点
- 完全なランタイムライブラリが使用できる。
- .NET 7 が「最小のカーネル」の様な役割を果たしてくれる為、動的リンクが可能になる。
欠点
- .NET 7 のソースコードは膨大である為、移植には長い時間を要する。
- 移植の方法次第で、UEFI の API を直接触る事ができなくなる可能性がある。
.NET 7 のランタイムライブラリのソースコードの一部をコピーする方法
- ランタイムライブラリから必要な部分のソースコードのみをコピーし、Native AOT を用いる方法を考察する。
- .NET 7 の機能の大半は C# で書かれており、C++ で書かれている部分は仮想マシン、JIT コンパイラ、ガベージコレクション、プラットフォーム抽象化レイヤー(PAL1)等のみである。
- よって、C# で書かれている部分のソースコードのみでも充分だろう。
利点
- ランタイムライブラリの一部が使用できる。
- 基本型の定義が不必要になる。
- コピーするコードは一部で良いので、移植に掛かる時間が短くなる。
- UEFI の API を直接触る事ができる。
欠点
- ランタイムライブラリの更新に手間が掛かる。
- ライブラリに更新があった際は、再びソースコードをコピーする必要がある。
- 動的リンクができない。
Roslyn を改造する方法
- オープンソースの C# コンパイラである Roslyn を改造し、UEFI アプリケーションを出力する機能を付け加える方法を考察する。
利点
- Native AOT と比べて自由度が高い。
- ランタイムライブラリを静的リンクできる様に改造する事もできる。
- Native AOT と単一ファイルアプリケーションは併用できない。
欠点
- Roslyn を改造する手間が掛かる。
- コンパイルを切り替える等の特殊な設定が必要になる。
最小の Linux カーネルを使う方法
- 最小の Linux カーネルの上で .NET 7 を実行する方法を考察する。
- これは .NET 7 と C# を用いて Linux ディストリビューションを開発する方法であると言える。
利点
- 完全なランタイムライブラリを使用できる。
- 動的リンクができる。
- NuGet を用いたライブラリの自動更新ができる。
- .NET 7 は Linux に対応しており、互換性の問題は殆ど無い。
欠点
- カーネルそのものは開発しないので、自作 OS の開発であると言えるか微妙である。
- UEFI の API を直接触る事ができない。
COSMOS を使う方法
- COSMOS と呼ばれる C# で OS を開発する為のフレームワークがある。
利点
- サードパーティー製のフレームワークを用いても良いのであれば、最も簡単な方法である。
欠点
- インストール作業に手間が掛かる。
- インストール作業の手間を無視すれば、実質的には欠点は無いと考えられる。
結論
- 困難ではあるものの .NET 7 と C# を用いて OS を開発する事は可能である。
- ただし、選択した方法によっては、C/C++ で開発する時よりも多くのコードを書く必要性が生じる場合もある。
- .NET 7 と C# は OS 開発に利用される事が想定されていないという点を注意する必要がある。
出典・参考文献
- コンパイル型言語 - Wikipedia
- 事前コンパイラ - Wikipedia
- 実行時コンパイラ - Wikipedia
- C# 関連のドキュメント - はじめに、チュートリアル、リファレンス。 | Microsoft Learn
- Native AOT deployment overview - .NET | Microsoft Learn
- dotnet-5.0におけるNativeAOTについて - Qiita
- dotnet-6.0におけるNativeAOTについて - Qiita
- zerosharp/efi-no-runtime at master · MichalStrehovsky/zerosharp (GitHub)
- dotnet/runtime: .NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps. (GitHub)
- dotnet/roslyn: The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs. (GitHub)
- .NET Compiler Platform SDK (Roslyn API) | Microsoft Learn
- アプリケーション配置用に単一ファイルを作成する - .NET | Microsoft Learn
- COSMOS - COSMOS
余談
- これまでの記事は敬体で書いていましたが、今回は常体で書きました。そのため少し不安が残ります。
- 余談はとても個人的な内容になりますので敬体で書きました。
- 分かり易くする為に事実と感想で文体を別ける様に心掛けています。
- 自分の過去の記事を再読してみましたが、今思うと拙作であったと感じます。
過去の記事の紹介
- 2019年12月25日
- 2019年12月24日
- 2018年12月25日
脚注
-
.NET Glossary には「Platform Adaptation Layer」と書かれているが、「Platform Abstraction Layer」と表現される場合もある。厳密な使い分けがある可能性もあるが、有力な情報は得られなかった。 ↩