Limiting the capacity of SD cards for the pi

Sep 17, 2023 Last reply: 2 years ago 204 Replies

Hi,



I build images for projects on 4GB cards so that I can save a completed image without using too much disc space. My problem comes when I try to burn a new card from the saved image. Often it will not fit because there are small differences in the size of the cards.



Does anyone know of a way to reduce the capacity of an SD card so that I can make a 4GB card maybe 3.5GB which would mean all cards could easily manage it and reduce the size of the save image.


Thanks.



Bob.


formatting link
has a long and detailed description of how to do this...

...basically 'parted' to shrink the partitions and 'truncate' to shrink the dd'ed image.

I have no idea if this method works, as I have never tried it

Another method cited that again I have no experience of is Pishrink -

formatting link
This looks at a cursory glance to be a script that automates the process.

Let me know if this works as I will need a similar script in due course

Much appreciate your help, thanks.

Unfortunately, my knowledge is not great and both of those articles very quickly went way passed my understanding.

I *think* they both assume I have a linux pc, I don't, I have a W10 PC.

For another project I recently looked at getting linux to run virtual on my PC but again I quickly ran out of knowledge and couldn't do it.

Articles mostly assume far more knowledge than I have.

I was hoping to simply reduce the size of the SD card before it was even formatted. Maybe that's not possible.

Thanks anyway.

Bob.

Ah. I never thought of that. You could install Linux in a virtual machine.

Oh. Mm. Its non trivial getting virtualBox set up if you are not especially technical.

HOWEVER you should be able to get a live Linux working by installing it on a DVD or USB stick and booting from that.

Or installing Linux on some old piece of hardware left over from the Resurrection and the Roman Empire...

Tell me about it.

Well I don't think you can do THAT. What you need is an installation on e.g. a 2GB card that can never exceed the size of the 4GB target.

Frankly why not bite the bullet and install 4GB images onto 8/16GB SD cards as these are as cheap as 4GB these days?

Oh yes, I remember doing that many years ago, so it's still possible. I might give that a go.

That's *exactly* what I am doing and then expanding to fill on the

16GB card.

I'm hitting the size problem only because I save a build in stages.

1) OS up and running. 2) OS + samba running. 3) Apache or mpd ... running 4) Pihole or MediaPlayer Running.

By doing that, if I'm testing beta versions of say media player then I don't need to build from scratch.

But if when i'm building I don't use the smallest 4GB I have and build something slightly bigger it will not go on a smaller 4GB card later for the next test.

Bob.

As it happens, I've just had to do that to reduce a 16GB image on a 32GB SD card to < 8GB. I did it just using a Pi and a USB SDcard adapter, old school style.

All as root on the Pi:

  1. Clone the SD card you're trying to shrink (using dd, Win32DiskImager or whatever you normally use to read/write SD card images), just in case.
  2. Insert the cloned SD card into the USB SDcard adapter connected to a Pi. It should appear as /dev/sdc or somesuch (dmesg should show it being picked up). I'll assume /dev/sdc for this.
  3. Mount the OS partition (second one) on the local Pi:

# mkdir /mnt/x # mount /dev/sd2 /mnt/x

  1. Tar up the OS partition to the local Pi. Note this assumes there's plenty of free space on the Pi filesystem!

# cd /mnt/x # tar -czf ~/xxx.tar.gz .

  1. Unmount the OS parition:

# cd # umount /mnt/x

  1. Use fdisk to delete and recreate the second partition (ONLY!) on the SDC card:

# fdisk /dev/sdc

p ## shows current partiton table, mine looked like this:

Disk /dev/sdc: 29.7 GiB, 31914983424 bytes, 62333952 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: 0xd9b3f436

Device Boot Start End Sectors Size Id Type /dev/sdc1 8192 532479 524288 256M c W95 FAT32 (LBA) /dev/sdc2 532480 31116287 30583808 14.6G 83 Linux

(still in fdisk):

d ## Delete second partition 2

n p 2 532480 ## original start sector of the second partition from above +7G ## Or however big you want it to be y ## Wipe filesystem signature

p ## Check it looks right:

Disk /dev/sdc: 29.7 GiB, 31914983424 bytes, 62333952 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: 0xd9b3f436

Device Boot Start End Sectors Size Id Type /dev/sdc1 8192 532479 524288 256M c W95 FAT32 (LBA) /dev/sdc2 532480 15212543 14680064 7G 83 Linux

w ## Do it

  1. Create filesyetem in new partition:

# mkfs -t ext4 /dev/sdc2

  1. Mount the new (empty) partition:

# mount /dev/sd2 /mnt/x

  1. Restore the OS files into it:

# cd /mnt/x # tar -xzf ~/xxx.tar.gz

  1. Unmount it:

# cd # umount /mnt/x

  1. Now you can create an image file of the reduced boot and OS partitions that can be written to a smaller SD card. To do this I have a short script that computes the size in MB from the last sector field of the fdisk output (messy but it seems to work). Again you'll need plenty of space wherever you want to put the new image:

# last_sector=$(echo "p" | fdisk /dev/sdc | awk '/^\/dev\/sdc/ { print $3 }' | sort -n | tail -1) # n_bytes="$(((last_sector+1)*512))" # n_mb="$(((n_bytes-1)/1048576+1))" # check="$((n_mb*1048576/512))" # echo "Last sector: ${last_sector}, ${n_mb} MB, writing ${check} sectors..."

# dd if=/dev/sdc bs=1048576 count=${n_mb} | gzip > ~/newcard.img.gz

(E&OE)

Don't forget to delete the temporary tarfile.

You could do what I have been half doing, and build a script that turns a raw installation into my customised one.

Thanks Ian that's very interesting. I'll look at this after the race.

Bob.

Yes. Done.

Yes.

So sorry, I've no idea how I would see that? I was logged in to the pi via putty before I plugged the device in but nothing appeared.

I'm only using a headless light version of the pios, is that my problem or is it just ignorance?

Thanks.

Bob.

That is a second SD card adapter plugged into the Pis USB port

OK, 'sudo mount' would show what it was and where it was..

Just ignorance, but its not hard to get there.

In linux all disks systems look like *files* in the directory /dev/ The dir command in linux is 'ls' so :

'ls /dev' should show your disk in there somewhere The SD card you are running on will be /dev/mmcblk0 and its two partitions /dev/mmcblk0p1 and /dev/mmcblk0p2. These will be 'mounted' on /boot, and /

mount | grep mm

is a command uou cvan use to see where they are mounted - the '| grep mm' means 'select only lines from the output containing 'mm' e.g.

$mount | grep mm /dev/mmcblk0p2 on / type ext4 (rw,noatime) /dev/mmcblk0p1 on /boot type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)

Now if you plug another SD card into the system via a USB SD card reader that should be automatically mounted somewhere.

My guess would be in a media subdirectory of your home directory.

so

$mount | grep media should tell you what it is called.

In Linux it is conventional that the whole disk will be files as /dev/something, and partitions on it will be /dev/somethinga or /dev/somethingb or /dev/somethingp1

etc...

These are all the *device names*you will need in order to manipulate the partitions and the raw SD card

In putty try typing: dmesg (and hit enter) or sudo dmesg (and hit enter) if you're not logged in as root.

Yes, that's about it. I see this from dmesg after the SD card is inserted:

[ 4259.125974] usb-storage 1-1.1.3:1.0: USB Mass Storage device detected [ 4259.127272] scsi host0: usb-storage 1-1.1.3:1.0 [ 4260.181673] scsi 0:0:0:0: Direct-Access Generic STORAGE DEVICE 9325 PQ: 0 ANSI: 0 [ 4260.183483] scsi 0:0:0:1: Direct-Access Generic STORAGE DEVICE 9325 PQ: 0 ANSI: 0 [ 4260.185400] scsi 0:0:0:2: Direct-Access Generic STORAGE DEVICE 9325 PQ: 0 ANSI: 0 [ 4260.187328] scsi 0:0:0:3: Direct-Access Generic STORAGE DEVICE 9325 PQ: 0 ANSI: 0 [ 4260.223150] sd 0:0:0:2: [sdc] Attached SCSI removable disk [ 4260.224466] sd 0:0:0:0: [sda] Attached SCSI removable disk [ 4260.227173] sd 0:0:0:3: [sdd] Attached SCSI removable disk [ 4260.232037] sd 0:0:0:1: [sdb] Attached SCSI removable disk [ 4346.699670] sd 0:0:0:2: [sdc] 62333952 512-byte logical blocks: (31.9 GB/29.7 GiB) [ 4346.707646] sdc: sdc1 sdc2 [ 4346.720048] sdc: sdc1 sdc2

If you're running any kind of desktop environment that may get in the way and mount the SD card in odd places, though if you're running a minimal system that shouldn't be an issue.

All the commands are standard Linux ones, so should be present.

I suggest you do "sudo bash" if you're not logging in as root, makes things simpler :)

Yes it is.

sudo mount gives me a half a page of text no meaning to me.

But after some googling I did find the command :

lsblk

That shows this...

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 1 3.6G 0 disk

+-sda1 8:1 1 256M 0 part +-sda2 8:2 1 3.4G 0 part mmcblk0 179:0 0 14.8G 0 disk +-mmcblk0p1 179:1 0 256M 0 part /boot +-mmcblk0p2 179:2 0 14.6G 0 part /

Despite one website telling me that sda would be the machines hard disc I worked out that it wasn't. sda is the sd inserted via usb. mmcblk0 is the harddrive.

So I tried to go a bit further...

mkdir /mnt/x gave Permission denied. sudo mkdir /mnt/x sudo mount /dev/sda2 /mnt/x cd /mnt/x all the above seemed to work.

tar -czf ~/xxx.tar.gz gave Cowardly refusing to create an empty archive. I thought maybe I was supposed to substitute some items in that command.

Thanks for the help it is appreciated.

That looks correct.

That's clever: :-)

That doesn't come back with anything, no error, nothing.

Thanks for that, I'm learning, slowly.

I think the usb device sd is /dev/sda with the main partition /dev/sda2 does that sound correct?

Interesting.

That gave me a huge list of text but I'm not sure where that helps me.

Thanks for the suggestion.

Bob.

This is a Pi. It likes to be different

yes.

man tar will tell you te tar commands,.

I think what you want is tar cfz <directory> <output file>

But a GUI has mane me lazy and I cant remember

So its miunted somwheer else.

Yes. If its a PI card /dev/sda1 will be the thing that ends up as /boot

- which is a msdos partioned thing. VFAT I think

"mount | grep sda" will tell you where they ended up.

Well I've looked at and read man tar and downloaded the full manual. At the moment it is a long way passed me making sense of it so I'm stumped for now.

Thanks everyone for your help.

Cheers,

Bob.

Nothing needs substituting, you're just missing the "." as the final parameter:

(That says what to put in the tarball, "." means the current directory)

<cut>

You already solved the problem, so it is no longer useful. You already discovered that your USB device is /dev/sda.

However, as someone already hinted before me, typing dmesg in putty should tell you that, if you type it just after inserting the USB in the port.

Since the horse already left the stable, you can put all this in the afterburner.

Thanks Ian, I would never have worked that out myself.

I'll have another go tomorrow.

Bob,

Good luck!

Be sure to do it all from a root shell, not via individual sudo calls btw, some of the commands need to be in the same shell as previous ones, and sudo breaks that.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required