如何创建没有root权限的多分区SD磁盘映像?

avi*_*orp 11 linux embedded image

是否有可能在没有root权限的情况下在linux中创建完整的SD映像(即没有环回挂载)?我正在寻找一种自动化嵌入式系统映像创建的方法.图像应包括特定的分区结构和格式化为FAT的分区,以及使用构建系统中的文件填充的ext2.

Cir*_*四事件 7

最小可运行sfdisk+mke2fs没有示例sudo

在此示例中,我们将创建一个包含两个 ext2 分区的映像文件,其中不包含sudosetsuid,每个分区都填充来自主机目录的文件。

然后我们将使用sudo losetupjust 来挂载分区来测试 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:
# /sf/ask/99364261/#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 "$@"; 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"
Run Code Online (Sandbox Code Playgroud)

在 Ubuntu 18.04 上测试。GitHub 上游.


Cat*_*kul 5

我正在尝试做同样的事情.我的第一次尝试使用了环回块设备,但我找到了需要环回的两个步骤的解决方法.

环回的步骤

这就是我正在做的事情($ 1是图像文件名,$ 2是文件大小):

  1. 使用创建归零磁盘映像文件 dd if=/dev/zero of=$1 bs=512 count=$(($2/512))
  2. 用.创建分区表 parted -s $1 mklabel msdos
  3. 用.创建分区 parted -s $1 "mkpart primary 0% 100%"
  4. 将分区附加到循环 sudo losetup --find $1 --offset $OFFSET_TO_PARTITION_BYTES
  5. 使用mkfs.ext4制作文件系统 mkfs.ext4 -I 128 -L BOOT -b 2048 -O ^has_journal /dev/loop0 $SIZE_IN_2048_BLOCKS
  6. mount/dev/loop0

使用环回是因为

  • 在步骤4和5中,mkfs没有偏移选项,因此使用losetup来解决该问题
  • 在步骤6中,mount允许使用操作系统ext4驱动程序

Looback解决方法

步骤4和5的糟糕解决方法:

  • xmount --in dd --out vdi disk.img mnt /
  • vdfuse -f mnt/disk.vdi -r ./mnt2
  • ./mnt2现在有两个文件:EntireDisk和Partition1
  • 在./mnt2/Partition1指向mkfs.ext4

第6步的解决方案:

  • 按照步骤5的所有步骤进行操作
  • 使用fuseext2挂载./mnt2/Partition1

警告

警告:ext4支持不会在他们的文档中公布,并且尝试mount会出现警告:

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
Run Code Online (Sandbox Code Playgroud)

更新

vdfuse应该能够在没有xmount帮助的情况下挂载原始映像,但是有一个错误忽略了RAW选项.

我在这里跟踪并修复了一个补丁:

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


小智 5

您可能想查看 genextfs,它在常规文件中创建一个 ext2 文件系统,无需任何安装。

  • 另请参阅 https://github.com/maximeh/buildroot/blob/master/fs/ext2/genext2fs.sh,它也生成 ext3,没有 `mount` 或 `sudo` 或其他 root 权限。 (2认同)

Joh*_*dge 5

我遇到了这个问题并且找不到可行的解决方案,所以我写了这个我们在这里开源的实用程序。

从自述文件:

$ 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
Run Code Online (Sandbox Code Playgroud)

  • 通过使用: 1. fdisk 将分区创建到稀疏文件中 2. partfs 单独访问创建的分区 3. dd 复制构建根生成的 ext4 文件 4. Fallocate 重新打孔以使文件再次稀疏 我可以实现所有目标我想要的非 root 的东西,所以非常感谢你。 (2认同)