Day 131 - UEFI Shellで動くQuine書いた
この記事はQuine Advent Calendar 2014の131日目です。
概要
wikipedia:UEFIというのはBIOSの後継のOSをブートさせる仕組みです。最近のパソコンは大体これになってます。
BIOSよりも柔軟で色々なことができて、UEFI Shellというシェルっぽいものを起動させることもできます。
で、そのUEFI Shell上で動作するQuineを作りました。
もはやQuineするのにOSはいりませんね。
動かし方
リポジトリの方に結構詳しく書いておいたので、そっち見てください。
‥‥すみません。一応、大ざっぱに説明します。
まず64bitでUEFIなPCと適当なUSBを用意します。USBの中身は予めFAT32にフォーマットしておいてください。
次に、USBのルートにEFI\Boot
という風にディレクトリを作って、その中にbootx64.efi
という名前でShell_Full.efi
を配置してください。Shell_Full.efi
というのはUEFI Shellのバイナリで、https://github.com/tianocore/edk2/tree/master/EdkShellBinPkg/FullShell/X64あたりから落としてこれます。
その後、どこでもいいのですけど、とりあえずUSBのルートにでもQuine.efi
を配置してください。これがQuineの本体になります。Quine.efi
はhttps://github.com/MakeNowJust/efi-quine/releases/tag/v1.0から落とせます。
ここまでの準備ができたら、PCを再起動してUSBからUEFI Shellを起動してください。多分Deleteキーを連打するとUEFIのメニューに入れるので、そこから起動します。
で、起動したらUEFI ShellでUSBの中身のところに移動して、そこでQuine.efi
を実行します。するとEFI QuineのAAが表示され、Quine.c
,Quine.inf
,QuinePkg.dec
,Quine.dsc
,target.txt
が生成されます。これらのファイルはQuine.efi
のビルドに必要なファイルです。
あとは普通にOSを起動して、diff
とかでリポジトリにあるQuine.c
と生成されたQuine.c
を比較して楽しみましょう。楽しい✌ ('ω' ✌ )三 ✌ ('ω') ✌ 三( ✌ 'ω') ✌
つらかったところ
VirtualBoxとかでもUEFIブートできるらしいんだけど調べるのが面倒だったのでずっと実機で開発し続けた結果膨大な時間を消費しました。一度Quine.efi
をビルド→再起動→UEFI Shellから実行、というフローは効率が悪すぎる。一つのQuineに8時間とか9時間とか、Quine Advent Calendarではまったく笑えません。
また、どうして画面に表示するのではなくファイルを生成するようにしているのかというと、単に画面に出力しようとするとUTF-16 LEでしか出力することができなかったからです。そのくせEDK2の設定ファイル系(Quine.inf
とか)はUTF-8なのですね。一度、諦めてUTF-16で出力して、Quineのあとで変換する作りにしようかな、と思ったのですが、それでもBOMが邪魔だったので妥協せずUTF-8で出力するようにしました。複数ファイルを生成しているのは「Quineはself-containedであれ」というid:ku-ma-me氏の言葉(だったと思う)に従った結果です。
他にも、ファイル出力の際に無効なメモリを参照して落ちたりとか、よく分からないバグかなり戦った気がします。UEFIは比較的簡単に開発できて楽しいのですが、デバッグに辛いものがある気がします。というかEDKはドキュメントが無さすぎです。コード読むしかありません。
いや、それでも楽しいんですけどね。
最後に
最後まで読んでいただきありがとうございました。