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
  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值