2

I am a beginner at EDK2 tianocore.

I have EFI Shell and I want to open current USB with EFI Shell as physical disk to read and write blocks. In WinAPI I know CreateFile function with argument like "\\.\D:", ReadFile and WriteFile.

What is the analogue for EDK2? Can you give example and some useful links?

UPD 30.06.2017.

I am trying to use EFI_USB_IO_PROTOCOL to get faster IO operations with USB-flash than EFI_BLOCK_IO_PROTOCOL.

I have such code:

EFI_STATUS
USBXYZDriverBindingSupported (
 IN EFI_HANDLE Controller,
 IN EFI_DEVICE_PATH *RemainingDevicePath
 )
{
     UINT32 *OpenStatus= NULL;
     EFI_USB_IO_PROTOCOL *UsbIo;
     EFI_STATUS Status;
     EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
     CHAR16 *DevStr = NULL;
     DevStr = DevicePathToStr(RemainingDevicePath);
     //
     // Check if USB_IO protocol is attached on the controller handle.
     //
     Status = BS->OpenProtocol (
         Controller,
         &gEfiUsbIoProtocolGuid,
         (VOID**)&UsbIo,
         gImgHandle,
         Controller,
         EFI_OPEN_PROTOCOL_GET_PROTOCOL
         );

     if (EFI_ERROR (Status)) {
         return Status;
     }

     //
     // Get the default interface descriptor
     //
     Status = UsbIo->UsbGetInterfaceDescriptor(
         UsbIo,
         &InterfaceDescriptor
     );
     Print(L"%a.%d %r %s\n", __FUNCTION__, __LINE__, Status, DevStr);

     UINTN a = 512;
     UINTN *byteSize = &a;
     char *buf = AllocateZeroPool(512);
     Status = UsbIo->UsbBulkTransfer(UsbIo, 0x82, buf, byteSize, 0, OpenStatus);

     Print(L"%a.%d %r %d %d\n", __FUNCTION__, __LINE__, Status,OpenStatus, *byteSize);


     BS->CloseProtocol (
         Controller,
         &gEfiUsbIoProtocolGuid,
         gImgHandle,
         Controller
         );
     return Status;
} 

And I have Success OpenProtocol output only with one device. Than I am trying to read first 512 bytes from USB. But, function UsbBulkTransfer fails.

Output:

USBXYZDriverBindingSupported.196 Success PciRoot(0)/Pci(0x14,0x0)/Usb(0x1,0x0) USBXYZDriverBindingSupported.203 Invalid Parametr 0 512

I read that EFI_INVALID_PARAMETER because of:

Data is NULL - not my option. I am trying to read data.

DataLength is NULL. - not my option. Length is 512.

If DeviceEndpoint is not valid. - possible reason. How to know what DeviceEndpoint means? How to get it, compute, use it?

I also tried to OpenProtocol with EFI_OPEN_PROTOCOL_GET_PROTOCOL and EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL. Nothing changed.

How to read data with UsbBulkTransfer? What is my mistake?

Thank you.

user3360601
  • 327
  • 3
  • 17
  • 1
    Did you download and look through https://github.com/tianocore/udk/releases/download/UDK2015/UDK2015.Documents.zip – Zan Lynx Jun 16 '17 at 16:36
  • @Zan Lynx, not yet, but I think I have found usefull function LibOpenRoot. But an argument - EFI_HANDLE. As I get - it is a handle on a USB drive. How can I get it? I will read docs soon, thanks. – user3360601 Jun 16 '17 at 16:39
  • 1
    And have you seen http://www.uefi.org/specifications ? – Zan Lynx Jun 16 '17 at 17:39
  • @Zan Lynx, thanks, in fact, edk2 docs about driver writer guide helped me. – user3360601 Jun 19 '17 at 06:08
  • 1
    @user3360601 try to do search first and then ask questions. Here is the solution: https://stackoverflow.com/questions/32324109/can-i-write-on-my-local-filesystem-using-efi – Alex D Jun 19 '17 at 17:06
  • @user3360601 Another way is you can also get stdlib port for UEFI, it's a bit of a magic dance around the fire to build it and set it up for you project, but after you've done it you can use regular C open, read, write, close... – Alex D Jun 19 '17 at 17:11
  • @Alex, thank you, but your link tells me how to open logical disk (ex, fs1, in my understanding). I want phisycal (ex, blk0). And I know how to open it in read blocks mode. – user3360601 Jun 20 '17 at 07:07
  • 1
    @user3360601 I don't see any problem, the mechanism is the same, just use EFI_DISK_IO_PROTOCOL to readDisk/writeDisk functions. It will give you physical access to your disk starting from MBR/GPT sector 0. – Alex D Jun 21 '17 at 18:34
  • @Alex, I have new interesting thing. I write in the usb flash memory fat32 for 4096 bytes. And 1Gb of memory I am filling up to 30 minutes. Is it ok? I thought that such a low-level function as EFI BLOCK IO PROTOCOL EFI_BLOCK_WRITE WriteBlocks; is fast enough. – user3360601 Jun 23 '17 at 08:46
  • @user3360601 Try to use UsbBulkTransfer of EFI_USB_IO_PROTOCOL it might do things faster. So, my educated guess is that most likely it's because of the underlaying driver for USB either bus driver or host controller. It's very slow and supports USB1.1 I suppose (30min for 1Gb looks like 1.1). Even the latest UEFI Spec 2.6 says that EFI_USB2_HC_PROTOCOL is designed to support both USB 1.1 and USB 2.0 – compliant host controllers. So, there is no even talks about 3.0, unfortunately. But, anyway bulk transfer should be faster. Let us know when you try it. I am curious myself. – Alex D Jun 25 '17 at 07:55
  • @Alex, sorry for being afk for days. I have updated this post with EFI_USB_IO_PROTOCOL. Please, give me advice – user3360601 Jun 30 '17 at 12:56
  • @user3360601 UINT32 *OpenStatus= NULL; doesn't look right to me. It must be a valid variable on stack UINT32 OpenStatus; and then you have to pass &OpenStatus; I believe that's why you have invalid argument. – Alex D Jul 06 '17 at 16:50

0 Answers0