Discussion:
[edk2] booting linux from SD memory card
Meenakshi Aggarwal
2015-07-15 04:20:02 UTC
Permalink
Hi,


I am trying to boot linux from SD card.

I have made below changes in my dsc file:
gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription|L"Linux from SD"
gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(B6F43CC0-9E45-11DF-BE21-0002A5D5C51B)/HD(1,MBR,0x6D6D636F,0x3F,0x115F16B)/kernel.itb"
gArmPlatformTokenSpaceGuid.PcdDefaultBootType|3
gArmPlatformTokenSpaceGuid.PcdPlatformBootTimeOut|10

Here B6F43CC0-9E45-11DF-BE21-0002A5D5C51B is Guid of my SD driver.


My driver's device path is:

gDevicePath = {
{
{ HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { (UINT8)sizeof(VENDOR_DEVICE_PATH), (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8) } },
EFI_CALLER_ID_GUID
},
{ END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
{ sizeof (EFI_DEVICE_PATH_PROTOCOL), 0}
}
};

Here VenHw has Type as 1 and subtype as 4 in device path whereas HD has Type as 4 and subtype as 1 as device path.

I am registering Type as 1 and subtype as 4 in my driver's device path, is this correct?


In BdsLoadImage() function check is on Type 4 and subtype 1 in BdsGetDeviceHd() function, which is failing in my case.


Also in BdsConnectAndUpdateDevicePath(),

do {
Remaining = *DevicePath;
// The LocateDevicePath() function locates all devices on DevicePath that support Protocol and returns
// the handle to the device that is closest to DevicePath. On output, the device path pointer is modified
// to point to the remaining part of the device path
Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, Handle);
if (!EFI_ERROR (Status)) {
if (*Handle == PreviousHandle) {
//
// If no forward progress is made try invoking the Dispatcher.
// A new FV may have been added to the system and new drivers
// may now be found.
// Status == EFI_SUCCESS means a driver was dispatched
// Status == EFI_NOT_FOUND means no new drivers were dispatched
//
Status = gDS->Dispatch ();
}

if (!EFI_ERROR (Status)) {
PreviousHandle = *Handle;
// Recursive = FALSE: We do not want to start the whole device tree
Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);
}
}
} while (!EFI_ERROR (Status) && !IsDevicePathEnd (Remaining));


In every loop we are using same value in Remaining (Remaining = *DevicePath), means it will exist only when there is an error in Status because IsDevicePathEnd (Remaining) will never be true.
Then what is the use of this check?


Kindly help.


Thanks & regards
Meenakshi Aggarwal
Andrew Fish
2015-07-15 15:31:27 UTC
Permalink
Post by Meenakshi Aggarwal
Hi,
I am trying to boot linux from SD card.
gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription|L"Linux from SD"
gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(B6F43CC0-9E45-11DF-BE21-0002A5D5C51B)/HD(1,MBR,0x6D6D636F,0x3F,0x115F16B)/kernel.itb"
gArmPlatformTokenSpaceGuid.PcdDefaultBootType|3
gArmPlatformTokenSpaceGuid.PcdPlatformBootTimeOut|10
Here B6F43CC0-9E45-11DF-BE21-0002A5D5C51B is Guid of my SD driver.
gDevicePath = {
{
{ HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { (UINT8)sizeof(VENDOR_DEVICE_PATH), (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8) } },
EFI_CALLER_ID_GUID
},
{ END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
{ sizeof (EFI_DEVICE_PATH_PROTOCOL), 0}
}
};
Here VenHw has Type as 1 and subtype as 4 in device path whereas HD has Type as 4 and subtype as 1 as device path.
I am registering Type as 1 and subtype as 4 in my driver’s device path, is this correct?
In BdsLoadImage() function check is on Type 4 and subtype 1 in BdsGetDeviceHd() function, which is failing in my case.
Also in BdsConnectAndUpdateDevicePath(),
do {
Remaining = *DevicePath;
// The LocateDevicePath() function locates all devices on DevicePath that support Protocol and returns
// the handle to the device that is closest to DevicePath. On output, the device path pointer is modified
// to point to the remaining part of the device path
Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, Handle);
if (!EFI_ERROR (Status)) {
if (*Handle == PreviousHandle) {
//
// If no forward progress is made try invoking the Dispatcher.
// A new FV may have been added to the system and new drivers
// may now be found.
// Status == EFI_SUCCESS means a driver was dispatched
// Status == EFI_NOT_FOUND means no new drivers were dispatched
//
Status = gDS->Dispatch ();
}
if (!EFI_ERROR (Status)) {
PreviousHandle = *Handle;
// Recursive = FALSE: We do not want to start the whole device tree
Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);
}
}
} while (!EFI_ERROR (Status) && !IsDevicePathEnd (Remaining));
In every loop we are using same value in Remaining (Remaining = *DevicePath), means it will exist only when there is an error in Status because IsDevicePathEnd (Remaining) will never be true.
Then what is the use of this check?
gBS->LocateDevicePath() is looking for the best match of the current device path. So you want to reset to the full device path every time you call and you get back the part that match. When the matching device path is an end node you are done, you have matched.

The gBS->ConnectController() is causing bus drivers to add new handles to the system, that contain a new device path node that will make the match better. So basically this code is starting (connecting) a specific device.

So in your case your driver seems like it is just publishing a protocol. So it will exist on the 1st call to gBS->LocateProtocol(). The gBS->ConnectController() will Start the partition driver, and add the handle with the HD device path.

https://svn.code.sf.net/p/edk2/code/trunk/edk2/MdePkg/Include/Uefi/UefiSpec.h <https://svn.code.sf.net/p/edk2/code/trunk/edk2/MdePkg/Include/Uefi/UefiSpec.h>
/**
Locates the handle to a device on the device path that supports the specified protocol.

@param[in] Protocol Specifies the protocol to search for.
@param[in, out] DevicePath On input, a pointer to a pointer to the device path. On output, the device
path pointer is modified to point to the remaining part of the device
path.
@param[out] Device A pointer to the returned device handle.

@retval EFI_SUCCESS The resulting handle was returned.
@retval EFI_NOT_FOUND No handles match the search.
@retval EFI_INVALID_PARAMETER Protocol is NULL.
@retval EFI_INVALID_PARAMETER DevicePath is NULL.
@retval EFI_INVALID_PARAMETER A handle matched the search and Device is NULL.

**/
typedef
EFI_STATUS
(EFIAPI *EFI_LOCATE_DEVICE_PATH)(
IN EFI_GUID *Protocol,
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
OUT EFI_HANDLE *Device
);


Thanks,

Andrew Fish
Post by Meenakshi Aggarwal
Kindly help.
Thanks & regards
Meenakshi Aggarwal
------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/_______________________________________________ <https://www.gigenetcloud.com/_______________________________________________>
edk2-devel mailing list
https://lists.sourceforge.net/lists/listinfo/edk2-devel <https://lists.sourceforge.net/lists/listinfo/edk2-devel>
Continue reading on narkive:
Loading...