Claod
Claod

Reputation: 21

Create a .efi to disable egpu and then chainload bootmgfw.efi

I'm using an .nsh to modify my pci from efi, and then I launch Windows from bootmgfw.efi.

But doing so the shell is visible for some seconds while commands are exacuting, and I don't think there is a way to execute this nsh silently.

But I don't know how to achieve this in an efi application:

"mm 000100003E 1" "fs0:/EFI/Microsoft/Boot/bootmgfw.efi"

So I'm here to ask you if there is a way to create an .efi to change my pci the exact same way, and launching the Windows bootloader after those changes, but silently.

The best would be to read pci addresses and the path of the bootloader from a .conf file. It would be helpful for lot of people in my case.

Short questions:

Thank you for your help

Upvotes: 0

Views: 421

Answers (1)

KagurazakaKotori
KagurazakaKotori

Reputation: 572

mm 000100003E 1 command is to write 1 at memory address 0x000100003E, in edk2 ShellPkg, it is implemented with a simple CopyMem function call, you can implement your own like this:

UINT8 value = 1;
CopyMem((VOID *)0x000100003E, &value, 1);

Calling another efi application in one efi application is possible, but its very complex, you need to do the following works:

  1. Get device handle of fs0
  2. Create device path for /EFI/Microsoft/Boot/bootmgfw.efi
  3. Load and start the efi application

As the efi application you are going to write is also located in fs0, probably fs0:\EFI\BOOT\BOOTX64.EFI, you can get fs0's device handle from it.

// Get device handle of fs0 from current application
EFI_LOADED_IMAGE_PROTOCOL *loaded_image;
gBS->OpenProtocol(ImageHandle, &LoadedImageProtocol, &loaded_image, ImageHandle, NULL,  EFI_OPEN_PROTOCOL_GET_PROTOCOL);

// Create device path
EFI_DEVICE_PATH_PROTOCOL *path = FileDevicePath(loaded_image->DeviceHandle, L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi");

// Load and start the image
EFI_HANDLE image;
gBS->LoadImage(FALSE, ImageHandle, path, NULL, 0, &image);
gBS->StartImage(image, NULL, NULL);

To read a configuration file, you need to use EFI File Protocol to open your config file and parse it on your own.

EFI_FILE_PROTOCOL *rootdir, *conffile;
UINT8 buf[1024];
UINTN bufsize = sizeof(buf);

// Open config file
rootdir = LibOpenRoot(loaded_image->DeviceHandle);
rootdir->Open(rootdir, &conffile, L"\\path\\to\\config", EFI_FILE_MODE_READ, 0);

// Read config file
conffile->Read(conffile, &bufsize, buf);

// Parse the file content in buf 
// ...

// Close conffile and rootdir
conffile->Close(conffile);
rootdir->Close(rootdir);

edk2 or gnu-efi is required for the above code to work.

References:

Upvotes: 1

Related Questions