Sao chép cài đặt Raspbian hiện có vào thẻ SD nhỏ hơn


25

Có thể sao chép bản cài đặt Raspbian hiện có và được định cấu hình sang thẻ SD nhỏ hơn không?

Khi tôi cài đặt Raspbian lần đầu tiên, tôi chỉ có một thẻ 32 GB trong tay, rõ ràng là lớn hơn mức cần thiết.


Hệ thống sẽ chạy tốt hơn và thẻ sẽ tồn tại lâu hơn với nhiều không gian trống hơn trong phân vùng chính của bạn, vì vậy đừng thu nhỏ nó quá nhiều - hãy giữ cho nó ít nhất gấp đôi mức sử dụng của bạn (ví dụ: nếu hệ thống của bạn là 2-3 GB, hãy sử dụng Thẻ 8GB và phát triển phân vùng để lấp đầy tất cả không gian có sẵn). Lưu ý rằng nếu bạn không phát triển phân vùng để bắt đầu, nó sẽ không phải là 32 GB, vì vậy bạn có thể không phải thu nhỏ nó.
goldilocks

Cảm ơn bạn đã chỉ ra điều này nhưng Raspberry của tôi hiện chỉ sử dụng 1,8 GB vì nó cài đặt thực sự cơ bản. Vì vậy, tôi đoán 4 GB là đủ.
mwld

Tôi đoán rằng tôi đã tăng nó lên hết cỡ khi lần đầu tiên cài đặt Debian Wheezy. Bây giờ tôi đã thu nhỏ nó xuống 2,5 GB nhưng vẫn không thành công. Xem những bình luận của tôi bên dưới.
mwld


1
Nếu một trong những câu trả lời dưới đây thỏa mãn câu hỏi của bạn, vui lòng kiểm tra câu trả lời.
Wes Modes

Câu trả lời:


12

Trong câu trả lời này, tôi trình bày những việc cần làm từng bước để mọi người hiểu logic đằng sau giải pháp và để có thể áp dụng các bước trong các vấn đề khác của họ.

Nhưng trước tiên, cần phải nói rằng đây là một vấn đề chung (không phải là raspi) để di chuyển các hệ thống tệp từ thẻ SD sang thẻ SD nhỏ hơn (nhưng đủ lớn cho dữ liệu).

Yêu cầu

Một máy tính xách tay có đầu đọc thẻ micro SD và Linux (tôi thích Ubuntu) chạy trên nó.

Các từ viết tắt

PIBOX      : Raspberry Pi which is used
SD_CARD_A  : 8GB micro SD card which is used on PIBOX and on which Raspbian-lite (the OS) is installed
SD_CARD_B  : 2GB micro SD card which will be used on PIBOX and on which Raspbian-lite (the OS) will be installed

Phân vùng của SD_CARD_A

Trong khi PIBOX đang chạy, chúng tôi liệt kê các phân vùng (phân vùng hệ thống không cần thiết không được hiển thị ở đây).

root@pibox:~# df -Th
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/root      ext4      7.3G  1.1G  5.9G  16% /
/dev/mmcblk0p1 vfat       63M   21M   43M  33% /boot

Có 2 phân vùng trên SD_CARD_A là //boot. Ngay cả 2GB cũng không được sử dụng.

Sao lưu SD_CARD_A

Sau khi chúng tôi tắt máy và tạm dừng PIBOX, chúng tôi rút SD_CARD_A ra khỏi bảng PIBOX và đưa nó vào đầu đọc thẻ của máy tính xách tay của chúng tôi.

Các phân vùng của SD_CARD_A được tự động gắn vào hệ thống của chúng tôi /dev/sdc1/dev/sdc2.

root@mylaptop:~# df -Th
Filesystem                    Type      Size  Used Avail Use% Mounted on
/dev/sdb2                     ext4       22G   13G  7.9G  63% /
/dev/sdb1                     vfat      197M  2.6M  195M   2% /boot/efi
/dev/sda8                     ext4       66G   11G   52G  17% /home
/dev/sdc1                     vfat       63M   21M   43M  33% /media/some_user_name/boot
/dev/sdc2                     ext4      7.3G  1.1G  5.9G  16% /media/some_user_name/some_uuid_serial

Chúng tôi ngắt kết nối các phân vùng khỏi hệ thống của chúng tôi để vận hành chúng thành công.

