Shrinking images on Linux

When creating images from existing ISOs you often need to allocate a number of MB for the image to at least fit the files that are in the ISO. Predicting the exact size of the image is hard, even for a program. In this case you will create an image that is larger than actually needed: the image is much larger than the files on the image are combined.

This post will show how to shrink an existing image to a more optimal size. We will do this on Linux, since all required tools are available there: GParted, fdisk and truncate.

Requirements

  • A Linux PC
  • Some knowledge how the terminal works will helps
  • The unoptimal image (myimage.img in this example)

Creating loopback device
GParted is a great application that can handle partition tables and filesystems quite well. In this tutorial we will use GParted to shrink the filesystem (and its accompaning partition in the partition table).

GParted operates on devices, not simple files like images. This is why we first need to create a device for the image. We do this using the loopback-functionality of Linux.

First we will enable loopback if it wasn‘t already enabled:

$ sudo modprobe loop

Now we can request a new (free) loopback device:

$ sudo losetup -f

This will return the path to a free loopback device. In this example this is /dev/loop0.

Next we create a device of the image:

$ sudo losetup /dev/loop0 myimage.img

Now we have a device /dev/loop0 that represents myimage.img. We want to access the partitions that are on the image, so we need to ask the kernel to load those too:

$ sudo partprobe /dev/loop0

This should give us the device /dev/loop0p1, which represents the first partition in myimage.img. We do not need this device directly, but GParted requires it.

Resize partition using GParted
Next we can load the device using GParted:

$ sudo gparted /dev/loop0

This should show a window similar to the following:

Now notice a few things:

  • There is one partition.
  • The partition allocates the entire disk/device/image.
  • The partition is filled partly.

We want to resize this partition so that is fits it content, but not more than that.

Select the partition and click Resize/Move. A window similar to the following will popup:

Drag the right bar to the left as much as possible.

Note that sometimes GParted will need a few MB extra to place some filesystem-related data. You can press the up-arrow at the New size-box a few times to do so. For example, I pressed it 10 times (=10MiB) for FAT32 to work. For NTFS you might not need to at all.

Finally press Resize/Move. You will return to the GParted window. This time it will look similar to the following:

Notice that there is a part of the disk unallocated. This part of the disk will not be used by the partition, so we can shave this part off of the image later. GParted is a tool for disks, so it doesn‘t shrink images, only partitions, we have to do the shrinking of the image ourselves.

Press Apply in GParted. It will now move files and finally shrink the partition, so it can take a minute or two, most of the time it finishes quickly. Afterwards close GParted.

Now we don‘t need the loopback-device anymore, so unload it:

$ sudo losetup -d /dev/loop0

Shaving the image

Now that we have all the important data at the beginning of the image it is time to shave of that unallocated part. We will first need to know where our partition ends and where the unallocated part begins. We do this using fdisk:

$ fdisk -l myimage.img

Here we will see an output similar to the following:

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

Note two things in the output:

  • The partition ends on block 9181183 (shown under End)
  • The block-size is 512 bytes (shown as sectors of 1 * 512)

We will use these numbers in the rest of the example. The block-size (512) is often the same, but the ending block (9181183) will differ for you. The numbers mean that the parition ends on byte 9181183*512 of the file. After that byte comes the unallocated-part. Only the first 9181183*512 bytes will be useful for our image.

Next we shrink the image-file to a size that can just contain the partition. For this we will use the truncate command (thanks uggla!). With the truncate command need to supply the size of the file in bytes. The last block was 9181183 and block-numbers start at 0. That means we need (9181183+1)*512 bytes. This is important, else the partition will not fit the image. So now we use truncate with the calculations:

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

Now copy the new image over to your phone, where it should act exactly the same as the old/big image.

时间: 2024-10-10 22:28:11

Shrinking images on Linux的相关文章

linux 逻辑卷管理 调整分区大小

测试机各种报错,创建个目录都报错,df看了一下,发现VolGroup-lv_root 100%,虚拟磁盘满了,怎么办呢 1,解决过程 # df -h //查看分区 # umount /home //取消挂载 # e2fsck -f /dev/mapper/VolGroup-lv_home //分区检测 # resize2fs -p /dev/mapper/VolGroup-lv_home 100G //将lv_home虚拟分区设为100G # mount /home //挂载home # df

Linux内核源代码情景分析-内存管理之slab-回收

在上一篇文章Linux内核源代码情景分析-内存管理之slab-分配与释放,最后形成了如下图的结构: 图 1 我们看到空闲slab块占用的若干页面,不会自己释放:我们是通过kmem_cache_reap和kmem_cache_shrink来回收的.他们的区别是: 1.我们先看kmem_cache_shrink,代码如下: int kmem_cache_shrink(kmem_cache_t *cachep) { if (!cachep || in_interrupt() || !is_chaine

Linux内核源代码情景分析-系统调用brk()

首先看下进程地址空间示意图: 我们简单的说,从低地址到高地址,代码区和数据区,空洞,堆栈区.    在Linux内核源代码情景分析-内存管理之用户堆栈的扩展,我们申请了从堆栈区往下,数据区上面的页面.    在Linux内核源代码情景分析-内存管理之用户页面的换入,我们申请了用于换入/换出的页面.    在本文中,我们申请的是从数据区往上,堆栈区下面的页面.    我们通过一个实例来分析,brk(),见下图: 1.由于新边界比旧边界地址高,我们申请旧边界和新边界之间的页面.就是把对应的虚拟地址映

Linux Process Virtual Memory

目录 1. 简介 2. 进程虚拟地址空间 3. 内存映射的原理 4. 数据结构 5. 对区域的操作 6. 地址空间 7. 内存映射 8. 反向映射 9.堆的管理 10. 缺页异常的处理 11. 用户空间缺页异常的校正 12. 内核缺页异常 13. 在内核和用户空间之间复制数据 1. 简介 用户层进程的虚拟地址空间是Linux的一个重要抽象,它向每个运行进程提供了同样的系统视图,这使得多个进程可以同时运行,而不会干扰到其他进程内存中的内容,此外,它容许使用各种高级的程序设计技术,如内存映射,学习虚

Linux中brk()系统调用,sbrk(),mmap(),malloc(),calloc()的异同【转】

转自:http://blog.csdn.net/kobbee9/article/details/7397010 brk和sbrk主要的工作是实现虚拟内存到内存的映射.在GNUC中,内存分配是这样的:       每个进程可访问的虚拟内存空间为3G,但在程序编译时,不可能也没必要为程序分配这么大的空间,只分配并不大的数据段空间,程序中动态分配的空间就是从这一块分配的.如果这块空间不够,malloc函数族(realloc,calloc等)就调用sbrk函数将数据段的下界移动,sbrk函数在内核的管理

linux进程地址空间--vma的基本操作【转】

转自:http://blog.csdn.net/vanbreaker/article/details/7855007 版权声明:本文为博主原创文章,未经博主允许不得转载. 在32位的系统上,线性地址空间可达到4GB,这4GB一般按照3:1的比例进行分配,也就是说用户进程享有前3GB线性地址空间,而内核独享最后1GB线性地址空间.由于虚拟内存的引入,每个进程都可拥有3GB的虚拟内存,并且用户进程之间的地址空间是互不可见.互不影响的,也就是说即使两个进程对同一个地址进行操作,也不会产生问题.在前面介

Kernel parameters for Db2 database server installation (Linux and UNIX)

Db2 11.1 For root installations, the database manager uses a formula to automatically adjust kernel parameter settings and eliminate the need for manual updates to these settings. Before you begin You must have root authority to modify kernel paramet

排查Linux机器是否已经被入侵

随着开源产品的越来越盛行,作为一个Linux运维工程师,能够清晰地鉴别异常机器是否已经被入侵了显得至关重要,个人结合自己的工作经历,整理了几种常见的机器被黑情况供参考 背景信息:以下情况是在CentOS 6.9的系统中查看的,其它Linux发行版类似 1.入侵者可能会删除机器的日志信息,可以查看日志信息是否还存在或者是否被清空,相关命令示例: [[email protected] ~]# ll -h /var/log/* -rw-------. 1 root root 2.6K Jul 7 18

linux下Nginx配置文件(nginx.conf)配置设置详解(windows用phpstudy集成)

linux备份nginx.conf文件举例: cp /usr/local/nginx/nginx.conf /usr/local/nginx/nginx.conf-20171111(日期) 在进程列表里 面找master进程,它的编号就是主进程号. ps -ef | grep nginx 查看进程 cat /usr/local/nginx/nginx.pid 每次修改完nginx文件都要重新加载配置文件linux命令: /usr/local/nginx -t //验证配置文件是否合法 若ngin