Genode OS Frameworkを新しいハードウェアプラットフォームに移植する

最近、ますます多くの企業がマイクロカーネルオペレーティングシステムに関心を示しています。 アカデミックカテゴリのこれらのシステムは、実際の製品で使用するためにOSのカテゴリに移行し始めます。 たとえば、最近導入されたSamsung Knoxプラットフォームは、OKL4 Microvisorを使用して構築されています。 現在、マイクロカーネルシステムは主に情報セキュリティの分野で使用されているため、このようなソリューションはさらに多くありますが、使用されている技術をすべてのメーカーが宣伝しているわけではありません。



マイクロカーネルOSの簡単な歴史と最も有名なプロジェクトの説明は、最近同僚のsartakovが記事「 Microkernels and FOSDEM'13 」で説明しました。 Genode OS Frameworkと、ARMアーキテクチャプロセッサに基づいた新しいハードウェアプラットフォームに移植するプロセスについて、さらに詳しく説明したいと思います。 Fnodeco.OCをGenodeのカーネルとして使用しました。







では、Genode OSフレームワークとは何ですか? これは、マイクロカーネルに基づいてオペレーティングシステムを構築するためのフレームワークです。 Genodeは、さまざまなマイクロカーネルを使用してOSを構築できる単一のAPIを提供します。 現在サポートされているマイクロカーネルは、Codezero、Fiasco、Fiasco.OC、Nova、OKL4、Pistachioです。 Linuxカーネルでの作業もサポートされています。 さらに、ARMアーキテクチャに基づく一部のプラットフォームでは、サードパーティコア(base-hw)を使用せずに実行することができます。

これらのコアは異なるプロセッサアーキテクチャをサポートし、一部のハードウェア機能を使用する場合があります。 たとえば、Fiasco.OCカーネルは、x86、amd64、ARMなどの多数のアーキテクチャで動作できます(他のアーキテクチャは利用可能ですが、Genodeでは現時点ではサポートされていません)。Novaコアはx86アーキテクチャのマイクロハイパーバイザーであり、使用できますハードウェア仮想化。 Genodeフレームワークの使用により、ソースコードを変更せずに、サポートされているカーネルのいずれかで使用するためにアプリケーションをコンパイルできます。

Genodeに関するより詳細な情報は、プロジェクトWebサイトに投稿されたドキュメント、および「 Ksys labs Summer School of System Programming 」についてNorman Feskeが読んだ資料から入手できます。



現在、ARMアーキテクチャ向けGenode + Fiasco.OCは、Realview PBXA9、Versatile Express A9X4、Pandaboard(TI OMAP4)、Freescale iMX53、Arndale(Samsung Exynos 5)のプラットフォームをサポートしています。 これらのデバッグボードはすべて非常に高価であり、一般的に入手が非常に難しいものもあります。 現在、100ドル未満の価格のシングルボードPCが数多くあり、愛好家はOSを研究するためのデバッグボードとして、またデバイスのプロトタイピングと製造の基礎として使用しています。 Linuxは通常、これらのデバイスに移植されており、一部のデバイスにはオープンソースのドキュメントがあります。 利用可能なデバイスの概要を含む優れた記事「 ホームクリエイティビティ(DIY)のためのミニコンピューターの選択 」。 説明したボードの一部のプラットフォームは、Fiasco.OCカーネルで既にサポートされており、移植は不要です。



おそらく、投稿の冒頭の写真から、ポーティングのプラットフォームとして既に推測しているように、 Allwinner A10 SoCベースのCubieboardミニPCを使用しました。

このプラットフォームは、いくつかの理由で興味深いものです。

-古すぎるCortex-A8アーキテクチャ。

-U-Bootローダーのソースコードの存在、Linuxカーネル、およびユーザーマニュアルの形式でのネットワークへの「漏洩」ドキュメントの存在。

-周辺機器の大規模なセット(SATA、HDMIなど);

-このチップ上に安価な「ハッキング可能な」デバイスが多数存在する(Cubieboard、Mele A1000 / A2000など)。



このSoCをより詳細に検討してください。



CPU:NEON、VFPv3、Trustzoneをサポートする最大1Ghzの周波数のARM Cortex-A8

GPU:Open GL ES 2.0をサポートするMali 400 MP

VPU:FullHDビデオをサポートするCedarX。

周辺機器:4xUSBホスト、USB OTG、4xSD / MMC、8xUART、4xSPI、3xI2C、GPIO、SATA、HDMI、LCDインターフェースなど



Fiasco.OCカーネルは、Cortex-A8プロセッサアーキテクチャをサポートしています。 つまり、新しいプラットフォームに移植するには、プラットフォームサポート、いわゆるボードサポートパッケージ (BSP)を追加するだけです。 BSPのソースコードは、ディレクトリkernel / fiasco / src / kern / arm / bspにあります。

Fiasco.OCのARMアーキテクチャのBSPには以下が含まれます。

-割り込みコントローラーのドライバー。

-タイマードライバー。

-UARTドライバー;

-リセットの実装。

さらに、BSPにはメモリ割り当て構成が含まれています。

A10のメモリは、ユーザーマニュアルに従って、次のように割り当てられます。



OSがメモリを使用するには、物理​​アドレスを知っている必要があります。 これらのパラメーターは、Mem_layoutクラスのmem_layout-arm-sun4i.cppファイルで設定されます。

EXTENSION class Mem_layout { public: enum Virt_layout_sun4i : Address { Timer_map_base = Devices1_map_base + 0x020C00, Intc_map_base = Devices1_map_base + 0x020400, Uart_base = Devices1_map_base + 0x028000, Watchdog_map_base = Timer_map_base + 0x90, }; enum Phys_layout_sun4i : Address { Devices1_phys_base = 0x01c00000, Sdram_phys_base = 0x40000000, Flush_area_phys_base = 0xe0000000, }; };
      
      





さまざまなソースからのイベントを処理するには、割り込みコントローラーが必要です。 割り込みコントローラーのドライバーは、コントローラーの制御、コントローラーの構成、割り込みのマスキング、機能の処理などの操作を実行するために使用されます。 pic-arm-sun4i.cppファイルのドライバーコード。



タイムスロットの終了やIPCタイムアウトなどのイベントを生成するには、タイマーが必要です。 A10には6つのタイマーがあります。 タイマーTimer0は、割り込みのタイマーとして使用されます。 SoCには、一般的なタイマーに加えて、目覚まし時計付きのウォッチドッグとRTCも含まれています。 システムモードでタイマーを使用するには、1 msごとに割り込みを生成する必要があります。 タイマーの初期化と必要な機能は、timer-arm-sun4i.cppファイルに実装されています。



カーネルは、UARTドライバーを使用してデバッグメッセージを出力し、JDBカーネルデバッガーにアクセスします。 Fiasco.OCにはUARTモジュールの初期化はありません;ブートローダーが既にそれを構成していると考えられています(この場合はU-Boot)。 UARTドライバーコードはuart-arm-sun4i.cppおよびkernel / fiasco / src / lib / uart / uart_sun4i.ccファイルにあります。



プロセッサの完全なリセットを実行するには、ウォッチドッグタイマーを使用します。この目的は、コードがループしたときにシステムをリセットすることです。 実装はreset-arm-sun4i.cppファイルにあります。



これらの手順を実行した後、選択したプロセッサのBSPを取得します。 しかし、カーネルはまだロードする必要があります。 ARMアーキテクチャでGenode + Fiasco.OCをロードするプロセスを検討してください。



1.起動時に、ROMブートはSDカード上のブートローダーを探します。SDカードがない場合は、NANDから起動します。

2.スタートアップスクリプトを実行するU-Bootは、ELFまたはu-boot-imageの形式でGenodeイメージをロードします。

3.ロードされたモジュールには、Fiasco.OCコアと、sigma0、ルートタスク(Genodeではコアモジュール)、ユーザープログラムなど、他のすべての実行可能ファイルが含まれます。

4. 1つはブートストラップで、次のようなカーネルの起動に必要な操作の一部を実行します。

-使用可能なメモリのスキャン(すべてのアーキテクチャで実行されるわけではありません。ARMでは、使用可能なメモリの値はプラットフォームの構成で指定されます)。

-メモリ内のモジュールの移動(sigma0およびルートタスクは、カーネルが起動時にモジュールを開始できるように、特定の領域に配置する必要があります)。

-カーネルを直接起動します。

7.カーネルは必要なシステム初期化を実行し、sigma0とルートタスクを開始します。

8.コアモジュール(ルートタスク)が起動し、Genodeサービスが初期化され、構成ファイルを使用して必要なアプリケーションを実行できるようになります。



したがって、Cubieboardでブートストラップを実行するには、このプラットフォームについて知る必要があるため、必要な構成l4 / mk / platform / cubieboard.confとl4 / pkg / bootstrap / server / src / platform / sun4i.ccを追加します。 さらに、コンソールへのダウンロードに関する情報を表示するには、UARTドライバーを実装する必要があります。



