背景

最近在使用eMMC作为外部存储设备过程中,出现eMMC两个分区数据全部被清空,文件系统数据和用户数据全部为0 ,在网上看到一篇文件说对eMMC加锁后强制解锁会清除用户数据,这样达到的效果与我遇到的类似,下面实现加锁和解锁代码进行测试。

环境

在uboot中添加对emmc命令加解锁测试比较方便,uboot版本2017.03

命令

对emmc加解锁主要是用CMD42命令进行操作,发送的命令和数据都是参考上面链接文章。

mmc现有命令

=> mmc
mmc - MMC sub systemUsage:
mmc info - display info of the current MMC device
mmc read addr blk# cnt
mmc write addr blk# cnt
mmc erase blk# cnt
mmc rescan
mmc part - lists available partition on current mmc device
mmc dev [dev] [part] - show or set current mmc device [partition]
mmc list - lists available devices
mmc hwpartition [args...] - does hardware partitioning

添加lock/unlock/clear命令,cmd/mmc.c,cmd_mmc结构体中:

 U_BOOT_CMD_MKENT(lock, 1, 0, do_lock, "", ""),U_BOOT_CMD_MKENT(unlock, 1, 0, undo_lock, "", ""),U_BOOT_CMD_MKENT(clear, 1, 0, do_clear, "", ""),
static void lock_emmc(struct mmc *mmc)
{mmc_lock_emmc(mmc);
}
static int do_lock(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{struct mmc *mmc;if (curr_device < 0) {if (get_mmc_num() > 0)curr_device = 0;else {puts("No MMC device available\n");return 1;}}mmc = init_mmc_device(curr_device, false);if (!mmc)return CMD_RET_FAILURE;lock_emmc(mmc);return CMD_RET_SUCCESS;
}

CMD42数据结构体

第0字节:设备锁/解锁模式

第1字节:密码长度,单位字节,这里设置1

第2字节:密码数据,这里设置简单的1

#define MMC_LOCK_UNLOCK          42struct mmc_pwd{u8 mode;u8 pwd_len;u8 pwd_data;
};

加锁

1. 若是没有选择设备,此时选择设备(CMD7),代码没实现,直接手动输入命令mmc dev 0。
           2. 设置block长度(CMD16),由8位设备锁/解锁模式,8位密码大小,总密码长度的大小决定。
           3. 发送CMD42命令,选择模式LOCK和SET_ PWD,另外加上PWD_LEN和PWD_DATA。

int mmc_lock_emmc(struct mmc *mmc)
{printf("mmc_lock_emmc\n");struct mmc_cmd cmd;struct mmc_data data;int timeout = 1000;printf("write_bl_len=%d\n",mmc->write_bl_len);//512if (mmc_set_blocklen(mmc, 3)){//设置block长度,总3个字节printf("mmc_set_blocklen failed!\n");return 0;}cmd.cmdidx = MMC_LOCK_UNLOCK;//CMD42cmd.cmdarg = 0;//cmd.resp_type = MMC_RSP_R1;struct mmc_pwd *src_pwd=(struct mmc_pwd *)malloc(3);if(NULL == src_pwd){printf("malloc failed!\n");return 0;}src_pwd->mode = 5;//lock and set pwdsrc_pwd->pwd_len = 1;src_pwd->pwd_data = 1;data.src = (char *)src_pwd;data.blocks = 1;data.blocksize = 3;data.flags = MMC_DATA_WRITE;if (mmc_send_cmd(mmc, &cmd, &data)) {printf("mmc write failed\n");return 0;}/* Waiting for the ready status */if (mmc_send_status(mmc, timeout)){printf("mmc_send_status failed\n");return 0;}return 0;
}

解锁

1. 若是没有选择设备,此时选择设备(CMD7),代码没实现,直接手动输入命令mmc dev 0。
           2. 设置block长度(CMD16),由8位设备锁/解锁模式,8位密码大小,总密码长度的大小决定。
           3. 发送CMD42命令,选择模式CLR_PWD,同样包括PWD_LEN和PWD,若是密码大小和内容正确,PWD内容会清除,且PWD_LEN设置为0。

