简体   繁体   中英

How to read LBA (UEFI)

I wanted to list the content of the root directory in UEFI, but I didn't find any protocol to do that; therefore I wanted to print the content of the directory file, but the EFI_FILE_PROTOCOL can't read direcory files. The only other thing that I can do is to read the disk sector which contains that information, but the EFI_BLOCK_IO_PROTOCOL returns 0x02 .

Here is the code:

#include <efi.h>
#include <efilib.h>

EFI_STATUS
efi_main(EFI_HANDLE Image, EFI_SYSTEM_TABLE* Systab)
{
    EFI_LOADED_IMAGE_PROTOCOL* LoadedImage;
    EFI_BLOCK_IO_PROTOCOL* BlockIO;
    UINT16* Buffer;
    EFI_STATUS Status;

    InitializeLib(Image, Systab);
    Status = uefi_call_wrapper(BS->HandleProtocol, 3,
                                Image,
                                &gEfiLoadedImageProtocolGuid,
                                &LoadedImage);
    if(Status != EFI_SUCCESS) {
        Print(L"HandleProtocol() failed [0]\n");
    }
    Status = uefi_call_wrapper(BS->HandleProtocol, 3,
                                LoadedImage->DeviceHandle,
                                &gEfiBlockIoProtocolGuid,
                                &BlockIO);
    if(Status != EFI_SUCCESS) {
        Print(L"HandleProtocol() failed [1]\n");
    }

    Status = uefi_call_wrapper(BlockIO->ReadBlocks, 5,
                                BlockIO,
                                BlockIO->Media->MediaId,
                                (EFI_LBA)1,
                                BlockIO->Media->BlockSize,
                                Buffer);
    if(Status != EFI_SUCCESS) {
        Print(L"Failed to read disk with code 0x%x\n", Status);
    }
    else for(int i = 0; i < 512; i++) {
        Print(L"%c", (CHAR8)Buffer[i]);
    }

    return EFI_SUCCESS; 
}

Can you spot what I did wrong?

UINT16* Buffer;

What's this? An uninitialized pointer! You pass this to ReadBlocks() , then you got an error. Your Buffer should be defined like this:

UINT8 Buffer[512];

By the way, the correct way to list files in a directory is to use EFI_FILE_PROTOCOL.Read() . The UEFI Specification says:

If This is a directory, the function reads the directory entry at the file's current position and returns the entry in Buffer . If the Buffer is not large enough to hold the current directory entry, then EFI_BUFFER_TOO_SMALL is returned and the current file position is not updated. BufferSize is set to be the size of the buffer needed to read the entry. On success, the current position is updated to the next directory entry. If there are no more directory entries, the read returns a zero-length buffer. EFI_FILE_INFO is the structure returned as the directory entry.

Here is the code example (error handling is ignored)

#include <efi.h>
#include <efilib.h>

#define FILE_BUFFER_SIZE 4096

EFI_STATUS efi_main(EFI_HANDLE *ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
    InitializeLib(ImageHandle, SystemTable);

    EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
    EFI_FILE_PROTOCOL *RootDir;
    UINT8 Buffer[FILE_BUFFER_SIZE];
    UINTN BufferSize;
    EFI_FILE_INFO *FileInfo;

    // clear screen
    uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);

    // open the filesystem
    uefi_call_wrapper(BS->LocateProtocol, 3, &FileSystemProtocol, NULL, &FileSystem);

    // open the root directory
    uefi_call_wrapper(FileSystem->OpenVolume, 2, FileSystem, &RootDir);

    while (TRUE) {
        BufferSize = sizeof(Buffer);

        // read one directory entry
        uefi_call_wrapper(RootDir->Read, 3, RootDir, &BufferSize, Buffer);

        // stop reading when there are no more entries
        if (BufferSize == 0) {
            break;
        }

        // cast and print the filename
        FileInfo = (EFI_FILE_INFO *)Buffer;
        Print(L"%s\n", FileInfo->FileName);
    }

    // close the root directory
    uefi_call_wrapper(RootDir->Close, 1, RootDir);

    Pause();

    return EFI_SUCCESS; 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM