当前位置:首页>Linux>Linux 内核如何初始化系统的 PCI 总线和设备

Linux 内核如何初始化系统的 PCI 总线和设备

  • 2026-08-21 15:40:48
Linux 内核如何初始化系统的 PCI 总线和设备

大家好,我是蟹老板~

PCI 的全称是外围组件互连。

它不只是主板上几个插槽的名字,而是一套完整规范,规定设备如何连接、如何寻址、如何报告身份,以及如何与处理器和其他设备交换数据

这整套过程,就是 PCI 初始化

CPU 直接连接 PCI 总线 0,视频设备也挂在这条总线上。另一个特殊设备 ——PCI-PCI 桥—— 把总线 0 延伸成了 PCI 总线 1。

站在桥接器的位置看,靠近 CPU 的一侧称为上游,远离 CPU 的一侧称为下游。总线 0 位于桥的上游,总线 1 位于桥的下游。

SCSI 控制器和以太网控制器都连接在总线 1 上。现实中,这座桥、下游总线和两个控制器甚至可能被集成在同一张 PCI 扩展卡中。

图中还有一座 PCI-ISA 桥。它负责照顾那些更老的 ISA 设备,例如键盘、鼠标和软盘控制器。换句话说,一个系统里可能同时生活着几代硬件,而 Linux 必须让它们和平相处。

一、Linux 面对的不是一条总线,而是一棵树

最简单的 PCI 系统确实可能只有一条总线,但实际机器通常没有这么简单。

一条 PCI 总线能够承载的设备数量受到电气特性的限制。当设备越来越多时,就需要通过 PCI-PCI 桥扩展出新的总线。新的总线上还可以继续连接桥,于是整个系统逐渐形成 树状结构

  • • 树根通常是 PCI 总线 0;
  • • 普通设备是树上的叶子;
  • • PCI-PCI 桥既是当前总线上的设备,也是通往下一层总线的入口。

这也是理解 Linux PCI 初始化的关键:内核不是简单扫描一排插槽,而是在遍历一棵硬件拓扑树

但是桥接器的存在给系统带来了两个问题。

CPU 如何访问桥后面的设备?

桥应该转发哪些地址,而哪些地址应该被挡住?

为了回答这两个问题,需要先看看 PCI 世界里到底有哪些地址空间。

二、PCI 设备为什么要拥有自己的地址空间

设备驱动程序想控制一块硬件,必须有地方可以读写。

例如,网卡会提供控制寄存器和状态寄存器。驱动程序通过写控制寄存器启动收发功能,通过读状态寄存器判断数据是否已经处理完成。SCSI 控制器也是类似的:驱动程序可能先检查设备是否就绪,然后再命令它把数据写入磁盘。

一种看似直接的做法,是把这些寄存器放进普通系统内存,让 CPU 和设备共享。

但这样做并不理想。

如果设备每次访问共享内存时都要与 CPU 争用总线,处理器可能不得不停下来等待。更麻烦的是,若允许外围设备毫无限制地读写主内存,一个故障设备甚至恶意设备就可能破坏内核数据,让系统瞬间失控。

于是,PCI 把问题拆开处理。

设备拥有自己的地址区域,CPU 可以访问这些区域;而设备若要访问系统主内存,则通常通过受控制的 DMA,也就是直接内存访问机制完成

在经典 PCI 模型中,主要涉及三类地址空间:

2.1 PCI I/O 地址空间

这块空间常用于放置设备寄存器。

驱动程序通过 I/O 读写操作访问它。例如,一些以太网控制器会把自己的控制寄存器映射到 PCI I/O 空间中。

2.2 PCI 内存地址空间

这也是设备与 CPU 通信的重要区域,只不过它按照内存访问方式映射。

显卡往往需要较大的地址范围来放置帧缓冲区,许多高性能设备也更倾向于使用内存映射 I/O。

2.3 PCI 配置地址空间

这块空间不负责传输正常业务数据,而是负责回答一组更基础的问题:

  • • 这里有没有设备?
  • • 它是谁生产的?
  • • 它属于什么类型?
  • • 它需要多少地址空间?
  • • 它能否进行 I/O 或内存访问?
  • • 它使用哪个中断引脚?

因此,PCI 配置空间主要由内核初始化代码访问。普通设备驱动程序通常不需要像初始化代码那样遍历配置空间,而是在设备已经被识别和分配资源后,使用 PCI I/O 或 PCI 内存空间控制设备

ISA 设备的世界稍微简单一些,它们通常只有 ISA I/O 和 ISA 内存两类地址空间。

某些处理器架构不能像访问普通内存那样直接访问 PCI 配置空间。例如 Alpha AXP 需要借助系统支持芯片组完成转换。常见办法是在处理器巨大的虚拟地址空间中划出一些特殊区域,通过稀疏映射把它们对应到 PCI I/O、PCI 内存或配置空间。

对驱动程序来说,这些架构差异最终会被内核封装起来;但在底层,处理器实际上可能通过完全不同的硬件路径抵达同一个 PCI 寄存器。

三、配置空间就是设备的“身份证档案”

系统中的每个 PCI 设备都拥有一块配置数据,PCI-PCI 桥也不例外。

这块配置数据通常以配置头开始。经典 PCI 配置头占用 256 字节,其中保存了设备的身份、能力、资源需求和当前状态

配置头在配置空间中的位置,与设备所在的总线、插槽和功能号有关。

一块显卡插在主板第一个 PCI 插槽时,会出现在一个配置地址;把它换到另一个插槽,它的配置地址也会跟着变化。不过,Linux 并不需要预先知道每张卡插在哪里。它只要按照系统提供的配置访问机制,逐个尝试可能存在的设备位置即可。

经典实现中,每个设备功能通常占用 256 字节配置空间。系统可以依次探测插槽和功能,并读取厂商标识与设备标识。

如果某个位置没有设备,读取结果常常是 0xFFFFFFFF。这就像敲门后没有任何回应,内核可以继续检查下一个位置

配置头中最重要的内容包括以下几类。

厂商标识和设备标识

厂商标识用来说明设备由谁制造,设备标识则说明它具体是哪一款产品。

例如:

  • • Digital 的厂商标识是 0x1011
  • • Intel 的厂商标识是 0x8086
  • • Digital 21141 快速以太网控制器的设备标识是 0x0009

厂商标识和设备标识组合起来,能够相当精确地确定设备型号。驱动程序也可以据此判断自己是否支持这块硬件

类代码

类代码不强调厂商,而是描述设备用途。

显卡、网络控制器、SCSI 控制器和桥接器都有各自的标准类别。例如,SCSI 控制器的类代码可以是 0x0100,PCI-PCI 桥常通过类代码 0x060400 识别。

类代码非常重要,因为即使内核不认识某个具体型号,也能先判断它大概属于哪种设备

状态寄存器

状态字段记录设备当前报告的各种状态和能力。每一位的含义由 PCI 标准规定。

命令寄存器

命令字段像一组总开关。

只有在其中打开相应位后,设备才可以响应 PCI I/O 地址、PCI 内存地址或执行总线主控操作。也就是说,内核即使已经为设备安排好地址,如果没有打开命令寄存器中的权限,设备仍然不会正式响应这些访问

基地址寄存器

基地址寄存器通常简称 BAR

它们既用于告诉系统设备需要哪种地址空间,也用于保存系统最终分配给设备的地址。

BAR 可以表达:

  • • 这是 I/O 空间还是内存空间;
  • • 设备需要多大的连续区域;
  • • 地址应当如何对齐;
  • • 设备最终被放置到哪里。

初始化阶段,Linux 会通过一套特殊的写入和读取操作,询问每个 BAR 到底需要多大空间。

中断引脚

经典 PCI 卡最多可以使用四个中断引脚,分别标记为 INTA、INTB、INTC 和 INTD。

配置头中的中断引脚字段说明设备使用哪一个物理引脚。这个选择通常由硬件连线决定,每次启动时不会随意变化。

中断线

中断线字段记录的是系统分配后的中断路由信息。

