Вопрос по embedded, image, linux – Как создать образ многораздельного SD-диска без прав root?

8

Можно ли создать полный образ SD в Linux без прав суперпользователя (то есть без монтирования по шлейфу)? Я ищу способ автоматизировать создание образа встроенной системы. Образ должен включать определенную структуру разделов и разделы, отформатированные в FAT и ext2, заполненные файлами из системы сборки.

@ user1442554 Мне кажется, я правильно ответил на вопрос. Если вы согласны, пожалуйста, пометьте мой ответ как правильный? Catskul
На ум приходят две идеи: одна - предварительно настроить разрешение для конкретной задачи, возможно, с помощью предохранителя. Другой способ - смоделировать монтирование, используя ту же идею, что и fakeroot - LD_PRELOAD, чтобы заменить функции обработки файлов, и вместо этого направлять файловые операции в выбранном каталоге через реализацию файловой системы непривилегированного пользовательского пространства, где изображение является обычным файлом данных. Вам также может понадобиться обычная возможность fakeroot, чтобы установить нужные биты прав доступа к файлам в изображении. Chris Stratton

Ваш Ответ

4   ответа
4

вы можете посмотреть на genextfs, что создает файловую систему ext2 в обычном файле без какого-либо монтирования.

Смотрите такжеgithub.com/maximeh/buildroot/blob/master/fs/ext2/genext2fs.sh который также генерирует ext3, безmount или жеsudo или иначе корневые привилегии.
1

Minimal runnable sfdisk + mke2fs example without sudo

В этом примере мы создадим, безsudo или жеsetsuidфайл изображения, содержащий два раздела ext2, каждый из которых содержит файлы из каталога хоста.

Затем мы будем использоватьsudo losetup просто смонтировать разделы, чтобы проверить, что ядро Linux действительно может их прочитать, как объяснено на:Как смонтировать один раздел из файла образа, который содержит несколько разделов в Linux?

Для более подробной информации смотрите:

Пример:

#!/usr/bin/env bash

# Input params.
root_dir_1=root1
root_dir_2=root2
partition_file_1=part1.ext2
partition_file_2=part2.ext2
partition_size_1_megs=32
partition_size_2_megs=32
img_file=img.img
block_size=512

# Calculated params.
mega="$(echo '2^20' | bc)"
partition_size_1=$(($partition_size_1_megs * $mega))
partition_size_2=$(($partition_size_2_megs * $mega))

# Create a test directory to convert to ext2.
mkdir -p "$root_dir_1"
echo content-1 > "${root_dir_1}/file-1"
mkdir -p "$root_dir_2"
echo content-2 > "${root_dir_2}/file-2"

# Create the 2 raw ext2 images.
rm -f "$partition_file_1"
mke2fs \
  -d "$root_dir_1" \
  -r 1 \
  -N 0 \
  -m 5 \
  -L '' \
  -O ^64bit \
  "$partition_file_1" \
  "${partition_size_1_megs}M" \
;
rm -f "$partition_file_2"
mke2fs \
  -d "$root_dir_2" \
  -r 1 \
  -N 0 \
  -m 5 \
  -L '' \
  -O ^64bit \
  "$partition_file_2" \
  "${partition_size_2_megs}M" \
;

# Default offset according to
part_table_offset=$((2**20))
cur_offset=0
bs=1024
dd if=/dev/zero of="$img_file" bs="$bs" count=$((($part_table_offset + $partition_size_1 + $partition_size_2)/$bs)) skip="$(($cur_offset/$bs))"
printf "
type=83, size=$(($partition_size_1/$block_size))
type=83, size=$(($partition_size_2/$block_size))
" | sfdisk "$img_file"
cur_offset=$(($cur_offset + $part_table_offset))
# TODO: can we prevent this and use mke2fs directly on the image at an offset?
# Tried -E offset= but could not get it to work.
dd if="$partition_file_1" of="$img_file" bs="$bs" seek="$(($cur_offset/$bs))"
cur_offset=$(($cur_offset + $partition_size_1))
rm "$partition_file_1"
dd if="$partition_file_2" of="$img_file" bs="$bs" seek="$(($cur_offset/$bs))"
cur_offset=$(($cur_offset + $partition_size_2))
rm "$partition_file_2"

# Test the ext2 by mounting it with sudo.
# sudo is only used for testing, the image is completely ready at this point.