root@mylaptop:~# umount /dev/sdc1
root@mylaptop:~# umount /dev/sdc2

Chúng tôi hiển thị thông tin thiết bị của SD_CARD_A chi tiết để xác nhận trong các bước tiếp theo.

root@mylaptop:~# fdisk -l /dev/sdc
Disk /dev/sdc: 7969 MB, 7969177600 bytes
246 heads, 62 sectors/track, 1020 cylinders, total 15564800 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: 0x2019f6d8

   Device Boot      Start         End      Blocks   Id  System
/dev/sdc1            8192      137215       64512    c  W95 FAT32 (LBA)
/dev/sdc2          137216    15564799     7713792   83  Linux

Ở trên bạn có thể thấy rằng SD_CARD_A có dung lượng 8GB.

Chúng tôi sao chép SD_CARD_A vào tệp pibox.img.

root@mylaptop:~# dd bs=4MB if=/dev/sdc of=pibox.img
1992+1 records in
1992+1 records out
7969177600 bytes (8.0 GB) copied, 416.582 s, 19.1 MB/s

Kiểm tra kích thước của các byte được sao chép, nó bằng với giá trị chúng ta nhận được bằng fdisk -l /dev/sdclệnh.

Mô-đun loopback Linux

Linux có một mô-đun gọi là loopback cung cấp cho chúng tôi xử lý tệp dưới dạng một thiết bị khối.

Chúng tôi tải mô-đun loopback.

root@mylaptop:~# modprobe loop

Chúng tôi tìm thấy một đường dẫn thiết bị loopback không sử dụng.

root@mylaptop:~# losetup -f /dev/loop0

Bây giờ, chúng tôi tạo một thiết bị loopback cho tệp pibox.img.

root@mylaptop:~# losetup /dev/loop0 pibox.img

Chúng tôi kích hoạt kernel về thay đổi phân vùng.

root@mylaptop:~# partprobe /dev/loop0

Chúng tôi xác nhận nếu các hoạt động trước đó là thành công.

root@mylaptop:~# losetup /dev/loop0
/dev/loop0: [0806]:69 (/root/pibox.img)

Chúng tôi hiển thị thông tin thiết bị loopback một cách chi tiết để so sánh nó với SD_CARD_A.

root@mylaptop:~# fdisk -l /dev/loop0
Disk /dev/loop0: 7969 MB, 7969177600 bytes
255 heads, 63 sectors/track, 968 cylinders, total 15564800 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: 0x2019f6d8

      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1            8192      137215       64512    c  W95 FAT32 (LBA)
/dev/loop0p2          137216    15564799     7713792   83  Linux

Ở trên, bạn có thể thấy rằng kích thước thiết bị loopback (= 7969177600 byte) và các phân vùng giống với SD_CARD_A's.

Toán cơ bản

Từ bây giờ, chúng tôi sẽ tập trung vào phân vùng /dev/loop0p2. Hãy đặt tên cho nó là THE_PARTATION .

Kích thước khối là 512 byte (như được in trên dòng bắt đầu bằng Đơn vị = sector .....)

THE_PARTATION bắt đầu từ khối 137216 và kết thúc ở khối 15564799, có nghĩa là nó có kích thước 15427584 blocks(= 15564799 - 137216 + 1).

Vì vậy, kích thước của THE_PARTITION tính bằng byte là 7898923008 bytes(= 512 * 15427584).

Để phù hợp với THE_PARTATION trong SD_CARD_B, chúng tôi muốn nó có kích thước mới 3710940 blocks hoặc nói cách khác 1900001280 bytes(= 512 * 3710940).

Vì vậy, số khối kết thúc mới được 3848155tính theo start block number(= 137216) + size in blocks(= 3710940) - 1.

Hệ thống tập tin so với phân vùng

Có 2 thao tác không nên nhầm lẫn với nhau.

  • Thay đổi kích thước hệ thống tập tin. Chúng tôi sẽ thu nhỏ hệ thống tệp trên THE_PARTATION bằng cách đặt kích thước của nó thành 3710940 blocks.
  • Thay đổi kích thước phân vùng. Chúng tôi sẽ thu nhỏ THE_PARTATION bằng cách đặt số khối kết thúc của nó thành 3848155.

Thu hẹp hệ thống tập tin

Trước khi thu nhỏ hệ thống tập tin, nó phải được đánh dấu là sạch bởi e2fsck.

