ここまで読んでいただき、本当にありがとうございます!
ここまで、UEFIでのベアメタルプログラミングの方法について説明しました。「やればできそうだ」と思ってもらえたら嬉しいです。
UEFIはかしこいです。色々な機能を持っていて、色々な事をやってくれます。仕様書の目次を眺めていると、「こんなこともファームウェア側でやってくれるのか」と驚きます*1。また、ソフトウェアの中で最も下のレイヤー*2を扱っているにも関わらず、メモリマップを説明せずに済んでいる事はすごいことです。
[*1] メモリアロケータを持っているのは個人的に驚きでした。
[*2] もちろん、厳密にはより下にファームウェアがありますが。
"はじめに"でも書きましたが、本書のコンセプトには、「UEFIファームウェアの機能をラップしていくだけでOSっぽいものが作れるんじゃ?」という思いがあります。中でも、ファイルシステムの機能をファームウェアが持っているのは強力です。フルスクラッチでOS自作を始めようと考えている人が居れば、UEFIで始めるのも良いんじゃないかなと思います。
最後に、バイナリ短歌で終わりたいと思います(コードリストformat_number_without_header、バイナリリストformat_number_without_header)。サンプルコードのディレクトリは"sample_tanka"です。
1: #define CONOUT_ADDR 0xa3819590 2: #define OUTPUTSTRING_ADDR 0xa387e1b8 3: 4: .text 5: .globl efi_main 6: efi_main: 7: /* OutputString第1引数(ConOut)をRCXへ格納 */ 8: movq $CONOUT_ADDR, %rcx 9: /* OutputStringのアドレスをRAXへ格納 */ 10: movq $OUTPUTSTRING_ADDR, %rax 11: /* ".ascii"のアドレスをRDXへ格納 */ 12: leaq msg, %rdx 13: /* OutputStringを呼び出す */ 14: callq *%rax 15: 16: /* 無限ループ */ 17: jmp . 18: 19: .data 20: msg: 21: /* "ABCD" */ 22: .ascii "A\0B\0C\0D\0\0\0" 23: /* "すごーい" */ 24: /*.ascii "Y0T0\3740D0\0\0"*/ 25: /* ボス */ 26: /*.ascii "\326\0\0\0"*/
1: 0000000000401000 <efi_main>: 2: 401000: 48 b9 90 95 81 a3 00 movabs $0xa3819590,%rcx 3: 401007: 00 00 00 4: 40100a: 48 b8 b8 e1 87 a3 00 movabs $0xa387e1b8,%rax 5: 401011: 00 00 00 6: 401014: 48 8d 14 25 00 20 40 lea 0x402000,%rdx 7: 40101b: 00 8: 40101c: ff d0 callq *%rax 9: 40101e: eb fe jmp 40101e <efi_main+0x1e>
ここまで読んでいただき、本当にありがとうございました。