summaryrefslogtreecommitdiffstats
path: root/src/interface/efi
diff options
context:
space:
mode:
authorMichael Brown2017-04-12 16:03:25 +0200
committerMichael Brown2017-04-12 16:58:05 +0200
commit84d406ccf48c8808b0bb30d526b758e4b58cacc8 (patch)
treee0d262d87136fcaf8f202ab7d6e51760a387fe78 /src/interface/efi
parent[efi] Add efi_sprintf() and efi_vsprintf() (diff)
downloadipxe-84d406ccf48c8808b0bb30d526b758e4b58cacc8.tar.gz
ipxe-84d406ccf48c8808b0bb30d526b758e4b58cacc8.tar.xz
ipxe-84d406ccf48c8808b0bb30d526b758e4b58cacc8.zip
[block] Allow use of a non-default EFI SAN boot filename
Some older operating systems (e.g. RHEL6) use a non-default filename on the root disk and rely on setting an EFI variable to point to the bootloader. This does not work when performing a SAN boot on a machine where the EFI variable is not present. Fix by allowing a non-default filename to be specified via the "sanboot --filename" option or the "san-filename" setting. For example: sanboot --filename \efi\redhat\grub.efi \ iscsi:192.168.0.1::::iqn.2010-04.org.ipxe.demo:rhel6 or option ipxe.san-filename code 188 = string; option ipxe.san-filename "\\efi\\redhat\\grub.efi"; option root-path "iscsi:192.168.0.1::::iqn.2010-04.org.ipxe.demo:rhel6"; Originally-implemented-by: Vishvananda Ishaya Abrams <vish.ishaya@oracle.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/interface/efi')
-rw-r--r--src/interface/efi/efi_block.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/src/interface/efi/efi_block.c b/src/interface/efi/efi_block.c
index fa2271b3..70a87dcf 100644
--- a/src/interface/efi/efi_block.c
+++ b/src/interface/efi/efi_block.c
@@ -518,10 +518,12 @@ static int efi_block_describe ( void ) {
*
* @v sandev SAN device
* @v handle EFI handle
+ * @v filename Filename (or NULL to use default)
+ * @v image Image handle to fill in
* @ret rc Return status code
*/
static int efi_block_boot_image ( struct san_device *sandev, EFI_HANDLE handle,
- EFI_HANDLE *image ) {
+ const char *filename, EFI_HANDLE *image ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_block_data *block = sandev->priv;
union {
@@ -563,7 +565,10 @@ static int efi_block_boot_image ( struct san_device *sandev, EFI_HANDLE handle,
end = efi_devpath_end ( path.path );
prefix_len = ( ( ( void * ) end ) - ( ( void * ) path.path ) );
filepath_len = ( SIZE_OF_FILEPATH_DEVICE_PATH +
- sizeof ( efi_block_boot_filename ) );
+ ( filename ?
+ ( ( strlen ( filename ) + 1 /* NUL */ ) *
+ sizeof ( filepath->PathName[0] ) ) :
+ sizeof ( efi_block_boot_filename ) ) );
boot_path_len = ( prefix_len + filepath_len + sizeof ( *end ) );
boot_path = zalloc ( boot_path_len );
if ( ! boot_path ) {
@@ -576,8 +581,12 @@ static int efi_block_boot_image ( struct san_device *sandev, EFI_HANDLE handle,
filepath->Header.SubType = MEDIA_FILEPATH_DP;
filepath->Header.Length[0] = ( filepath_len & 0xff );
filepath->Header.Length[1] = ( filepath_len >> 8 );
- memcpy ( filepath->PathName, efi_block_boot_filename,
- sizeof ( efi_block_boot_filename ) );
+ if ( filename ) {
+ efi_sprintf ( filepath->PathName, "%s", filename );
+ } else {
+ memcpy ( filepath->PathName, efi_block_boot_filename,
+ sizeof ( efi_block_boot_filename ) );
+ }
end = ( ( ( void * ) filepath ) + filepath_len );
end->Type = END_DEVICE_PATH_TYPE;
end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
@@ -609,9 +618,10 @@ static int efi_block_boot_image ( struct san_device *sandev, EFI_HANDLE handle,
* Boot from EFI block device
*
* @v drive Drive number
+ * @v filename Filename (or NULL to use default)
* @ret rc Return status code
*/
-static int efi_block_boot ( unsigned int drive ) {
+static int efi_block_boot ( unsigned int drive, const char *filename ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct san_device *sandev;
EFI_HANDLE *handles;
@@ -649,7 +659,7 @@ static int efi_block_boot ( unsigned int drive ) {
*/
rc = -ENOENT;
for ( i = 0 ; i < count ; i++ ) {
- if ( ( rc = efi_block_boot_image ( sandev, handles[i],
+ if ( ( rc = efi_block_boot_image ( sandev, handles[i], filename,
&image ) ) != 0 )
continue;
DBGC ( sandev, "EFIBLK %#02x found boot image\n",