移植の最後の手順は、必要な構成ファイルをGenodeビルドシステムに追加することです。 プロセスは簡単です。説明しません。リポジトリの対応するコミットの変更を確認できます。 ビルドシステムの適切な説明は、講義「 Genode OS Framework Programming Environment 」で説明されました。



ソースコードは、チュートリアルブランチのGithub https://github.com/Ksys-labs/genodeにあります 。 r47-sun4iブランチのリポジトリhttps://github.com/Ksys-labs/focの Fiasco.OCの修正バージョン。これらのソースコードにはすでに必要なパッチが含まれており、Genodeビルドシステムを使用してダウンロードされます。



ビルドするには、ソースコードを複製する必要があります。

 git clone git://github.com/Ksys-labs/genode.git git checkout tutorials cd genode
      
      





ARM用のビルドツールチェーン:

 ./tools/tool_chain arm
      
      





Fiasco.OCカーネルをダウンロードします。

 make prepare -C base-foc
      
      





これで、すべてを実行する準備が整いました。

1.次のコマンドを使用して、アセンブリのディレクトリを作成します。

 ./tools/create_builddir foc_cubieboard BUILD_DIR=_build.foc_cubieboard cd _build.foc_cubieboard
      
      





2. hello_tutorialリポジトリを追加して、最も簡単なシナリオに対処します。このシナリオでは、まだ利用できないドライバーは必要ありません。

 echo 'REPOSITORIES += $(GENODE_DIR)/hello_tutorial' >> etc/build.conf
      
      





3. u-boot-imageファイル生成をオンにします

 echo 'SPECS += uboot' >> etc/spec.conf
      
      





4.画像を収集する

 make run/hello
      
      





短いビルドの後、var / run / helloディレクトリにELF(hello.elf)とu-boot-image(uImage)の形式でイメージを取得します。

デバイスで起動した後、接続されたコンソールで、helloチュートリアルから起動プロセスと実行中のアプリケーションを確認できます。

ログ
L4ブートストラップ

ビルド:#4番目。 4月 18 22:48:37 MSK 2013、4.7.2

最大1024 MBのRAMをスキャンする

メモリサイズは1024MB(40,000,000-80,000,000)

RAM:0000000040000000-000000007fffffff:1048576kB

合計RAM:1024MB

mod07:4117e000-411b8e3c:genode /タイマー

mod06:41148000-4117ddc0:genode / hello_server

mod05:4111c000-41147c28:genode / hello_client

mod04:410d6000-4111b738:genode / init

mod03:410d5000-410d51a4:genode / config

mod02:4106e000-410d431c:genode /コア

mod01:41064000-4106d374:sigma0

mod00:41015000-41063d20:/home/vanner/projects/genode/_build.foc_cubieboard/kernel/fiasco.oc/fiasco

41100000の背後で最大8つのモジュールを移動する

移動モジュール00 {41015000-41063d1f}-> {412a4000-412f2d1f} [322848]

移動モジュール01 {41064000-4106d373}-> {412f3000-412fc373} [37748]

移動モジュール02 {4106e000-410d431b}-> {412fd000-4136331b} [418588]

移動モジュール03 {410d5000-410d51a3}-> {411b9000-411b91a3} [420]

移動モジュール04 {410d6000-4111b737}-> {411ba000-411ff737} [284472]

移動モジュール05 {4111c000-41147c27}-> {41100000-4112bc27} [179240]

移動モジュール06 {41148000-4117ddbf}-> {4112c000-41161dbf} [220608]

移動モジュール07 {4117e000-411b8e3b}-> {41162000-4119ce3b} [241212]

移動モジュール03 {411b9000-411b91a3}-> {4119d000-4119d1a3} [420]

移動モジュール04 {411ba000-411ff737}-> {4119e000-411e3737} [284472]

/home/vanner/projects/genode/_build.foc_cubieboard/kernel/fiasco.oc/fiasco -serial_escをスキャンしています

スキャンsigma0

スキャニングgenode /コア

mbiを[0x4100e000-0x4100e19c]に移動しました

cts / genode / _build.foc_cubieboard / kernel / fiasco.oc / fiascoの読み込み

sigma0を読み込んでいます

genode / coreの読み込み

カーネル情報ページを検索...

0x40002000のカーネル情報ページが見つかりました

リスト「regions」の地域

[40001000、400019ff] {a00} Kern cts / genode / _build.foc_cubieboard / kernel / fiasco.oc / fiasco

