aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-05-02 13:47:29 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-05-02 13:50:17 -0700
commit01c5b4edde1409dfc5cc84c71342ef671399022c (patch)
treefcc8a0657516aa2ca77fa4436b2e308a47d7cc8a
parent873e07fbf78344e0041f29892e08f31820da87a4 (diff)
downloadsyslinux-01c5b4edde1409dfc5cc84c71342ef671399022c.tar.gz
syslinux-01c5b4edde1409dfc5cc84c71342ef671399022c.tar.xz
syslinux-01c5b4edde1409dfc5cc84c71342ef671399022c.zip
mboot: move map initialization out of map_image()
The amap/mmap initialization were buried randomly inside map_image(), which at the very least makes the code needlessly hard to read. Furthermore, it is at least possible that we may want to be able to map multiple images in the future. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--com32/mboot/map.c69
-rw-r--r--com32/mboot/mboot.c3
-rw-r--r--com32/mboot/mboot.h1
3 files changed, 38 insertions, 35 deletions
diff --git a/com32/mboot/map.c b/com32/mboot/map.c
index bdfcfcf0..b65c016a 100644
--- a/com32/mboot/map.c
+++ b/com32/mboot/map.c
@@ -78,6 +78,29 @@ addr_t map_string(const char *string)
return map_data(string, strlen(string)+1, 1, 0);
}
+int init_map(void)
+{
+ /*
+ * Note: mmap is the memory map (containing free and zeroed regions)
+ * needed by syslinux_shuffle_boot_pm(); amap is a map where we keep
+ * track ourselves which target memory ranges have already been
+ * allocated.
+ */
+ mmap = syslinux_memory_map();
+ amap = syslinux_dup_memmap(mmap);
+ if (!mmap || !amap) {
+ error("Failed to allocate initial memory map!\n");
+ return -1;
+ }
+
+#if DEBUG
+ dprintf("Initial memory map:\n");
+ syslinux_dump_memmap(stdout, mmap);
+#endif
+
+ return 0;
+}
+
int map_image(void *ptr, size_t len)
{
int mbh_len;
@@ -121,12 +144,6 @@ int map_image(void *ptr, size_t len)
}
}
- /*
- * Note: mmap is the memory map (containing free and zeroed regions)
- * needed by syslinux_shuffle_boot_pm(); amap is a map where we keep
- * track ourselves which target memory ranges have already been
- * allocated.
- */
if ( len < sizeof(Elf32_Ehdr) ||
memcmp(eh->e_ident, "\x7f""ELF\1\1\1", 6) ||
(eh->e_machine != EM_386 && eh->e_machine != EM_486 &&
@@ -138,18 +155,6 @@ int map_image(void *ptr, size_t len)
eh->e_phoff+eh->e_phentsize*eh->e_phnum > len )
eh = NULL; /* No valid ELF header found */
- mmap = syslinux_memory_map();
- amap = syslinux_dup_memmap(mmap);
- if (!mmap || !amap) {
- error("Failed to allocate initial memory map!\n");
- goto bail;
- }
-
-#if DEBUG
- dprintf("Initial memory map:\n");
- syslinux_dump_memmap(stdout, mmap);
-#endif
-
/*
* Note: the Multiboot Specification implies that AOUT_KLUDGE should
* have precedence over the ELF header. However, Grub disagrees, and
@@ -177,13 +182,13 @@ int map_image(void *ptr, size_t len)
if (syslinux_memmap_type(amap, addr, msize) != SMT_FREE) {
printf("Memory segment at 0x%08x (len 0x%08x) is unavailable\n",
addr, msize);
- goto bail; /* Memory region unavailable */
+ return -1; /* Memory region unavailable */
}
/* Mark this region as allocated in the available map */
if (syslinux_add_memmap(&amap, addr, msize, SMT_ALLOC)) {
error("Overlapping segments found in ELF header\n");
- goto bail;
+ return -1;
}
if (ph->p_filesz) {
@@ -191,14 +196,14 @@ int map_image(void *ptr, size_t len)
if (syslinux_add_movelist(&ml, addr, (addr_t)cptr+ph->p_offset,
dsize)) {
error("Failed to map PHDR data\n");
- goto bail;
+ return -1;
}
}
if (msize > dsize) {
/* Zero-filled region. Mark as a zero region in the memory map. */
if (syslinux_add_memmap(&mmap, addr+dsize, msize-dsize, SMT_ZERO)) {
error("Failed to map PHDR zero region\n");
- goto bail;
+ return -1;
}
}
if (addr+msize > mboot_high_water_mark)
@@ -224,7 +229,7 @@ int map_image(void *ptr, size_t len)
addr = map_data(sh, len, 4096, MAP_HIGH|MAP_NOPAD);
if (!addr) {
error("Failed to map symbol table\n");
- goto bail;
+ return -1;
}
mbinfo.flags |= MB_INFO_ELF_SHDR;
@@ -246,7 +251,7 @@ int map_image(void *ptr, size_t len)
align, MAP_HIGH);
if (!addr) {
error("Failed to map symbol section\n");
- goto bail;
+ return -1;
}
sh[i].sh_addr = addr;
}
@@ -268,38 +273,32 @@ int map_image(void *ptr, size_t len)
!= SMT_FREE) {
printf("Memory segment at 0x%08x (len 0x%08x) is unavailable\n",
mbh->load_addr, data_len+bss_len);
- goto bail; /* Memory region unavailable */
+ return -1; /* Memory region unavailable */
}
if (syslinux_add_memmap(&amap, mbh->load_addr,
data_len+bss_len, SMT_ALLOC)) {
error("Failed to claim a.out address space!\n");
- goto bail;
+ return -1;
}
if (data_len)
if (syslinux_add_movelist(&ml, mbh->load_addr, (addr_t)data_ptr,
data_len)) {
error("Failed to map a.out data\n");
- goto bail;
+ return -1;
}
if (bss_len)
if (syslinux_add_memmap(&mmap, mbh->load_end_addr, bss_len, SMT_ZERO)) {
error("Failed to map a.out bss\n");
- goto bail;
+ return -1;
}
if (mbh->bss_end_addr > mboot_high_water_mark)
mboot_high_water_mark = mbh->bss_end_addr;
} else {
error("Invalid Multiboot image: neither ELF header nor a.out kludge found\n");
- goto bail;
+ return -1;
}
return 0;
-
- bail:
- syslinux_free_memmap(amap);
- syslinux_free_memmap(mmap);
- syslinux_free_movelist(ml);
- return -1;
}
/*
diff --git a/com32/mboot/mboot.c b/com32/mboot/mboot.c
index b1b2c77a..7103b3a3 100644
--- a/com32/mboot/mboot.c
+++ b/com32/mboot/mboot.c
@@ -185,6 +185,9 @@ int main(int argc, char *argv[])
return 1; /* Failure */
}
+ if (init_map())
+ return 1; /* Failed to allocate intitial map */
+
/*
* Map the primary image. This should be done before mapping anything
* else, since it will have fixed address requirements.
diff --git a/com32/mboot/mboot.h b/com32/mboot/mboot.h
index c05d69f1..19a98e00 100644
--- a/com32/mboot/mboot.h
+++ b/com32/mboot/mboot.h
@@ -81,6 +81,7 @@ addr_t map_data(const void *data, size_t len, size_t align, int flags);
addr_t map_string(const char *string);
int map_image(void *ptr, size_t len);
void mboot_run(int bootflags);
+int init_map(void);
/* mem.c */
void mboot_make_memmap(void);