AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 1174487
Accepted
Leos313
Leos313
Asked: 2019-09-17 01:26:09 +0800 CST2019-09-17 01:26:09 +0800 CST 2019-09-17 01:26:09 +0800 CST

为更小的 SD 卡“重新调整大小”.img。如何缩小可引导的 SD 卡映像

  • 772

语境

我有一个 16 GB 的 SD 卡,带有用于 Raspberry Pi 的基于 Linux 的操作系统。大部分空间是空的。

我想.img与其他人共享 SD 但如果我使用命令

dd if=/dev/sdXX of=/home/user123/SD.img

它将创建一个 16 GB 的图像。太大。

问题

如何将 16GB SD 卡映像重新调整为更小的 4GB?

我已经尝试过使用 GParted:它可以毫无问题地创建一个 4GB 的分区,但是整个.imgSD 卡仍然是 16 GB 和 12 GB 的未分配空间。

GParted 表

我已经阅读了在 Ubuntu 中克隆多个分区的问题和答案,但我仍然无法将 16GB SD 卡的大小重新调整为 4GB 的。

更多信息

~$ lsblk 
...

sdc      8:32   1  14,9G  0 disk 
├─sdc1   8:33   1   100M  0 part 
└─sdc2   8:34   1     4G  0 part 
~$ sudo fdisk -l /dev/sdc
Disk /dev/sdc: 14,9 GiB, 15931539456 bytes, 31116288 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
Disklabel type: dos
Disk identifier: 0xf8a631ce

Device     Boot  Start     End Sectors  Size Id Type
/dev/sdc1  *      2048  206847  204800  100M  c W95 FAT32 (LBA)
/dev/sdc2       206848 8595455 8388608    4G 83 Linux

任何建议表示赞赏!

请注意:正如 Melebius 在评论中所观察到的,正确使用的词是收缩:

您无法调整 SD 卡的大小,因为它是具有给定容量且无法更改的硬件。您显然想要缩小 SD 卡映像。

resize partitioning disk-image dd sd-card
  • 5 5 个回答
  • 40577 Views

5 个回答

  • Voted
  1. Best Answer
    Leos313
    2019-09-17T03:11:48+08:002019-09-17T03:11:48+08:00

    本文给出了解决我的问题的解决方案(*)。它与另一个非常相似,但它更好地解释了如何计算以及数字和分区的含义。

    关键信息是命令的使用truncate。遵循完整的解决方案,以免丢失答案。

    初步步骤包括在您的 PC 中克隆 SD 卡:

    1. 用于lsblk查看哪些设备可用以及它们的分区是否已挂载

    2. 卸载要在 PC 上复制的设备的所有分区。例如:

       umount /dev/sdc1
       umount /dev/sdc2
      
    3. 创建整个 SD 卡的副本,其中所有分区都已卸载

       dd if=/dev/sdc of=/path/to/file/myimage.img
      

    在 Linux 上缩小图像

    问题的背景:

    拥有myimage.img更大的硬件支持(如果它更小应该没有问题;但是,使用相同的策略,您可以更好地使图像适合硬件支持)。

    秘诀是使用标准的 Linux 工具和工具:GPartedfdisk和truncate.

    要求:

    • 一台 Linux 电脑
    • .img你想要缩小的(myimage.img在这个例子中)

    创建环回设备:

    GParted 是一个通常用于管理分区表和文件系统的应用程序。为了缩小图像,将在答案的第一部分使用 GParted。

    GParted 在设备上运行,而不是像图像这样的简单文件。这就是为什么我们首先需要为图像创建一个设备。我们使用 Linux 的环回功能来做到这一点。

    让我们启用环回:

    sudo modprobe loop
    

    让我们请求一个新的(免费)环回设备:

    sudo losetup -f
    

    该命令返回到空闲环回设备的路径:

    /dev/loop0
    

    让我们创建一个图像的设备:

    sudo losetup /dev/loop0 myimage.img
    

    该设备/dev/loop0代表myimage.img. 我们想要访问映像上的分区,所以我们需要让内核也加载这些分区:

    sudo partprobe /dev/loop0
    

    这应该给我们设备/dev/loop0p1,它代表 中的第一个分区myimage.img。我们并不直接需要这个设备,但 GParted 需要它。

    使用 GParted 调整分区大小:

    让我们使用 GParted 加载新设备:

    sudo gparted /dev/loop0
    

    当 GParted 应用程序打开时,它应该会出现一个类似于以下内容的窗口:

    截屏

    现在注意几点:

    • 有一个分区。
    • 分区分配整个磁盘/设备/映像。
    • 分区被部分填充。

    我们想调整这个分区的大小,使其适合其内容,但仅此而已。

    选择分区并单击调整大小/移动。将弹出一个类似于以下的窗口:

    对话框截图

    将右栏尽可能向左拖动。

    请注意,有时 GParted 需要额外的几 MB 来放置一些与文件系统相关的数据。您可以按几次新尺寸框上的向上箭头来执行此操作。例如,我按了 10 次 (=10MiB) 以使 FAT32 工作。对于 NTFS,您可能根本不需要。

    最后按调整大小/移动。您将返回到 GParted 窗口。这次它看起来类似于以下内容:

    右侧未分配空间

    请注意,有一部分磁盘未分配。这部分磁盘不会被分区使用,因此我们可以稍后将这部分从映像中剔除。GParted是一个磁盘工具,所以它不收缩镜像,只有分区,我们必须自己做镜像的收缩。

    按ApplyGParted。它现在将移动文件并最终缩小分区,因此可能需要一两分钟,但大多数情况下它会很快完成。然后关闭 GParted。

    现在我们不再需要 loopback-device 了,所以卸载它:

    sudo losetup -d /dev/loop0
    

    剃须图像:

    现在我们在图像的开头有了所有重要的数据,是时候去掉那些未分配的部分了。我们首先需要知道我们的分区在哪里结束以及未分配部分从哪里开始。我们使用fdisk:

    fdisk -l myimage.img
    

    在这里,我们将看到类似于以下的输出:

    Disk myimage.img: 6144 MB, 6144000000 bytes, 12000000 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 identifier: 0x000ea37d
    
          Device Boot      Start         End      Blocks   Id  System
    myimage.img1            2048     9181183     4589568    b  W95 FAT32
    

    注意输出中的两件事:

    • 分区结束于块 9181183(如下所示End)
    • 块大小为 512 字节(显示为 的扇区1 * 512)

    我们将在示例的其余部分中使用这些数字。块大小 (512) 通常是相同的,但结束块 (9181183) 会因您而异。这些数字表示分区在文件的字节 9181183 512 处结束。在那个字节之后是未分配部分。只有前 9181183 512 个字节对我们的图像有用。

    接下来,我们将图像文件缩小到可以包含分区的大小。为此,我们将使用truncate命令(感谢 uggla!)。使用 truncate 命令需要以字节为单位提供文件的大小。最后一个块是 9181183,块号从 0 开始。这意味着我们需要 (9181183+1)*512 字节。这很重要,否则分区将不适合图像。所以现在我们使用 truncate 进行计算:

    truncate --size=$[(9181183+1)*512] myimage.img
    

    (*) FrozenCow 的原帖好像已经移到这里了。

    • 32
  2. mook765
    2019-09-17T02:05:30+08:002019-09-17T02:05:30+08:00

    您可以使用选项bs和-command 来限制输出文件count的dd大小。

    例子:

    dd if=sdx of=SD.img bs=1G count=4
    

    将产生一个大小为 4 GiB 的输出文件。

    深入了解man dd.

    您需要知道必须复制多少字节才能完全覆盖所有分区,因此请查看sudo fdisk -l /dev/sdx哪个扇区是您需要的最后一个扇区。

    分区需要位于磁盘的开头(如您提供的图片中所示)。

    带有 msdos-partition-table 的磁盘可以通过这种方式轻松克隆,但是如果磁盘使用 GPT 并且要克隆到不同大小的磁盘,则需要调整保护性 MBR 和驻留在最需要重新创建磁盘的末尾,这可以使用gdisk.


    从你的fdisk-output 你可以看到最后一个分区的最后一个扇区是扇区8595455,这意味着你必须复制至少 8595455+1 个扇区(第一个扇区是 0)。对于 512 字节的扇区大小,这等于 4,400,873,472 字节。bs乘以count必须大于或等于此。

    也许这对于一个 4GB 的 U 盘来说还是太大了,你仍然可以减小它的大小sdc2,里面还有很多未使用的空间。

    对于您提供的当前示例,

     dd if=/dev/sdc of=SD.img bs=10M count=420
    

    将覆盖分区表,sdc1并且sdc2. 计算:

    10*1024*1024*420 = 4,404,019,200 > 4,400,873,472
    
    • 3
  3. user1040155
    2020-02-02T23:02:21+08:002020-02-02T23:02:21+08:00

    resize2fs也可以用来调整它的大小。

    sudo resize2fs -fp SD.img 4G
    

    它还会调整文件本身的大小!

    • 3
  4. mp3k
    2021-02-16T01:04:01+08:002021-02-16T01:04:01+08:00

    所选答案完全适用于dos disklabel 类型。对于GPT类型,需要考虑添加 33 个扇区,因为 GPT 在磁盘末尾也存储了一张表。

    因此,对于 GPT 用户,“截断”命令需要如下所示:

    截断 --size=$[( End_of_last_partition + 1 + 33 )*512] myimage.img

    这应该会在fdisk -l. 要解决此问题,请运行以下命令:

    gdisk myimage.img
    

    运行命令以验证磁盘: v. 您应该会在磁盘上看到一些错误。

    “在 gdisk 中,你可以输入x进入专家菜单,然后输入e将备份分区表数据移动到磁盘的新端,然后输入w将更改写入磁盘。” [来源]如何在不损坏 GPT 分区表(结束指针)的情况下截断未使用空间的磁盘映像文件- 谢谢!

    • 3
  5. slm
    2022-01-30T14:23:30+08:002022-01-30T14:23:30+08:00

    浏览了这里的许多方法,我理解了所有这些方法,但这些步骤是我不期待的,因为必须依次执行它们以简单地缩小 Raspberry Pi IMG 文件。因此,我从一个名为PiShrink的项目中发现了这个 Bash 脚本。

    执行起来非常简单,它可以在我的 MacOS M1 Mac Mini 上启动。

    背景故事

    在我的特殊情况下,我有 2 个 32GB SD 卡,无论出于何种原因,1 比另一个稍小(~95MB),balenaEtcher拒绝将 IMG 从 2 个 SD 卡中的较大者写入较小的部分。

    我知道我只使用了 32GB 中的约 10GB,所以我可以缩小 IMG 文件以适应。

    脚步

    首先,我有以下文件。该.zip文件包含该.img文件,但我在下面显示它是从它解压缩的。

    $ ls -lh | grep -E 'img|zip'
    -rw-r--r--  1 root staff  28G Jan 29 13:16 backup.zip
    --w--wx-w-  1 slm  staff  30G Jan  1  1980 disk.img
    

    然后我下载了 PiShrink shell 脚本并使其可执行:

    $ wget https://raw.githubusercontent.com/Drewsif/PiShrink/master/pishrink.sh
    $ chmod +x pishrink.sh
    

    然后我像这样运行它:

    $ sudo pishrink disk.img pi.img
    Copying disk.img to pi.img...
    e2fsck 1.44.0 (7-Mar-2018)
    Pass 1: Checking inodes, blocks, and sizes
    Pass 2: Checking directory structure
    Pass 3: Checking directory connectivity
    Pass 4: Checking reference counts
    Pass 5: Checking group summary information
    STORAGE: 69402/7684096 files (0.2% non-contiguous), 9562823/30732288 blocks
    resize2fs 1.44.0 (7-Mar-2018)
    resize2fs 1.44.0 (7-Mar-2018)
    Resizing the filesystem on /dev/disk4s2 to 9273700 (1k) blocks.
    Begin pass 2 (max = 245358)
    Relocating blocks             XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Begin pass 3 (max = 3752)
    Scanning inode table          XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Begin pass 4 (max = 3420)
    Updating inode references     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    The filesystem on /dev/disk4s2 is now 9273700 (1k) blocks long.
    
    "disk4" ejected.
    fdisk: could not open MBR file /usr/standalone/i386/boot0: No such file or directory
    Enter 'help' for information
    fdisk: 1>          Starting       Ending
     #: id  cyl  hd sec -  cyl  hd sec [     start -       size]
    ------------------------------------------------------------------------
     2: 83 1023   3  32 - 1023 254   2 [   1056768 -   61464576] Linux files*
    Partition id ('0' to disable)  [0 - FF]: [83] (? for help) Do you wish to edit in CHS mode? [n] Partition offset [0 - 62521344]: [1056768] Partition size [1 - 61464576]: [61464576] fdisk:*1> Writing MBR at offset 0.
    fdisk: 1> Shrunk pi.img from 30G to 9.3G
    

    生成的 IMG 文件现在约为 9GB。

    $ ls -lh | grep -E 'img|zip'
    -rw-r--r--  1 root staff  28G Jan 29 13:16 backup.zip
    --w--wx-w-  1 slm  staff  30G Jan  1  1980 disk.img
    --w---x---  1 root staff 9.4G Jan 29 17:04 pi.img
    

    然后我将它重新打包为 ZIP 文件,以便在磁盘上处理它时尽可能保持最有效的大小。

    $ sudo zip pi.zip pi.img
    

    我们现在有以下一组文件:

    $ ls -lh | grep -E 'img|zip'
    -rw-r--r--  1 root staff  28G Jan 29 13:16 backup.zip
    --w--wx-w-  1 slm  staff  30G Jan  1  1980 disk.img
    --w---x---  1 root staff 9.4G Jan 29 17:04 pi.img
    -rw-r--r--  1 root staff 8.3G Jan 29 17:08 pi.zip
    

    然后我可以使用balenaEtcher或ApplePi-Baker将 ZIP 文件刻录到“较小”的 SD 卡上。

    ss01

    在我的 Mac 上戳 SD 卡,我可以看到它显示 ~10GB。

    $ diskutil list /dev/disk4
    /dev/disk4 (external, physical):
       #:                       TYPE NAME                    SIZE       IDENTIFIER
       0:     FDisk_partition_scheme                        *31.9 GB    disk4
       1:             Windows_FAT_32 LIBREELEC               536.9 MB   disk4s1
       2:                      Linux                         10.0 GB    disk4s2
                        (free space)                         21.3 GB    -
    

    注意:我可以使用lsblk等从 Linux 系统执行相同的命令。

    后期操作

    使用上述方法后,我确实注意到 SD 卡中的文件系统不足 32GB。主要是这样显示的:

    $ df -h | grep -E "File|mmc"
    Filesystem                Size      Used Available Use% Mounted on
    /dev/mmcblk0p1          511.7M    141.7M    370.0M  28% /flash
    /dev/mmcblk0p2            8.6G      8.2G    377.4M  96% /storage
    

    启动备份后,通过从内部扩展 SD 文件系统应该可以轻松解决此问题。

    首先,我首先使用parted扩展分区:

    $ parted /dev/mmcblk0 resizepart 2 100%
    Warning: Partition /dev/mmcblk0p2 is being used. Are you sure you want to
    continue?
    Yes/No? yes
    yes
    Information: You may need to update /etc/fstab.
    

    然后我重新启动了系统:

    $ reboot
    

    在我使用以下方法在线扩展文件系统之后resize2fs:

    $ resize2fs /dev/mmcblk0p2
    resize2fs 1.45.6 (20-Mar-2020)
    Filesystem at /dev/mmcblk0p2 is mounted on /storage; on-line resizing required
    old_desc_blocks = 71, new_desc_blocks = 234
    The filesystem on /dev/mmcblk0p2 is now 30638592 (1k) blocks long.
    
    

    现在它显示了 SD 卡上的所有可用空间:

    $ df -h | grep -E "File|mmc"
    Filesystem                Size      Used Available Use% Mounted on
    /dev/mmcblk0p1          511.7M    141.7M    370.0M  28% /flash
    /dev/mmcblk0p2           28.3G      8.2G     20.1G  29% /storage
    
    • 2

相关问题

  • 如何通过命令行轻松调整图像大小?

  • Linux 文件系统层次结构中的默认目录是什么意思?

  • 如何将 /usr 移动到新分区?

  • 如何从双启动计算机访问加密的主文件夹?

  • 您对台式机和家庭服务器的驱动器分区方案有什么建议?[关闭]

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve