ARM: atags_offset at 0x100
Yegor Yefremov
yegorslists at googlemail.com
Thu Mar 12 07:55:03 EDT 2009
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;
More information about the kexec
mailing list