1. 程式人生 > >uboot的eMMC初始化程式碼流程分析

uboot的eMMC初始化程式碼流程分析

原始碼參考九鼎科技移植的X210開發板捆綁BSP中的uboot, 版本為1.3.4

mmc初始化函式int mmc_initialize(bd_t *bis)在uboot/lib_arm/board.c中的start_armboot()函式中被呼叫(uboot的C語言階段)

puts ("SD/MMC:  ");
mmc_exist = mmc_initialize(gd->bd);

1. 函式本體在uboot/mmc/mmc.c中

    INIT_LIST_HEAD(&mmc_devices);
    cur_dev_num = 0;

mmc_devices是一個mmc.c中定義的核心連結串列型別的全域性變數

struct list_head {
    struct list_head *next, *prev;
};
static struct list_head mmc_devices;

INIT_LIST_HEAD初始化mmc_devices, 將next, prev都指向自己,表示目前沒有已註冊的mmc裝置, cur_dev_num被相應初始化為0

#define INIT_LIST_HEAD(ptr) do { \
    (ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)

cpu_mmc_init(bd_t *bis)函式中呼叫了三個初始化函式,函式定義在uboot/cpu/s5pc11x/cpu.c中

setup_hsmmc_clock();
setup_hsmmc_cfg_gpio();
smdk_s3c_hsmmc_init();

setup_hsmmc_clock()的定義在uboot/cpu/s5pc11x/setup_hsmmc.c中, 設定MMC通道0和通道2的clock source為SCLKMPLL(暫存器CLK_SRC4), 設定分頻係數(暫存器CLK_DIV4)使得給MMC的時鐘頻率小於50Mhz

setup_hsmmc_cfg_gpio()的定義也在uboot/cpu/s5pc11x/setup_hsmmc.c中, 設定MMC通道0和通道2相應的GPIO為mmc模式,MMC0對應GPG0, MMC2對應GPG2,主要設定暫存器GPG0CON, GPG0PUD, GPG2CON, GPG2PUD

smdk_s3c_hsmmc_init()的定義在uboot/drivers/mmc/s3c_hsmmc.c中,其中對通道0和通道2分別呼叫了s3c_hsmmc_initialize(), 函式定義也在uboot/drivers/mmc/s3c_hsmmc.c中

static int s3c_hsmmc_initialize(int channel)

mmc設定維護在mmc_channel[]這個結構體陣列中,每次呼叫s3c_hsmmc_initialize(x)就是對特定通道的mmc裝置進行初始化的過程

struct mmc mmc_channel[MMC_MAX_CHANNEL];
mmc = &mmc_channel[channel];

mmc裝置初始化的過程包括以下內容,主要是填充了mmc_host[x]和mmc_channel[x]兩個結構體
a. mmc->name賦值

sprintf(mmc->name, "S3C_HSMMC%d", channel);

b. mmc->priv賦值,mmc_host[]是uboot/drivers/mmc/s3c_hsmmc.c中定義的一個結構體陣列

mmc->priv = &mmc_host[channel];
struct sdhci_host mmc_host[MMC_MAX_CHANNEL];

c. 其它賦值

    mmc->send_cmd = s3c_hsmmc_send_command;
    mmc->set_ios = s3c_hsmmc_set_ios;
    mmc->init = s3c_hsmmc_init;

    mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
    mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS;
#if defined(USE_MMC0_8BIT) || defined(USE_MMC2_8BIT)
    mmc->host_caps |= MMC_MODE_8BIT;
#endif
    mmc->f_min = 400000;
    mmc->f_max = 52000000;
    mmc_host[channel].clock = 0;

d. 繫結mmc_host[x]與S5PV210對應mmc通道的暫存器地址, SDMA System Address register (Channel X)

mmc_host[channel].ioaddr = (void *)ELFIN_HSMMC_X_BASE;

c. 最後呼叫int mmc_register(struct mmc *mmc)進行註冊, 函式定義在uboot/drivers/mmc/mmc.c中, 註冊內容也是填充mmc_channel[x]結構體, 包括把這個結構體內嵌的核心連結串列初始化並加入到mmc_devices連結串列的尾端

    mmc->block_dev.if_type = IF_TYPE_MMC;
    mmc->block_dev.dev = cur_dev_num++;
    mmc->block_dev.removable = 1;
    mmc->block_dev.block_read = mmc_bread;
    mmc->block_dev.block_write = mmc_bwrite;

    INIT_LIST_HEAD(&mmc->link);
    list_add_tail(&mmc->link, &mmc_devices);

struct mmc *find_mmc_device(int dev_num)函式定義在uboot/drivers/mmc/mmc.c中, 用於在mmc_devices查到到已經註冊的mmc device結構體

mmc = find_mmc_device(0);

如果找到的話, 進行card初始化操作(retry一次)

err = mmc_init(mmc);

int mmc_init(struct mmc *host)函式定義在uboot/drivers/mmc/mmc.c中,包括卡的具體狀態機流程,將另起一編進行分析

相關推薦

uboot的eMMC初始程式碼流程分析

