Linux memo 2020/04/05 eMMC編

● 雑多情報メモ
http://trac.gateworks.com/wiki/MMC
https://www.slideshare.net/VijayGESYS/emmc-embedded-multimedia-card-overview
https://www.micron.com/-/media/client/global/documents/products/technical-note/emmc/tn5205_emmc_linux_enablement.pdf(PDF注意)

● Linuxのmmcドライバのコードを読むときの注意点
kernelバージョンによりちょっとずつ動きが変更されていたり、
ベンダー固有のホストコントローラドライバで変なことをやっていたり、
Vanilla LinuxとAndroid Linuxとでも微妙にコードが違っていたり、
ので、特に細かいCMDの処理について、ネット上の情報を鵜呑みにせず、実際に動かして確認しないと怖い。
素直に、CMDをprintkするやり方が無難かと思う。blockのread,writeはスキップしとかないと大変なことになる。

● mmc-utils
https://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc-utils.git
./mmc extcsd read /dev/mmcblk0
とかでEXT_CSDを出せる。
/sys/block/mmcblk0/
/sys/class/mmc_host/mmc0/mmc0:0001
あたりにもext_csd(他いろいろ)が生えているが、これは、初期化時にSEND_EXT_CSDしたときの値になっている。
./mmc extcsdは、コマンド叩いたときにSEND_EXT_CSDを送って取得しているので、長時間動かしている場合は値の違いに注意。
ちなみに、resume時はeMMCの電源入れ直してmmc_init()からやり直すので、raw_ext_csdが更新されることになる、スマホの場合注意。

● ブロックサイズ
EXT_CSD_HC_ERASE_GRP_SIZE 224 RO
EXT_CSD_ERASE_GROUP_DEF 175 R,W
hc_erase_size(==HC_ERASE_GRP_SIZE)がいわゆるブロックサイズっぽいけど、ガベコレが高度化した現代のmanagedフラッシュだと、secure eraseとか以外ではあんまり意味をなさない値じゃないかなと思う。
ERASE_GROUP_DEFに1を書く必要があるけど、まぁ現在はこれをせずにeMMCを使うことはほぼありえないと思う。

● eMMCのJEDEC規格バージョン
EXT_CSD_REV 192 RO
ただ、JEDEC書を読まんとわからんレベルの値のテーブルになってる。

● HPI(High Priority Interrupt)
EXT_CSD_HPI_MGMT 161 R,W
EXT_CSD_HPI_FEATURES 503 RO
HPI_FEATURESのビット0が立っている場合、HPI_MGMTに1を立てて有効にする。
実際にHPI機能を使って止めたいときはCMDを送る。
ビット1が立っている場合は、STOP_TRANSMISSTIONを、そうでない場合はSEND_STATUSを送って止める。
Sanitizeなどのキャンセルに使える。

● Background Operation
EXT_CSD_BKOPS_EN 163 R,W
EXT_CSD_BKOPS_START 164 W
EXT_CSD_OUT_OF_INTERRUPT_TIME 198 RO
EXT_CSD_BKOPS_STATUS 246 RO
EXT_CSD_BKOPS_SUPPORT 502 RO

EXT_CSD_BKOPS_LEVEL_2 0x2
EXT_CSD_MANUAL_BKOPS_MASK 0x01
EXT_CSD_AUTO_BKOPS_MASK 0x02
EXT_CSD_BKOPS_MANUAL_EN BIT(0)
EXT_CSD_BKOPS_AUTO_EN BIT(1)
MMC_BKOPS_TIMEOUT_MS (120 * 1000) /* 120s */

BKOPS_ENにBKOPS_MANUAL_ENを書くことで、manual background operationが使えるようになる(write once)。
BKOPS_STATUSを見て、BKOPS_LEVEL_2以上だったら、BKOPS_STARTにBKOPS_MANUAL_ENを書いてbackground operationを行う。

BKOPS_ENにBKOPS_AUTO_ENを書くことで、auto background operationが有効になる(write once)
あとは放っておくだけで良い。
msm-kernelではautoのほうを使うようになっていて、Vanillaとはコードが異なっている?

● Power Off Notification
EXT_CSD_POWER_OFF_NOTIFICATION 34 R,W
起動時にPOWER_OFF_NOTIFICATIONに1を書くことで機能が使えるようになる。
Linuxでは、suspend時にSHORT, shutdown時にLONGの値を書くという使い方をしているようだ。

● Cache
EXT_CSD_FLUSH_CACHE 32 W
EXT_CSD_CACHE_CTRL 33 R,W
EXT_CSD_CACHE_SIZE 249 RO
CACHE_SIZE(からの4byte)がサイズを表し、0より大きいと、CACHE機能を持っている。
CACHE_CTRLに1を書くと有効になる。
FLUSH_CACHEに1を書くと、FLUSHする。
CMDQの場合はまた異なるようだけど、詳細まだわからず。

● CMDQ
EXT_CSD_CMDQ_MODE_EN 15 R,W
EXT_CSD_CMDQ_SUPPORT 308 RO
EXT_CSD_CMDQ_SUPPORTED BIT(0)
CMDQ_SUPPORTにCMDQ_SUPPORTEDが立っていると、機能を持っている。
hostが対応している(MMC_CAP2_CQE_DCMD)ならば、CMDQ_MODE_ENに1を書いて、cmdqを有効化する。
Linux-4.16でCQE対応が入った。
block-mqにつながるので、block-mq側の対応がbuggyだったりしないかは注意点となるか。
block-mqについても、改めてもっと突っ込んで調査しておく必要がある気がしてる。

● DISCARD(eMMC)
MMC_ERASE_ARG 0x00000000
MMC_SECURE_ERASE_ARG 0x80000000
MMC_TRIM_ARG 0x00000001
MMC_DISCARD_ARG 0x00000003
MMC_SECURE_TRIM1_ARG 0x80000001
MMC_SECURE_TRIM2_ARG 0x80008000
MMC_SECURE_ARGS 0x80000000
MMC_TRIM_ARGS 0x00008001
startセクタを指定してMMC_ERASE_GROUP_STARTを送り、endセクタを指定してMMC_ERASE_GROUP_ENDを送り、eraseの種別をargに指定してMMC_ERASEを送る。
DISCARD, TRIM, ERASEの順で使えるかどうかを判断して使おうとする。
drivers/mmc/core/block.c mmc_blk_mq_issue_rq()あたりを読むべし。
新しめのLinuxではREQ_BARRIERはなくなった?

このブログ記事について

このページは、らるるが2020年4月 5日 03:48に書いたブログ記事です。

ひとつ前のブログ記事は「ソフトウェアの著作権の期限切れについて」です。

次のブログ記事は「Linux memo 2020/04/07 ext4編」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

ウェブページ

Powered by Movable Type 7.9.0