[PATCH] Fixed unaligned access
Fabian van der Werf
fvanderwerf at gmail.com
Sat Oct 8 07:34:30 EDT 2011
---
drivers/ata/disk_drive.c | 15 ++++++++++-----
1 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/ata/disk_drive.c b/drivers/ata/disk_drive.c
index 14b5e66..6a5dc87 100644
--- a/drivers/ata/disk_drive.c
+++ b/drivers/ata/disk_drive.c
@@ -38,6 +38,7 @@
#include <malloc.h>
#include <common.h>
#include <block.h>
+#include <asm/unaligned.h>
/**
* Description of one partition table entry (D*S type)
@@ -97,25 +98,29 @@ static int disk_register_partitions(struct device_d
*dev, struct partition_entry
int part_order[4] = {0, 1, 2, 3};
int i, rc;
char drive_name[16], partition_name[19];
+ u32 partition_start, partition_size;
/* TODO order the partitions */
for (i = 0; i < 4; i++) {
+ partition_start =
get_unaligned(&table[part_order[i]].partition_start);
+ partition_size =
get_unaligned(&table[part_order[i]].partition_size);
+
sprintf(drive_name, "%s%d", dev->name, dev->id);
sprintf(partition_name, "%s%d.%d", dev->name, dev->id, i);
- if (table[part_order[i]].partition_start != 0) {
+ if (partition_start != 0) {
#if 1
/* ignore partitions we can't handle due to 32 bit limits */
- if (table[part_order[i]].partition_start > 0x7fffff)
+ if (partition_start > 0x7fffff)
continue;
- if (table[part_order[i]].partition_size > 0x7fffff)
+ if (partition_size > 0x7fffff)
continue;
#endif
dev_dbg(dev, "Registering partition %s to drive %s\n",
partition_name, drive_name);
rc = devfs_add_partition(drive_name,
- table[part_order[i]].partition_start * SECTOR_SIZE,
- table[part_order[i]].partition_size * SECTOR_SIZE,
+ partition_start * SECTOR_SIZE,
+ partition_size * SECTOR_SIZE,
DEVFS_PARTITION_FIXED, partition_name);
if (rc != 0)
dev_err(dev, "Failed to register partition %s (%d)\n",
partition_name, rc);
--
1.7.0.4
--00151743f83c849e6104aec83018
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Hi,<br><br><br>I ran into problems trying to boot the pandaboard, which I t=
hink is the same others reported on this list. After printing the pandaboar=
d revision number execution simply stops. I traced the problem to an unalig=
ned access in disk_register_partitions(). Barebox loads first sector of the=
disk in memory. The offset of the partition table is 446 (decimal) which c=
auses the entire partition table to be unaligned.<br>
<br>Below is a simple patch. Though, I am not sure whether this is the righ=
t fix, because this would affect all arm platforms and I would expect that =
such a bug would be noted earlier. I fiddled a little with the alignment bi=
t in the System Control Register, but without success. I have to admit that=
I don't yet fully understand the behaviour of this bit.<br>
<br>Does someone else have any ideas? Or is my patch acceptable?<br><br><br=
>Kind regards,<br><br>Fabian van der Werf<br><br><br>From f98e14b971e026925=
1d8694be4c7b0254a30bc52 Mon Sep 17 00:00:00 2001<br>From: Fabian van der We=
rf <<a href=3D"mailto:fvanderwerf at gmail.com" target=3D"_blank">fvanderwe=
rf at gmail.com</a>><br>
Date: Sat, 8 Oct 2011 13:34:30 +0200<br>Subject: [PATCH] Fixed unaligned ac=
cess<br><br>---<br>=A0drivers/ata/disk_drive.c |=A0=A0 15 ++++++++++-----<b=
r>=A01 files changed, 10 insertions(+), 5 deletions(-)<br><br>diff --git a/=
drivers/ata/disk_drive.c b/drivers/ata/disk_drive.c<br>
index 14b5e66..6a5dc87 100644<br>--- a/drivers/ata/disk_drive.c<br>+++ b/dr=
ivers/ata/disk_drive.c<br>@@ -38,6 +38,7 @@<br>=A0#include <malloc.h>=
<br>=A0#include <common.h><br>=A0#include <block.h><br>+#includ=
e <asm/unaligned.h><br>
=A0<br>=A0/**<br>=A0 * Description of one partition table entry (D*S type)<=
br>@@ -97,25 +98,29 @@ static int disk_register_partitions(struct device_d =
*dev, struct partition_entry<br>=A0=A0=A0=A0 int part_order[4] =3D {0, 1, 2=
, 3};<br>=A0=A0=A0=A0 int i, rc;<br>
=A0=A0=A0=A0 char drive_name[16], partition_name[19];<br>+=A0=A0=A0 u32 par=
tition_start, partition_size;<br>=A0<br>=A0=A0=A0=A0 /* TODO order the part=
itions */<br>=A0<br>=A0=A0=A0=A0 for (i =3D 0; i < 4; i++) {<br>+=A0=A0=
=A0 =A0=A0=A0 partition_start =3D get_unaligned(&table[part_order[i]].p=
artition_start);<br>
+=A0=A0=A0 =A0=A0=A0 partition_size=A0 =3D get_unaligned(&table[part_or=
der[i]].partition_size);<br>+<br>=A0=A0=A0=A0 =A0=A0=A0 sprintf(drive_name,=
"%s%d", dev->name, dev->id);<br>=A0=A0=A0=A0 =A0=A0=A0 spr=
intf(partition_name, "%s%d.%d", dev->name, dev->id, i);<br>
-=A0=A0=A0 =A0=A0=A0 if (table[part_order[i]].partition_start !=3D 0) {<br>=
+=A0=A0=A0 =A0=A0=A0 if (partition_start !=3D 0) {<br>=A0#if 1<br>=A0/* ign=
ore partitions we can't handle due to 32 bit limits */<br>-=A0=A0=A0 =
=A0=A0=A0 =A0=A0=A0 if (table[part_order[i]].partition_start > 0x7fffff)=
<br>
+=A0=A0=A0 =A0=A0=A0 =A0=A0=A0 if (partition_start > 0x7fffff)<br>=A0=A0=
=A0=A0 =A0=A0=A0 =A0=A0=A0 =A0=A0=A0 continue;<br>-=A0=A0=A0 =A0=A0=A0 =A0=
=A0=A0 if (table[part_order[i]].partition_size > 0x7fffff)<br>+=A0=A0=A0=
=A0=A0=A0 =A0=A0=A0 if (partition_size > 0x7fffff)<br>=A0=A0=A0=A0 =A0=
=A0=A0 =A0=A0=A0 =A0=A0=A0 continue;<br>
=A0#endif<br>=A0=A0=A0=A0 =A0=A0=A0 =A0=A0=A0 dev_dbg(dev, "Registerin=
g partition %s to drive %s\n",<br>=A0=A0=A0=A0 =A0=A0=A0 =A0=A0=A0 =A0=
=A0=A0 partition_name, drive_name);<br>=A0=A0=A0=A0 =A0=A0=A0 =A0=A0=A0 rc =
=3D devfs_add_partition(drive_name,<br>-=A0=A0=A0 =A0=A0=A0 =A0=A0=A0 =A0=
=A0=A0 table[part_order[i]].partition_start * SECTOR_SIZE,<br>
-=A0=A0=A0 =A0=A0=A0 =A0=A0=A0 =A0=A0=A0 table[part_order[i]].partition_siz=
e * SECTOR_SIZE,<br>+=A0=A0=A0 =A0=A0=A0 =A0=A0=A0 =A0=A0=A0 partition_star=
t * SECTOR_SIZE,<br>+=A0=A0=A0 =A0=A0=A0 =A0=A0=A0 =A0=A0=A0 partition_size=
* SECTOR_SIZE,<br>=A0=A0=A0=A0 =A0=A0=A0 =A0=A0=A0 =A0=A0=A0 DEVFS_PARTITI=
ON_FIXED, partition_name);<br>
=A0=A0=A0=A0 =A0=A0=A0 =A0=A0=A0 if (rc !=3D 0)<br>=A0=A0=A0=A0 =A0=A0=A0 =
=A0=A0=A0 =A0=A0=A0 dev_err(dev, "Failed to register partition %s (%d)=
\n", partition_name, rc);<br>-- <br>1.7.0.4<br><br>
--00151743f83c849e6104aec83018--
More information about the barebox
mailing list