【Linux系统编程】(二十二)从磁盘物理结构到地址映射:Ext 系列文件系统硬件底层原理深度剖析


目录

前言

一、认识文件系统的硬件基础:从机房到磁盘

[1.1 机房、机柜、服务器与磁盘的层级关系](#1.1 机房、机柜、服务器与磁盘的层级关系)

[1.2 磁盘物理结构:机械硬盘的 "五脏六腑"](#1.2 磁盘物理结构:机械硬盘的 “五脏六腑”)

[1.3 磁盘存储结构:磁道、柱面与扇区的三维布局](#1.3 磁盘存储结构:磁道、柱面与扇区的三维布局)

[1.3.1 磁道(Track)](#1.3.1 磁道(Track))

[1.3.2 扇区(Sector)](#1.3.2 扇区(Sector))

[1.3.3 柱面(Cylinder)](#1.3.3 柱面(Cylinder))

[1.3.4 磁盘容量的计算方式](#1.3.4 磁盘容量的计算方式)

二、磁盘的逻辑结构:从三维物理空间到一维线性地址

[2.1 逻辑结构的核心思想:把磁盘 "拉直" 成磁带](#2.1 逻辑结构的核心思想:把磁盘 “拉直” 成磁带)

[2.2 磁盘逻辑结构的真实映射](#2.2 磁盘逻辑结构的真实映射)

[2.3 逻辑结构的优势](#2.3 逻辑结构的优势)

[三、CHS 与 LBA 地址:磁盘寻址的两种方式](#三、CHS 与 LBA 地址:磁盘寻址的两种方式)

[3.1 CHS 寻址:基于物理结构的传统寻址方式](#3.1 CHS 寻址:基于物理结构的传统寻址方式)

[3.1.1 CHS 寻址的工作原理](#3.1.1 CHS 寻址的工作原理)

[3.1.2 CHS 寻址的局限性](#3.1.2 CHS 寻址的局限性)

[3.2 LBA 寻址:基于逻辑结构的现代寻址方式](#3.2 LBA 寻址:基于逻辑结构的现代寻址方式)

[3.2.1 LBA 寻址的工作原理](#3.2.1 LBA 寻址的工作原理)

[3.2.2 LBA 寻址的优势](#3.2.2 LBA 寻址的优势)

[3.3 CHS 与 LBA 地址的相互转换](#3.3 CHS 与 LBA 地址的相互转换)

[3.3.1 转换前的准备参数](#3.3.1 转换前的准备参数)

[3.3.2 CHS 转换为 LBA](#3.3.2 CHS 转换为 LBA)

[3.3.3 LBA 转换为 CHS](#3.3.3 LBA 转换为 CHS)

[3.3.4 转换的实际应用场景](#3.3.4 转换的实际应用场景)

[3.4 实战:用 bash 命令查看磁盘的 CHS 和 LBA 信息](#3.4 实战:用 bash 命令查看磁盘的 CHS 和 LBA 信息)

[3.4.1 查看磁盘的基本信息](#3.4.1 查看磁盘的基本信息)

[3.4.2 计算磁盘的 CHS 参数](#3.4.2 计算磁盘的 CHS 参数)

[3.4.3 验证分区的 LBA 地址](#3.4.3 验证分区的 LBA 地址)

[四、硬件底层与 Ext 文件系统的关联](#四、硬件底层与 Ext 文件系统的关联)

总结


前言

在 Linux 系统中,Ext 系列文件系统(Ext2/Ext3/Ext4)无疑是最核心的存储基石。我们每天用touch创建文件、用cp复制数据、用rm删除内容,却很少思考这些操作背后的硬件底层是如何工作的。文件数据是如何在机械磁盘中存储的?磁头、磁道、柱面这些硬件概念和文件系统有什么关联?CHS 和 LBA 地址又是如何实现数据精准定位的?今天这篇文章,我们就从硬件底层出发,一步步揭开 Ext 系列文件系统的硬件工作原理,带大家走进磁盘存储的微观世界。下面就让我们正式开始吧!


一、认识文件系统的硬件基础:从机房到磁盘

要理解 Ext 系列文件系统,首先得搞清楚它赖以生存的硬件环境。从宏观的机房到微观的磁盘扇区,每一层硬件都在为文件存储提供支撑。

1.1 机房、机柜、服务器与磁盘的层级关系

在互联网架构中,存储数据的硬件设备有着清晰的层级结构。最顶层是机房,这里是所有硬件设备的 "家",配备了恒温、恒湿、防静电、防雷击等专业设施,确保设备稳定运行。机房里整齐排列着一个个机柜,机柜就像 "货架",承载着服务器、交换机、存储阵列等核心设备。

服务器是数据处理和存储的核心单元,而我们今天的主角 ------磁盘 ,就是服务器的重要外设。与 CPU、内存等高速电子设备不同,机械磁盘是计算机中唯一的机械设备,这也决定了它 "容量大、价格便宜但速度慢" 的特性。我们平时存储的文件、数据库数据、日志等,最终都会落脚到磁盘这个物理载体上。

1.2 磁盘物理结构:机械硬盘的 "五脏六腑"

如果把磁盘拆开,我们会发现它的内部结构并不复杂,主要由盘片、磁头、磁头臂、主轴、永磁铁等部件组成,就像一个精密的 "机械玩具"。

  • 盘片(Platter):这是磁盘存储数据的核心载体,类似我们日常用的光盘,表面涂有一层磁性材料,数据就是通过改变磁性材料的极性来存储的。一个磁盘通常会有多个盘片,叠放在一起,就像一叠 CD 光盘。
  • 磁头(Head):负责读取和写入盘片上的数据,相当于我们写字的 "笔"。每个盘片的上下两面都对应一个磁头,也就是说,一个有 3 个盘片的磁盘会有 6 个磁头。磁头非常精密,工作时会悬浮在盘片表面的气垫上,距离盘片仅有几纳米,几乎快要接触到盘片但又不会碰到,这也是为什么磁盘工作时不能剧烈晃动的原因。
  • 磁头臂(Actuator Arm):磁头被固定在磁头臂的末端,磁头臂可以带动磁头在盘片的半径方向上移动,从而让磁头能够访问盘片上不同位置的数据。
  • 主轴(Spindle):所有盘片都固定在主轴上,主轴会以恒定的转速旋转(常见转速有 7200 转 / 分、15000 转 / 分),带动盘片一起转动,让磁头能够连续访问盘片上的不同扇区。

这些部件协同工作,就构成了机械磁盘的物理基础。数据的读写过程,本质上就是磁头在旋转的盘片上移动、定位并进行磁性操作的过程。

1.3 磁盘存储结构:磁道、柱面与扇区的三维布局

了解了磁盘的物理部件后,我们再来看数据在磁盘上的存储布局。从物理层面看,数据被存储在盘片的磁性涂层上,其存储结构可以分为磁道、柱面和扇区三个关键概念,三者构成了一个三维的存储地址空间。

1.3.1 磁道(Track)

当盘片高速旋转时,磁头在盘片表面划出的圆形轨迹就是磁道。我们可以把磁道想象成盘片上的一个个同心圆,从盘片的外圈到内圈,磁道被依次编号为 0 磁道、1 磁道、2 磁道...... 需要注意的是,靠近主轴的最内圈磁道通常不存储数据,而是用于磁头的停靠和校准。

每个磁道的宽度非常窄,一盘磁盘的盘片上通常会有数千个磁道。由于磁道是圆形的,外圈磁道的周长比内圈磁道长,但它们存储的数据量却是相同的,这就导致外圈磁道的存储密度比内圈磁道低,这也是机械磁盘存储效率的一个小遗憾。

1.3.2 扇区(Sector)

为了方便数据的读写和管理,每个磁道又被划分成了多个相等的扇形区域,这就是扇区。扇区是磁盘存储数据的最小物理单位,每个扇区的大小固定为 512 字节(这是行业标准,后续虽然出现了 4KB 扇区的磁盘,但 512 字节扇区的兼容性仍被广泛支持)。

扇区的编号从 1 开始(注意不是从 0 开始),每个磁道上的扇区数量通常是相同的,比如 63 个。这样一来,每个扇区就可以通过 "磁头 + 磁道 + 扇区" 的组合来唯一标识,这也是后续 CHS 寻址方式的基础。

1.3.3 柱面(Cylinder)

前面提到,一个磁盘有多个盘片,每个盘片有上下两个盘面,每个盘面都有自己的磁头和磁道。那么,所有盘面上半径相同的磁道就会构成一个圆柱形的空间,这个空间就是柱面。

柱面是一个非常重要的逻辑概念,它的数量等同于单个盘面上的磁道数量。为什么柱面如此重要?因为所有磁头都由同一个磁头臂带动,能够 "共进退"------ 当磁头臂移动时,所有磁头会同时移动到各个盘面的同一半径位置,也就是同一个柱面上。这意味着,访问同一个柱面上的数据时,不需要移动磁头臂,只需要切换不同的磁头即可,这能极大地提高数据读写效率。

1.3.4 磁盘容量的计算方式

了解了磁头、磁道(柱面)、扇区的概念后,我们就可以计算磁盘的总容量了。磁盘的容量计算公式如下:

磁盘容量 = 磁头数 × 柱面数(磁道数)× 每道扇区数 × 每扇区字节数

举个例子:假设一个磁盘有 2 个磁头(1 个盘片,上下两面),1024 个柱面,每个磁道有 63 个扇区,每个扇区 512 字节,那么这个磁盘的容量就是:

2 × 1024 × 63 × 512 = 65536 × 63 = 4128768字节 = 4032KB = 3.9375MB

虽然这个例子中的磁盘容量很小,但它清晰地展示了磁盘容量的计算逻辑。实际应用中的磁盘,磁头数、柱面数和每道扇区数都会大得多,从而实现更大的存储容量。

二、磁盘的逻辑结构:从三维物理空间到一维线性地址

磁盘的物理结构是三维的(磁头、柱面、扇区),但这种三维结构对操作系统来说并不友好 ------ 操作系统更习惯用线性的地址来管理存储资源。为了解决这个问题,我们需要将磁盘的三维物理结构映射为一维的逻辑结构,这就引出了**LBA(Logical Block Address,逻辑块地址)**的概念。

2.1 逻辑结构的核心思想:把磁盘 "拉直" 成磁带

我们可以做一个形象的比喻:磁带是一种线性存储设备,数据被顺序存储在磁带上,访问数据时需要从磁带的一端依次查找。而磁盘虽然是三维物理结构,但从逻辑上看,我们可以把它想象成一卷卷起来的磁带 ------ 当我们把这些 "磁带"(磁道)拉直后,磁盘上的所有扇区就会形成一个连续的线性序列,每个扇区都对应一个唯一的线性地址,这个地址就是 LBA 地址。

这种逻辑结构的转换,让操作系统不再需要关心磁盘的物理结构(磁头、柱面、扇区),只需要通过 LBA 地址就可以访问任意扇区的数据,极大地简化了操作系统对磁盘的管理。

2.2 磁盘逻辑结构的真实映射

前面我们提到,所有磁头是 "共进退" 的,这意味着磁盘的物理访问顺序是按柱面优先的 ------ 先访问完一个柱面上的所有扇区,再移动磁头臂访问下一个柱面。这种物理访问特性,也决定了逻辑 LBA 地址与物理 CHS 地址的映射关系。

从逻辑上看,磁盘的扇区排列顺序是这样的:

  1. 先访问柱面 0 上的所有扇区 :依次访问每个磁头(盘面)对应的磁道,每个磁道上的扇区按编号从 1 到 n 依次排列;
  2. 柱面 0 的所有扇区访问完毕后,磁头臂移动到柱面 1 ,重复步骤 1 的过程;
  3. 依次类推,直到所有柱面的扇区都被排列完毕。

这种排列方式,就像把磁盘的三维物理空间(柱面 C、磁头 H、扇区 S)"扁平化" 成了一维的 LBA 地址序列。每个 LBA 地址都对应着唯一的一个物理扇区,而 LBA 地址与物理 CHS 地址之间的转换,则由磁盘的固件(硬件电路和伺服系统)自动完成,不需要操作系统干预。

2.3 逻辑结构的优势

磁盘逻辑结构的核心价值在于 "屏蔽物理细节,简化管理"。具体来说,它有以下几个优势:

  1. 简化地址管理:操作系统只需要维护一个线性的 LBA 地址空间,不需要关心磁头、柱面、扇区的物理分布;
  2. 提高访问效率:由于 LBA 地址是连续的,操作系统可以很容易地实现连续存储和顺序读写,而磁盘固件会根据物理结构优化访问路径;
  3. 兼容不同硬件:不同厂商、不同规格的磁盘,其物理结构(磁头数、柱面数、扇区数)可能不同,但通过 LBA 地址的统一抽象,操作系统可以无缝兼容这些不同的硬件设备。

三、CHS 与 LBA 地址:磁盘寻址的两种方式

磁盘的寻址方式有两种:CHS(Cylinder-Head-Sector)寻址LBA(Logical Block Address)寻址。CHS 是基于磁盘物理结构 的寻址方式,而 LBA 是基于逻辑结构的寻址方式。两者之间可以相互转换,共同支撑起磁盘的数据访问功能。

3.1 CHS 寻址:基于物理结构的传统寻址方式

CHS 寻址是最早的磁盘寻址方式,它直接使用磁盘的物理结构参数(柱面号 C、磁头号 H、扇区号 S)来定位扇区。

3.1.1 CHS 寻址的工作原理

CHS 寻址的过程非常直观,就像我们在图书馆找书一样:

  1. 确定柱面号 C:相当于找到书架所在的区域;
  2. 确定磁头号 H:相当于找到书架的某一层;
  3. 确定扇区号 S:相当于找到该层书架上的某一本书。

通过这三个参数的组合,就可以唯一确定一个物理扇区。例如,CHS 地址(C=0,H=1,S=5)表示的是第 0 个柱面、第 1 个磁头(盘面)、第 5 个扇区。

3.1.2 CHS 寻址的局限性

CHS 寻址虽然直观,但存在一个致命的缺陷 ------支持的磁盘容量有限。这是因为早期的 BIOS 和操作系统对 CHS 地址的存储位数做了限制:

  • 磁头号 H:用 8 位存储,最多支持 2^8=256 个磁头;
  • 柱面号 C:用 10 位存储,最多支持 2^10=1024 个柱面;
  • 扇区号 S:用 6 位存储,最多支持 2^6=63 个扇区(扇区号从 1 开始,所以实际支持 63 个)。

结合每个扇区 512 字节的标准,CHS 寻址支持的最大磁盘容量为:

(注:这里的 1MB=1048576 字节,如果按 1MB=1000000 字节计算,大约是 8.4GB)

这个容量限制在早期的小容量磁盘时代不成问题,但随着磁盘技术的发展,当磁盘容量超过 8GB 后,CHS 寻址就无法支持了。这也促使了 LBA 寻址方式的诞生。

3.2 LBA 寻址:基于逻辑结构的现代寻址方式

LBA 寻址是为了解决 CHS 寻址的容量限制而设计的,它将磁盘上的所有扇区按逻辑顺序编号,形成一个线性的地址空间,地址从 0 开始递增。

3.2.1 LBA 寻址的工作原理

LBA 寻址完全忽略磁盘的物理结构,将磁盘视为一个由扇区组成的一维数组每个扇区对应一个数组下标(即 LBA 地址)。操作系统访问磁盘时,只需要给出目标扇区的 LBA 地址,磁盘固件会自动将 LBA 地址转换为 CHS 地址,然后定位到对应的物理扇区。

例如,LBA 地址 0 对应磁盘的第一个扇区(CHS 地址通常为 C=0,H=0,S=1),LBA 地址 1 对应下一个扇区,以此类推。

3.2.2 LBA 寻址的优势

相比 CHS 寻址,LBA 寻址有以下几个显著优势:

(1)支持大容量磁盘:LBA 地址的位数不受限制(现代系统通常用 32 位或 64 位存储 LBA 地址),32 位 LBA 地址支持的最大磁盘容量为:

而 64 位 LBA 地址支持的最大容量更是达到了惊人的 18EB(1EB=1024PB,1PB=1024TB),完全满足现代大容量磁盘的需求。

(2)简化操作系统实现:操作系统不需要关心磁盘的物理参数(磁头数、柱面数、扇区数),只需要管理线性的 LBA 地址空间,极大地简化了文件系统和磁盘驱动的实现。

(3)兼容性更好:LBA 寻址是行业标准,所有现代磁盘和操作系统都支持,能够无缝兼容不同规格的存储设备。

3.3 CHS 与 LBA 地址的相互转换

虽然现代操作系统都使用 LBA 寻址,但磁盘固件仍需要将 LBA 地址转换为 CHS 地址才能访问物理扇区。同时,在某些特殊场景下(如磁盘分区、系统启动),也可能需要进行 CHS 与 LBA 地址的转换。下面我们就来详细介绍两者的转换公式。

3.3.1 转换前的准备参数

在进行地址转换前,我们需要知道磁盘的三个关键参数:

  • 磁头数(H_total):磁盘的总磁头数量;
  • 每磁道扇区数(S_per_track):每个磁道的扇区数量;
  • 单个柱面的扇区总数(S_per_cylinder)

这三个参数会存储在磁盘的固件中,操作系统可以通过磁盘驱动获取。

3.3.2 CHS 转换为 LBA

已知一个扇区的 CHS 地址(C,H,S),将其转换为 LBA 地址的公式如下:

公式说明:

  • 首先计算该扇区所在柱面之前的所有柱面占用的扇区总数(C×Sper_cylinder​)
  • 然后计算该扇区所在磁头之前的所有磁头占用的扇区总数(H×Sper_track​)
  • 最后计算该扇区在当前磁道中的偏移量(S−1,因为扇区号从 1 开始,而 LBA 地址从 0 开始);
  • 三者相加即为该扇区的 LBA 地址。

举个例子:假设磁盘参数为 H_total=2,S_per_track=63,那么 S_per_cylinder=2×63=126。如果 CHS 地址为(C=1,H=1,S=5),则对应的 LBA 地址为:

3.3.3 LBA 转换为 CHS

已知一个扇区的 LBA 地址,将其转换为 CHS 地址(C,H,S)的公式如下:

公式说明:

  • 柱面号 C:LBA 地址除以单个柱面的扇区总数,取整数部分;
  • 磁头号 H:LBA 地址对单个柱面的扇区总数取余,结果再除以每磁道扇区数,取整数部分;
  • 扇区号 S:LBA 地址对每磁道扇区数取余,结果加 1(因为扇区号从 1 开始)。

继续用上面的例子:LBA 地址 = 193,磁盘参数 H_total=2,S_per_track=63,S_per_cylinder=126。则对应的 CHS 地址为:

与之前的 CHS 地址一致,验证了转换公式的正确性。

3.3.4 转换的实际应用场景

CHS 与 LBA 地址的转换主要由磁盘固件自动完成,但在以下场景中,我们也可能会手动涉及:

  1. 磁盘分区 :在 MBR(Master Boot Record)分区表中,分区的起始和结束地址会同时存储 CHS 地址和 LBA 地址,用于兼容不同的寻址方式;
  2. 系统启动:早期的 BIOS 启动程序使用 CHS 地址访问磁盘的引导扇区,而现代 UEFI 启动程序则使用 LBA 地址;
  3. 磁盘故障排查:当磁盘出现坏道时,我们可以通过 LBA 地址定位到对应的物理扇区,进行修复或屏蔽。

3.4 实战:用 bash 命令查看磁盘的 CHS 和 LBA 信息

在 Linux 系统中,我们可以通过fdisk命令查看磁盘的 CHS 和 LBA 相关信息。下面我们就来实战操作一下。

3.4.1 查看磁盘的基本信息

执行以下命令查看系统中的磁盘设备:

bash 复制代码
fdisk -l

命令输出示例:

复制代码
Disk /dev/vda: 42.9 GB, 42949672960 bytes, 83886080 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000b2d99

Device Boot      Start         End      Blocks   Id  System
/dev/vda1   *        2048    83875364    41936658+  83  Linux

从输出中我们可以获取以下关键信息:

  • 磁盘总容量:42.9 GB;
  • 总扇区数:83886080(LBA 地址范围从 0 到 83886079);
  • 扇区大小:512 字节;
  • 分区 /dev/vda1 的起始扇区(LBA):2048,结束扇区(LBA):83875364。

3.4.2 计算磁盘的 CHS 参数

由于现代磁盘容量较大,fdisk命令默认不会显示 CHS 参数,但我们可以通过总扇区数和磁盘的默认参数(通常 H_total=255,S_per_track=63)来估算 CHS 参数。

根据磁盘容量公式:

我们可以推导出柱面数:

代入示例中的总扇区数 83886080,假设 H_total=255,S_per_track=63,则:

这就是该磁盘的柱面数估算值。

3.4.3 验证分区的 LBA 地址

我们可以通过lsblk命令查看分区的详细信息,验证 LBA 地址:

bash 复制代码
lsblk -o NAME,SIZE,START,END,TYPE

命令输出示例:

复制代码
NAME   SIZE START      END TYPE
vda    40G     0 83886079 disk
vda1   40G  2048 83875364 part

输出中的**STARTEND字段就是分区的起始和结束 LBA 地址** ,与fdisk命令的输出一致。

四、硬件底层与 Ext 文件系统的关联

看到这里,可能有同学会问:我们讲了这么多磁盘硬件和寻址方式,这些和 Ext 系列文件系统有什么关系呢?

其实,Ext 系列文件系统的核心功能就是在磁盘硬件的基础上,实现文件的组织、管理和访问。磁盘硬件提供了最底层的存储能力(扇区存储),而 Ext 文件系统则在这个基础上构建了一套逻辑结构(块、inode、目录、分区等),让用户能够通过文件名而非 LBA 地址来访问文件。

两者的关联可以总结为以下几点:

  1. 扇区是文件系统的物理基础 :Ext 文件系统的最小存储单位是**"块"(Block)** ,而一个块由多个连续的扇区组成(常见的块大小为 4KB,即 8 个扇区)。文件系统的块分配、数据读写,最终都会映射到磁盘扇区的读写。
  2. LBA 地址是文件系统的寻址桥梁:Ext 文件系统在管理块时,会将块映射到对应的 LBA 地址范围。当文件系统需要读写某个块时,会通过 LBA 地址访问磁盘,而磁盘固件会自动完成 LBA 到 CHS 的转换。
  3. 磁盘分区是文件系统的独立空间:Ext 文件系统通常会安装在磁盘的一个分区上,分区本质上是磁盘上的一个连续 LBA 地址范围。文件系统只需要管理该分区内的 LBA 地址,不需要关心其他分区的情况。
  4. 硬件特性决定文件系统的优化方向:由于磁盘的磁头移动和盘片旋转需要时间,Ext 文件系统会通过预分配块、优化 inode 布局、目录缓存等方式,减少磁头移动次数,提高数据访问效率,这都是基于磁盘硬件特性的优化。

总结

通过这些内容,我们可以得出一个核心结论:Ext 系列文件系统的底层依赖于磁盘硬件的存储能力和寻址方式。磁盘硬件提供了扇区级别的存储,而 LBA 寻址方式则为文件系统提供了统一、高效的寻址接口。理解这些硬件底层原理,不仅能帮助我们更好地理解 Ext 文件系统的工作机制,还能在实际应用中(如磁盘分区、性能优化、故障排查)提供理论支持。

在后续的文章中,我们将在此基础上,进一步讲解 Ext 系列文件系统的逻辑结构(块、inode、目录、超级块等),以及文件的创建、读取、修改、删除等操作的底层实现。如果大家有任何疑问或想了解的内容,欢迎在评论区留言讨论!

最后,感谢大家的阅读!如果这篇文章对你有帮助,别忘了点赞、收藏、转发哦~

相关推荐
AnalogElectronic2 小时前
linux 测试网络和端口是否连通的命令详解
linux·网络·php
Edward111111112 小时前
4月28日防火墙问题
linux·运维·服务器
子琦啊3 小时前
【算法复习】字符串 | 两个底层直觉,吃透高频题
linux·运维·算法
AOwhisky4 小时前
Kubernetes 学习笔记:集群管理、命名空间与 Pod 基础
linux·运维·笔记·学习·云原生·kubernetes
小龙在慢慢变强..4 小时前
目录结构(FHS 标准)
linux·运维·服务器
2035去旅行4 小时前
嵌入式开发,如何选择C标准库
linux·arm开发
刘延林.4 小时前
win11系统下通过 WSL2 安装Ubuntu 24.04 使用RTX 5080 GPU
linux·运维·ubuntu
CodeOfCC6 小时前
Linux 嵌入式arm64安装openclaw
linux·运维·服务器
宵时待雨7 小时前
linux笔记归纳3:linux开发工具
linux·运维·笔记
magrich7 小时前
安装NoMachine并解决无外接显示器桌面黑屏
linux·运维·服务器