跳转到内容

Aros/Developer/IODeviceDriversDev

来自 Wikibooks,开放世界的开放书籍
Aros 维基百科的导航栏
Aros 用户
Aros 用户文档
Aros 用户常见问题解答
Aros 用户应用程序
Aros 用户 DOS Shell
Aros/User/AmigaLegacy
Aros 开发文档
Aros 开发者文档
从 AmigaOS/SDL 移植软件
面向 Zune 初学者
Zune .MUI 类
面向 SDL 初学者
Aros 开发者构建系统
特定平台
Aros x86 完整系统 HCL
Aros x86 音频/视频支持
Aros x86 网络支持
Aros 英特尔 AMD x86 安装
Aros 存储支持 IDE SATA 等
Aros Poseidon USB 支持
x86-64 支持
摩托罗拉 68k Amiga 支持
Linux 和 FreeBSD 支持
Windows Mingw 和 MacOSX 支持
Android 支持
Arm Raspberry Pi 支持
PPC Power Architecture
杂项
Aros 公共许可证

AOS 在 dos 列表锁定和解锁时分别调用 Forbid() 和 Permit()。 (在 Guru 书中也提到这是 1.x 兼容性“特性”)

目前有以下注释

/* This came from MorphOS source code, however looks strange.
   Commented out but left for reference. 
    if (dl)
    Forbid(); */

删除注释或将其放入 #ifdef _mc68000 中,或者不做任何操作?毕竟这是 AOS 半文档化的功能。我认为我们应该在 LDF_WRITE 上调用 Forbid(),但在 LDF_READ 上保持打开。

是时候将处理程序从 DEVS: 移动到 L: 了。现在它们是像 L: 中的 AOS 处理程序一样的包处理程序。2011 年 6 月底,现在有了 DOS 包,文件句柄和锁不再是同一件事。像这样的代码

    fdesc *desc = __getfdesc(fd);

    if (!desc)
    {
        errno = EBADF;

    return -1;
    }

    return __stat(desc->fcb->fh, sb);

在编译器/clib/fstat 中需要从文件句柄创建锁。最好的方法是什么,NameFromFromFH 然后 Lock?我们是否需要对 clib 的某些部分采用完全不同的方法?有 LockFromFH/DupLockFromFH() 和 OpenFromLock() - 涵盖了两个方向。不需要,我们可以在 __stat() 中使用 ExamineFH 和 NameFromFH。

fib_FileName 存储为 AROS_BSTR。因此,如果定义了 AROS_FAST_BSTR,则它是一个 C ASCIIZ 字符串,否则它是一个 BSTR。

由于 fib_FileName 和 fib_Comment 保证对齐 BPTR,因此在 MKBADDR(&fib_Filename[0]) 上使用 AROS_BSTR_* 宏是完全安全的,它会为您封装所有内容。

建议重写这两个 ps/2 总线驱动程序,然后对所有需要的延迟使用 timer.device(在代码中添加了很多忙等待延迟。尤其是在中断代码中…)。

  • 分离串行鼠标驱动程序。
  • 将 PS/2 鼠标驱动程序与键盘驱动程序合并(它们使用相同的低级函数,需要链接在一起,这就是为什么我

仍然将 x86-64-pc 板支持包链接到 ELF 中)。

在 AmigaOS 3.1 中,应用程序会查询 printer.device ,它会读取打印机首选项文件,并与为该信息选择的打印机驱动程序(针对每台打印机定制)进行通信,并将信息提供给应用程序程序。除了参考自己的首选项以进行页面设置等之外,应用程序程序还会使用打印机设备提供的某些控件来控制实际的打印机驱动程序,并向其提供正确的命令、二进制位图或 ASCII 文本数据来执行打印作业。我建议从为 AROS 创建标准(类似 ASL)打印支持请求器开始,并开发新的打印机首选项文件标准和 printer.device,可以很好地集成到 CUPS、Ghostscript 等中,这些项目是当前开发和支持的开源项目。

  • 创建一个与 OS31 兼容的 printer.device - 该设备必须调用打印机驱动程序中的相应函数,例如 init()、dospecial()、render()、transfer()、density(),并处理各种 CMD 调用,例如 CMD_FLUSH、RESET、START、STOP、WRITE、DUMPRPORT、PRTCOMMAND、QUERY、RAWPRINT 等,并调用相应的函数,同时也要尝试使其与 RTG 兼容。
  • 在其中创建一个后台任务
  • 创建一个驱动程序来测试我的网络打印机

