6

Linux eMMC信息读取

 1 year ago
source link: https://wowothink.com/33268c93/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Linux eMMC信息读取

2018-09-02 | Linux driver
2,735 | 16

某一天,领导安排一个任务,要画一份某个项目的eMMC的layout,将分区信息表示出来,哪个分区的起始地址和结束地址,占用了多大等等信息。在此,整理了相关的内容,通过这几个常用的命令可以大致了解这块eMMC的分区情况。


mount查看分区挂载情况

执行mount命令,可以查看分区挂载的情况。

@xxx:/ # mount
rootfs on / type rootfs (ro,size=1272540k,nr_inodes=318135)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
tmpfs on /dev type tmpfs (rw,relatime,mode=755)
/dev/block/mmcblk0p1 on /system type ext4 (ro,relatime,journal_checksum,data=ordered)
tmpfs on /tmp type tmpfs (rw,relatime)
/dev/block/mmcblk0p2 on /data type ext4 (rw,nosuid,nodev,noatime,nodelalloc,journal_checksum,data=ordered)

可以知道,mmcblk0p1挂载到/system分区,mmcblk0p2挂载到/data分区。


查看eMMC分区情况

/sys/class/block/ 目录下可以查看当前系统的分区情况:

total 0
lrwxrwxrwx 1 root root 0 1970-01-01 00:34 loop0 -> ../../devices/virtual/block/loop0
lrwxrwxrwx 1 root root 0 1970-01-01 00:34 loop1 -> ../../devices/virtual/block/loop1
lrwxrwxrwx 1 root root 0 1970-01-01 00:34 loop2 -> ../../devices/virtual/block/loop2
lrwxrwxrwx 1 root root 0 1970-01-01 00:34 loop3 -> ../../devices/virtual/block/loop3
lrwxrwxrwx 1 root root 0 1970-01-01 00:34 loop4 -> ../../devices/virtual/block/loop4
lrwxrwxrwx 1 root root 0 1970-01-01 00:34 mmcblk0 -> ../../devices/platform/6b030000.esdhc/mmc_host/mmc0/mmc0:0001/block/mmcblk0
lrwxrwxrwx 1 root root 0 1970-01-01 00:34 mmcblk0boot0 -> ../../devices/platform/6b030000.esdhc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0boot0
lrwxrwxrwx 1 root root 0 1970-01-01 00:34 mmcblk0boot1 -> ../../devices/platform/6b030000.esdhc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0boot1
lrwxrwxrwx 1 root root 0 1970-01-01 00:34 mmcblk0p1 -> ../../devices/platform/6b030000.esdhc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p1
lrwxrwxrwx 1 root root 0 1970-01-01 00:34 mmcblk0p2 -> ../../devices/platform/6b030000.esdhc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p2
lrwxrwxrwx 1 root root 0 1970-01-01 00:34 mmcblk0rpmb -> ../../devices/platform/6b030000.esdhc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0rpmb

从上面的信息可以知道:

  • 这个eMMC上总共共有5个分区,boot0/boot1/p1/p2/rpmb分区;
  • 这个eMMC用到的控制器为6b030000.esdhc;
  • 我们可以到../../devices/platform/6b030000.esdhc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/目录下查看更具体的信息;
    @xxx:/sys/devices/platform/6b030000.esdhc/mmc_host/mmc0/mmc0:0001/block/mmcblk0 # ll
    total 0
    -r--r--r-- 1 root root 4096 1970-01-01 00:35 alignment_offset
    -rw-r--r-- 1 root root 4096 1970-01-01 00:35 badblocks
    lrwxrwxrwx 1 root root 0 1970-01-01 00:35 bdi -> ../../../../../../../virtual/bdi/179:0
    -r--r--r-- 1 root root 4096 1970-01-01 00:35 capability
    -r--r--r-- 1 root root 4096 1970-01-01 00:35 dev
    lrwxrwxrwx 1 root root 0 1970-01-01 00:35 device -> ../../../mmc0:0001
    -r--r--r-- 1 root root 4096 1970-01-01 00:35 discard_alignment
    -r--r--r-- 1 root root 4096 1970-01-01 00:35 ext_range
    -rw-r--r-- 1 root root 4096 1970-01-01 00:35 force_ro
    drwxr-xr-x 2 root root 0 1970-01-01 00:00 holders
    -r--r--r-- 1 root root 4096 1970-01-01 00:35 inflight
    drwxr-xr-x 2 root root 0 1970-01-01 00:00 integrity
    drwxr-xr-x 7 root root 0 1970-01-01 00:00 mmcblk0boot0
    drwxr-xr-x 7 root root 0 1970-01-01 00:00 mmcblk0boot1
    drwxr-xr-x 4 root root 0 1970-01-01 00:00 mmcblk0p1
    drwxr-xr-x 4 root root 0 1970-01-01 00:00 mmcblk0p2
    drwxr-xr-x 7 root root 0 1970-01-01 00:00 mmcblk0rpmb
    drwxr-xr-x 2 root root 0 1970-01-01 00:00 power
    drwxr-xr-x 3 root root 0 1970-01-01 00:00 queue
    -r--r--r-- 1 root root 4096 1970-01-01 00:35 range
    -r--r--r-- 1 root root 4096 1970-01-01 00:35 removable
    -r--r--r-- 1 root root 4096 1970-01-01 00:35 ro
    -r--r--r-- 1 root root 4096 1970-01-01 00:35 size
    drwxr-xr-x 2 root root 0 1970-01-01 00:00 slaves
    -r--r--r-- 1 root root 4096 1970-01-01 00:35 stat
    lrwxrwxrwx 1 root root 0 1970-01-01 00:35 subsystem -> ../../../../../../../../class/block
    -rw-r--r-- 1 root root 4096 1970-01-01 00:00 uevent
    @xxx:/sys/devices/platform/6b030000.esdhc/mmc_host/mmc0/mmc0:0001/block/mmcblk0 #

