当前位置:首页>Linux>Linux 设备模型:设计与实现

Linux 设备模型:设计与实现

  • 2026-07-01 07:01:11
Linux 设备模型:设计与实现

阅读本文的前提:你写过一点内核驱动,但对设备模型的整体架构还比较模糊。本文不堆砌术语,目标是让你搞清楚"设备模型这套机制到底是怎么工作的",所有代码均来自 Linux 5.7.8 内核源码。


一、为什么需要设备模型?

先从一个痛点说起。

Linux 早期(2.4 时代),每个子系统各管各的。PCI 驱动自己遍历 PCI 总线找设备,USB 驱动自己遍历 USB 树,platform 设备干脆没有统一管理。后果是:

  • 电源管理无法统一:内核不知道系统里有多少设备,怎么统一做 suspend/resume?
  • 热插拔散落各地:PCI 有 PCI 的 uevent,USB 有 USB 的 uevent,没有统一抽象
  • 设备文件创建靠手写mknod 命令 Hardcode,插一个新设备就得改 udev 规则

2.6 内核引入了设备模型,核心目标就是用一套统一的数据结构描述所有硬件,建立一棵完整的设备树。之后电源管理、热插拔、驱动匹配、sysfs 导出全部基于这棵树。


二、设计思想:分层抽象

设备模型的设计哲学可以概括为三个层次:

用户空间  ↓  通过 sysfs 交互内核抽象层(class / bus / device / driver)  ↓底层基础设施(kobject / kset / kref)

越往上越面向用户,越往下越面向内核。这个分层非常重要——你写的驱动只需要接触上层的 device/device_driver/bus_type,不需要直接跟 kobject 打交道。


三、底层基础设施:kobject

3.1 kobject 是什么?

kobject 是设备模型的最底层构件。它本身不复杂,本质上是一个带有引用计数的对象,嵌在各种结构体里使用:

// 路径:D:\work\linux-5.7.8\linux-5.7.8\include\linux\kobject.hstructkobject {constchar          *name;                   // sysfs 目录名structlist_headentry;// 挂到父 kset 的链表节点structkobject      *parent;// 父 kobject,决定 sysfs 目录层级structkset         *kset;// 所属 ksetstructkobj_type    *ktype;// 描述该对象的操作(析构函数等)structkrefkref;// 引用计数unsignedint state_initialized:1;           // 是否已初始化unsignedint state_in_sysfs:1;              // 是否已在 sysfs 中表现unsignedint state_add_uevent_sent:1;unsignedint state_remove_uevent_sent:1;unsignedint uevent_suppress:1;             // 是否压制 uevent};

每个 kobject 在 /sys/ 下对应一个目录。parent 指针决定了这个目录的层级,name 就是目录名。

3.2 引用计数怎么工作的?

// 路径:D:\work\linux-5.7.8\linux-5.7.8\lib\kobject.cstaticvoidkobject_get(struct kobject *kobj){if (kobj)        kref_get(&kobj->kref);}staticvoidkobject_put(struct kobject *kobj){if (kobj)        kref_put(&kobj->kref, kobject_release);}staticvoidkobject_release(struct kref *kref){structkobject *kobj = container_of(krefstructkobjectkref);conststructkobj_type *t = get_ktype(kobj);    pr_debug("kobject: '%s' (refcount: %d): %s\n",         kobj->name, kref_read(&kobj->kref), __func__);if (t && t->release)        t->release(kobj);          // 调用具体的释放函数else        pr_debug("kobject: '%s' (end): %s\n", kobj->name, __func__);}

引用计数归零时,自动调用 ktype->release() 来释放内存。这个机制保证了对象在所有引用都释放之前不会被销毁,避免了 use-after-free。

3.3 kset 是什么?

kset 是一组 kobject 的集合,可以理解为一个可以包含子 kobject 的容器

// 路径:D:\work\linux-5.7.8\linux-5.7.8\include\linux\kobject.hstructkset {structlist_headlist;// 该 kset 下所有 kobject 的链表spinlock_t list_lock;structkobjectkobj;// kset 自身也是一个 kobjectconststructkset_uevent_ops *uevent_ops;};

kobject 通过 entry 挂入 kset->list,通过 parent 建立目录树结构。一个典型的 kset 下的目录结构:

/sys/bus/pci/          ← kset 的 kobject  ├── devices/         ← 子 kset  └── drivers/         ← 子 kset

四、bus_type:总线抽象

4.1 为什么需要总线抽象?

拿 USB 和 PCI 来说,它们的设备发现机制完全不同:PCI 靠配置空间读取 Vendor ID/Device ID,USB 靠描述符枚举。但有一点是相同的——都需要"设备和驱动匹配"这个逻辑bus_type 就是把"总线"这个概念抽象出来,让匹配逻辑可以统一实现。

4.2 bus_type 的定义

// 路径:D:\work\linux-5.7.8\linux-5.7.8\include\linux\device.hstructbus_type {constchar          *name;           // "pci", "usb", "platform", "i2c"constchar          *dev_name;       // 设备命名方式,比如 USB 用 "usb-X"structdevice       *dev_root;// 总线根设备// 设备与驱动的匹配——这是 bus_type 最重要的函数int                 (*match)(struct device *dev, struct device_driver *drv);// 总线上设备被探测前/后调用的钩子int                 (*probe)(struct device *dev);int                 (*remove)(struct device *dev);// uevent 回调,热插拔时通知用户空间int                 (*uevent)(struct device *dev, struct kobj_uevent_env *env);// 总线的属性,会在 /sys/bus/<name>/ 下以文件形式暴露structattribute_group **bus_groups;structattribute_group **dev_groups;structattribute_group **drv_groups;unsignedint drivers_autoprobe:1;structsubsys_private *p;// 私有数据,对外不可见};

4.3 总线的注册

以 platform 总线为例,它是 Linux 最简单也最常用的一种总线(设备树上的设备、PCI 总线上的设备等都属于 platform 设备):

// 路径:D:\work\linux-5.7.8\linux-5.7.8\drivers\base\platform.cintplatform_bus_type_init(void){    platform_bus_type.probe = platform_probe;    platform_bus_type.remove = platform_remove;    platform_bus_type.uevent = platform_uevent;return bus_register(&platform_bus_type);      // 关键函数}

bus_register() 做了什么?它创建了 /sys/bus/platform/ 目录,并在里面初始化了 devices 和 drivers 两个子目录:

// 路径:D:\work\linux-5.7.8\linux-5.7.8\drivers\base\bus.cintbus_register(struct bus_type *bus){int retval;structsubsys_private *p;structlock_class_key *key = &bus->p->subsys_key;// 创建 /sys/bus/<name>/    retval = kset_register(&bus->p->devices_kset->kset);    retval = kset_register(&bus->p->drivers_kset->kset);// 在 bus->p->devices_kset 和 bus->p->drivers_kset 上注册// 之后 device 和 driver 注册时自动放入对应子目录    ...}

4.4 平台总线的 match 实现

platform 总线的匹配规则非常直接——名字相同就匹配

// 路径:D:\work\linux-5.7.8\linux-5.7.8\drivers\base\platform.cstaticintplatform_match(struct device *dev, struct device_driver *drv){structplatform_device *pdev = to_platform_device(dev);structplatform_driver *pdrv = to_platform_driver(drv);// 匹配方式一:名字完全匹配(最常用)if (of_driver_match_device(dev, drv))return1;if (pdrv->id_table)return platform_match_id(pdrv->id_table, pdev) != NULL;// 匹配方式三:设备名 == 驱动名(fallback)if (strcmp(pdev->name, drv->name) == 0)return1;return0;}

这个函数告诉我们一个重要事实:设备模型提供了 match 机制,但 match 的具体策略由各总线自己决定。PCI 总线按 Vendor/Device ID 匹配,USB 总线按接口类匹配,而 platform 总线按名字匹配——策略各异,框架统一。


五、device:设备抽象

5.1 device 结构

// 路径:D:\work\linux-5.7.8\linux-5.7.8\include\linux\device.hstructdevice {structdevice       *parent;// 父设备,比如 USB 控制器是 USB 设备的父设备structdevice_private   *p;structkobjectkobj;// 嵌入 kobject,决定它在 sysfs 中的位置constchar          *init_name;      // 设备初始名字,如 "eth0"conststructdevice_type *type;structbus_type     *bus;// 设备所属的总线structdevice_driver *driver;// 已经绑定的驱动void                *platform_data;  // platform 设备的私有数据void                *driver_data;    // 驱动私有的设备数据structdev_links_infolinks;// 设备与其他设备之间的依赖关系structdev_pm_infopower;// 电源管理信息structdev_msi_infomsi;    ...    device_node         *of_node;        // 设备树节点(Device Tree)    fwnode_handle       *fwnode;         // 固件节点抽象};

注意 parent 字段——这使得设备之间形成了一棵树。系统启动时,parent 指向控制器或总线,设备层层嵌套,最终根设备的 parent 为 NULL,整棵树以根设备为根。

5.2 设备的注册

// 路径:D:\work\linux-5.7.8\linux-5.7.8\drivers\base\core.cintdevice_register(struct device *dev){    device_initialize(dev);return device_add(dev);}voiddevice_initialize(struct device *dev){    dev->kobj.kset = devices_kset;      // 挂入 /sys/devices/    kobject_init(&dev->kobj, &device_ktype);    INIT_LIST_HEAD(&dev->p->knode_class);    ...}intdevice_add(struct device *dev){    ...// 1. 将 device 的 kobject 加入 sysfs    kobject_add(&dev->kobj, dev->kobj.parent, "%s", dev->init_name);// 2. 在 /sys/devices/<bus>/ 下创建符号链接    bus_add_device(dev);// 3. 将设备加入所属 class    devices_kset->p->default_groups[0] = dev->type->groups;// 4. 发送 uevent 通知用户空间    kobject_uevent(&dev->kobj, KOBJ_ADD);// 5. 尝试与已有驱动匹配    bus_probe_device(dev);    ...}

这个函数是设备注册的核心路径。bus_probe_device(dev) 的实现很关键:

// 路径:D:\work\linux-5.7.8\linux-5.7.8\drivers\base\bus.cvoidbus_probe_device(struct device *dev){structbus_type *bus = dev->bus;structdevice_driver *drv;int ret;if (!bus)return;if (bus->p->drivers_autoprobe)        bus_for_each_drv(bus, NULL, &dev->state_initialized,                 __device_attach);}

它遍历总线上所有驱动,对每个驱动调用 __device_attach,后者调用 bus->match() 来判断是否匹配。


六、device_driver:驱动抽象

6.1 driver 结构

// 路径:D:\work\linux-5.7.8\linux-5.7.8\include\linux\device.hstructdevice_driver {constchar      *name;               // 驱动名,用于 matchstructbus_type *bus;// 驱动所属的总线structmodule   *owner;int             (*probe)(struct device *dev);    // 匹配成功后调用int             (*remove)(struct device *dev);   // 设备移除时调用void            (*shutdown)(struct device *dev); // 关机时调用int             (*suspend)(struct device *dev, pm_message_t state);int             (*resume)(struct device *dev);structdriver_private *p;};

6.2 驱动的注册与匹配

// 路径:D:\work\linux-5.7.8\linux-5.7.8\drivers\base\driver.cintdriver_register(struct device_driver *drv){    ...    bus_add_driver(drv);                  // 把驱动加入总线的驱动列表    kobject_add(&drv->p->kobj, &bus->p->devices_kset->kobj, "%s", drv->name);    driver_add_groups(drv, bus->drv_groups);// 尝试去匹配当前总线上所有已注册的设备    driver_attach(drv);return0;}intdriver_attach(struct device_driver *drv){return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);}staticint __driver_attach(struct device *dev, void *data){int ret;    ret = bus->match(dev, drv);           // ← 关键:调用总线的 matchif (ret == 0)return0;                         // 不匹配,跳过if (ret < 0)return ret;    ret = driver_probe_device(drv, dev);  // 匹配则执行 probe    ...}

6.3 probe 的完整流程

// 路径:D:\work\linux-5.7.8\linux-5.7.8\drivers\base\dd.cstaticintdriver_probe_device(struct device_driver *drv, struct device *dev){    ...// 1. 调用总线的 probe 钩子(如果定义了的话)if (dev->bus->probe)        ret = dev->bus->probe(dev);elseif (drv->probe)        ret = drv->probe(dev);            // ← 最终调用驱动的 probe// 2. 绑定成功后,建立双向链接    driver_bound(dev, drv);// 3. 发送 uevent 通知用户空间    kobject_uevent(&dev->kobj, KOBJ_BIND);return ret;}staticvoiddriver_bound(struct device *dev, struct device_driver *drv){    dev->driver = drv;                    // 设备记住驱动    dev->p->driver = drv;                 // 私有数据也记一份// 在 sysfs 中建立符号链接// /sys/devices/.../my-device/driver -> /sys/bus/.../drivers/my-driver/if (dev->bus && dev->bus->p && dev->bus->p->drivers_autoprobe)        sysfs_create_link(&dev->kobj, &drv->p->kobj, "driver");}

绑定完成后,device->driver 和 driver->p->kobj 之间互相指向对方,sysfs 里也建立了符号链接——用户空间可以随时查到哪个设备对应哪个驱动。


七、class:设备类抽象

7.1 为什么需要 class?

想象一下你要写一个管理网络设备的管理工具。你需要知道系统里有哪些网卡,但网卡可能是 PCI 的、USB 的、虚拟的——物理路径完全不同。class 解决了这个问题:它按功能(而非物理位置)组织设备

7.2 class 的注册

// 路径:D:\work\linux-5.7.8\linux-5.7.8\drivers\base\class.cint __class_register(struct class *cls, struct lock_class_key *key){structsubsys_private *p;int retval;    p = kzalloc(sizeof(*p), GFP_KERNEL);if (!p)return -ENOMEM;    p->class = cls;    cls->p = p;// 创建 /sys/class/<name>/    retval = kset_register(&cls->p->class_kset);    ...}intclass_register(struct class *cls){return __class_register(cls, &__key);}

7.3 设备加入 class 时发生什么?

当一个设备注册并属于某个 class 时,内核在 /sys/class/<name>/ 下创建一个符号链接指向设备的真实路径:

// 路径:D:\work\linux-5.7.8\linux-5.7.8\drivers\base\class.cintclass_add_device(struct class *class, struct device *device){structdevice *parent;structsubsys_private *cls_p = class->p;// 在 /sys/class/<classname>/ 下创建符号链接if (cls_p)        sysfs_create_link(&cls_p->class_dir->kobj, &device->kobj,                  device->init_name);}

这样用户空间程序只需要去 /sys/class/net/ 下就能找到所有网卡,而不需要关心它们在 /sys/devices/ 下的具体路径。


八、电源管理:设备模型的应用

设备模型对电源管理的支持是它被引入内核的重要原因之一。每个 device 都有一个 power 字段:

// 路径:D:\work\linux-5.7.8\linux-5.7.8\include\linux\device.hstructdev_pm_info {pm_message_t       state;              // 当前电源状态unsignedint      can_wakeup:1;        // 设备能否唤醒系统unsignedint      async_suspend:1;bool              is_prepared:1;       // 是否已准备好挂起bool              is_suspended:1;      // 是否已挂起bool              may_skip_resume:1;structwakeup_source    *wakeup;structtimer_listsuspend_timer;unsignedlong    timer_expires;    ...};

系统 suspend 时,内核从设备树的叶子节点开始,依次调用每个设备的 ->pm->runtime_suspend() 或 ->pm->suspend();resume 时反向遍历。这保证了子设备先挂起、后恢复,父设备后挂起、先恢复——和树的后序遍历顺序完全一致。


九、全景:设备模型的 sysfs 视图

/sys/├── devices/│   └── platform/              ← 设备树的根,所有设备的物理位置│       └── my-device/│           ├── driver -> ../../../bus/platform/drivers/my-driver/│           ├── subsystem -> ../../../class/myclass/│           └── uevent├── bus/                       ← 所有总线│   └── platform/│       ├── devices/           ← 挂在此总线上的设备(符号链接)│       │   └── my-device -> ../../../devices/platform/my-device/│       └── drivers/│           └── my-driver/│               ├── bind│               ├── unbind│               ├── uevent│               └── new_id├── class/                     ← 所有设备类│   └── myclass/│       └── my-device -> ../../devices/platform/my-device/└── drivers/                   ← 全局驱动视图(已被 bus 替代)

uevent 文件特别有用:往里面写东西会触发 uevent,可以用来模拟设备插拔,方便调试。


十、核心流程总结

10.1 设备注册 → 匹配驱动

platform_driver_register()  → bus_add_driver()            在 /sys/bus/platform/drivers/ 注册  → driver_attach()    → bus_for_each_dev()        遍历平台上所有设备      → __driver_attach()        → platform_match()      比较驱动名和设备名        → driver_probe_device()          → drv->probe()        匹配成功,调用驱动probe          → driver_bound()            → sysfs_create_link() 建立 driver 符号链接            → kobject_uevent()  发送 KOBJ_BIND uevent

10.2 驱动注册 → 匹配设备(设备先于驱动存在的情况)

platform_device_register()  → device_add()    → kobject_add()             在 /sys/devices/ 创建目录    → bus_add_device()          在 /sys/bus/platform/devices/ 创建链接    → kobject_uevent()          发送 KOBJ_ADD uevent    → bus_probe_device()      → bus_for_each_drv()        → __device_attach()          → platform_match()          → driver_probe_device()            → drv->probe()            → driver_bound()

这两条路径是对称的——谁先注册并不重要,设备模型保证最终总能匹配上。


十一、总结

Linux 设备模型的核心逻辑:

概念
作用
sysfs 位置
kobject
底层基础设施,管 sysfs 映射和引用计数
每个目录对应一个
kset
一组 kobject 的集合
目录下的子目录
bus_type
负责设备和驱动的匹配(match)
/sys/bus/
device_driver
驱动的逻辑,probe/remove/suspend/resume 回调
/sys/bus/*/drivers/
device
具体硬件设备,挂在某个 bus 上
/sys/devices/
class
同一类设备的统一抽象(按功能分组)
/sys/class/

设备模型看起来复杂,但它的设计非常优雅:用分层抽象解决耦合问题,用 kobject + 引用计数解决生命周期问题,用 match 回调解决驱动兼容性问题和可扩展性问题

理解了总线(bus)、设备(device)、驱动(driver)、类(class)这四个核心概念及其关系,再去看 pci_bus_typeusb_bus_typei2c_adapter 这些具体子系统的实现,就会发现它们都在这个框架里——框架是通用的,细节是具体的。

真正复杂的不是设备模型本身,而是它要解决的那些硬件层面的历史遗留问题。模型本身是干净的。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-03 00:54:32 HTTP/2.0 GET : https://f.mffb.com.cn/a/500910.html
  2. 运行时间 : 0.583507s [ 吞吐率:1.71req/s ] 内存消耗:4,448.51kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=19a9fbf9de6989370ad126adce53538f
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000808s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001233s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.011537s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.008567s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001362s ]
  6. SELECT * FROM `set` [ RunTime:0.101112s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001909s ]
  8. SELECT * FROM `article` WHERE `id` = 500910 LIMIT 1 [ RunTime:0.059390s ]
  9. UPDATE `article` SET `lasttime` = 1783011272 WHERE `id` = 500910 [ RunTime:0.015305s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.016820s ]
  11. SELECT * FROM `article` WHERE `id` < 500910 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.012548s ]
  12. SELECT * FROM `article` WHERE `id` > 500910 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.052082s ]
  13. SELECT * FROM `article` WHERE `id` < 500910 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.101660s ]
  14. SELECT * FROM `article` WHERE `id` < 500910 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.005789s ]
  15. SELECT * FROM `article` WHERE `id` < 500910 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.107157s ]
0.585177s