SD卡:如何在不移除SD卡的情况下强制内核再次读取WP pin
SD card: how to force the kernel to read the WP pin again without removing the sdcard
我有以下udev规则来挂载sd卡的第一个分区到/mnt/sdcard。
KERNEL=="mmcblk0p1", SUBSYSTEMS=="mmc", ATTRS{name}=="?*", ATTRS{serial}=="?*", ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="sdcard", RUN+="/usr/bin/mount_sdcard"
KERNEL=="mmcblk0", ACTION=="remove", RUN+="/usr/bin/unmount_sdcard"
我的 /usr/bin/mount_sdcard
可执行文件是:
#!/bin/sh
# log event
logger -t mount_sdcard -p user.warn "New SD Card detected"
# mount to /mnt/sdcard
mount_result=`mount $DEVNAME /mnt/sdcard 2>&1`
# On errors, send error to log
echo $mount_result | logger -t mount_sdcard -p user.error
if [ "x$mount_result" = "x" ]
then
# print filesystem type
stat -f /mnt/sdcard | grep Type | cut -d: -f4 | logger -t mount_sdcard -p user.warn
# print space left on device
df -h /dev/sdcard | logger -t mount_sdcard -p user.warn
fi
此代码工作正常,当插入 SD 卡时,分区以读写 (rw) 方式挂载。
但如果 sd 卡在启动时已经存在,分区将以只读方式挂载 (ro)。
在这种情况下,如果不手动移除并重新插入 sd 卡,我无法挂载分区读写。
我尝试卸载然后再次装载。我尝试使用重新挂载选项:mount -o remount,rw /dev/mmcblk0p1
这似乎有效,但当 运行 mount
命令时分区仍标记为 ro:
/dev/mmcblk0p1 on /mnt/sdcard type ext4 (ro,relatime,data=ordered)
更新:
问题更精确:
这是在自定义硬件上,其中 ARM 处理器上的 WP(写保护)引脚连接到处理器的输出。
在启动时,此输出将 sdcard 控制器设置为只读模式,并在初始化后反转此输出以允许写入 sd 卡。
问题是内核只会在启动时和插入卡时尝试读取此 WP pin。
==> 在启动内核 sd 卡控制器时将卡设置为 ro:
kernel: [ 1.723728] mmc0: new high speed SD card at address 59b4
kernel: [ 1.738262] mmcblk0: mmc0:59b4 USD 1.87 GiB (ro)
并且WP pin改变后卡为removed/replugged,内核sd卡控制器将卡设置为rw:
kernel: [ 527.931457] mmc0: new high speed SD card at address 59b4
kernel: [ 527.943988] mmcblk0: mmc0:59b4 USD 1.87 GiB
我的问题变了:如何在不移除sd卡的情况下强制内核再次读取WP pin?
我会尝试的一些事情:
运行fsck /dev/mmcblk0p1
。未能以 rw
模式挂载分区通常是文件系统状态不干净的标志。这里可能不是这种情况,因为您可以通过重新插入卡来正确安装它,但最好是安全的。
尝试通过 /etc/fstab
挂载 /dev/mmcblk0p1
看看是否可行。我知道这不会是一个确定的解决方案,但至少您可以将 mount
的问题与 udev
.
的问题区分开来
比较启动时有关 SD 卡的 dmesg
输出与之后重新插入卡时的 dmesg
输出。控制器似乎无法在启动时正确初始化,但此问题稍后会消失。找出间歇性问题可能会为您解决问题。
通过使用以下命令重置此卡的控制器,我能够再次读取 WP 引脚:
首先获取控制器:
$ readlink /sys/block/mmcblk0
../devices/soc0/soc/2100000.aips-bus/2194000.usdhc/mmc_host/mmc0/mmc0:59b4/block
然后解绑再绑定卡片:
$ echo 2194000.usdhc > /sys/bus/platform/drivers/sdhci-esdhc-imx/unbind
$ echo 2194000.usdhc > /sys/bus/platform/drivers/sdhci-esdhc-imx/bind
我有以下udev规则来挂载sd卡的第一个分区到/mnt/sdcard。
KERNEL=="mmcblk0p1", SUBSYSTEMS=="mmc", ATTRS{name}=="?*", ATTRS{serial}=="?*", ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="sdcard", RUN+="/usr/bin/mount_sdcard"
KERNEL=="mmcblk0", ACTION=="remove", RUN+="/usr/bin/unmount_sdcard"
我的 /usr/bin/mount_sdcard
可执行文件是:
#!/bin/sh
# log event
logger -t mount_sdcard -p user.warn "New SD Card detected"
# mount to /mnt/sdcard
mount_result=`mount $DEVNAME /mnt/sdcard 2>&1`
# On errors, send error to log
echo $mount_result | logger -t mount_sdcard -p user.error
if [ "x$mount_result" = "x" ]
then
# print filesystem type
stat -f /mnt/sdcard | grep Type | cut -d: -f4 | logger -t mount_sdcard -p user.warn
# print space left on device
df -h /dev/sdcard | logger -t mount_sdcard -p user.warn
fi
此代码工作正常,当插入 SD 卡时,分区以读写 (rw) 方式挂载。
但如果 sd 卡在启动时已经存在,分区将以只读方式挂载 (ro)。
在这种情况下,如果不手动移除并重新插入 sd 卡,我无法挂载分区读写。
我尝试卸载然后再次装载。我尝试使用重新挂载选项:mount -o remount,rw /dev/mmcblk0p1
这似乎有效,但当 运行 mount
命令时分区仍标记为 ro:
/dev/mmcblk0p1 on /mnt/sdcard type ext4 (ro,relatime,data=ordered)
更新:
问题更精确: 这是在自定义硬件上,其中 ARM 处理器上的 WP(写保护)引脚连接到处理器的输出。
在启动时,此输出将 sdcard 控制器设置为只读模式,并在初始化后反转此输出以允许写入 sd 卡。 问题是内核只会在启动时和插入卡时尝试读取此 WP pin。
==> 在启动内核 sd 卡控制器时将卡设置为 ro:
kernel: [ 1.723728] mmc0: new high speed SD card at address 59b4
kernel: [ 1.738262] mmcblk0: mmc0:59b4 USD 1.87 GiB (ro)
并且WP pin改变后卡为removed/replugged,内核sd卡控制器将卡设置为rw:
kernel: [ 527.931457] mmc0: new high speed SD card at address 59b4
kernel: [ 527.943988] mmcblk0: mmc0:59b4 USD 1.87 GiB
我的问题变了:如何在不移除sd卡的情况下强制内核再次读取WP pin?
我会尝试的一些事情:
运行
fsck /dev/mmcblk0p1
。未能以rw
模式挂载分区通常是文件系统状态不干净的标志。这里可能不是这种情况,因为您可以通过重新插入卡来正确安装它,但最好是安全的。尝试通过
/etc/fstab
挂载/dev/mmcblk0p1
看看是否可行。我知道这不会是一个确定的解决方案,但至少您可以将mount
的问题与udev
. 的问题区分开来
比较启动时有关 SD 卡的
dmesg
输出与之后重新插入卡时的dmesg
输出。控制器似乎无法在启动时正确初始化,但此问题稍后会消失。找出间歇性问题可能会为您解决问题。
通过使用以下命令重置此卡的控制器,我能够再次读取 WP 引脚:
首先获取控制器:
$ readlink /sys/block/mmcblk0
../devices/soc0/soc/2100000.aips-bus/2194000.usdhc/mmc_host/mmc0/mmc0:59b4/block
然后解绑再绑定卡片:
$ echo 2194000.usdhc > /sys/bus/platform/drivers/sdhci-esdhc-imx/unbind
$ echo 2194000.usdhc > /sys/bus/platform/drivers/sdhci-esdhc-imx/bind