[kexec-tools][PATCH] zImage-arm: bugfix: load kernel at TEXT_OFFSET
Daniel Mack
daniel at zonque.org
Mon May 5 06:13:11 PDT 2014
On 05/05/2014 01:48 PM, Wang Nan wrote:
> This patch fix a problem introduced by commit e5d6a55 which make ARM
> kexec fails.
>
> Due to that commit, kernel is loaded at a dynamically offset: it computes
> extra_size using size of dtb, and load zImage at base + extra_size. When
> dtb size small (for example, 0x3000 bytes), kernel will be loaded at
> address like 0x60003000. For ARM zImage such address is incorrect.
Ah, ok. Thanks for the heads-up. Your fixup works for me as well, two
minor style nits commented on inline.
> ---
> kexec/arch/arm/kexec-zImage-arm.c | 31 ++++++++++++++++++++++++++++---
> 1 file changed, 28 insertions(+), 3 deletions(-)
>
> diff --git a/kexec/arch/arm/kexec-zImage-arm.c b/kexec/arch/arm/kexec-zImage-arm.c
> index 4b5d3f4..539192b 100644
> --- a/kexec/arch/arm/kexec-zImage-arm.c
> +++ b/kexec/arch/arm/kexec-zImage-arm.c
> @@ -362,11 +362,10 @@ int zImage_arm_load(int argc, char **argv, const char *buf, off_t len,
>
> if (dtb_file) {
> dtb_buf = slurp_file(dtb_file, &dtb_length);
> - extra_size = _ALIGN(dtb_length, getpagesize());
> - } else if (use_atags) {
> - extra_size = 0x8000; /* 32k should be plenty for ATAGs */
> }
The curly braces are not needed anymore now.
> + extra_size = 0x8000;
> +
You can move the initialization to the variable declaration above.
Thanks,
Daniel
> /*
> * If we are loading a dump capture kernel, we need to update kernel
> * command line and also add some additional segments.
> @@ -460,6 +459,32 @@ int zImage_arm_load(int argc, char **argv, const char *buf, off_t len,
> create_flatten_tree(&dtb_buf, &dtb_length, command_line);
> }
>
> + /*
> + * Search in memory to make sure there is enough memory
> + * to hold initrd and dtb.
> + *
> + * Even if no initrd is used, this check is still
> + * required for dtb.
> + *
> + * Crash kernel use fixed address, no check is ok.
> + */
> + if ((info->kexec_flags & KEXEC_ON_CRASH) == 0) {
> + unsigned long page_size = getpagesize();
> + /*
> + * DTB size may be increase a little
> + * when setup initrd size. Add a full page
> + * for it is enough.
> + */
> + unsigned long hole_size = _ALIGN_UP(initrd_size, page_size) +
> + _ALIGN(dtb_length + page_size, page_size);
> + unsigned long initrd_base_new = locate_hole(info,
> + hole_size, page_size,
> + initrd_base, ULONG_MAX, INT_MAX);
> + if (base == ULONG_MAX)
> + return -1;
> + initrd_base = initrd_base_new;
> + }
> +
> if (ramdisk) {
> add_segment(info, ramdisk_buf, initrd_size,
> initrd_base, initrd_size);
>
More information about the kexec
mailing list