Question

I had the idea of running a small service next to the OS but I'm not sure if it is possible. I tried to figure it out by reading some docs but didn't get far, so here comes my question.

I read about the UEFI runtime services.
Would it be possible to have a small module in the firmware which runs next to what ever operating system is used and that sends information concerning the location of the device to an address on the internet?

As far as my knowledge goes, I would say that it should not possbile to run something in the background once UEFI handed the control over to the OS kernel.

To clarify my intentions, I would like to have something like that on my laptop. There is the Prey project but it is installed inside the OS. I'm using a Linux distribution without autologin. If somebody would steal it they would probably just install Windows.

Was it helpful?

Solution

What you want to do is prohibited because that would be the gateway for viruses, loggers and other malwares.

That said, if you want to get some code running aside of the OS, you should look at System Management Mode (SMM).

SMM is an execution mode of the x86 processors orthogonal to the standard protected mode. SMM allows the BIOS to completely suspend the OS on all the CPUs at once and enter in SMM mode to execute some BIOS services. Switching to SMM mode happens right now on your x86 machine, as you're reading this Stackoverflow answer. It is triggered either by:

  • hardware: a dedicated System Management Interrupt line (SMI#), very similar to how IRQs work,
  • software: via an I/O access to a location considered special by the motherboard logic (port 0xb2 is common).

SMM services are called SMM handlers and for instance sensors values are very often retrieved by the means of a SMM call to a SMM handler.

SMM handlers are setup during the DXE phase of UEFI firmware initialization into the SMRAM, an area dedicated to SMM handlers. See the following diagram:

Platform Iniitialization Boot Phases

SMM Drivers are dispatched by the SMM Core during the DXE Phase. So additional SMI handlers can be registered in the DXE Phase. Late in the DXE Phase, when no more SMM drivers can be dispatched, SMRAM will be locked down (as recommended practice). Once SMRAM is locked down, no additional SMM Drivers may be dispatched, so not additional SMI handlers can be registered. For example, an SMM Driver that registers an SMI handler cannot be loaded from the EFI Shell or be added as a DriverOption in the UEFI Boot Manager.

source: tianocore

This means that the code of your SMM handler must be present in the BIOS image, which implies rebuilding the BIOS with your handler added. It's tricky but tools exist out there to both provide a DXE environment and build your SMM handler code into a PE executable, as well as other tools to add a DXE driver to an existing BIOS image. Not all BIOS manufacturers are supported though. It's risky unless your Flash chip is in a socket and you can reprogram it externally.

But the first thing is to check if the SMRAM is locked on your system. If you're lucky you can add your very own SMM handler directly in SMRAM. It's fidly but doable.

Note: SMM handlers inside the BIOS are independent from the OS so it would run even if a robber installs a new Operating System, which is what you want. However being outside of an OS has huge disadvantages: you'd need to embedd in your SMM handler a driver for the network interface (a polling-only, interrupt-less driver!) and wlan 802.11, DHCP and IP support to connect to the Wifi and get your data routed to an external host on the Internet. How would you determine the wifi SSID and password? Well you could wait for the OS to initialize the network adapter for you, but you'd need to save/restore the full state of the network host controller between calls. Not a small or easy project.

OTHER TIPS

As far as my knowledge goes, I would say that it should not possbile to run something in the background once UEFI handed the control over to the OS kernel.

I agree. Certainly, the boot environment (prior to ExitBootServices() only uses a single threaded model.

There is no concept of threads in the UEFI spec as far as I can see. Furthermore each runtime service is something the OS deliberately invokes, much like the OS provides system calls for applications. Once you enter a runtime system function, note the following restriction from 7.1:

Callers are prohibited from using certain other services from another processor or on the same processor following an interrupt as specified in Table 30.

Depending on which parts of the UEFI firmware your runtime service needed access to would depend on which firmware functions would be non-reentrant whilst your call was busy.

Which is to say that, even if you were prepared to sacrifice a thread to sit eternally inside an EFI runtime service, you could well block the entire rest of the kernel from using other runtime services.

I do not think it is going to be possible unfortunately, but interesting question all the same!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top