Skip to content

Commit 65b93f7

Browse files
Add a new tutorial explaining how to create a small SD card image (#39)
1 parent 6281eed commit 65b93f7

File tree

1 file changed

+199
-0
lines changed

1 file changed

+199
-0
lines changed

tutorials/create_sd_image.md

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
---
2+
sort: 8
3+
---
4+
5+
# Creating a backup of your SD card
6+
7+
You may find it helpful to take an image of your Turtlebot's microSD card. This makes it easy to
8+
restore a backup, or deploy the same image to multiple robots by flashing the same image to
9+
multiple cards.
10+
11+
## Clean up the image
12+
13+
Before creating the image, you may find it helpful to clean up some automatically-generated files
14+
from the Raspberry Pi. This can reduce the size of the image.
15+
16+
SSH into the Turtlebot and run any or all of the following commands:
17+
```bash
18+
# Empty journalctl logs
19+
sudo journalctl --flush --rotate
20+
sudo journalctl --vacuum-time=1s
21+
22+
# Clean cached apt packages
23+
sudo apt clean
24+
25+
# Empty Bash History
26+
rm .bash_history
27+
history -c
28+
```
29+
30+
## Remove the microSD card
31+
32+
Once you have cleaned the system, power off the Turtlebot and remove the microSD card from the
33+
Raspberry Pi. Plug the card into your laptop (you may need an adaptor if your computer does not
34+
have a built-in microSD card reader).
35+
36+
Open a terminal and perform the following steps.
37+
38+
## Determine the card's device file
39+
40+
Determine the microSD card's device handle on your laptop. Run `lsblk -d -e7` in a terminal to
41+
list connected storage devices. The output should look something like this:
42+
```
43+
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
44+
mmcblk0 179:0 0 29.7G 0 disk
45+
nvme0n1 259:0 0 476.9G 0 disk
46+
```
47+
48+
Find the drive whose size is closest to your microSD card and note its name. In the example above
49+
a 32GB card is used, so the 29.7G drive, named `mmcblk0` is the card. Note this name for subsequent
50+
steps. Anytime in the following instructions, wherever you see `mmcblk0` replace it with your SD
51+
card's file if it is different.
52+
53+
```warning
54+
The following steps will make modifications to your SD card. To make a simple backup that will not
55+
modify the SD card, run
56+
57+
`sudo dd if=/dev/mmcblk0 of=my_turtlebot_backup.img status=progress`
58+
59+
This will produce a much larger image on-disk, but will not modify the SD card you are copying.
60+
```
61+
62+
## Shrink the filesystem
63+
64+
```warning
65+
This step will modify the SD card.
66+
```
67+
68+
Typically the file system on the microSD card will not take up the entire drive. By shrinking the
69+
filesystem we can reduce the size of the image we will create. Run the following commands,
70+
replacing `mmcblk0` with the name of your card if necessary.
71+
72+
Unmount the partitions if they are mounted:
73+
```bash
74+
for part in $(ls /dev/mmcblk0p*); do
75+
sudo umount $part
76+
done
77+
```
78+
79+
Determine the size of the main storage partition. Using the standard Turtlebot SD card images, this
80+
is partition `p2`. If you have created your own custom image the partition may be different.
81+
```bash
82+
sudo e2fsck -f /dev/mmcblk0p2
83+
```
84+
This will output something like this:
85+
```
86+
e2fsck 1.47.0 (5-Feb-2023)
87+
Pass 1: Checking inodes, blocks, and sizes
88+
Pass 2: Checking directory structure
89+
Pass 3: Checking directory connectivity
90+
Pass 4: Checking reference counts
91+
Pass 5: Checking group summary information
92+
writable: 194593/1868256 files (0.5% non-contiguous), 1770531/7660411 blocks
93+
```
94+
Note the final line where it specifies the number of blocks used, `1770531` in the example
95+
above.
96+
97+
Determine the block size by running
98+
```bash
99+
sudo tune2fs -l /dev/mmcblk0p2 |grep -i "block size"
100+
```
101+
This will produce output like this, indicating the block size in bytes:
102+
```
103+
Block size: 4096
104+
```
105+
106+
Multiply the number of used blocks (`1770531`) by the block size (`4096`) to determine the number
107+
of bytes used by the filesystem, `1770531 * 4096 = 7252094976` in this example. Round this value
108+
up slightly to get the number of gigabytes to resize the filesystem to. It is advisable to add a
109+
little extra room, e.g. 0.25 to 0.5GB to make sure there's extra room in the filesystem the first
110+
time it boots. In this example we have approximately 7.25GB used, so we will round up to 7.5GB.
111+
112+
Resize the filesystem by running
113+
```bash
114+
sudo resize2fs /dev/mmcblk0p2 7.5G
115+
```
116+
117+
After resizing, re-run
118+
```bash
119+
sudo e2fsck -f /dev/mmcblk0p2
120+
```
121+
to make sure nothing was corrupted.
122+
123+
## Shrink the partition
124+
125+
```warning
126+
This step will modify the SD card.
127+
```
128+
129+
After shrinking the filesystem we can resize the actual partition. The instructions below assume
130+
you are using the standard Turtlebot 4 SD card image, where the user data is stored on the second
131+
partition. If you have a custom image you may need to resize a different partition.
132+
133+
Run the following command:
134+
```bash
135+
sudo parted /dev/mmcblk0
136+
```
137+
`parted` is a command-line tool with many options.
138+
139+
Run the `print` command to print the size of the partition in GiB. One GiB is `2^30 = 1073741824`
140+
bytes, as opposed to one GB which is `10^9 = 1000000000` bytes, so the numbers printed will not
141+
necessarily be the same as in previous steps. The output of the `print` command will look
142+
something like this:
143+
```
144+
Model: SD SP32G (sd/mmc)
145+
Disk /dev/mmcblk0: 31.9GB
146+
Sector size (logical/physical): 512B/512B
147+
Partition Table: msdos
148+
Disk Flags:
149+
150+
Number Start End Size Type File system Flags
151+
1 1049kB 538MB 537MB primary fat32 boot, lba
152+
2 538MB 31.9GB 31.4GB primary ext4
153+
```
154+
155+
Note that the sizes are in MiB and GiB, despite using "MB" and "GB" units. (One MiB is
156+
`2^20 = 1048576` bytes.)
157+
158+
Starting with the size of the filesystem from the previous step (7.5GB for this example), increase
159+
the size by 0.2. Multiply this result by `2^30`: `(7.5 + 0.2) * 2^30 = 7.7 * 1073741824 = 8267812044.8`.
160+
161+
Add this value to the start position of partition `2` in bytes (`538 * 2**20 = 564133888`):
162+
`8267812044.8 + 564133888 = 8831945932.8`. Divide this value by the block size of `512`:
163+
`8831945932.8 / 512 = 17249894.4`. Round this value up to the next `1000` to get the new end sector
164+
for partition `2`: `17249894.4 -> 17250000`. Note this number for the next step.
165+
166+
In `parted` run the following command to resize the partition:
167+
```
168+
resizepart 2 17250000s
169+
```
170+
Note that the `s` after the number is required to specify the end sector.
171+
172+
When the operation completes re-run the `print` command to make sure the change was applied.
173+
Quit `parted` by typing `quit`.
174+
175+
In the `bash` terminal, check the number of sectors in the disk:
176+
```bash
177+
sudo fdisk -l /dev/mmcblk0
178+
```
179+
180+
## Make the image
181+
182+
Finally we can create the SD card image using the `dd` command:
183+
```bash
184+
sudo dd if=/dev/mmcblk0 of=turtlebot4_custom_sd_image.img bs=512 count=17250000 status=progress
185+
```
186+
with the following substitutions:
187+
- `if` is set to the SD card's device file,
188+
- `of` is the name you wish to give the image, and
189+
- `count` is the number of the end sector determined in the previous step.
190+
191+
## Flashing the image
192+
193+
You can flash your new Turtlebot4 image by following the
194+
[same steps](../setup/basic.md#install-latest-raspberry-pi-image) you would use to install the
195+
latest official SD card image for your robot:
196+
```bash
197+
wget https://raw.githubusercontent.com/turtlebot/turtlebot4_setup/jazzy/scripts/sd_flash.sh
198+
bash sd_flash.sh turtlebot4_custom_sd_image.img
199+
```

0 commit comments

Comments
 (0)