PDF中でLinuxをブートしてる?
PDFといえば、「静的なドキュメント」のイメージが強いが、実はPDFにはJavaScriptを埋め込める仕組みがあり、しかもその機能を使って「PDFの中でOSをエミュレートして起動」させることまでできてしまう。このちょっと変わった試みを通じて、PDFフォーマットの意外な可能性について見ていく。
PDFとJavaScriptの関係
PDFはAdobe が提唱したフォーマットであり、Acrobatの世界ではフォームの入力チェックやダイアログ表示などを行うためのJavaScript APIが豊富に定義されている。
しかしブラウザ(Chromium やFirefox など)に搭載されているPDFエンジンでは、セキュリティ の理由からそのAPIのごく一部しか実装されていない。
それでも、テキストフィールドへの書き込みやボタンイベントの取得など、最低限の機能は使えるため、その範囲で相当凝った仕組みを作ることが可能である。
asm.jsでエミュレーションを実現
今回のキモとなるのは、C言語をEmscripten というコンパイラを使ってasm.js に変換するという手法だ。
WebAssembly (WASM) ではなく、あえてasm.jsを選ぶのは、ブラウザのPDFプラグイン(特にChromium系)でJITが無効化されている関係もある。JITが使えない環境だとWASMはもちろんasm.jsでも重くなるが、まだasm.jsのほうが動かしやすい場合があるのだという。
TinyEMUでLinuxをブート
実際にPDFの中で動かされているのは、TinyEMU という軽量のRISC-V エミュレータだ。これをasm.jsにコンパイルしPDF内のJavaScriptとして実行することで、Linuxを起動するという仕組みになっている。
エミュレータの描画は、PDF内のテキストフィールドにASCII アートのように文字を並べて疑似的な画面を実装し、キーボード入力は複数のボタンやテキストボックスを活用して行う。かなり力技だが、ちゃんとブートプロセスが可視化され、簡単なコマンド入力も可能である。
パフォーマンスの課題
最大の問題は、パフォーマンス が極端に落ちることである。ChromeのPDFエンジンはJITコンパイラ が完全にオフになっているため、asm.jsのコードが数十倍以上遅く動作してしまう。結果として、Linuxのブートには30〜60秒ほどかかり、さらに64bit版を使う場合は2倍以上の時間を要する。実用レベルとは言いがたいが、「本来は静的な文書であるPDFでOSを起動する」というデモとしては、かなりインパクトがある。
まとめ
PDFにはJavaScript を埋め込む余地があり、そこにエミュレータ を仕込むことで、Linuxを起動させることが可能である。
ブラウザのPDFリーダーはAPIが厳しく制限されており、セキュリティ 上の理由でJITコンパイルも使えないことが多いため、パフォーマンスは非常に低い。
それでも、このような「意外な場所でOSを動かしてしまう」というアイデアは素晴らしい。