Hi,
On 02/27/2018 05:14 PM, Bastian Stender wrote:
I am trying to write eMMC boot partitions and set the extcsd register to
that boot partition afterwards. I try achieve this with a C/GLib
application using the ioctls from drivers/mmc/core/block.c (like
mmc-utils does) and a regular write to /dev/mmcblk1.
I am trying to implement atomic boot partition updates, so it's
important that toggling the active boot partitions works reliably.
The problem can be reproduced with mmc-utils [1]:
# precondition: enable boot partition 1 for boot
$ mmc bootpart enable 1 0 /dev/mmcblk1
$ sleep 1
# make the device writeable
$ echo 0 > /sys/block/mmcblk1boot1/force_ro
# write something to the device
$ dd if=/dev/zero of=/dev/mmcblk1boot1 count=512
# enable boot partition 2 for boot
$ mmc bootpart enable 2 0 /dev/mmcblk1
# read the state of the extcsd registers
$ mmc extcsd read /dev/mmcblk1 | grep "Boot Partition"
Boot Partition 1 enabled
I did expect "Boot Partition 2 enabled" here. Most of the time the first
boot partition is enabled at the end (maybe around 90% of the time).
This issue can be observed on v4.16-rc2 (and at least on 4.15.1 as well
as on 4.14.0). I tested this on two different eMMCs.
Setting the second boot partition active, writing to the first and then
setting the first active in the very same way *does work*. Very strange.
What I got so far:
I did some debugging, but could not get the actual root cause of the
problem. What I did observe seems to be timing related. The sleep
command in the steps above seems to be required to actually make the
boot partition switch happen. Similar problems seem to cause this bug.
Inserting another sleep between writing (dd command) and enabling the
boot partition seems to make it work. In the C/GLib application a delay
greater than 0.5 seconds helps.
Another thing I saw is the extcsd register showing the desired boot
partition as enabled, but a fraction of a second later it seems to get
reverted (overwritten?).
During debugging I got the impression that the ioctl method
(__mmc_blk_ioctl_cmd) does not update the cached extcsd registers, but
that's not the case if I'm not mistaken.
It should be mentioned that the extcsd register "PARTITION_CONFIG
(before BOOT_CONFIG) [179]" holds BOOT_PARTITION_ENABLE (bit 3-5) as
well as PARTITION_ACCESS (bit 0-2). PARTITION_ACCESS gets written pretty
regularly during eMMC access. So maybe the BOOT_PARTITION_ENABLE bits I
am writing get in fact reverted/overwritten somewhere. Maybe a delay is
required in that case in the kernel driver?
Does anyone have an idea what is happening here? Any hints how to debug
this?
Regards,
Bastian
[1] https://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc-utils.git/
We figured it out in the meantime. It is fixed by "[PATCH] mmc: block:
fix updating ext_csd caches on ioctl call"
(id:20180308140811.6966-1-bst@xxxxxxxxxxxxxx).
Regards,
Bastian
--
Pengutronix e.K.
Industrial Linux Solutions
http://www.pengutronix.de/
Peiner Str. 6-8, 31137 Hildesheim, Germany
Amtsgericht Hildesheim, HRA 2686
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html