Upstream-Status: Backport [d2f94e74fbd60bf491753895d2474105efb3dedf] Signed-off-by: Jonathan Liu From 5d57e8eb46f209481069d70eaa778481f6fa3edb Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Wed, 17 Jul 2013 13:04:30 +0100 Subject: [PATCH 3/4] 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 --- core/fs/pxe/bios.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/core/fs/pxe/bios.c b/core/fs/pxe/bios.c index 81aa715..5f61824 100644 --- a/core/fs/pxe/bios.c +++ b/core/fs/pxe/bios.c @@ -1,4 +1,5 @@ #include +#include #include #include "pxe.h" #include @@ -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); -- 1.8.5.3