# losetup automation functions from:
# https://stackoverflow.com/questions/1419489/how-to-mount-one-partition-from-an-image-file-that-contains-multiple-partitions/39675265#39675265
loop-mount-partitions() (
  set -e
  img="$1"
  dev="$(sudo losetup --show -f -P "$img")"
  echo "$dev" | sed -E 's/.*[^[:digit:]]([[:digit:]]+$)/\1/g'
  for part in "${dev}p"*; do
    if [ "$part" = "${dev}p*" ]; then
      # Single partition image.
      part="${dev}"
    fi
    dst="/mnt/$(basename "$part")"
    echo "$dst" 1>&2
    sudo mkdir -p "$dst"
    sudo mount "$part" "$dst"
  done
)
loop-unmount-partitions() (
  set -e
  for loop_id in "[email protected]"; do
    dev="/dev/loop${loop_id}"
    for part in "${dev}p"*; do
      if [ "$part" = "${dev}p*" ]; then
        part="${dev}"
      fi
      dst="/mnt/$(basename "$part")"
      sudo umount "$dst"
    done
    sudo losetup -d "$dev"
  done
)

loop_id="$(loop-mount-partitions "$img_file")"
sudo cmp /mnt/loop0p1/file-1 "${root_dir_1}/file-1"
sudo cmp /mnt/loop0p2/file-2 "${root_dir_2}/file-2"
loop-unmount-partitions "$loop_id"

Проверено на Ubuntu 18.04.GitHub upstream.

3

У меня была эта проблема, и я не смог найти жизнеспособного решения, поэтому я написал эту утилиту, которую мы открыли с открытым исходным кодом.Вот.

Из README:

$ dd if=/dev/zero of=disk.image bs=1M count=4
4+0 records in
4+0 records out
4194304 bytes (4.2 MB, 4.0 MiB) copied, 0.00470867 s, 891 MB/s
$ parted --script disk.image \
    mktable msdos mkpart primary 2048s 100% set 1 boot on
$ mkdir mntdir
$ partfs -o dev=disk.image mntdir
$ mkfs.ext4 mntdir/p1
mke2fs 1.42.13 (17-May-2015)
Creating filesystem with 3072 1k blocks and 768 inodes

Allocating group tables: done
Writing inode tables: done
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done

$ fusermount -u mntdir
Используя: 1. fdisk для создания разделов в разреженном файле 2. partfs для индивидуального доступа к созданным разделам 3. dd для копирования файлов ext4, сгенерированных корневым каталогом сборки 4. Сверните, чтобы повторно пробить отверстия, чтобы сделать файл разреженным снова, я мог бы добиться всего Вещи, которые я хотел от имени пользователя root, поэтому большое спасибо.
5

Я пытаюсь сделать то же самое. Моя первая попытка использовала блочное устройство обратной петли, но я нашел обходные пути к обоим шагам, которые требуют обратной петли.

Steps with loopback

Вот что я делаю ($ 1 - это имя файла изображения, $ 2 - размер файла):

  1. create zeroed disk image file with dd if=/dev/zero of=$1 bs=512 count=$(($2/512))
  2. create partition table with parted -s $1 mklabel msdos
  3. create partition with parted -s $1 "mkpart primary 0% 100%"
  4. attach partition to loop sudo losetup --find $1 --offset $OFFSET_TO_PARTITION_BYTES
  5. make file system with mkfs.ext4 with mkfs.ext4 -I 128 -L BOOT -b 2048 -O ^has_journal /dev/loop0 $SIZE_IN_2048_BLOCKS
  6. mount /dev/loop0

Петля используется потому что

  • in step 4 & 5, mkfs doesn't have an offset option so losetup is used to solve that problem
  • in step 6, mount allows the use of the operating systems ext4 driver

Looback workarounds

Дерьмовый обходной путь для шага 4 & amp; 5:

  • xmount --in dd --out vdi disk.img mnt/
  • vdfuse -f mnt/disk.vdi -r ./mnt2
  • ./mnt2 will now have two files: EntireDisk, and Partition1
  • point mkfs.ext4 at ./mnt2/Partition1

Обходное решение для шага 6:

  • follow all steps for step 5 work around
  • use fuseext2 to mount ./mnt2/Partition1

Caveat

Предостережение: поддержка ext4 не объявляется в их документации, и попытки монтирования сопровождаются предупреждением:

This is experimental code, opening rw a real file system could be
dangerous for your data. Please add "-o ro" if you want to open the file
system image in read-only mode, or "-o rw+" if you accept the risk to test
this module

Update

vdfuse должен иметь возможность монтировать необработанный образ без помощи xmount, но есть ошибка, которая игнорирует параметр RAW.

Я выследил и исправил ошибку с патчем здесь:

https://bugs.launchpad.net/ubuntu/+source/virtualbox-ose/+bug/1019075

Вы нашли способ заставить это работать? Кажется, это исходит от лет, но, глядя на ошибку, кажется, ничего не было сделано. Это происходит от версии ваших инструментов?
Насколько я знаю, ничего не было сделано. Вы можете использовать мой патч, если хотите перекомпилировать инструмент.

Похожие вопросы