lshw学习——简单介绍

文章目录

简介

lshw: HardWare LiSter for Linux 一般用来查看linux设备的硬件信息,包括内存、cpu、主板等信息。

bash 复制代码
$ lshw --help
Hardware Lister (lshw) - 
usage: lshw [-format] [-options ...]
       lshw -version

        -version        print program version ()

format can be
        -html           output hardware tree as HTML
        -xml            output hardware tree as XML
        -json           output hardware tree as a JSON object
        -short          output hardware paths
        -businfo        output bus information

options can be
        -class CLASS    only show a certain class of hardware
        -C CLASS        same as '-class CLASS'
        -c CLASS        same as '-class CLASS'
        -disable TEST   disable a test (like pci, isapnp, cpuid, etc. )
        -enable TEST    enable a test (like pci, isapnp, cpuid, etc. )
        -quiet          don't display status
        -sanitize       sanitize output (remove sensitive information like serial numbers, etc.)
        -numeric        output numeric IDs (for PCI, USB, etc.)
        -notime         exclude volatile attributes (timestamps) from output

代码:https://ezix.org/src/pkg/lshw.git

核心结构

cpp 复制代码
class hwNode
{
  public:
    hwNode(const string & id,
      hw::hwClass c = hw::generic,
      const string & vendor = "",
      const string & product = "",
      const string & version = "");
    hwNode(const hwNode & o);
    ~hwNode();
    hwNode & operator =(const hwNode & o);

    string getId() const;

    void setHandle(const string & handle);
    string getHandle() const;

    bool enabled() const;
    bool disabled() const;
    void enable();
    void disable();
    bool claimed() const;
    void claim(bool claimchildren=false);
    void unclaim();

    hw::hwClass getClass() const;
    const char * getClassName() const;
    void setClass(hw::hwClass c);

    string getDescription() const;
    void setDescription(const string & description);

    string getVendor() const;
    void setVendor(const string & vendor);

    string getSubVendor() const;
    void setSubVendor(const string & subvendor);

    string getProduct() const;
    void setProduct(const string & product);

    string getSubProduct() const;
    void setSubProduct(const string & subproduct);

    string getVersion() const;
    void setVersion(const string & version);

    string getDate() const;
    void setDate(const string &);

    string getSerial() const;
    void setSerial(const string & serial);

    unsigned long long getStart() const;
    void setStart(unsigned long long start);

    unsigned long long getSize() const;
    void setSize(unsigned long long size);

    unsigned long long getCapacity() const;
    void setCapacity(unsigned long long capacity);

    unsigned long long getClock() const;
    void setClock(unsigned long long clock);

    unsigned int getWidth() const;
    void setWidth(unsigned int width);

    string getSlot() const;
    void setSlot(const string & slot);

    string getModalias() const;
    void setModalias(const string & modalias);

    unsigned int countChildren(hw::hwClass c = hw::generic) const;
    hwNode * getChild(unsigned int);
    hwNode * getChildByPhysId(long);
    hwNode * getChildByPhysId(const string &);
    hwNode * getChild(const string & id);
    hwNode * findChildByHandle(const string & handle);
    hwNode * findChildByLogicalName(const string & handle);
    hwNode * findChildByBusInfo(const string & businfo);
    hwNode * findChildByResource(const hw::resource &);
    hwNode * findChild(bool(*matchfunction)(const hwNode &));
    hwNode * addChild(const hwNode & node);
    bool isBus() const
    {
      return countChildren()>0;
    }

    bool isCapable(const string & feature) const;
    void addCapability(const string & feature, const string & description = "");
    void describeCapability(const string & feature, const string & description);
    string getCapabilities() const;
    vector<string> getCapabilitiesList() const;
    string getCapabilityDescription(const string & feature) const;

    void attractHandle(const string & handle);

    void setConfig(const string & key, const string & value);
    void setConfig(const string & key, unsigned long long value);
    string getConfig(const string & key) const;
    vector<string> getConfigKeys() const;
    vector<string> getConfigValues(const string & separator = "") const;

    vector<string> getLogicalNames() const;
    string getLogicalName() const;
    void setLogicalName(const string &);

    string getDev() const;
    void setDev(const string &);

    string getBusInfo() const;
    void setBusInfo(const string &);

    string getPhysId() const;
    void setPhysId(long);
    void setPhysId(unsigned, unsigned);
    void setPhysId(unsigned, unsigned, unsigned);
    void setPhysId(const string &);
    void assignPhysIds();

    void addResource(const hw::resource &);
    bool usesResource(const hw::resource &) const;
    vector<string> getResources(const string & separator = "") const;

    void addHint(const string &, const hw::value &);
    hw::value getHint(const string &) const;
    vector<string> getHints() const;

    void merge(const hwNode & node);

    void fixInconsistencies();

    string asXML(unsigned level = 0);
    string asJSON(unsigned level = 0);
    string asString();

    bool dump(const string & filename, bool recurse = true);
  private:

    void setId(const string & id);

    bool attractsHandle(const string & handle) const;
    bool attractsNode(const hwNode & node) const;

    struct hwNode_i * This;
};

扫描设备原理

大部分都是通过读取/proc/sys/dev虚拟文件系统下面的文件内容获取系统运行状态和设备信息。

下面就依次分析lshw源码中core文件夹下面提供的函数:

scan_abi

/proc/sys/abi,含义参考https://www.kernel.org/doc/Documentation/admin-guide/sysctl/abi.rst

scan_burner

ioctl执行scsi命令

scan_cdrom

核心代码:

c++ 复制代码
ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
ioctl(fd, CDROM_GET_CAPABILITY);
ioctl(fd, CDROM_DRIVE_STATUS, 0)

scan_cpufreq

/sys/devices/system/cpu/cpu%d/cpufreq/,下面有cpu频率信息

bash 复制代码
ls /sys/devices/system/cpu/cpu0/cpufreq/
affected_cpus     cpuinfo_min_freq                          energy_performance_preference  scaling_cur_freq  scaling_max_freq
base_frequency    cpuinfo_transition_latency                related_cpus                   scaling_driver    scaling_min_freq
cpuinfo_max_freq  energy_performance_available_preferences  scaling_available_governors    scaling_governor  scaling_setspeed

scan_cpuid

scan_cpuinfo

/proc/cpuinfo,从该文件获取cpu信息。

scan_device_tree

/proc/device-tree,从该路径下获取信息

scan_disk

核心代码:

c++ 复制代码
long size = 0;
unsigned long long bytes = 0;
int sectsize = 0;
int physsectsize = 0;
int fd = open(disk_path, O_RDONLY | O_NONBLOCK);
ioctl(fd, BLKPBSZGET, &physsectsize)
ioctl(fd, BLKSSZGET, &sectsize)
ioctl(fd, BLKGETSIZE64, &bytes)
(ioctl(fd, BLKGETSIZE, &size)

scan_display

scan_dmi

/sys/firmware/dmi/tables,扫描该路径下面信息。

bash 复制代码
$ ls /sys/firmware/dmi/tables
DMI  smbios_entry_point

还会尝试结合/dev/mem/sys/firmware/efi/systab/proc/efi/systab的内容分析。

scan_fat

读取裸设备块数据,随后解析FAT文件系统格式。

scan_fb

/proc/devices中获取fb设备号,随后获取到framebuffer设备文件描述符fb,核心代码:

c++ 复制代码
#define FBIOGET_VSCREENINFO     0x4600
#define FBIOGET_FSCREENINFO     0x4602
ioctl(fd[i], FBIOGET_FSCREENINFO, &fbi);
ioctl(fd[i], FBIOGET_VSCREENINFO, &fbconfig);

scan_graphics

/sys/class/graphics,扫描该路径下面的设备信息。

bash 复制代码
ls /sys/class/graphics/fb0/
bits_per_pixel  bl_curve  cursor  device  modes  pan    rotate  stride     uevent
blank           console   dev     mode    name   power  state   subsystem  virtual_size

scan_ide

/proc/ide,扫描该路径下设备的信息。

scan_ideraid

扫描ideraid设备,核心还是通过ioctl来直接获取设备信息。

scan_input

/sys/class/input,扫描该路径下面设备信息。

bash 复制代码
$ ls /sys/class/input/
event0  event2  event4  input0  input3  input5  js0   mouse0  mouse2
event1  event3  event5  input1  input4  input6  mice  mouse1

scan_isapnp

scan_lvm

通过读取裸设备文件,通过解析LVM2 structures获取lvm信息。

scan_memory

核心代码

c++ 复制代码
pagesize = sysconf(_SC_PAGESIZE);
physpages = sysconf(_SC_PHYS_PAGES);
stat("/proc/kcore", &buf)

读取/sys/bus/memory/sys/devices/system/memory/

bash 复制代码
$ ls /sys/bus/memory/
devices  drivers  drivers_autoprobe  drivers_probe  uevent
$ ls /sys/devices/system/memory/
auto_online_blocks  memory1   memory13  memory3   memory35  memory39  memory42  memory46  memory7  probe
block_size_bytes    memory10  memory14  memory32  memory36  memory4   memory43  memory47  memory8  soft_offline_page
hard_offline_page   memory11  memory15  memory33  memory37  memory40  memory44  memory5   memory9  uevent
memory0             memory12  memory2   memory34  memory38  memory41  memory45  memory6   power

scan_mmc

/sys/class/mmc_host/

scan_mounts

/proc/mounts读取挂载信息。

scan_network

通过扫描/proc/net/dev/sys/class/net获取网络设备,之后通过ioctl获取设备信息。

scan_nvme

扫描/sys/class/nvme获取nvme设备,之后再扫描磁盘。

scan_parisc

/sys/devices/parisc

scan_partitions

扫描磁盘分区

scan_pci、scan_pci_legacy

扫描/proc/bus/pci/sys/bus/pci获取pci设备,随后读取设备裸数据来获取信息。

scan_pcmcialegacy

scan_pcmcia

scan_pnp

/sys/bus/pnp

scan_s390_devices

scan_scsi

扫描scsi设备,/proc/scsi/sys/class/scsi_*

scan_smp

/sys/devices/system/cpu/online

scan_sound

/sys/class/sound

scan_spd

/proc/sys/dev/sensors

scan_sysfs

scan_usb

/proc/bus/usb/devices/sys/kernel/debug/usb/devices

scan_vio

/sys/bus/vio

scan_virtio

/sys/bus/virtio

scan_volume

总结

lshw源码用到一下几点

  1. linux内核文件系统
  2. 系统接口如ioctlstat
  3. 操作系统概念,比如文件系统结构、网络、总线
  4. 工程上抽象出统一的设备结构
    以上只是对lshw的初步分析,进一步的理解还是需要直接阅读代码

参考

Hardware Lister (lshw)
linux内核文件系统:proc、tmpfs、devfs、sysfs简要介绍
linux下 /proc 和 /sys 详解
Linux kernel简介
proc/sys目录介绍
Documentation for /proc/sys/abi/
The Linux Kernel documentation

相关推荐
上海运维Q先生1 小时前
面试题整理4----lvs,nginx,haproxy区别和使用场景
linux·运维·nginx
UntifA1 小时前
Linux大杂烩!!!
linux
Bug.ink4 小时前
Linux学习——9_Ubuntu Linux操作系统
linux·学习·ubuntu
whoami-46 小时前
Linux基础入门
linux·运维·服务器
zym大哥大6 小时前
Shell自定义(二)
linux·windows
码农秃头老李6 小时前
系列1:基于Centos-8.6部署Kubernetes (1.24-1.30)
linux·kubernetes·centos
魏 无羡6 小时前
linux CentOS系统上卸载Kubernetes(k8s)
linux·kubernetes·centos
超爱吃士力架7 小时前
Linux系统中常用的两种包管理工具 apt和yum
java·linux·后端