Search code examples
firmwareuefiedk2

Does a protocol continue to be in memory and usable by other drivers even after the driver that installed it is unloaded?


If we have a driver that installs a protocol in EDK2/UEFI and then that driver is unloaded, does the protocol continue to exist and be usable by other drivers and services? Same question for UEFI applications. I am mostly wondering if the UEFI framework somehow ties the protocols to the drivers that installed them and if the driver is unloaded does the protocol remain usable by other drivers after the image is unloaded or does the protocol also exit memory when the driver is unloaded.

I think code could certainly be made to make this be the case that when the driver exits it uninstalls the protocol it made, however does this occur by default within UEFI/EDK2? Or would this only occur if the driver explicitly stated to uninstall the protocol when it is unloaded?

Additionally, what is best practice for industry here? Should protocols generally continue to live on past the drivers that installed them or should the two be linked?

Sorry if this question is high level. I am trying to gain some high-level intuition for this topic.


Solution

  • A driver or application is required to uninstall its protocols and free the associated memory before exiting. It is not done automatically by the UEFI core.

    Since protocols generally contain pointers to functions in the driver, it would be impossible for the driver to be unloaded while the protocols still exist. (However, it would be possible to orphan a protocol that doesn't contain any function pointers.)

    (Citations are from UEFI specification version 2.8.)

    7.4, EFI_IMAGE_ENTRY_POINT:

    If the image supports dynamic unloading, it must supply an unload function in the EFI_LOADED_IMAGE_PROTOCOL structure before returning control from its entry point.

    7.4 Exit:

    When an EFI boot service driver or runtime service driver exits, firmware frees the image only if the ExitStatus is an error code; otherwise the image stays resident in memory. The driver must not return an error code if it has installed any protocol handlers or other active callbacks into the system that have not (or cannot) be cleaned up. If the driver exits with an error code, it is responsible for freeing all resources before exiting.

    7.4, UnloadImage:

    If the image has been started and has an Unload() entry point, control is passed to that entry point. If the image’s unload function returns EFI_SUCCESS, the image is unloaded; otherwise, the error returned by the image’s unload function is returned to the caller. The image unload function is responsible for freeing all allocated memory and ensuring that there are no references to any freed memory, or to the image itself, before returning EFI_SUCCESS.
    If the image has been started and does not have an Unload() entry point, the function returns EFI_UNSUPPORTED.

    4.7.3:

    Any protocols installed or memory allocated ... must be uninstalled or freed [in the driver's Unload function].