diff mbox

[v5,06/16] x86/boot/reloc: create generic alloc and copy functions

Message ID 1471646606-28519-7-git-send-email-daniel.kiper@oracle.com (mailing list archive)
State New, archived
Headers show

Commit Message

Daniel Kiper Aug. 19, 2016, 10:43 p.m. UTC
Create generic alloc and copy functions. We need
separate tools for memory allocation and copy to
provide multiboot2 protocol support.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v4 - suggestions/fixes:
   - avoid assembly usage.

v3 - suggestions/fixes:
   - use "g" constraint instead of "r" for alloc_mem() bytes argument
     (suggested by Jan Beulich).

v2 - suggestions/fixes:
   - generalize new functions names
     (suggested by Jan Beulich),
   - reduce number of casts
     (suggested by Jan Beulich).
---
 xen/arch/x86/boot/reloc.c |   51 ++++++++++++++++++++++++++-------------------
 1 file changed, 30 insertions(+), 21 deletions(-)

Comments

Jan Beulich Aug. 25, 2016, 11:34 a.m. UTC | #1
>>> On 20.08.16 at 00:43, <daniel.kiper@oracle.com> wrote:
> Create generic alloc and copy functions. We need
> separate tools for memory allocation and copy to
> provide multiboot2 protocol support.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

The amount of casting in this patch alone looks very reasonable now.
Before ack-ing this and respective subsequent patches I'd like to see
the final result though. To facilitate that I have to re-raise a previously
asked question: Do you have a tree somewhere which one could use
to look at the final result?

Jan
Daniel Kiper Aug. 30, 2016, 2:32 p.m. UTC | #2
On Thu, Aug 25, 2016 at 05:34:31AM -0600, Jan Beulich wrote:
> >>> On 20.08.16 at 00:43, <daniel.kiper@oracle.com> wrote:
> > Create generic alloc and copy functions. We need
> > separate tools for memory allocation and copy to
> > provide multiboot2 protocol support.
> >
> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
>
> The amount of casting in this patch alone looks very reasonable now.
> Before ack-ing this and respective subsequent patches I'd like to see
> the final result though. To facilitate that I have to re-raise a previously
> asked question: Do you have a tree somewhere which one could use
> to look at the final result?

Sadly no.

Daniel
Jan Beulich Aug. 30, 2016, 3:12 p.m. UTC | #3
>>> On 30.08.16 at 16:32, <daniel.kiper@oracle.com> wrote:
> On Thu, Aug 25, 2016 at 05:34:31AM -0600, Jan Beulich wrote:
>> >>> On 20.08.16 at 00:43, <daniel.kiper@oracle.com> wrote:
>> > Create generic alloc and copy functions. We need
>> > separate tools for memory allocation and copy to
>> > provide multiboot2 protocol support.
>> >
>> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
>>
>> The amount of casting in this patch alone looks very reasonable now.
>> Before ack-ing this and respective subsequent patches I'd like to see
>> the final result though. To facilitate that I have to re-raise a previously
>> asked question: Do you have a tree somewhere which one could use
>> to look at the final result?
> 
> Sadly no.

Alternatively, could you simply send the final resulting source file?

Jan
Daniel Kiper Aug. 31, 2016, 3:13 p.m. UTC | #4
On Tue, Aug 30, 2016 at 09:12:45AM -0600, Jan Beulich wrote:
> >>> On 30.08.16 at 16:32, <daniel.kiper@oracle.com> wrote:
> > On Thu, Aug 25, 2016 at 05:34:31AM -0600, Jan Beulich wrote:
> >> >>> On 20.08.16 at 00:43, <daniel.kiper@oracle.com> wrote:
> >> > Create generic alloc and copy functions. We need
> >> > separate tools for memory allocation and copy to
> >> > provide multiboot2 protocol support.
> >> >
> >> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> >>
> >> The amount of casting in this patch alone looks very reasonable now.
> >> Before ack-ing this and respective subsequent patches I'd like to see
> >> the final result though. To facilitate that I have to re-raise a previously
> >> asked question: Do you have a tree somewhere which one could use
> >> to look at the final result?
> >
> > Sadly no.
>
> Alternatively, could you simply send the final resulting source file?

Please look below...

