IMX6UL eMMC加锁和解锁代码分析与实现
背景
最近在使用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加锁和解锁代码分析与实现相关推荐
- ReentrantLock 公平锁和非公平锁加锁和解锁源码分析(简述)
- title: ReentrantLock 公平锁和非公平锁加锁和解锁源码分析(简述) - date: 2021/8/16 文章目录 一.ReentrantLock 1. 构造函数 二.Reentr ...
- 分析为什么加锁和解锁操作是原子的
临界资源:多线程执行流共享的资源就叫做临界资源. 临界区:每个线程内部,访问临界自娱的代码,就叫做临界区. 互斥:任何时刻,互斥保证有且只有一个执行流进入临界区,访问临界资源,通常对临界资源起保护作用 ...
- SM01 事务代码的加锁以及解锁
工作中,免不了需要用到事务代码的加解锁功能. 事务代码:SM01 在事务代码中输入你要加锁的事务代码值,点击查找,定位到该事务代码,然后再锁定的勾选框中进行勾选,保存即可! 解锁同上,去掉勾选,保存.
- 加锁和解锁-ReentrantLock详解-AQS-并发编程(Java)
文章目录 1 AQS 1.1 概念 1.2 两种锁机制 1.3 公平锁和非公平锁 1.3 锁竞争 1.4 条件变量 2 ReentrantLock 2.1 简介 2 加锁 2.1 加锁成功 2.2 加 ...
- 【图解】一篇搞定ReentrantLock的加锁和解锁过程
文章目录 1. 概述 2. AbstractQueuedSynchronizer(AQS) 3. 加锁 4. 解锁 5. 公平锁和非公平锁的区别 1. 概述 本文主要结合图片分析ReentrantLo ...
- IMX6UL eMMC初始化流程
环境 在uboot中分析emmc初始化流程代码,emmc在uboot中方便添加命令和打印调试,uboot版本:2017.03 开机打印 uboot启动打印 U-Boot 2017.03-g101318 ...
- ZBar源码分析——多线程部分代码分析 | 2021SC@SDUSC
2021SC@SDUSC 目录 一.ZBar中的多线程 线程:cpu调度的最小单位 何为线程安全? 锁机制 二.ZBar中使用多线程的代码示例 Window线程的上锁与解锁 Vedio视频流的上锁与解 ...
- Java 线程池框架核心代码分析
转载自 Java 线程池框架核心代码分析 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和资源消耗都是很高的.线程池应运而生,成为我们管理线程的利器.Java 通过Executo ...
- java队列加锁_java并发-----浅析ReentrantLock加锁,解锁过程,公平锁非公平锁,AQS入门,CLH同步队列...
前言 为什么需要去了解AQS,AQS,AbstractQueuedSynchronizer,即队列同步器.它是构建锁或者其他同步组件的基础框架(如ReentrantLock.ReentrantRead ...
最新文章
- 美元加息怎么“剪羊毛”
- Ruby调用shell命令
- SAP QM 质量检验特殊业务需求之方案漫谈
- Storm源码阅读之SpoutOutputCollector
- IDEA 集成Lombok 插件-安装插件
- 分享一个理工男必学的撩妹姿势
- F. Cowmpany Cowmpensation(树形dp + 拉格朗日插值)
- python能做什么项目-用python真的可以做很多有趣的事!我自己做了些小项目!大家看看...
- Oracle中用于发送邮件的存储过程
- sql语句与mysql_MySQL-sql语句
- 51nod 1133 不重叠的线段
- Android 之 网络连接(Connecting to the Network)
- 计算机手速专业说法,大学里“挂科率超高”的专业,学霸也不好拿捏,考试难补考更难...
- 软考——计算机基础知识总结
- html Antv L7 + mapbox 实现3D地图 3D中国地图 不限于中国地图
- computer一词来源
- Polar码(2)- Polar编码
- Linux的DNS设置
- 大数据Spark实战第五集 Spark股票交易实时价格分析
- 港科夜闻|香港科大(广州)与深圳湾实验室签署重要战略合作协议,共同促进粤港澳大湾区产业升级、社会发展与科技进步...