OSのブートローダーを作成しようと思いUEFIでhello worldを表示させるプログラムをDELPHIに移植できないかと思い挑戦してみましたがだめでした。
以下のコードを直して出来上がるものか、それとも全然ダメかそれすらもよくわかりません。ご検討よろしくお願いいたします。
参考にしたのは
URL>>http://d.hatena.ne.jp/shina_ecc/20140819/1408434995
library BOOTX64;
{$SETPESUBSYSVERSION <10>}
const
EFI_SUCCESS = 0;
type
EFI_STATUS = UInt64;
EFI_HANDLE = Pointer;
Pefi_protocol = ^EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
EFI_TEXT_STRING = function(This: Pefi_protocol; Str: PChar): EFI_STATUS; stdcall;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL = record
public
a: Pointer;
OutputString: EFI_TEXT_STRING;
end;
EFI_SYSTEM_TABLE = record
public
a: array [0 .. 51] of Byte;
ConsoleOutHandle: EFI_HANDLE;
ConOut: Pefi_protocol;
end;
function Efi_Main(ImageHandle: EFI_HANDLE;
SystemTable: EFI_SYSTEM_TABLE): UInt64; stdcall;
begin
SystemTable.ConOut^.OutputString(SystemTable.ConOut, 'hello, world');
while True do;
result := EFI_SUCCESS;
end;
exports
Efi_Main;
end.
Efi_Mainの第2パラメータがポインタになってないのが気になりますね…
編集 削除アドバイスに感謝します
ただ、ご指摘の点も検討してみましたが解決には至りませんでした。
今後は解決済みを入れず様子を見守る展開になりそうです。
鋭意努力します。
目標はDELPHIによるスクラッチOSの作成ですからじっくり考えます。
もう一つ気がついたところを(五月雨式で申し訳ない
EFI_SYSTEM_TABLEのメンバのアライメント、合ってますか?4バイトアライメントならaが要素数52でも不思議じゃないんですけど、
8バイトアライメントだとaが52でも56でも変わらないというか、実質56になっちゃってるのでは。こういう場合はpacked recordに
して、アライメントを全てコードで合わせるほうがいいと思います。あとSizeOfで最終的な構造体のサイズを取ってチェックしたほうが。
{$IF SizeOf(EFI_SYSTEM_TABLE) <> 68}
{$MESSAGE WARN 'SizeOf(EFI_SYSTEM_TABLE) is not 68'}
{$IFEND}
とかしておくとコンパイル時にチェックできていいですよ。
packed修飾子にそのような仕組みがあったとはしりませんでした。私はOS自作の本を読んでいた関係でなんとかアラインメントをイメージできたので取り入れてみます。
元ネタのサイトでは
DLLを作成
OBJCOPYでSUBSYSTEMを10
あとSTDCALLで関数を定義して
エントリポイントをEXPORTSでEfi_Mainにしてあります。
ポイントは抑えたのですが実際にはそれではできません。
(PACKEDを使うと配列が遅くなるというのだけ頭に入れてました。)
(解決ではなく状況継続なら現状のソースを再提示しておかないと、これ以上の回答はつかないと思いますよ…
編集 削除