然后添加

  • 一个后台监视器
  • 创建首选项应用程序(也许使用 printer.device v44 首选项消息,目前还不清楚)
  • 一个调用 Ghostscript 的驱动程序(如果实际的 gs 端口可用)
  • 一个用于我的 PS 打印机的驱动程序,并添加对 USB 链接的支持
  • 一个用于我的 PCL 打印机的驱动程序(同一个)
  • Sonic 的理念:用于打印的图形设备上下文
  • 一个调用其他内容(如 cups 二进制文件)的驱动程序
Postscript      Text  Graphics      
  |               |        | 
  |            PS Encapsulation 
  |                  |          
  |            Ghostscript Core      Rendering Section
  |                  |
  +------------------+ 
  | 
Print Queue                     
  |
  +----+-----+-----+         Printing Section 
  |    |     |     |
Net:  Par:  USB:  Ser: (???)

需要支持

页面设置应包含标准选项(以及用户可自定义的选项),用于选择方向、页面大小和介质类型。 (一个起点是 [www.pwg.org/ipp/index.html IPP](Internet Printing Protocol)标准文档中列出的那些选项)。

打印选项应有位置选择要预览、打印或打印到磁盘作为文件(全部、当前、范围)的文档页面,打印文件类型可以是 PDF、SVG、PNG、JPEG。它应该有 N-Up、双面打印、添加作业单、整理功能(例如订书、打孔、切割(卷轴式介质))的设置。

带有排队和作业管理的色彩管理。

实现可以渲染到位图并使用多种不同格式将其提供给打印机的驱动程序,以处理不支持 PCL 或 PS 的低端喷墨打印机,其中许多打印机没有记录的协议(例如,您可能需要反向工程 CUPS 驱动程序)。

文件系统

[编辑 | 编辑源代码]

改进的 hostdisk.device 设计,合并了一些通用代码。在 Windows 上实现了对 64 位映像文件长度的处理。默认情况下使用扁平 LBA,而不是可能不适合的虚拟几何。

我记得单块柱面是一个问题。我认为某些分区/文件系统结构至少需要每柱面两个块,也许更多。请参阅 Poseidon massstorage.class,我在那里遇到了这个问题。

我会检查 Poseidon 代码。但是,另一方面,扁平 LBA 地址似乎是唯一合理的选择,可以与其他已经有一段时间忽略柱面对齐的 OS 共存。我想知道为什么 AmigaDOS 创建者在任何地方都使用柱面,因为无论是在低级还是高级上,AmigaOS 都使用 LBA 地址。文件系统只是执行 cyl * sectors * heads。这更有可能是一个 Poseidon 缺陷。

根据 RKM 的 scsi.device 部分,设备驱动程序本身似乎需要解析 RDB 并生成引导节点,这与当前的 AROS 方法大不相同,后者由“引导程序”负责 RDB 解析。

所以,这里有一个计划。它应该更像 AOS,并将导致对 RDB 卷的支持“热插拔” - 即 RDB CDROM 和 CompactFlash 设备。因此,基本上,引导程序中递归扫描磁盘分区表的代码将被移动到 partition.library 中的函数中,该函数将从设备驱动程序调用?这听起来不错,并且还会消除 mass-storage 类中该代码的重复。

一些要点

无分区的卷的 DOS 设备将如何处理?目前,ATA 设备作为 HDx 启动,而 ATAPI 设备作为 CDx 启动。如果 HD 具有分区表,则 HDx 将被删除并替换为任何拥有 IO 的分区。以同样的方式。如果没有分区,则会创建“引导块”样式节点(HD0),否则,您将只获得分区。partition.library 将处理所有块设备的 DOS 详细信息 - 它们只需要在磁盘更改时调用该函数即可。

看来我们大多数文件系统 *确实* 正确地处理 ACTION_INHIBIT 和 ACTION_DIE(大多是)。


partition.library -------------

  • 向 partition.library 添加一个“BOOL MakeDosPartitions(CONST_STRPTR device, IPTR unit)”。

partition.library

 - Enumerates through all partitions (RDB or MBR), and
   MakeDosNode() a list of DOS nodes (dnlist), generating unique
   DOS device names if needed. (ie "HD0.1" if "HD0" exists)

