linux mmc sdカード起動プロセスの詳細

3513 ワード

ワークフロー:mmc駆動プライマリファイルにはdrivers/mmc/card/blockが含まれます.cdrivers/mmc/card/queue.cdrivers/mmc/core/core.cdrivers/mmc/core/host.cdriver/mmc/core/カーネル起動時にcore/coreを最初に実行する.cのmmc_Init、mmc、sdバス、host classデバイスを登録します.次にcard/blockを実行する.cでは、ブロックデバイスを申請する.
データ構造:mmcバス操作関連関数.mmcカードはSPI、SDIO、8 LineMMCなどの多くの総データ線をサポートするが、異なるバスの操作制御方式は異なるため、この構造によって対応するバスコールバック関数に関連する.//
struct mmc_bus_ops {
   void (*remove)(struct mmc_host *);
   void (*detect)(struct mmc_host *);
   int (*sysfs_add)(struct mmc_host *, struct mmc_card *card);
   void (*sysfs_remove)(struct mmc_host *, struct mmc_card *card);
   void (*suspend)(struct mmc_host *);
   void (*resume)(struct mmc_host *);
};
//  mmc core/mmc.c
static const struct mmc_bus_ops mmc_ops = {
   .remove = mmc_remove,
   .detect = mmc_detect,
   .sysfs_add = mmc_sysfs_add,
   .sysfs_remove = mmc_sysfs_remove,
   .suspend = mmc_suspend,
   .resume = mmc_resume,
};
// sd core/sd.c
static const struct mmc_bus_ops mmc_sd_ops = {
   .remove = mmc_sd_remove,
   .detect = mmc_sd_detect,
   .sysfs_add = mmc_sd_sysfs_add,
   .sysfs_remove = mmc_sd_sysfs_remove,
   .suspend = mmc_sd_suspend,
   .resume = mmc_sd_resume,
};
// sdio core/sdio.c
static const struct mmc_bus_ops mmc_sdio_ops = {
   .remove = mmc_sdio_remove,
   .detect = mmc_sdio_detect,
};

バス操作の関数について:.detectは、ドライバがmmcカードの状態を検出するためにこの関数を呼び出すことが多い、具体的にはCMD 13コマンドを送信して応答を読み返し、応答が間違っている場合は順次呼び出すことを実現する.remove、detach_busはカードを除去し、バスを解放します.
全体アーキテクチャ:kernel起動時、mmc_を前後して実行Init()およびmmc_blk_Init()は、mmcデバイスおよびmmcブロックモジュールを初期化する.次にmmcデバイスドライバをマウントすると、ドライバ内のxx_が実行されます.mmc_probe()は、hostデバイスにマウントされているsdデバイスを検出します.probe関数はhostデバイスを作成し、遅延タスクmmc_を開きます.rescan().駆動マウントに成功した後、mmc_rescan()関数が実行され、カードが初期化される(ステップは後述).バスに有効なデバイスがスキャンされた場合、対応する関数を呼び出してデバイスをシステムにインストールします.mmc_attach_sdio()、mmc_attach_sd()、mmc_attach_mmc()の3つの関数は、それぞれsdioデバイス、sdカード、mmcカードをロードします.sdカードでは、駆動サイクルでACMD 41、CMD 55をカードに送信し、OCRレジスタを読み出し、成功後、CMD 2(CIDを読む)、CMD 3(RCAを得る)、CMD 9(CSDを読む)、CMD 7(選択カードを読む)の順に送信する.あといくつかのコマンドはACMD 41&CMD 51で、CMD 6を使用して高速モードに切り替えるなど、いくつかの機能を切り替えます.上記の手順により、現在挿入されているカードが有効で識別可能なメモリカードであることが判明した.次にmmc_を呼び出すadd_card()はメモリカードをシステムに追加します.正式にシステムドライバと接続されています.カードデバイスをシステムに追加した後、mmcブロックデバイスに駆動を通知します.ブロックデバイスドライバがprobe関数、すなわちmmc_を呼び出すblk_probe()関数,mmc_blk_Probe()はまず新しいmmc_を割り当てるblk_data構造変数を呼び出し、mmc_を呼び出すinit_Queue、blkキューを初期化します.スレッドmmc_を作成しますqueue_thread().
mmc_rescan:mmc_rescan()関数は、駆動マウント時に、駆動xx_mmc_probe()呼び出しmmc_alloc_host()時に開始される遅延タスク.xx_mmc_probe()->mmc_alloc_host()->INIT_DELAYED_WORK(&host->detect, mmc_rescan);当
core部1、取得バス2、バス操作構造ポインタbus_をチェックopsは,空であれば各バスを再利用してポートを走査し,検出順序はSDIO,Normal SD,MMCの順である.対応するカードタイプが検出されたら、mmc_を使用します.attach_bus()は対応するバス操作をhostに接続する.void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops)
{
   ...
   host->bus_ops = ops;
   ...
}

3、初期化カードは以下のプロセスの初期化に続く:a、CMD 0を送信カードをIDLE状態bに入れ、CMD 8を送信し、カードがSD 2かどうかを検査する.0.SD1.1はCMD 8に対応するものではないので、SD 2にある.0 Specでは、まずCMD 8を送信ことが提案されているが、応答が無効なコマンドであれば、カードはSD 1である.1,そうでなければSD 2である.0(SD 2.0 Spec参照).c、CMD 5を送信してOCRレジスタを読み出す.d、ACMD 55、CMD 41を送信し、カードを動作状態にする.MMCカードはACMD 55、CMD 41をサポートしていません.このステップが通過した場合、このカードがSDカードであることを証明します.e、dステップが間違っている場合は、CMD 1を送信してカードがMMCであるか否かを判定する.SDカードはCMD 1をサポートしないが、MMCカードはSDとMMCタイプの判断根拠となる.f、ACMD 41もCMD 1もパスできない場合、このカードはおそらく無効なカードで、初期化に失敗します.