ゼロからのOS自作入門 読みメモ 2章 その5
その4の続き
EFI_MEMORY_DESCRIPTOR構造体
/// /// Definition of an EFI memory descriptor. /// typedef struct { /// /// Type of the memory region. /// Type EFI_MEMORY_TYPE is defined in the /// AllocatePages() function description. /// UINT32 Type; /// /// Physical address of the first byte in the memory region. PhysicalStart must be /// aligned on a 4 KiB boundary, and must not be above 0xfffffffffffff000. Type /// EFI_PHYSICAL_ADDRESS is defined in the AllocatePages() function description /// EFI_PHYSICAL_ADDRESS PhysicalStart; /// /// Virtual address of the first byte in the memory region. /// VirtualStart must be aligned on a 4 KiB boundary, /// and must not be above 0xfffffffffffff000. /// EFI_VIRTUAL_ADDRESS VirtualStart; /// /// NumberOfPagesNumber of 4 KiB pages in the memory region. /// NumberOfPages must not be 0, and must not be any value /// that would represent a memory page with a start address, /// either physical or virtual, above 0xfffffffffffff000. /// UINT64 NumberOfPages; /// /// Attributes of the memory region that describe the bit mask of capabilities /// for that memory region, and not necessarily the current settings for that /// memory region. /// UINT64 Attribute; } EFI_MEMORY_DESCRIPTOR;
- Type
- メモリ領域の種別
- PhysicalStart
- メモリ領域先頭の物理メモリアドレス
- VirtualStart
- メモリ領域先頭の仮想メモリアドレス
- NumberOfPages
- メモリ領域の大きさ
- Attribute
- メモリ領域が使える用途を示すビット集合
メモリマップ構造体
struct MemoryMap {
UINTN buffer_size;
VOID* buffer;
UINTN map_size;
UINTN map_key;
UINTN descriptor_size;
UINT32 descriptor_version;
}
メモリマップのファイルへの保存
Main.c
のメモリマップのファイルへの保存部
CHAR8 memmap_buf[4096 * 4]; // メモリマップを確保 struct MemoryMap memmap = {sizeof(memmap_buf), memmap_buf, 0, 0, 0, 0}; GetMemoryMap(&memmap); // メモリマップを取得、gBS->GetMemoryMapに値が入る EFI_FILE_PROTOCOL* root_dir; OpenRootDir(image_handle, &root_dir); // 書き込み先のファイルを開く。存在しなければ新規作成。これはルートディレクトリを開いている。 EFI_FILE_PROTOCOL* memmap_file; root_dir->Open( root_dir, &memmap_file, L"\\memmap", // root_dir を開いている。ファイル名はmemmap EFI_FILE_MODE_READ | EFI_FILE_MORE_WRITE | EFI_FILE_MORE_CREATE, 0); // 読み|書き|作成モードでオープン SaveMemoryMap(&memmap, memmap_file); // ここで取得したメモリマップを保存する memmap_file->Close(memmap_file); // ファイルを閉じる
以下追ったコード
- EFI_FILE_PROTOCOL
/// The EFI_FILE_PROTOCOL provides file IO access to supported file systems. /// An EFI_FILE_PROTOCOL provides access to a file's or directory's contents, /// and is also a reference to a location in the directory tree of the file system /// in which the file resides. With any given file handle, other files may be opened /// relative to this file's location, yielding new file handles. /// struct _EFI_FILE_PROTOCOL { /// /// The version of the EFI_FILE_PROTOCOL interface. The version specified /// by this specification is EFI_FILE_PROTOCOL_LATEST_REVISION. /// Future versions are required to be backward compatible to version 1.0. /// UINT64 Revision; EFI_FILE_OPEN Open; EFI_FILE_CLOSE Close; EFI_FILE_DELETE Delete; EFI_FILE_READ Read; EFI_FILE_WRITE Write; EFI_FILE_GET_POSITION GetPosition; EFI_FILE_SET_POSITION SetPosition; EFI_FILE_GET_INFO GetInfo; EFI_FILE_SET_INFO SetInfo; EFI_FILE_FLUSH Flush; EFI_FILE_OPEN_EX OpenEx; EFI_FILE_READ_EX ReadEx; EFI_FILE_WRITE_EX WriteEx; EFI_FILE_FLUSH_EX FlushEx; };
サポートされているファイルシステムへのファイルIOアクセスを提供している
- OpenRootDir
Main.c
で定義したOpenRootDir
EFI_STATUS OpenRootDir(EFI_HANDLE image_handle, EFI_FILE_PROTOCOL** root) { EFI_LOADED_IMAGE_PROTOCOL* loaded_image; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* fs; // handle のチェック gBS->OpenProtocol( image_handle, &gEfiLoadedImageProtocolGuid, (VOID**)&loaded_image, image_handle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); gBS->OpenProtocol( loaded_image->DeviceHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID**)&fs, image_handle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); // root を開く fs->OpenVolume(fs, root); return EFI_SUCCESS; }
- EFI_OPEN_PROTOCOL
/** Queries a handle to determine if it supports a specified protocol. If the protocol is supported by the handle, it opens the protocol on behalf of the calling agent. ... **/ typedef EFI_STATUS (EFIAPI *EFI_OPEN_PROTOCOL)( IN EFI_HANDLE Handle, IN EFI_GUID *Protocol, OUT VOID **Interface, OPTIONAL IN EFI_HANDLE AgentHandle, IN EFI_HANDLE ControllerHandle, IN UINT32 Attributes );
handleが指定されたプロトコルをサポートしているかどうかを判別する
- OpenVolume
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume;
/** Open the root directory on a volume. ... **/ typedef EFI_STATUS (EFIAPI *EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME)( IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, OUT EFI_FILE_PROTOCOL **Root );
rootディレクトリを開く
- EFI_FILE_OPEN
/** Opens a new file relative to the source file's location. ... **/ typedef EFI_STATUS (EFIAPI *EFI_FILE_OPEN)( IN EFI_FILE_PROTOCOL *This, // ファイルを開く場所 OUT EFI_FILE_PROTOCOL **NewHandle, // 開いたファイル? IN CHAR16 *FileName, // 開くファイルの名前 IN UINT64 OpenMode, // 作成読み書きのモード指定 IN UINT64 Attributes );
指定したファイルを開く
- EFI_FILE_CLOSE
/** Closes a specified file handle. ... **/ typedef EFI_STATUS (EFIAPI *EFI_FILE_CLOSE)( IN EFI_FILE_PROTOCOL *This );
指定したファイルを閉じる
ペース遅いけどSaveMemoryMap次追います