@@ -124,6 +124,7 @@
#define IH_TYPE_SCRIPT 6 /* Script file */
#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */
#define IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */
+#define IH_TYPE_KERNEL_NOLOAD 14 /* OS Kernel Image (noload) */
/*
* Compression Types
@@ -175,10 +175,15 @@ void load_elf_hdr(const char *filename, void *hdr, bool *is64, Error **errp);
int load_aout(const char *filename, hwaddr addr, int max_sz,
int bswap_needed, hwaddr target_page_size);
+#define LOAD_UIMAGE_LOADADDR_INVALID (-1)
+
/** load_uimage_as:
* @filename: Path of uimage file
* @ep: Populated with program entry point. Ignored if NULL.
- * @loadaddr: Populated with the load address. Ignored if NULL.
+ * @loadaddr: load address if none specified in the image or when loading a
+ * ramdisk. Populated with the load address. Ignored if NULL or
+ * LOAD_UIMAGE_LOADADDR_INVALID (images which do not specify a load
+ * address will not be loadable).
* @is_linux: Is set to true if the image loaded is Linux. Ignored if NULL.
* @translate_fn: optional function to translate load addresses
* @translate_opaque: opaque data passed to @translate_fn
@@ -30,8 +30,9 @@
* Documentation/arm/Booting and Documentation/arm64/booting.txt
* They have different preferred image load offsets from system RAM base.
*/
-#define KERNEL_ARGS_ADDR 0x100
-#define KERNEL_LOAD_ADDR 0x00010000
+#define KERNEL_ARGS_ADDR 0x100
+#define KERNEL_NOLOAD_ADDR 0x02000000
+#define KERNEL_LOAD_ADDR 0x00010000
#define KERNEL64_LOAD_ADDR 0x00080000
#define ARM64_TEXT_OFFSET_OFFSET 8
@@ -1082,7 +1083,8 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
}
entry = elf_entry;
if (kernel_size < 0) {
- kernel_size = load_uimage_as(info->kernel_filename, &entry, NULL,
+ uint64_t loadaddr = info->loader_start + KERNEL_NOLOAD_ADDR;
+ kernel_size = load_uimage_as(info->kernel_filename, &entry, &loadaddr,
&is_linux, NULL, NULL, as);
}
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && kernel_size < 0) {
@@ -613,13 +613,26 @@ static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr,
goto out;
if (hdr->ih_type != image_type) {
- fprintf(stderr, "Wrong image type %d, expected %d\n", hdr->ih_type,
- image_type);
- goto out;
+ if (!(image_type == IH_TYPE_KERNEL &&
+ hdr->ih_type == IH_TYPE_KERNEL_NOLOAD)) {
+ fprintf(stderr, "Wrong image type %d, expected %d\n", hdr->ih_type,
+ image_type);
+ goto out;
+ }
}
/* TODO: Implement other image types. */
switch (hdr->ih_type) {
+ case IH_TYPE_KERNEL_NOLOAD:
+ if (!loadaddr || *loadaddr == LOAD_UIMAGE_LOADADDR_INVALID) {
+ fprintf(stderr, "this image format (kernel_noload) cannot be "
+ "loaded on this machine type");
+ goto out;
+ }
+
+ hdr->ih_load = *loadaddr + sizeof(*hdr);
+ hdr->ih_ep += hdr->ih_load;
+ /* fall through */
case IH_TYPE_KERNEL:
address = hdr->ih_load;
if (translate_fn) {
@@ -156,7 +156,7 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
/* If it wasn't an ELF image, try an u-boot image. */
if (kernel_size < 0) {
- hwaddr uentry, loadaddr;
+ hwaddr uentry, loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
kernel_size = load_uimage(kernel_filename, &uentry, &loadaddr, 0,
NULL, NULL);
@@ -161,7 +161,7 @@ void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base,
/* If it wasn't an ELF image, try an u-boot image. */
if (kernel_size < 0) {
- hwaddr uentry, loadaddr;
+ hwaddr uentry, loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
kernel_size = load_uimage(kernel_filename, &uentry, &loadaddr, 0,
NULL, NULL);
@@ -995,6 +995,7 @@ void ppce500_init(MachineState *machine)
* Hrm. No ELF image? Try a uImage, maybe someone is giving us an
* ePAPR compliant kernel
*/
+ loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
payload_size = load_uimage(filename, &bios_entry, &loadaddr, NULL,
NULL, NULL);
if (payload_size < 0) {
@@ -179,7 +179,7 @@ static void bamboo_init(MachineState *machine)
CPUPPCState *env;
uint64_t elf_entry;
uint64_t elf_lowaddr;
- hwaddr loadaddr = 0;
+ hwaddr loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
target_long initrd_size = 0;
DeviceState *dev;
int success;
@@ -402,7 +402,7 @@ static void sam460ex_init(MachineState *machine)
CPUPPCState *env;
PPC4xxI2CState *i2c[2];
hwaddr entry = UBOOT_ENTRY;
- hwaddr loadaddr = 0;
+ hwaddr loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
target_long initrd_size = 0;
DeviceState *dev;
SysBusDevice *sbdev;