dmidecode命令主要是通过DMI获取主机的硬件信息,其输出的信息包括BIOS、系统、主板、处理器、内存、缓存等等。它是通过SMBIOS(System Management BIOS)来获取信息的。SMBIOS是主板或系统制造者以标准格式显示产品管理信息所需遵循的统一规范。

什么是DMI?

DMI (Desktop Management Interface, DMI)的主要组成部分是Management InformationFormat (MIF)数据库,这个数据库包括了所有有关电脑系统和配件的信息。

百度百科到的资料:

DMI是指Direct Media Interface(直接媒体接口)的缩写,DMI是Intel(英特尔)公司开发用于连接主板南北桥的总线,取代了以前的Hub-Link总线。DMI采用点对点的连接方式,时钟频率为100MHz,由于它是基于PCI-Express总线,同样采用8bit/10bit(有效位宽8bit)编码因此具有PCI-E总线的优势。

在4系列芯片组没有取消前端总线FSB时,DMI 是Intel(英特尔)公司开发用于北桥(G)MCH(Graphics & Memory controller hub)和南桥ICH10/ICH7之间的芯片连接总线。DMI实现了上行与下行双向数据传输率,单通道单向传输速率达到2.5GT/s,采用8bit/10bit编码,共计4条通道。这个高速接口集成了高级优先服务,允许并发通讯和真正的同步传输能力。它的基本功能对于软件是完全透明的,因此早期的软件也可以正常操作。

从5系列芯片组开始的新构架设计中,前端总线被取消,北桥芯片的功能被整合进CPU中。显卡采用了PCI-E ×16的通道直连CPU,当多卡交火时分为×8+×8(双卡)或×8+×4+×4(三卡)(具体分配方式要参考主板设计)。因为PCI-E2.0的应用,DMI升级到DMI2.0,单通道单向传输速率达到5GT/s。同时DMI2.0也不再用于南北桥芯片的连接,而是用于CPU和芯片组(原南桥芯片组)的连接。如下图所示,下图展示的是北桥集成到CPU后的情况:

所以,我们现在可以知道,为何dmidecode工具可以获取主板,内存等信息了,因为很多关于系统硬件的底层信息都是通过DMI通道获取的,我们看一下dmidecode工具的帮助信息:

dmidecode 工具会读取/sys/firmware/dmi/tables/smbios_entry_point文件。

czl@czl-Vostro-3268:~$ sudo strace -e trace=open,close,openat dmidecode
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
close(3)                                = 0
# dmidecode 3.1
openat(AT_FDCWD, "/sys/firmware/dmi/tables/smbios_entry_point", O_RDONLY) = 3
close(3)                                = 0
Getting SMBIOS data from sysfs.
SMBIOS 3.0.0 present.
Table at 0x000E0000.openat(AT_FDCWD, "/sys/firmware/dmi/tables/DMI", O_RDONLY) = 3
close(3)                                = 0

dmidecode的常见用法:

$ dmidecode                                                       # 打印所有硬件信息
$ dmidecode -q                                                  # 打印所有硬件信息,比较简洁
$ dmidecode -h                                                  # 获取帮助
$ dmidecode | grep 'Product Name'         # 以过滤的方式来查看指定的硬件信息
$ dmidecode --type bios                                # 查看BIOS相关的硬件信息
$ dmidecode --type system                          # 查看系统相关的硬件信息
$ dmidecode --type baseboard                  # 查看主板相关的硬件信息
$ dmidecode --type chassis                         # 查看机箱相关的硬件信息
$ dmidecode --type processor                    # 查看处理器相关的硬件信息
$ dmidecode --type memory                      # 查看内存相关的硬件信息
$ dmidecode |grep 'Serial Number'         # 查看主板的序列号
$ dmidecode -s system-serial-number  # 查看系统序列号
$ dmidecode -t 11                                           # 查看OEM信息
$ dmidecode -t 7                                             # 查看L1/L2/L3 Cache信息
$ dmidecode -t 4                                             # 查看CPU信息
$ dmidecode -t slot                                        #查看PCIE Slot槽位信息

take get pcie slot for example

czl@czl-Vostro-3268:~$ sudo dmidecode  -t slot
# dmidecode 3.1
Getting SMBIOS data from sysfs.
SMBIOS 3.0.0 present.Handle 0x0024, DMI type 9, 17 bytes
System Slot InformationDesignation: SLOT1Type: x1 PCI ExpressCurrent Usage: AvailableLength: ShortID: 1Characteristics:3.3 V is providedPME signal is supportedBus Address: 0000:ff:1f.7Handle 0x0025, DMI type 9, 17 bytes
System Slot InformationDesignation: SLOT2Type: x16 PCI Express 3Current Usage: AvailableLength: LongID: 2Characteristics:3.3 V is providedPME signal is supportedBus Address: 0000:ff:1f.7

dmidecode打开文件

sudo strace -tt -T -v -f -e trace=file -o ./strace.log dmidecode

对应的内核代码在文件drivers/firmware/dmi_scan.c中:

获取机器型号的方法

method 1:

dmesg

method 2:

sudo dmidecode -t 1

内核中获取dmi信息

前面提到,用户空间dmidecode工具是通过/sys/firmware/dmi/tables/smbios_entry_point文件来获取dmi信息的,sysfs是内核空间创建的一个内存文件系统,则必然在内核中也有完备的dmi信息,那么在内核中如何获取呢?

在dmi的内核实现文件dmi_scan.c中,能找到如下几个接口,它们有被作为开放接口export出去,分别是:

u64 dmi_memdev_size(u16 handle);
void dmi_memdev_name(u16 handle, const char **bank, const char **device);
bool dmi_match(enum dmi_field f, const char *str);
int dmi_walk(void (*decode)(const struct dmi_header *, void *);
int dmi_get_bios_year(void);
bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp);
const struct dmi_device *dmi_find_device(int type, const char *name,const struct dmi_device *from);
int dmi_name_in_vendors(const char *str);
const char *dmi_get_system_info(int field);
const struct dmi_system_id *dmi_first_match(const struct dmi_system_id *list);
int dmi_check_system(const struct dmi_system_id *list);

其中,dmi_get_system_info接口和dmi_check_system接口,是内核中比较常用的几个,dmi_get_system_info 它的参数包含如下类型,在内核中被广泛使用:

dmi_check_system则提供了一个完整的黑/白名单检测语义,用户需要首先将黑/白名单的信息记录在一个struct dmi_system_id类型的数组中,之后以次数组为参数调用dmi_check_system,函数将会返回你当前主班上信息匹配的个数。用户基于此完成应用语义。

典型用法参考drivers/i2c/busses/i2c-piix4.c文件中的用法。

原理

dmi数据存储在哪里?

dmi数据是二进制数据,需要通过架构的IO操作读取到内核,内核为此创建了一个32字节的全局buffer保存,叫做static u8 smbios_entry_point[32];

关键逻辑是首先调用dmi_early_remap对存储smbios信息的区域进行映射,拿到虚拟地址后再dmi_smbios3_present/dmi_present中调用memcpy_fromio读进dmi_early_remap buffer中。最后设置dmi_available为1。

dmidecode就是将smbios_entry_point读取到用户空间解码发挥作用的。

execve("/usr/sbin/dmidecode", ["dmidecode"], 0x7fff725b3940 /* 26 vars */) = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240\35\2\0\0\0\0\0"..., 832) = 832
close(3)                                = 0
openat(AT_FDCWD, "/sys/firmware/dmi/tables/smbios_entry_point", O_RDONLY) = 3
read(3, "_SM_\7\37\2\7s\0\0\0\0\0\0\0_DMI_\327D*\20\0\16\0\4\1\0", 32) = 31
read(3, "", 1)                          = 0
close(3)                                = 0
openat(AT_FDCWD, "/sys/firmware/dmi/tables/DMI", O_RDONLY) = 3
read(3, "\0\30\0\0\1\2I\352\3\0\220\337\t|\0\0\0\0\201\7\4\6\0\0Phoenix "..., 10820) = 4096
read(3, "RAM slot #33\0\0\21\"]\0:\0\377\377\0\0\0\0\0\0\t\0\1\1"..., 6724) = 4096
read(3, "\0\0\0\0\0NVD #61\0\0\21\"\271\0%\0\377\377 \0 \0\0\0\t\0\1\1"..., 2628) = 2628
read(3, "", 0)                          = 0
close(3)                                = 0
+++ exited with 0 +++

注意其中的raw_table_read函数实现。

除此之外,dmi仅仅是一个 sysfs中创建的子目录

callstack

[  129.107667] Hardware name: Dell Inc. Vostro 3268/0TJYKK, BIOS 1.11.1 12/11/2018
[  129.107667] Call Trace:
[  129.107669]  dump_stack+0x6d/0x8b
[  129.107670]  raw_table_read+0x24/0x30
[  129.107672]  sysfs_kf_bin_read+0x4d/0x80
[  129.107673]  kernfs_fop_read+0xad/0x1a0
[  129.107675]  __vfs_read+0x1b/0x40
[  129.107676]  vfs_read+0x8e/0x130
[  129.107678]  ksys_read+0xa7/0xe0
[  129.107679]  __x64_sys_read+0x1a/0x20
[  129.107681]  do_syscall_64+0x57/0x190
[  129.107682]  entry_SYSCALL_64_after_hwframe+0x5c/0xc1
[  129.107683] RIP: 0033:0x7f01e2dd1031

dmidecode源码

获取源码

wget -c http://download.savannah.gnu.org/releases/dmidecode/dmidecode-3.4.tar.xz

编译:

$ make
cc -O2 -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wmissing-prototypes -Winline -Wundef -D_FILE_OFFSET_BITS=64 -c dmidecode.c -o dmidecode.o
cc -O2 -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wmissing-prototypes -Winline -Wundef -D_FILE_OFFSET_BITS=64 -c dmiopt.c -o dmiopt.o
cc -O2 -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wmissing-prototypes -Winline -Wundef -D_FILE_OFFSET_BITS=64 -c dmioem.c -o dmioem.o
cc -O2 -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wmissing-prototypes -Winline -Wundef -D_FILE_OFFSET_BITS=64 -c dmioutput.c -o dmioutput.o
cc -O2 -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wmissing-prototypes -Winline -Wundef -D_FILE_OFFSET_BITS=64 -c util.c -o util.o
cc  dmidecode.o dmiopt.o dmioem.o dmioutput.o util.o -o dmidecode
cc -O2 -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wmissing-prototypes -Winline -Wundef -D_FILE_OFFSET_BITS=64 -c biosdecode.c -o biosdecode.o
cc  biosdecode.o util.o -o biosdecode
cc -O2 -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wmissing-prototypes -Winline -Wundef -D_FILE_OFFSET_BITS=64 -c ownership.c -o ownership.o
cc  ownership.o util.o -o ownership
cc -O2 -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wmissing-prototypes -Winline -Wundef -D_FILE_OFFSET_BITS=64 -c vpddecode.c -o vpddecode.o
cc -O2 -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wmissing-prototypes -Winline -Wundef -D_FILE_OFFSET_BITS=64 -c vpdopt.c -o vpdopt.o
cc  vpddecode.o vpdopt.o util.o -o vpddecode

编译结果有四个目标文件,分别是dmidecode,ownership, vpdecode, biosdecode.

内核中的应用

内核在打印dump_stack时,会输出主板型号,BIOS型号等信息。这些信息的来源即是DMI。

dmi_setup->dump_stack_set_arch_desc.

打印:

dump_stack->dump_stack_set_arch_desc->printk("%sHardware name: %s\n",log_lvl, dump_stack_arch_desc_str);

参考资料

https://blog.csdn.net/zhangliang19950813/article/details/105763801

结束

Linux下dmi信息分析工具dmidecode原理相关推荐

  1. Linux下常用日志分析工具

    Linux下常用日志分析工具 Logcheck简介 对于拥有大量账户.系统繁忙的Linux系统而言,其日志文件是极其庞大的,很多没有用的信息会将值得注意的信息淹没,给用户分析日志带来了很大的不便.现在 ...

  2. linux下网络包分析工具下载,Wireshark下载-网络封包分析工具 v3.2.6 官方版 - 下载吧...

    Wireshark(前称Ethereal)是免费的网络协议检测程序,支持Unix,Windows.让您经由程序抓取运行的网站的相关资讯,包括每一封包流向及其内容.资讯可依操作系统语系看出,方便查看.监 ...

  3. Linux下Apache日志分析工具--AWStats安装使用

    source:http://blog.sina.com.cn/s/blog_5ce0e67e0100baf5.html http://doc.linuxpk.com/28437.html 1.事先安装 ...

  4. 粗略的看下两款Linux下的性能分析工具

    uptime -> 查询系统负载信息 我们先执行下uptime命令看下: uptime 以逗号分隔我们可以看到第一段是 # 16:03:53 => 系统当前的时间 # up 4:25 =& ...

  5. linux跟踪内存检测原理,wooyun/Linux下基于内存分析的Rootkit检测方法.html at master · exitmsconfig/wooyun · GitHub...

    Linux下基于内存分析的Rootkit检测方法 - 路人甲 原文地址:http://drops.wooyun.org/tips/4731 0x00 引言 某Linux服务器发现异常现象如下图,确定被 ...

  6. linux 系统级性能分析工具 perf 的介绍与使用

    目录 1. 背景知识 1.1 tracepoints 1.2 硬件特性之cache 2. 主要关注点 3. perf的使用 3.0 perf引入的overhead 3.1 perf list 3.2 ...

  7. Linux下程序的Profiling工具-性能测试工具GNU gprof

    Linux下程序的Profiling工具 http://blog.chinaunix.net/uid-128922-id-289972.html 我们在写程序,特别是嵌入式程序的时候,通常需要对程序的 ...

  8. Linux查看c语言组件进程,Linux下查看进程IO工具iopp

    Linux下的IO检测工具最常用的是iostat,不过iostat只能查看到总的IO情况.如果要细看具体那一个程序点用的IO较高,可以使用iotop .不过iotop对内核版本和Python版本有要求 ...

  9. 常用Linux网络/内存/磁盘分析工具

    Centos查看网卡.CPU.内存等使用率 # watch more /proc/net/dev 性能分析和监控工具 uptime dmesg | tail vmstat 1 mpstat -P AL ...

最新文章

  1. 阿里将AI引入时尚界,消费者会对程序员的审美买账吗?
  2. linux 连接远程命令行,screen命令行远程连接
  3. 移动端触摸移动小demo
  4. Django环境搭建
  5. Unity延迟和重复调用方法
  6. OpenCV 4.0 在Windows10系统下的安装教程
  7. 【转】一些 SQLite技巧
  8. 脉冲激光器的重要参数
  9. 变分模态分解算法matlab程序,一种基于变分模态分解理论和K最近邻算法的心电信号分类方法与流程...
  10. SQL Server 2012 SQLEXPRESS 无法通过IP连接访问问题的解决
  11. 超级超级实用的整个网页截图技巧
  12. 基于FusionInsight Manager的大数据架构图
  13. Python flag用法
  14. 百宝云网络验证对接+脚本更新功能(源码)
  15. 计算机再带word打不开,电脑上 word打不开怎么办(精选).doc
  16. FPGA学习思维导图
  17. Qt:一个简洁漂亮的高仿网易云播放器
  18. shell-------数组遍历、切片、替换等操作
  19. Android中的单元测试
  20. 群晖python套件包_群晖中给Python3安装pip工具以安装扩展包

热门文章

  1. 购物中心户外广场美陈设计方案
  2. bootice添加linux引导,bootice怎么添加win10引导_网站服务器运行维护
  3. ERP项目售前需求调研提纲
  4. netcore 使用NHibernate
  5. SEO中常见的专业术语
  6. 个人工作、学习常用网站
  7. Private关键字详解
  8. 《Web前端开发之HTML+CSS精英课堂【渡一教育】》文档版笔记(完结)
  9. Java项目:酒店宾馆管理系统(java+SpringBoot+html+layui+jQuery+maven+mysql)
  10. 工欲善其事,必先利其器,分享5款Windows效率软件