LinuxとベアメタルOSの同時発売

最近、BSDライセンスの下で8キロ行のCコードの小さなプロジェクトをネットワークに投稿しました。 公式には、これは私の顧客である産業オートメーションのベンダー向けのベンチマークのコレクションです。 コードは非常に具体的であり、一見すると、PLCとモーション制御の狭い領域以外ではほとんど適用できません。 しかし、小さなハイライトがありますが、IDZの記事ではあまり注目していません。 ベンチマークの配信には、実行のためのベアメタル環境が含まれていました。 この投稿では、それが何であり、どのように使用できるかを説明します。



ベアメタルOSとは何ですか? これは、カーネル/カーネルを初期化し、ユーザープログラムに制御を移す小さなコードです。何らかの理由で、通常のOSやRTOSなしでも実行する必要があります。 当然、このプログラムのコードでは、必要なすべてのデバイスのライブラリとドライバーを静的にリンクする必要があります...Habréのこの春には、ベアメタルOSの作成に関する一連の記事が既にありました。 したがって、私は自分自身を繰り返さず、ロード手順を説明しません。 ただし、この投稿を完全に理解するには、そのシリーズの2つの重要な記事を読み直すことをお勧めします。 これは、GRUBから直接OSの代わりに任意のプログラムをビルド、ダウンロード、実行する方法を説明しています。 そして、複数のコアで一度にコードを実行する方法を次に示します。 BranJames Molloyの英語の主要なソース( osdevと最も有名な例)のチュートリアルもお勧めします。



2番目の記事では、新しいカーネルの初期化コードを実行する方法について詳しく説明しています。 これを行うには、Init IPI(Inter-Processor-Interrupt)を送信し、さらに2つのStartup IPIを送信します。 IPI転送は、特定の物理アドレスに数バイトを書き込むだけで開始されます。 しかし、小さなLinuxユーザーモードブートローダー(特定のアドレスにバイナリをコピーし、このバイナリで起動するために他のカーネルにInit IPI 2xSIPIを送信するプログラム)を作成するとどうなりますか?



カーネルパニックが発生すると思いますか? 実際、このカーネルでは、Linuxはすでにユーザープロセス、アイドルプロセス、または割り込みを実行しています。 実際、すべてが一度に落ちるわけではありませんが、システムは不安定に動作し始め、すぐにフリーズします。 また、カーネルを1つだけ使用してLinuxをブートした場合、または実行中のシステムで残りのカーネルをオフラインにした場合はどうなりますか? (たとえば、次のように:

$ sudo echo 0 > /sys/devices/system/cpu/cpu1/online





そして、0を除くすべてのコアに対して繰り返します。



この場合、タスクスケジューラとの競合を恐れることはできません。 しかし、Linux mmはすでに起動時に利用可能なすべての物理メモリをバケットに切り刻み、それを独自のものであると正しく考えています。 幸いなことに、ここで作業ラウンドがあります。 2つでも-少し連続した物理メモリを丁寧に要求するカーネルモジュールを作成し、リンカーのスクリプトを変更して、バイナリの.textおよび.data領域をこのメモリに配置できます。 そして、あなたはそれをさらに簡単にすることができます-ブート時に特定のアドレスで物理メモリのビットを予約するようLinuxに依頼してください。 たとえば、オプションmemmap = 0x80M $ 0x18000000でカーネルをロードすると、OSはアドレス0x18000000から始まる128メガバイトの連続した物理メモリを割り当てます。 残念ながら、3.1のLinuxカーネルは、このオプションを使用してブートの最初にクラッシュすることがあります。 今、私はただ理由を見つけようとしています。



Voilà、今では複数のカーネルでLinuxを、他のすべてのユーザーで任意のベアメタルプログラムを使用できます。 しかし、これはどのように役立つのでしょうか? OSなしでコードを実行するタスクがすでにあるとします。 たとえば、異なるx86プラットフォームで実行し、平均コード実行時間と最悪時間の間の広がりを測定するベンチマークが必要でした。 x86は決して決定要因ではありませんが、オペレーティングシステムを追加すると...コンパクトで機敏なRTOSであっても、レイテンシとジッタがどこから来るのかはまだ明らかではありません。 さらに、各クライアントには独自のRTOSがあり、一部のクライアントはベアメタルよりも少し難しいです。 または、遅延の影響を受けやすいマイクロコントローラーからのコードがあり、これは既にOSなしで機能し、x86プロセッサーコアの1つでポートスローする必要がある場合です。 カーネルのカーネルスレッドで単にオンにし、それ以外のすべてを無効にすると、それでも中断されます。 RT-Linuxパッチを使用すると、すべての機能が向上しますが、遅延が追加され、他の有用なパッチと互換性がない場合があります。



そして、なぜブートローダー(GRUB)によってロードされるクリーンなベアメタルイメージよりもLinuxとベアメタルが一緒に優れているのでしょうか? そして、Linuxの方が便利です! Linuxホストのコマンドラインでハードウェア全体をリブートするか、シェルコマンドを2、3回だけリブートするかを比較してください。 同様に、デバッグでは、Linuxを使用すると、ベアメタルOSを完全に読み書きでき、プロセスのハードウェアを診断できます。 (もちろん、注意してください!)このアプローチにはいくつかの欠点があります。 LinuxでベアメタルOSを実行するには、IPIの送信先のカーネルのACPI IDを知る必要があります。 最初のコアの番号が0、2番目のコアの番号が1などであると考える場合、あなたは楽観主義者です。 私は非常に異なるオプションを見ました:)。 列挙を行う必要があります。これは、私が参照した投稿の1つで説明されているか、オプションを選択する必要があります。 (そして、ハイパースレッディングを忘れるのを忘れないでください!)。 別の待ち伏せは、非決定論です。 Linuxで最初のカーネル以外をすべて無効にし、その上で深刻な実行を行わない場合、ベアメタルコードを実行するカーネルのパフォーマンスに対するLinuxの影響を測定することはできません。 ただし、100%の保証はまだありません-希望する場合、または偶然に、共有リソース(キャッシュ、メモリコントローラー)を介してベアメタルコードのパフォーマンスに大きく影響する可能性があります。 たとえば、VGAコンソール(Ctrl-Alt-F1、Ctrl-Alt-F2)を切り替えて、ベアメタルOSのパフォーマンスを測定してみてください。



誰かがそれがどのように機能するかに興味がある場合、または実際にそれを使用する方法についてのアイデアを持っている場合(BSDライセンスが許可します) -IDZまたはgithubからソースをダウンロードします(そこは新鮮です)。 ベアメタルOS自体はtools / src / baremetalにあります。 最初のディレクトリ-phymemは、物理メモリを読み書きするためのツールです。 そして2つ目-smallos-実際にはランタイムです。 そこにあるものはすべてベンチマークを実行するように設計されているので、ファイルを使用してそれらを遮断する必要があります-ベンチ/ *へのリンクを捨てるだけで、smallos / MakefileからOを呼び出し、smallos / apps / mwaitTester.cのベンチマークを呼び出すコードをコードに置き換えます。 Linuxユーザーモードブートローダーはsmallos / linux_bootにあります。 頑張って



All Articles