当前位置: 首页 > article >正文

lshw学习——简单介绍

文章目录

    • 简介
    • 核心结构
    • 扫描设备原理
      • scan_abi
      • scan_burner
      • scan_cdrom
      • scan_cpufreq
      • scan_cpuid
      • scan_cpuinfo
      • scan_device_tree
      • scan_disk
      • scan_display
      • scan_dmi
      • scan_fat
      • scan_fb
      • scan_graphics
      • scan_ide
      • scan_ideraid
      • scan_input
      • scan_isapnp
      • scan_lvm
      • scan_memory
      • scan_mmc
      • scan_mounts
      • scan_network
      • scan_nvme
      • scan_parisc
      • scan_partitions
      • scan_pci、scan_pci_legacy
      • scan_pcmcialegacy
      • scan_pcmcia
      • scan_pnp
      • scan_s390_devices
      • scan_scsi
      • scan_smp
      • scan_sound
      • scan_spd
      • scan_sysfs
      • scan_usb
      • scan_vio
      • scan_virtio
      • scan_volume
    • 总结
    • 参考

简介

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

$ 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

核心结构

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

核心代码:

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频率信息

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

核心代码:

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,扫描该路径下面信息。

$ 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,核心代码:

#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,扫描该路径下面的设备信息。

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,扫描该路径下面设备信息。

$ 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

核心代码

pagesize = sysconf(_SC_PAGESIZE);
physpages = sysconf(_SC_PHYS_PAGES);
stat("/proc/kcore", &buf)

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

$ 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


http://www.kler.cn/a/444176.html

相关文章:

  • 游戏渠道假量解决方案
  • 二叉搜索树Ⅲ【东北大学oj数据结构8-3】C++
  • 使用Python实现量子通信模拟:探索安全通信的未来
  • .net core在linux导出excel,System.Drawing.Common is not supported on this platform
  • 开放词汇目标检测(Open-Vocabulary Object Detection, OVOD)综述
  • 数据结构:B树与B+树
  • Java字符串的|分隔符转List实现方案
  • LLM大语言模型私有化部署-使用Dify与Qwen2.5打造专属知识库
  • Linux学习——9_Ubuntu Linux操作系统
  • js逆向基础-hook调试
  • Guava 提供了集合操作 `List`、`Set` 和 `Map` 三个工具类
  • HarmonyOS 输入框组件:TextInput 和 TextArea 深度解析
  • Oracle RAC最佳实践-优化私网连接
  • kubeadm安装K8s高可用集群之集群初始化及master/node节点加入calico网络插件安装
  • 系列1:基于Centos-8.6部署Kubernetes (1.24-1.30)
  • 深入浅出Flink CEP丨如何通过Flink SQL作业动态更新Flink CEP作业
  • git stash 的文件如何找回
  • 数据结构--插入排序
  • JAVA开发时获取用户信息失败,分析后端日志信息
  • spring @Mapper Converter转换泛型异常
  • Kafka Streams 在监控场景的应用与实践
  • 使用正则表达式提取PDF文件页数的实现方案
  • 观察者模式(sigslot in C++)
  • docker pull 报错Get “https://registry-1.docker.io/v2/“: net/http: request canceled while waiting for c
  • CSS学习-第三天
  • 基于springboot的在线政务服务系统的设计与实现-仅供学习