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

相关推荐
hhcgchpspk10 小时前
一次msf免杀渗透入门实践
linux·经验分享·网络安全·系统安全·渗透·msf
小白勇闯网安圈10 小时前
Vmware的Ubuntu构建极简版Linux发行版
linux
刘某的Cloud10 小时前
shell脚本-read-输入
linux·运维·bash·shell·read
broad-sky10 小时前
Ubuntu上查看USB相机连接的是哪个口,如何查看
linux·数码相机·ubuntu
秋深枫叶红10 小时前
嵌入式第三十七篇——linux系统编程——线程控制
linux·学习·线程·系统编程
shaohui97311 小时前
ARMv7 linux中断路由以及处理
linux·gic·cpsr·armv7
三小尛11 小时前
linux的开发工具vim
linux·运维·vim
陈陈爱java11 小时前
Conda 常用命令行
linux·windows·conda
twdnote11 小时前
dokcer 环境中集成LibreOffice
linux
ChristXlx11 小时前
Linux安装redis(虚拟机适用)
linux·运维·redis