引导程序已经包含生成 DOS 设备名称的代码,所以我们更改所用格式之前应该有一个充分的理由。

 - If the new partition list doesn't match an old dnlist in the
   partition.library's current 'everything I've seen since boot'
   database:
   * Calls RemDosEntry() on all DeviceNodes in the old dnlist
     for this device/unit (if any).
   * Removes all the old dnlist entries from Expansion->Mountlist
   * Remember the new dnlist as one seen by partition.library
 - But if it *does* match an existing list, use that instead of
   the new one we just made.
 - Call AddBootNode() on all the DeviceNodes in the new list,
    with appropriate (bootable > -128, or nonbootable = -128) priorities.

每个可以具有 RDB/MBR/GUID 分区的 foo.device ------

  • 修改 ata.device、usb massstorage.class 等

- 调用 Partition/MakeDosPartitions(..)

  on every diskchange event.

trackdisk.device ----

  • 使用 DosType = 0 创建 DeviceNode 条目,没有处理程序,并
 DE_BOOTBLOCKs etc. set correctly for a BootBlock style BootNode.
  • AddBootNode(5, 0, dn, NULL)

引导程序 ----

初始引导设备选择菜单(来自 dosboot.resource)现在被移动到这里,并且可以用于调整 ExpansionBase->Mountlist 中条目的顺序,以及其他内容。

由于 partition.library 维护设备的分区到卷的映射,因此我们可以从 strap 中删除分区代码。

1)扫描 ExpansionBase->Mountlist,并

 * If not a valid BootNode (node type is not NT_BOOTNODE), ignore it.
 * If BootNode->bn_Pri == -128 (non-bootable), ignore it.
 * If any of the following are true, ignore it:
    - (dn = BootNode->bn_DeviceNode ) == NULL
    - (fssm = BADDR(dn->dn_Startup)) == NULL
    - (de = BADDR(fssm->fssm_Environ)) == NULL
 * bootblocks = (de->de_TableSize < DE_BOOTBLOCKS) ? 0 : de->de_BootBlocks;
 * If the node is a valid BootPoint node (bootblocks == 0): (m68k only)
    - (cd = (struct ConfigDev *)BootNode->bn_Node.ln_Name) != NULL
    - (da = cd->cd_Rom.er_DiagArea) != NULL
    - (da->da_Config & DAC_CONFIGTIME) != 0
    -- If *all* the above is true, then:
       if da->da_BootPoint(configDev, register A2 = bn) returns,
           then booting from this device failed.
 * If the node is a valid BootBlock node (bootblocks > 0): (all archs)
    - OpenDevice(fssm->fssm_Device, fssm->fssm_Unit, &io, fssm->fssm_Flags ) == 0 
    - Read a bootblock as described in the RKM BootBlock section,
      and verify that the checksum is correct.
    - If de->de_DosType == 0:
       * Update the BootNode's de->de_DosType with the DosType in the
         bootblock
    - If de->de_DosType != bootblock's de_DosType
       * Ignore this device, continue to the next one in the Mountlist
    - m68k ONLY: Actually call the bootblock code
      If the BootBlock's init() routine returns, assume booting from this
         device failed.
    - non-m68k ONLY: Simulate calling the bootblock code
      - InitResident(FindResident("dos.library", BNULL));

2)没有有效的引导块?然后尝试启动 dos.library,看看是否有任何“DOS 可引导”节点。

 * InitResident(FindResident("dos.library", BNULL));
   /* If we return here, then DOS couldn't mount a SYS: volume */

3)显示引导动画的循环,然后返回到(1)


dos.library -----

这里的主要变化是 dos.library *可能失败*,并且如果它找不到 SYS: 卷,则可以 *退出*,返回代码为 FALSE。

在基本的 DOS 库初始化之后

 1) While ExpansionBase->MountList is non-empty {
     * Remove the first entry (highest priority) off of the MountList
     * If a valid boot node, try to DeviceProc() it.
     * If DeviceProc() succeeds, this is the SYS: node - exit the loop
     * Otherwise, add the node to a temporary list (bn_unbootable)
   }
 2) If no SYS: node:
       * Re-add bn_unbootable to the Mountlist
       * clean up DOS allocated memory
       * return FALSE from this init of dos.library - This is safe, as no DOS volumes have been mounted
 3) Otherwise, we have a bootable SYS: node!
 4) (non-Amiga) If the SYS:AROS.boot file exists and is *NOT* valid for this machine, Intuition up a requester to tell the user about it, and allow the user to reboot or continue into the weeds of danger.
    - Since we can't safely dismount SYS: at this time, there's no easy way to handle this case without a reboot.

