aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2024-03-05 20:20:10 +0000
committerMichael Brown <mcb30@ipxe.org>2024-03-06 12:19:22 +0000
commit636ccb4ca55c73841e634f9d5986087fb3565da4 (patch)
tree31a788498a6a03bfead3a7df5c8da9ef13eab8b9
parentb1c13cc43ece3008f7012cf736fc943d5bb89131 (diff)
downloadipxe-636ccb4ca55c73841e634f9d5986087fb3565da4.zip
ipxe-636ccb4ca55c73841e634f9d5986087fb3565da4.tar.gz
ipxe-636ccb4ca55c73841e634f9d5986087fb3565da4.tar.bz2
[block] Allow for additional SAN boot parameters alongside filename
The drive specification alone does not necessarily contain enough information to perform a SAN boot (or local disk boot) under UEFI. If the next-stage bootloader is installed in the EFI system partition under a non-standard name (e.g. "\EFI\debian\grubx64.efi") then this explicit boot filename must also be specified. Generalise this concept to use a "SAN boot configuration parameters" structure (currently containing only the optional explicit boot filename), to allow for easy expansion to provide other parameters such as the partition UUID or volume label. Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/arch/x86/interface/pcbios/int13.c5
-rw-r--r--src/core/dummy_sanboot.c4
-rw-r--r--src/core/null_sanboot.c2
-rw-r--r--src/hci/commands/sanboot_cmd.c6
-rw-r--r--src/include/ipxe/sanboot.h10
-rw-r--r--src/include/usr/autoboot.h3
-rw-r--r--src/interface/efi/efi_block.c23
-rw-r--r--src/usr/autoboot.c15
8 files changed, 45 insertions, 23 deletions
diff --git a/src/arch/x86/interface/pcbios/int13.c b/src/arch/x86/interface/pcbios/int13.c
index 2c5e862..372d40b 100644
--- a/src/arch/x86/interface/pcbios/int13.c
+++ b/src/arch/x86/interface/pcbios/int13.c
@@ -1511,7 +1511,7 @@ static int int13_load_eltorito ( unsigned int drive, struct segoff *address ) {
* Attempt to boot from an INT 13 drive
*
* @v drive Drive number
- * @v filename Filename (or NULL to use default)
+ * @v config Boot configuration parameters
* @ret rc Return status code
*
* This boots from the specified INT 13 drive by loading the Master
@@ -1521,7 +1521,8 @@ static int int13_load_eltorito ( unsigned int drive, struct segoff *address ) {
*
* Note that this function can never return success, by definition.
*/
-static int int13_boot ( unsigned int drive, const char *filename __unused ) {
+static int int13_boot ( unsigned int drive,
+ struct san_boot_config *config __unused ) {
struct memory_map memmap;
struct segoff address;
int rc;
diff --git a/src/core/dummy_sanboot.c b/src/core/dummy_sanboot.c
index 506b20c..e22998d 100644
--- a/src/core/dummy_sanboot.c
+++ b/src/core/dummy_sanboot.c
@@ -95,11 +95,11 @@ static void dummy_san_unhook ( unsigned int drive ) {
* Boot from dummy SAN device
*
* @v drive Drive number
- * @v filename Filename (or NULL to use default)
+ * @v config Boot configuration parameters
* @ret rc Return status code
*/
static int dummy_san_boot ( unsigned int drive __unused,
- const char *filename __unused ) {
+ struct san_boot_config *config __unused ) {
return -EOPNOTSUPP;
}
diff --git a/src/core/null_sanboot.c b/src/core/null_sanboot.c
index 7c0680f..2340cd2 100644
--- a/src/core/null_sanboot.c
+++ b/src/core/null_sanboot.c
@@ -38,7 +38,7 @@ static void null_san_unhook ( unsigned int drive __unused ) {
}
static int null_san_boot ( unsigned int drive __unused,
- const char *filename __unused ) {
+ struct san_boot_config *config __unused ) {
return -EOPNOTSUPP;
}
diff --git a/src/hci/commands/sanboot_cmd.c b/src/hci/commands/sanboot_cmd.c
index 3907276..9c7e9ab 100644
--- a/src/hci/commands/sanboot_cmd.c
+++ b/src/hci/commands/sanboot_cmd.c
@@ -100,6 +100,7 @@ static int sanboot_core_exec ( int argc, char **argv,
struct command_descriptor *cmd,
int default_flags, int no_root_path_flags ) {
struct sanboot_options opts;
+ struct san_boot_config config;
struct uri *uris[argc];
int count;
int flags;
@@ -124,6 +125,9 @@ static int sanboot_core_exec ( int argc, char **argv,
}
}
+ /* Construct configuration parameters */
+ config.filename = opts.filename;
+
/* Construct flags */
flags = default_flags;
if ( opts.no_describe )
@@ -134,7 +138,7 @@ static int sanboot_core_exec ( int argc, char **argv,
flags |= no_root_path_flags;
/* Boot from root path */
- if ( ( rc = uriboot ( NULL, uris, count, opts.drive, opts.filename,
+ if ( ( rc = uriboot ( NULL, uris, count, opts.drive, &config,
flags ) ) != 0 )
goto err_uriboot;
diff --git a/src/include/ipxe/sanboot.h b/src/include/ipxe/sanboot.h
index b11197f..d981226 100644
--- a/src/include/ipxe/sanboot.h
+++ b/src/include/ipxe/sanboot.h
@@ -105,6 +105,12 @@ enum san_device_flags {
SAN_NO_DESCRIBE = 0x0001,
};
+/** SAN boot configuration parameters */
+struct san_boot_config {
+ /** Boot filename (or NULL to use default) */
+ const char *filename;
+};
+
/**
* Calculate static inline sanboot API function name
*
@@ -165,10 +171,10 @@ void san_unhook ( unsigned int drive );
* Attempt to boot from a SAN device
*
* @v drive Drive number
- * @v filename Filename (or NULL to use default)
+ * @v config Boot configuration parameters
* @ret rc Return status code
*/
-int san_boot ( unsigned int drive, const char *filename );
+int san_boot ( unsigned int drive, struct san_boot_config *config );
/**
* Describe SAN devices for SAN-booted operating system
diff --git a/src/include/usr/autoboot.h b/src/include/usr/autoboot.h
index 3719b82..a081a70 100644
--- a/src/include/usr/autoboot.h
+++ b/src/include/usr/autoboot.h
@@ -14,6 +14,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct net_device;
struct uri;
struct settings;
+struct san_boot_config;
/** uriboot() flags */
enum uriboot_flags {
@@ -33,7 +34,7 @@ extern void set_autoboot_ll_addr ( const void *ll_addr, size_t len,
extern int uriboot ( struct uri *filename, struct uri **root_paths,
unsigned int root_path_count, int drive,
- const char *san_filename, unsigned int flags );
+ struct san_boot_config *san_config, unsigned int flags );
extern struct uri *
fetch_next_server_and_filename ( struct settings *settings );
extern int netboot ( struct net_device *netdev );
diff --git a/src/interface/efi/efi_block.c b/src/interface/efi/efi_block.c
index 11d1115..e81d6bb 100644
--- a/src/interface/efi/efi_block.c
+++ b/src/interface/efi/efi_block.c
@@ -583,13 +583,13 @@ static int efi_block_filename ( unsigned int drive, EFI_HANDLE handle,
* @v drive Drive number
* @v handle Filesystem handle
* @v path Block device path
- * @v filename Filename (or NULL to use default)
+ * @v config Boot configuration parameters
* @v fspath Filesystem device path to fill in
* @ret rc Return status code
*/
static int efi_block_match ( unsigned int drive, EFI_HANDLE handle,
EFI_DEVICE_PATH_PROTOCOL *path,
- const char *filename,
+ struct san_boot_config *config,
EFI_DEVICE_PATH_PROTOCOL **fspath ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
EFI_GUID *protocol = &efi_device_path_protocol_guid;
@@ -624,8 +624,10 @@ static int efi_block_match ( unsigned int drive, EFI_HANDLE handle,
drive, efi_devpath_text ( u.path ) );
/* Check if filesystem contains boot filename */
- if ( ( rc = efi_block_filename ( drive, handle, filename ) ) != 0 )
+ if ( ( rc = efi_block_filename ( drive, handle,
+ config->filename ) ) != 0 ) {
goto err_filename;
+ }
/* Success */
rc = 0;
@@ -642,12 +644,12 @@ static int efi_block_match ( unsigned int drive, EFI_HANDLE handle,
*
* @v drive Drive number
* @v handle Block device handle
- * @v filename Filename (or NULL to use default)
+ * @v config Boot configuration parameters
* @v fspath Filesystem device path to fill in
* @ret rc Return status code
*/
static int efi_block_scan ( unsigned int drive, EFI_HANDLE handle,
- const char *filename,
+ struct san_boot_config *config,
EFI_DEVICE_PATH_PROTOCOL **fspath ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
EFI_GUID *protocol = &efi_device_path_protocol_guid;
@@ -690,7 +692,7 @@ static int efi_block_scan ( unsigned int drive, EFI_HANDLE handle,
/* Check for a matching filesystem */
if ( ( rc = efi_block_match ( drive, handles[i], u.path,
- filename, fspath ) ) != 0 )
+ config, fspath ) ) != 0 )
continue;
break;
@@ -847,10 +849,11 @@ static int efi_block_local ( EFI_HANDLE handle ) {
* Boot from EFI block device
*
* @v drive Drive number
- * @v filename Filename (or NULL to use default)
+ * @v config Boot configuration parameters
* @ret rc Return status code
*/
-static int efi_block_boot ( unsigned int drive, const char *filename ) {
+static int efi_block_boot ( unsigned int drive,
+ struct san_boot_config *config ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
EFI_DEVICE_PATH_PROTOCOL *fspath = NULL;
EFI_HANDLE *handles;
@@ -943,13 +946,13 @@ static int efi_block_boot ( unsigned int drive, const char *filename ) {
DBGC ( vdrive, "EFIBLK %#02x attempting to boot\n", vdrive );
/* Scan for a matching filesystem within this drive */
- if ( ( rc = efi_block_scan ( vdrive, handle, filename,
+ if ( ( rc = efi_block_scan ( vdrive, handle, config,
&fspath ) ) != 0 ) {
continue;
}
/* Attempt to boot from the matched filesystem */
- rc = efi_block_exec ( vdrive, fspath, filename );
+ rc = efi_block_exec ( vdrive, fspath, config->filename );
break;
}
diff --git a/src/usr/autoboot.c b/src/usr/autoboot.c
index d1f2596..4b64ca8 100644
--- a/src/usr/autoboot.c
+++ b/src/usr/autoboot.c
@@ -116,7 +116,7 @@ const struct setting skip_san_boot_setting __setting ( SETTING_SANBOOT_EXTRA,
* @v root_paths Root path(s)
* @v root_path_count Number of root paths
* @v drive SAN drive (if applicable)
- * @v san_filename SAN filename (or NULL to use default)
+ * @v san_config SAN boot configuration parameters
* @v flags Boot action flags
* @ret rc Return status code
*
@@ -128,8 +128,9 @@ const struct setting skip_san_boot_setting __setting ( SETTING_SANBOOT_EXTRA,
*/
int uriboot ( struct uri *filename, struct uri **root_paths,
unsigned int root_path_count, int drive,
- const char *san_filename, unsigned int flags ) {
+ struct san_boot_config *san_config, unsigned int flags ) {
struct image *image;
+ const char *san_filename;
int rc;
/* Hook SAN device, if applicable */
@@ -182,11 +183,12 @@ int uriboot ( struct uri *filename, struct uri **root_paths,
/* Attempt SAN boot if applicable */
if ( ! ( flags & URIBOOT_NO_SAN_BOOT ) ) {
+ san_filename = san_config->filename;
if ( fetch_intz_setting ( NULL, &skip_san_boot_setting) == 0 ) {
printf ( "Booting%s%s from SAN device %#02x\n",
( san_filename ? " " : "" ),
( san_filename ? san_filename : "" ), drive );
- rc = san_boot ( drive, san_filename );
+ rc = san_boot ( drive, san_config );
printf ( "Boot from SAN device %#02x failed: %s\n",
drive, strerror ( rc ) );
} else {
@@ -387,6 +389,7 @@ static int have_pxe_menu ( void ) {
* @ret rc Return status code
*/
int netboot ( struct net_device *netdev ) {
+ struct san_boot_config san_config;
struct uri *filename;
struct uri *root_path;
char *san_filename;
@@ -421,6 +424,10 @@ int netboot ( struct net_device *netdev ) {
/* Fetch SAN filename (if any) */
san_filename = fetch_san_filename ( NULL );
+ /* Construct SAN boot configuration parameters */
+ memset ( &san_config, 0, sizeof ( san_config ) );
+ san_config.filename = san_filename;
+
/* If we have both a filename and a root path, ignore an
* unsupported or missing URI scheme in the root path, since
* it may represent an NFS root.
@@ -442,7 +449,7 @@ int netboot ( struct net_device *netdev ) {
/* Boot using next server, filename and root path */
if ( ( rc = uriboot ( filename, &root_path, ( root_path ? 1 : 0 ),
- san_default_drive(), san_filename,
+ san_default_drive(), &san_config,
( root_path ? 0 : URIBOOT_NO_SAN ) ) ) != 0 )
goto err_uriboot;