[U-Boot] static var mem alignment issue/question
Måns Rullgård
mans at mansr.com
Tue Nov 29 13:06:14 CET 2016
Tim Harvey <tharvey at gateworks.com> writes:
> Greetings,
>
> In debugging an issue with a rather old branch of U-Boot (2015-04) I
> found that the static assignment of a data buffer was not 32-bit
> aligned which caused data aborts. However I find that current U-boot
> master does not suffer this issue and no matter what I declare static
> before the particular variable its always 32-bit aligned. I don't see
> any code changes that would cause this and in both cases I'm building
> with the same gcc5.2.0 toolchain.
>
> The code in question is this this from cmd/fdt.c:
>
> } else if (argv[1][0] == 's') {
> char *pathp; /* path */
> char *prop; /* property */
> int nodeoffset; /* node offset from libfdt */
> static char data[SCRATCHPAD]; /* storage for the property */
> int len; /* new length of the property */
> int ret;
>
> What guarantee's that 'data' above is 32-bit aligned in master that is
> missing from the older U-Boot branch I'm using? Perhaps there is some
> arg in a Makefile that I'm missing?
There are no such guarantees. Things often end up 4-byte aligned by
chance simply because most of them are a multiple of 4 bytes in size.
The code should be fixed, either by explicitly aligning the buffer or by
using the put_unaligned_b32() accessor in fdt_parse_prop(). Here's an
untested patch:
>From 714f6a16062cc43e9aadfba29b295365fd4926de Mon Sep 17 00:00:00 2001
From: Mans Rullgard <mans at mansr.com>
Date: Tue, 29 Nov 2016 11:59:37 +0000
Subject: [PATCH] cmd/fdt: fix unaligned memory access
The buffer passed to fdt_parse_prop() might be unaligned. Use the
proper access helper when writing 32-bit values.
Signed-off-by: Mans Rullgard <mans at mansr.com>
---
cmd/fdt.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/cmd/fdt.c b/cmd/fdt.c
index b503357dc3a8..560b8cc9df61 100644
--- a/cmd/fdt.c
+++ b/cmd/fdt.c
@@ -17,6 +17,7 @@
#include <fdt_support.h>
#include <mapmem.h>
#include <asm/io.h>
+#include <asm/unaligned.h>
#define MAX_LEVEL 32 /* how deeply nested we will go */
#define SCRATCHPAD 1024 /* bytes of scratchpad memory */
@@ -766,7 +767,7 @@ static int fdt_parse_prop(char * const *newval, int count, char *data, int *len)
cp = newp;
tmp = simple_strtoul(cp, &newp, 0);
- *(__be32 *)data = __cpu_to_be32(tmp);
+ put_unaligned_be32(tmp, data);
data += 4;
*len += 4;
--
2.10.2
--
Måns Rullgård
More information about the U-Boot
mailing list