upgrades!
This commit is contained in:
parent
4135c34d3d
commit
8ae11a1e70
146
README.md
146
README.md
|
|
@ -1,127 +1,43 @@
|
|||
# Manjaro ARM Installer
|
||||
|
||||
Scripts for installing Manjaro ARM directly to SD/eMMC cards or USB sticks without the need for images.
|
||||
Fork of [upstream](https://gitlab.manjaro.org/manjaro-arm/applications/manjaro-arm-installer) with `--output-image` mode added — builds to a sparse `.img` file via loop device instead of writing to a real block device. With no flags, behaves identically to upstream.
|
||||
|
||||
This script is "interactive". Meaning that it asks you questions when run to customize your install. Like username, password etc.
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# build to an image file (12 GB)
|
||||
sudo ./manjaro-arm-installer --output-image ./manjaro.img --image-size 12G
|
||||
|
||||
## Dependencies (Arch package names):
|
||||
* bash
|
||||
* wget
|
||||
* git
|
||||
* systemd
|
||||
* dialog
|
||||
* parted
|
||||
* libarchive
|
||||
* qemu-user-static-binfmt (only needed when script is run from other architectures than `aarch64`)
|
||||
* openssl
|
||||
* gawk
|
||||
* dosfstools
|
||||
* polkit
|
||||
* btrfs-progs (for btrfs filesystem support)
|
||||
* f2fs-tools (for f2fs filesystem support)
|
||||
* cryptsetup (for encryption support)
|
||||
* grub-efi-arm64 (only needed when script is run from other arcitectures than `aarch64`) (from AUR) (for `generic-efi` support)
|
||||
# env-var form (drop-in for scripts)
|
||||
sudo IMG_OUTPUT=manjaro.img IMG_SIZE=12G ./manjaro-arm-installer
|
||||
|
||||
## Installing and using from Manjaro (x64 and ARM) repositories:
|
||||
To use this script, please make sure that the following is correct:
|
||||
|
||||
* An SD/eMMC card with at least 8 GB storage is plugged in, but not mounted. This Script **will** remove everything on it.
|
||||
* That your user account has `sudo` rights.
|
||||
|
||||
Then install the `manjaro-arm-installer` package with:
|
||||
```
|
||||
sudo pacman -Syu manjaro-arm-installer
|
||||
```
|
||||
Then reboot or run `sudo systemctl restart systemd-binfmt`. You can now launch the installer with:
|
||||
```
|
||||
sudo bash manjaro-arm-installer
|
||||
# compress after build (xz preferred, zstd fallback)
|
||||
sudo ./manjaro-arm-installer --output-image ./manjaro.img --compress
|
||||
```
|
||||
|
||||
Default image size is `8G` if `--image-size` isn't passed.
|
||||
|
||||
## Installing and using from gitlab:
|
||||
To use this script, please make sure that the following is correct:
|
||||
|
||||
* An SD/eMMC card or USB stick with at least 8 GB storage is plugged in, but not mounted. This Script **will** remove everything on it.
|
||||
* That your user account has `sudo` rights.
|
||||
* That you have rebooted or restarted the binfmt service with `sudo systemctl restart systemd-binfmt` if you are running the script from any other architecture than `aarch64`.
|
||||
|
||||
Then use this to get it:
|
||||
```
|
||||
git clone https://gitlab.manjaro.org/manjaro-arm/applications/manjaro-arm-installer
|
||||
cd manjaro-arm-installer
|
||||
chmod +x manjaro-arm-installer
|
||||
sudo bash ./manjaro-arm-installer (Use Default stable branch)
|
||||
sudo bash ./manjaro-arm-installer arm-testing (Use testing branch)
|
||||
sudo bash ./manjaro-arm-installer arm-unstable (Use unstable branch)
|
||||
```
|
||||
|
||||
## Known Issues:
|
||||
* Because `dialog` is weird, the script needs to be run in `bash`.
|
||||
|
||||
## Supported Devices:
|
||||
* ClockworkPi DevTerm
|
||||
* Generic
|
||||
* Generic EFI
|
||||
* Beelink GT1 Ultimate
|
||||
* Odroid C4
|
||||
* Odroid C2
|
||||
* Odroid HC4
|
||||
* Odroid M1 (new)
|
||||
* Odroid N2
|
||||
* Odroid N2
|
||||
* Orange Pi 4 LTS (new)
|
||||
* Pine64-LTS / Sopine
|
||||
* Pine64+
|
||||
* Pinebook
|
||||
* Pine H64
|
||||
* PinePhone
|
||||
* PinePhone Pro (Experimental)
|
||||
* Pinebook Pro
|
||||
* PineTab
|
||||
* Radxa Zero
|
||||
* Raspberry Pi 5's/4's/3's/zero2w
|
||||
* Rock 3A (new)
|
||||
* Rock64
|
||||
* Rock Pi 4B
|
||||
* Rock Pi 4C
|
||||
* RockPro64
|
||||
* LibreComputer Renegade
|
||||
* NanoPC T4
|
||||
* Quartz64 Model A
|
||||
* Quartz64 Model B (new)
|
||||
* Khadas Vim 1
|
||||
* Khadas Vim 2
|
||||
* Khadas Vim 3
|
||||
|
||||
## Supported Editions / Desktops:
|
||||
* Minimal (no xorg, no apps)
|
||||
* KDE/Plasma (full plasma desktop with apps)
|
||||
* XFCE (full XFCE desktop with apps)
|
||||
* i3 (tiling window manager with gtk apps)
|
||||
* Sway (tiling wayland window manager with gtk apps)
|
||||
* LXQT (full LXQT desktop with some qt apps)
|
||||
* Mate (full mate desktop with apps)
|
||||
* Server (minimal install with LAMP and Docker)
|
||||
* Gnome (full Gnome desktop with apps)
|
||||
* Budgie (full Budge desktop with apps) (EXPERIMENTAL)
|
||||
* Phosh (A mobile interface for phones based on GTK/Gnome)
|
||||
* Plasma Mobile (A mobile interface for phones based on QT/Plasma)
|
||||
|
||||
## Other notes:
|
||||
This script is available in the **Manjaro** repository and can be installed with `sudo pacman -S manjaro-arm-installer`.
|
||||
|
||||
This script **should** be distro-agnostic, which means you can run the install script to install *Manjaro ARM* from **any** distro, as long as the dependencies are met.
|
||||
|
||||
### Quirks Ubuntu
|
||||
Ubuntu does not list keymaps the same way as Arch based systems. The script will not fail - but it will skip the console keymap selection thus defaulting to us console keymap.
|
||||
|
||||
See https://www.claudiokuenzler.com/blog/1257/how-to-fix-missing-keymaps-debian-ubuntu-localectl-failed-read-list
|
||||
|
||||
Ubuntu stores the qemu bin formats in different locations and this will make the script fail. As the reference is only a validation - it is possible to work around it by creating a symlink
|
||||
|
||||
sudo ln -s /usr/lib/binfmt.d/qemu-aarch.conf /usr/lib/binfmt.d/qemu-aarch64-static.conf
|
||||
|
||||
The interactive dialogs (edition, user, password, locale, etc.) run as normal.
|
||||
|
||||
## Dependencies
|
||||
|
||||
Same as upstream: `bash wget git systemd dialog parted libarchive openssl gawk dosfstools polkit`. Plus `binfmt-qemu-static` if running on x86_64 (reboot or `sudo systemctl restart systemd-binfmt` after install). `xz` or `zstd` only if using `--compress`.
|
||||
|
||||
<!-- acord-archive
|
||||
UEsDBBQAAAAIAAAAIQBY4Te2GAAAABYAAAALAAAAY29uZmlnLnRvbWwrSy0qzszPU7BVMOTiii5J
|
||||
TMpJLY7lAgBQSwMEFAAAAAgAAAAhAJ3v8MxyAgAAWAQAABMAAABzcmMvX3VubmFtZWRfMS5jb3Jk
|
||||
pVPNbtNAEL77KUbtgUSKHVqhqqrUA6gQ9VBR0VZIINQde8fOkvWu2VknaU48BE/IkzDrJKRIcOJm
|
||||
z+58PzPf5nmeLYzTcAlH6Lx7an3PR5lUaC21l1k00VI6PcpyuXsMN+i+YvDw+sMNXDuOaC2FLHvn
|
||||
wwJ8DZ/7jmMgbL+M5jF2fDGdNgKBZdFuGwsfmunuO8fQTrHrrKkwGu/4+UFu9uhjWJk4B5Xnvo9d
|
||||
H3PTYkMKWq8JUGvS8PP7Dyh7YzVD9IDAHQYmUIVpGwW1EQ9Lg2C970DT0lQECZ5QJ9GrYKJxzbZV
|
||||
xFsora8Wu5sFfEz0zkNtseEJlDTHJTEYTS6KdGufUuveeZFlx8fwwKIxy5RSJfJcBjfIGygcDAa2
|
||||
skYnpzB7M8641x6Kvw8A/nR+uJbsyeFQzdlsCE5OZ0IP5Jb5EgPUPrQw0sF3gpb+gKtgusg7wuub
|
||||
2eP7h/vbh/vL55CpfHf96e2lwP1LVKKpfNsFYgaso8jcWhytNyDVmkIgPYENRw21tJRYLf7P554u
|
||||
TTXLrqjG3sbdMAf3hkGdzxSYOqXlMBapsHsRoUNm0rKg+3kKgGjGKpolgTZofcMwIm1SEifQM4XJ
|
||||
0LDyQWxIINDSBChWxRhC7wBZMhFatNuFX1FH8mxcZYiz7A5bSjf2obiAIQewaiiCvAjgJ4lfq3fM
|
||||
QhSi5NiaEkM1T5K8wDFbaHAlSfRcc/TeMnTeLkxUBdzaXuyWxtVtzL9R2+cyRsnjYF8EuhRp72B9
|
||||
fvZ49gpGgUrvI0gG1LCErYIqWom8dIbfmvItptptdbeecQFqvVFDf9qpfDkJvnD1nJjUYT+q+AVQ
|
||||
SwECFAMUAAAACAAAACEAWOE3thgAAAAWAAAACwAAAAAAAAAAAAAApIEAAAAAY29uZmlnLnRvbWxQ
|
||||
SwECFAMUAAAACAAAACEAne/wzHICAABYBAAAEwAAAAAAAAAAAAAApIFBAAAAc3JjL191bm5hbWVk
|
||||
XzEuY29yZFBLBQYAAAAAAgACAHoAAADkAgAAAAA=
|
||||
-->
|
||||
|
|
|
|||
|
|
@ -48,6 +48,43 @@ LOCALE=""
|
|||
HOSTNAME=""
|
||||
CRYPT=""
|
||||
|
||||
# ─── image-output mode (added) ────────────────────────────────────────────────
|
||||
# When IMG_OUTPUT is set, the installer writes to a sparse image file via
|
||||
# losetup -fP instead of asking the user to pick a block device.
|
||||
#
|
||||
# Set via environment OR via --output-image / -o flag, e.g.:
|
||||
# sudo IMG_OUTPUT=manjaro.img IMG_SIZE=8G ./manjaro-arm-installer
|
||||
# sudo ./manjaro-arm-installer --output-image manjaro.img --image-size 8G
|
||||
#
|
||||
# Defaults: IMG_SIZE=8G, IMG_COMPRESS=0
|
||||
IMG_OUTPUT="${IMG_OUTPUT:-}"
|
||||
IMG_SIZE="${IMG_SIZE:-8G}"
|
||||
IMG_COMPRESS="${IMG_COMPRESS:-0}"
|
||||
IMG_LOOPDEV=""
|
||||
|
||||
# parse our own flags out of $@ before the script's branch-detection logic
|
||||
# (which only inspects $1) sees them
|
||||
_filtered_args=()
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-o|--output-image) IMG_OUTPUT="$2"; shift 2 ;;
|
||||
--image-size) IMG_SIZE="$2"; shift 2 ;;
|
||||
--compress) IMG_COMPRESS=1; shift ;;
|
||||
*) _filtered_args+=("$1"); shift ;;
|
||||
esac
|
||||
done
|
||||
set -- "${_filtered_args[@]}"
|
||||
|
||||
# cleanup hook — detaches the loop device on exit/interrupt so we don't leak
|
||||
_img_cleanup() {
|
||||
if [[ -n "$IMG_LOOPDEV" ]] && losetup "$IMG_LOOPDEV" &>/dev/null; then
|
||||
sync
|
||||
losetup -d "$IMG_LOOPDEV" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
trap _img_cleanup EXIT INT TERM
|
||||
# ─── end image-output mode ────────────────────────────────────────────────────
|
||||
|
||||
# check if root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "*******************************************************************************************"
|
||||
|
|
@ -951,6 +988,25 @@ if [ ! -z "$CONFIRMROOTPASSWORD" ]
|
|||
then
|
||||
|
||||
# simple command to put the results of lsblk (just the names of the devices) into an array and make that array populate the options
|
||||
if [[ -n "$IMG_OUTPUT" ]]; then
|
||||
# ─── image-output branch (added) ──────────────────────────────────────
|
||||
msg "Image-output mode: writing to $IMG_OUTPUT (size $IMG_SIZE)"
|
||||
if [[ -e "$IMG_OUTPUT" ]]; then
|
||||
info "removing existing $IMG_OUTPUT"
|
||||
rm -f "$IMG_OUTPUT" || { msg "could not remove existing image"; exit 1; }
|
||||
fi
|
||||
# create sparse file
|
||||
truncate -s "$IMG_SIZE" "$IMG_OUTPUT" \
|
||||
|| { msg "truncate failed"; exit 1; }
|
||||
# losetup with -P enables partition device nodes (loopNp1, loopNp2)
|
||||
IMG_LOOPDEV=$(losetup -fP --show "$IMG_OUTPUT") \
|
||||
|| { msg "losetup failed"; exit 1; }
|
||||
info "attached as $IMG_LOOPDEV"
|
||||
SDCARD="$IMG_LOOPDEV"
|
||||
DEV_NAME="${IMG_LOOPDEV#/dev/}"
|
||||
SDTYP="${SDCARD:5:2}" # will be "lo" — handled below
|
||||
# ─── end image-output branch ──────────────────────────────────────────
|
||||
else
|
||||
let i=0
|
||||
W=()
|
||||
while read -r line; do
|
||||
|
|
@ -966,6 +1022,7 @@ WARNING! This WILL destroy the data on it!" 20 50 10 \
|
|||
DEV_NAME=$SDCARD
|
||||
SDCARD=/dev/$SDCARD
|
||||
SDTYP=${SDCARD:5:2}
|
||||
fi
|
||||
else
|
||||
clear
|
||||
exit 1
|
||||
|
|
@ -973,7 +1030,8 @@ fi
|
|||
|
||||
if [[ "$SDTYP" = "sd" ]]; then
|
||||
SDDEV=""
|
||||
elif [[ "$SDTYP" = "mm" || "$SDTYP" = "nv" ]]; then
|
||||
elif [[ "$SDTYP" = "mm" || "$SDTYP" = "nv" || "$SDTYP" = "lo" ]]; then
|
||||
# loop devices use /dev/loopNp1 partition naming, same as mmcblk/nvme
|
||||
SDDEV="p"
|
||||
else
|
||||
clear
|
||||
|
|
@ -1148,3 +1206,26 @@ create_install
|
|||
cleanup
|
||||
show_elapsed_time "${FUNCNAME}" "${timer_start}"
|
||||
sync
|
||||
|
||||
# ─── image-output finalization (added) ────────────────────────────────────────
|
||||
if [[ -n "$IMG_OUTPUT" ]]; then
|
||||
msg "Detaching loop device $IMG_LOOPDEV"
|
||||
sync
|
||||
losetup -d "$IMG_LOOPDEV" 2>/dev/null || true
|
||||
IMG_LOOPDEV=""
|
||||
|
||||
if [[ "$IMG_COMPRESS" = "1" ]]; then
|
||||
msg "Compressing $IMG_OUTPUT (this may take a while)"
|
||||
if command -v xz &>/dev/null; then
|
||||
xz -T0 -v "$IMG_OUTPUT"
|
||||
msg "Compressed: ${IMG_OUTPUT}.xz"
|
||||
elif command -v zstd &>/dev/null; then
|
||||
zstd -T0 -19 --rm "$IMG_OUTPUT" -o "${IMG_OUTPUT}.zst"
|
||||
msg "Compressed: ${IMG_OUTPUT}.zst"
|
||||
else
|
||||
info "Neither xz nor zstd found — leaving image uncompressed"
|
||||
fi
|
||||
fi
|
||||
msg "Image build complete: ${IMG_OUTPUT}$([[ "$IMG_COMPRESS" = "1" ]] && echo ".xz")"
|
||||
fi
|
||||
# ─── end image-output finalization ────────────────────────────────────────────
|
||||
|
|
|
|||
|
|
@ -0,0 +1,117 @@
|
|||
--- /home/claude/work/arm-installer/manjaro-arm/manjaro-arm-installer 2026-04-25 00:04:54.000000000 +0000
|
||||
+++ /home/claude/work/manjaro-arm-installer-patched 2026-04-25 00:08:21.126014412 +0000
|
||||
@@ -48,6 +48,43 @@
|
||||
HOSTNAME=""
|
||||
CRYPT=""
|
||||
|
||||
+# ─── image-output mode (added) ────────────────────────────────────────────────
|
||||
+# When IMG_OUTPUT is set, the installer writes to a sparse image file via
|
||||
+# losetup -fP instead of asking the user to pick a block device.
|
||||
+#
|
||||
+# Set via environment OR via --output-image / -o flag, e.g.:
|
||||
+# sudo IMG_OUTPUT=manjaro.img IMG_SIZE=8G ./manjaro-arm-installer
|
||||
+# sudo ./manjaro-arm-installer --output-image manjaro.img --image-size 8G
|
||||
+#
|
||||
+# Defaults: IMG_SIZE=8G, IMG_COMPRESS=0
|
||||
+IMG_OUTPUT="${IMG_OUTPUT:-}"
|
||||
+IMG_SIZE="${IMG_SIZE:-8G}"
|
||||
+IMG_COMPRESS="${IMG_COMPRESS:-0}"
|
||||
+IMG_LOOPDEV=""
|
||||
+
|
||||
+# parse our own flags out of $@ before the script's branch-detection logic
|
||||
+# (which only inspects $1) sees them
|
||||
+_filtered_args=()
|
||||
+while [[ $# -gt 0 ]]; do
|
||||
+ case "$1" in
|
||||
+ -o|--output-image) IMG_OUTPUT="$2"; shift 2 ;;
|
||||
+ --image-size) IMG_SIZE="$2"; shift 2 ;;
|
||||
+ --compress) IMG_COMPRESS=1; shift ;;
|
||||
+ *) _filtered_args+=("$1"); shift ;;
|
||||
+ esac
|
||||
+done
|
||||
+set -- "${_filtered_args[@]}"
|
||||
+
|
||||
+# cleanup hook — detaches the loop device on exit/interrupt so we don't leak
|
||||
+_img_cleanup() {
|
||||
+ if [[ -n "$IMG_LOOPDEV" ]] && losetup "$IMG_LOOPDEV" &>/dev/null; then
|
||||
+ sync
|
||||
+ losetup -d "$IMG_LOOPDEV" 2>/dev/null || true
|
||||
+ fi
|
||||
+}
|
||||
+trap _img_cleanup EXIT INT TERM
|
||||
+# ─── end image-output mode ────────────────────────────────────────────────────
|
||||
+
|
||||
# check if root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "*******************************************************************************************"
|
||||
@@ -951,6 +988,25 @@
|
||||
then
|
||||
|
||||
# simple command to put the results of lsblk (just the names of the devices) into an array and make that array populate the options
|
||||
+ if [[ -n "$IMG_OUTPUT" ]]; then
|
||||
+ # ─── image-output branch (added) ──────────────────────────────────────
|
||||
+ msg "Image-output mode: writing to $IMG_OUTPUT (size $IMG_SIZE)"
|
||||
+ if [[ -e "$IMG_OUTPUT" ]]; then
|
||||
+ info "removing existing $IMG_OUTPUT"
|
||||
+ rm -f "$IMG_OUTPUT" || { msg "could not remove existing image"; exit 1; }
|
||||
+ fi
|
||||
+ # create sparse file
|
||||
+ truncate -s "$IMG_SIZE" "$IMG_OUTPUT" \
|
||||
+ || { msg "truncate failed"; exit 1; }
|
||||
+ # losetup with -P enables partition device nodes (loopNp1, loopNp2)
|
||||
+ IMG_LOOPDEV=$(losetup -fP --show "$IMG_OUTPUT") \
|
||||
+ || { msg "losetup failed"; exit 1; }
|
||||
+ info "attached as $IMG_LOOPDEV"
|
||||
+ SDCARD="$IMG_LOOPDEV"
|
||||
+ DEV_NAME="${IMG_LOOPDEV#/dev/}"
|
||||
+ SDTYP="${SDCARD:5:2}" # will be "lo" — handled below
|
||||
+ # ─── end image-output branch ──────────────────────────────────────────
|
||||
+ else
|
||||
let i=0
|
||||
W=()
|
||||
while read -r line; do
|
||||
@@ -966,6 +1022,7 @@
|
||||
DEV_NAME=$SDCARD
|
||||
SDCARD=/dev/$SDCARD
|
||||
SDTYP=${SDCARD:5:2}
|
||||
+ fi
|
||||
else
|
||||
clear
|
||||
exit 1
|
||||
@@ -973,7 +1030,8 @@
|
||||
|
||||
if [[ "$SDTYP" = "sd" ]]; then
|
||||
SDDEV=""
|
||||
-elif [[ "$SDTYP" = "mm" || "$SDTYP" = "nv" ]]; then
|
||||
+elif [[ "$SDTYP" = "mm" || "$SDTYP" = "nv" || "$SDTYP" = "lo" ]]; then
|
||||
+ # loop devices use /dev/loopNp1 partition naming, same as mmcblk/nvme
|
||||
SDDEV="p"
|
||||
else
|
||||
clear
|
||||
@@ -1148,3 +1206,26 @@
|
||||
cleanup
|
||||
show_elapsed_time "${FUNCNAME}" "${timer_start}"
|
||||
sync
|
||||
+
|
||||
+# ─── image-output finalization (added) ────────────────────────────────────────
|
||||
+if [[ -n "$IMG_OUTPUT" ]]; then
|
||||
+ msg "Detaching loop device $IMG_LOOPDEV"
|
||||
+ sync
|
||||
+ losetup -d "$IMG_LOOPDEV" 2>/dev/null || true
|
||||
+ IMG_LOOPDEV=""
|
||||
+
|
||||
+ if [[ "$IMG_COMPRESS" = "1" ]]; then
|
||||
+ msg "Compressing $IMG_OUTPUT (this may take a while)"
|
||||
+ if command -v xz &>/dev/null; then
|
||||
+ xz -T0 -v "$IMG_OUTPUT"
|
||||
+ msg "Compressed: ${IMG_OUTPUT}.xz"
|
||||
+ elif command -v zstd &>/dev/null; then
|
||||
+ zstd -T0 -19 --rm "$IMG_OUTPUT" -o "${IMG_OUTPUT}.zst"
|
||||
+ msg "Compressed: ${IMG_OUTPUT}.zst"
|
||||
+ else
|
||||
+ info "Neither xz nor zstd found — leaving image uncompressed"
|
||||
+ fi
|
||||
+ fi
|
||||
+ msg "Image build complete: ${IMG_OUTPUT}$([[ "$IMG_COMPRESS" = "1" ]] && echo ".xz")"
|
||||
+fi
|
||||
+# ─── end image-output finalization ────────────────────────────────────────────
|
||||
Loading…
Reference in New Issue