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

2024-04-12

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


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

在此示例中,我们将创建不带sudo or setsuid,一个包含两个 ext2 分区的映像文件,每个分区都填充了主机目录中的文件。

然后我们将使用sudo losetup只是为了安装分区来测试 Linux 内核实际上可以读取它们,如下所述:如何在 Linux 上挂载包含多个分区的镜像文件中的一个分区? https://stackoverflow.com/questions/1419489/how-to-mount-one-partition-from-an-image-file-that-contains-multiple-partitions/39675265#39675265

欲了解更多详情,请参阅:

  • sfdisk:处理分区表:https://superuser.com/questions/332252/how-to-create-and-format-a-partition-using-a-bash-script/1132834#1132834 https://superuser.com/questions/332252/how-to-create-and-format-a-partition-using-a-bash-script/1132834#1132834
  • mke2fs:处理分区的 EXT 格式化:https://superuser.com/questions/605196/how-to-create-ext2-image-without-superuser-rights/1366762#1366762 https://superuser.com/questions/605196/how-to-create-ext2-image-without-superuser-rights/1366762#1366762

这个例子:

#!/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 "$@"; 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 上游 https://github.com/cirosantilli/linux-cheat/blob/77dd7baa68dac3534a50f8a084f732f378113c59/mke2fs-multi.sh.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在没有 root 权限的情况下创建多分区 SD 磁盘映像? 的相关文章

  • 如何在 Linux 中检测通过 GUI 登录的用户

    我想在我的程序中捕获通过 GUI 登录的用户名 我的程序作为守护进程从 root 登录运行 如果非 root 用户通过 GUI 登录 我的程序应该会收到通知 我正在粘贴我当前的程序 该程序调用一个 perl 脚本 利用系统调用来检查当前登录
  • 窗口放置:适用于 Linux (KDE) 的类似 WinSplit Revolution 的应用程序? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 适用于 Linux KDE 的类似 WinSplit Revolution 的应用程序是什么 或者也许 KDE 中有一个我缺少的功能 平铺通常是窗口管
  • 使用 Android NDK 使用 -fsigned-char 进行构建安全吗?

    为了与其他平台保持一致 我需要使用signed char在我正在处理的一些本机代码中 但默认情况下在Android NDK上char类型是unsigned 我尝试明确使用signed char类型 但它生成太多警告differ in sig
  • Bash:更新文件中的变量

    我知道这是一个简单的答案 在找到答案之前我可能可以继续在谷歌上进行挖掘 但我的日程很紧 我希望能得到一个轻松的答复 我需要在安装时更新 ifcfg eth0 中的变量 换句话说 这就是需要发生的事情 以下变量需要更改 ONBOOT no B
  • 将管道输入转储到文件的简单方法是什么? (Linux)

    我正在寻找一个小 shell 脚本 它可以将任何内容通过管道传输到其中 并将其转储到文件中 用于电子邮件调试目的 有任何想法吗 unix 命令 tee 可以做到这一点 man tee
  • x86-64 上这个语句有什么问题?

    该函数的目的是获取堆栈的起始地址 unsigned long find start void asm movq rsp eax 当我编译它时 出现错误 Error suffix or operands invalid for movq mo
  • 使用 cmake 和 opencv 对符号“gzclose”的未定义引用[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我尝试构建该项目 doppia https bitbucket org rodrigob doppia 但发生链接错误 我想这是一
  • Bash 变量:区分大小写?

    Bash shell 脚本区分大小写吗 是可变的date与DATE 是的 它区分大小写 就像 UNIX 的其余部分一样 date and DATE是两个不同的变量 makefile and Makefile是两个不同的文件 h and H是
  • Android - GC 滞后于列表视图滚动“更大”的图像

    在列表视图中 我想在列表条目上绘制一个图像 这 20 张图像必须缩放以填充垂直模式的宽度 手机分辨率为 480 x 800 像素 SGS2 图像分辨率为 400x400 大小约为 100KB 我已将图像放在可绘制文件夹中 当我滚动列表时 它
  • 为多线程 UDP 客户端执行“close ()”时套接字描述符未释放

    我在下面编写了 UDP 客户端 它基本上生成一个单独的线程来接收数据报 但是数据报仅在主线程中发送 现在 在 Linux 发行版上实例化 udpClient 1 UDP 客户端后按 ctrl D 实现退出循环 围绕 getline 调用 并
  • 寻找 jQuery 效果来逐渐显示隐藏的 DIV/图像

    可能我错过了一些明显的东西 但我无法弄清楚如何慢慢地显示隐藏的图像 DIV 以便它从上到下显示 如果你看一下这个 jsfiddle 你会看到我试图在 jQuery 中使用 show 来显示的图像 http jsfiddle net nick
  • 是否可以允许jenkins访问只有root或某些特定程序可以访问的文件?

    我基本上想做的是允许 jenkins 访问我的 android sdk linux 文件夹和所有子目录 我的老板不想自己更改文件夹的权限 我应该在构建过程中这样做 我见过一些在构建过程中在执行 shell 中运行一些命令的示例 是否可以在该
  • Kubernetes Pod 已终止 - 退出代码 137

    我需要一些关于 k8s 1 14 和在其上运行 gitlab 管道所面临的问题的建议 许多作业都会抛出退出代码 137 错误 我发现这意味着容器突然终止 集群信息 库伯内特版本 1 14 使用的云 AWS EKS 节点 C5 4xLarge
  • PyGTK+3(PyGObject)创建屏幕截图?

    我过去 3 天在 google 上搜索 如何使用 PyGTK 3 创建屏幕截图 有关于 pyqt pygtk 2 wx 和 PIL 的 gallizion 教程 顺便说一句 我不需要 scrot imlib2 imagemagick 等外部
  • Ubuntu 上的 Docker 无法连接到本地主机,但可以连接到其 IP

    我运行的是 Ubuntu 18 04 uname r 5 3 0 46 generic 我已经安装了docker docker version Docker version 19 03 8 build afacb8b7f0 我有一个简单的
  • 从命令输出中设置 GDB 中的环境变量

    我试图在挑战中利用缓冲区溢出 缓冲区从环境变量中获取其值 在 GDB 中 我知道您可以使用以下命令设置环境变量 set environment username test 但是我需要传递用户名变量特殊字符 所以我需要执行以下操作 set e
  • 为什么我的 Java 代码执行 bash 命令不正确?

    我试图让我的 Java 程序与 Linux bash 交互 但出了问题 我有一个简单的可执行文件prog从中读取一个整数stdin并输出其平方 执行中 echo 5 prog 从 bash 本身打印正确答案25 in stdout但运行 i
  • bash 调整图像尺寸以适合特定大小

    我到处搜索但找不到这个问题的答案 我想精确输出一个文件夹中的所有图像 大小为 50Kb 并保持原始的宽高比 I tried ImageMagick并将大小调整为 250x250 例如 但它对我不起作用 它所做的是更改第一个尺寸并适应另一个尺
  • 验证 BASH 脚本时出现问题 [已关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我在尝试验证 bash 脚本时出现代码 lint 错误 bin bash if eq 0 then printf No argum
  • 无法使用Linux服务启动Archiva 2.1.0

    我正在尝试在 Linux 上启动最近发布的 Apache Archiva v2 1 0 独立版 出于测试目的 该 zip 已解压缩在 opt archiva 2 0 文档说 http archiva apache org docs 2 1

随机推荐