关于这些参数的意义,可以参照:
https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-block
https://www.kernel.org/doc/Documentation/block/stat.txt


查看各个分区的大小

/sys/devices/platform/6b030000.esdhc/mmc_host/mmc0/mmc0:0001/block/目录下,有几个以mmcblk0开头的目录名,这里面包含了分区的起始和结束的block地址。比如说,mmcblk0p2挂载出来的/data分区。

  • 获取分区的大小:
    # cat mmcblk0p2/size
    524288

读取到分区的size为524288 block大小,1个block为512字节,那么这个/data分区的大小为:524288 block * 512Bytes/block = 268435456Bytes = 256MB

  • 获取到分区的起始地址:
    # cat mmcblk0p2/start
    1423360

读取eMMC控制器的相关寄存器

eMMC控制器厂商会提供一个寄存器概要信息,比如说美光家的eMMC的spec,详见:http://www.chinaflashmarket.com/Uploads/file/2015/12/25/Micron_emmc_v50.pdf
如果想要更进一步了解每个寄存器各个bit的详细信息,需要参考JEDEC提供的JESD84-B50-1文档。

/sys/devices/platform/6b030000.esdhc/mmc_host/mmc0/mmc0:0001/目录下可以读取到cidcsddsrocr、寄存器的值,如下:

@xxx:/sys/devices/platform/6b030000.esdhc/mmc_host/mmc0/mmc0:0001 # ll
total 0
drwxr-xr-x 3 root root 0 1970-01-01 00:00 block
-r--r--r-- 1 root root 4096 1970-01-01 01:49 cid
-r--r--r-- 1 root root 4096 1970-01-01 01:49 cmdq_en
-r--r--r-- 1 root root 4096 1970-01-01 01:49 csd
-r--r--r-- 1 root root 4096 1970-01-01 01:49 date
lrwxrwxrwx 1 root root 0 1970-01-01 01:49 driver -> ../../../../../../bus/mmc/drivers/mmcblk
-r--r--r-- 1 root root 4096 1970-01-01 01:49 dsr
-r--r--r-- 1 root root 4096 1970-01-01 01:49 enhanced_area_offset
-r--r--r-- 1 root root 4096 1970-01-01 01:49 enhanced_area_size
-r--r--r-- 1 root root 4096 1970-01-01 01:49 erase_size
-r--r--r-- 1 root root 4096 1970-01-01 01:49 ffu_capable
-r--r--r-- 1 root root 4096 1970-01-01 01:49 fwrev
-r--r--r-- 1 root root 4096 1970-01-01 01:49 hwrev
-r--r--r-- 1 root root 4096 1970-01-01 01:49 life_time
-r--r--r-- 1 root root 4096 1970-01-01 01:49 manfid
-r--r--r-- 1 root root 4096 1970-01-01 01:49 name
-r--r--r-- 1 root root 4096 1970-01-01 01:49 ocr
-r--r--r-- 1 root root 4096 1970-01-01 01:49 oemid
drwxr-xr-x 2 root root 0 1970-01-01 00:00 power
-r--r--r-- 1 root root 4096 1970-01-01 01:49 pre_eol_info
-r--r--r-- 1 root root 4096 1970-01-01 01:49 preferred_erase_size
-r--r--r-- 1 root root 4096 1970-01-01 01:49 prv
-r--r--r-- 1 root root 4096 1970-01-01 01:49 raw_rpmb_size_mult
-r--r--r-- 1 root root 4096 1970-01-01 01:49 rel_sectors
-r--r--r-- 1 root root 4096 1970-01-01 01:49 serial
lrwxrwxrwx 1 root root 0 1970-01-01 01:49 subsystem -> ../../../../../../bus/mmc
-r--r--r-- 1 root root 4096 1970-01-01 01:49 type
-rw-r--r-- 1 root root 4096 1970-01-01 00:00 uevent



读取ext_csd寄存器

这个寄存器属于csd扩展出来的,需要将debugfs挂载出来才能读取到。首先执行:mount -t debugfs none /sys/kernel/debug/
/sys/kernel/debug/mmc0目录下,cat ios可以查看这个eMMC控制器的工作频率和位宽基本信息。

@xxx:/sys/kernel/debug/mmc0 # cat ios
clock: 52000000 Hz
actual clock: 41666666 Hz
vdd: 21 (3.3 ~ 3.4 V)
bus mode: 2 (push-pull)
chip select: 0 (don't care)
power mode: 2 (on)
bus width: 3 (8 bits)
timing spec: 8 (mmc DDR52)
signal voltage: 1 (1.80 V)
driver type: 0 (driver type B)

然后在/sys/kernel/debug/mmc0/mmc0\:0001/目录下就可以看到ext_csd寄存器了。

@xxx:/sys/kernel/debug/mmc0/mmc0:0001 # ll
total 0
-r-------- 1 root root 0 1970-01-01 00:00 ext_csd
-r-------- 1 root root 0 1970-01-01 00:00 state
-r-------- 1 root root 0 1970-01-01 00:00 status

cat ext_csd可以得到一个512字节大小的数据,如下

@xxx:/sys/kernel/debug/mmc0/mmc0:0001 # cat ext_csd
00000000000000000000000000000000390300c0470700c04707000000000000000101000000000000000000000000000000000000000000000000000a000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000900e00070100000000151f20000000000000000000000000000000010100090000000008000200571f0a0aeeee8888001e0f460f78140100c0470710140a0a090201320808400007fdfb550100640aeeeeee99011e0200000000320a00100000ee01000000000000000000012020010100000000000000000000000000000000000000000000000000000000000000000000000000001f0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ffffffff00000103007f0003013f3f01010100000000000000

当然这样看很难看,无法很快的确认寄存器中某些位的值。因此,网上就有个小哥写了个python脚本来解析这512字节的数据,以常人可以理解的格式进行解析。详见:https://blog.kylemanna.com/linux/parse-emmc-extended-csd-ecsd-registers-with-python/
输出的格式如下:

victor @victor-HP:~/ work2/cal_time$ python analysis_ext_csd.py 
0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0016: 39 03 00 c0 47 07 00 c0 47 07 00 00 00 00 00 00
0032: 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00
0048: 00 00 00 00 00 00 00 00 00 00 00 00 0a 00 00 01
0064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0096: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0112: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0128: 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00
0144: 00 00 00 00 00 00 00 00 00 00 00 00 00 90 0e 00
0160: 07 01 00 00 00 00 15 1f 20 00 00 00 00 00 00 00
0176: 00 00 00 00 00 00 00 00 01 01 00 09 00 00 00 00
0192: 08 00 02 00 57 1f 0a 0a ee ee 88 88 00 1e 0f 46
0208: 0f 78 14 01 00 c0 47 07 10 14 0a 0a 09 02 01 32
0224: 08 08 40 00 07 fd fb 55 01 00 64 0a ee ee ee 99
0240: 01 1e 02 00 00 00 00 32 0a 00 10 00 00 ee 01 00
0256: 00 00 00 00 00 00 00 00 01 20 20 01 01 00 00 00
0272: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0288: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0304: 00 00 00 1f 01 00 00 00 00 00 00 00 00 00 00 00
0320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0336: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0352: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0368: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0384: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0416: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0432: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0448: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0464: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0480: 00 00 00 00 00 00 01 ff ff ff ff 00 00 01 03 00
0496: 7f 00 03 01 3f 3f 01 01 01 00 00 00 00 00 00 00
BOOT_SIZE_MULTI[226] = 0x20

Python的内容如下:

#!/usr/bin/env python
"""
Author: Kyle Manna <[email protected]>
Blog: https://blog.kylemanna.com
"""
import binascii
import re
import sys

def str2bytearray(s):
if len(s) % 2:
s = '0' + s

reorder = True
if reorder:
r = []
i = 1
while i <= len(s):
r.append(s[len(s) - i - 1])
r.append(s[len(s) - i])
i += 2
s = ''.join(r)

out = binascii.unhexlify(s)

return out


if __name__ == '__main__':

ecsd_str = '00000000000000000000000000000000390300c0470700c04707000000000000000101000000000000000000000000000000000000000000000000000a000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000900e00070100000000151f20000000000000000000000000000000010100090000000008000200571f0a0aeeee8888001e0f460f78140100c0470710140a0a090201320808400007fdfb550100640aeeeeee99011e0200000000320a00100000ee01000000000000000000012020010100000000000000000000000000000000000000000000000000000000000000000000000000001f0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ffffffff00000103007f0003013f3f01010100000000000000'
#ecsd_str = '320100'
ecsd = str2bytearray(ecsd_str)
csd_len = len(ecsd)

line_len = 16
i = 0
while i < len(ecsd):
sys.stdout.write("{0:04d}:\t".format(i))
for j in range(line_len):
if (i < csd_len):
sys.stdout.write("{0:=02x}".format(ord(ecsd[csd_len-i-1])))
i = i + 1
else:
break

if (j == (line_len - 1)): pass
elif (i % 4): sys.stdout.write(" ")
else: sys.stdout.write(" ")

sys.stdout.write("\n")

print "BOOT_SIZE_MULTI[226] = 0x{:x}".format(ord(ecsd[csd_len-168-1]))




Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK