ARM: atags_offset at 0x100

Yegor Yefremov yegorslists at
Thu Mar 12 07:55:03 EDT 2009

On Wed, Mar 11, 2009 at 9:59 AM, Yegor Yefremov
<yegorslists at> 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;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,

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)

 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);

 	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;

More information about the kexec mailing list