Daniel

/*
 * reloc.c
 *
 * 32-bit flat memory-map routines for relocating Multiboot structures
 * and modules. This is most easily done early with paging disabled.
 *
 * Copyright (c) 2009, Citrix Systems, Inc.
 *
 * Authors:
 *    Keir Fraser <keir@xen.org>
 */

/*
 * This entry point is entered from xen/arch/x86/boot/head.S with:
 *   - 0x4(%esp) = MULTIBOOT_INFORMATION_ADDRESS,
 *   - 0x8(%esp) = BOOT_TRAMPOLINE_ADDRESS.
 */
asm (
    "    .text                         \n"
    "    .globl _start                 \n"
    "_start:                           \n"
    "    jmp  reloc                    \n"
    );

typedef unsigned int u32;
#include "../../../include/xen/multiboot.h"

#define __stdcall	__attribute__((__stdcall__))

#define ALIGN_UP(arg, align) \
                (((arg) + (align) - 1) & ~((typeof(arg))(align) - 1))

static u32 alloc;

static u32 alloc_mem(u32 bytes)
{
    return alloc -= ALIGN_UP(bytes, 16);
}

static u32 copy_mem(u32 src, u32 bytes)
{
    u32 dst, dst_ret;

    dst = alloc_mem(bytes);
    dst_ret = dst;

    while ( bytes-- )
        *(char *)dst++ = *(char *)src++;

    return dst_ret;
}

static u32 copy_string(u32 src)
{
    u32 p;

    if ( src == 0 )
        return 0;

    for ( p = src; *(char *)p != '\0'; p++ )
        continue;

    return copy_mem(src, p - src + 1);
}

multiboot_info_t __stdcall *reloc(u32 mbi_old, u32 trampoline)
{
    multiboot_info_t *mbi;
    int i;

    alloc = trampoline;

    mbi = (multiboot_info_t *)copy_mem(mbi_old, sizeof(*mbi));

    if ( mbi->flags & MBI_CMDLINE )
        mbi->cmdline = copy_string(mbi->cmdline);

    if ( mbi->flags & MBI_MODULES )
    {
        module_t *mods;

        mbi->mods_addr = copy_mem(mbi->mods_addr, mbi->mods_count * sizeof(module_t));

        mods = (module_t *)mbi->mods_addr;

        for ( i = 0; i < mbi->mods_count; i++ )
        {
            if ( mods[i].string )
                mods[i].string = copy_string(mods[i].string);
        }
    }

    if ( mbi->flags & MBI_MEMMAP )
        mbi->mmap_addr = copy_mem(mbi->mmap_addr, mbi->mmap_length);

    if ( mbi->flags & MBI_LOADERNAME )
        mbi->boot_loader_name = copy_string(mbi->boot_loader_name);

    /* Mask features we don't understand or don't relocate. */
    mbi->flags &= (MBI_MEMLIMITS |
                   MBI_CMDLINE |
                   MBI_MODULES |
                   MBI_MEMMAP |
                   MBI_LOADERNAME);

    return mbi;
}
Jan Beulich Aug. 31, 2016, 3:25 p.m. UTC | #5
>>> On 31.08.16 at 17:13, <daniel.kiper@oracle.com> wrote:
> On Tue, Aug 30, 2016 at 09:12:45AM -0600, Jan Beulich wrote:
>> >>> On 30.08.16 at 16:32, <daniel.kiper@oracle.com> wrote:
>> > On Thu, Aug 25, 2016 at 05:34:31AM -0600, Jan Beulich wrote:
>> >> >>> On 20.08.16 at 00:43, <daniel.kiper@oracle.com> wrote:
>> >> > Create generic alloc and copy functions. We need
>> >> > separate tools for memory allocation and copy to
>> >> > provide multiboot2 protocol support.
>> >> >
>> >> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
>> >>
>> >> The amount of casting in this patch alone looks very reasonable now.
>> >> Before ack-ing this and respective subsequent patches I'd like to see
>> >> the final result though. To facilitate that I have to re-raise a previously
>> >> asked question: Do you have a tree somewhere which one could use
>> >> to look at the final result?
>> >
>> > Sadly no.
>>
>> Alternatively, could you simply send the final resulting source file?
> 
> Please look below...

