diff --git a/kexec/arch/i386/kexec-bzImage.c b/kexec/arch/i386/kexec-bzImage.c index 62260139..81ca2df5 100644 --- a/kexec/arch/i386/kexec-bzImage.c +++ b/kexec/arch/i386/kexec-bzImage.c @@ -281,14 +281,18 @@ int do_bzImage_load(struct kexec_info *info, if (real_mode->protocol_version >=0x0205 && relocatable_kernel) { /* Relocatable bzImage */ unsigned long kern_align = real_mode->kernel_alignment; + unsigned long kernel32_min_addr = KERN32_BASE; unsigned long kernel32_max_addr = DEFAULT_BZIMAGE_ADDR_MAX; + if (kernel32_min_addr < real_mode->pref_address) + kernel32_min_addr = real_mode->pref_address; + if (kernel32_max_addr > real_mode->initrd_addr_max) kernel32_max_addr = real_mode->initrd_addr_max; kernel32_load_addr = add_buffer(info, kernel + kern16_size, k_size, size, kern_align, - 0x100000, kernel32_max_addr, + kernel32_min_addr, kernel32_max_addr, 1); } else { kernel32_load_addr = KERN32_BASE; diff --git a/kexec/arch/x86_64/kexec-bzImage64.c b/kexec/arch/x86_64/kexec-bzImage64.c index 210bc0af..29ed8c98 100644 --- a/kexec/arch/x86_64/kexec-bzImage64.c +++ b/kexec/arch/x86_64/kexec-bzImage64.c @@ -120,6 +120,8 @@ static int do_bzImage64_load(struct kexec_info *info, char *modified_cmdline; unsigned long cmdline_end; unsigned long align, addr, k_size; + unsigned long kernel64_min_addr = KERN32_BASE; + unsigned long kernel64_max_addr = -1; unsigned kern16_size_needed; /* @@ -204,8 +206,14 @@ static int do_bzImage64_load(struct kexec_info *info, dbgprintf("kernel init_size 0x%x\n", real_mode->init_size); size = _ALIGN(real_mode->init_size, 4096); align = real_mode->kernel_alignment; + + if (kernel64_min_addr < real_mode->pref_address) + kernel64_min_addr = real_mode->pref_address; + addr = add_buffer(info, kernel + kern16_size, k_size, - size, align, 0x100000, -1, -1); + size, align, + kernel64_min_addr, kernel64_max_addr, + -1); if (addr == ULONG_MAX) die("can not load bzImage64"); dbgprintf("Loaded 64bit kernel at 0x%lx\n", addr);