Files
OrionOS/iso/docker/entrypoint-arm64.sh
T
nmemmertandClaude Sonnet 4.6 4cda708cc2 Fix ARM64 initramfs: write complete archiso mkinitcpio hooks inline
The archiso git repo doesn't ship the hooks as standalone files, and
ALARM has no archiso package. Write the hooks directly in the entrypoint
with the correct three-phase structure:

- run_earlyhook: modprobe squashfs/overlay/iso9660/loop/vfat before udev
- run_hook: parse archisolabel/archisobasedir from /proc/cmdline, set
  mount_handler="archiso_mount_handler"
- archiso_mount_handler: find ISO by label (fallback to TYPE=iso9660),
  mount it, mount squashfs at arch/$(uname -m)/airootfs.sfs, set up
  tmpfs cowspace, mount overlay to /new_root

install hook: add all required modules (squashfs, overlay, iso9660,
loop, vfat, nls_*) and binaries (blkid, losetup, sleep, uname).
Each mount step prints its progress and bails with a clear error message
on failure so boot panics are diagnosable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-27 08:40:18 -04:00

826 lines
25 KiB
Bash
Executable File

#!/usr/bin/env bash
# Runs inside the Docker container (aarch64).
# Produces /dist/orionos-arm64.iso using archiso's "releng" profile as a base.
set -euo pipefail
DIST="${DIST:-/dist}"
WORK=/tmp/orionos-work
PROFILE=/tmp/orionos-profile
SRC=/orionos
echo "════════════════════════════════════════"
echo " OrionOS ARM64 ISO Builder"
echo "════════════════════════════════════════"
# ── 1. Start from archiso's releng profile ────────────────────────────
echo ">>> Copying archiso releng profile..."
cp -r /usr/share/archiso/configs/releng "$PROFILE"
# Override the releng pacman.conf: it only has Arch Linux x86_64 repos.
# ALARM's linux-aarch64 kernel lives in [alarm] — without this the kernel
# package silently fails to install and /boot/vmlinuz-* is never created.
cat > "$PROFILE/pacman.conf" <<'PACMANCONF'
[options]
HoldPkg = pacman glibc
Architecture = aarch64
SigLevel = Never
# alarm-local is a file:// repo baked into the Docker image containing the
# pre-downloaded linux-aarch64 package. It comes first so pacstrap can always
# find the kernel even when the upstream [alarm] mirror is unreliable.
[alarm-local]
SigLevel = Never
Server = file:///alarm-local-repo
[core]
Include = /etc/pacman.d/mirrorlist
[extra]
Include = /etc/pacman.d/mirrorlist
[alarm]
Include = /etc/pacman.d/mirrorlist
[aur]
Include = /etc/pacman.d/mirrorlist
PACMANCONF
# The releng profile ships linux.preset in its airootfs for x86_64 linux kernel.
# It references /boot/vmlinuz-linux which doesn't exist on ALARM; remove it so
# mkinitcpio doesn't try to process it and fail.
rm -f "$PROFILE/airootfs/etc/mkinitcpio.d/linux.preset"
# ── 2. Package list — ARM64 (no syslinux, no Intel GPU, no broadcom-wl)
cat > "$PROFILE/packages.aarch64" <<'PKGS'
base
linux-aarch64
linux-firmware
mkinitcpio
grub
efibootmgr
xorg-server
xorg-xinit
xorg-xrandr
xorg-xset
xorg-xsetroot
xterm
alacritty
ttf-dejavu
ttf-liberation
noto-fonts
libxft
fontconfig
imlib2
xf86-video-fbdev
xf86-video-vesa
mesa
xf86-input-libinput
spice-vdagent
alsa-utils
alsa-firmware
pipewire
pipewire-alsa
pipewire-pulse
wireplumber
networkmanager
networkmanager-openvpn
thunar
gvfs
gvfs-smb
tumbler
ffmpegthumbnailer
file-roller
mousepad
feh
picom
xbindkeys
arandr
pavucontrol
brightnessctl
dunst
network-manager-applet
polkit-gnome
xdg-user-dirs
xdg-utils
shared-mime-info
desktop-file-utils
adwaita-icon-theme
gnome-themes-extra
hicolor-icon-theme
firefox
mpv
evince
viewnior
xscreensaver
xfce4-power-manager
bluez
blueman
xclip
scrot
parcellite
papirus-icon-theme
pacman-contrib
zip
unzip
p7zip
wget
curl
man-db
noto-fonts-emoji
playerctl
xorg-xkill
rsync
arch-install-scripts
htop
nano
git
sudo
bash-completion
fastfetch
plymouth
PKGS
# Remove the x86_64 package list so archiso doesn't get confused
rm -f "$PROFILE/packages.x86_64"
# ── 3. airootfs overlay — files that land in the live system ─────────
AIROOTFS="$PROFILE/airootfs"
# The archiso mkinitcpio hooks are not shipped as separate files in the
# archiso git repo. ALARM has no archiso package. Write them here with
# correct module loading, device detection, and overlay setup.
mkdir -p "$AIROOTFS/usr/lib/initcpio/hooks" "$AIROOTFS/usr/lib/initcpio/install"
cat > "$AIROOTFS/usr/lib/initcpio/hooks/archiso" <<'HOOK'
#!/usr/bin/ash
run_earlyhook() {
# Load all modules needed for live boot before udev runs
modprobe -q squashfs 2>/dev/null || true
modprobe -q overlay 2>/dev/null || true
modprobe -q iso9660 2>/dev/null || true
modprobe -q loop 2>/dev/null || true
modprobe -q vfat 2>/dev/null || true
}
run_hook() {
# Read kernel cmdline parameters
for _param in $(cat /proc/cmdline); do
case "${_param}" in
archisobasedir=*) archisobasedir="${_param#archisobasedir=}" ;;
archisolabel=*) archisolabel="${_param#archisolabel=}" ;;
esac
done
[ -z "${archisobasedir}" ] && archisobasedir="arch"
export mount_handler="archiso_mount_handler"
}
archiso_mount_handler() {
local _newroot="${1}"
local _dev _sfs _arch _i
# Find ISO device by label; fall back to any iso9660 device
_i=0
while [ "${_i}" -lt 30 ]; do
if [ -n "${archisolabel}" ]; then
_dev=$(blkid -l -t "LABEL=${archisolabel}" -o device 2>/dev/null)
fi
[ -z "${_dev}" ] && \
_dev=$(blkid -t TYPE=iso9660 -o device 2>/dev/null | head -1)
[ -n "${_dev}" ] && break
sleep 1
_i=$(( _i + 1 ))
done
if [ -z "${_dev}" ]; then
echo "ERROR: archiso: cannot find ISO device (label=${archisolabel})"
return 1
fi
echo ":: archiso: found device ${_dev}"
mkdir -p /run/archiso/bootmnt
mount -r "${_dev}" /run/archiso/bootmnt || {
echo "ERROR: archiso: cannot mount ${_dev}"
return 1
}
# Squashfs path: arch/<uname -m>/airootfs.sfs
_arch=$(uname -m)
_sfs="/run/archiso/bootmnt/${archisobasedir}/${_arch}/airootfs.sfs"
echo ":: archiso: mounting squashfs ${_sfs}"
mkdir -p /run/archiso/airootfs
if ! mount -r -t squashfs "${_sfs}" /run/archiso/airootfs; then
echo "ERROR: archiso: cannot mount squashfs ${_sfs}"
echo " contents of /run/archiso/bootmnt/${archisobasedir}/:"
ls "/run/archiso/bootmnt/${archisobasedir}/" 2>/dev/null || true
return 1
fi
# Writable overlay on top of the read-only squashfs
mkdir -p /run/archiso/cowspace
mount -t tmpfs -o size=75%,mode=0755 tmpfs /run/archiso/cowspace
mkdir -p /run/archiso/cowspace/upper /run/archiso/cowspace/work
mount -t overlay overlay \
-o "lowerdir=/run/archiso/airootfs,upperdir=/run/archiso/cowspace/upper,workdir=/run/archiso/cowspace/work" \
"${_newroot}" || {
echo "ERROR: archiso: overlay mount failed"
return 1
}
echo ":: archiso: overlay ready"
}
HOOK
chmod 755 "$AIROOTFS/usr/lib/initcpio/hooks/archiso"
cat > "$AIROOTFS/usr/lib/initcpio/install/archiso" <<'INSTALL'
#!/bin/bash
build() {
add_runscript
# Filesystems for the live medium
add_module squashfs
add_module overlay
add_module iso9660
add_module loop
add_module vfat
add_module fat
add_module nls_cp437
add_module nls_iso8859_1
add_module nls_utf8
# Required binaries
add_binary blkid
add_binary losetup
add_binary sleep
add_binary uname
# Pre-create mount points so the initramfs has them
add_dir /run/archiso/bootmnt
add_dir /run/archiso/airootfs
add_dir /run/archiso/cowspace
}
help() {
echo "Mounts the archiso squashfs live root via overlay."
}
INSTALL
chmod 755 "$AIROOTFS/usr/lib/initcpio/install/archiso"
echo ">>> archiso mkinitcpio hooks written to airootfs"
mkdir -p "$AIROOTFS/etc/mkinitcpio.conf.d"
cat > "$AIROOTFS/etc/mkinitcpio.conf.d/archiso.conf" <<'MKCONF'
MODULES=()
BINARIES=()
FILES=()
HOOKS=(base udev archiso block filesystems keyboard)
MKCONF
cat > "$AIROOTFS/etc/hostname" <<'EOF'
orionos
EOF
mkdir -p "$AIROOTFS/etc/sudoers.d"
echo "%wheel ALL=(ALL) ALL" > "$AIROOTFS/etc/sudoers.d/wheel"
# ── 4. Install OrionOS binaries ─────────────────────────────────────────
echo ">>> Installing OrionOS binaries..."
mkdir -p "$AIROOTFS/usr/local/bin"
install -m755 "$SRC/wm/orionwm" "$AIROOTFS/usr/local/bin/orionwm"
install -m755 "$SRC/deskbar/oriondeskbar" "$AIROOTFS/usr/local/bin/oriondeskbar"
install -m755 "$SRC/launcher/orionlauncher" "$AIROOTFS/usr/local/bin/orionlauncher"
install -m755 "$SRC/themes/orionwallpaper" "$AIROOTFS/usr/local/bin/orionwallpaper"
install -m755 "$SRC/nebula/nebula" "$AIROOTFS/usr/local/bin/nebula"
install -m755 "$SRC/orionpkg/orionpkg" "$AIROOTFS/usr/local/bin/orionpkg"
install -m755 "$SRC/installer/orioninstall" "$AIROOTFS/usr/local/bin/orioninstall"
if [[ -f "$SRC/installer/orioninstall-gui" ]]; then
install -m755 "$SRC/installer/orioninstall-gui" "$AIROOTFS/usr/local/bin/orioninstall-gui"
fi
if [[ -f "$SRC/rigel/rigel" ]]; then
install -m755 "$SRC/rigel/rigel" "$AIROOTFS/usr/local/bin/rigel"
fi
if [[ -f "$SRC/quill/quill" ]]; then
install -m755 "$SRC/quill/quill" "$AIROOTFS/usr/local/bin/quill"
fi
if [[ -f "$SRC/lens/lens" ]]; then
install -m755 "$SRC/lens/lens" "$AIROOTFS/usr/local/bin/lens"
fi
# ── 5. GTK theme ──────────────────────────────────────────────────────
echo ">>> Installing GTK theme..."
mkdir -p "$AIROOTFS/usr/share/themes"
cp -r "$SRC/themes/OrionOS" "$AIROOTFS/usr/share/themes/"
# ── 6. picom config ───────────────────────────────────────────────────
mkdir -p "$AIROOTFS/etc/orionos"
install -m644 "$SRC/themes/picom.conf" "$AIROOTFS/etc/orionos/picom.conf"
# ── 7. Default wallpaper ──────────────────────────────────────────────
echo ">>> Generating default wallpaper..."
mkdir -p "$AIROOTFS/usr/share/orionos/wallpapers"
if convert -size 1920x1080 gradient:"#1E3A5A-#0E1A28" \
"$AIROOTFS/usr/share/orionos/wallpapers/orionos-default.png" 2>/dev/null; then
echo " Wallpaper generated."
else
echo " (ImageMagick unavailable — wallpaper skipped)"
fi
# ── 8. User skeleton ──────────────────────────────────────────────────
echo ">>> Writing user skeleton..."
SKEL="$AIROOTFS/etc/skel"
mkdir -p "$SKEL/.config/gtk-3.0"
cat > "$SKEL/.xinitrc" <<'XINITRC'
#!/bin/sh
[ -f "$HOME/.Xresources" ] && xrdb -merge "$HOME/.Xresources"
xset r rate 250 30
xrandr --dpi 96
# SPICE clipboard agent (UTM copy-paste between host and VM)
spice-vdagent &
orionwallpaper
xdg-user-dirs-update 2>/dev/null || true
export GTK_THEME=OrionOS
mkdir -p "$HOME/.config/gtk-3.0"
cat > "$HOME/.config/gtk-3.0/settings.ini" <<EOF
[Settings]
gtk-theme-name=OrionOS
gtk-font-name=Sans 10
gtk-icon-theme-name=Papirus-Dark
gtk-cursor-theme-name=Adwaita
EOF
cat > "$HOME/.gtkrc-2.0" <<EOF
include "/usr/share/themes/OrionOS/gtk-2.0/gtkrc"
EOF
pipewire &
pipewire-pulse &
wireplumber &
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &
dunst &
nm-applet &
picom --config /etc/orionos/picom.conf &
parcellite &
xscreensaver -no-splash &
xfce4-power-manager &
xbindkeys &
oriondeskbar &
exec orionwm
XINITRC
chmod 755 "$SKEL/.xinitrc"
cat > "$SKEL/.xbindkeysrc" <<'XBK'
"orionlauncher"
Mod1 + F1
"nebula"
super + s
"brightnessctl set 10%-"
XF86MonBrightnessDown
"brightnessctl set +10%"
XF86MonBrightnessUp
"pactl set-sink-mute @DEFAULT_SINK@ toggle"
XF86AudioMute
"pactl set-sink-volume @DEFAULT_SINK@ -5%"
XF86AudioLowerVolume
"pactl set-sink-volume @DEFAULT_SINK@ +5%"
XF86AudioRaiseVolume
XBK
mkdir -p "$AIROOTFS/etc/fonts"
cat > "$AIROOTFS/etc/fonts/local.conf" <<'FONTS'
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<match target="font">
<edit name="antialias" mode="assign"><bool>true</bool></edit>
<edit name="hinting" mode="assign"><bool>true</bool></edit>
<edit name="hintstyle" mode="assign"><const>hintslight</const></edit>
<edit name="rgba" mode="assign"><const>rgb</const></edit>
<edit name="lcdfilter" mode="assign"><const>lcddefault</const></edit>
</match>
<alias>
<family>sans-serif</family>
<prefer><family>DejaVu Sans</family><family>Noto Color Emoji</family></prefer>
</alias>
<alias>
<family>monospace</family>
<prefer><family>DejaVu Sans Mono</family></prefer>
</alias>
</fontconfig>
FONTS
cat > "$SKEL/.Xresources" <<'XRES'
XTerm*faceName: DejaVu Sans Mono
XTerm*faceSize: 11
XTerm*renderFont: true
XTerm*antialias: true
XTerm*background: #0E1520
XTerm*foreground: #C8D4E8
XTerm*cursorColor: #4A90D9
XTerm*scrollBar: false
XTerm*saveLines: 4096
XTerm*metaSendsEscape: true
XTerm*utf8: 2
XTerm*color0: #1A1E2A
XTerm*color1: #CC4444
XTerm*color2: #44AA66
XTerm*color3: #BBAA22
XTerm*color4: #4488CC
XTerm*color5: #8844CC
XTerm*color6: #44AACC
XTerm*color7: #C8D4E8
XTerm*color8: #3A4050
XTerm*color9: #FF6666
XTerm*color10: #66CC88
XTerm*color11: #DDCC44
XTerm*color12: #66AAFF
XTerm*color13: #AA66FF
XTerm*color14: #66CCEE
XTerm*color15: #EEF4FF
XRES
mkdir -p "$SKEL/.config/alacritty"
cat > "$SKEL/.config/alacritty/alacritty.toml" <<'ALACRITTY'
[window]
padding = { x = 10, y = 8 }
decorations = "none"
opacity = 0.96
title = "Terminal"
[font]
normal = { family = "DejaVu Sans Mono", style = "Regular" }
bold = { family = "DejaVu Sans Mono", style = "Bold" }
size = 11.0
[colors.primary]
background = "#0E1520"
foreground = "#C8D4E8"
[colors.cursor]
text = "#0E1520"
cursor = "#4A90D9"
[colors.normal]
black = "#1A1E2A"
red = "#CC4444"
green = "#44AA66"
yellow = "#BBAA22"
blue = "#4488CC"
magenta = "#8844CC"
cyan = "#44AACC"
white = "#C8D4E8"
[colors.bright]
black = "#3A4050"
red = "#FF6666"
green = "#66CC88"
yellow = "#DDCC44"
blue = "#66AAFF"
magenta = "#AA66FF"
cyan = "#66CCEE"
white = "#EEF4FF"
[colors.selection]
background = "#2060A0"
text = "#F0F4FF"
[scrolling]
history = 10000
[cursor]
style = { shape = "Block", blinking = "On" }
blink_interval = 500
ALACRITTY
mkdir -p "$SKEL/.config/dunst"
cat > "$SKEL/.config/dunst/dunstrc" <<'DUNST'
[global]
font = Sans 10
geometry = "300x5-20+46"
transparency = 0
frame_color = "#2A3A5A"
frame_width = 1
separator_color = "#2A3A5A"
sort = yes
indicate_hidden = yes
shrink = no
markup = full
format = "<b>%s</b>\n%b"
alignment = left
word_wrap = yes
padding = 10
horizontal_padding = 10
max_icon_size = 32
sticky_history = yes
history_length = 20
browser = firefox
[urgency_low]
background = "#1C2230"
foreground = "#A0B8D0"
timeout = 5
[urgency_normal]
background = "#1E3050"
foreground = "#D0E0F0"
timeout = 8
[urgency_critical]
background = "#5A1010"
foreground = "#FFD0D0"
frame_color = "#AA2020"
timeout = 0
DUNST
cat > "$SKEL/.config/gtk-3.0/settings.ini" <<'GTK3'
[Settings]
gtk-theme-name=OrionOS
gtk-font-name=Sans 10
gtk-icon-theme-name=Adwaita
gtk-cursor-theme-name=DMZ-White
GTK3
# ── Plymouth dark navy boot splash ───────────────────────────────────
echo ">>> Creating Plymouth theme..."
PLYM="$AIROOTFS/usr/share/plymouth/themes/orionos"
mkdir -p "$PLYM"
cat > "$PLYM/orionos.plymouth" <<'PLYMDEF'
[Plymouth Theme]
Name=OrionOS
Description=OrionOS dark navy boot splash
ModuleName=script
[script]
ImageDir=/usr/share/plymouth/themes/orionos
ScriptFile=/usr/share/plymouth/themes/orionos/orionos.script
PLYMDEF
cat > "$PLYM/orionos.script" <<'PLYMSCRIPT'
W = Window.GetWidth();
H = Window.GetHeight();
Window.SetBackgroundTopColor(0.067, 0.082, 0.125);
Window.SetBackgroundBottomColor(0.040, 0.055, 0.090);
logo = Image("logo.png");
logo_sprite = Sprite(logo);
logo_sprite.SetPosition(
Math.Int((W - logo.GetWidth()) / 2),
Math.Int(H * 0.40 - logo.GetHeight() / 2),
1
);
BAR_W = Math.Int(Math.Min(W * 0.42, 440));
BAR_H = 4;
bar_x = Math.Int((W - BAR_W) / 2);
bar_y = Math.Int(H * 0.72);
bar_bg = Image("bar_bg.png").Scale(BAR_W, BAR_H);
bar_bg_sprite = Sprite(bar_bg);
bar_bg_sprite.SetPosition(bar_x, bar_y, 2);
bar_fill_sprite = Sprite();
bar_fill_sprite.SetPosition(bar_x, bar_y, 3);
fun boot_progress_callback(time, progress) {
fill_w = Math.Int(BAR_W * progress);
if (fill_w < 2) fill_w = 2;
bar_fill = Image("bar_fg.png").Scale(fill_w, BAR_H);
bar_fill_sprite.SetImage(bar_fill);
}
Plymouth.SetBootProgressFunction(boot_progress_callback);
PLYMSCRIPT
if command -v convert &>/dev/null; then
convert -size 340x90 xc:none \
-font DejaVu-Sans-Bold -pointsize 62 \
-fill "#90BBEE" -gravity center \
-annotate 0 "OrionOS" \
"$PLYM/logo.png" 2>/dev/null || true
convert -size 1x1 xc:"#1C2840" "$PLYM/bar_bg.png" 2>/dev/null || true
convert -size 1x1 xc:"#1E58A8" "$PLYM/bar_fg.png" 2>/dev/null || true
fi
# ── VirtIO / QEMU display config (UTM) ────────────────────────────────
mkdir -p "$AIROOTFS/etc/X11/xorg.conf.d"
cat > "$AIROOTFS/etc/X11/xorg.conf.d/20-virtio.conf" <<'VIRTIO'
Section "Device"
Identifier "VirtIO GPU"
Driver "modesetting"
Option "AccelMethod" "none"
EndSection
VIRTIO
cat > "$AIROOTFS/etc/X11/xorg.conf.d/40-libinput.conf" <<'TOUCHPAD'
Section "InputClass"
Identifier "Touchpad"
MatchIsTouchpad "on"
Driver "libinput"
Option "Tapping" "on"
Option "NaturalScrolling" "true"
Option "ScrollMethod" "twofinger"
EndSection
TOUCHPAD
cat > "$AIROOTFS/etc/X11/xorg.conf.d/10-keyboard.conf" <<'KEYBOARD'
Section "InputClass"
Identifier "All Keyboards"
MatchIsKeyboard "on"
Driver "libinput"
Option "XkbLayout" "us"
Option "XkbOptions" "terminate:ctrl_alt_bksp"
EndSection
KEYBOARD
# ── 9. profiledef.sh — aarch64, EFI only ─────────────────────────────
cat > "$PROFILE/profiledef.sh" <<'PROFILEDEF'
#!/usr/bin/env bash
iso_name="orionos-arm64"
iso_label="ORIONOS_ARM64_$(date +%Y%m)"
iso_publisher="OrionOS Project"
iso_application="OrionOS — BeOS-inspired Linux Desktop (ARM64)"
iso_version="0.2"
install_dir="arch"
buildmodes=('iso')
bootmodes=('uefi.systemd-boot')
arch="aarch64"
pacman_conf="pacman.conf"
airootfs_image_type="squashfs"
airootfs_image_tool_options=('-comp' 'zstd' '-Xcompression-level' '5' '-b' '1M')
bootstrap_tarball_compression=('zstd' '-c' '-T0' '--auto-threads=logical' '--long' '-19')
file_permissions=(
["/etc/shadow"]="0:0:400"
["/etc/skel/.xinitrc"]="0:0:755"
["/root/customize_airootfs.sh"]="0:0:755"
["/usr/local/bin/orionwm"]="0:0:755"
["/usr/local/bin/oriondeskbar"]="0:0:755"
["/usr/local/bin/orionlauncher"]="0:0:755"
["/usr/local/bin/orionwallpaper"]="0:0:755"
["/usr/local/bin/nebula"]="0:0:755"
["/usr/local/bin/orionpkg"]="0:0:755"
["/usr/local/bin/orioninstall"]="0:0:755"
)
PROFILEDEF
# ── 10. EFI boot loader (aarch64 kernel paths) ───────────────────────
mkdir -p "$PROFILE/efiboot/loader/entries"
cat > "$PROFILE/efiboot/loader/loader.conf" <<'LOADER'
default orionos.conf
timeout 5
editor no
LOADER
cat > "$PROFILE/efiboot/loader/entries/orionos.conf" <<'ENTRY'
title OrionOS ARM64
linux /arch/boot/aarch64/vmlinuz-linux-aarch64
initrd /arch/boot/aarch64/initramfs-linux-aarch64.img
options archisobasedir=arch archisolabel=%ARCHISO_LABEL% quiet splash loglevel=3
ENTRY
# ── 11. Auto-login ────────────────────────────────────────────────────
mkdir -p "$AIROOTFS/etc/systemd/system/getty@tty1.service.d"
cat > "$AIROOTFS/etc/systemd/system/getty@tty1.service.d/autologin.conf" <<'AUTOLOGIN'
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin orion --noclear %I $TERM
AUTOLOGIN
cat > "$SKEL/.bash_profile" <<'BASH_PROFILE'
if [[ -z $DISPLAY && $XDG_VTNR -eq 1 ]]; then
startx 2>&1 | tee /tmp/x-session.log
fi
BASH_PROFILE
# ── 12. customize_airootfs.sh ────────────────────────────────────────
cat > "$PROFILE/airootfs/root/customize_airootfs.sh" <<'CUSTOMIZE'
#!/usr/bin/env bash
set -euo pipefail
sed -i 's/#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
locale-gen
echo "LANG=en_US.UTF-8" > /etc/locale.conf
ln -sf /usr/share/zoneinfo/UTC /etc/localtime
echo "=== /boot/ contents ==="
ls -la /boot/ 2>&1 || echo "(cannot list /boot)"
echo "=== linux-aarch64 package status ==="
pacman -Q linux-aarch64 2>&1 || echo "NOT INSTALLED"
echo "=== /usr/lib/modules/ ==="
ls /usr/lib/modules/ 2>&1 || echo "(empty)"
echo "=== end diagnostics ==="
# ALARM aarch64 may install the kernel as /boot/Image (uncompressed EFI
# stub) rather than /boot/vmlinuz-linux-aarch64. Archiso's vmlinuz-* glob
# and systemd-boot both expect the vmlinuz-* naming — create a symlink.
if [[ ! -f /boot/vmlinuz-linux-aarch64 ]]; then
if [[ -f /boot/Image ]]; then
ln -sf Image /boot/vmlinuz-linux-aarch64
echo ">>> Symlinked /boot/Image -> vmlinuz-linux-aarch64"
elif [[ -f /boot/Image.gz ]]; then
ln -sf Image.gz /boot/vmlinuz-linux-aarch64
echo ">>> Symlinked /boot/Image.gz -> vmlinuz-linux-aarch64"
else
echo "WARNING: no kernel image found in /boot/ — build will likely fail"
ls /boot/ 2>&1 || true
fi
fi
useradd -m -G wheel,audio,video,storage,input -s /bin/bash orion 2>/dev/null || true
echo "orion:orionos" | chpasswd
echo "%wheel ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/wheel
chmod 440 /etc/sudoers.d/wheel
systemctl enable NetworkManager
systemctl enable spice-vdagentd 2>/dev/null || true
systemctl enable bluetooth 2>/dev/null || true
systemctl enable fstrim.timer 2>/dev/null || true
update-desktop-database 2>/dev/null || true
fc-cache -f 2>/dev/null || true
plymouth-set-default-theme orionos 2>/dev/null || true
# Override linux-aarch64.preset with an 'archiso' entry for the live initramfs.
# Done here (post-pacstrap) to avoid conflicting with the package's own preset
# file during installation. mkarchiso looks for a preset named 'archiso'.
cat > /etc/mkinitcpio.d/linux-aarch64.preset <<'PRESET'
ALL_config="/etc/mkinitcpio.conf.d/archiso.conf"
ALL_kver="/boot/vmlinuz-linux-aarch64"
PRESETS=('archiso')
archiso_image="/boot/initramfs-linux-aarch64.img"
PRESET
mkinitcpio -p linux-aarch64 2>&1 | tail -10 || true
mkdir -p /etc/skel
cat > /etc/skel/.xscreensaver <<'SS'
mode: blank
timeout: 0:10:00
lock: True
lockTimeout: 0:00:00
dpmsEnabled: True
dpmsStandby: 0:10:00
dpmsSuspend: 0:20:00
dpmsOff: 0:30:00
SS
cp -r /etc/skel/. /home/orion/ 2>/dev/null || true
chown -R orion:orion /home/orion
chmod +x /usr/local/bin/orionwm \
/usr/local/bin/oriondeskbar \
/usr/local/bin/orionlauncher \
/usr/local/bin/orionwallpaper \
/usr/local/bin/orioninstall 2>/dev/null || true
[ -f /usr/local/bin/orioninstall-gui ] && chmod +x /usr/local/bin/orioninstall-gui
echo "OrionOS ARM64 customization complete."
CUSTOMIZE
chmod 755 "$PROFILE/airootfs/root/customize_airootfs.sh"
# ── 13. Fix EFI FAT image size for the large ARM64 kernel ────────────
# mkarchiso calculates EFI FAT image size as roughly (kernel+initramfs MiB)+N
# but the ARM64 kernel Image is ~50 MB and FAT filesystem overhead pushes
# the total over the calculated limit → "Disk full".
#
# Strategy: put a mkfs.fat wrapper earlier in PATH that transparently adds
# +128 MiB to every -C (create) call. This works regardless of which exact
# formula the installed mkarchiso version uses.
cat > /usr/local/bin/mkfs.fat <<'MKFAT'
#!/usr/bin/bash
args=("$@")
# When creating (-C) the EFI FAT image, add 128 MiB to the requested size
if [[ " ${args[*]} " == *" -C "* ]] && [[ "${args[-1]}" =~ ^[0-9]+$ ]]; then
args[-1]=$(( ${args[-1]} + 131072 )) # +128 MiB in KiB blocks
fi
exec /usr/bin/mkfs.fat "${args[@]}"
MKFAT
chmod +x /usr/local/bin/mkfs.fat
export PATH="/usr/local/bin:$PATH"
echo ">>> mkfs.fat wrapper active — EFI FAT creation gets +128 MiB headroom"
echo ">>> mkarchiso EFI size lines (for reference):"
grep -n "1024.*1024\|fat.*size\|efi.*size\|img_size" /usr/bin/mkarchiso 2>/dev/null \
| grep -iv "^[0-9]*:#\|comment" | head -8 || true
# ── 14. Build the ISO ─────────────────────────────────────────────────
echo ">>> Building ARM64 ISO (this takes 5-15 minutes)..."
mkdir -p "$DIST" "$WORK"
mkarchiso -v \
-w "$WORK" \
-o "$DIST" \
"$PROFILE"
echo ""
echo "════════════════════════════════════════"
echo " Build complete!"
find "$DIST" -name "*.iso" -exec echo " ISO: {}" \;
echo "════════════════════════════════════════"