On Wed, Mar 11, 2009 at 9:59 AM, Yegor Yefremov <yegorslists at googlemail.com> wrote: > I'm working with KS8695 SoC. Everything is functioning so far. The > only issue I have now is the atags_offset. In kexec-zImage-arm.c it is > defined as 0x1000 (4k), but many ARM based boards await ATAGs at 0x100 > (see http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob_plain;f=arch/arm/mach-ks8695/board-dsm320.c;hb=HEAD). > If I change this settings in kernel, then I see the atags, but I can't > simply change the atags_offset in kexec-zImage-arm.c, because it is > not 4k aligned. I get the following error message: > > Base address: ?100 is not page aligned > > Unfortunately I cannot change the kernel, cause backward compatibility > with older kernels must be guarantied. Is there any solution for this > problem how to bring kexec to put ATAGs at 0x100? I found a temporary solution for this problem. According to Documentation/arm/Booting recommended place for ATAGs are the first 16KiB of RAM. So I just allocate this space and atag_offset is used as offset within this 16KiB. The kernel gets the whole chunk and doesn't complain about non aligned memory. I also changed atag_offset to 0x100, cause there are really few boards awaiting boot_params at an offset different from 0x100. For other boards not using this offset special command line parameter --atag_offset can be introduced to overwrite the default setting. Are there any concerns about allocating 16KiB at once or any other concerns regarding this method? Best regards, Yegor Index: kexec-tools/kexec/arch/arm/kexec-zImage-arm.c =================================================================== --- kexec-tools.orig/kexec/arch/arm/kexec-zImage-arm.c +++ kexec-tools/kexec/arch/arm/kexec-zImage-arm.c @@ -16,6 +16,7 @@ #define COMMAND_LINE_SIZE 1024 #define BOOT_PARAMS_SIZE 1536 +#define ATAGS_SEGMENT_SIZE (4 * getpagesize()) struct tag_header { uint32_t size; @@ -124,6 +125,7 @@ struct tag * atag_read_tags(void) static int atag_arm_load(struct kexec_info *info, unsigned long base, + unsigned int atag_offset, const char *command_line, off_t command_line_len, const char *initrd, off_t initrd_len) { @@ -133,14 +135,15 @@ int atag_arm_load(struct kexec_info *inf struct tag *params; uint32_t *initrd_start; - buf = xmalloc(getpagesize()); + // allocate 16K + buf = xmalloc(ATAGS_SEGMENT_SIZE); if (!buf) { fprintf(stderr, "Compiling ATAGs: out of memory\n"); return -1; } - memset(buf, 0xff, getpagesize()); - params = (struct tag *)buf; + memset(buf, 0xff, ATAGS_SEGMENT_SIZE); + params = (struct tag *)(buf + atag_offset); if (saved_tags) { // Copy tags @@ -186,7 +189,7 @@ int atag_arm_load(struct kexec_info *inf params->hdr.size = 0; params->hdr.tag = ATAG_NONE; - len = ((char *)params - buf) + sizeof(struct tag_header); + len = ATAGS_SEGMENT_SIZE; add_segment(info, buf, len, base, len); @@ -207,7 +210,7 @@ int zImage_arm_load(int argc, char **arg struct kexec_info *info) { unsigned long base; - unsigned int atag_offset = 0x1000; /* 4k offset from memory start */ + unsigned int atag_offset = 0x100; /* 4k offset from memory start */ unsigned int offset = 0x8000; /* 32k offset from memory start */ const char *command_line; off_t command_line_len; @@ -266,7 +269,7 @@ int zImage_arm_load(int argc, char **arg if (base == ULONG_MAX) return -1; - if (atag_arm_load(info, base + atag_offset, + if (atag_arm_load(info, base, atag_offset, command_line, command_line_len, ramdisk_buf, ramdisk_length) == -1) return -1;