[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v5 06/16] x86/boot/reloc: create generic alloc and copy functions



On Wed, Aug 31, 2016 at 09:25:57AM -0600, Jan Beulich wrote:
> >>> On 31.08.16 at 17:13, <daniel.kiper@xxxxxxxxxx> wrote:
> > On Tue, Aug 30, 2016 at 09:12:45AM -0600, Jan Beulich wrote:
> >> >>> On 30.08.16 at 16:32, <daniel.kiper@xxxxxxxxxx> wrote:
> >> > On Thu, Aug 25, 2016 at 05:34:31AM -0600, Jan Beulich wrote:
> >> >> >>> On 20.08.16 at 00:43, <daniel.kiper@xxxxxxxxxx> 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@xxxxxxxxxx>
> >> >>
> >> >> 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@xxxxxxx>
 *    Daniel Kiper <daniel.kiper@xxxxxxxxxx>
 */

/*
 * 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);
}

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.