Files
vphone-cli/scripts/cfw_host_mode.sh
T
zqxwceandClaude Opus 4.8 d28754e89e cfw: Implement ramdisk-free host-mount CFW install
Add a host-mount install path that replaces the DFU + ramdisk_send +
iproxy + SSH transport: mount the VM's Disk.img volumes on the host, place
every CFW file locally, then flip the boot snapshot offline
(tools/apfs_snap_rename.py). The resulting VM is identical to the
ramdisk-installed one, minus the round-trips.

- cfw_host_mode.sh: sourced by cfw_install*.sh when CFW_HOST_MODE=1;
  overrides ssh_cmd/scp_to/scp_from/remote_mount/remote_file_exists to run
  locally against volumes mounted at $CFW_HOST_MNT/mnt{1,3,5} (host / is
  read-only, so device /mntN tokens are remapped), routes /usr/bin/tar to
  gtar (bsdtar lacks the GNU flags), and skips snaputil/dropbearkey/halt.
- cfw_install{,_dev,_jb,_exp}.sh: source the shim after their helper defs
  (host-mode is opt-in; the SSH path is unchanged). Also reword progress
  messages that assumed the ramdisk/SSH flow ("~3 minutes" scp, "to
  device", "Reboot the device") to read correctly in both modes.
- cfw_install_host.sh + `make cfw_install_host VARIANT=regular|dev|jb|exp`:
  attach the image, run the chosen installer under CFW_HOST_MODE as root,
  detach, and run the offline snapshot flip. Restores ownership of the
  host-side artifacts it creates (vm/.vphoned.signed, .cfw_temp, ...) to
  the invoking user afterward, so a later user-run `make boot` isn't
  blocked by root-owned files.

Runs as root (owners-honored mounts / chown / cp) via a sudo re-exec. No
authenticated-root/ARV change needed; mount_apfs -o rw honors owners.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01XZVS9oqVNmHJzpb8mFtKJx
2026-07-06 15:15:01 +03:00

53 lines
2.5 KiB
Bash

# cfw_host_mode.sh — sourced by cfw_install*.sh when CFW_HOST_MODE=1.
#
# Replaces the SSH-to-ramdisk transport with local operations on the image
# volumes mounted on the host (by the host driver). The rest of each
# installer's logic (cfw.py patching, ldid signing, ipsw/aea cryptex decrypt,
# hdiutil DMG mounts, xcrun builds, DSC/DT patchers) is already host-side and
# runs unchanged. Must run as root. The boot-source flip the ramdisk did with
# `snaputil` is done separately, offline, by tools/apfs_snap_rename.py.
#
# The host root (/) is read-only (SSV), so device paths /mnt1,/mnt3,/mnt5 are
# remapped onto a writable scratch base (CFW_HOST_MNT). Only those exact
# device tokens are remapped, so host source paths (e.g. .../mnt_sysos) are
# left untouched.
: "${CFW_HOST_CONTAINER:?CFW_HOST_MODE=1 but CFW_HOST_CONTAINER (host apfs container disk, e.g. disk20) unset}"
CFW_HOST_MNT="${CFW_HOST_MNT:-/private/tmp/cfwhost}"
/bin/mkdir -p "$CFW_HOST_MNT"
_HOST_TAR="$(command -v gtar 2>/dev/null || echo /opt/homebrew/bin/gtar)"
_map() { # remap device /mntN tokens -> $CFW_HOST_MNT/mntN
local s="$1"
s="${s//\/mnt1/$CFW_HOST_MNT/mnt1}"
s="${s//\/mnt2/$CFW_HOST_MNT/mnt2}"
s="${s//\/mnt3/$CFW_HOST_MNT/mnt3}"
s="${s//\/mnt5/$CFW_HOST_MNT/mnt5}"
printf '%s' "$s"
}
ssh_cmd() {
local c="$*"
case "$c" in
*snaputil*) return 0 ;; # flip done offline
*dropbearkey*) return 0 ;; # host keys made at first boot
*dropbear_rsa_host_key*|*dropbear_ecdsa_host_key*) return 0 ;; # skip chmod of keys not created
*/sbin/halt*) return 0 ;; # no VM to halt
esac
c="${c//\/usr\/bin\/tar/$_HOST_TAR}" # macOS bsdtar lacks GNU flags
/bin/sh -c "$(_map "$c")"
}
scp_to() { /bin/cp -R "$(_map "$1")" "$(_map "$2")"; }
scp_from() { /bin/cp "$(_map "$1")" "$(_map "$2")"; }
remote_file_exists() { [[ -e "$(_map "$1")" ]]; }
remote_mount() {
local dev="$1" mnt opts="${3:-rw}"
mnt="$(_map "$2")"
local slice="${dev##*disk1}" # /dev/disk1sN -> sN
local hostdev="/dev/${CFW_HOST_CONTAINER}${slice}"
/bin/mkdir -p "$mnt"
/sbin/mount | /usr/bin/grep -q " on $mnt " && return 0
/sbin/mount_apfs -o "$opts" "$hostdev" "$mnt" 2>/dev/null || true
/sbin/mount | /usr/bin/grep -q " on $mnt " || die "host mount failed: $hostdev -> $mnt"
}
wait_for_device_ssh_ready() { :; }