这个数字本身未必直接代表设备驱动程序眼中的硬件 IRQ,但它可以作为初始化代码、中断子系统和驱动程序之间传递路由结果的媒介。最终目标只有一个:设备发出中断时,Linux 必须把它送到正确的驱动程序处理函数

四、设备还没分配地址前,不能急着“开门营业”

PCI 设备不会在系统一上电后就自动响应所有 I/O 和内存请求。

内核需要先完成以下工作:

  1. 1. 识别设备;
  2. 2. 判断设备需要多少地址;
  3. 3. 找到一块不会与其他设备冲突的区域;
  4. 4. 把地址写入 BAR;
  5. 5. 配置沿途桥接器的转发窗口;
  6. 6. 最后修改命令寄存器,允许设备响应相应访问。

在 PCI 初始化完成之前,驱动程序不能假设设备的寄存器已经出现在某个可用地址

配置空间和普通设备空间的职责也要分清:

  • • PCI 初始化代码读取和修改配置空间;
  • • 设备驱动程序主要访问已经分配好的 PCI I/O 和 PCI 内存区域。

驱动程序看到的是一块可以正常使用的设备资源,至于它位于主总线上还是穿过了两三座桥,通常不需要驱动程序亲自处理。

这正是桥接机制努力实现的效果——把复杂拓扑藏在内核和硬件后面

五、PCI-ISA 桥:给老设备留一扇门

早期 PC 上大量设备按照 ISA 规范工作,而且许多寄存器地址早在 IBM PC 时代就固定下来了。

例如,即使是一台昂贵的 Alpha AXP 工作站,它的软盘控制器仍可能出现在与早期 PC 相同的 ISA I/O 地址位置。

硬件更新换代可以很快,为了兼容性。许多系统会同时提供 PCI 和 ISA 设备。

PCI-ISA 桥的工作,就是把针对某些低地址区域的 PCI 访问转换成 ISA 访问

通常,PCI I/O 和 PCI 内存空间中的低地址部分会保留给传统 ISA 外设。当处理器访问这些地址时,PCI-ISA 桥识别出请求属于 ISA 范围,于是把它转换后送往 ISA 总线。

这样一来,处理器和操作系统仍然可以通过统一的系统路径访问旧设备,而不必把整个系统退回到 ISA 时代。

随着纯 PCI 系统逐渐普及,这类兼容桥的重要性会下降。但在经典 PC 架构中,它是新旧设备能够共存的关键角色。

六、PCI-PCI 桥不只是延长线,它还会过滤流量

PCI-PCI 桥连接两条 PCI 总线,但它并不会把所有请求无脑复制到下游。

假设总线 0 上有显卡,总线 1 上有网卡和 SCSI 控制器。桥接器只应该把属于网卡和 SCSI 控制器的访问转发到总线 1。

显卡的地址明明位于桥上游,如果也被广播到下游,不但浪费带宽,还可能造成地址冲突或设备误响应。

为此,每座 PCI-PCI 桥都包含若干地址窗口:

  • • PCI I/O 窗口;
  • • PCI 内存窗口;
  • • 某些情况下还包括预取内存窗口。

窗口由基地址和限制地址定义。

只有落在窗口范围内的请求,桥才会向下游转发;范围之外的访问直接被忽略

例如,某座桥的 PCI 内存窗口被设置为 0x400000 到 0x402000,那么访问这段区域时,请求可以穿过桥;访问显卡所在的 0x200000 区域时,桥就不会理会。

完成配置后,普通驱动程序几乎感觉不到桥的存在。它只需访问设备资源,硬件会根据各座桥的窗口自动把请求送到正确总线。

不过,要达到这种“看起来什么都没有发生”的效果,Linux 初始化阶段必须非常准确地算出每座桥后面有哪些设备,以及它们总共需要多少地址空间。

七、桥后面的设备,怎样才能被配置访问找到

普通 I/O 和内存访问可以通过桥接窗口转发,但系统在刚启动时还有一个更早的问题:桥后面的设备尚未被识别,内核如何读取它们的配置空间?

PCI 规范定义了两种经典配置周期:

  • • Type 0 配置周期;
  • • Type 1 配置周期。

Type 0:访问当前总线上的设备

Type 0 配置周期不携带总线编号。

它的意思近似于:“我找的设备就在当前这条总线上。”

配置地址中的一部分用于选择设备。具体如何选择,取决于主机桥或 PCI 控制器的设计。

有些系统采用独热方式:某一位对应某个插槽。例如第 11 位选择插槽 0,第 12 位选择插槽 1。

另一些系统则直接把设备编号编码进相应字段。

无论硬件采用哪种方案,Type 0 的共同特点都是:它只面向当前总线上的设备,不负责跨越桥接器寻找更远的目标

Type 1:访问其他总线上的设备

Type 1 配置周期中包含总线编号。

普通 PCI 设备通常忽略 Type 1 周期,PCI-PCI 桥则会检查其中的总线号,决定是否应该把请求送往下游。

为了做出这个决定,每座桥至少需要知道三个编号:

  • • 主总线号:桥上游连接的总线;
  • • 次级总线号:桥下游紧邻的第一条总线;
  • • 从属总线号:从这座桥继续向下,能够抵达的最大总线号。

收到 Type 1 配置周期后,桥大致按照以下规则处理:

  1. 1. 如果目标总线号不在次级总线号与从属总线号之间,忽略请求;
  2. 2. 如果目标总线号正好等于次级总线号,把 Type 1 转换成 Type 0,并发送到下游总线;
  3. 3. 如果目标总线号大于次级总线号、但不超过从属总线号,保持 Type 1 格式继续向下转发。

假设内核要访问总线 3 上的设备 1。

CPU 首先发出目标总线为 3 的 Type 1 配置周期。沿途某座桥发现总线 3 不在自己的管理范围内,就会忽略它;另一座桥发现总线 3 位于自己的下游范围内,于是继续转发;当请求抵达次级总线号恰好为 3 的桥时,它会被转换成 Type 0 周期,最终由总线 3 上的设备 1 响应。

整条链路成立的前提,是所有桥的总线编号必须满足一条核心规则:

一座 PCI-PCI 桥后面的所有总线编号,都必须落在该桥的次级总线号和从属总线号之间

一旦编号不满足这条规则,桥就无法正确判断配置请求该不该转发。结果往往不是“慢一点”,而是内核彻底看不到下游设备。

总线编号不是为了让输出看起来整齐,而是 PCI 配置路由能够工作的基础

八、Linux 会先画地图,再让驱动程序上场

经典 Linux PCI 初始化过程可以分成三个逻辑层次。

第一层扫描设备并建立拓扑

内核从根总线开始,探测每个可能的设备位置。

发现设备后,内核读取它的配置头,记录厂商、型号、类代码、BAR、中断等信息。如果发现的是 PCI-PCI 桥,则继续扫描桥后的总线。

这一阶段负责回答:“系统里到底有什么?”

第二层:PCI BIOS 或平台访问层

不同架构访问 PCI 配置空间的硬件方式并不相同。

Intel PC 可能依赖 BIOS 已经提供的配置结果和标准服务;Alpha AXP 没有完全相同的 PC BIOS 环境,但内核会提供等价的平台代码。

上层 PCI 扫描逻辑不希望关心每种芯片组的具体寄存器,只需要一层统一接口来完成配置空间读写。

这一层回答:“怎样在当前机器上读到那些配置数据?”

第三层:平台修正与资源安排

某些平台的固件已经把设备资源安排妥当,Linux 主要负责读取和复现现有配置。

另一些平台则需要内核亲自完成更多工作,例如:

  • • 分配 PCI I/O 地址;
  • • 分配 PCI 内存地址;
  • • 设置 PCI-PCI 桥的转发窗口;
  • • 建立中断路由;
  • • 修复平台固件留下的不完整或错误配置。

这一阶段回答:“发现设备之后,怎样让它真正可用?”

在早期实现中,这些平台相关操作常被称为 PCI fixup,也就是 PCI 修正或补救代码。

九、内核用什么数据结构保存整张 PCI 地图

Linux 扫描 PCI 系统时,会在内存中建立一份与硬件拓扑相对应的数据结构。

每个 PCI 设备由一个 pci_dev 结构描述。

这个“设备”不仅包括网卡、显卡和存储控制器,也包括 PCI-PCI 桥。因为从当前总线看,桥本身同样占用一个设备位置,也拥有配置头和 BAR 等信息。

每条 PCI 总线则由一个 pci_bus 结构描述。

pci_bus 会记录:

  • • 当前总线编号;
  • • 这条总线上的设备;
  • • 父总线;
  • • 通往父总线的桥;
  • • 下游子总线;
  • • 可用和已分配的资源范围。

除根总线外,每条 PCI 总线都是通过某个 PCI-PCI 桥抵达的。一个子 pci_bus 会指向对应的桥设备,而这个桥设备又属于上一级总线。

这样一来,pci_bus 和 pci_dev 自然组成一棵树。

早期 Linux 还会维护一个指向所有 PCI 设备的全局链表,例如 pci_devices。树状结构适合表达父子关系,全局设备链表则适合快速遍历所有设备。

两种视图各有用途:

  • • 想知道设备位于哪座桥后面,沿树查找;
  • • 想让某段代码依次查看所有 PCI 设备,遍历全局链表更方便。

十、扫描从总线 0 开始,但不会只停留在表面

PCI 初始化代码并不是传统意义上服务某个硬件的设备驱动程序。它更像一个开机阶段的硬件调查员。

扫描通常从 PCI 总线 0 开始。

内核依次尝试读取每个可能设备位置上的厂商标识和设备标识。如果返回值表明没有设备,就继续下一个位置;如果读取成功,就创建一个 pci_dev,并把配置头中的关键信息保存下来。

随后,内核检查类代码。

如果这是普通设备,先记录下来,后续再分配资源和匹配驱动。

如果类代码是 0x060400,说明它是一座 PCI-PCI 桥。内核便创建对应的子 pci_bus,给下游总线安排编号,并立即进入下游继续扫描。

这种顺着一条分支走到底,再回来处理其他分支的方法,就是 深度优先扫描

假设总线 0 上同时连接着一块显卡和一座桥,而桥后的总线 1 上连接着网卡和 SCSI 控制器,那么扫描过程可能是:

  1. 1. 在总线 0 发现桥;
  2. 2. 暂时离开总线 0,进入总线 1;
  3. 3. 识别总线 1 上的网卡和 SCSI 控制器;
  4. 4. 如果总线 1 上还有桥,继续深入;
  5. 5. 当前分支结束后,再回到总线 0 处理后面的显卡。

这并不是说显卡不重要,而是深度优先遍历更适合同时解决桥接器的总线编号问题。

十一、最麻烦的一步:给桥后面的总线编号

为了让桥转发 Type 1 配置周期,每座桥都要提前知道主总线号、次级总线号和从属总线号。

问题是,第一次发现一座桥时,Linux 只知道它的上游总线,却不知道它后面到底有多少层。

举例来说,内核刚在总线 0 上发现桥 1,此时可以把桥后的第一条总线命名为总线 1。但桥 1 后面是否还有桥?最远会延伸到总线 2、总线 4,还是总线 20?在扫描完成前,内核无法知道。

经典解决办法是:

  1. 1. 先给桥分配确定的次级总线号;
  2. 2. 暂时把从属总线号设为 0xFF
  3. 3. 允许大量目标总线号的 Type 1 周期先通过;
  4. 4. 深入扫描桥后的全部拓扑;
  5. 5. 确定实际最大总线号后,再把 0xFF 改成准确值。

临时使用 0xFF,相当于先告诉桥:“暂时认为你能通往所有更远的总线,等我调查结束再缩小范围。”

下面用四步展示这个过程。

第一步:发现桥 1

桥 1 位于总线 0 上。

Linux 为它设置:

  • • 主总线号:0;
  • • 次级总线号:1;
  • • 临时从属总线号:0xFF

此时,目标总线号为 1 或更大的 Type 1 配置周期都可以通过桥 1。

目标为总线 1 的周期会被转换成 Type 0,直接用于扫描总线 1;目标为更大总线号的周期则保持 Type 1,继续为后续桥接器扫描做准备。

第二步:在总线 1 上发现桥 2

Linux 进入总线 1 后发现桥 2,并把它后面的总线编号设为 2。

继续扫描后,发现桥 2 的下游没有其他 PCI-PCI 桥。所以呢 桥 2 能够到达的最大总线号就是 2。

它最终得到:

  • • 主总线号:1;
  • • 次级总线号:2;
  • • 从属总线号:2。

这个分支就此结束。

第三步:回到总线 1,发现桥 3

扫描代码回到总线 1,继续检查剩余设备,并发现桥 3。

桥 3 后面的新总线被编号为 3,暂时设置:

  • • 主总线号:1;
  • • 次级总线号:3;
  • • 从属总线号:0xFF

此时,总线 1、2、3 都已经能够通过适当的桥接路径接收配置访问。

第四步:在总线 3 上发现桥 4

Linux 进入总线 3,发现桥 4,并把桥后的总线编号设为 4。

桥 4 后面没有更多桥,所以它的次级和从属总线号都是 4。

扫描返回桥 3。现在内核知道,桥 3 的下游最远可以抵达总线 4,于是把桥 3 的从属总线号更新为 4。

随后继续返回桥 1。桥 1 能够抵达总线 1、2、3 和 4,它的最终从属总线号也被设置为 4。

最终结果如下:

  • • 桥 1 管理总线 1~4;
  • • 桥 2 管理总线 2;
  • • 桥 3 管理总线 3~4;
  • • 桥 4 管理总线 4。

这样,任何指向总线 1~4 的配置访问,都能被沿途桥接器正确判断、转发和转换。

十二、发现设备不代表资源已经够用

拓扑建立完成后,Linux 还要解决另一个现实问题:每个设备到底需要多少 PCI I/O 或 PCI 内存空间?

设备不会通过一句人类可读的话告诉内核:“请给我 64KB。”

它通过 BAR 回答这个问题。

用全 1 询问 BAR 的大小

经典 PCI 设备的 BAR 支持一种很巧妙的探测方法。

内核先保存 BAR 原值,然后向 BAR 写入全 1,再把它读回来。

设备不会简单返回刚刚写入的全部 1,而是会把自己不参与地址译码的低位清零。内核根据返回值中的位掩码,就能推导出该 BAR 所需的空间大小

BAR 最低位还可以帮助判断资源类型:

  • • 最低位表示这是 I/O BAR 时,设备请求 PCI I/O 空间;
  • • 最低位表示这是内存 BAR 时,设备请求 PCI 内存空间。

假设某个 BAR 探测后表明需要 0x100 字节,那么它不仅需要连续的 0x100 字节,起始地址通常也要按照 0x100 的边界自然对齐。

这套设计使单个 BAR 的大小通常表现为 2 的幂,并且能够通过掩码快速计算。

例如,DECChip 21142 快速以太网控制器可能报告自己需要 0x100 字节的 I/O 或内存区域。Linux 找到合适位置后,把起始地址写回 BAR。此后,该地址范围就对应设备的控制寄存器和状态寄存器。

探测 BAR 时必须格外小心。因为写入全 1 只是询问大小,完成后还要恢复或重新写入正式地址,不能让设备一直保留探测值

十三、资源分配像俄罗斯套娃:设备地址必须装进桥窗口

PCI I/O 和 PCI 内存空间并不是无限的。

Linux 不但要给每个设备分配地址,还要保证 桥后设备的地址全部落在上游桥的窗口中

假设一座桥后面有三块设备,它们分别需要三段内存。Linux 不能把这三段地址随意撒在整个 PCI 地址空间里,否则桥就需要建立多个零散窗口,而经典桥接器通常只提供有限的连续范围。

更理想的安排是:

  1. 1. 把同一座桥后面的设备资源尽量集中;
  2. 2. 计算覆盖这些资源的连续区间;
  3. 3. 把这段区间写进桥的基地址和限制寄存器;
  4. 4. 让桥只转发该区间。

此外,桥窗口还有自己的对齐要求。

通常情况下:

  • • PCI I/O 窗口通常按 4KB 边界对齐;
  • • PCI 内存窗口通常按 1MB 边界对齐。

资源分配不仅是“找空位”,还要同时满足设备 BAR 对齐、桥窗口对齐和父子包含关系。

这就像整理行李:

  • • 每个设备是一件物品;
  • • 每条子总线是一只箱子;
  • • 每座桥要求下游所有物品都装进这只箱子的连续空间;
  • • 上一级桥又要把整只箱子装进更大的箱子。

Linux 通常借助已经建立好的 pci_bus 和 pci_dev 树递归完成这项工作。

十四、经典资源分配算法怎样运行

从根总线开始,平台修正代码维护当前可用的 PCI I/O 和 PCI 内存基地址。

处理一条总线时,大致会执行以下步骤。

1. 先满足桥窗口的对齐要求

进入某条总线前,先把当前 I/O 基地址对齐到 4KB 边界,把当前内存基地址对齐到 1MB 边界。

这两个位置可以被看作当前子树资源区间的起点。

2. 为当前总线上的普通设备分配资源

内核检查设备的 BAR 需求,为每个 BAR 寻找满足大小和自然对齐要求的地址。

分配完成后,更新全局 I/O 或内存基地址,使其指向下一段空闲位置。

3. 打开设备访问能力

地址写入 BAR 后,内核可以设置配置头中的命令寄存器,允许设备响应 PCI I/O 或 PCI 内存访问。

设备这时才算真正拥有了可使用的“门牌号”。

4. 递归处理下游总线

如果当前总线上存在 PCI-PCI 桥,内核进入桥后的总线,继续为下游设备分配资源。

递归返回时,全局基地址已经移动到了整个下游子树资源之后。

5. 计算桥窗口终点

下游设备全部处理完后,再次按照 4KB 或 1MB 对齐当前基地址。

进入下游前记录的起点,加上递归结束后的终点,就构成这座桥需要覆盖的 I/O 和内存窗口。

6. 配置并启用桥接

Linux 把窗口起止地址写入 PCI-PCI 桥的配置寄存器,然后打开桥接器的 I/O 和内存转发功能。

此后,落在窗口中的上游请求会被送往下游,窗口之外的请求则不会通过。

这种算法的关键优点,是先完整分配一个下游分支,再确定覆盖整个分支的桥窗口。它与前面的深度优先总线扫描思路十分一致

十五、用一个具体例子看懂地址是怎样分下去的

继续使用开头的系统:

  • • 总线 0 上有视频设备;
  • • 总线 0 通过一座 PCI-PCI 桥连接总线 1;
  • • 总线 1 上有以太网设备和 SCSI 设备;
  • • 系统还需要为 ISA 兼容访问保留低地址区域。

下面是一种经典分配过程。

起点:避开 ISA 保留区域

系统把可分配的 PCI I/O 基地址设为:

0x4000

把可分配的 PCI 内存基地址设为:

0x100000

低于这些位置的地址可以继续留给 PCI-ISA 桥转换成传统 ISA 访问。

不过,设备资源还必须按照自身大小自然对齐,真正使用的起始地址可能继续向上调整。

视频设备:先占用较大的内存区域

假设视频设备请求 0x200000 字节 PCI 内存。

当前内存基地址是 0x100000,但 0x200000 大小的资源通常应按照 0x200000 对齐,起始位置调整到:

0x200000

视频设备获得:

0x200000` ~ `0x3FFFFF

分配后,下一段可用 PCI 内存基地址变为:

0x400000

PCI I/O 基地址仍然是:

0x4000

穿过桥,处理下游设备

接下来进入 PCI-PCI 桥后的总线 1。

因为当前 I/O 基地址 0x4000 已经位于 4KB 边界,内存基地址 0x400000 也位于 1MB 边界,所以可以直接把它们作为下游窗口的起点。

假设以太网设备的若干资源合计占用约 0xB0 字节 I/O 空间和 0xB0 字节内存空间。

它的 I/O 资源从:

0x4000

开始分配,分配后 I/O 游标移动到:

0x40B0

它的内存资源从:

0x400000

开始分配,分配后内存游标移动到:

0x4000B0

实际处理单个 BAR 时,仍然需要分别满足每个 BAR 的大小和对齐要求。

SCSI 设备:先对齐,再分配

假设 SCSI 控制器请求 0x1000 字节 PCI 内存。

当前内存游标是 0x4000B0,并未位于 0x1000 边界,需要向上对齐到:

0x401000

SCSI 设备获得:

0x401000` ~ `0x401FFF

分配完成后,内存游标移动到:

0x402000

I/O 游标仍是:

0x40B0

回到桥上,生成转发窗口

总线 1 上的设备已经分配完成。

桥下游实际使用的 I/O 范围从 0x4000 开始,到 0x40B0 附近结束;内存范围从 0x400000 开始,到 0x402000 附近结束。

Linux 根据桥寄存器的粒度和对齐要求,对窗口终点进行适当上调,然后把结果写入桥。

概念上,这座桥的窗口覆盖:

  • • PCI I/O:从 0x4000 开始,包含下游网卡所需区域;
  • • PCI 内存:从 0x400000 开始,覆盖以太网设备和 SCSI 设备。

这样,访问视频设备的 0x200000 地址区间不会通过桥,而访问 0x400000 或 0x401000 一带的请求则会被转发到总线 1。

桥不需要知道访问最终属于网卡还是 SCSI 控制器。它只负责把属于下游地址窗口的请求送过去,具体由下游总线上的设备继续完成地址匹配

十六、为什么不同平台上的工作量不一样

在经典 Intel PC 上,系统 BIOS 往往已经在 Linux 启动前完成了相当一部分 PCI 配置。

它可能已经:

  • • 给总线编号;
  • • 为 BAR 分配地址;
  • • 设置桥窗口;
  • • 安排中断路由;
  • • 打开必要的设备访问权限。

Linux 启动后,可以读取这些结果并建立自己的设备模型。只要固件配置合理,就没有必要把所有内容推倒重来。

Alpha AXP 等非传统 PC 平台的情况可能不同。

平台固件不一定提供相同的 BIOS 服务,或者只完成了部分配置。Linux 的平台代码需要承担更多责任,包括:

  • • 查询每个设备的 BAR 大小;
  • • 分配 PCI I/O 和内存资源;
  • • 配置桥接器窗口;
  • • 生成中断线信息;
  • • 修复特定芯片组或主板的异常行为。

所以,所谓 PCI BIOS 层并不一定意味着机器里真的存在一套与 PC 完全相同的 BIOS。更准确地说,它代表一组统一的 PCI 配置访问和管理接口

对上层扫描代码而言,无论底层是 Intel BIOS、Alpha 支持芯片组还是其他平台机制,最终都应该能够完成相同的基本操作:

  • • 读取配置字节、字和双字;
  • • 写入配置寄存器;
  • • 查找设备;
  • • 控制 PCI 地址空间访问。

设备驱动程序也因此不必为每种处理器平台重新理解整套 PCI 配置机制。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-08-21 22:33:07 HTTP/2.0 GET : https://f.mffb.com.cn/a/505283.html
  2. 运行时间 : 0.484292s [ 吞吐率:2.06req/s ] 内存消耗:5,036.30kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=f7a9c1e1c831be6bb8bb5b08294089f2
  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.000938s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001359s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.066376s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000822s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001494s ]
  6. SELECT * FROM `set` [ RunTime:0.000538s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001438s ]
  8. SELECT * FROM `article` WHERE `id` = 505283 LIMIT 1 [ RunTime:0.054774s ]
  9. UPDATE `article` SET `lasttime` = 1787322787 WHERE `id` = 505283 [ RunTime:0.076381s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.013176s ]
  11. SELECT * FROM `article` WHERE `id` < 505283 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.007368s ]
  12. SELECT * FROM `article` WHERE `id` > 505283 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.007744s ]
  13. SELECT * FROM `article` WHERE `id` < 505283 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.053136s ]
  14. SELECT * FROM `article` WHERE `id` < 505283 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.002035s ]
  15. SELECT * FROM `article` WHERE `id` < 505283 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.005270s ]
0.490563s