3.15.7 ConOut
As with ConIn, firmware connects the ConOut devices using the device paths in the ConOut global UEFI variable. If ConIn was not complicated enough, the ConOut global UEFI device path in this example is a compound device path and indicates that the ConOut device is being mirrored with the console splitter driver to two separate devices.
ConOut = Acpi(HWP0002,0,PNP0A03)/Pci(1|1)/Uart(9600 N81)/VenMsg(Vt100+);Acpi(HWP0002,0,PNP0A03)/Pci(4|0)
The UEFI connection process searches the handle database for a device path that matches the first device path in the ConOut variable:
Acpi(HWP0002,0,PNP0A03)/Pci(1|1)/Uart(9600 N81)/VenMsg(Vt100+)`
Luckily, the device path already exists on handle 3C in its entirety thanks to the connection work done for ConIn.
3C: Txtin Txtout ConIn ConOut StdErr DevPath
(Acpi(HWP0002,0,PNP0A03)/Pci(1|1)/Uart(9600 N81)/VenMsg(Vt100+))
UEFI performs a ConnectController()
on handle 3C. Because this step was
previously done with ConIn, there is nothing more to be done here.
The connection process has not yet been completed for ConOut because the device path is a compound device path and a second device needs to be connected:
Acpi(HWP0002,0,PNP0A03)/Pci(4|0)
The UEFI connection process searches the handle database for a device path that matches Acpi(HWP0002,0,PNP0A03)/Pci(4|0). The device path already exists in its entirety on handle 1C and was created by the PCI bus driver when it started and exposed the PCI devices.
1C: PciIo DevPath (Acpi(HWP0002,0,PNP0A03)/Pci(4|0))
UEFI now performs a ConnectController()
on handle 1C. Note that the device
path is a complete match, so there is no remaining device path to pass in this
time. ConnectController()
constructs the prioritized list of drivers in the system
and calls the Supported()
service for each one, passing in the device handle
1C. The only driver that returns EFI_SUCCESS
is the GraphicsOutput driver.
2E: Image(CirrusLogic5430Dxe) Driver Binding ComponentName2 ComponentName
ConnectController()
calls this driver's Start()
function and Start()
consumes the device's EFI_PCI_IO_PROTOCOL
and installs the
EFI_GRAPHICS_OUTPUT_PROTOCOL
onto the device handle 1C.
1C: PciIo GraphicsOutput DevPath (Acpi(HWP0002,0,PNP0A03)/ Pci(4|0))
ConnectController()
continues to process its list of drivers and finds that
the GraphicsConsole
driver's Supported()
service returns EFI_SUCCESS
.
2D: Image(GraphicsConsoleDxe) DriverBinding ComponentName2 ComponentName
Next, the graphics console driver's Start()
service consumes the
EFI_GRAPHICS_OUTPUT_PROTOCOL
and produces the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
on the same device handle 1C.
1C: Txtout PciIo GraphicsOutput DevPath (Acpi(HWP0002,0,PNP0A03)/
Pci(4|0))
ConnectController()
continues to process its list of drivers, now searching
for a driver that supports this controller, and finds two driver handles that
return EFI_SUCCESS
from their Supported()
services. These two driver
handles are from the platform console management driver:
32: Image(ConPlatformDxe) DriverBinding ComponentName2 ComponentName
Driver handle 32 installs a ConOut Tag GUID on the handle if the device path is listed in the ConOut global UEFI variable. In this example, the case is true. Driver 32 also installs a StdErr Tag GUID on the handle if the device path is listed in the ErrOut global UEFI variable. This case is also true in the example. Therefore, handle 1C has two new protocols on it: ConOut and StdErr.
1C: Txtout PciIo ConOut StdErr DevPath (Acpi(HWP0002,0,PNP0A03)/Pci(4|0))
These two protocols (ConOut and StdErr) are used to mark devices in the system that have been user-selected as ConOut and StdErr. These protocols are actually just Tag GUID without any functions or data.
There are two other driver handles that return EFI_SUCCESS
to the
Supported()
service. These driver handles are from the console splitter
driver for the ConOut and StdErr devices in the system.
36: DriverBindingComponentName
37: DriverBindingComponentName
Remember that when the console splitter driver was first loaded, it created three virtual handles.
38: TxtinEx TxtIn SimplePointer AbsolutePointer
39: Txtout GraphicsOutput UgaDraw
3A: Txtout
The console splitter driver's Supported()
service for driver handle 36
examines the handle 1C for a ConOut Protocol. Having found it, EFI_SUCCESS
is returned. The Start()
service then opens the ConOut protocol on device
handle 1C such that the device handle 39 becomes a child controller and
starts aggregating the SIMPLE_TEXT_OUTPUT_PROTOCOL
services.
The same thing happens for driver handle 37 with StdErr; the SIMPLE_TEXT_OUTPUT_PROTOCOL
functionality on device handle 1C is aggregated into the SIMPLE_TEXT_OUTPUT_PROTOCOL
on device handle 3A.