int mmc_unlock_emmc(struct mmc *mmc)
{printf("mmc_unlock_emmc\n");struct mmc_cmd cmd;struct mmc_data data;int timeout = 1000;printf("write_bl_len=%d\n",mmc->write_bl_len);if (mmc_set_blocklen(mmc, 3)){printf("mmc_set_blocklen failed!\n");return 0;}cmd.cmdidx = MMC_LOCK_UNLOCK;cmd.cmdarg = 0;//cmd.resp_type = MMC_RSP_R1;struct mmc_pwd *src_pwd=(struct mmc_pwd *)malloc(3);if(NULL == src_pwd){printf("malloc failed!\n");return 0;}src_pwd->mode = 2;//unlock and clear pwdsrc_pwd->pwd_len = 1;src_pwd->pwd_data = 1;data.src = (char *)src_pwd;data.blocks = 1;data.blocksize = 3;data.flags = MMC_DATA_WRITE;if (mmc_send_cmd(mmc, &cmd, &data)) {printf("mmc write failed\n");return 0;}/* Waiting for the ready status */if (mmc_send_status(mmc, timeout)){printf("mmc_send_status failed\n");return 0;}return 0;
}

强制清除

用户忘了密码的情况,host可以清除所有PWD内容,这个过程叫做强行清除。
           1. 选择设备CMD7
           2. 设置block长度为1byte(CMD16)
           3. 发送CMD42,选择模式ERASE,data block表明模式ERASE。

struct mmc_pwd_clear{u8 mode;
};int mmc_clear_emmc(struct mmc *mmc)
{printf("mmc_clear_emmc\n");struct mmc_cmd cmd;struct mmc_data data;int timeout = 1000;printf("write_bl_len=%d\n",mmc->write_bl_len);if (mmc_set_blocklen(mmc, 1)){printf("mmc_set_blocklen failed!\n");return 0;}cmd.cmdidx = MMC_LOCK_UNLOCK;cmd.cmdarg = 0;//cmd.resp_type = MMC_RSP_R1;struct mmc_pwd_clear *src_pwd_clear=(struct mmc_pwd *)malloc(1);if(NULL == src_pwd_clear){printf("malloc failed!\n");return 0;}src_pwd_clear->mode = 8;//q-cleardata.src = (char *)src_pwd_clear;data.blocks = 1;data.blocksize = 1;data.flags = MMC_DATA_WRITE;if (mmc_send_cmd(mmc, &cmd, &data)) {printf("mmc write failed\n");return 0;}/* Waiting for the ready status */if (mmc_send_status(mmc, timeout)){printf("mmc_send_status failed\n");return 0;}return 0;
}

测试

选择设备

加锁前正常读

加锁

加锁后读失败

加锁后内核启动到文件系统读emmc失败打印

mmc1: new DDR MMC card at address 0001
mmcblk1: mmc1:0001 P1XXXX 7.20 GiB
mmcblk1boot0: mmc1:0001 P1XXXX partition 1 16.0 MiB
mmcblk1boot1: mmc1:0001 P1XXXX partition 2 16.0 MiB
mmcblk1rpmb: mmc1:0001 P1XXXX partition 3 128 KiB
hub 1-1:1.0: USB hub found
hub 1-1:1.0: 4 ports detected
usb 1-1.1: new high-speed USB device number 3 using ci_hdrc
usb 1-1.3: new full-speed USB device number 4 using ci_hdrc
EXT4-fs (ram0): mounted filesystem with ordered data mode. Opts: (null)
VFS: Mounted root (ext4 filesystem) readonly on device 1:0.
devtmpfs: mounted
Freeing unused kernel memory: 1024K (c0a00000 - c0b00000)
mmcblk1: error -110 sending stop command, original cmd response 0x2000900, card status 0x2400900
mmcblk1: error -110 transferring data, sector 0, nr 8, cmd response 0x2000900, card status 0x0
mmcblk1: error -110 sending stop command, original cmd response 0x2000900, card status 0x2400900
mmcblk1: error -110 transferring data, sector 0, nr 8, cmd response 0x2000900, card status 0x0
mmcblk1: retrying using single block read
mmcblk1: error -110 transferring data, sector 0, nr 8, cmd response 0x2000900, card status 0x0
blk_update_request: I/O error, dev mmcblk1, sector 0
mmcblk1: error -110 transferring data, sector 1, nr 7, cmd response 0x2000900, card status 0x0
blk_update_request: I/O error, dev mmcblk1, sector 1

解锁

解锁后读成功

加锁后强制清除

强制清除前分区存在

强制清除

强制清除后读成功,但数据全部为0

分区被删除

总结

加锁后强制清除会删除用户创建的分区和数据,EMMC出厂的数据会保留。与我遇到的情况有差异,我的是分区还在,但是分区里面的文件系统数据和用户数据全部被清空,原因待查中。。。