[40002000、40060fff] {5f000} Kern cts / genode / _build.foc_cubieboard / kernel / fiasco.oc / fiasco

[40090000、4009673b] {673c} Sigma0 sigma0

[40098000、4009e17b] {617c} Sigma0 sigma0

[40100000、4024743f] {147440}ルートgenode /コア

[41000000、410143f3] {143f4}ブートブートストラップ

[4100e000、4100e299] {29a}ルートマルチブート情報

[41100000、411e3737] {e3738}ルートモジュール

APIバージョン:(87)実験的

Sigma0構成IP:40090100 sp:41013d24

ルートタスク設定IP:4014af84 sp:00000000

カーネルcts / genode / _build.foc_cubieboard / kernel / fiasco.oc / fiascoを40001198で開始

スタートアップからこんにちは:: stage2

Boot_alloc:サイズ= 0x180

Boot_alloc:追加のメモリブロック@ 0xf13e1000(サイズ= 400)

Boot_alloc:@ 0xf13e1000

Boot_alloc:残りの空きブロック@ 0xf13e1180(サイズ= 280)

キャッシュ構成:オン

ID_PFR [01]:00001131 00000011 ID_ [DA] FR0:00000400 00000000

ID_MMFR [04]:01100003 20000000 01202000 00000211

FPU0:アーチ:VFPv3(3)、パート:VFPv3(30)、r:3、v:c、i:41、t:ハード、p:dbl / sngl

スタートアップ:: stage2終了

シリアルESC:シリアルUARTにIRQ 1を割り当て

低速タイマーハンドラーでシリアルハックを使用しない。

Fiasco.OC(arm)へようこそ!

L4 / Fiasco.OCアームマイクロカーネル1998-2013 TUドレスデン

改訂:sun4iのgcc 4.7.2でコンパイルされた8991035 []

ビルド:#3番目。 4月 18 22:48:33 MSK 2013



タイマーループを調整しています...完了。

SIGMA0:こんにちは!

KIP @ 40002000

メンテナンス構造に4KBを割り当てました

SIGMA0:すべてのリソースマップのダンプ

RAM:------------------------

[0:40000000; 40000fff]

[0:40061000; 4008ffff]

[0:40097000; 40097fff]

[0:4009f000; 400fffff]

[4:40100000; 40247fff]

[0:40248000; 4100dfff]

[4:4100e000; 4100efff]

[0:4100f000; 410fffff]

[4:41100000; 411e3fff]

[0:411e4000; 7effffff]

IOMEM:----------------------

[0:0; 3fffffff]

[0:80000000; ffffffff]



KIP @ 40002000

マジック:4be6344c

バージョン:87014444

sigma0 esp:41013d24 eip:40090100

sigma1 esp:00000000 eip:00000000

ルートesp:00000000 eip:4014af84

MBI @ 4100e000

mod [3] [4119d000,4119d1a4)config

mod [4] [4119e000,411e3738)init

mod [5] [41100000,4112bc28)hello_client

mod [6] [4112c000,41161dc0)hello_server

mod [7] [41162000,4119ce3c)タイマー

:ram_alloc:アロケーター40230784ダンプ:

ブロック:[50000000,5000001c)サイズ= 0000001c avail = 00000000 max_avail = 00000000

ブロック:[5000001c、50000038)サイズ= 0000001c avail = 00000000 max_avail = 00000000

ブロック:[50000038,50000054)サイズ= 0000001c avail = 00000000 max_avail = 00000000

ブロック:[50000054,50000070)サイズ= 0000001c avail = 00000000 max_avail = 2effff58

ブロック:[50000070,5000008c)サイズ= 0000001c avail = 00000000 max_avail = 00000000

ブロック:[5000008c、500000a8)サイズ= 0000001c avail = 00000000 max_avail = 2effff58

ブロック:[500000a8,7f000000)サイズ= 2effff58 avail = 2effff58 max_avail = 2effff58

=> mem_size = 788529152(752 MB)/ mem_avail = 788528984(751 MB)

:region_alloc:アロケーター402318f4ダンプ:

ブロック:[00001000,40000000)サイズ= 3ffff000 avail = 3ffff000 max_avail = 3ffff000

ブロック:[7f000000、bfff0000)サイズ= 40ff0000 avail = 40ff0000 max_avail = 40ff0000

ブロック:[bfff1000、c0000000)size = 0000f000 avail = 0000f000 max_avail = 0000f000

=> mem_size = 2164252672(2063 MB)/ mem_avail = 2164252672(2063 MB)