找到一个分区,其中没有匹配的 AROS.boot 文件,这不是错误条件。我们需要支持 32 位/64 位双启动系统。目前,据我所知,这是不可能的。32 位 Exec 不会运行 64 位代码,而 64 位 Exec 不会运行 32 位代码。ABI 完全不同。

支持这一点将是……至少可以说,一项有趣的任务,超出了本提案的范围。

 5) Add bn_unbootable to the Mountlist - NOTE: The SYS: device node will *not* be in the Mountlist anymore
 6) For each node in the Mountlist:
    * If a valid bootnode (NT_BOOTNODE and bn_Pri > -128):
        - If ADNF_STARTPROC is set, DeviceProc() it.
 7) Execute the dosboot.resource
     DOSBootResource = FindResource("dosboot.resource")
     InitResident(DOSBootResource, 0)
     /* If we return from here, ALERT! */

dosboot.resource ----

此资源不再自动启动。

所有引导菜单内容都已移动到“引导程序”

所有安装都已移动到 dos.library

我们只需要创建初始分配,并启动 shell。

也许我们也可以把它移到 dos.library 中?

  • 创建 "Initial CLI" 进程
    Create initial assigns
    InitCode(RTF_AFTERDOS, 0)
       - This is, I believe, more like AOS, in that the initial
         assigns and CLI are up during RTF_AFTERDOS, and
         RTF_AFTERDOS code is called in the "Initial CLI" context
    Execute S:Startup-Sequence or Shell
  • RemTask(NULL);

存在一些“恶意边缘情况”,只能通过确保所有处理程序能够正确处理 ACTION_DIE 以及重启时过时的 FileLocks 和 FileHandles 来解决。

我不确定是否需要 partition.device。已经存在一种机制来处理从一个端口到另一个端口的 USB 驱动器的热插拔,同时保留卷的锁和通知请求(我认为两个端口是否在同一个控制器上并不重要)。它的工作方式与在 AmigaOS 中允许您将软盘从 DF0: 交换到 DF1: 的机制相同。这已经在 fat-handler 中实现。这里的想法是创建一个处理所有现有文件系统的单个代码点,而无需让每个文件系统钩入设备的磁盘更改机制。

如果处理程序收到新消息(例如尝试写入现有文件句柄),它的原始块 I/O 将转到该卷的 partition.device 单位,如果 Intuition 不可用,该 I/O 将阻塞(即 WaitSignal()),直到卷重新挂载。

我们所有的处理程序都应该正确支持 ACTION_INHIBIT 和 ACTION_DIE,这样当卷实际上已被移除时,处理程序不会认为它仍然存在。

或者,partition.library 可以发出一个弹出窗口(例如“卷 BigDog: 不再可用。[等待卷] [将错误返回应用程序]”),并等待卷返回,或者将 I/O 错误返回到文件系统。

无论哪种情况,是的,处理程序可能会保留下来。

如果我们想要大力推动在所有文件系统中支持 ACTION_INHIBIT,那么我们不需要 partition.device 代理设备。..但是,由于它们在不被禁止时将继续绑定到同一个 Exec 设备/单位,因此我们仍然需要 partition.device 代理来处理热插拔分区集(因为 USB 记忆棒或 AHCI 热插拔驱动器可能会移动到不同的单位,甚至不同的 Exec 设备)。[ACTION_INHIBIT 更好,因为这应该防止在我们尝试 ACTION_DIE 弹出分区集的处理程序时,它们具有打开的 Locks 或 FileHandles 时,出现“离线”卷的堆积。至少 AFS 似乎能够恢复它再次找到的卷。] partition.device 代理不需要,只需要在磁盘更改时根据需要自动发送 ACTION_INHIBIT。

它在 AmigaOS 中是否曾经与离线卷一起使用?是的,这对 AFS 中 DosList 卷管理的实现至关重要。请参阅 afs/main.c 中的 ACTION_INHIBIT: 部分,并跟踪代码路径。

离线卷有什么问题?在它们的处理程序死亡后,它们可能会保留下来,并在重新插入时被处理程序的另一个实例采用。fat-handler 和 massstorage.class 是一个很好的概念证明,因为所有这些热插拔和离线卷都很好地工作(自数据包切换以来,我没有测试过此功能)。

[是的,即使 ACTION_INHIBIT 正常工作,您也可以通过热插拔无数个不同的 USB 记忆棒来占用所有内存,但我目前认为这是一个不有趣的边缘情况。如果它变得有趣,我们应该确保至少 afs-handler 和 fat-handler 能正确处理 ACTION_DIE。]

步骤

[edit | edit source]
  1. 当一个 Exec 块设备(例如 trackdisk.device 单位 0)首次挂载时,它被分配一个具有处理程序(例如 FFS)的 Dos 设备节点(DLT_DEVICE),并且该处理程序知道它将一直连接到 DosEnviron 中指定的 Exec 设备,直到它收到 ACTION_DIE(例如 trackdisk.device,单位 0(为了简洁起见,'td-0')
  2. 假设插入一张软盘。此时,td-0 处理程序(FFS)探测软盘,在检测到 FFS 磁盘后,为它创建一个新的 DLT_VOLUME,并将卷的 dol_Task 设置为处理程序的 dol_Task。不要认为 FFS 会确定文件系统是否为 FSS,认为它“假设”它是 - 如果它无法读取它,它会假设它只是没有被格式化或已损坏。
  3. 新的锁附加到 DLT_VOLUME 的 dol_LockList。(也许是懒加载,但这是理论)。有点像。它们通常只在卷离线(介质被移除)后才附加到 dol_LockList。
  4. 假设软盘被弹出。此时,td-0 处理程序(FFS)探测软盘设备,发现没有磁盘存在,并在自身上执行 ACTION_INHIBIT/TRUE。ACTION_INHIBIT 看到一些锁打开,将 DLT_VOLUME 的 dol_Task 设置为 NULL,并将 DLT_VOLUME 保留在 DosList 中。或多或少。处理程序通过 Toni 提到的命令收到软盘不存在的指示。此时,卷的未决锁将附加到 dol_LockList。
  5. 如果尝试对弹出 DLT_VOLUME 上的锁/文件句柄执行 I/O,Dos 会检测到 Lock 的 fl_Volumes' dol_Task 为 NULL,并弹出“请插入卷 XXX”请求器。1.0 版本在 DOS 和 FS 之间存在差异。如果 DOS 需要从卷 Vol: 获取文件,但发现它不存在,它会要求用户将其插入任何位置。但如果 FS 试图在磁盘上定位另一个块,那么它会要求将磁盘替换到特定驱动器中。(是的,我认为,它只是说“磁盘”,而不是给出它的名称,这在你刚完成三次磁盘交换时是一个很大的烦恼)。我不记得随着时间的推移这是如何改进的,尽管如此。
    1. 插入一张新的软盘。td-0 处理程序执行与 (2) 相同的操作。某件事将不得不抑制 DOSFALSE,否则什么都不会发生。如果 td-0 正在等待重新插入,它现在可能会返回请求的数据。处理程序实际上正在等待 IOHF_MEDIA_CHANGE,并将重新扫描设备以确定新的卷是什么,至少 AROS 就是这样实现的。在 AROS 中,探测是在介质插入时在 FFS 处理程序本身中完成的。据我所知,AOS 也做了同样的事情。
  6. 最初在 td-0 上的软盘现在插入到 td-1 中。探测后,td-1 处理程序在 DosList 中找到相同的卷,并将卷的 dol_Task 设置为 td-1 的 dol_Task。原始卷现在可用。是的。此外,td-1 处理程序从 dol_LockList 获取卷的锁。对 DOS 可用,也就是说。您可以再次打开该卷上的文件。如果 td-0 在它上面打开了文件,它会继续要求重新插入它(除非 AOS 或 AROS 改进了这一点)。处理程序使用设备驱动程序的 TD_ADDCHANGEINT/TD_REMCHANGEINT(旧代码使用 TD_REMOVE,或者在最坏的情况下轮询)i/o 命令来检测介质更改。

基本总结是,DOS 设备节点绑定到该设备,持续时间为设备节点的生命周期(直到它收到 ACTION_DIE),并且它管理它看到的任何卷的生成、检测、弹出和复活,_在_它的_文件系统_类型_中,_对于_那个_exec_设备_。

如果是这样,我认为这个模型崩溃的地方在这里

1) 当一个 Exec RDB 可用的块设备(例如 ata.device 0)第一次被看到时,会扫描分区,并为每个分区创建 DOS 设备,并分配处理程序。每个处理程序都绑定到 Exec 设备、单位和由它们的 DosEnviron 向量指定的块范围。

2) 每个 DLT_DEVICE 都期望能够与其底层 Exec 设备通信,直到它收到 ACTION_INHIBIT 或 ACTION_DIE。

3) 现在假设多个分区已经创建了它们的 DLT_VOLUMEs,我们对一些分区有一些打开的锁,而其他分区没有锁。

4) ata-0 设备被弹出。每个现有的 DOS 设备处理程序将收到 IOHF_MEDIA_CHANGE 事件,并检测到没有介质存在,就像情况 4 一样,将它们的卷设置为卸载或“不可用”。它们不应该收到 MEDIA_CHANGE;它们应该收到 INHIBIT。更改的介质不是它们的;它们的介质消失了,因为它们所在的介质发生了变化。与 diskfiles 相比:您已经从 USB 记忆棒挂载了一个磁盘文件。您拔出记忆棒;磁盘文件不会突然插入不同的卷,它只是无法再访问它的卷。将卷 AOSDMS: 重新插入设备 DFile1: 中。

第 1 到 4 点是正确的,但在第 4 步中可能会采取其他步骤,具体取决于我们正在谈论的驱动器类型。假设我们正在谈论一个在热插拔接口上的硬盘驱动器,例如典型的 USB 硬盘或闪存驱动器。对于 USB,第 4 步对应于 HD 的 USB 插头从系统中移除。所有使用 HD 的处理程序都将收到 ACTION_DIE。那些具有未决锁的处理程序将在死亡之前将它们放到它们的卷的 dol_LocksList 中。处理程序消失后,已移除 HD 的 Exec 块设备将被销毁。

如果我们认为处理程序在没有打开的锁时返回 ACTION_INHIBIT 或 ACTION_DIE 时返回 DOSFALSE 是一个错误。

或者,这是一个更强的要求,即(只要没有正在进行的 I/O)Dos 设备处理程序应该始终正确处理 ACTION_INHIBIT 和 ACTION_DIE,并将它们的锁迁移到离线卷,并且新的处理程序应该能够在卷再次联机时恢复这些锁?

如果有活动 I/O,并且处理程序针对动作 ACTION_INHIBIT 和 ACTION_DIE 返回 DOSFALSE,那么处理程序应该保留下来,并等待设备重新插入,对吗?

5) 插入一个新的 MBR 设备。现有的 DOS 处理程序仍然分配给旧的分区布局,看到 OHF_MEDIA_CHANGE,并尝试在旧的范围内探测新磁盘上的新卷。希望它们不会找到任何。新的 MBR 卷在哪里插入?如果它是另一个 USB HD,新的处理程序将被设置,就像之前的 RDB HD 一样。RDB 的处理程序已经消失,因此它们不会造成任何麻烦。新的 MBR 卷,位于与旧卷相同的物理热插拔插槽中(设备和单位)。Exec 设备需要在重新插入时重新扫描分区,对吗?并且 *不* 将 IOHF_MEDIA_CHANGE 传递给任何“陈旧”的处理程序,直到它已验证这些处理程序与它们打开的原始 RDB 相匹配,对吗?它们没有看到磁盘更改,新卷的插入将为每个新分区创建新的 DOS 设备。这里确实存在一个问题,即我们是否想要 Action_Die 并重用设备号。这两种方法可能都有优点。

所以...现在怎么办?ata-0 设备应该重新扫描以查找新的分区吗?是的。其他任务/处理程序?

旧的 Dos 设备应该保留下来(ACTION_INHIBITed),直到我们看到一些看起来像旧 RDB 的东西吗?在我上面描述的情况下(USB HD)不是这样。更有趣的情况类似于接受分区可移动介质的 DVD-RAM 驱动器。IMHO,当分区介质被移除时,处理程序应该收到 ACTION_DIE,但 Exec 块设备会保留下来。这可能也适用于 SATA HD。是的,至少那些被禁止的。关于重用数字的问题出现了。如果我们重用了那些没有锁的数字,那么重新插入记忆棒可能会为它们提供不同的设备号。

如果它们不抑制怎么办?但我们最好不要拉动控制杆,因为它们正在忙着写入它。我们应该从旧的 RDB 中 ACTION_DIE DOS 设备吗?是的,因为它们是为不再存在的情况动态创建的。不,因为我们可能希望重新插入该卷。我们必须权衡一下。有人知道参考吗?

如果它们不消失怎么办?那么该操作系统组件中存在错误。

华夏公益教科书