aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Langasek <steve.langasek@canonical.com>2012-07-20 13:51:46 -0700
committerMatt Fleming <matt.fleming@intel.com>2012-07-27 10:57:21 +0100
commit454a7bd18bb4632f124c6cf77845f2e9988b0c7c (patch)
tree516859d3d4a1dd94b829b1cf97510dc11fdf2bd4
parent562349fbf5ee542e96feae675aaa507ab56ef346 (diff)
downloadefilinux-454a7bd18bb4632f124c6cf77845f2e9988b0c7c.tar.gz
Support loading kernels by relative path
Allow specifying paths to files (kernel images, initrds) relative to the boot drive instead of hard-coding a disk path / number in the efilinux.cfg. Signed-off-by: Steve Langasek <steve.langasek@canonical.com> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r--entry.c2
-rw-r--r--fs/fs.c19
-rw-r--r--fs/fs.h2
-rw-r--r--loaders/bzimage/bzimage.c14
4 files changed, 26 insertions, 11 deletions
diff --git a/entry.c b/entry.c
index 5e165b1..b5155af 100644
--- a/entry.c
+++ b/entry.c
@@ -323,7 +323,7 @@ read_config_file(EFI_LOADED_IMAGE *image, CHAR16 **options,
if (err != TRUE)
return FALSE;
- err = file_open(path, &file);
+ err = file_open(image, path, &file);
if (err != EFI_SUCCESS)
return FALSE;
diff --git a/fs/fs.c b/fs/fs.c
index 8a45442..477afd1 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -73,7 +73,7 @@ handle_to_dev(EFI_HANDLE *handle)
* @file: used to return a pointer to the allocated file on success
*/
EFI_STATUS
-file_open(CHAR16 *name, struct file **file)
+file_open(EFI_LOADED_IMAGE *image, CHAR16 *name, struct file **file)
{
EFI_FILE_HANDLE fh;
struct file *f;
@@ -91,10 +91,19 @@ file_open(CHAR16 *name, struct file **file)
break;
}
- if (!name[dev_len] || !dev_len)
- goto notfound;
+ if (!name[dev_len] || !dev_len) {
+ dev_len = 0;
+ if (!image)
+ goto notfound;
+
+ i = handle_to_dev(image->DeviceHandle);
+ if (i < 0 || i >= nr_fs_devices)
+ goto notfound;
- name[dev_len] = 0;
+ f->handle = fs_devices[i].fh;
+ goto found;
+ } else
+ name[dev_len++] = 0;
if (name[0] >= '0' && name[0] <= '9') {
i = Atoi(name);
@@ -126,7 +135,7 @@ file_open(CHAR16 *name, struct file **file)
found:
/* Strip the device name */
- filename = name + dev_len + 1;
+ filename = name + dev_len;
/* skip any path separators */
while (*filename == ':' || *filename == '\\')
diff --git a/fs/fs.h b/fs/fs.h
index 0f76d0c..4a6c71f 100644
--- a/fs/fs.h
+++ b/fs/fs.h
@@ -98,7 +98,7 @@ file_size(struct file *f, UINT64 *size)
return EFI_SUCCESS;
}
-extern EFI_STATUS file_open(CHAR16 *name, struct file **file);
+extern EFI_STATUS file_open(EFI_LOADED_IMAGE *image, CHAR16 *name, struct file **file);
extern EFI_STATUS file_close(struct file *f);
extern void list_boot_devices(void);
diff --git a/loaders/bzimage/bzimage.c b/loaders/bzimage/bzimage.c
index 8789876..d323874 100644
--- a/loaders/bzimage/bzimage.c
+++ b/loaders/bzimage/bzimage.c
@@ -54,7 +54,7 @@ struct initrd {
struct file *file;
};
-static void parse_initrd(struct boot_params *buf, char *cmdline)
+static void parse_initrd(EFI_LOADED_IMAGE *image, struct boot_params *buf, char *cmdline)
{
EFI_PHYSICAL_ADDRESS addr;
struct initrd *initrds;
@@ -116,7 +116,7 @@ static void parse_initrd(struct boot_params *buf, char *cmdline)
*n = '\0';
- err = file_open(filename, &rdfile);
+ err = file_open(image, filename, &rdfile);
if (err != EFI_SUCCESS)
goto close_handles;
@@ -174,6 +174,7 @@ load_kernel(EFI_HANDLE image, CHAR16 *name, char *_cmdline)
EFI_PHYSICAL_ADDRESS pref_address;
struct boot_params *boot_params;
EFI_MEMORY_DESCRIPTOR *map_buf;
+ EFI_LOADED_IMAGE *info = NULL;
struct e820_entry *e820_map;
UINT64 setup_sz, init_size;
struct boot_params *buf;
@@ -187,7 +188,12 @@ load_kernel(EFI_HANDLE image, CHAR16 *name, char *_cmdline)
UINT64 size;
int i, j = 0;
- err = file_open(name, &file);
+ err = handle_protocol(image, &LoadedImageProtocol, (void **)&info);
+ if (err != EFI_SUCCESS)
+ info = NULL;
+
+ err = file_open(info, name, &file);
+
if (err != EFI_SUCCESS)
goto out;
@@ -279,7 +285,7 @@ load_kernel(EFI_HANDLE image, CHAR16 *name, char *_cmdline)
cmdline = (char *)(UINTN)addr;
memcpy(cmdline, _cmdline, strlen(_cmdline) + 1);
- parse_initrd(buf, cmdline);
+ parse_initrd(info, buf, cmdline);
buf->hdr.cmd_line_ptr = (UINT32)(UINTN)cmdline;