IMX6UL eMMC加锁和解锁代码分析与实现相关推荐

  1. ReentrantLock 公平锁和非公平锁加锁和解锁源码分析(简述)

    - title: ReentrantLock 公平锁和非公平锁加锁和解锁源码分析(简述) - date: 2021/8/16 文章目录 一.ReentrantLock 1. 构造函数 二.Reentr ...

  2. 分析为什么加锁和解锁操作是原子的

    临界资源:多线程执行流共享的资源就叫做临界资源. 临界区:每个线程内部,访问临界自娱的代码,就叫做临界区. 互斥:任何时刻,互斥保证有且只有一个执行流进入临界区,访问临界资源,通常对临界资源起保护作用 ...

  3. SM01 事务代码的加锁以及解锁

    工作中,免不了需要用到事务代码的加解锁功能. 事务代码:SM01 在事务代码中输入你要加锁的事务代码值,点击查找,定位到该事务代码,然后再锁定的勾选框中进行勾选,保存即可! 解锁同上,去掉勾选,保存.

  4. 加锁和解锁-ReentrantLock详解-AQS-并发编程(Java)

    文章目录 1 AQS 1.1 概念 1.2 两种锁机制 1.3 公平锁和非公平锁 1.3 锁竞争 1.4 条件变量 2 ReentrantLock 2.1 简介 2 加锁 2.1 加锁成功 2.2 加 ...

  5. 【图解】一篇搞定ReentrantLock的加锁和解锁过程

    文章目录 1. 概述 2. AbstractQueuedSynchronizer(AQS) 3. 加锁 4. 解锁 5. 公平锁和非公平锁的区别 1. 概述 本文主要结合图片分析ReentrantLo ...

  6. IMX6UL eMMC初始化流程

    环境 在uboot中分析emmc初始化流程代码,emmc在uboot中方便添加命令和打印调试,uboot版本:2017.03 开机打印 uboot启动打印 U-Boot 2017.03-g101318 ...

  7. ZBar源码分析——多线程部分代码分析 | 2021SC@SDUSC

    2021SC@SDUSC 目录 一.ZBar中的多线程 线程:cpu调度的最小单位 何为线程安全? 锁机制 二.ZBar中使用多线程的代码示例 Window线程的上锁与解锁 Vedio视频流的上锁与解 ...

  8. Java 线程池框架核心代码分析

    转载自 Java 线程池框架核心代码分析 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和资源消耗都是很高的.线程池应运而生,成为我们管理线程的利器.Java 通过Executo ...

  9. java队列加锁_java并发-----浅析ReentrantLock加锁,解锁过程,公平锁非公平锁,AQS入门,CLH同步队列...

    前言 为什么需要去了解AQS,AQS,AbstractQueuedSynchronizer,即队列同步器.它是构建锁或者其他同步组件的基础框架(如ReentrantLock.ReentrantRead ...

最新文章

  1. 美元加息怎么“剪羊毛”
  2. Ruby调用shell命令
  3. SAP QM 质量检验特殊业务需求之方案漫谈
  4. Storm源码阅读之SpoutOutputCollector
  5. IDEA 集成Lombok 插件-安装插件
  6. 分享一个理工男必学的撩妹姿势
  7. F. Cowmpany Cowmpensation(树形dp + 拉格朗日插值)
  8. python能做什么项目-用python真的可以做很多有趣的事!我自己做了些小项目!大家看看...
  9. Oracle中用于发送邮件的存储过程
  10. sql语句与mysql_MySQL-sql语句
  11. 51nod 1133 不重叠的线段
  12. Android 之 网络连接(Connecting to the Network)
  13. 计算机手速专业说法,大学里“挂科率超高”的专业,学霸也不好拿捏,考试难补考更难...
  14. 软考——计算机基础知识总结
  15. html Antv L7 + mapbox 实现3D地图 3D中国地图 不限于中国地图
  16. computer一词来源
  17. Polar码(2)- Polar编码
  18. Linux的DNS设置
  19. 大数据Spark实战第五集 Spark股票交易实时价格分析
  20. 港科夜闻|香港科大(广州)与深圳湾实验室签署重要战略合作协议,共同促进粤港澳大湾区产业升级、社会发展与科技进步...

热门文章

  1. 华章IT图书书讯(2012年第7期)
  2. 小动物光学成像的发展(荧光成像,生物发光成像)
  3. 【调剂】欢迎调剂模式识别、计算机视觉、虚拟现实方向研究生-上海应用技术大学...
  4. 学习笔记(一)贝叶斯公式
  5. 【人物访谈·02期】关于对数据分析前辈的一次行业探讨
  6. iOS中数组拼接方法
  7. 华为摄像机搜索软件_华为安防:举智能之火 成燎原之势
  8. Unity 中批量修改模型材质球
  9. 运动控制的轴到底是什么
  10. 删除的文件怎样恢复?实用的方法