Add a generic loader
v2 cover Add a generic loader
This work is based on the original work by Li Guang with extra features added by Peter C and myself.
The idea of this loader is to allow the user to load multiple images or values into QEMU at startup.
Memory values can be loaded like this: -device loader,addr=0xfd1a0104,data=0x8000000e,data-len=4
Images can be loaded like this: -device loader,file=./images/u-boot.elf,cpu=0
This can be useful and we use it a lot in Xilinx to load multiple images into a machine at creation (ATF, Kernel and DTB for example).
It can also be used to set registers.
The limiation for arch is based off settting the ELF_ARCH macro.
The reset patch is required otherwise the reset will never be registered and the loader can't change the PC in the case of images.
V2:
- Add an entry to the maintainers file
- Add some documentation
- Perform bounds checking on the data_len
- Register and unregister the reset in the realise/unrealise
Changes since RFC:
- Add support for BE
Alistair Francis (2):
generic-loader: Add a generic loader
docs: Add a generic loader explanation document
MAINTAINERS | 6 ++ default-configs/arm-softmmu.mak | 1 + docs/generic-loader.txt | 21 ++++++ hw/misc/Makefile.objs | 2 + hw/misc/generic-loader.c | 142 +++++++++++++++++++++++++++++++++++++++ include/hw/misc/generic-loader.h | 50 ++++++++++++++ 6 files changed, 222 insertions(+) create mode 100644 docs/generic-loader.txt create mode 100644 hw/misc/generic-loader.c create mode 100644 include/hw/misc/generic-loader.h
Signature · 1 line
2.5.0
PATCH v2 1/2 generic-loader: Add a generic loader
Add a generic loader to QEMU which can be used to load images or set memory values.
This only supports ARM architectures at the moment.
---
V2:
- Add maintainers entry
- Perform bounds checking
- Register and unregister the reset in the realise/unrealise
Changes since RFC:
- Add BE support
MAINTAINERS | 6 ++ default-configs/arm-softmmu.mak | 1 + hw/misc/Makefile.objs | 2 + hw/misc/generic-loader.c | 142 +++++++++++++++++++++++++++++++++++++++ include/hw/misc/generic-loader.h | 50 ++++++++++++++ 5 files changed, 201 insertions(+) create mode 100644 hw/misc/generic-loader.c create mode 100644 include/hw/misc/generic-loader.h
MAINTAINERS +6 -0
@@ -956,6 +956,12 @@ F: hw/acpi/nvdimm.c F: hw/mem/nvdimm.c F: include/hw/mem/nvdimm.h +Generic Loader +M: Alistair Francis <[email protected]> +S: Maintained +F: hw/misc/generic-loader.c +F: include/hw/misc/generic-loader.h + Subsystems ---------- Audio
default-configs/arm-softmmu.mak +1 -0
@@ -110,3 +110,4 @@ CONFIG_IOH3420=y CONFIG_I82801B11=y CONFIG_ACPI=y CONFIG_SMBIOS=y +CONFIG_LOADER=y
hw/misc/Makefile.objs +2 -0
@@ -46,3 +46,5 @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o obj-$(CONFIG_PVPANIC) += pvpanic.o obj-$(CONFIG_EDU) += edu.o obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o + +obj-$(CONFIG_LOADER) += generic-loader.o
hw/misc/generic-loader.c new file +142 -0
142 lines not on this page · raw message
include/hw/misc/generic-loader.h new file +50 -0
50 lines not on this page · raw message
Signature · 1 line
2.5.0
Re: [Qemu-devel] [PATCH v2 1/2] generic-loader: Add a generic loader
Quoted 6 lines · Alistair Francis
Add a generic loader to QEMU which can be used to load images or set memory values.
This only supports ARM architectures at the moment.
Signed-off-by Alistair Francis <[email protected]>
I don't seem to be able to see this on the list. Maybe this is that email sending problem again?
Quoted 137 lines
---
V2:
- Add maintainers entry
- Perform bounds checking
- Register and unregister the reset in the realise/unrealise
Changes since RFC:
- Add BE supportMAINTAINERS | 6 ++ default-configs/arm-softmmu.mak | 1 + hw/misc/Makefile.objs | 2 + hw/misc/generic-loader.c | 142 +++++++++++++++++++++++++++++++++++++++ include/hw/misc/generic-loader.h | 50 ++++++++++++++ 5 files changed, 201 insertions(+) create mode 100644 hw/misc/generic-loader.c create mode 100644 include/hw/misc/generic-loader.hMAINTAINERS +6
-0@@ -956,6 +956,12 @@ F: hw/acpi/nvdimm.c F: hw/mem/nvdimm.c F: include/hw/mem/nvdimm.h +Generic Loader +M: Alistair Francis <[email protected]> +S: Maintained +F: hw/misc/generic-loader.c +F: include/hw/misc/generic-loader.h + Subsystems ---------- Audiodefault-configs/arm-softmmu.mak +1
-0@@ -110,3 +110,4 @@ CONFIG_IOH3420=y CONFIG_I82801B11=y CONFIG_ACPI=y CONFIG_SMBIOS=y +CONFIG_LOADER=yhw/misc/Makefile.objs +2
-0@@ -46,3 +46,5 @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o obj-$(CONFIG_PVPANIC) += pvpanic.o obj-$(CONFIG_EDU) += edu.o obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o + +obj-$(CONFIG_LOADER) += generic-loader.ohw/misc/generic-loader.c new file +78
-0@@ -0,0 +1,142 @@ +/* +* Generic Loader +* +* Copyright (C) 2014 Li Guang +* Copyright (C) 2016 Xilinx Inc. +* Written by Li Guang <[email protected]> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* for more details. +*/ + +#include "qemu/osdep.h" +#include "hw/sysbus.h" +#include "sysemu/dma.h" +#include "hw/loader.h" +#include "hw/misc/generic-loader.h" + +#define CPU_NONE 0xFF + +static void generic_loader_reset (void *opaque) +{ +GenericLoaderState *s =GENERIC_LOADER (opaque); + +if (s->cpu) { +CPUClass *cc =CPU_GET_CLASS (s->cpu); +cpu_reset (s->cpu); + cc->set_pc (s->cpu, s->addr); + } + +if (s->data_len) { +assert (s->data_len <sizeof (s->data)); +dma_memory_write ((s->cpu ? s->cpu : first_cpu)->as, s->addr, &s->data, + s->data_len); + } +} + +static void generic_loader_realize (DeviceState *dev,Error **errp) +{ +GenericLoaderState *s =GENERIC_LOADER (dev); +hwaddr entry; +int big_endian; +int size =0 ; + +qemu_register_reset (generic_loader_reset, dev); + +if (s->cpu_nr !=CPU_NONE ) { +CPUState *cs = first_cpu; +int cpu_num =0 ; + +CPU_FOREACH (cs) { +if (cpu_num == s->cpu_nr) { + s->cpu = cs; +break ; + }else if (!CPU_NEXT (cs)) { +error_setg (errp,"Specified boot CPU#%d is nonexistent" , + s->cpu_nr); +return ; + }else { + cpu_num++; + } + } + } + +#ifdef TARGET_WORDS_BIGENDIAN + big_endian =1 ; +#else + big_endian =0 ; +#endif + +if (s->file) { +if (!s->force_raw) {
hw/misc/generic-loader.c line 88
Quoted 10 lines
hw/misc/generic-loader.c new file +10
-0+ size =load_elf (s->file,NULL ,NULL , &entry,NULL ,NULL , + big_endian,ELF_ARCH ,0 ); + +if (size <0 ) { + size =load_uimage (s->file, &entry,NULL ,NULL ,NULL ,NULL ); + } + } + +if (size <0 ) { + size =load_image_targphys (s->file, s->addr,0 );
This is wrong, nothing will ever get loaded.
Fixing and sending a V3.
Thanks,
Alistair
Quoted 114 lines
hw/misc/generic-loader.c new file +54
-0+ }else { + s->addr = entry; + } + +if (size <0 ) { +error_setg (errp,"Cannot load specified image %s" , s->file); +return ; + } + } + +if (s->data_len && (s->data_len >sizeof (s->data))) { +error_setg (errp,"data-len cannot be more then the data size" ); +return ; + } +} + +static void generic_loader_unrealize (DeviceState *dev,Error **errp) +{ +qemu_unregister_reset (generic_loader_reset, dev); +} + +static Property generic_loader_props[] = { +DEFINE_PROP_UINT64 ("addr" , GenericLoaderState, addr,0 ), +DEFINE_PROP_UINT64 ("data" , GenericLoaderState, data,0 ), +DEFINE_PROP_UINT8 ("data-len" , GenericLoaderState, data_len,0 ), +DEFINE_PROP_UINT8 ("cpu" , GenericLoaderState, cpu_nr,CPU_NONE ), +DEFINE_PROP_BOOL ("force-raw" , GenericLoaderState, force_raw, false), +DEFINE_PROP_STRING ("file" , GenericLoaderState, file), +DEFINE_PROP_END_OF_LIST (), +}; + +static void generic_loader_class_init (ObjectClass *klass,void *data) +{ +DeviceClass *dc =DEVICE_CLASS (klass); + + dc->realize = generic_loader_realize; + dc->unrealize = generic_loader_unrealize; + dc->props = generic_loader_props; + dc->desc ="Generic Loader" ; +} + +static TypeInfo generic_loader_info = { + .name =TYPE_GENERIC_LOADER , + .parent =TYPE_DEVICE , + .instance_size =sizeof (GenericLoaderState), + .class_init = generic_loader_class_init, +}; + +static void generic_loader_register_type (void ) +{ +type_register_static (&generic_loader_info); +} + +type_init (generic_loader_register_type)include/hw/misc/generic-loader.h new file +50
-1@@ -0,0 +1,50 @@ +/* +* Generic Loader +* +* Copyright (C) 2014 Li Guang +* Written by Li Guang <[email protected]> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* for more details. +*/ + +#ifndef GENERIC_LOADER_H +#define GENERIC_LOADER_H + +#include "elf.h" + +#if defined(TARGET_AARCH64 ) +#define ELF_ARCH EM_AARCH64 +#elif defined(TARGET_ARM ) +#define ELF_ARCH EM_ARM +#endif + +typedef struct GenericLoaderState { +/* <private> */ +DeviceState parent_obj; + +/* <public> */ +CPUState *cpu; + +uint64_t addr; +uint64_t data; +uint8_t data_len; +uint8_t cpu_nr; + +char *file; + +bool force_raw; +}GenericLoaderState ; + +#define TYPE_GENERIC_LOADER "loader" +#define GENERIC_LOADER (obj) OBJECT_CHECK(GenericLoaderState, (obj), \ + TYPE_GENERIC_LOADER) + +#endif --2.5.0
PATCH v2 2/2 docs: Add a generic loader explanation document
In reply to Alistair Francis---
docs/generic-loader.txt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 docs/generic-loader.txt
docs/generic-loader.txt new file +21 -0
@@ -0,0 +1,21 @@ +Copyright (c) 2016 Xilinx Inc. + +This work is licensed under the terms of the GNU GPL, version 2 or later. See +the COPYING file in the top-level directory. + + +This loader allows the user to load multiple images or values into QEMU at startup. + +Loading Memory Values +--------------------------- +Memory values can be loaded like this: + -device loader,addr=0xfd1a0104,data=0x8000000e,data-len=4 + +Loading Images +--------------------------- +Images can be loaded like this: + -device loader,file=./images/boot.elf,cpu=0 + +The limiation for arch is based off settting the ELF_ARCH macro. + +At the moment only the ARM arhitectures are supported
Signature · 1 line
2.5.0