On 01/22/13 01:17, David Woodhouse wrote: > When I have a virtio disk attached to a qemu VM, it doesn't appear in > the OVMF boot menu, so I can't boot from it. This is because the > BdsGetBootTypeFromDevicePath() function in GenericBdsLib.c only works on > the device path and isn't able to infer that 'PciRoot(0x0)/Pci(0x5,0x0)' > is a virtio disk. It could be *any* PCI device, if the path is all > you're looking at. > > Should the VirtioBlk driver actually be registering a *child* of the Pci > device node, such as PciRoot(0x0)/Pci(0x5,0x0)/Virtio(0), so that we can > automatically work out what it is from the path? Or is there a better > way?
The virtio-blk driver implements the EFI_BLOCK_IO_PROTOCOL for virtio-blk devices; that should be enough for enumerating the disk. If, instead of selecting Boot Manager in the OVMF boot menu, you go to Boot Maintenance Manager Boot Options Add Boot Option then in the File Explorer appearing there, something like PciRoot(0x0)/Pci(0x5,0x0)/HD(...) shows up. (It can be navigated down to \EFI\BOOT\BOOTX64.EFI.) The device path node that corresponds to the HD(...) substring is constructed by code outside of the virtio-blk driver (on top of the block IO protocol that virtio-blk produces). This HD(...) DP node is of type MEDIA_DEVICE_PATH, subtype MEDIA_HARDDRIVE_DP (see "DevPathToTextTable" and DevPathToTextHardDrive() in "MdeModulePkg/Universal/DevicePathDxe/DevicePathToText.c"). The calls seem to advance as in: PlatformBdsPolicyBehavior() [OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c] BdsLibEnumerateAllBootOption() [IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c] BdsGetBootTypeFromDevicePath() SetBootOrderFromQemu() [OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c] BdsGetBootTypeFromDevicePath() seems to handle MEDIA_HARDDRIVE_DP. It progresses through PciRoot(...) and Pci(...), and returns BDS_EFI_MEDIA_HD_BOOT for type MEDIA_DEVICE_PATH, subtype MEDIA_HARDDRIVE_DP. However BdsLibEnumerateAllBootOption() chooses to ignore BDS_EFI_MEDIA_HD_BOOT on purpose (unlike BDS_EFI_MESSAGE_SCSI_BOOT, which BdsGetBootTypeFromDevicePath() returns for virtio-scsi devices). See the comment on BdsLibEnumerateAllBootOption(): --------*-------- 4. Fixed BlockIo - The boot option only points to a Fixed blockIo device, like HardDisk. These device should contain a *fixed* blockIo protocol in their device handle. BDS will skip fixed blockIo devices, and NOT automatically create boot option for them. But BDS will help to delete those fixed blockIo boot option, whose description rule conflict with other auto-created boot options. [...] This function will enumerate all possible boot device in the system, and automatically create boot options for Network, Shell, Removable BlockIo, and Non-BlockIo Simplefile devices. --------*-------- Therefore the problem is not a missing child device path node; code outside of virtio-blk appends the appropriate MEDIA_HARDDRIVE_DP node to the device path. The problem is that BdsLibEnumerateAllBootOption() skips MEDIA_HARDDRIVE_DP / BDS_EFI_MEDIA_HD_BOOT deliberately. I'm not sure what the intent was. ( Later on, SetBootOrderFromQemu() would retrieve the fw_cfg boot order, translate the OpenFirmware device paths to UEFI device path prefixes, reorder the list of enumerated boot options against matching device path prefixes, and kill the rest of UEFI boot options. However BdsLibEnumerateAllBootOption() doesn't return a boot option for virtio-blk automatically, hence it doesn't matter if the fw_cfg boot order would favor it. Once a boot option for a virtio-blk device has been established manually (down to the BOOTX64.EFI file), and if it doesn't conflict with an auto-enumerated boot option, then it will be available to SetBootOrderFromQemu(). ( If you set DEBUG_VERBOSE / 0x00400000 in "gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel" in file "OvmfPkg/OvmfPkgX64.dsc", then the Match() function in "OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c" will log the boot options enumerated by BdsLibEnumerateAllBootOption() as it tries to match each OpenFirmware device path against them. Something like: SetBootOrderFromQemu: FwCfg: /pci@i0cf8/scsi@7/disk@0,0 SetBootOrderFromQemu: FwCfg: <end> ParseOfwNode: DriverName="pci" UnitAddress="i0cf8" DeviceArguments="" ParseOfwNode: DriverName="scsi" UnitAddress="7" DeviceArguments="" ParseOfwNode: DriverName="disk" UnitAddress="0,0" DeviceArguments="" TranslateOfwPath: success: "PciRoot(0x0)/Pci(0x7,0x0)/HD(" Match: against "PciRoot(0x0)/Pci(0x1,0x0)/Floppy(0x0)": no match Match: against "PciRoot(0x0)/Pci(0x1,0x0)/Floppy(0x1)": no match Match: against "MemoryMapped(0xB,0xDFC0E000,0xDFFBDFFF)/FvFile(C57AD6B7-0515-40A8-9D21-551652854E37)": no match Match: against "PciRoot(0x0)/Pci(0x7,0x0)/HD(2,GPT,A2146CB9-2947-4342-9528-D9F4369CBEF4,0x96800,0x31800)/\EFI\Boot\bootx64.efi": match TranslateOfwPath: no more nodes EmuVariablesUpdatedCallback Saved NV Variables to NvVars file SetBootOrderFromQemu: setting BootOrder: success ) ) Laszlo ------------------------------------------------------------------------------ Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS, MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft MVPs and experts. ON SALE this month only -- learn more at: http://p.sf.net/sfu/learnnow-d2d _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel