ARM GICv3 学习笔记(一)

本文是 ARM GICv3 学习笔记系列的第一篇,系统梳理 GICv3 的中断类型、硬件架构、状态机模型、亲和性路由、安全模型以及中断处理流程。内容基于 ARM 官方文档《Learn the architecture - Generic Interrupt Controller v3 and v4, Overview》《Arm Generic Interrupt Controller Architecture Specification》以及《GICv3 and GICv4 Software Overview》整理,侧重于建立 GICv3 的整体认知框架。

1、中断类型与 INTID

GIC(Generic Interrupt Controller)是 ARM 平台上的通用中断控制器,负责管理系统中所有中断的优先级、分发和路由。GICv3 支持四种中断类型,按 INTID(Interrupt ID)范围划分:

INTID 范围 中断类型 说明
0--15 SGI(Software Generated Interrupt) 软件生成中断,用于处理器间通信(IPI),通过写 GIC 的 SGI 寄存器产生
16--31 PPI(Private Peripheral Interrupt) 私有外设中断,仅属于单个核心,例如 Generic Timer 中断
32--1019 SPI(Shared Peripheral Interrupt) 共享外设中断,可路由到任意已连接的核心
1020--8191 保留 ---
8192-- LPI(Locality-specific Peripheral Interrupt) GICv3 新增,基于 ITS(Interrupt Translation Service)和内存表,编程模型与上述三种截然不同


Learn the architecture - Generic Interrupt Controller v3 and v4, Overview

2、硬件连接方式:专用信号线与 MSI

传统中断控制器通过专用硬件信号线从外设连接到中断控制器:

GICv3 在此基础上增加了**消息信号中断(MSI, Message-Signaled Interrupts)**机制:外设通过向中断控制器的寄存器地址发起写操作来触发中断,无需专用物理信号线。

对大型 SoC 而言,MSI 消除了为数百个中断源逐一布设物理信号线的需求,显著简化了后端设计。从软件视角看,无论是专用信号线还是 MSI,中断处理流程基本一致------差异仅在于外设侧的配置方式(例如需要指定中断控制器的地址)。

在 GICv3 中,SPI 可以配置为 MSI,而 LPI 始终是 MSI。不同中断类型的寄存器使用方式如下:

3、中断状态机

3.1 四种基本状态

GIC 为每个 SPI、PPI 和 SGI 维护一个状态机,包含四种状态:

状态 含义
Inactive 中断源未触发
Pending 中断源已触发,但尚未被 PE(Processing Element,即 CPU 核心)确认
Active PE 已通过读取 ICC_IAR1_EL1 确认该中断
Active and Pending 当前中断实例处于 Active,同时外设又产生了新的中断请求


Learn the architecture - Generic Interrupt Controller v3 and v4, Overview

3.2 电平触发下的状态转换

中断的触发方式(电平/边沿)决定了状态转换路径的差异。

对于 电平敏感(Level-sensitive) 中断,外设拉高中断线后信号会持续保持有效,直到软件清除外设的中断源:

  1. Inactive → Pending:当中断源被 assert 时,中断从 Inactive 转换为 Pending。此时,如果该中断已使能且优先级足够高,GIC 会向处理器单元 (PE) assert(拉高)中断信号。
  2. Pending → Active and Pending:当 PE 读取中断确认寄存器 (IAR) 确认中断时,状态本应转为 Active。但由于是电平触发,且外设信号仍然保持 assert(高电平),GIC 检测到输入端依然有效,因此状态立即变为(或保持在) Active and Pending。此时 GIC 会暂时撤销发给 Core 的信号(图中第二个波形中间的凹陷)。
  3. Active and Pending → Active :软件在中断处理过程中,清除了外设的中断源,导致外设撤销(de-asserts)了中断信号。此时 GIC 检测到输入变低,状态从 Active and Pending 跌落为单纯的 Active。
  4. Active → Inactive:软件中断处理结束,PE 向中断结束寄存器 (EOIR) 写入。由于此时外设信号已经撤销(处于非挂起状态),GIC 将状态从 Active 转换为 Inactive,完成整个生命周期。

3.3 边沿触发下的状态转换

对于**边沿敏感(Edge-sensitive)**中断,外设发送的是一个脉冲,不会持续保持有效电平:

  1. Inactive → Pending:当外设发送一个上升沿脉冲时,GIC 捕获到这个边沿,中断从 Inactive 转换为 Pending。GIC 随即向处理器单元 (PE) 发送中断信号。
  2. Pending → Active:当 PE 读取中断确认寄存器 (IAR) 确认中断时,状态从 Pending 转换为 Active。此时 GIC 会撤销发给 PE 的中断信号(拉低),告诉 PE "你可以开始干活了"。
  3. Active → Active and Pending:在 PE 还在处理(状态仍为 Active)的时候,外设又发送了第二个脉冲(上升沿)。GIC 再次捕获到这个边沿,因为当前状态已经是 Active,所以它标记一个新的挂起,状态变为 Active and Pending。
  4. Active and Pending → Pending:当 PE 处理完第一次中断,向中断结束寄存器 (EOIR) 写入时,GIC 认为当前的 Active 实例结束了。但由于刚才捕获了第二个脉冲(处于 Pending 状态),所以状态机从 A&P 回落到 Pending。此时,GIC 会再次向 PE 发送中断信号,通知还有第二次中断需要处理。

4、中断亲和性

4.1 MPIDR_EL1:多核拓扑标识

在多核 ARM 系统中,每个 PE 通过 MPIDR_EL1(Multiprocessor Affinity Register)获得唯一硬件标识。该寄存器使用四个层级字段描述 PE 在拓扑中的位置:

复制代码
<Aff3>.<Aff2>.<Aff1>.<Aff0>



ARM Architecture Reference Manual ARMv8, for ARMv8-A architecture profile

不同微架构对这四个字段的使用方式有所差异。以 Cortex-A57 为例:

  • Aff3 不支持;
  • Aff2 + Aff1 组合标识 Cluster;
  • Aff0 的低 2 位标识 Cluster 内的 Core ID(单簇最多 4 核心)。

ARM® Cortex®-A57 MPCore™ Processor Revision: r1p1 Technical Reference Manual

以 cortex-A55 为例:

  • Aff0:标识同一核心内的线程 ID(SMT);
  • Aff1:标识 Cluster 内的 CPU Core;
  • Aff2 + Aff3 组合标识 Cluster。



ARM® Cortex®-A55 Core Revision: r1p0 Technical Reference Manual

关键认知MPIDR_EL1 提供了统一的寻址格式,但具体的字段有效位宽和含义取决于微架构实现。配置 GIC 中断路由时,必须确认目标平台的 MPIDR 编码方式。

4.2 GICD_IROUTER:SPI 路由寄存器

GICv3 的中断亲和性建立在 MPIDR_EL1 的拓扑抽象之上。对于每个 SPI,GIC 分配器都有一个对应的 GICD_IROUTER 寄存器(64 位),用于指定该 SPI 的目标 PE。


Arm® Generic Interrupt Controller Architecture Specification GIC architecture version 3 and version 4

字段说明:

字段 含义
Aff3--Aff0 路由目标 PE 的亲和值,直接映射到 MPIDR_EL1 的对应层级
Interrupt_Routing_Mode(bit 31) 0:精确路由到 Aff3--Aff0 指定的唯一核心;1:由 GIC 从当前参与中断分发的核心中任选一个

中断亲和性路由仅适用于 SPI。PPI 是每个核心私有的,无需路由;SGI 通过 SGI 寄存器中的目标字段指定接收方;LPI 的路由由 ITS 管理。

5. 安全模型与中断分组

GICv3 与 ARM TrustZone 深度集成。软件必须为每个 INTID 分配一个组(Group),该组决定了中断的安全属性:

安全状态 信号方式
Group 0 Secure 始终以 FIQ 发出
Secure Group 1 Secure IRQ 发出(当前为 Secure 状态时)
Non-secure Group 1 Non-secure IRQ 发出(当前为 Non-secure 状态时)

Group 1 中断的具体信号类型(IRQ 还是 FIQ)取决于当前 PE 的安全状态和异常等级:

关键 :IRQ 和 FIQ 是 CPU Interface 与 PE 之间的物理信号线。由 CPU Interface 根据中断的 Group 属性及 PE 当前的安全状态,决定通过哪条信号线向 PE 发出通知。

只有运行在 Secure 状态下的软件才有权分配 INTID 到各个 Group。Non-secure 状态下是否允许访问安全中断的配置/状态,可通过 GICD_NSACRnGICR_NSACR 寄存器逐 INTID 控制。

5.2 双重安全状态与单一安全状态

TrustZone 是可选特性。GICD_CTLR.DS 位控制 GIC 的安全状态模式:

  • DS == 0:支持双重安全状态(Secure + Non-secure),三种中断组全部可用。
  • DS == 1:仅单一安全状态,只支持 Group 0(FIQ)和 Group 1(IRQ):


6. 中断异常等级路由

在 ARMv8 安全架构中,物理 IRQ 和 FIQ 的异常等级路由由 EL3 的 SCR_EL3 寄存器中两个关键位控制,这是中断进入安全世界的"总开关"。

FIQ 路由控制:

  • FIQ == 0:EL3 以下产生的物理 FIQ 不进 EL3,由当前异常等级处理。
  • FIQ == 1:所有 FIQ 强制路由到 EL3。

IRQ 路由控制:

  • IRQ == 0:EL3 以下(EL0/EL1/EL2)产生的物理 IRQ 不进 EL3;即使当前在 EL3,也不接收物理 IRQ。
  • IRQ == 1:所有物理 IRQ 强制路由到 EL3。

将安全模型(第 5 节)与异常等级路由结合来看,典型的配置是:IRQ 路由到 EL1 处理当前安全状态的 Group 1 中断,FIQ 路由到 EL3 处理跨安全状态的中断转发(Secure Monitor 执行上下文切换)。

下图展示了当前执行于 EL0、IRQ 路由到 EL1 且 FIQ 路由到 EL3 时的处理流程:

7. GICv3 架构组件

GICv3 的寄存器接口分为三个层次:

  • 分发器(Distributor)接口
  • 重分发器(Redistributor)接口
  • CPU 接口(CPU interface)

这些接口的关系如下图所示:


Learn the architecture - Generic Interrupt Controller v3 and v4, Overview

7.1 Distributor(分发器)

内存映射寄存器,对系统中所有核心共享,主要负责 SPI 的全局配置:

  • SPI 的使能、禁用与优先级设置
  • 为每个 SPI 配置路由信息(GICD_IROUTER
  • 将每个 SPI 设置为电平敏感或边沿触发
  • 生成消息信号中断(Message-signaled SPIs)
  • 控制 SPI 的激活(Active)和挂起(Pending)状态
  • 确定每种安全状态(Security state)下使用的编程模型:亲和性路由(Affinity routing)或传统模型(Legacy)。

7.2 Redistributor(重分发器)

每个 PE 私有一组 Redistributor 寄存器,负责该核心的本地中断管理:

  • SGI 和 PPI 的使能、禁用与优先级设置
  • PPI 的触发方式配置
  • SGI 和 PPI 的中断组分配
  • 控制 SGI 和 PPI 的状态
  • 配置 LPI 的 pending 表和配置表基地址
  • 为已连接的 PE 提供电源管理支持

SGI 的生成由本地 PE 写系统寄存器发起,但跨核转发本质上依赖 Distributor 的全局仲裁------Distributor 根据写入的亲和性路由信息,将 SGI 分发到目标 PE 对应的 Redistributor,再由 Redistributor 提交给目标 CPU Interface。

7.3 CPU Interface(CPU 接口)

每个 PE 内部的一组系统寄存器ICC_*_ELn),通过 MRS/MSR 指令访问:

  • 通用中断控制与使能配置
  • 中断确认(Acknowledge)
  • 优先级降级(Priority Drop)与停用(Deactivation)
  • 设置 PE 的中断优先级掩码
  • 定义抢占策略
  • 查询当前最高优先级的 Pending 中断

使用 CPU Interface 寄存器之前,必须通过 ICC_SRE_ELn.SRE 位启用系统寄存器接口:



Arm® Generic Interrupt Controller Architecture Specification GIC architecture version 3 and version 4

8、中断处理流程与 Priority 机制

8.1 完整处理流程

一个物理中断在 GIC 中的生命周期包含六个阶段:


Arm® Generic Interrupt Controller Architecture Specification GIC architecture version 3 and version 4

  1. Generate interrupt

    interrupt 可以由 peripheral(外设)触发,也可以由 software(软件)主动生成。

  2. Distribute

    IRI(Interrupt Routing Infrastructure)负责进行 interrupt grouping(中断分组)、interrupt prioritization(中断优先级仲裁),并控制将 interrupt forwarding(中断转发)到各个 CPU interface。

  3. Deliver

    physical CPU interface 会将 interrupt deliver 给对应的 PE(Processing Element,处理单元/CPU 核)。

  4. Activate

    当运行在 PE 上的软件对某个 interrupt 执行 acknowledge 后(读取 IAR),GIC 会将 Highest Active Priority 更新为该 interrupt 的优先级。

    对于 SPI、SGI 和 PPI 类型的 interrupt,此时该 interrupt 会进入 Active 状态。

  5. Priority drop

    运行在 PE 上的软件通知 GIC:当前最高优先级 interrupt 已经被处理到允许降低 running priority 的阶段。

    随后,running priority 会恢复为该 interrupt 被 acknowledge 之前的值。

    这一阶段通常表示 interrupt handler 已经执行完 "EOI(End Of Interrupt)" 的语义。

  6. Deactivation

    Deactivation 会清除 interrupt 的 Active state,从而使该 interrupt 在再次 pending 时,能够重新被 CPU 接收和处理。

    对于 LPI(Locality-specific Peripheral Interrupt),不要求执行 deactivation。

8.2 Priority 概念辨析

GIC 中存在多个容易混淆的优先级概念:

名称 含义
interrupt priority 中断本身的优先级(寄存器中配置的静态值)
highest pending priority 当前所有 Pending 中断中的最高优先级
active priority 当前 Active 中断的优先级
running priority CPU 当前的抢占门槛(Preemption Threshold)

其中最关键的是 Running Priority ------它不表示"CPU 当前运行什么中断",而是定义哪些中断可以抢占当前执行。GIC 中优先级数值越小表示优先级越高。

举例:CPU 正在处理优先级 0x40 的中断------优先级 0x10 的中断可以抢占,优先级 0x80 的中断则只能保持 Pending。

8.3 Priority Drop 与 Deactivation 分离

传统中断控制器中,EOI 同时完成"降低优先级"和"结束中断"两个动作。GICv3 将它们拆分为两个独立阶段:

阶段 作用
Priority Drop 降低 Running Priority,允许其他中断进入
Deactivation 清除 Active 状态,结束当前中断实例

分离设计的优势:

  • 更早恢复中断响应能力(Priority Drop 后即可响应更高优先级中断);
  • 避免低优先级中断被长时间阻塞;
  • 同时防止同一中断重复进入(Deactivation 前该中断仍视为 Active)。

8.4 EOImode

Priority Drop 与 Deactivation 是否同时发生,由 ICC_CTLR_EL1.EOImode 控制:


模式 ICC_EOIR1_EL1 的效果 额外操作
EOImode = 0(默认) 同时完成 Priority Drop + Deactivation 无需
EOImode = 1(Split EOI) 仅执行 Priority Drop 需显式写 ICC_DIR_EL1 完成 Deactivation

Split EOI 模式下,写 EOIR 后 Running Priority 恢复,CPU 可以立即响应其他中断,但当前中断仍保持 Active 状态------这也是 Pending + Active 状态产生的核心场景之一。


8.5 Pending + Active 状态的设计价值

Split EOI 模式下,Pending + Active 状态解决了一个关键问题:

以 UART 电平触发中断为例:

  1. CPU 已确认(Acknowledge)该中断,进入 Active 状态;
  2. 软件执行 Priority Drop(写 EOIR),恢复 Running Priority;
  3. 设备侧中断线仍保持有效(外设尚未清除中断源)。

此时外设信号持续有效,中断可能再次进入 Pending。但由于该中断仍处于 Active,GIC 不会再次激活同一个中断实例,而是进入 Pending + Active 状态。

这一机制的核心价值是:

允许其他中断继续响应(高优先级抢占),同时避免当前中断处理函数递归重入。

这也是 ARM GIC 将中断抢占与中断完成解耦的设计思想所在。

9. SGI 的发送与接收

9.1 SGI 寄存器

SGI 通过写 CPU Interface 中的系统寄存器生成。GICv3 提供三个 SGI 寄存器,分别对应不同的安全属性:

寄存器 用途 访问条件
ICC_SGI0R_EL1 生成 Group 0 中断(最高优先级 Secure 任务) Secure 状态
ICC_SGI1R_EL1 生成 Group 1 中断,目标为当前安全状态 Secure 或 Non-secure
ICC_ASGI1R_EL1 生成 Group 1 中断,目标为对侧安全状态 仅 Secure 状态(通常 EL3)

ICC_SGI1R_EL1 的行为取决于写寄存器时 PE 的安全状态:

  • 当前在 Secure 世界 → 发送的是 Secure Group 1 中断(SGI)
  • 当前在 Non-secure 世界 → 发送的是 Non-secure Group 1 中断(NSGI)

ICC_ASGI1R_EL1 用于 Secure 世界主动向 Non-secure 世界发送中断。

9.2 目标路由控制

SGI 寄存器中的 IRM(Interrupt Routing Mode)字段决定路由策略:

模式一:精确投递(IRM = 0)

中断发送到 <Aff3>.<Aff2>.<Aff1>.<Target List> 指定的核心。其中 <Target List> 是一个位图(bitmap),每一位对应 <Aff1> 层级下的一个核心(实际上替代了 Aff0 的作用)。一次 SGI 最多可同时发送给 16 个 PE,且可以包含发起者自身。

模式二:广播(IRM = 1)

中断发送给系统中所有已连接的核心,但排除发起者自身。适用于需要通知全局但无需自扰的场景。

9.3 安全状态与分组的转发规则

SGI 的安全属性和分组由三个因素共同决定:

  1. 发起方 PE 的安全状态
  2. 写入的 SGI 寄存器(SGI0R / SGI1R / ASGI1R)
  3. 目标 PE 的本地配置GICR_IGROUPR0GICR_IGRPMODR0

GIC 在转发前会综合检查上述条件。目标 PE 的 GICR_IGROUPR0GICR_IGRPMODR0 配置必须与中断实际携带的 Group 属性一致,否则不予转发。


注:此表假设 GICD_CTLR.DS == 0。当 GICD_CTLR.DS == 1,标记为(*)的 SGI 也被转发。

10. 关键寄存器速查

10.1 Distributor

Distributor 寄存器为内存映射(Memory-mapped),对系统所有核心全局可见,主要负责 SPI 的配置与分发。关键寄存器如下:

寄存器 功能
GICD_CTLR 全局控制:使能 Group 0/1、亲和性路由、安全状态模式(DS)、ARE 等
GICD_TYPER 类型信息:系统支持的 SPI 数量、LPI 是否支持、ITS 数量等
GICD_IIDR 实现者标识:产品 ID 与版本号
GICD_IGROUPRn/GICD_IGRPMODRn 中断分组:为每个 INTID 分配 Secure Group 0/Non-secure Group 1/Secure Group 1
GICD_ISENABLERn 中断使能(Set):置位对应 bit 使能该 SPI
GICD_ICENABLERn 中断使能(Clear):置位对应 bit 禁用该 SPI
GICD_ISPENDRn / GICD_ICPENDRn Pending 状态控制(Set/Clear):手动置位或清除 SPI 的 Pending 状态
GICD_ISACTIVERn / GICD_ICACTIVERn Active 状态控制(Set/Clear):手动置位或清除 SPI 的 Active 状态
GICD_IPRIORITYRn 优先级配置:为每个 SPI 设置 8-bit 优先级值
GICD_ICFGRn 触发方式配置:将每个 SPI 设置为电平敏感或边沿触发
GICD_IROUTERn 中断路由:为每个 SPI 指定目标 PE 的亲和性地址(对应 MPIDR_EL1)及路由模式
GICD_NSACRn 非安全态访问控制:控制 Non-secure 状态下能否访问各 INTID 的安全中断配置
GICD_SGIR 传统 SGI 生成(Legacy 模式下使用)



10.2 Redistributors

Redistributor 寄存器为每个 PE 私有(内存映射),负责该核心的 SGI/PPI 管理及 LPI 基地址配置。关键寄存器如下:

寄存器 功能
GICR_CTLR Redistributor 控制:使能当前 PE 的中断转发、电源管理等
GICR_TYPER 类型信息:当前 PE 的亲和性值、LPI 支持情况
GICR_WAKER 唤醒控制:控制 Redistributor 的睡眠/唤醒状态转换
GICR_IGROUPR0 中断分组:为当前 PE 的 SGI/PPI 分配 Group 0 或 Group 1
GICR_IGRPMODR0 Group 1 安全属性:为当前 PE 的每个 Group 1 INTID 指定 Secure 或 Non-secure
GICR_ISENABLER0 / GICR_ICENABLER0 中断使能(Set/Clear):使能或禁用当前 PE 的 SGI/PPI
GICR_ISPENDR0 / GICR_ICPENDR0 Pending 状态控制(Set/Clear):手动管理 SGI/PPI 的 Pending 状态
GICR_ISACTIVER0 / GICR_ICACTIVER0 Active 状态控制(Set/Clear):手动管理 SGI/PPI 的 Active 状态
GICR_IPRIORITYRn 优先级配置:为 SGI/PPI 设置优先级
GICR_ICFGR0 / GICR_ICFGR1 触发方式配置:将 PPI 设置为电平敏感或边沿触发(SGI 固定为边沿)
GICR_NSACR 非安全态访问控制:控制 Non-secure 软件能否生成 Secure SGI
GICR_PROPBASER LPI 配置表基地址:指向内存中 LPI 属性表的物理地址
GICR_PENDBASER LPI Pending 表基地址:指向内存中 LPI Pending 状态表的物理地址

GICR_IGROUPR0:该寄存器用于划分当前 PE 上每个 INTID 的中断组别(是属于 Group 0 还是 Group 1)



GICR_IGRPMODR0:该寄存器用于界定属于 Group 1 的每个 INTID 的安全状态(是属于 Secure 还是 Non-secure)


10.3 CPU Interface

CPU Interface 寄存器以系统寄存器形式(ICC_*_ELn)访问,通过 MRS/MSR 指令读写。关键寄存器如下:

寄存器 功能
ICC_SRE_ELn 系统寄存器接口使能:控制 CPU Interface 是否通过系统寄存器访问(SRE 位)
ICC_CTLR_EL1 CPU Interface 控制:含 EOImode、优先级丢弃模式等全局配置
ICC_PMR_EL1 优先级掩码:屏蔽优先级低于设定值的中断,实现中断屏蔽与抢占控制
ICC_IAR1_EL1 中断确认:读取当前最高优先级 Pending 中断的 INTID,同时使该中断进入 Active 状态
ICC_EOIR1_EL1 中断结束:执行 Priority Drop / Deactivation(具体行为取决于 EOImode)
ICC_DIR_EL1 中断停用:在 Split EOI 模式下显式清除 Active 状态(Deactivation)
ICC_RPR_EL1 Running Priority:只读,反映当前 CPU 的抢占门槛
ICC_HPPIR1_EL1 最高 Pending 优先级:只读,查询当前最高优先级 Pending 中断的 INTID
ICC_SGI0R_EL1 SGI 生成(Group 0):生成 Secure Group 0 中断,仅 Secure 态可用
ICC_SGI1R_EL1 SGI 生成(Group 1, 当前安全态):生成 Group 1 中断,目标为当前安全状态
ICC_ASGI1R_EL1 SGI 生成(Group 1, 对侧安全态):生成 Group 1 中断,目标为对侧安全状态,仅 EL3 可用

参考

  1. Learn the architecture - Generic Interrupt Controller v3 and v4, Overview Version 3.2
  2. Arm Generic Interrupt Controller Architecture Specification --- GIC architecture version 3 and version 4
  3. GICv3 and GICv4 Software Overview
相关推荐
YangYang9YangYan1 小时前
产品经理学习数据分析的价值与路径
学习·数据分析·产品经理
哩哩橙1 小时前
分支电路对限时电流速断保护的影响
人工智能·笔记·数据挖掘
東隅已逝,桑榆非晚1 小时前
深⼊理解指针(5)
c语言·笔记·算法
星夜夏空991 小时前
STM32单片机学习(13) —— 串口通信协议
stm32·单片机·学习
祁白_1 小时前
跨平台通用危险函数深度解析
linux·windows·笔记·安全·系统命令
柿柿快乐1 小时前
用户认证系统实现文档
linux·服务器·网络·学习·基础教学
The Chosen One9851 小时前
分享对dp题目的理解-不断更新ing
笔记·算法·深度优先·动态规划·dp
Chloeis Syntax1 小时前
JavaEE学习日记(2)---文件操作和IO
java·笔记·学习·java-ee
南境十里·墨染春水1 小时前
linux学习进展 Redis详解
linux·redis·学习