原始碼參考九鼎科技移植的X210開發板捆綁BSP中的uboot, 版本為1.3.4 mmc初始化函式int mmc_initialize(bd_t *bis)在uboot/lib_arm/board.c中的start_armboot()函式中被呼叫(uboot

[Android7.0]NFC初始流程分析

1、NFC初始化的時序圖: 2、程式碼分析: 初始化分兩部分,第一供應framework使用的服務端初始化,並將服務新增到ServiceManager中,第二是初始化NFC介面卡NfcAdapter,其中就包含何種對應NFC協議的服務。 * 服務端的初

U-boot初始階段流程分析

U-boot的初始化主要分為兩個階段 第一階段:主要是SOC內部的初始化,板級的初始化比較少,所以移植的修改量比較小。此階段由組合語言編寫,程式碼主體分佈在start.S和lowlevel_init.S中。 其中start.S作為主幹,其主要流程為: 注:

DDR2初始程式碼分析[s5pv210, K4T1G164QQ]

以下流程基本為簡單翻譯(原文參考s5pv210的資料手冊1.2.1.3章節) 1. DMC及DDR2顆粒上電, 且電壓穩定 2. DMC保持CKE為低電平 3. SOC提供時鐘(XDDR2SEL保持高電平以保持CKE為低) 4. 根據實際工作時鐘頻率設定

SpringMVC初始階段流程源碼分析

ext and 啟動 rtti nal apm isa 分析 img 1、都知道SpringMVC項目啟動的時候都會初始化一個類:DispatcherServlet,看這個類的源碼我們可以發現他其實就是一個servlet, 為什麽這麽說呢?請看: DispatcherS

【DWM1000】 code 解密一 工程初始代碼分析

eof associate 回調函數 pre ack 也有 tca use fas Draft ,以後整理 instance_init 函數追下去,絕大多數的代碼都在初始化如下結構體 typedef struct { INST_MODE mode; instan

SpringMVC(一)--SpringMVC的初始流程

設計 splay 上傳 app color 完成 關系 handler 數據庫 SpringMVC是Spring提供給WEB應用的MVC框架,MVC框架一般來說由三部分組成: Model:模型層,一般由java bean完成,主要是進行數據庫操作; View:視圖層

java 類的成員之四 初始程式碼塊(程式碼塊)的使用

java 類的成員之四 初始化程式碼塊(程式碼塊)的使用 1.java類的成員有四個 2.非static(非靜態)程式碼塊(初始化塊)的使用 3.static(靜態)程式碼塊(初始化塊)的使用 4.java初始化塊面試題

hyperledger fabric超級賬本java sdk樣例e2e程式碼流程分析

 一  checkConfig  Before     1.1  private static final TestConfig testConfig = TestConfig.getConfig();  &

twemproxy0.4原理分析-系統初始過程原理分析

概述 本文介紹twemproxy的系統初始化過程。該過程包括以下幾個方面的內容: 讀取配置檔案,根據配置檔案初始化資料結構 和後臺伺服器建立連線,形成伺服器連線池 初始化事件處理框架,並設定最開始的事件處理函式 建立twemproxy的監聽socket,

spi nand driver程式碼流程分析

硬體環境     主晶片:bcm63xx,      spi nand:Winbond W25N01GV 程式碼環境     linux-4.1.27/drivers/mtd         mtd_blkdevs.o  mtdblock.o  mtdchar.o  m

SpringXD 任務、啟動訊息通訊程式碼流程分析

任務部署時,xd-admin和container之間通過zookeeper的節點監聽通訊。container監聽zk deployment節點,執行部署。同事繫結kafka message consumer和reactor subscriber。 任務啟動時,xd-admin和container通過

各大主流網站css初始程式碼

程式碼是網上找到  順便做個筆記,如有侵權請通知我刪除 謝謝 首先是要做css初始化的原因: 不同瀏覽器對各個元素的margin,padding,border,font等屬性的定義各有不同,不同瀏覽器的顯示效果可能不一樣,為杜絕這種情況,通過css強制讓所有元素的屬性值都一

nova boot程式碼流程分析(四):nova與neutron的l2 agent(neutron-linuxbridge-agent)互動

#/nova/virt/libvirt/driver.py:LibvirtDriver # NOTE(ilyaalekseyev): Implementation like in multinics # for xenapi(tr3buchet)

C語言全域性未初始資料段分析

前言:         在分析C語言全域性未初始化變數時,發現在目標檔案中全域性未初始化變數並不是直接放在bss段中。         再後來發現在兩個.c檔案中定義同名的全域性變數,連結時居然沒有

C/C++—— 在建構函式中呼叫虛擬函式能實現多型嗎(Vptr指標初始的過程分析

問題引入: 比如:如果我們想在父類的建構函式中呼叫虛擬函式,當定義子類物件的時候,父類的建構函式中的虛擬函式執行的是子類中的函式。 在下面的例子中,定義子類物件的時候,在父類建構函式中的print虛擬函式執行的不是子類中的print函式,而是父類中的prin

GD32晶片的USART1初始程式碼

void usart_init(void) { /* Enable USART2 APB clock */ RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_USART1, ENABLE); /* USART1 Pins configu

Spring 初始過程詳細分析 [原始碼] (二)

上章講到org.springframework.context.support.AbstractApplicationContext.refresh() ,這個方法完成了spring IOC容器的初始化, 在看程式碼前,我們首先要大概瞭解下spring BeanFactor

Android狀態列顯示電池狀態程式碼流程分析

BatteryController.java 註冊廣播接收器,接收Intent.ACTION_BATTERY_CHANGED廣播 之後呼叫BatteryStateChangeCallback cb.onBatteryLevelChanged(level, plugged)來

Spring初始過程原始碼分析(1)

本文主要詳細分析Spring初始化過程的原始碼分析,目的是理解Spring具體是如何工作的。部分內容查閱於網路,有不妥之處望指正。 1、web專案中伺服器一啟動就開始載入web.xml,Spring的啟動是從web.xml中的org.springframewo