:io_mem:アロケーター40230be0ダンプ:

ブロック:[00000000,40000000)サイズ= 40,000,000 avail = 40,000,000 max_avail = 40,000,000

ブロック:[40001000,40002000)サイズ= 00001000 avail = 00001000 max_avail = 40000000

ブロック:[40003000,40061000)サイズ= 0005e000 avail = 0005e000 max_avail = 0005e000

ブロック:[40090000,40097000)サイズ= 00007000 avail = 00007000 max_avail = 0005e000

ブロック:[40098000,4009f000)サイズ= 00007000 avail = 00007000 max_avail = 80ffffff

ブロック:[7f000000、ffffffff)サイズ= 80ffffff avail = 80ffffff max_avail = 80ffffff

=> mem_size = 3238449151(3088 MB)/ mem_avail = 3238449151(3088 MB)

:io_port:アロケーター4023103cダンプ:

:irq:アロケーター40231498ダンプ:

ブロック:[00000000,00000100)サイズ= 00000100 avail = 00000100 max_avail = 00000100

=> mem_size = 256(0 MB)/ mem_avail = 256(0 MB)

:rom_fs:Rom_fs 402321a8ダンプ:

Rom:[4119e000,411e3738)init

ROM:[41100000,4112bc28)hello_client

ROM:[4119d000,4119d1a4)config

ROM:[4112c000,41161dc0)hello_server

ROM:[40002000,40003000)l4v2_kip

ROM:[40002000,40003000)キップ

ROM:[41162000,4119ce3c)タイマー

:コア範囲:アロケーター40233f08ダンプ:

ブロック:[40100000,40248000)サイズ= 00148000 avail = 00148000 max_avail = 00148000

ブロック:[41100000,411e4000)サイズ= 000e4000 avail = 000e4000 max_avail = 2f000000

ブロック:[50000000,7f000000)size = 2f000000 avail = 2f000000 max_avail = 2f000000

=> mem_size = 790806528(754 MB)/ mem_avail = 790806528(754 MB)

int main():-ローカルサービスの作成-int main():-initの開始-int main():751 MBをinitに転送

int main():-initが作成され、終了条件を待機中-[init]ファイル「ld.lib.so」を開けませんでした

[init-> hello_server] Hello :: Root_component :: Root_component(Genode :: Rpc_entrypoint *、Genode :: Allocator *):ルートコンポーネントの作成。

[init-> hello_server] virtual Hello :: Session_component * Hello :: Root_component :: _ create_session(const char *):Helloセッションを作成します。

[init-> hello_client] virtual void Hello :: Session_client :: say_hello():Saying Hello。

[init-> hello_server] virtual void Hello :: Session_component :: say_hello():私はここにいます...こんにちは。

[init-> hello_client] int main():2 + 5 = 7を追加

[init-> hello_client] virtual void Hello :: Session_client :: say_hello():Saying Hello。

[init-> hello_server] virtual void Hello :: Session_component :: say_hello():私はここにいます...こんにちは。

[init-> hello_client] int main():2 + 5 = 7を追加

...



ご覧のとおり、マイクロカーネルを新しいアーキテクチャに移植することはまったく難しくありません。 もちろん、上で書いたように、実際のプロジェクトで小核を使用するには、すべてがプラットフォームハードウェアのサポートに依存します。 たとえば、PandaboardおよびGumstix Overoに基づいたデバイスのプロトタイプを作成する場合、GPIO、UART、SPI、I2Cなどの多くのドライバーを追加する必要がありました。 これらのインターフェイスは、LCD、タッチスクリーン、およびスマートカードリーダーで動作するために必要でした。 CunodeboardをGenodeのミニPCとして使用するには、少なくともフレームバッファー、USB、イーサネットのドライバーを作成(またはポート)する必要があります。



Genode Labsは、そのフレームワークに基づいて最新のOSを構築することを計画しており、自信を持ってこの方向に進んでいます。 これは、代替OSに関連する非常に興味深いオープンソースプロジェクトです。 Genodeはリソースをそれほど要求しません。私の意見では、ARMアーキテクチャに基づくシングルボードPCは、このOSの安価なプラットフォームの1つとして使用される可能性があります。



さらに、Genodeはコンピューターサイエンスの学習に最適であり、学生で興味をお持ちの場合は、ぜひご参加ください。 これを行うには、最初の3つの講義( 1、2、3 )を見て、それらのタスクを完了する必要があります。 ソリューションをGithubに投稿し、edu @ ksyslabs.orgにリンクを送信する必要があります。



All Articles