aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-07-03 11:45:02 +0100
committerMatt Fleming <matt.fleming@intel.com>2013-07-03 12:14:35 +0100
commit0aad5be4e47048a91ce007fdb630e407cb67c381 (patch)
tree918b46d2ba333d829bb6305c199ae68971495f60
parentb63e0f20f7f6717eaca978a0c499b953949c6dd2 (diff)
downloadsyslinux-0aad5be4e47048a91ce007fdb630e407cb67c381.tar.gz
syslinux-0aad5be4e47048a91ce007fdb630e407cb67c381.tar.xz
syslinux-0aad5be4e47048a91ce007fdb630e407cb67c381.zip
efi: only read ADV when booting from disksyslinux-6.01-pre6
We aren't expecting to be able to access ldlinux.sys when booting over PXE. Follow the pre-5.00 behaviour and simply initialise the ADV buffer without even attempting to open the file. Also, delete all references to EXTLINUX, we do not support it under EFI. Without this patch we hang in efi_open() when booting PXELINUX because no root volume is set as we're not booting from disk. This regression was caused by commit a17fdfb8 ("com32: Catch up with GCC changes to ctor/dtor funcs") because now constructors are actually being invoked on EFI and efi_adv_init() is called by __syslinux_init(). Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r--efi/adv.c100
-rw-r--r--efi/adv.h2
2 files changed, 17 insertions, 85 deletions
diff --git a/efi/adv.c b/efi/adv.c
index b390fd8f..4056db15 100644
--- a/efi/adv.c
+++ b/efi/adv.c
@@ -24,11 +24,10 @@
*/
#define _GNU_SOURCE
+#include <syslinux/config.h>
#include <string.h>
#include "adv.h"
-#define IS_SYSLINUX /* remove this: test build only */
-
unsigned char syslinux_adv[2 * ADV_SIZE];
static void cleanup_adv(unsigned char *advbuf)
@@ -183,93 +182,29 @@ int read_adv(const char *path, const char *cfg)
return err;
}
-/* For EFI platform, initialize ADV by opening ldlinux.sys or extlinux.sys
+/* For EFI platform, initialize ADV by opening ldlinux.sys
* as configured and return the primary (adv0) and alternate (adv1)
* data into caller's buffer. File remains open for subsequent
- * operations. This routine is to be called from comboot
- * vector. Currently only IS_SYSLINUX or IS_EXTLINUX is supported
- *
- * TODO:
- * 1. Need to set the path to ldlinux.sys or extlinux.sys; currently null
- * 2. What if there are errors?
+ * operations. This routine is to be called from comboot vector.
*/
void efi_adv_init(void)
{
- char *name;
- int rv;
- int err = 0;
- unsigned char *advbuf = syslinux_adv;
- EFI_FILE_HANDLE fd; /* handle to ldlinux.sys or extlinux.sys */
- CHAR16 *file;
- EFI_FILE_INFO st, xst;
+ union syslinux_derivative_info sdi;
-#if defined IS_SYSLINUX
- name = SYSLINUX_FILE;
-#elif defined IS_EXTLINUX
- name = EXTLINUX_FILE;
-#else
- #error "IS_SYSLINUX or IS_EXTLINUX must be specified to build ADV"
-#endif
- /* FIXME: No path defined to syslinux/extlinux file */
- rv = make_filespec(&file, "", name);
- if (rv < 0 || !file) {
- efi_errno = EFI_OUT_OF_RESOURCES;
- efi_perror(L"efi_adv_init:");
- return;
- }
+ get_derivative_info(&sdi);
- fd = efi_open(file, EFI_FILE_MODE_READ);
- if (fd == (EFI_FILE_HANDLE)NULL) {
- err = -1;
- efi_printerr(L"efi_adv_init: Unable to open file %s\n", file);
- } else if (efi_fstat(fd, &st)) {
- err = -1;
- efi_printerr(L"efi_adv_init: Unable to get info for file %s\n", file);
- } else if (st.FileSize < 2 * ADV_SIZE) {
- /* Too small to be useful */
- err = -2;
- efi_printerr(L"efi_adv_init: File %s size too small to be useful %s\n", file);
- } else if (efi_xpread(fd, advbuf, 2 * ADV_SIZE,
- st.FileSize - 2 * ADV_SIZE) != 2 * ADV_SIZE) {
- err = -1;
- efi_printerr(L"efi_adv_init: Error reading ADV data from file %s\n", file);
- } else {
- /* We got it... maybe? */
+ if (sdi.c.filesystem == SYSLINUX_FS_SYSLINUX)
+ read_adv("", SYSLINUX_FILE);
+ else {
__syslinux_adv_ptr = &syslinux_adv[8]; /* skip head, csum */
__syslinux_adv_size = ADV_LEN;
- err = syslinux_validate_adv(advbuf) ? -2 : 0;
- if (!err) {
- /* Got a good one*/
- efi_clear_attributes(fd);
-
- /* Need to re-open read-write */
- efi_close(fd);
- /* There is no SYNC attribute with EFI open */
- fd = efi_open(file, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE);
- /* on error, only explicit comparison with null handle works */
- if (fd == (EFI_FILE_HANDLE)NULL) {
- err = -1;
- efi_perror(L"efi_adv_init:");
- } else if (efi_fstat(fd, &xst) || xst.FileSize != st.FileSize) {
- /* device/inode info don't exist in the EFI file info structure */
- efi_perror(L"efi_adv_init: file status error/mismatch");
- err = -2;
- }
- /* TODO: Do we need to set attributes of the sys file? */
- }
- }
- if (file)
- free(file);
- if (fd != 0)
- efi_close(fd);
- /* TODO: In case of errors, we could set efi_errno to EFI_LOAD_ERROR
- * to mean that ADV could not be loaded up
- */
+ syslinux_validate_adv(syslinux_adv);
+ }
}
/* For EFI platform, write 2 * ADV_SIZE data to the file opened
- * at ADV initialization. (i.e ldlinux.sys or extlinux.sys).
+ * at ADV initialization. (i.e ldlinux.sys).
*
* TODO:
* 1. Validate assumption: write back to file from __syslinux_adv_ptr
@@ -284,17 +219,16 @@ int efi_adv_write(void)
unsigned char *advbuf = syslinux_adv;
int rv;
int err = 0;
- EFI_FILE_HANDLE fd; /* handle to ldlinux.sys or extlinux.sys */
+ EFI_FILE_HANDLE fd; /* handle to ldlinux.sys */
CHAR16 *file;
EFI_FILE_INFO st, xst;
+ union syslinux_derivative_info sdi;
+
+ get_derivative_info(&sdi);
+ if (sdi.c.filesystem != SYSLINUX_FS_SYSLINUX)
+ return -1;
-#if defined IS_SYSLINUX
name = SYSLINUX_FILE;
-#elif defined IS_EXTLINUX
- name = EXTLINUX_FILE;
-#else
- #error "IS_SYSLINUX or IS_EXTLINUX must be specified to build ADV"
-#endif
rv = make_filespec(&file, "", name);
if (rv < 0 || !file) {
efi_errno = EFI_OUT_OF_RESOURCES;
diff --git a/efi/adv.h b/efi/adv.h
index e8ccb352..419ad3ba 100644
--- a/efi/adv.h
+++ b/efi/adv.h
@@ -8,9 +8,7 @@
/* ADV information */
#define ADV_SIZE 512 /* Total size */
#define ADV_LEN (ADV_SIZE-3*4) /* Usable data size */
-/* Currently, one of IS_SYSLINUX or IS_EXTLINUX must be defined for ADV */
#define SYSLINUX_FILE "ldlinux.sys"
-#define EXTLINUX_FILE "extlinux.sys"
#define ADV_MAGIC1 0x5a2d2fa5 /* Head signature */
#define ADV_MAGIC2 0xa3041767 /* Total checksum */