aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-07-17 13:04:30 +0100
committerMatt Fleming <matt.fleming@intel.com>2013-07-17 22:27:16 +0100
commitd2f94e74fbd60bf491753895d2474105efb3dedf (patch)
tree353419f9461eecd7e31ecbf8d6b3a9b361018c9f
parent787d7e568fe08d7080d2cd03cd9ee27c327eca67 (diff)
downloadsyslinux-d2f94e74fbd60bf491753895d2474105efb3dedf.tar.gz
syslinux-d2f94e74fbd60bf491753895d2474105efb3dedf.tar.xz
syslinux-d2f94e74fbd60bf491753895d2474105efb3dedf.zip
PXELINUX: Add bios memscan function
We can mark the memory region occupied by the PXE stack as SMT_TERMINAL provided that KeepPXE isn't set. Historically some very old non-relocatable kernel images (memtest86+) have a load address that falls within the PXE stack region, so we need to attempt to load into that region if at all possible. Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r--core/fs/pxe/bios.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/core/fs/pxe/bios.c b/core/fs/pxe/bios.c
index 81aa715c..5f618248 100644
--- a/core/fs/pxe/bios.c
+++ b/core/fs/pxe/bios.c
@@ -1,4 +1,5 @@
#include <syslinux/firmware.h>
+#include <syslinux/memscan.h>
#include <core.h>
#include "pxe.h"
#include <net.h>
@@ -10,6 +11,9 @@ static uint16_t real_base_mem; /* Amount of DOS memory after freeing */
static bool has_gpxe;
static uint32_t gpxe_funcs;
+static addr_t pxe_code_start, pxe_code_size;
+static addr_t pxe_data_start, pxe_data_size;
+
/*
* Validity check on possible !PXE structure in buf
* return 1 for success, 0 for failure.
@@ -88,6 +92,29 @@ static const struct pxenv_t *memory_scan_for_pxenv_struct(void)
return memory_scan(0x10000, is_pxenv);
}
+static int pxelinux_scan_memory(scan_memory_callback_t callback, void *data)
+{
+ int rv = 0;
+
+ /*
+ * If we are planning on calling unload_pxe() and unmapping the PXE
+ * region before we transfer control away from PXELINUX we can mark
+ * that region as SMT_TERMINAL to indicate that the region will
+ * become free at some point in the future.
+ */
+ if (!KeepPXE) {
+ dprintf("Marking PXE code region 0x%x - 0x%x as SMT_TERMINAL\n",
+ pxe_code_start, pxe_code_start + pxe_code_size);
+ rv = callback(data, pxe_code_start, pxe_code_size, SMT_TERMINAL);
+
+ dprintf("Marking PXE data region 0x%x - 0x%x as SMT_TERMINAL\n",
+ pxe_data_start, pxe_data_start + pxe_data_size);
+ rv = callback(data, pxe_data_start, pxe_data_size, SMT_TERMINAL);
+ }
+
+ return rv;
+}
+
/*
* Find the !PXE structure; we search for the following, in order:
*
@@ -204,6 +231,14 @@ int pxe_init(bool quiet)
printf("UNDI data segment at %04X len %04X\n", data_seg, data_len);
}
+ pxe_code_start = code_seg << 4;
+ pxe_code_size = code_len;
+
+ pxe_data_start = data_seg << 4;
+ pxe_data_size = data_len;
+
+ syslinux_memscan_new(pxelinux_scan_memory);
+
code_seg = code_seg + ((code_len + 15) >> 4);
data_seg = data_seg + ((data_len + 15) >> 4);