static struct syslinux_movelist *ml = NULL;
static struct syslinux_memmap *mmap = NULL, *amap = NULL;
static struct multiboot_header *mbh;
-static addr_t mboot_high_water_mark = 0;
+static addr_t mboot_high_water_mark = 0x100000;
/*
* Note: although there is no such thing in the spec, at least Xen makes
* As a precaution, this also pads the data with zero up to the next
* alignment datum.
*/
-addr_t map_data(const void *data, size_t len, int align, bool high)
+addr_t map_data(const void *data, size_t len, size_t align, int flags)
{
- addr_t start = high ? mboot_high_water_mark : 0x800;
- addr_t pad = -len & (align-1);
- addr_t xlen = len+pad;
+ addr_t start = (flags & MAP_HIGH) ? mboot_high_water_mark : 0x2000;
+ addr_t pad = (flags & MAP_NOPAD) ? 0 : -len & (align-1);
+ addr_t xlen = len+pad;
if (syslinux_memmap_find(amap, SMT_FREE, &start, &xlen, align) ||
syslinux_add_memmap(&amap, start, len+pad, SMT_ALLOC) ||
if (!string)
return 0;
else
- return map_data(string, strlen(string)+1, 4, true);
+ return map_data(string, strlen(string)+1, 1, 0);
}
int map_image(void *ptr, size_t len)
sh = (Elf32_Shdr *)((char *)eh + eh->e_shoff);
len = eh->e_shentsize * eh->e_shnum;
- addr = map_data(sh, len, 4096, true);
+ /*
+ * Align this, but don't pad -- in general this means a bunch of
+ * smaller sections gets packed into a single page.
+ */
+ addr = map_data(sh, len, 4096, MAP_HIGH|MAP_NOPAD);
if (!addr) {
error("Failed to map symbol table\n");
goto bail;
align = sh[i].sh_addralign ? sh[i].sh_addralign : 0;
addr = map_data((char *)ptr + sh[i].sh_offset, sh[i].sh_size,
- align, true);
+ align, MAP_HIGH);
if (!addr) {
error("Failed to map symbol section\n");
goto bail;
return -1;
}
+ map_list = map_data(mod_list, list_size, 16, 0);
+ if (!map_list) {
+ printf("Cannot map module list\n");
+ return -1;
+ }
+
for (i = 0; i < nmodules; i++) {
addr_t mod_map = 0;
addr_t cmd_map = 0;
+ dprintf("Module %d cmdline: \"%s\"\n", i, modules[i].cmdline);
+
cmd_map = map_string(modules[i].cmdline);
- mod_map = map_data(modules[i].data, modules[i].len, 4096, true);
+ mod_map = map_data(modules[i].data, modules[i].len, 4096, MAP_HIGH);
if (!mod_map) {
printf("Failed to map module (memory fragmentation issue?)\n");
return -1;
mod_list[i].pad = 0;
}
- map_list = map_data(mod_list, list_size, 16, false);
- if (!map_list) {
- printf("Cannot map module list\n");
- return -1;
- }
-
mbinfo.flags |= MB_INFO_MODS;
mbinfo.mods_count = nmodules;
mbinfo.mods_addr = map_list;
static int get_modules(char **argv, struct module_data **mdp)
{
char **argp, **argx;
- struct module_data *md, *mp;
+ struct module_data *mp;
int rv;
int module_count = 1;
int arglen;
module_count++;
}
- *mdp = md = malloc(module_count * sizeof(struct module_data));
- if (!md) {
+ *mdp = mp = malloc(module_count * sizeof(struct module_data));
+ if (!mp) {
error("Out of memory!\n");
return -1;
}
- mp = md;
argp = argv;
while (*argp) {
/* Note: it seems Grub transparently decompresses all compressed files,
arglen += strlen(*argx)+1;
if (arglen == 0) {
- mp->cmdline = NULL;
+ mp->cmdline = strdup("");
} else {
char *p;
- md->cmdline = p = malloc(arglen);
+ mp->cmdline = p = malloc(arglen);
for ( ; *argp && strcmp(*argp, module_separator); argp++) {
p = strpcpy(p, *argp);
*p++ = ' ';
if (map_image(modules[0].data, modules[0].len))
return 1;
- /* Map auxilliary images */
- if (nmodules > 1) {
- if (map_modules(modules+1, nmodules-1))
- return 1;
- }
-
/* Map the mbinfo structure */
- regs.ebx = map_data(&mbinfo, sizeof mbinfo, 4, false);
+ regs.ebx = map_data(&mbinfo, sizeof mbinfo, 4, 0);
if (!regs.ebx) {
error("Failed to map Multiboot info structure!\n");
return 1;
/* Map the primary command line */
if (modules[0].cmdline) {
mbinfo.cmdline = map_string(modules[0].cmdline);
+ dprintf("Main cmdline: \"%s\"\n", modules[0].cmdline);
if (mbinfo.cmdline)
mbinfo.flags |= MB_INFO_CMDLINE;
}
+ /* Map auxilliary images */
+ if (nmodules > 1) {
+ if (map_modules(modules+1, nmodules-1))
+ return 1;
+ }
+
/* Add auxilliary information */
mboot_make_memmap();
mboot_apm();
extern struct syslinux_pm_regs regs;
/* map.c */
-addr_t map_data(const void *data, size_t len, int align, bool high);
+#define MAP_HIGH 1
+#define MAP_NOPAD 2
+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);
mbinfo.mem_upper = (highmem - 0x100000) >> 10;
mbinfo.flags |= MB_INFO_MEMORY;
- /* XXX: Should this be +4? */
+ /* The spec says this address should be +4, but Grub disagrees */
mbinfo.mmap_addr = map_data(ard, nmap*sizeof *ard, 4, false);
if (mbinfo.mmap_addr) {
mbinfo.mmap_length = nmap*sizeof *ard;