root@mylaptop:~# e2fsck -f /dev/loop0p2
e2fsck 1.42.9 (4-Feb-2014)
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
/dev/loop0p2: 41175/475776 files (0.2% non-contiguous), 309183/1928448 blocks

Chúng tôi thu nhỏ hệ thống tập tin với resize2fs.

root@mylaptop:~# resize2fs /dev/loop0p2 3710940s
resize2fs 1.42.9 (4-Feb-2014)
Resizing the filesystem on /dev/loop0p2 to 463867 (4k) blocks.
The filesystem on /dev/loop0p2 is now 463867 blocks long.

Thu hẹp phân vùng

Chúng tôi tìm hiểu số THE_PARTATION là gì với parted.

root@mylaptop:~# parted /dev/loop0
GNU Parted 2.3
Using /dev/loop0
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print                                                            
Model: Loopback device (loop)
Disk /dev/loop0: 7969MB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start   End     Size    Type     File system  Flags
 1      4194kB  70.3MB  66.1MB  primary  fat16        lba
 2      70.3MB  7969MB  7899MB  primary  ext4

(parted) quit

Chúng tôi thu nhỏ THE_PARTATION với parted.

root@mylaptop:~# parted /dev/loop0 unit s resizepart 2 3848155
Warning: Shrinking a partition can cause data loss, are you sure you want to continue?
Yes/No? Yes  

Chúng tôi đã thực hiện với các thiết bị loopback. Chúng tôi tách nó ra.

root@mylaptop:~# losetup -d /dev/loop0

Cắt bớt tập tin hình ảnh

Chúng tôi xác minh bảng phân vùng mới.

root@mylaptop:~# fdisk -l pibox.img 

Disk pibox.img: 7969 MB, 7969177600 bytes
255 heads, 63 sectors/track, 968 cylinders, total 15564800 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: 0x2019f6d8

    Device Boot      Start         End      Blocks   Id  System
pibox.img1            8192      137215       64512    c  W95 FAT32 (LBA)
pibox.img2          137216     3848155     1855470   83  Linux

Trong đầu ra, có thể thấy rõ rằng số khối kết thúc của THE_PARTATION bị giảm from 15564799 to 3848155.

Khối cuối cùng mà chúng tôi sử dụng là 3848155. Việc đánh số khối bắt đầu từ 0. Vì vậy, chúng ta có tổng số khối 3848155 + 1 và kích thước mới của tệp pibox.img phải là 1970255872 bytes (= (3848155 + 1) * 512).

Chúng tôi cắt ngắn tập tin pibox.img.

root@mylaptop:~# truncate --size=1970255872 pibox.img

Chúng tôi xác minh kích thước mới của tệp pibox.img.

root@mylaptop:~# ls -l pibox.img 
-rw-r--r-- 1 root root 1970255872 Oct 13 21:53 pibox.img

Tạo SD_CARD_B

Chúng tôi đặt SD_CARD_B vào đầu đọc thẻ của máy tính xách tay của chúng tôi. Các phân vùng của SD_CARD_B được tự động gắn vào hệ thống của chúng tôi /dev/sdc1/dev/sdc2.

root@mylaptop:~# df -Th
Filesystem                    Type      Size  Used Avail Use% Mounted on
/dev/sdb2                     ext4       22G   13G  7.9G  63% /
/dev/sdb1                     vfat      197M  2.6M  195M   2% /boot/efi
/dev/sda8                     ext4       66G   11G   52G  17% /home
/dev/sdc1                     vfat       63M   21M   43M  33% /media/some_user_name/boot
/dev/sdc2                     ext4      1.8G  1.6G   59M  97% /media/some_user_name/some_uuid_serial

Ở trên bạn có thể thấy rằng SD_CARD_B có dung lượng 2GB.

Chúng tôi ngắt kết nối các phân vùng đó khỏi hệ thống của chúng tôi để hoạt động trên SD_CARD_B thành công.

root@mylaptop:~# umount /dev/sdc1
root@mylaptop:~# umount /dev/sdc2

Chúng tôi sao chép tệp pibox.img vào SD_CARD_B.

root@mylaptop:~# dd bs=4MB if=pibox.img of=/dev/sdc
492+1 records in
492+1 records out
1970255872 bytes (2.0 GB) copied, 646.967 s, 3.0 MB/s

