UEFI应用程序用于创建ext2 / 3/4文件系统

问题描述

几乎所有的Linux发行版在安装期间都会调用一个应用程序,该应用程序会将存储驱动器格式化为ext2 / 3/4文件系统。 怎么做?它可以通过任何UEFI应用程序实现吗?

解决方法

文件系统的创建与UEFI无关。

Unix方法是将硬件资源公开为伪文件(reference),以便可以使用标准文件命令来访问硬件。如果是HDD或SDD,则可以通过设备节点(例如/dev/sda/dev/sdb)访问原始驱动器。根据硬件的不同,您可能还会使用诸如/dev/nvme0n1之类的名称。您可以打开这些文件并像对待其他文件一样操作它们(例如,在C中使用fopenfreadfseek等)。 Linux内核会将对这些伪文件的任何写或读操作映射到原始驱动器。

通常,您希望在应用文件系统之前对驱动器进行分区(这样可以将文件系统直接应用于整个驱动器而不进行任何分区)。要创建分区,您需要将分区表(例如GPT格式)写入驱动器的开头。然后,您可以在分区表中为分区创建条目。创建分区后,Linux应将每个分区公开为单独的设备节点(例如/dev/sda1/dev/sda2/dev/nvme0n1p1/dev/nvme0n1p2)。这些文件可以像其他文件一样再次打开和处理。考虑到分区的偏移量,Linux内核将再次将对这些文件的写入或读取操作映射到原始驱动器。

要在分区上创建文件系统,您将使用诸如mkfs.ext4e2fsprogs的一部分)之类的工具。 mkfs.ext4将打开该分区的分区伪文件,并将文件系统数据结构写入该文件。 Linux内核会将写操作映射到原始驱动器上。

让我们考虑以下示例。我们将创建一个新文件,并使Linux内核假装该文件是驱动器(使用循环设备)。然后,我们将在此“驱动器”上创建一个新的分区表,然后在其分区之一上创建一个文件系统。

  • 创建一个大小为2G的文件,将其用作我们的驱动器:

    # dd if=/dev/zero of=my_disk bs=1024 count=2000000
    2000000+0 records in
    2000000+0 records out
    2048000000 bytes (2,0 GB,1,9 GiB) copied,8,13332 s,252 MB/s
    
  • 创建一个循环设备,使我们可以将文件视为新驱动器:

    # losetup -f
    /dev/loop0
    # losetup -P /dev/loop0 my_disk 
    
  • 在磁盘上创建分区表:

    # fdisk /dev/loop0                                                   
    Command: g
    
    Created a new GPT disklabel (GUID: 8155F57B-0E54-1146-9CC1-E5092C1F671C).
    
    Command: n
    Partition number (1-128,default 1): 
    First sector (2048-3999966,default 2048): 
    Last sector,+/-sectors or +/-size{K,M,G,T,P} (2048-3999966,default 3999966): 
    
    Created a new partition 1 of type 'Linux filesystem' and of size 1,9 GiB.
    
    Command: w
    

    您现在应该可以看到新创建的分区的新设备节点/dev/loop0p1。如果没有尝试,请尝试类似partprobe之类的方法来通知内核分区布局的更改,或者使用losetup -d /dev/loop0删除循环设备,然后通过上一步再次打开它。

  • 在驱动器的分区上创建文件系统:

    # mkfs.ext4 /dev/loop0p1 
    mke2fs 1.45.6 (20-Mar-2020)
    Discarding device blocks: done                            
    Creating filesystem with 499739 4k blocks and 125184 inodes
    Filesystem UUID: 09d1a2e7-4ef1-4a89-92ab-eae1a80d9534
    Superblock backups stored on blocks: 
         32768,98304,163840,229376,294912
    
    Allocating group tables: done                            
    Writing inode tables: done                            
    Creating journal (8192 blocks): done
    Writing superblocks and filesystem accounting information: done 
    

    您还可以应用strace来观察mkfs.ext4使用的系统调用。您应该能够看到open的{​​{1}}和close呼叫,还有一些/dev/loop0p1read的呼叫。您应该看不到任何写操作。这是因为lseek似乎改用mkfs.ext4reference),其中文件的一部分被映射到内存中,这样,对内存的修改将被文件写入到文件中内核(比手动将文件的一部分读取到缓冲区,修改缓冲区并将缓冲区写回到文件中要快一些)。但是内存映射并不特定于作为分区设备节点的文件,您也可以在常规文件上使用mmap

  • 安装文件系统:

    mmap

    例如,您可以然后在# mount /dev/loop0p1 /mnt 中创建一个文件,卸载该文件系统,然后再次安装它以确认该文件已在我们的新驱动器上创建。

您可以看到在示例中ext4文件系统是通过访问驱动器分区的设备节点而创建的。在安装典型的Linux发行版期间,将以相同的方式创建文件系统,除了在实际驱动器上使用分区的设备节点,而不是在本示例中使用的循环设备。

参考:

  • Arch Linux安装指南:link
  • Gentoo安装手册:link