I don't think that was the file at the end of the series, as asked
for above? There's no mb2 code in there afaics...

Jan
Daniel Kiper Aug. 31, 2016, 7:39 p.m. UTC | #6
On Wed, Aug 31, 2016 at 09:25:57AM -0600, Jan Beulich wrote:
> >>> On 31.08.16 at 17:13, <daniel.kiper@oracle.com> wrote:
> > On Tue, Aug 30, 2016 at 09:12:45AM -0600, Jan Beulich wrote:
> >> >>> On 30.08.16 at 16:32, <daniel.kiper@oracle.com> wrote:
> >> > On Thu, Aug 25, 2016 at 05:34:31AM -0600, Jan Beulich wrote:
> >> >> >>> On 20.08.16 at 00:43, <daniel.kiper@oracle.com> wrote:
> >> >> > Create generic alloc and copy functions. We need
> >> >> > separate tools for memory allocation and copy to
> >> >> > provide multiboot2 protocol support.
> >> >> >
> >> >> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> >> >>
> >> >> The amount of casting in this patch alone looks very reasonable now.
> >> >> Before ack-ing this and respective subsequent patches I'd like to see
> >> >> the final result though. To facilitate that I have to re-raise a previously
> >> >> asked question: Do you have a tree somewhere which one could use
> >> >> to look at the final result?
> >> >
> >> > Sadly no.
> >>
> >> Alternatively, could you simply send the final resulting source file?
> >
> > Please look below...
>
> I don't think that was the file at the end of the series, as asked
> for above? There's no mb2 code in there afaics...

I understood that you need reloc.c after this patch but it looks
that I was wrong. So, here it is after applying whole series.

Daniel

/*
 * reloc.c
 *
 * 32-bit flat memory-map routines for relocating Multiboot structures
 * and modules. This is most easily done early with paging disabled.
 *
 * Copyright (c) 2009, Citrix Systems, Inc.
 * Copyright (c) 2013-2016 Oracle and/or its affiliates. All rights reserved.
 *
 * Authors:
 *    Keir Fraser <keir@xen.org>
 *    Daniel Kiper <daniel.kiper@oracle.com>
 */

/*
 * This entry point is entered from xen/arch/x86/boot/head.S with:
 *   - 0x4(%esp) = MULTIBOOT_MAGIC,
 *   - 0x8(%esp) = MULTIBOOT_INFORMATION_ADDRESS,
 *   - 0xc(%esp) = BOOT_TRAMPOLINE_ADDRESS.
 */
asm (
    "    .text                         \n"
    "    .globl _start                 \n"
    "_start:                           \n"
    "    jmp  reloc                    \n"
    );

typedef unsigned int u32;
typedef unsigned long long u64;

#include "../../../include/xen/multiboot.h"
#include "../../../include/xen/multiboot2.h"

#define NULL		((void *)0)

#define __stdcall	__attribute__((__stdcall__))

#define ALIGN_UP(arg, align) \
                (((arg) + (align) - 1) & ~((typeof(arg))(align) - 1))

#define get_mb2_data(tag, type, member)   (((multiboot2_tag_##type##_t *)(tag))->member)
#define get_mb2_string(tag, type, member) ((u32)get_mb2_data(tag, type, member))

static u32 alloc;

static u32 alloc_mem(u32 bytes)
{
    return alloc -= ALIGN_UP(bytes, 16);
}

static void zero_mem(u32 s, u32 bytes)
{
    while ( bytes-- )
        *(char *)s++ = 0;
}

static u32 copy_mem(u32 src, u32 bytes)
{
    u32 dst, dst_ret;

    dst = alloc_mem(bytes);
    dst_ret = dst;

    while ( bytes-- )
        *(char *)dst++ = *(char *)src++;

    return dst_ret;
}

static u32 copy_string(u32 src)
{
    u32 p;

    if ( src == 0 )
        return 0;

    for ( p = src; *(char *)p != '\0'; p++ )
        continue;

    return copy_mem(src, p - src + 1);
}

