1
/******************************************************************************
4
* 32-bit flat memory-map routines for relocating Multiboot structures
5
* and modules. This is most easily done early with paging disabled.
7
* Copyright (c) 2009, Citrix Systems, Inc.
10
* Keir Fraser <keir.fraser@citrix.com>
17
" mov $_start,%edi \n"
20
" sub $1b-_start,%esi \n"
21
" mov $__bss_start-_start,%ecx \n"
31
typedef unsigned int u32;
32
#include "../../../include/xen/multiboot.h"
36
static void *memcpy(void *dest, const void *src, unsigned int n)
38
char *s = (char *)src, *d = dest;
44
static void *reloc_mbi_struct(void *old, unsigned int bytes)
46
static void *alloc = &_start;
47
alloc = (void *)(((unsigned long)alloc - bytes) & ~15ul);
48
return memcpy(alloc, old, bytes);
51
static char *reloc_mbi_string(char *old)
54
for ( p = old; *p != '\0'; p++ )
56
return reloc_mbi_struct(old, p - old + 1);
59
multiboot_info_t *reloc(multiboot_info_t *mbi_old)
61
multiboot_info_t *mbi = reloc_mbi_struct(mbi_old, sizeof(*mbi));
64
if ( mbi->flags & MBI_CMDLINE )
65
mbi->cmdline = (u32)reloc_mbi_string((char *)mbi->cmdline);
67
if ( mbi->flags & MBI_MODULES )
69
module_t *mods = reloc_mbi_struct(
70
(module_t *)mbi->mods_addr, mbi->mods_count * sizeof(module_t));
73
mbi->mods_addr = (u32)mods;
75
for ( i = 0; i < mbi->mods_count; i++ )
78
mods[i].string = (u32)reloc_mbi_string((char *)mods[i].string);
79
if ( mods[i].mod_end > max_addr )
80
max_addr = mods[i].mod_end;
84
* 32-bit Xen only maps bottom 1GB of memory at boot time. Relocate
85
* modules which extend beyond this (GRUB2 in particular likes to
86
* place modules as high as possible below 4GB).
88
#define BOOTMAP_END (1ul<<30) /* 1GB */
89
if ( (XEN_BITSPERLONG == 32) && (max_addr > BOOTMAP_END) )
91
char *mod_alloc = (char *)BOOTMAP_END;
92
for ( i = 0; i < mbi->mods_count; i++ )
93
mod_alloc -= mods[i].mod_end - mods[i].mod_start;
94
for ( i = 0; i < mbi->mods_count; i++ )
96
u32 mod_len = mods[i].mod_end - mods[i].mod_start;
97
mods[i].mod_start = (u32)memcpy(
98
mod_alloc, (char *)mods[i].mod_start, mod_len);
99
mods[i].mod_end = mods[i].mod_start + mod_len;
100
mod_alloc += mod_len;
105
if ( mbi->flags & MBI_MEMMAP )
106
mbi->mmap_addr = (u32)reloc_mbi_struct(
107
(memory_map_t *)mbi->mmap_addr, mbi->mmap_length);
109
/* Mask features we don't understand or don't relocate. */
110
mbi->flags &= (MBI_MEMLIMITS |