讀本篇博文所需要的先行知識
關于芯片內部的ROM的作用、工作原理的介紹,鏈接如下:
https://blog.csdn.net/wenhao_ir/article/details/145969584
eMMC的物理結構、特點、用途
這個標題的相關內容見我的另一篇博文,博文鏈接如下:
https://blog.csdn.net/wenhao_ir/article/details/145367399
eMMC設備的存儲區域結構
eMMC(Embedded MultiMediaCard)是一種嵌入式存儲設備,符合JEDEC(Joint Electron Device Engineering Council)標準,廣泛用于嵌入式系統,如智能手機、單板計算機和工業設備。eMMC的存儲區域結構主要包括以下部分:
1. Boot Partition(引導分區)
- 作用:用于存儲引導加載程序(如U-Boot),系統啟動時可以直接從該區域加載引導代碼。
- 特點:
- eMMC通常提供兩個Boot分區(
Boot Partition 1
和Boot Partition 2
)。這兩個Boot分區在Fastboot(FB)協議中通常被命令名為boot0和boot1,并分別編號為1和2。關于Fastboot(FB)協議的詳細介紹,請見博文 https://blog.csdn.net/wenhao_ir/article/details/145985144 - 每個Boot分區的大小通常是固定的(如128KB、512KB或4MB,取決于eMMC規格)。
- 可以通過
EXT_CSD[179] BOOT_CONFIG
配置哪個Boot分區用于啟動。關于EXT_CSD[179] BOOT_CONFIG
的詳細介紹見本博文后面。 - 只能通過特殊方式(如u-boot中的eMMC命令
mmc bootpart enable
或 Linux 系統下的命令dd if=uboot.img of=/dev/mmcblkXboot0
)寫入。 - 不能用于普通數據存儲。
- eMMC通常提供兩個Boot分區(
2. RPMB(Replay Protected Memory Block,防重放保護存儲區)
- 作用:
- 主要用于存儲安全相關數據,例如加密密鑰、認證信息、防篡改數據等。
- 具有防重放保護機制,可防止存儲數據的回滾攻擊。防重放保護通常是指防止攻擊者通過回滾存儲器內容,恢復到較早的狀態,從而繞過安全檢查或重現舊的、可能已被撤銷的憑據。
- 特點:
- 只能通過安全認證的方式訪問,不能像普通塊設備一樣讀寫。
- 通常容量較小,例如512KB或更大。
- 不能直接掛載或用于普通存儲。
3. General Purpose Partitions(通用分區)
- 作用:
- 額外的可由用戶定義的分區,可用于存儲操作系統、應用程序或其他數據。
- 特點:
- eMMC允許創建最多4個通用分區。
- 大小可配置,但一旦分配就不能動態調整。
- 適用于某些特殊用途,例如存放文件系統、日志或者特定數據。
4. User Data Area(用戶數據區域)
- 作用:
- 主要存儲操作系統、根文件系統、用戶數據等。
- 特點:
- 這個區域是eMMC中容量最大的部分,相當于普通SD卡的存儲空間。
- 可以劃分多個邏輯分區(如ext4、FAT等)。
- 直接映射為Linux設備,例如
/dev/mmcblkX
(裸設備)或/dev/mmcblkXpY
(分區)。 - 采用可磨損均衡(Wear Leveling)和壞塊管理機制,以提高eMMC的壽命和穩定性。
5. Enhanced User Data Area(增強型用戶數據區)
- 作用:
- 允許將部分User Data Area轉換為SLC模式,以提升寫入壽命和可靠性。
- 特點:
- 通過配置EXT_CSD寄存器來分配。
- 犧牲存儲容量換取更高的耐久性。
- 適用于高頻寫入的數據,如日志、數據庫等。
6.eMMC分區示意圖
下面分區示意圖中提到的“FB協議”的詳細介紹請參看我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145985144
+----------------------+ 0x00000000
| Boot Partition 1 | (大小固定,如4MB)【在FB協議中被命令為boot0,編號為1】
+----------------------+
| Boot Partition 2 | (大小固定,如4MB)【在FB協議中被命令為boot1,編號為2】
+----------------------+
| RPMB Partition | (大小固定,如512KB)
+----------------------+
| General Purpose 1 | (可選)
+----------------------+
| General Purpose 2 | (可選)
+----------------------+
| General Purpose 3 | (可選)
+----------------------+
| General Purpose 4 | (可選)
+----------------------+
| User Data Area | (最大存儲區域)【在FB協議中被命令為 userdata 或 mmcblk0,編號為0】
+----------------------+ 0xFFFFFFFF
上面這個分區示意圖中eMMC的相關分區在FB(Fastboot)協議中的名稱和編號再附一張表:
eMMC 分區 | Fastboot 分區名稱 | 編號 (mmc partconf) |
---|---|---|
Boot Partition 1 | boot0 | 1 |
Boot Partition 2 | boot1 | 2 |
User Data Area(主存儲區) | userdata 或 mmcblk0 | 0 |
eMMC通常存儲容量有多大?我開發析上的eMMC容易有多大?
從上面的分區示意圖可以看出,其尋址空間為0x00000000~0xFFFFFFFF,一共有8個F,即32位,32位剛好對應的是4GB,所以eMMC通常的存儲容量是4GB大小。我的開發板也正是4GB大小的eMMC,如下圖所示:
在核心版的原理圖中(文件MYC-Y6ULX1211.pdf)中搜索“eMMC”得到如下結果:
然后查看板子的絲印文件(100ask_imx6ull_PRO_V11_silktop(絲印圖).pdf):
所在eMMC芯片在硬件實物中的位置如下圖所示:
7. Linux系統中將eMMC的各區域分別映射為什么名稱的設備文件?
在Linux系統中,eMMC的不同區域通常會映射成不同的設備節點:
eMMC區域 | 設備節點示例 | 說明 |
---|---|---|
Boot Partition 1 | /dev/mmcblk0boot0 | 引導分區 1 |
Boot Partition 2 | /dev/mmcblk0boot1 | 引導分區 2 |
RPMB Partition | /dev/mmcblk0rpmb | 認證存儲區(受保護) |
User Data Area | /dev/mmcblk0 | 用戶數據區(整個eMMC) |
分區1(如rootfs) | /dev/mmcblk0p1 | 用戶數據區的一個分區 |
分區2(如/data) | /dev/mmcblk0p2 | 用戶數據區的另一個分區 |
如何查看Linux系統的eMMC的分區信息(設備節點信息)
可以使用以下命令查看eMMC的分區信息:
lsblk
cat /proc/partitions
ls /dev/mmcblk*
fdisk -l /dev/mmcblk*
我的開發板運行命令lsblk
的結果如下:
我的開發板運行命令cat /proc/partitions
的結果如下:
[root@imx6ull:~]# cat /proc/partitions
major minor #blocks name
.....179 0 3817472 mmcblk1179 1 512000 mmcblk1p1179 2 1048576 mmcblk1p2179 3 10240 mmcblk1p3179 24 4096 mmcblk1rpmb179 16 4096 mmcblk1boot1179 8 4096 mmcblk1boot0
從運行結果來看,用戶數據區(User Data Area )的設備節點名為mmcblk1
,它被劃分成了三個邏輯分區,分別為mmcblk1p1
、mmcblk1p2
、mmcblk1p3
,容量大小情況如下:
mmcblk1
:3817472KB = 3728MB ≈ 3.6GB
mmcblk1p1
:512000KB = 500MB ≈ 0.48GB
mmcblk1p2
:1048576KB = 1024MB ≈ 1 GB
mmcblk1p3
:10240KB = 10MB
可見,第2分區是最大的,有1個GB的大小。
命令fdisk -l /dev/mmcblk*
的運行結果如下:
從中可以看到eMMC設備節點的詳細信息,我整理一下輸出信息如下:
[root@imx6ull:~]# fdisk -l /dev/mmcblk*Disk /dev/mmcblk1boot0: 4 MB, 4194304 bytes, 8192 sectors
128 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Disk /dev/mmcblk1boot0 doesn't contain a valid partition tableDisk /dev/mmcblk1boot1: 4 MB, 4194304 bytes, 8192 sectors
128 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Disk /dev/mmcblk1boot1 doesn't contain a valid partition tableDisk /dev/mmcblk1: 3728 MB, 3909091328 bytes, 7634944 sectors
119296 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type
/dev/mmcblk1p1 * 0,65,4 63,254,1 4098 1028097 1024000 500M 83 Linux
/dev/mmcblk1p2 * 63,254,2 194,137,9 1028098 3125249 2097152 1024M 83 Linux
/dev/mmcblk1p3 194,137,10 195,207,14 3125250 3145729 20480 10.0M c Win95 FAT32 (LBA)Disk /dev/mmcblk1p1: 500 MB, 524288000 bytes, 1024000 sectors
16000 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Disk /dev/mmcblk1p1 doesn't contain a valid partition tableDisk /dev/mmcblk1p2: 1024 MB, 1073741824 bytes, 2097152 sectors
32768 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Disk /dev/mmcblk1p2 doesn't contain a valid partition tableDisk /dev/mmcblk1p3: 10 MB, 10485760 bytes, 20480 sectors
320 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Disk /dev/mmcblk1p3 doesn't contain a valid partition tablefdisk: can't open '/dev/mmcblk1rpmb': Input/output error
上面輸出信息中mmcblk1p1
和mmcblk1p2
在Boot項上有個*
代表這兩個分區是可引導的,但在ARM 嵌入式系統這個信息不重要,原因是i.MX6ULL 內部的 ROM中的 代碼可以直接從 eMMC 的Boot Partition (比如mmcblk1boot1) 中加載 U-Boot,無需從用戶數據區去加載引導程序(u-boot)。這里的*
號只是一個標志,表示該分區被設定為可引導,但不一定真正參與系統啟動。
eMMC的EXT_CSD[179] BOOT_CONFIG
是什么東西?
名字來源
EXT_CSD
這個名字的來源是Extended CSD
。CSD
是Card-Specific Data
的縮寫,直譯為“卡指定數據”,即為為設置存儲卡指定的數據,實際上就是存儲器的寄存器。
所以我們通常說:“eMMC 設備的 EXT_CSD寄存器。”
eMMC 設備的 EXT_CSD寄存器是一個 512 字節大小的寄存器空間,用于存儲 eMMC 設備的各種擴展配置參數。EXT_CSD[179] 表示 EXT_CSD 寄存器的第 179 個字節(從 0 開始計算)。在 eMMC 規格中,EXT_CSD[179] 這個字節被定義為 BOOT_CONFIG(引導配置),所以出現了標題中的EXT_CSD[179] BOOT_CONFIG
這個名字。
EXT_CSD[179]
(BOOT_CONFIG)寄存器解析
EXT_CSD[179]
(BOOT_CONFIG)寄存器解析如下:
EXT_CSD[179]
主要用于設置 eMMC 的引導相關配置,包括:
- 選擇哪個 Boot 分區作為默認啟動分區。
- 是否啟用 Boot 訪問模式。
- 是否啟用高速度模式(HS_TIMING)。
BOOT_CONFIG
(EXT_CSD[179])的位定義:
位范圍 | 名稱 | 說明 |
---|---|---|
7 | BOOT_ACK | 是否在 Boot 過程中啟用 BOOT_ACK 響應(0: 關閉,1: 使能)。【關于什么叫 BOOT_ACK 響應,請往后面看】 |
6:5 | BOOT_PARTITION_ENABLE | 選擇哪個 Boot 分區用于啟動: 00b - 用戶分區 01b - Boot 分區1 10b - Boot 分區2 11b - 保留 |
4:3 | BOOT_PARTITION_ACCESS | 選擇當前訪問的 Boot 分區(僅在 BOOT_MODE 訪問時生效):00b - 用戶分區 01b - Boot 分區1 10b - Boot 分區2 11b - 保留 |
2:0 | BOOT_MODE | Boot 訪問模式選擇: 000b - 普通數據模式 001b - 強制 Boot 010b - 備用 Boot 011b - 用戶區 Boot 100b - 關機后 Boot 其他 - 保留 |
BOOT_CONFIG
的常見配置:
如果你希望 eMMC 在上電后自動從 Boot 分區 1 啟動,并啟用 BOOT_ACK
,可以設置:
EXT_CSD[179] = 0x48 // 0b01001000
解釋:
BOOT_ACK
= 1(啟用 Boot ACK)BOOT_PARTITION_ENABLE
= 01(Boot 分區 1)BOOT_PARTITION_ACCESS
= 00(無 Boot 訪問)BOOT_MODE
= 000(普通數據模式)
如何修改 EXT_CSD[179]
:
在 u-boot中,可以使用 mmc
工具進行查看和修改:
讀取 EXT_CSD 信息
mmc extcsd read /dev/mmcblk0修改 Boot 分區配置(例如設置為 Boot 分區1)
mmc bootpart enable 1 1 /dev/mmcblk0
如果你是用 mmc
設備直接操作,可以通過 mmc cmd6
命令修改 EXT_CSD[179]
。
什么叫eMMC的 BOOT_ACK
響應?
BOOT_ACK
(Boot Acknowledge,啟動確認)是 eMMC 在 Boot 過程中提供的一個特殊的確認信號,用于指示 eMMC 設備已進入 Boot 模式,并準備好傳輸 Boot 數據了。
在 eMMC 設備的 EXT_CSD[179]
(BOOT_CONFIG)寄存器的 第 7 位(bit7) 控制是否啟用 BOOT_ACK
機制:
BOOT_ACK = 0
(默認) → 設備在 Boot 過程中不會發送 ACK 響應,主機必須自己確定 eMMC 是否進入了 Boot 模式。BOOT_ACK = 1
→ eMMC 在 Boot 過程開始時會發送一個ACK
響應,通知主機 Boot 過程已啟動。
BOOT_ACK
作用
-
確保 eMMC 進入 Boot 模式
- 在
BOOT_ACK
使能的情況下,主機(比如 BootROM 或 Bootloader)可以通過檢測ACK
確保 eMMC 正確進入 Boot 模式。
- 在
-
提高 Boot 穩定性
- 某些平臺在上電初始化時,需要確保 eMMC 設備正確響應 Boot 過程,否則可能會進入錯誤狀態。
-
防止誤讀取數據
BOOT_ACK
使能后,主機不會誤將未準備好的數據當作 Boot 數據讀取。
eMMC BOOT_ACK
過程
-
主機復位并發送 Boot 啟動命令
- 發送
CMD0
(GO_IDLE_STATE)并選擇 Boot 模式。【關于CMD0
是怎么回事?請看本篇博文后面內容(搜索“eMMC的命令詳解”和“關于 eMMC的CMD0
命令選擇Boot 模式的工作流程的詳解”)。】
- 發送
-
eMMC 響應
BOOT_ACK
(如果啟用)- 設備進入 Boot 狀態后,會返回
ACK
,通知主機已準備好發送 Boot 數據。
- 設備進入 Boot 狀態后,會返回
-
主機開始接收 Boot 數據
- 設備按照 Boot 配置傳輸 Boot 分區數據(通常是
BOOT_PARTITION_1
或BOOT_PARTITION_2
)。
- 設備按照 Boot 配置傳輸 Boot 分區數據(通常是
在Linux系統下,如何讀取EXT_CSD[179]
的配置值?
在 Linux 設備中,可以查看 eMMC 的EXT_CSD[179]
的配置值,用下面的命令即可:
mmc extcsd read /dev/mmcblk0 | grep BOOT_CONFIG
你應該會看到 EXT_CSD[179]
配置,例如:
BOOT_CONFIG = 0x48
其中:
0x48 = 0b01001000
BOOT_ACK = 1
(使能 Boot ACK)BOOT_PARTITION_ENABLE = 01
(Boot 分區 1)BOOT_PARTITION_ACCESS = 00
(無手動訪問)
之前已經確認(搜索“ 如何查看Linux系統的eMMC的分區信息(設備節點信息)”),我的開發板的eMMC的設備節點名為mmcblk1
,所以對于我的開發板,需要運行下面的命令:
mmc extcsd read /dev/mmcblk1 | grep BOOT_CONFIG
但運行結果如下:
這說明在讀取/dev/mmcblk1
的配置信息中,只搜索到一句話含有BOOT_CONFIG
這個關鍵詞,這句話如下:
Boot config protection [BOOT_CONFIG_PROT: 0x00]
BOOT_CONFIG_PROT
是 Boot 配置保護的寄存器,用于 保護 eMMC Boot 分區配置,防止意外修改。0x00
說明 Boot 配置保護未啟用,你仍然可以修改 eMMC 的 Boot 分區配置。
也就是說沒有出現我們期望的信息,看來如何在Linux系統中獲取EXT_CSD[179]
的配置值,還需要進一步研究, 但這個問題并不是本篇博文的重點,所以暫且把這個問題放在一邊。
eMMC的哪些分區是不可調整的?哪些是可以調整的?
問:eMMC的存儲區域是出廠時就劃分好的,還是后來根據需要用工具或命令劃分的?
答:
1. 出廠默認劃分的區域
在 eMMC 出廠時,制造商已經預先劃分了以下區域:
eMMC 區域 | 出廠時狀態 |
---|---|
Boot Partition 1 | 預設大小(如 4MB),無法調整 |
Boot Partition 2 | 預設大小(如 4MB),無法調整 |
RPMB Partition | 預設大小(如 512KB),無法調整 |
User Data Area | 整個剩余容量,可以重新分區 |
General Purpose Partitions(通用分區) | 默認不存在,需要手動創建 |
2. 后續可手動調整的部分
雖然 Boot 分區和 RPMB 分區的大小是固定的,但用戶可以使用工具或命令進行如下調整:
- 劃分用戶數據區(User Data Area) → 用
fdisk
、parted
等工具創建文件系統分區,如/dev/mmcblk0p1
(rootfs)、/dev/mmcblk0p2
(data)。 - 創建通用分區(General Purpose Partitions) → 通過修改 eMMC 的
EXT_CSD
寄存器,將一部分用戶數據區轉換為通用分區。 - 轉換部分用戶數據區為增強型存儲(Enhanced User Data Area, SLC模式) → 提升可靠性,但會減少容量。
eMMC的主要引腳功能介紹
eMMC(嵌入式多媒體卡)采用 BGA 封裝,不同版本的 eMMC 可能有不同的引腳定義。一般來說,eMMC 主要使用 11 個信號引腳,支持 1-bit、4-bit 和 8-bit 數據總線模式。
1. eMMC 主要引腳功能
eMMC 采用 BGA-153、BGA-169 或 BGA-100 封裝,以下是常見的引腳定義:
引腳名稱 | 引腳編號 | 描述 |
---|---|---|
VCC | 供電引腳 | 核心電源(通常為 3.3V) |
VCCQ | 供電引腳 | I/O 電源(1.8V 或 3.3V,根據工作模式) |
VSS / GND | 供電引腳 | 地線 |
CLK(Clock) | 時鐘信號 | 由主機提供時鐘(最大 200MHz,HS400 模式下可達 400MHz) |
CMD(Command) | 命令信號 | 雙向信號,用于主機和 eMMC 之間傳輸命令和響應 |
DAT0-DAT7(Data) | 數據線 | 支持 1-bit(DAT0)、4-bit(DAT0-DAT3)、8-bit(DAT0~DAT7) 模式 |
RST_n(Reset) | 復位信號 | 可選,用于硬件復位 |
DS(Data Strobe) | 僅在 HS400 模式下使用 | 提高數據同步精度 |
NC(Not Connected) | - | 保留未使用的引腳 |
2. 詳細引腳說明
(1)電源相關
- VCC(核心電源):通常為 3.3V,部分低功耗 eMMC 可能支持 1.8V。
- VCCQ(I/O 電源):
- 3.3V(常見于舊版 eMMC 4.3 及以下)
- 1.8V(eMMC 4.5 及以上,低功耗模式)
- VSS(GND):地線,必須連接到電源地。
(2)控制信號
- CLK(時鐘信號):
- 由主機提供,用于同步數據傳輸。
- 默認頻率 0~26MHz,高速模式可達 52MHz,HS200/HS400 模式下可達 200MHz/400MHz。
- CMD(命令信號):
- 由主機發送 eMMC 命令,eMMC 也可在該引腳上返回響應(雙向)。
- 邏輯上屬于 開漏/推挽驅動。
- RST_n(復位信號,可選):
- 低電平復位 eMMC,部分 eMMC 可能不支持該引腳。
(3)數據傳輸
- DAT0~DAT7(數據線):
- DAT0:用于 1-bit 模式。
- DAT0-DAT3:用于 4-bit 模式。
- DAT0-DAT7:用于 8-bit 模式(通常用于 eMMC)。
- 具有 內部上拉,在 空閑狀態 下維持高電平。
- DS(數據選通信號,HS400 模式專用):
- 僅在 HS400 模式 下使用。
- 作用:主機用于數據同步。
3. eMMC 數據模式
模式 | 使用的引腳 | 速率 |
---|---|---|
1-bit 模式 | CLK、CMD、DAT0 | 低速 |
4-bit 模式 | CLK、CMD、DAT0-DAT3 | 中速 |
8-bit 模式 | CLK、CMD、DAT0-DAT7 | 高速(推薦) |
在 Linux/嵌入式系統中,eMMC 通常采用 8-bit 模式,以提高讀寫效率。
4. BGA-153 引腳排列示意圖
典型的 BGA-153(11x11)封裝 引腳示意:
____________________________| || DAT7 DAT6 DAT5 DAT4 | ← 數據線| VSS VCCQ CMD CLK | ← 控制 & 電源| DAT3 DAT2 DAT1 DAT0 | ← 數據線|____________________________|
不同封裝(BGA-100、BGA-153、BGA-169)的引腳排列可能有所不同,但信號功能基本相同。
5.關于eMMC沒有地址線的說明(eMMC如何進行尋址)
1. eMMC 為何沒有地址線?
在傳統的并行存儲器(如 NOR Flash、SRAM)中,CPU 需要使用 地址線(Address Bus) 選擇存儲單元,用 數據線(Data Bus) 進行讀寫。但 eMMC 采用 MMC(MultiMediaCard)協議,使用 CMD 命令接口 進行數據尋址,并通過 數據線(DAT0-DAT7) 傳輸數據,因此 不需要單獨的地址線。
2. eMMC 的尋址方式
eMMC 的尋址是基于 邏輯塊地址(LBA, Logical Block Addressing),類似于硬盤(SD 卡也是同樣的方式)。訪問數據時:
- CPU 通過 CMD 發送讀/寫命令,指定要訪問的 LBA 地址。
- eMMC 內部的 Flash 控制器 解析 LBA 地址,將其映射到 NAND Flash 物理地址。
- 數據通過 DAT 線傳輸,并由 eMMC 內部管理 ECC、磨損均衡等。
Linux 訪問 eMMC 時,通常把它當作塊設備 /dev/mmcblk0
,通過 dd
、fdisk
等工具進行分區和訪問,而不是像 SRAM 那樣直接使用地址線訪問
eMMC的命令詳解
eMMC(嵌入式多媒體卡)遵循 MMC(MultiMediaCard)協議,使用一套標準的 命令格式(Command Format) 來與主機(如處理器或控制器)進行通信。eMMC 的命令分為多種類型,并采用 48-bit 或 136-bit 的格式。
1. eMMC 命令格式
eMMC 命令的基本格式如下:
位 | 名稱 | 說明 |
---|---|---|
47 | 起始位(Start Bit) | 固定為 0 |
46 | 傳輸方向(Transmission Bit) | 1 表示主機到設備,0 表示設備到主機 |
45:40 | 命令索引(Command Index) | 6-bit 命令編號,如 CMD0 為 000000 |
39:8 | 參數(Argument) | 32-bit 參數,具體值因命令而異 |
7:1 | CRC 校驗(CRC7) | 7-bit 循環冗余校驗 |
0 | 結束位(End Bit) | 固定為 1 |
注意:
- 該格式適用于 所有 48-bit 命令(最常見)。
CMD2
例外,它使用 136-bit 長響應,返回CID
號(卡片標識)。
2. eMMC 命令類型
(1)基本命令
命令 | 名稱 | 描述 |
---|---|---|
CMD0 | GO_IDLE_STATE | 使 eMMC 進入空閑狀態 |
CMD1 | SEND_OP_COND | 發送 OCR(操作條件寄存器),檢查 eMMC 是否準備好 |
CMD2 | ALL_SEND_CID | 發送 eMMC 的唯一 ID 號 |
CMD3 | SET_RELATIVE_ADDR | 設置 eMMC 的 RCA(相對地址) |
CMD6 | SWITCH | 切換 eMMC 的模式(如改變工作電壓) |
CMD7 | SELECT/DESELECT_CARD | 選中或取消選中某張 eMMC 卡 |
(2)讀/寫命令
命令 | 名稱 | 描述 |
---|---|---|
CMD8 | SEND_EXT_CSD | 讀取 eMMC EXT_CSD (擴展寄存器) |
CMD9 | SEND_CSD | 讀取 eMMC CSD (卡片特性描述符) |
CMD16 | SET_BLOCKLEN | 設置讀寫塊大小 |
CMD17 | READ_SINGLE_BLOCK | 讀取單個塊 |
CMD18 | READ_MULTIPLE_BLOCK | 讀取多個塊 |
CMD24 | WRITE_BLOCK | 寫入單個塊 |
CMD25 | WRITE_MULTIPLE_BLOCK | 寫入多個塊 |
(3)數據傳輸命令
命令 | 名稱 | 描述 |
---|---|---|
CMD12 | STOP_TRANSMISSION | 停止多塊傳輸 |
CMD13 | SEND_STATUS | 查詢 eMMC 的狀態 |
CMD23 | SET_BLOCK_COUNT | 預設多塊傳輸的塊數 |
3. eMMC 響應格式
eMMC 響應有 6 種類型:
- R1(正常響應):包含 eMMC 狀態
- R2(CID/CSD 響應):136-bit 長響應
- R3(OCR 響應):包含操作條件寄存器
- R4(不常用)
- R5(不常用)
- R6(RCA 響應)
例如:
CMD2
返回 R2 響應(136-bit)CMD1
返回 R3 響應(48-bit)CMD13
返回 R1 響應(48-bit)
4. 數據傳輸格式
eMMC 讀寫數據時,數據通過 單線(1-bit)、4-bit 或 8-bit 模式 進行傳輸,通常格式如下:
- 起始位
- 數據塊
- CRC 校驗
- 停止位
eMMC 允許 單塊或多塊傳輸,多塊傳輸可以提高讀寫效率。
5.小結
- eMMC 采用 48-bit 標準命令格式,有
Start Bit
、Command Index
、Argument
、CRC7
和End Bit
。 - 命令分為 初始化命令、數據傳輸命令、控制命令。
- 不同命令返回 不同格式的響應(R1、R2、R3等)。
- 數據傳輸支持 單塊/多塊模式,使用
CMD17/18
進行讀取,CMD24/25
進行寫入。
關于 eMMC的CMD0
命令選擇Boot 模式的工作流程的詳解
上面一個目錄已經詳細介紹了eMMC的命令的相關知識,在此基礎上,我們再來了解下CMD0
命令對Boot模式的選擇。
在 eMMC 設備的 Boot 過程 中,主機(Host,例如 CPU 或 BootROM)需要 復位 eMMC 并使其進入 Boot 模式,這個過程通常通過 CMD0
(GO_IDLE_STATE)實現。
1. CMD0
(GO_IDLE_STATE)命令的作用
CMD0
是 eMMC 規范中的一個標準命令,其作用是:
- 讓 eMMC 進入空閑(Idle)狀態,類似于軟復位(Software Reset)。
- 可以附帶參數來指定 eMMC 的 啟動模式(Boot Mode)。
在正常的數據模式下,CMD0
的參數通常是 0x00000000
,表示讓 eMMC 進入 Idle State(空閑狀態)。
但在 Boot 過程中,CMD0
可以使用特定參數,使 eMMC 進入 Boot 模式 并準備傳輸 Boot 數據。
2. CMD0
選擇 Boot 模式的參數
當系統啟動時,BootROM 或 Bootloader 需要告訴 eMMC 進入 Boot 模式。
這通常通過 CMD0
命令 帶上特定參數 來完成。
CMD0 參數值 | 含義 |
---|---|
0x00000000 | 進入 空閑狀態(Idle State),用于普通復位 |
0xFFFFFFFA | 進入 Boot 操作模式(Boot Operation Mode) |
0xFFFFFFF1 | 進入 備用 Boot 模式(Alternative Boot Mode) |
其中,0xFFFFFFFA
是 最常用的,因為它會讓 eMMC 從 BOOT_PARTITION_ENABLE
指定的 Boot 分區啟動。【 BOOT_PARTITION_ENABLE
是在EXT_CSD[179]
中配置的,EXT_CSD[179]
在前文已有詳細介紹。】
3. 使用CMD0
進入 Boot 模式并啟動u-boot的完整流程
步驟 1:上電并初始化 eMMC
- 處理器上電后,eMMC 仍然處于 Inactive State(未激活狀態),不會立即工作。
- 處理器需要復位 eMMC,并配置 Boot 模式。
步驟 2:發送 CMD0 0xFFFFFFFA
進入 Boot 模式
- BootROM 發送:
CMD0 (0xFFFFFFFA)
- eMMC 進入 Boot 模式,準備從 Boot 分區傳輸數據。
步驟 3:eMMC 發送 BOOT_ACK
(可選)
如果 BOOT_ACK
(EXT_CSD[179] Bit7)被啟用:
- eMMC 會發送一個 ACK 響應,通知主機已準備好發送 Boot 數據。
步驟 4:eMMC 傳輸 Boot 數據
- eMMC 進入 Boot 傳輸模式,并從
EXT_CSD[179]
(BOOT_CONFIG)指定的 Boot 分區(BOOT_PARTITION_1
或BOOT_PARTITION_2
)發送 Boot 代碼(通常是 Bootloader)。 - 這個傳輸過程是 單向的,eMMC 只負責發送,主機通過 低速模式(默認 26MHz) 讀取 Boot 數據。
步驟 5:主機加載 Boot 代碼
- BootROM 讀取 eMMC 傳輸的 Boot 數據(如
u-boot
)。 - 如果數據有效,BootROM 跳轉到 Boot 代碼,繼續啟動操作系統。
常用的eMMC配置修改工具有哪些?
① u-boot可以修改eMMC的配置。
② Linux系統也可以修改eMMC的配置。
③ 注意:百問網基于NXP提供的uuu工具搞出的燒寫工具在進行燒寫準備前也可能去修改eMMC的配置。百問網提供的燒寫工具的詳細介紹見 https://blog.csdn.net/wenhao_ir/article/details/145653414 其實這個燒寫工具本質上也是使用的u-boot,詳情見 https://blog.csdn.net/wenhao_ir/article/details/145985144
Linux系統中如何管理eMMC分區
① 查看eMMC信息
cat /sys/class/mmc_host/mmc0/mmc0:0001/ext_csd
對于我的開發板而言,mmc的序號值為1,但是下面這個目錄:
/sys/class/mmc_host/mmc1/mmc1:0001
中,只有csd
文件,沒有ext_csd
文件,如下圖所示:
可見,如需在Linux下查看我的開發板的eMMC的ext_csd
信息,還需要作進一步研究,這并不是本篇博文的重點,所以暫且不作進一步研究。
② 訪問Boot分區
# 讀取Boot分區
dd if=/dev/mmcblk0boot0 of=boot.img bs=1M# 寫入Boot分區(需啟用寫入)
echo 0 > /sys/block/mmcblk0boot0/force_ro
dd if=u-boot.img of=/dev/mmcblk0boot0 bs=1M
③ 格式化User Data分區
mkfs.ext4 /dev/mmcblk0p1
④如何查看eMMC的分區信息(設備節點信息)
請在本博文中搜索關鍵詞“以下命令查看eMMC的分區信息”查看相關內容。
⑤在Linux系統下,如何讀取EXT_CSD[179]
的配置值?
詳情請搜索在本篇博文中搜索關鍵詞:“在Linux系統下,如何讀取EXT_CSD[179]
的配置值”
擴展閱讀
Fastboot(FB)協議介紹
https://blog.csdn.net/wenhao_ir/article/details/145985144
百問網在uuu工具的基礎上開發出的燒寫工具的介紹
https://blog.csdn.net/wenhao_ir/article/details/145653414
Bootloader的三個階段詳解(BootROM、SPL、U-Boot)
https://blog.csdn.net/wenhao_ir/article/details/145999721
SPL和U-Boot合成鏡像u-boot-dtb.imx
時需要作填充數據處理
https://blog.csdn.net/wenhao_ir/article/details/145999721