Kiểm tra kích thước của các byte được sao chép, nó bằng với giá trị chúng ta nhận được bằng ls -l pibox.imglệnh.

Khởi động PIBOX

Sau khi chúng tôi lấy SD_CARD_B ra khỏi máy tính xách tay của chúng tôi và đưa nó vào bảng PIBOX, chúng tôi khởi động hệ thống và đăng nhập vào bảng điều khiển PIBOX.

Chúng tôi liệt kê các phân vùng (một số phân vùng hệ thống không cần thiết khác không được hiển thị ở đây).

root@pibox:~# df -Th
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/root      ext4      1.8G  1.1G  601M  64% /
/dev/mmcblk0p1 vfat       63M   21M   43M  33% /boot

Tốt một. Tôi nghĩ rằng một số nội dung của bạn với việc thiết lập loopback có thể dài dòng và không cần thiết, bạn có thể muốn kiểm tra xem. Một cái gì đó rất giống với một câu hỏi rất giống nhau: raspberrypi.stackexchange.com/a/29952/5538
goldilocks

@goldilocks, chưa được thử nghiệm nhưng tôi nghĩ sử dụng loopback là cần thiết. Theo như tôi biết rằng parted không thể hoạt động trực tiếp trên tập tin hình ảnh, nó cần một giao diện thiết bị cho các hoạt động của nó.
vaha

Có nhưng tôi nghĩ bạn sẽ thấy bạn không cần phải bận tâm losetuphoặc thậm chí -o loop=whatever. Theo bài đăng khác tôi chỉ sử dụng mount -o offset=123 /imagefilepath /mntpointvà việc sử dụng loopback là ẩn. Tôi cho rằng điều đó thường đúng trên linux bây giờ - hãy thử và xem. Sau đó, bạn có thể giảm điều đó xuống chỉ bằng cách nói các phân vùng được gắn kết thông qua một "thiết bị loopback" ảo.
goldilocks

5

Khi bạn sử dụng dd if=/dev/sdx of=/path/to/image bs=1M, hãy /dev/sdxtham khảo toàn bộ "đĩa", vì vậy hình ảnh sẽ luôn có kích thước của toàn bộ thẻ.

Thay vào đó, bạn cần phải sử dụng dd if=/dev/sdxn ...ở đâu nlà số phân vùng.

Có lẽ bạn sẽ cần phải làm điều này hai lần - một lần cho /bootphân vùng và một lần cho /phân vùng.

Sau đó, bạn cần tạo các phân vùng trên thẻ mới ít nhất bằng hai thẻ gốc đó để gửi lại nội dung.


3

Sử dụng một cái gì đó như parted (trình soạn thảo phân vùng) để thu nhỏ phân vùng chính thành kích thước nhỏ hơn và sau đó sử dụng một công cụ như Clonezilla để sao chép từ phân vùng nhỏ hơn hiện tại vào thẻ mới của bạn. Bạn có thể sẽ phải làm điều này trên một máy tính khác, mặc dù.


Thật không may, điều này đã không làm việc. Tôi thu nhỏ phân vùng xuống 2,5 GB với GParted. Nhưng khi tôi cố gắng tạo một hình ảnh từ nó sang USB, nó đã lớn hơn (4,3 GB - nhưng tôi nghĩ rằng nó muốn sao chép toàn bộ 32 GB và chỉ dừng ở mức 4,3 GB vì giới hạn kích thước tệp FAT).
mwld

2
Tôi đã sử dụng lệnh dd if=/dev/sdx of=/path/to/image bs=1Mtừ chủ đề này: raspberrypi.stackexchange.com/questions/311/iêu
mwld

Bạn có ý tưởng nào về cách tôi có thể sao chép phân vùng chính với 2,5 GB vào hình ảnh mà vẫn tạo thẻ SD với Raspbian có thể khởi động từ nó không?
mwld

Xin lỗi vì sự phản ứng chậm. Tôi bắt đầu với thẻ SD 4GB, tạo một hình ảnh và sau đó viết hình ảnh đó lên 8GB và các thẻ lớn hơn. Tôi chưa cần sử dụng phân vùng lớn hơn cho bất cứ điều gì tôi đã làm việc. Tôi không biết về một công cụ sẽ cho phép bạn tạo một hình ảnh của một phân vùng riêng lẻ trên thẻ SD.
Jerry Gagnon

3
  1. Tạo hình ảnh của thẻ bằng một trong các phương pháp đã được đề cập - Làm cách nào để sao lưu Raspberry Pi của tôi?

  2. Sử dụng tập lệnh tại http://sirlagz.net/2013/03/10/script-automatic-rpi-image-downsizer/ để thu nhỏ hình ảnh

  3. Khôi phục hình ảnh thu nhỏ trên thẻ mới nhỏ hơn


Tôi đã gặp phải vấn đề này khi tôi đang cố gắng đạt được cùng một mục tiêu để sao lưu hình ảnh của mình, tuy nhiên tôi không muốn toàn bộ thẻ CHỈ có dữ liệu liên quan trên thẻ. Theo đề nghị ở trên, tôi đã tìm kiếm kịch bản ở đây sirlagz.net/2013/03/10/script-automatic-rpi-image-downsizer nhưng không thể tìm thấy. bất kỳ ai có thể cập nhật trên liên kết này nếu nó ở đâu đó có sẵn?
shallyverma

Tôi vẫn có thể truy cập liên kết và bài viết là một kịch bản. Sao chép tập lệnh vào một tập tin và đặt tên cho nó script.sh, Làm cho tập tin thực thi bằng cách sử dụng chmodvà thực thi nó.
Mihir

1

Tôi đã sử dụng rsyncđể sao chép các hệ thống tập tin từ đĩa này sang đĩa khác trong một thời gian, không có trục trặc. Ưu điểm của việc sử dụng rsync là nó sao chép nội dung của hệ thống tệp, thay vì thực hiện sao chép cấp độ khối của thiết bị; kết quả là, nó thực sự không quan tâm kích thước của các ổ đĩa đích và nguồn là bao nhiêu, miễn là ổ đĩa đích có đủ dung lượng để chứa dữ liệu.

Vì vậy, đây là cách tôi sẽ làm điều đó:

  1. Tạo một cài đặt raspbian mới trên thẻ SD mới, nhỏ hơn mong muốn của bạn.
  2. Khởi động vào bản cài đặt mới và mở rộng hệ thống tập tin để lấp đầy toàn bộ đĩa. Tắt máy pi.
  3. Bây giờ gắn thẻ mới và thẻ cũ và sử dụng rsync -avx oldFilesystem newFilesystemđể sao chép / ghi đè hệ thống tệp trên thẻ mới với hệ thống tệp từ thẻ cũ.
  4. Cuối cùng, khởi động vào hệ thống mới của bạn và chạy rpi-updateđể đảm bảo rằng chương trình cơ sở của bạn phù hợp và cập nhật.

Sau này, thẻ mới của bạn sẽ có một hệ thống Raspbian hoạt động hoàn hảo được cài đặt trên nó.


Vậy đối với phương pháp này (Bước 3), tôi cần 2 đầu đọc thẻ SD?
Victor Van Hee

Hai đầu đọc thẻ SD hoặc một thiết bị trung gian. Bạn có thể rsync hệ thống tập tin cũ vào một thư mục trên ổ cứng của bạn, sau đó rsync thư mục đó vào thẻ SD thứ hai, nếu bạn không muốn chọn một đầu đọc.
sdenton4

1

Tôi đã tạo một tập lệnh shell để sao lưu và khôi phục tất cả dữ liệu trên Thẻ SD. Đầu tiên, nó xóa một số dữ liệu (tương ứng với dự án của tôi) và thu nhỏ phân vùng về kích thước tối thiểu để hình ảnh lớn như dữ liệu trên thẻ SD. Ngoài ra, tập lệnh tạo tệp * .zip của hình ảnh. Sau khi khôi phục hình ảnh đã tạo sang Thẻ SD khác, phân vùng sẽ được mở rộng đến kích thước tối đa. Kịch bản sử dụng các lệnh được đề cập trong các câu trả lời khác. Vì đây là kịch bản shell fist của tôi với kích thước này, tôi đã mất hàng giờ để tạo ra nó và nó không phải là máy bay phản lực hoàn hảo. Đặc biệt tôi không biết cách xử lý các giá trị trả về của resize2fs và fdisk để người dùng phải nhập các giá trị tôi cần. Có bất kỳ ý tưởng để khắc phục điều đó? Tôi hy vọng kịch bản này sẽ giúp người khác. Hãy chỉnh sửa và cải thiện nó.

"Usage:
    <skriptname> -b <path>                  create backup of SC Card (dev/mmcblk0) to file <path>/JJJJ-MM-DD_HHMM.img
    <skriptname> -r <path>/FILENAME.img     restore an exitsting image (<path>/FILENAME.img) to the SD Card (dev/mmcblk0) 
    <skriptname> -r <path>/FILENAME.zip     unzip and restore an exitsting image (<path>/FILENAME.zip) to the SD Card (dev/mmcblk0)
    <skriptname> -h                         show this hlep

đây là:

#!/bin/bash 

# check if the user is root
if (( $EUID != 0 )); then
  echo "This script requires root privileges please run as root"
  exit
fi


while getopts ":b:r:h" opt; do
  case $opt in
    b)
      mode="backup"
      OUTPATH=$OPTARG
      ;;
    r)
      mode="restore"
      DIRFILENAME=$OPTARG
      ;;
    h)
      mode="help"
      ;;
    \?)
      echo "Invalid option: -$OPTARG. Use -h for help" >&2
      exit 1
      ;;
    :)
      echo "Option -$OPTARG requires an argument. Use -h for help" >&2
      exit 1
      ;;
  esac
done
# no option
if [ $OPTIND == 1 ]
then
  echo "$(basename "$0") needs an option! Use -h for help"
  exit 1
fi


myMount(){
  # create mountpoint if not existing
  if [ ! -d /tmp/sd2/ ] ; then
    mkdir /tmp/sd2
  fi

  # mount partition
  mount -v -t ext4 /dev/mmcblk0p2 /tmp/sd2
  err=$?
  if [ $err != 0 ]; then
    echo "mount failed error: $err"
    exit 1
  fi
}

myUmount(){
  cd /home/ # otherwise umount will fail
  # fuser -vm /tmp/sd2/

  # umount partition
  umount -v /tmp/sd2
  err=$?
  if [ $err != 0 ]; then
    echo "umount failed error: $err"
    exit 1
  fi
}

myEnlarge(){
  echo "enlarge partition..."
  # enlarge partition is not posible with fdisk -> delete and recreate it
  (
  echo d # delete partition
  echo 2 # patition number
  echo n # add a new partition
  echo p # primary partition
  echo 2 # partition number
  echo   # first sector (accept default: varies)
  echo   # last sector (accept default: varies)
  echo w # write changes
  ) | fdisk /dev/mmcblk0

  echo "\n check filesystem... "
  e2fsck -f -v -C 0 /dev/mmcblk0p2

  # enlarge filesystem to maxsize
  resize2fs -p /dev/mmcblk0p2
}

case "$mode" in
"help")
  echo "Usage:
    $(basename "$0") -b <path>                  create backup of SC Card (dev/mmcblk0) to file <path>/JJJJ-MM-DD_HHMM.img
    $(basename "$0") -r <path>/FILENAME.img     restore an exitsting image (<path>/FILENAME.img) to the SD Card (dev/mmcblk0) 
    $(basename "$0") -r <path>/FILENAME.zip     unzip and restore an exitsting image (<path>/FILENAME.zip) to the SD Card (dev/mmcblk0)
    $(basename "$0") -h                         show this hlep
--------------------------------
Adrian Zeitler, Germany 2017"
  ;;
"backup")  ####################################### backup ####################################### 
  echo "an image of the SD Card (/dev/mmcblk0) whitch is as smal as possible will be created to $OUTPATH."
  # ------------------  delete some data --------------------

  echo "Do you want to delete tempfiles? [y/n]" 
  read delfiles

  if [ "$delfiles" = "y" ]
    then
      echo "Delete tempfiles..."

      myMount

      # remove some data
      cd /tmp/sd2/home/alarm/
      rm -v -f hagelbeere.db
      rm -v -f HAILcam.log
      rm -v -f HAILcam.log.1
      rm -v -f test.jpg

      myUmount

    elif [ "$delfiles" = "n" ]
      then
    echo "I don't delete anything."
    else
    echo "Sorry, I didn't understand."
    exit 1
  fi


  # --------------------------------------------------------------
  # shrink partition 2 to minimum size

  echo "check file system... "
  e2fsck -f -v -C 0 /dev/mmcblk0p2
  err=$?
  if [ $err != 0 ]; then
    echo "file system check failed, error: $err"
    exit 1
  fi

  echo "shrink filesystem of partition 2 to minimum size..."
  resize2fs -p -M /dev/mmcblk0p2
  err=$?
  if [ $err != 0 ]; then
    echo "resize2fs failed, error: $err"
    exit 1
  fi
  # --> Das Dateisystem auf /dev/mmcblk0p2 ist nun 692365 Blöcke groß.

  echo "Please tell me the new filesystem size displayed above:"
  read size
  # from resize2fs blocksize, fdisk wants sector: sector = block * 8
  size=$(( $size*8 ))

  # shrink partition is not posible with fdisk -> delete and recreate it
  (
  echo d # delete partition
  echo 2 # patition number
  echo n # add a new partition
  echo p # primary partition
  echo 2 # partition number
  echo   # first sector (accept default: varies)
  echo +$size  # last sector
  echo w # write changes
  ) | fdisk /dev/mmcblk0
  err=$?
  if [ $err != 0 ]; then
    echo "fdisk failed, error: $err"
    exit 1
  fi


  # --------------------------------------------------------------

  # fill unused space with zeros
  echo "Do you want to fill unused space with zeros? [y/n]" 
  read fillzeros


  if [ "$fillzeros" = "y" ]
    then
      echo "Copy zeros. This will end up with an error. But this is ok."

      myMount    

      dd if=/dev/zero | pv | dd of=/tmp/sd2/nullen.datei conv=noerror,notrunc,sync bs=10240
      # exits with error -> this is normal

      # dlelete zeros
      rm -v -f /tmp/sd2/nullen.datei
      sync

      myUmount

    elif [ "$fillzeros" = "n" ]
      then
    echo "I don't delete anything."
    else
    echo "Sorry, I didn't understand."
    exit 1
  fi

  # --------------------------------------------------------------

  # find out end of partition
  fdisk -l /dev/mmcblk0
  echo "Please tell me the end of mmcblk0p2 displayed above."
  read count



  DATE=$(date +"%Y-%m-%d_%H%M")
  IMGFILENAME=$DATE.img 
  echo "Do you want to create image with filename $OUTPATH$IMGFILENAME? [y/n]"
  read answer
  if [ "$answer" = "y" ]
  then
    echo "Do you want to create a *.zip file of the created image? [y/n]"
    read zip
    echo "Do you want to enlarge partition 2 to maxsize after image creation? [y/n]"
    read enlarge

    echo "create image..."
    cd $OUTPATH
    # create image with dd, stop at and of partition
    # count=N   copy only N input blocks
    # bs=BYTES  read and write up to BYTES bytes at a time = block size
    # pv    show status
    dd if=/dev/mmcblk0 | pv -s $(( $count*512 )) | dd of=$IMGFILENAME bs=512 count=$count
    err=$?
    if [ $err != 0 ]; then
      echo "dd failed error: $err"
      exit 1
    fi

    # --------------------------------------------------------------
    # create zip file
    # or like this:
    # sudo dd if=/dev/sdX | pv |gzip > /pfad/zur/datei.img.gz
    if [ "$zip" = "y" ]
    then
      echo "create zip file..."
      zip $DATE.zip $IMGFILENAME
    fi
    # --------------------------------------------------------------
  fi

  # --------------------------------------------------------------
  # enlarge partition 2

  if [ "$enlarge" = "y" ]
  then
    myEnlarge
  fi

  ;; #end case mode backup
"restore")  ####################################### restore ####################################### 
  #chek if image exists
  if [[ -s "$DIRFILENAME" ]]
  then
    # check if file is an image or zip file
    if [[ $DIRFILENAME =~ \.img$ ]]
    then
      IMGFILENAME=$(basename "$DIRFILENAME")
    elif [[ $DIRFILENAME =~ \.zip$ ]]
    then
      ZIPFILENAME=$(basename "$DIRFILENAME")
    else
      echo "Not the right file format. I accept *.img and *.zip"
      exit 1
    fi
  else
    echo "Image file does not exist."
    exit 1
  fi
  echo "the file $DIRFILENAME will be restored to the SD Card /dev/mmcblk0"

  #change to the path of the imagefile
  SOURCEPATH=$(dirname "$DIRFILENAME")
  cd $SOURCEPATH


  if [ "$ZIPFILENAME" != "" ]
  then
    echo "unzip file"
    # change file extention form zip zu img
    l=$(( ${#ZIPFILENAME}-3 ))
    IMGFILENAME="${ZIPFILENAME:0:l}img"
    unzip $ZIPFILENAME
  fi

  echo "Do you realy want to restore $SOURCEPATH/$IMGFILENAME to the SD card /dev/mmcblk0? 
  Warning: all data on the device /dev/mmcblk0 will be lost! [y/n]"
  read answer
  if [ "$answer" = "y" ]
  then
    echo "Do you want to enlarge partition 2 to maxsize after restoring? [y/n]"
    read enlarge
    echo "restore image..."
    filesize=$(wc -c <"$IMGFILENAME")
    echo "Filesize = $filesize Byte"
    dd if=$IMGFILENAME | pv -s $filesize | dd of=/dev/mmcblk0 bs=512
    err=$?
    if [ $err != 0 ]; then
      echo "dd failed error: $err"
      exit 1
    fi
  fi

  # --------------------------------------------------------------
  # enlarge partition 2
  if [ "$enlarge" = "y" ]
  then
    myEnlarge
  fi

  ;; #end case mode restore
esac

0

Giải pháp đơn giản nhất mà tôi tìm thấy là thực hiện sao lưu thẻ gốc lớn hơn bằng cách sử dụng các lệnh dd được nêu ở trên và sau đó khôi phục hình ảnh sang thẻ nhỏ hơn bằng cách sử dụng một cái gì đó như piwriter. dd có thể hoạt động tốt ... không chắc chắn. PiWriter đã trả về một lỗi kể từ khi nó hết phòng, nhưng vì hình ảnh không chứa bất kỳ dữ liệu thực tế nào ngoài kích thước của thẻ nhỏ hơn nên nó chỉ cắt bớt các cung trống. Tôi không chắc ý nghĩa của việc này là ... phân vùng có thể cần kiểm tra hoặc sửa chữa nhưng tôi có thể xác minh rằng nó hoạt động khi tôi đặt nó vào Pi.


1
Đây là một lời khuyên rất nguy hiểm, bạn sẽ không bao giờ biết nếu thực sự có bất kỳ dữ liệu nào vượt quá kích thước. chúng tôi đang tìm kiếm một giải pháp đáng tin cậy hơn và đã được chứng minh để làm việc.
lenik

Tôi sống nguy hiểm, tôi có thể nói gì;) Nói một cách nghiêm túc mặc dù tôi không có nhiều kinh nghiệm làm việc với dd hoặc bản đồ phân vùng nên tôi ở trong lãnh thổ chưa được khám phá ở đây. Tôi có lẽ đã gặp may vì tôi chỉ có khoảng 800 MB dữ liệu chuyển từ thẻ 16 GB sang thẻ 8GB. Tuy nhiên, vì tò mò, có cách nào để có thể phân mảnh dữ liệu trước để đảm bảo tất cả được nhóm ở đầu phân vùng không? Có vẻ hackish nhưng có lẽ?
Pooch

Tôi không biết về chống phân mảnh, nhưng bạn chắc chắn có thể thay đổi kích thước các phân vùng của mình và di chuyển chúng đến đầu thẻ SD, vì vậy chúng chỉ chiếm phần đầu. mất nhiều thời gian hơn dd đơn giản, nhưng kết quả đáng tin cậy hơn nhiều.
lenik

0

Tôi sử dụng một phiên bản cũ win32diskimager-RELEASE-0.1-r15-win32để đọc hình ảnh, nó tạo ra một hình ảnh 4GB thậm chí từ thẻ SD 8GB và sau đó ghi hình ảnh với phiên bản win32diskimager mới nhất.

Tôi sử dụng phiên bản cũ hơn vì phiên bản cũ sẽ bỏ qua mọi lỗi.


Không có tùy chọn nào trong phiên bản mới, 0.95, cho phép bạn thực hiện tương tự, tức là bỏ qua mọi lỗi? Thật không may, trang sourceforge không xuất hiện để liệt kê bất kỳ tùy chọn có sẵn nào. Nó chỉ có vẻ rủi ro nhẹ khi sử dụng phần mềm tiền beta
Greenonline

Tôi không nhận được bất kỳ sự ấm áp nào từ việc sử dụng một chương trình sẽ bỏ qua mọi lỗi.
RufusVS
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.