You're right (as I saw another comment cite the primary-source for); but I'm still curious now, whether there'd be a way to pull this off.
> I think that would mean you cannot use native drivers
Yes, that's right.
> at which point you're just writing another bootloader
But that's not necessarily true.
Even if you could only use EFI boot+runtime services until you call ExitBootServices, in theory, an OS kernel could have a HAL for which many different pieces of hardware have an "EFI boot services driver" as well as a native driver; and where the active driver for a given piece of discovered hardware could be hotswapped "under" the HAL abstraction, atomically, without live HAL-intermediated kernel handles going bad — as long as the kernel includes a driver-to-driver state-translation function for the two implementations.
So you could "bring up" a kernel and userland while riding on EFI boot services; and then the kernel would snap its fingers at some critical point, and it'd suddenly all be native drivers.
Of course, Linux is not architected in a way that even comes close to allowing something like this. (Windows might be, maybe?)
---
I think a more interesting idea, though, would come from slightly extending the UEFI spec. Imagine two calls: PauseBootServices and ResumeBootServices.
PauseBootServices would stop all management of devices by the EFI (so, as with ExitBootServices, you'd have to be ready to take over such management) — but crucially, it would leave all the stuff that EFI had discovered+computed+mapped into memory during early boot, mapped into memory (and these pages would be read-only and would be locked at ring-negative-3 or something, so the kernel wouldn't have permission to unmap them.)
If this existed, then at any time (even in the middle of running a multi-user OS!), the running kernel that had previously called PauseBootServices, could call ResumeBootServices — basically "relinquishing back" control over the hardware to EFI.
EFI would then go about reinitializing all hardware other than the CPU and memory, taking over the CPU for a while the same way peripheral bring-up logic does at early boot. But when it's done with getting all the peripherals into known-good states, it would then return control to the caller[1] of ResumeBootServices, with the kernel now having transitioned into being an EFI app again.
[1] ...through a vector of the caller's choice. To get those drivers back into being EFI boot services drivers before the kernel tries using them again, naturally.
It's a dumb idea, mostly useless, thoroughly impractical to implement given how ossified EFI already is — but it'd "work" ;)
Giving "the control of hardware back" is going to be extremely difficult. Just look at the mess that ACPI is: there are lots of notebooks that Linux can not put into/back from hibernation, and here we're talking simply about pausing/resuming devices themselves. What you are proposing means that an OS would have to revert the hardware back to the state that would be compatible with its state at the moment of booting, so that UEFI could manage it correctly. I don't think that's gonna happen.
> I think that would mean you cannot use native drivers
Yes, that's right.
> at which point you're just writing another bootloader
But that's not necessarily true.
Even if you could only use EFI boot+runtime services until you call ExitBootServices, in theory, an OS kernel could have a HAL for which many different pieces of hardware have an "EFI boot services driver" as well as a native driver; and where the active driver for a given piece of discovered hardware could be hotswapped "under" the HAL abstraction, atomically, without live HAL-intermediated kernel handles going bad — as long as the kernel includes a driver-to-driver state-translation function for the two implementations.
So you could "bring up" a kernel and userland while riding on EFI boot services; and then the kernel would snap its fingers at some critical point, and it'd suddenly all be native drivers.
Of course, Linux is not architected in a way that even comes close to allowing something like this. (Windows might be, maybe?)
---
I think a more interesting idea, though, would come from slightly extending the UEFI spec. Imagine two calls: PauseBootServices and ResumeBootServices.
PauseBootServices would stop all management of devices by the EFI (so, as with ExitBootServices, you'd have to be ready to take over such management) — but crucially, it would leave all the stuff that EFI had discovered+computed+mapped into memory during early boot, mapped into memory (and these pages would be read-only and would be locked at ring-negative-3 or something, so the kernel wouldn't have permission to unmap them.)
If this existed, then at any time (even in the middle of running a multi-user OS!), the running kernel that had previously called PauseBootServices, could call ResumeBootServices — basically "relinquishing back" control over the hardware to EFI.
EFI would then go about reinitializing all hardware other than the CPU and memory, taking over the CPU for a while the same way peripheral bring-up logic does at early boot. But when it's done with getting all the peripherals into known-good states, it would then return control to the caller[1] of ResumeBootServices, with the kernel now having transitioned into being an EFI app again.
[1] ...through a vector of the caller's choice. To get those drivers back into being EFI boot services drivers before the kernel tries using them again, naturally.
It's a dumb idea, mostly useless, thoroughly impractical to implement given how ossified EFI already is — but it'd "work" ;)