まず、BLDKはEDKIIがベースになってます。以前に弄ってたEDKとはモジュールの扱いの流儀がちょっと違うようで、まだよくわかってません。なので、EDKIIのモジュール作成方法について調べてみます。
EDKIIのドキュメントは以下からゲットします。
http://sourceforge.net/projects/edk2/files/General%20Documentation/
http://sourceforge.net/projects/edk2/files/Specifications/
なんだか読み物がたくさんありますが、さしあたって、EDKII Module Writer_s Guide_0_7.pdfをざっくり眺めてみました。
まだ、完全に内容を理解できてないですが、まずドライバやアプリのモジュールを作成するにはxxxxPkgとかって名前でディレクトリを作って、複数のモジュールをまとめておくパッケージを作成することになってるようです。
んで、そのパッケージにはDECとDSCファイルというパッケージの定義やビルドの挙動を記述したファイルを作成することになってるっぽいです。あと、FDFファイルというのもあって、これは、フラッシュ(ROMイメージ)に何を含めるかということを記述するようです。これは全てのモジュールに必要ではなくて、最終成果物としてROMイメージを出力したいモジュールだけ必要になるようです。
そして、パッケージの中にドライバ等のモジュールを(必要なだけ複数でも)作成することになってて、DXEドライバならxxxxDxeとかっていうフォルダにするのがお勧めみたいです。このフォルダにソースコードやバイナリモジュールならバイナリを置くわけですが、それぞれのモジュールにINFファイルというのを作成する必要があるようです。
なんだか、DECやらDSCとかFDFとかINFとか複雑なことになってますが、ビルド時にこれらのメタデータを元にmakefileが自動生成されるようです。EDKIIでは以前のEDKと違い、ビルド環境が、クロスプラットフォームで、複数のコンパイラやビルドシステム、OSに対応しているため、こんなことになってるっぽいです。
あと、PCDなる機構があって、これをうまくつかうことで、メタデータから定数や機能のON/OFFをコントロールできる仕組みが用意されているようです。
で、これらメタデータの記述ルールに関しては別途Specificationのドキュメントが個々に用意されているのですが、まだ全部目を通せていません。
とはいえ、ドキュメント読んでばかりだと、つまらないので、とにかくなんか作ってみてみます。そのほうが理解も早いしね。
そんなわけで、今回は特に何もしてくれないテストドライバを適当に書いてみます。目的はどっちかというとビルドシステムに慣れることですね。とりあえず、BLDKにはいくつもドライバソースが含まれているので、それらを参考にします。8254TimerDxeあたりがシンプルな構造で参考になりました。
で、ごにょごにょ試行錯誤しつつ以下のコードを書いてみました。
//
// TestDriver.c
//
#include "TestDriver.h"
EFI_GUID gEfiTestDriverProtocolGuid = EFI_TEST_DRIVER_PROTOCOL_GUID;
EFI_HANDLE mTestHandle = NULL;
//
// driver produces
//
EFI_TEST_DRIVER_PROTOCOL mTest = {
TestDriverFunction
};
EFI_STATUS
EFIAPI
TestDriverFunction (
)
{
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
TestDriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
//
// Install the Test Driver Protocol onto a new handle
//
return gBS->InstallMultipleProtocolInterfaces (
&mTestHandle,
&gEfiTestDriverProtocolGuid,
&mTest,
NULL
);
}
//
// TestDriver.h
//
#ifndef __TEST_DRIVER_H__
#define __TEST_DRIVER_H__
#include <Library/UefiBootServicesTableLib.h>
#include "TestDriverProtocol.h"
EFI_STATUS
EFIAPI
TestDriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
EFI_STATUS
EFIAPI
TestDriverFunction (
);
#endif
//
// TestDriverProtocol.h
//
#ifndef __TEST_DRIVER_PROTOCOL_H__
#define __TEST_DRIVER_PROTOCOL_H__
#define EFI_TEST_DRIVER_PROTOCOL_GUID \
{ 0x8d37d58, 0x8c26, 0x4e39, { 0x92, 0xf3, 0x14, 0x97, 0x89, 0x5f, 0x60, 0x63 } }
typedef
EFI_STATUS
(EFIAPI *EFI_TEST_DRIVER_FUNCTION)(
);
typedef struct _EFI_TEST_DRIVER_PROTOCOL {
EFI_TEST_DRIVER_FUNCTION TestFunction;
}EFI_TEST_DRIVER_PROTOCOL;
extern EFI_GUID gEfiTestDriverProtocolGuid;
#endif
#
# TestDriver.inf
#
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = TestDriver
FILE_GUID = CD5E357E-94D9-484d-BA43-CB632FC50C03
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 0.1
ENTRY_POINT = TestDriverEntryPoint
[Packages]
MdePkg/MdePkg.dec
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
[LibraryClasses]
UefiDriverEntryPoint
UefiBootServicesTableLib
UefiLib
[Sources]
TestDriverProtocol.h
TestDriver.h
TestDriver.c
[Protocols]
[Depex]
TRUE
で、DECやDSCも必要かと思いきや、どうやらパッケージ単体でビルドする場合は必要っぽいですが、この場合BLDKのROMイメージを作成するので、ビルド対象がCrownBayPlatformPkgになります。なので、このパッケージのDSCとFDFの適当な所にTestDriver.infへのパスを書いておけばビルドされるぽいです。ほんとはルールに則ってパッケージ毎にあったほうがいいんでしょうけどね。
で、ビルドは通ったものの、何もしないドライバなので、動かしても何も起きないです。ふんにゃかです。
でもまあ、パッケージ作成の理解は進んだし、概ね雰囲気も掴めてきたので、良しとします。来週はシリアルドライバ作成に着手したいところです。
週一の開発ペースだと、ボリュームの大きめな課題は中々進まないですねえ。ちまちまがんばります。
今週はここまでっす。
0 件のコメント:
コメントを投稿