5

Is it possible to copy files to EFI using some sort of network protocol?

For example, I have a computer and a virtual machine. The virtual machine boots to EFI and I need to copy file to it and then execute it in EFI environment.

Is this possible?

1
  • 2
    In theory, yes. In practice, you'll need a complete TCP/IP stack, with everything from network card drivers up to a client or server for FTP, SSH, or some other protocol that can be used to transfer files. Most (maybe all) of the parts exist, but not necessarily for every system -- you might be thwarted by lack of a driver for your network hardware, for instance. Beyond that, you'll need to track down every piece, and I'm afraid I can't provide pointers to any of it, at least not in ready-to-use binary form. (TianoCore provides parts in source code form.)
    – Rod Smith
    Mar 7, 2017 at 14:22

3 Answers 3

6

Well, when i started developing EFI applications, i found the same problem. How to send file on EFI environment? For now I know these ways:

1. USB storage device.

Probably the easiest way if you copy files not too often. Just put files on USB flash drive and connect it to virtual machine (VM).

To access file from EFI environment you need EFI shell or something like that. VMware already has integrated shell, while on other VMs you may need to obtain it. To do this you can use wonderful rEFInd Boot Manager, which contains shell. Unzip it, insert iso image in VM's CD-ROM and boot from it. In the rEFInd menu choose "Start EFI Shell". You will see command prompt, where all storage devices mapped as FS0, FS1,... If you see only FS0 (rEFInd file system), then you probably forgot to connect USB drive to VM.

Now to get your file just type commands like this:

fs1:
cd directory_with_file

All shell commands can be found by help command.

2. Transfer via TFTP.

Longer to setup, faster to use. Nice if you send files often, while developing EFI applications for example. For this method you need TFTP server like tftpd-hpa working (it could be on your host machine), EFI Shell + TFTP client on your VM. There is plenty information about starting TFTP server, so you can find manual yourself. Also it is nice to have DHCP server (it is optional, but configuration will be much easier with DHCP).

TFTP client can be built from Tianocore sources or downloaded as x64 precompiled binary from my cloud (i dont know why Tianocore maintainers do not provide it in binary). Put tftp.efi on your VM somewhere you can access it (USB drive or virtual HDD). Put your file in TFTP root directory (like /srv/tftp). Probably you should turn your VM's network adapter into bridge mode, so it has real ip, if you want to use DHCP. Start EFI shell VM as described above. When you see command prompt, type these commands.

ifconfig -s eth0 dhcp
fs1:
cd destination_directory
tftp 192.168.3.1 file_to_copy

Where:

  • eth0 is your network adapter, you can find required one with ifconfig -l. Also you can use static ip instead of dhcp, see help ifconfig
  • fs1: is your file system with tftp.efi, it could be fs0: or other depends on your booting device
  • tftp is tftp.efi app, 192.168.3.1 is ip address of TFTP server (host machine or real server)

Also you can write this commands in startup.nsh file in the root of your bootable file system to do it on VM loading. Or only last line in another *.nsh script file to download while EFI running.

3. QEMU virtual machine

It is very handy for simple testings, you do not need TFTP, DHCP, USB drive, etc. If it is ok to recreate VM each time you boot, there is wonderful article about creating and debugging EFI applications with QEMU on osdev.org.

5

Adding on to Dmitry's Solution:

4. Transfer via HTTP
This one is similar to TFTP in that you will need to build the binary for it and place it in the same location as your shell (or elsewhere, but typing out the path to the application gets tiresome).

I've found that I need to run connect prior to ifconfig to properly connect drivers to their handlers. I use a simple startup.nsh script to make things a bit faster:

FS0:
connect
ifconfig -r eth0
ifconfig -s eth0 dhcp
ifconfig -l eth0

Be aware that if you have multiple block devices, you may have a different FS<x>: to input. You can use map to list the devices out.

Then to pull your file from an HTTP server (given that you have http.efi):

http <server_ip> <remote_path_to_file>  

This will overwrite the current file. If you want to keep it:

http <server_ip> <remote_path_to_file> <new_local_filename>

To set up a local HTTP server (Ubuntu):

sudo apt-get install apache2
/etc/init.d/apache2 start

Drop your desired files in /var/www/html for top access.

I've also documented some personal notes from my experiences in building the TianoCore Shell and applications since there seem to be several README's out of date and/or floating in various locations.

To Build TianoCore EDKII UEFI Shell and Utilities

These instructions were ONLY tested on UBUNTU 18.04, 20.10 with EDK II repository head at 35ed29f

1. Clone the EDK II repository

git clone --recursive https://github.com/tianocore/edk2.git

or

git clone https://github.com/tianocore/edk2.git
cd edk2
git submodule update --init

2. Install requirements

Not sure which of these are required due to multiple READMEs. I used all as 'better safe than sorry'.

sudo apt-get install uuid-dev nasm gcc-5 build-essential \
     iasl git python3-distutils texinfo \
     bison flex libgmp3-dev libmpfr-dev subversion

3. Compile build tools

cd edk2
make -C BaseTools

4. Initialize the environment

. edksetup.sh

5. Adjust config (in my case for X64 architecture)

vi ./Conf/target.txt
  • SetLine: ACTIVE_PLATFORM = ./ShellPkg/ShellPkg.dsc
  • SetLine: TARGET_ARCH = X64
  • SetLine: TOOL_CHAIN_TAG = GCC5

There are flags to override the platform, arch, tool chain when building but I prefer to just adjust the config.

6. Build the package

build

7. Locate the files

cd ./edk2/Build/Shell/DEBUG_GCC5/X64/

Either Shell_<GUID>.efi file is fine. I had:

  • Shell_7C04A583-9E3E-4f1c-AD65-E05268D0B4D1.efi
  • Shell_EA4BB293-2D7F-4456-A681-1F22F42CD0BC.efi
  • http.efi
0

If you just want to execute a remote EFI binary, look for the "rload" command if its available in your EFI shell.

This uses TFTP. And this assume your EFI has network drivers and all.

In my shell, haven't found a command to actually copy the remote file to the filesystem, which is kind of annoying.

1
  • Is rload really exist in EFI shell? Sep 7, 2022 at 8:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .