|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |