3-EMMC命令使用

在調試emmc的過程,我們需要用到命令讀寫emmc,燒錄,查看emmc寄存器,設置寄存器等功能,所以uboot和linux下都有各自的命令可以使用。

1、 uboot下mmc命令


1.1、mmc信息

查看mmc信息:mmc info

描述了emmc的速率、大小、塊大小等

MT7622> mmc info
Device: mmc@11230000
Manufacturer ID: 1
OEM: 100
Name: S4000 
Bus Speed: 48000000
Mode: MMC DDR52 (52MHz)
Rd Block Len: 512
MMC version 5.1
High Capacity: Yes
Capacity: 3.6 GiB
Bus Width: 8-bit DDR
Erase Group Size: 512 KiB
HC WP Group Size: 8 MiB
User Capacity: 3.6 GiB WRREL
Boot Capacity: 4 MiB ENH
RPMB Capacity: 4 MiB ENH
Boot area 0 is not write protected
Boot area 1 is not write protected

如果有多個mmc設備的時候,比如一個emmc、一個SD卡,這時候我們操作emmc之前需要先選擇emmc設備

MT7622> mmc dev 0
mtk_sd mmc@11230000: sclk: 255319, timing: 0
mtk_sd mmc@11230000: sclk: 24000000, timing: 0
mtk_sd mmc@11230000: sclk: 12000000, timing: 4
switch to partitions #0, OK
mmc0(part 0) is current device
1.2、GPT分區表讀取

查看gpt的分區地址后,這樣我們收到操作emmc的時候,也知道每個分區的內容,避免寫錯。

MT7622> mmc part

Partition Map for MMC device 0  --   Partition Type: EFI

Part    Start LBA       End LBA         Name
        Attributes
        Type GUID
        Partition GUID
  1     0x00001000      0x00001fff      "fip"
        attrs:  0x0000000000000005
        type:   c12a7328-f81f-11d2-ba4b-00a0c93ec93b
        guid:   5452574f-2211-4433-5566-778899aabb01
  2     0x00002000      0x000027ff      "ubootenv"
        attrs:  0x0000000000000001
        type:   0fc63daf-8483-4772-8e79-3d69d8477de4
        guid:   5452574f-2211-4433-5566-778899aabb02
  3     0x00003000      0x0001afff      "firmware"
        attrs:  0x0000000000000000
        type:   cae9be83-b15f-49cc-863f-081b744a2d93
        guid:   5452574f-2211-4433-5566-778899aabb03
  4     0x0001b000      0x00032fff      "firmware2"
        attrs:  0x0000000000000000
        type:   cae9be83-b15f-49cc-863f-081b744a2d93
        guid:   5452574f-2211-4433-5566-778899aabb04
  5     0x00033000      0x000333ff      "zbootconfig"
        attrs:  0x0000000000000000
        type:   0fc63daf-8483-4772-8e79-3d69d8477de4
        guid:   5452574f-2211-4433-5566-778899aabb05

燒錄的時候可以直接解析gpt中的firmware地址進行燒錄

gpt_partition_list=fip ubootenv firmware firmware2 zbootconfig mmcsda1
1.3、讀、寫、擦

mmc 的讀寫擦都是使用塊為單位,上面的mmc info可以知道一個block的大小是512KB

mmc read addr blk# cnt
mmc write addr blk# cnt
mmc erase blk# cnt

mmc讀操作:

mmc read 0x4007FF28 0x600 0x10

讀操作說明:從mmc設備塊上1536*512個字節處開始(1536是0x600的十進制),讀取16×512個字節(16是10的10進制)到內存0x10800000 處。

這邊的512是根據mmc的塊特性決定,上面mmcinfo里面的Block Len:512

以kernel為例,若前面的分區為94M(也就是kernel的分區從94M的地方開始),那么,0x600的地方的值應為:9421024的十六進制0x2F000。

讀到這個地址后,可以用md.b打印內存信息 md 內存地址 長度

md.b 0x4007FF28 0x1000

MT7622> md.b 0x4007FF28
4007ff28: 88 16 88 58 90 29 04 00 55 2d 42 6f 6f 74 00 00    ...X.)..U-Boot..
4007ff38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
4007ff48: 00 00 00 00 00 00 00 00 00 00 e0 41 ff ff ff ff    ...........A....
4007ff58: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ff68: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ff78: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ff88: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ff98: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ffa8: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ffb8: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ffc8: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ffd8: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007ffe8: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
4007fff8: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
40080008: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
40080018: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................

寫操作:

mmc write 0x90000000 0x600 0x10 

寫操作說明:把內存0x90000000開始,長度為16x512大小的數據,寫入到mmc設備塊偏移位置為0x600處。

擦除操作:

mmc erase 0x600 0x10

擦除操作說明:從mmc設備塊上1536*512個字節處開始(1536是0x600的十進制),擦除16×512個字節(16是10的10進制)。

1.4、固件升級

環境參數里面有很多命令參數

MT7622> printenv 
boot_default=run boot_firmware
boot_firmware=led $bootled_pwr on ; run emmc_read_firmware && bootm $loadaddr#$bootconf ; led $bootled_pwr off
boot_tftp_firmware=tftpboot $loadaddr $bootfile_firmware && env exists replacevol && iminfo $loadaddr && run emmc_write_firmware ; if env exists noboot ; then else bootm $loadaddr#$bootconf ; fi
boot_tftp_write_bl2=tftpboot $loadaddr $bootfile_bl2 && run emmc_write_bl2
boot_tftp_write_fip=tftpboot $loadaddr $bootfile_fip && run emmc_write_fip
bootcmd=run boot_firmware
bootconf=config@1
bootdelay=3
bootfile_bl2=openwrt-mediatek-mt7622-ZH-A0501-EMMC-squashfs-emmc-1ddr-preloader.bin
bootfile_fip=ZH-A0501-u-boot.fip
bootfile_firmware=openwrt-mediatek-mt7622-ZH-A0501-EMMC-squashfs-sysupgrade.bin
bootled_pwr=zihome:blue
bootled_rec=zihome:yellow
bootmenu_0=Default boot command.=run boot_default
bootmenu_1=Boot firmware system from eMMC.=run boot_firmware ; run bootmenu_confirm_return
bootmenu_2=Load firmware system via TFTP then write to eMMC.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_firmware ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return
bootmenu_3=Load BL31+U-Boot FIP via TFTP then write to eMMC.=run boot_tftp_write_fip ; run bootmenu_confirm_return
bootmenu_4=Load BL2 preloader via TFTP then write to eMMC.=run boot_tftp_write_bl2 ; run bootmenu_confirm_return
bootmenu_5=Reboot.=reset
bootmenu_6=Reset all settings to factory defaults.=run reset_factory ; reset
bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60
bootmenu_delay=3
bootmenu_title=      ( ( ( OpenWrt ) ) )  [eMMC]
emmc_read_firmware=mmc dev 0 && part start mmc 0 $part_firmware part_addr && part size mmc 0 $part_firmware part_size && run mmc_read_vol
emmc_write_bl2=mmc dev 0 1 && mmc partconf 0 1 1 1 && mmc erase 0x0 0x400 && mmc write $loadaddr 0x0 0x100 ; mmc partconf 0 1 1 0
emmc_write_fip=mmc dev 0 0 && mmc erase 0x1000 0x1000 && mmc write $loadaddr 0x1000 0x1000 && mmc erase 0x2000 0x800
emmc_write_firmware=mmc dev 0 && part start mmc 0 $part_firmware part_addr && part size mmc 0 $part_firmware part_size && run mmc_write_vol
ethact=ethernet@1b100000
gpt_partition_list=fip ubootenv firmware firmware2 zbootconfig mmcsda1
ipaddr=192.168.2.119
loadaddr=0x4007ff28
mmc_read_vol=mmc read $loadaddr $part_addr 0x8 && imszb $loadaddr image_size && test 0x$image_size -le 0x$part_size && mmc read $loadaddr 0x$part_addr 0x$image_size
mmc_write_vol=imszb $fileaddr image_size && test 0x$image_size -le 0x$part_size && mmc erase 0x$part_addr 0x$part_size && mmc write $fileaddr 0x$part_addr 0x$fileblk
part_firmware=firmware
reset_factory=eraseenv && reset
reset_type=0
serverip=192.168.2.88
ver=U-Boot 2021.10 (Feb 18 2022 - 06:51:54 +0000)

Environment size: 2778/524283 bytes

升級的話我們可以使用上訴命令拆解,比如要升級fip文件。

正常我們是選擇3進行升級

bootmenu_3=Load BL31+U-Boot FIP via TFTP then write to eMMC.=run boot_tftp_write_fip ; run bootmenu_confirm_return

3的實際命令就是boot_tftp_write_fip命令,這個命令實際又是兩個命令組成

boot_tftp_write_fip=tftpboot $loadaddr $bootfile_fip && run emmc_write_fip

emmc_write_fip命令實際又是多個命令組成,所以我們可以一步一步自己執行

emmc_write_fip=mmc dev 0 0 && mmc erase 0x1000 0x1000 && mmc write $loadaddr 0x1000 0x1000 && mmc erase 0x2000 0x800

2、 linux下mmc命令


2.1、設備生成

內核啟動后,驅動會將MMC的幾個物理分區分別掛載成對應的設備

  • mmcblk0boot0、mmcblk0boot1、mmcblk0rpmb這是三個獨立的分區,內核mtd不會使用到
  • mmcblk0分區就用用戶分區,給內核mtd使用,只要再根據實際應用軟件mtd分區
[    1.726828] mmc0: new DDR MMC card at address 0001
[    1.736013] mmcblk0: mmc0:0001 S40004 3.64 GiB 
[    1.741029] mmcblk0boot0: mmc0:0001 S40004 partition 1 4.00 MiB
[    1.747099] mmcblk0boot1: mmc0:0001 S40004 partition 2 4.00 MiB
[    1.753180] mmcblk0rpmb: mmc0:0001 S40004 partition 3 4.00 MiB
[    1.764627] Alternate GPT is invalid, using primary GPT.
[    1.769988]  mmcblk0: p1 p2 p3 p4 p5 p128
[    2.704843] 13 cmdlinepart partitions found on MTD device EMMC
[    2.710693] Creating 13 MTD partitions on "EMMC":
[    2.715400] 0x000000000000-0x000000200000 : "gpt"
[    2.720864] 0x000000200000-0x000000400000 : "fip"
[    2.726225] 0x000000400000-0x000000600000 : "uboot-env"
[    2.732165] 0x000000600000-0x000003600000 : "firmware"
[    2.742601] 2 fit-fw partitions found on MTD device firmware
[    2.748319] 0x000000600000-0x0000008d0000 : "kernel"
[    2.757981] 0x0000008e0000-0x000003600000 : "rootfs"
[    2.763555] mtd: device 5 (rootfs) set to be root filesystem
[    2.769277] 0x000003600000-0x000006600000 : "firmware2"
[    2.779141] 0x000006600000-0x000006680000 : "zbootconfig"

在設備管理下可以看到mmc的塊設備和mtd的塊設備

oot@openwrt:~# cat /proc/partitions 
major minor  #blocks  name

 179        0    3817472 mmcblk0
 179        1       2048 mmcblk0p1
 179        2       1024 mmcblk0p2
 179        3      49152 mmcblk0p3
 179        4      49152 mmcblk0p4
 179        5        512 mmcblk0p5
 259        0       2031 mmcblk0p128
 179       24       4096 mmcblk0rpmb
 179       16       4096 mmcblk0boot1
 179        8       4096 mmcblk0boot0
  31        0       2048 mtdblock0
  31        1       2048 mtdblock1
  31        2       2048 mtdblock2
  31        3      49152 mtdblock3
  31        4       2880 mtdblock4
  31        5      46208 mtdblock5
  31        6      49152 mtdblock6

mmc的操作命令在mmc-utils包中,支持很多命令,下面只介紹常用的幾個命令

2.2、讀取寄存器值

mmc有很多寄存器,所以有專門的寄存器查看命令

root@openwrt:~# mmc extcsd read /dev/mmcblk0
=============================================
  Extended CSD rev 1.8 (MMC 5.1)
=============================================

Card Supported Command sets [S_CMD_SET: 0x01]
HPI Features [HPI_FEATURE: 0x01]: implementation based on CMD13
Background operations support [BKOPS_SUPPORT: 0x01]
Max Packet Read Cmd [MAX_PACKED_READS: 0x3f]
Max Packet Write Cmd [MAX_PACKED_WRITES: 0x3f]
Data TAG support [DATA_TAG_SUPPORT: 0x01]
Data TAG Unit Size [TAG_UNIT_SIZE: 0x00]
Tag Resources Size [TAG_RES_SIZE: 0x00]
Context Management Capabilities [CONTEXT_CAPABILITIES: 0x78]
Large Unit Size [LARGE_UNIT_SIZE_M1: 0x01]
Extended partition attribute support [EXT_SUPPORT: 0x03]
Generic CMD6 Timer [GENERIC_CMD6_TIME: 0x05]
Power off notification [POWER_OFF_LONG_TIME: 0x64]
Cache Size [CACHE_SIZE] is 1024 KiB
Background operations status [BKOPS_STATUS: 0x00]
1st Initialisation Time after programmed sector [INI_TIMEOUT_AP: 0x0a]
Power class for 52MHz, DDR at 3.6V [PWR_CL_DDR_52_360: 0x00]
Power class for 52MHz, DDR at 1.95V [PWR_CL_DDR_52_195: 0x00]
Power class for 200MHz at 3.6V [PWR_CL_200_360: 0x00]
Power class for 200MHz, at 1.95V [PWR_CL_200_195: 0x00]
Minimum Performance for 8bit at 52MHz in DDR mode:
 [MIN_PERF_DDR_W_8_52: 0x00]
 [MIN_PERF_DDR_R_8_52: 0x00]
TRIM Multiplier [TRIM_MULT: 0x02]
Secure Feature support [SEC_FEATURE_SUPPORT: 0x55]
Boot Information [BOOT_INFO: 0x07]
 Device supports alternative boot method
 Device supports dual data rate during boot
 Device supports high speed timing during boot
Boot partition size [BOOT_SIZE_MULTI: 0x20]
...

比如我們最常用的PARTITION_CONFIG值

root@Openwrt:/# mmc extcsd read /dev/mmcblk0 | grep PARTITION_CONFIG
Boot configuration bytes [PARTITION_CONFIG: 0x48]
2.3、修改啟動使能位

如下介紹:

mmc bootpart enable <boot_partition> <send_ack> <device>
    Enable the boot partition for the <device>.
    Disable the boot partition for the <device> if <boot_partition> is set to 0.
    To receive acknowledgment of boot from the card set <send_ack>
    to 1, else set it to 0

該接口就可以設置前面提到的BOOT_PARTITION_ENABLE的值,設置啟動分區。

方法1:使能boot1,將BOOT_PARTITION_ENABLE設置為1,設置完再讀出寄存器PARTITION_CONFIG的值看是否改變。

root@Openwrt:/# mmc bootpart enable 1 1 /dev/mmcblk0
root@Openwrt:/# mmc extcsd read /dev/mmcblk0 | grep PARTITION_CONFIG
Boot configuration bytes [PARTITION_CONFIG: 0x48]

方法2:使能UDA,將BOOT_PARTITION_ENABLE設置為7,設置完再讀出寄存器PARTITION_CONFIG的值看是否改變。

root@Openwrt:/# mmc bootpart enable 7 1 /dev/mmcblk0
root@Openwrt:/# mmc extcsd read /dev/mmcblk0 | grep PARTITION_CONFIG
Boot configuration bytes [PARTITION_CONFIG: 0x78]
2.4、允許寫入Boot分區

正常情況下,我們沒辦法往boot1和boot2分區寫內容,有寫保護;所以當我們要燒錄preloader的時候就需要去掉寫保護。

echo 0 > /sys/block/mmcblk0boot0/force_ro #將boot1的寫保護去掉
dd if=mtk-bpi-r64-preloader-emmc.bin of=/dev/mmcblk0boot0
mmc bootpart enable 1 1   /dev/mmcblk0
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,533評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,055評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,365評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,561評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,346評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,889評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,978評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,118評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,637評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,558評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,739評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,246評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,980評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,619評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,347評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,702評論 2 370

推薦閱讀更多精彩內容