本ページの位置は https://www.si-linux.co.jp/ -> 技術情報 CAT Wiki -> MMCホットプラグ

MMCのホットプラグ

CAT724をはじめLinuxシステムでは最初に見つけたSDカード(mmcblk)を0番とし次に見つけた物を1番とする。CAT724の場合は

  • CPUボード上のmicroSDがプライマリ
  • マザーボード上の標準サイズSDがセカンダリ

である。電源投入時に最初からmicroSD、標準サイズSD共に挿入されている場合は

microSD       /dev/mmcblk0
標準サイズSD  /dev/mmcblk1

になるが、microSDを挿入せず標準SDのみで起動すると最初に見つけた標準SDが /dev/mmcblk0になり、次にmicroSDを活線挿入(ホットプラグ)するとmicroSDが/dev/mmcblk1 となって逆転してしまう。

この問題の対策としてudevを使用する。

デバイス名の固定

/sbin/blkid ファイルをインストールすればudev経由で

# ls -l /dev/disk/by-path/platform-sh_mobile_sdhi.0
lrwxrwxrwx 1 root root 13 Dec  3 20:30 /dev/disk/by-path/platform-sh_mobile_sdhi.0-part1 -> ../../mmcblk0p1

のように自動的にシンボリックリンクを張るので /dev/mmcblk* を使うのではなく
/dev/disk/by-path/platform-sh_mobile_sdhi.0-part1 を使えば /dev/mmcblk* が変動してしまう問題は解決する。

/dev/disk/by-path/platform-sh_mobile_sdhi.0-part1     microSD第1パーティション
/dev/disk/by-path/platform-sh_mobile_sdhi.1-part1     標準SD第1パーティション

fileblkid SH4 seuqqze版 /sbin/blkid 実行ファイル。保存後に

# chmod +x /sbin/blkid

とする。

分かりやすい名前でマウントポイントを作る

# rommode rw
# mkdir /media/microsd1              # マイクロSD第1パーティション用マウントポイント
# mkdir /media/outsd1                # 外のSD第1パーティション用マウントポイント

/etc/fstab にマウントポイントのひも付けを記述する。/etc/fstab に以下を追記する

/dev/disk/by-path/platform-sh_mobile_sdhi.0-part1       /media/microsd1 vfat rw,noauto,sync,flush  0 0
/dev/disk/by-path/platform-sh_mobile_sdhi.1-part1       /media/outsd1   vfat rw,noauto,sync,flush  0 0
# デバイス名                      マウント先      fsタイプ   オプション  fsck順序 backup順序

編集が終わったらread-onlyに戻す

# rommode ro

オプションの sync は遅延書き込みの抑制。デフォルトはasync=非同期=遅延書き込みを行う。リムーバブルメディアは不意に抜かれる危険性を考慮し sync にしておくと安全。しかし遅くなるので注意。VFATはsyncに対応していないので似たようなオプションのflushを付けておく。

noauto と付けておくと起動時には自動マウントしない。手動またはアプリケーションで

# mount /media/microsd1
# umount /media/microsd1

のようにして利用する。

自動マウント

調査

microSDを入れた状態で以下のコマンドを実行しudevで使用する属性を調べる

# udevadm info --query=all --name=/dev/disk/by-path/platform-sh_mobile_sdhi.0-part1
P: /devices/platform/sh_mobile_sdhi.0/mmc_host/mmc0/mmc0:e624/block/mmcblk0/mmcblk0p1
N: mmcblk0p1
S: block/179:1
S: disk/by-id/memstick-SU02G_0x523f7e56-part1
S: disk/by-path/platform-sh_mobile_sdhi.0-part1
S: disk/by-uuid/B8A8-894F
E: UDEV_LOG=3
E: DEVPATH=/devices/platform/sh_mobile_sdhi.0/mmc_host/mmc0/mmc0:e624/block/mmcblk0/mmcblk0p1
E: MAJOR=179
E: MINOR=1
E: DEVNAME=/dev/mmcblk0p1
E: DEVTYPE=partition
E: SUBSYSTEM=block
E: ID_BUS=memstick
E: ID_SERIAL=SU02G_0x523f7e56
E: ID_PATH=platform-sh_mobile_sdhi.0
E: ID_PART_TABLE_TYPE=dos
E: ID_FS_SEC_TYPE=msdos
E: ID_FS_UUID=B8A8-894F
E: ID_FS_UUID_ENC=B8A8-894F
E: ID_FS_VERSION=FAT16
E: ID_FS_TYPE=vfat
E: ID_FS_USAGE=filesystem
E: DEVLINKS=/dev/block/179:1 /dev/disk/by-id/memstick-SU02G_0x523f7e56-part1
   /dev/disk/by-path/platform-sh_mobile_sdhi.0-part1
   /dev/disk/by-uuid/B8A8-894F
(P:path N:name S:symlink E:property の意味 --query=path とすると P: だけ表示される)

DEVPATHは /sys/$DEVPATHを意味する。 /sys/$DEVPATH に移動してlsする

# cd /sys/devices/platform/sh_mobile_sdhi.0/mmc_host/mmc0/mmc0:e624/block/mmcblk0/mmcblk0p1
# ls -l
-r--r--r-- 1 root root 4096 Dec  3 20:48 alignment_offset
-r--r--r-- 1 root root 4096 Dec  3 20:48 dev
-r--r--r-- 1 root root 4096 Dec  3 20:48 discard_alignment
drwxr-xr-x 2 root root    0 Dec  3 20:48 holders
-r--r--r-- 1 root root 4096 Dec  3 20:48 inflight
-r--r--r-- 1 root root 4096 Dec  3 20:30 partition
drwxr-xr-x 2 root root    0 Dec  3 20:48 power
-r--r--r-- 1 root root 4096 Dec  3 20:48 ro
-r--r--r-- 1 root root 4096 Dec  3 20:48 size
-r--r--r-- 1 root root 4096 Dec  3 20:48 start
-r--r--r-- 1 root root 4096 Dec  3 20:48 stat
lrwxrwxrwx 1 root root    0 Dec  3 20:30 subsystem -> ../../../../../../../../../class/block
-rw-r--r-- 1 root root 4096 Dec  3 20:30 uevent

ここにあるファイルの中身は次のudevルールの中で ATTR{ } で参照する。例えばパーティション番号は

# cat partition
1

でありこれはudevルール中で ATTR{partition} の構文になる

自動マウントudevルール

CAT724は /etc/udev/ に aufs を用いていてramdisk上に上書きされるようになっている。これを外さないと編集がROMに反映されないのでumountしてから編集を行う

# umount /etc/udev/
# rommode rw

/etc/udev/rules.d/10-mmcblk-automount.rules を新規作成する

ACTION=="add",\
        SUBSYSTEM=="block",\
        DEVPATH=="/devices/platform/sh_mobile_sdhi.0*",\
        ATTR{partition}=="1",\
        RUN+="/bin/mount $env{DEVNAME} /media/microsd1"

ACTION=="add",\
        SUBSYSTEM=="block",\
        DEVPATH=="/devices/platform/sh_mobile_sdhi.1*",\
        ATTR{partition}=="1",\
        RUN+="/bin/mount $env{DEVNAME} /media/outsd1"

ACTION=="remove",\
        SUBSYSTEM=="block",\
        DEVPATH=="/devices/platform/sh_mobile_sdhi.0*",\
        RUN+="/bin/umount -lf /media/microsd1"

ACTION=="remove",\
        SUBSYSTEM=="block",\
        DEVPATH=="/devices/platform/sh_mobile_sdhi.1*",\
        RUN+="/bin/umount -lf /media/outsd1"

rulesの構文は少々複雑だが次の通り

  • 改行は¥マークでエスケープする
  • ルールは,カンマでつなげて and 条件となる
  • 比較演算子==は条件の記述
  • 代入演算子=や+=は動作 を意味する。最初の例では
ACTION=="add",SUBSYSTEM=="block",DEVPATH=="/devices/platform/sh_mobile_sdhi.0*",ATTR{partition}=="1"

がand条件で

RUN+="/bin/mount /media/microsd1"

が動作となる。これによって sh_mobile_sdhi.0 の partition==1 がaddされたときに "/bin/mount /media/microsd1" が実行され自動マウントされる。同様に umount ルールも記述する。

記述が完了したら

# rommode ro

として再起動する

動作確認

再起動後に microSD を挿入すると /media/microsd1 に自動マウントされることが確認できる(mount コマンドにて確認)。

メディアを抜くと umount される。ただし書き込み最中のデータがあるとメモリカードが破壊されるので十分に注意すること。syncコマンドを実行してから抜くと安全である。

メモ

udevイベントのウォッチ

# udevadm monitor --env

関連

社内リンク

社外リンク

udevルールについてはここが分かりやすい

Last-modified: 2019-07-22 (月) 17:56:00 (32d)