static multiboot_info_t *mbi_mbi(u32 mbi_in)
{
    int i;
    multiboot_info_t *mbi_out;

    mbi_out = (multiboot_info_t *)copy_mem(mbi_in, sizeof(*mbi_out));

    if ( mbi_out->flags & MBI_CMDLINE )
        mbi_out->cmdline = copy_string(mbi_out->cmdline);

    if ( mbi_out->flags & MBI_MODULES )
    {
        module_t *mods;

        mbi_out->mods_addr = copy_mem(mbi_out->mods_addr,
                                      mbi_out->mods_count * sizeof(module_t));

        mods = (module_t *)mbi_out->mods_addr;

        for ( i = 0; i < mbi_out->mods_count; i++ )
        {
            if ( mods[i].string )
                mods[i].string = copy_string(mods[i].string);
        }
    }

    if ( mbi_out->flags & MBI_MEMMAP )
        mbi_out->mmap_addr = copy_mem(mbi_out->mmap_addr, mbi_out->mmap_length);

    if ( mbi_out->flags & MBI_LOADERNAME )
        mbi_out->boot_loader_name = copy_string(mbi_out->boot_loader_name);

    /* Mask features we don't understand or don't relocate. */
    mbi_out->flags &= (MBI_MEMLIMITS |
                       MBI_CMDLINE |
                       MBI_MODULES |
                       MBI_MEMMAP |
                       MBI_LOADERNAME);

    return mbi_out;
}

static multiboot_info_t *mbi2_mbi(u32 mbi_in)
{
    const multiboot2_memory_map_t *mmap_src;
    const multiboot2_tag_t *tag;
    module_t *mbi_out_mods = NULL;
    memory_map_t *mmap_dst;
    multiboot_info_t *mbi_out;
    u32 ptr;
    unsigned int i, mod_idx = 0;

    ptr = alloc_mem(sizeof(*mbi_out));
    mbi_out = (multiboot_info_t *)ptr;
    zero_mem(ptr, sizeof(*mbi_out));

    /* Skip Multiboot2 information fixed part. */
    ptr = ALIGN_UP(mbi_in + sizeof(multiboot2_fixed_t), MULTIBOOT2_TAG_ALIGN);

    /* Get the number of modules. */
    for ( tag = (multiboot2_tag_t *)ptr;
          (u32)tag - mbi_in < ((multiboot2_fixed_t *)mbi_in)->total_size;
          tag = (multiboot2_tag_t *)ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN) )
        if ( tag->type == MULTIBOOT2_TAG_TYPE_MODULE )
            ++mbi_out->mods_count;
        else if ( tag->type == MULTIBOOT2_TAG_TYPE_END )
            break;

    if ( mbi_out->mods_count )
    {
        mbi_out->flags = MBI_MODULES;
        mbi_out->mods_addr = alloc_mem(mbi_out->mods_count * sizeof(module_t));
        mbi_out_mods = (module_t *)mbi_out->mods_addr;
    }

    /* Skip Multiboot2 information fixed part. */
    ptr = ALIGN_UP(mbi_in + sizeof(multiboot2_fixed_t), MULTIBOOT2_TAG_ALIGN);

    /* Put all needed data into mbi_out. */
    for ( tag = (multiboot2_tag_t *)ptr;
          (u32)tag - mbi_in < ((multiboot2_fixed_t *)mbi_in)->total_size;
          tag = (multiboot2_tag_t *)ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN) )
        switch ( tag->type )
        {
        case MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME:
            mbi_out->flags |= MBI_LOADERNAME;
            ptr = get_mb2_string(tag, string, string);
            mbi_out->boot_loader_name = copy_string(ptr);
            break;

        case MULTIBOOT2_TAG_TYPE_CMDLINE:
            mbi_out->flags |= MBI_CMDLINE;
            ptr = get_mb2_string(tag, string, string);
            mbi_out->cmdline = copy_string(ptr);
            break;

        case MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO:
            mbi_out->flags |= MBI_MEMLIMITS;
            mbi_out->mem_lower = get_mb2_data(tag, basic_meminfo, mem_lower);
            mbi_out->mem_upper = get_mb2_data(tag, basic_meminfo, mem_upper);
            break;

        case MULTIBOOT2_TAG_TYPE_MMAP:
            if ( get_mb2_data(tag, mmap, entry_size) < sizeof(*mmap_src) )
                break;

            mbi_out->flags |= MBI_MEMMAP;
            mbi_out->mmap_length = get_mb2_data(tag, mmap, size);
            mbi_out->mmap_length -= sizeof(multiboot2_tag_mmap_t);
            mbi_out->mmap_length /= get_mb2_data(tag, mmap, entry_size);
            mbi_out->mmap_length *= sizeof(memory_map_t);

            mbi_out->mmap_addr = alloc_mem(mbi_out->mmap_length);

            mmap_src = get_mb2_data(tag, mmap, entries);
            mmap_dst = (memory_map_t *)mbi_out->mmap_addr;

            for ( i = 0; i < mbi_out->mmap_length / sizeof(memory_map_t); i++ )
            {
                /* Init size member properly. */
                mmap_dst[i].size = sizeof(memory_map_t);
                mmap_dst[i].size -= sizeof(((memory_map_t){0}).size);
                /* Now copy a given region data. */
                mmap_src = (void *)mmap_src + i * get_mb2_data(tag, mmap, entry_size);
                mmap_dst[i].base_addr_low = (u32)mmap_src->addr;
                mmap_dst[i].base_addr_high = (u32)(mmap_src->addr >> 32);
                mmap_dst[i].length_low = (u32)mmap_src->len;
                mmap_dst[i].length_high = (u32)(mmap_src->len >> 32);
                mmap_dst[i].type = mmap_src->type;
            }
            break;

        case MULTIBOOT2_TAG_TYPE_MODULE:
            mbi_out_mods[mod_idx].mod_start = get_mb2_data(tag, module, mod_start);
            mbi_out_mods[mod_idx].mod_end = get_mb2_data(tag, module, mod_end);
            ptr = get_mb2_string(tag, module, cmdline);
            mbi_out_mods[mod_idx].string = copy_string(ptr);
            mbi_out_mods[mod_idx].reserved = 0;
            ++mod_idx;
            break;

        case MULTIBOOT2_TAG_TYPE_END:
            return mbi_out;

        default:
            break;
        }

    return mbi_out;
}

multiboot_info_t __stdcall *reloc(u32 mb_magic, u32 mbi_in, u32 trampoline)
{
    alloc = trampoline;

    if ( mb_magic == MULTIBOOT2_BOOTLOADER_MAGIC )
        return mbi2_mbi(mbi_in);
    else
        return mbi_mbi(mbi_in);
}
Jan Beulich Sept. 1, 2016, 7:35 a.m. UTC | #7
>>> On 31.08.16 at 21:39, <daniel.kiper@oracle.com> wrote:
> I understood that you need reloc.c after this patch but it looks
> that I was wrong. So, here it is after applying whole series.

Thanks. Here are my notes:

All callers of alloc_mem() cast the result to a pointer. While most of
them also need the result as an integer, there's one exception:

    ptr = alloc_mem(sizeof(*mbi_out));
    mbi_out = (multiboot_info_t *)ptr;
    zero_mem(ptr, sizeof(*mbi_out));

Since this is also the only caller of zero_mem() it tells me that less
casting would be needed if alloc_mem() returned void *, and if
zero_mem() took void * for its first parameter.

Otoh it looks like copy_{mem,string}() are best left the way they are
now.

The amount of casting in e.g.

    for ( tag = (multiboot2_tag_t *)ptr;
          (u32)tag - mbi_in < ((multiboot2_fixed_t *)mbi_in)->total_size;
          tag = (multiboot2_tag_t *)ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN) )

is still ugly, the more that the entire construct exists more than once.
One thing to consider (which would make things at least a little less
fragile) would be to make tag (and maybe then also mbi_in) a union of
u32 and multiboot2_fixed_t *. For parameter passing purposes from
reloc() it may then be desirable for this to actually be a transparent
union.

Jan
Douglas Goldstein Sept. 6, 2016, 3:33 p.m. UTC | #8
On 8/30/16 9:32 AM, Daniel Kiper wrote:
> On Thu, Aug 25, 2016 at 05:34:31AM -0600, Jan Beulich wrote:
>>>>> On 20.08.16 at 00:43, <daniel.kiper@oracle.com> wrote:
>>> Create generic alloc and copy functions. We need
>>> separate tools for memory allocation and copy to
>>> provide multiboot2 protocol support.
>>>
>>> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
>>
>> The amount of casting in this patch alone looks very reasonable now.
>> Before ack-ing this and respective subsequent patches I'd like to see
>> the final result though. To facilitate that I have to re-raise a previously
>> asked question: Do you have a tree somewhere which one could use
>> to look at the final result?
> 
> Sadly no.
> 
> Daniel
> 

Daniel,

I'd encourage you to go to https://github.com/xen-project/xen and "fork"
the project and use that space to push your branches. It's free (as in
beer) hosting for any long series and you can enable
https://travis-ci.org to do some basic build tests on patch series
before you mail them out.
diff mbox

Patch

diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
index 28c6cea..21b1f32 100644
--- a/xen/arch/x86/boot/reloc.c
+++ b/xen/arch/x86/boot/reloc.c
@@ -32,60 +32,69 @@  typedef unsigned int u32;
 
 static u32 alloc;
 
-static void *reloc_mbi_struct(void *old, unsigned int bytes)
+static u32 alloc_mem(u32 bytes)
 {
-    void *new;
+    return alloc -= ALIGN_UP(bytes, 16);
+}
 
-    alloc -= ALIGN_UP(bytes, 16);
-    new = (void *)alloc;
+static u32 copy_mem(u32 src, u32 bytes)
+{
+    u32 dst, dst_ret;
+
+    dst = alloc_mem(bytes);
+    dst_ret = dst;
 
     while ( bytes-- )
-        *(char *)new++ = *(char *)old++;
+        *(char *)dst++ = *(char *)src++;
 
-    return (void *)alloc;
+    return dst_ret;
 }
 
-static char *reloc_mbi_string(char *old)
+static u32 copy_string(u32 src)
 {
-    char *p;
-    for ( p = old; *p != '\0'; p++ )
+    u32 p;
+
+    if ( src == 0 )
+        return 0;
+
+    for ( p = src; *(char *)p != '\0'; p++ )
         continue;
-    return reloc_mbi_struct(old, p - old + 1);
+
+    return copy_mem(src, p - src + 1);
 }
 
-multiboot_info_t __stdcall *reloc(multiboot_info_t *mbi_old, u32 trampoline)
+multiboot_info_t __stdcall *reloc(u32 mbi_old, u32 trampoline)
 {
     multiboot_info_t *mbi;
     int i;
 
     alloc = trampoline;
 
-    mbi = reloc_mbi_struct(mbi_old, sizeof(*mbi));
+    mbi = (multiboot_info_t *)copy_mem(mbi_old, sizeof(*mbi));
 
     if ( mbi->flags & MBI_CMDLINE )
-        mbi->cmdline = (u32)reloc_mbi_string((char *)mbi->cmdline);
+        mbi->cmdline = copy_string(mbi->cmdline);
 
     if ( mbi->flags & MBI_MODULES )
     {
-        module_t *mods = reloc_mbi_struct(
-            (module_t *)mbi->mods_addr, mbi->mods_count * sizeof(module_t));
+        module_t *mods;
 
-        mbi->mods_addr = (u32)mods;
+        mbi->mods_addr = copy_mem(mbi->mods_addr, mbi->mods_count * sizeof(module_t));
+
+        mods = (module_t *)mbi->mods_addr;
 
         for ( i = 0; i < mbi->mods_count; i++ )
         {
             if ( mods[i].string )
-                mods[i].string = (u32)reloc_mbi_string((char *)mods[i].string);
+                mods[i].string = copy_string(mods[i].string);
         }
     }
 
     if ( mbi->flags & MBI_MEMMAP )
-        mbi->mmap_addr = (u32)reloc_mbi_struct(
-            (memory_map_t *)mbi->mmap_addr, mbi->mmap_length);
+        mbi->mmap_addr = copy_mem(mbi->mmap_addr, mbi->mmap_length);
 
     if ( mbi->flags & MBI_LOADERNAME )
-        mbi->boot_loader_name = (u32)reloc_mbi_string(
-            (char *)mbi->boot_loader_name);
+        mbi->boot_loader_name = copy_string(mbi->boot_loader_name);
 
     /* Mask features we don't understand or don't relocate. */
     mbi->flags &= (MBI_MEMLIMITS |