web-dev-qa-db-ja.com

クロスコンパイルJavaアプリを直接実行するARM

注意してください:この例ではARM SAM3X8Eを使用していますが、これを具体例として使用しているだけなので、この質問に対する答えは簡単に得られます。 AVRなどの他のMCUを使用する.

crazy質問があります。実際には、それは何よりも低レベルのコンピュータアーキテクチャに関する私の知識を確認することに関するものであり、必ずしも実際に実行しようとするものではありません。

LinuxまたはWindowsマシンでJavaアプリを作成し、そのアプリを直接フラッシュできるイメージにクロスコンパイルすることに関するプロセスとツールを理解することに興味があります。 ARM SAM3X8EなどのMCU。

なぜ私がこれをしたいのでしょうか、それは正気な人の最初の反応でしょう。再び:

  • この質問は、何よりも、低レベルのプログラミング/コンピュータアーキテクチャに対する私の理解を確認/明確にすることに関するものです。 しかし
  • Oneこれを行う考えられる理由は、私がいるシナリオです。 MCU/ARMチップでアプリケーション(Linuxボックスなどではない)を実行することはできますが、アプリケーションが非常に複雑であるため、Cで記述して保守するのは非常に困難です。しかし、Javaでは、強力な構文、データ構造、および活用できるサードパーティのライブラリ/ OSSコンポーネントの大規模なエコシステムを備えているため、アプリの作成がはるかに簡単になります。

上記のユースケースに確信が持てない場合でも(理由については興味があります)、私はstillに興味があります。どのようにしてそのような解決策が力ずくで強制されることができるか。

ヘルプ/ガイダンスなしで解決策をまとめる必要がある場合は、次のようにします。

  • 自分のJVMをCで実装する(笑)
  • 最終的にJavaアプリは入力データ(バイトコード)としてJVMに供給されます)。したがって、このカスタムJVMのソースコードは、特定の入力ファイルを探してバイトコードを読み取るためにハードコードする必要があります。この入力ファイルをbytecode_input.cと呼びます。
  • Javaバイトコード(javacによって生成された)を取り、それをbytecode_input.cに変換したある種のクロスコンパイラが必要になります。このようにして、カスタムJVMをコンパイルすると、私のアプリのバイトコードは、結果のJVM実行可能ファイルに統合されます。
  • カスタムJVMを作成するには、Cコードで特定のシステムコールを実装する必要があるため、アプリケーションがFileWriterを使用してファイルに書き込むと、JVMはどのシステムコールを実行するかを認識します。
  • ここで、JVMのコンパイルの出力がMCUにフラッシュできるものであることを確認する必要があります。

私が何かを見逃していない限り(ここでも、上記の手順は決して簡単なものではなく、それぞれが作成に数人年かかる可能性があることを理解している場合)、それで十分だと思います。基本的に、私はJavaでアプリを作成し、バイトコードにコンパイルし、bytecode_file_generatorを介して実行し、bytecode_input.cという名前のCファイルに変換します。次に、そのCファイルは、JVMの残りの部分(標準のJVMが持つすべて、GC、メモリ管理、バイトコード検証、クラスローダーなどを含む)でコンパイルされ、MCUにフラッシュできる実行可能ファイル/イメージを生成します。

bytecode_input.cが不思議で曖昧なように見える場合、これが私の意味するCの擬似コードです。

// This C file simply defines a variable called 'bytecode'
// which contains a static/hardcoded table of all the app's bytecode:
int[] BYTECODE = new int[SIZE_OF_CLASS_FILE] {
    103, 1929, 1939, 549, 9939,
    3949, 3949, 20304, 28, 238
};

次に、JVMは、通常のJVMのように実行時にBYTECODEをハードコードされた入力として読み取ります。

通常、JVMはOS上で実行されます。 MCUはプログラムをベアメタルで実行するため、OSについて心配する必要はありません。RTOSのような機能が必要な場合は、それをカスタムJVMに組み込むことができます。

Icould(私はそう思う)アプリのJavaソースをCに変換する非常に賢いクロスコンパイラーを作成するだけです)カスタムJVMの関与をすべてスキップしますが、JVMが提供するすべての優れた機能(GC、メモリ管理など)を失うことになります。

だから私の質問:あなたが魔法の「Ok、私は今のところ有効なユースケースとしてこれを受け入れます...」ボタンを押すことができると仮定すると、ここでの私のアプローチは根本的に間違っていますか?主要なステップ/プロセスを見落としていないか?

4
smeeb

LLVMを使用して、ターゲットのJavaをバイナリにコンパイルできます。ドキュメントをざっと見ると、多くのARM=バリアントのサポートが示されています。

https://llvm.org/svn/llvm-project/Java/trunk/docs/Java-frontend.txt

また、この静脈の別のスタックオーバーフロースタイルの答えは、

https://stackoverflow.com/questions/10804280/is-there-a-llvm-Java-front-end-that-c​​onverts-Java-source-to-llvms-intermediate

2
Tim Williscroft