问题描述
现时代的安卓手机厂商都喜欢自己克客制化 Android 系统,做一套具有品牌特点的 UI 界面。我们客户也不例外,由于客户克制化了 UI 界面后,在 setting 中显示手机存储容量的界面上,需要读取 /data/data/emmc_total_size 节点获取 eMMC(Flash) 的大小。因此驱动这边需要实现 /data/data/emmc_total_size 这个节点,将 eMMC 大小传递到上层。
功能实现
kernel 中的需要创建 sys 节点,这里修改了 mmc.c 和 card.h 两个文件,具体修改的 diff 如下:
1 | diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c |
sys 节点创建好了,接下来创建到 /data/data/ 目录下的链接文件。
创建链接文件需要修改 device 目录下的 init 配置文件。
1 | diff --git a/project_name/init.target.rc b/project_name/init.target.rc |
如何验证
找到一台 16+2 的手机,先看看 sys 下的节点功能是否生效。
找不到节点的话,可以先 find 下节点名,找到节点路径。
1 | C:\Users\wangbing>adb shell |
找到路径后下次直接 cat 就可以了。
1 | C:\Users\wangbing\Desktop\unlock>adb shell cat /sys/devices/soc/7824900.sdhci/mmc_host/mmc0/mmc0:0001/emmc_total_size |
sys 节点已经生效了,再看看到 /data/data 的链接文件有没有功能。
1 | C:\Users\wangbing\Desktop\unlock>adb shell cat /data/data/emmc_total_size |
核心模块
查看代码前后逻辑,发现这里计算 ROM 容量的大小是通过计算 eMMC 的 sector(扇区) 的个数乘以 sector 的大小计算到的总容量。
EMMC 中的 ROM 由扇区(sector)组成,扇区有 512Byte 和 4KB 两种大小。
- 具体的扇区的大小是记录在 Extended CSD register 的 ExtCSD[61] 中.
- 拥有的扇区的个数是记录在 Extended CSD register 的 ExtCSD[215:212] 中.
详细的信息请查阅 《JESD84-B51》 协议手册 7.4 小节。
相关代码如下:
1 |
|
总结下就是:
读取 eMMC Extended CSD 寄存器中的第 61 位获取到扇区大小,这里获取到的是 512KB/扇区。
读取 eMMC Extended CSD 寄存器中的第 212~215 这四位获取到 eMMC 拥有的扇区数目。
然后使用扇区大小乘以扇区数目,得到 ROM 容量,最后通过移位操作将得到的扇区容量换算成 GB 为单位的大小值。
最后在 sys 节点中将这个计算出的 GB 为单位的大小值传递给上层。
扩展思考
上面仅仅是实现了从 emmc 内部动态的读取出 ROM 的容量,那么如果我们要动态获取到 RAM 容量要怎么操作?
思路1: 通过读取 /proc/meminfo 节点,获取到 MemTotal 的大小对应的字符串(获取前27个字符),通过解析这段字符串,得到 MemTotal 大小,再换算成 GB 单位即可。
1 | C:\Users\wangbing>adb shell cat /proc/meminfo |