inferno0230 revidoval tento gist 4 weeks ago. Přejít na revizi
1 file changed, 273 insertions
partition_gbl.sh(vytvořil soubor)
| @@ -0,0 +1,273 @@ | |||
| 1 | + | #!/usr/bin/env bash | |
| 2 | + | # Partition a whole disk with a bringup-oriented Android GBL GPT layout. | |
| 3 | + | # | |
| 4 | + | # Usage: | |
| 5 | + | # sudo ./partition_gbl_disk.sh [--efi /path/to/BOOTAA64.EFI] /dev/sdX | |
| 6 | + | # | |
| 7 | + | # Optional environment overrides: | |
| 8 | + | # SUPER_SIZE=8G ./partition_gbl_disk.sh /dev/sdX | |
| 9 | + | # | |
| 10 | + | # The script intentionally asks for confirmation once before touching the disk. | |
| 11 | + | ||
| 12 | + | set -euo pipefail | |
| 13 | + | ||
| 14 | + | ESP_SIZE="${ESP_SIZE:-8M}" | |
| 15 | + | MISC_SIZE="${MISC_SIZE:-4M}" | |
| 16 | + | BOOT_SIZE="${BOOT_SIZE:-128M}" | |
| 17 | + | VENDOR_BOOT_SIZE="${VENDOR_BOOT_SIZE:-128M}" | |
| 18 | + | INIT_BOOT_SIZE="${INIT_BOOT_SIZE:-8M}" | |
| 19 | + | VBMETA_SIZE="${VBMETA_SIZE:-4M}" | |
| 20 | + | DTBO_SIZE="${DTBO_SIZE:-32M}" | |
| 21 | + | SUPER_SIZE="${SUPER_SIZE:-8G}" | |
| 22 | + | METADATA_SIZE="${METADATA_SIZE:-64M}" | |
| 23 | + | ||
| 24 | + | die() { | |
| 25 | + | echo "error: $*" >&2 | |
| 26 | + | exit 1 | |
| 27 | + | } | |
| 28 | + | ||
| 29 | + | usage() { | |
| 30 | + | cat >&2 <<EOF | |
| 31 | + | Usage: | |
| 32 | + | sudo $0 [--efi /path/to/BOOTAA64.EFI] /dev/sdX | |
| 33 | + | ||
| 34 | + | Creates a destructive GPT layout for Android GBL bringup: | |
| 35 | + | android_esp_a/b, misc, boot_a/b, vendor_boot_a/b, init_boot_a/b, | |
| 36 | + | vbmeta_a/b, dtbo_a/b, dtb_a/b, pvmfw_a/b, super, metadata, userdata. | |
| 37 | + | ||
| 38 | + | Options: | |
| 39 | + | --efi FILE Copy FILE to both ESPs as /EFI/BOOT/BOOTAA64.EFI | |
| 40 | + | -h, --help Show this help | |
| 41 | + | ||
| 42 | + | Environment overrides: | |
| 43 | + | ESP_SIZE=$ESP_SIZE | |
| 44 | + | MISC_SIZE=$MISC_SIZE | |
| 45 | + | BOOT_SIZE=$BOOT_SIZE | |
| 46 | + | VENDOR_BOOT_SIZE=$VENDOR_BOOT_SIZE | |
| 47 | + | INIT_BOOT_SIZE=$INIT_BOOT_SIZE | |
| 48 | + | VBMETA_SIZE=$VBMETA_SIZE | |
| 49 | + | DTBO_SIZE=$DTBO_SIZE | |
| 50 | + | PVMFW_SIZE=$PVMFW_SIZE | |
| 51 | + | SUPER_SIZE=$SUPER_SIZE | |
| 52 | + | METADATA_SIZE=$METADATA_SIZE | |
| 53 | + | EOF | |
| 54 | + | } | |
| 55 | + | ||
| 56 | + | require_cmd() { | |
| 57 | + | command -v "$1" >/dev/null 2>&1 || die "missing required command: $1" | |
| 58 | + | } | |
| 59 | + | ||
| 60 | + | cleanup() { | |
| 61 | + | if [[ -n "${ESP_A_MNT:-}" && -d "${ESP_A_MNT:-}" ]]; then | |
| 62 | + | umount "$ESP_A_MNT" 2>/dev/null || true | |
| 63 | + | rmdir "$ESP_A_MNT" 2>/dev/null || true | |
| 64 | + | fi | |
| 65 | + | if [[ -n "${ESP_B_MNT:-}" && -d "${ESP_B_MNT:-}" ]]; then | |
| 66 | + | umount "$ESP_B_MNT" 2>/dev/null || true | |
| 67 | + | rmdir "$ESP_B_MNT" 2>/dev/null || true | |
| 68 | + | fi | |
| 69 | + | if [[ -n "${SFDISK_SCRIPT:-}" ]]; then | |
| 70 | + | rm -f "$SFDISK_SCRIPT" | |
| 71 | + | fi | |
| 72 | + | } | |
| 73 | + | ||
| 74 | + | partition_path() { | |
| 75 | + | local disk="$1" | |
| 76 | + | local number="$2" | |
| 77 | + | ||
| 78 | + | case "$disk" in | |
| 79 | + | *[0-9]) printf '%sp%s\n' "$disk" "$number" ;; | |
| 80 | + | *) printf '%s%s\n' "$disk" "$number" ;; | |
| 81 | + | esac | |
| 82 | + | } | |
| 83 | + | ||
| 84 | + | EFI_PAYLOAD="" | |
| 85 | + | ARGS=() | |
| 86 | + | ||
| 87 | + | while [[ $# -gt 0 ]]; do | |
| 88 | + | case "$1" in | |
| 89 | + | --efi) | |
| 90 | + | [[ $# -ge 2 ]] || die "--efi requires a file path" | |
| 91 | + | EFI_PAYLOAD="$2" | |
| 92 | + | shift 2 | |
| 93 | + | ;; | |
| 94 | + | -h | --help) | |
| 95 | + | usage | |
| 96 | + | exit 0 | |
| 97 | + | ;; | |
| 98 | + | --) | |
| 99 | + | shift | |
| 100 | + | ARGS+=("$@") | |
| 101 | + | break | |
| 102 | + | ;; | |
| 103 | + | -*) | |
| 104 | + | die "unknown argument: $1" | |
| 105 | + | ;; | |
| 106 | + | *) | |
| 107 | + | ARGS+=("$1") | |
| 108 | + | shift | |
| 109 | + | ;; | |
| 110 | + | esac | |
| 111 | + | done | |
| 112 | + | ||
| 113 | + | [[ ${#ARGS[@]} -eq 1 ]] || { | |
| 114 | + | usage | |
| 115 | + | exit 2 | |
| 116 | + | } | |
| 117 | + | ||
| 118 | + | DISK="${ARGS[0]}" | |
| 119 | + | ||
| 120 | + | [[ $EUID -eq 0 ]] || die "run as root, for example: sudo $0 $DISK" | |
| 121 | + | [[ -b "$DISK" ]] || die "$DISK is not a block device" | |
| 122 | + | if [[ -n "$EFI_PAYLOAD" ]]; then | |
| 123 | + | [[ -f "$EFI_PAYLOAD" ]] || die "--efi payload does not exist or is not a regular file: $EFI_PAYLOAD" | |
| 124 | + | fi | |
| 125 | + | ||
| 126 | + | require_cmd sfdisk | |
| 127 | + | require_cmd lsblk | |
| 128 | + | require_cmd findmnt | |
| 129 | + | if [[ -n "$EFI_PAYLOAD" ]]; then | |
| 130 | + | require_cmd mount | |
| 131 | + | require_cmd umount | |
| 132 | + | require_cmd mkfs.vfat | |
| 133 | + | fi | |
| 134 | + | ||
| 135 | + | if [[ "$(lsblk -dn -o TYPE "$DISK")" != "disk" ]]; then | |
| 136 | + | die "$DISK is not a whole disk according to lsblk" | |
| 137 | + | fi | |
| 138 | + | ||
| 139 | + | if findmnt --source "$DISK" >/dev/null 2>&1; then | |
| 140 | + | die "$DISK itself is mounted; unmount it first" | |
| 141 | + | fi | |
| 142 | + | ||
| 143 | + | while read -r child; do | |
| 144 | + | [[ -n "$child" ]] || continue | |
| 145 | + | if findmnt --source "$child" >/dev/null 2>&1; then | |
| 146 | + | die "$child is mounted; unmount all partitions on $DISK first" | |
| 147 | + | fi | |
| 148 | + | done < <(lsblk -nrpo NAME "$DISK" | tail -n +2) | |
| 149 | + | ||
| 150 | + | cat <<EOF | |
| 151 | + | About to DESTROY ALL DATA on: | |
| 152 | + | $DISK | |
| 153 | + | ||
| 154 | + | Planned GPT layout: | |
| 155 | + | 1 android_esp_a $ESP_SIZE EFI System, FAT32 | |
| 156 | + | 2 android_esp_b $ESP_SIZE EFI System, FAT32 | |
| 157 | + | 3 misc $MISC_SIZE | |
| 158 | + | 4 boot_a $BOOT_SIZE | |
| 159 | + | 5 boot_b $BOOT_SIZE | |
| 160 | + | 6 vendor_boot_a $VENDOR_BOOT_SIZE | |
| 161 | + | 7 vendor_boot_b $VENDOR_BOOT_SIZE | |
| 162 | + | 8 init_boot_a $INIT_BOOT_SIZE | |
| 163 | + | 9 init_boot_b $INIT_BOOT_SIZE | |
| 164 | + | 10 vbmeta_a $VBMETA_SIZE | |
| 165 | + | 11 vbmeta_b $VBMETA_SIZE | |
| 166 | + | 12 dtbo_a $DTBO_SIZE | |
| 167 | + | 13 dtbo_b $DTBO_SIZE | |
| 168 | + | 14 super $SUPER_SIZE | |
| 169 | + | 15 metadata $METADATA_SIZE | |
| 170 | + | 16 userdata remaining space | |
| 171 | + | ||
| 172 | + | EOF | |
| 173 | + | if [[ -n "$EFI_PAYLOAD" ]]; then | |
| 174 | + | cat <<EOF | |
| 175 | + | GBL EFI payload: | |
| 176 | + | $EFI_PAYLOAD | |
| 177 | + | ||
| 178 | + | The payload will be copied to both Android ESPs as: | |
| 179 | + | /EFI/BOOT/BOOTAA64.EFI | |
| 180 | + | ||
| 181 | + | EOF | |
| 182 | + | fi | |
| 183 | + | cat <<EOF | |
| 184 | + | This cannot be undone by this script. | |
| 185 | + | EOF | |
| 186 | + | ||
| 187 | + | read -r -p "Continue and destroy all data on $DISK? [y/N]: " CONFIRMATION | |
| 188 | + | case "$CONFIRMATION" in | |
| 189 | + | y | Y | yes | YES) | |
| 190 | + | ;; | |
| 191 | + | *) | |
| 192 | + | die "aborting" | |
| 193 | + | ;; | |
| 194 | + | esac | |
| 195 | + | ||
| 196 | + | SFDISK_SCRIPT="$(mktemp)" | |
| 197 | + | trap cleanup EXIT | |
| 198 | + | ||
| 199 | + | # Declarative GPT layout for sfdisk. Omitted start sectors let sfdisk choose | |
| 200 | + | # aligned starts. Omitted userdata size consumes the remaining disk. | |
| 201 | + | cat >"$SFDISK_SCRIPT" <<EOF | |
| 202 | + | label: gpt | |
| 203 | + | ||
| 204 | + | name="android_esp_a", size=$ESP_SIZE,type=uefi, name="EFI" | |
| 205 | + | name="android_esp_b", size=$ESP_SIZE,type=uefi, name="EFI" | |
| 206 | + | name="misc", size=$MISC_SIZE | |
| 207 | + | name="boot_a", size=$BOOT_SIZE | |
| 208 | + | name="boot_b", size=$BOOT_SIZE | |
| 209 | + | name="vendor_boot_a", size=$VENDOR_BOOT_SIZE | |
| 210 | + | name="vendor_boot_b", size=$VENDOR_BOOT_SIZE | |
| 211 | + | name="init_boot_a", size=$INIT_BOOT_SIZE | |
| 212 | + | name="init_boot_b", size=$INIT_BOOT_SIZE | |
| 213 | + | name="vbmeta_a", size=$VBMETA_SIZE | |
| 214 | + | name="vbmeta_b", size=$VBMETA_SIZE | |
| 215 | + | name="dtbo_a", size=$DTBO_SIZE | |
| 216 | + | name="dtbo_b", size=$DTBO_SIZE | |
| 217 | + | name="super", size=$SUPER_SIZE | |
| 218 | + | name="metadata", size=$METADATA_SIZE | |
| 219 | + | name="userdata" | |
| 220 | + | EOF | |
| 221 | + | ||
| 222 | + | echo "Writing GPT with sfdisk..." | |
| 223 | + | sfdisk "$DISK" <"$SFDISK_SCRIPT" | |
| 224 | + | ||
| 225 | + | if command -v partprobe >/dev/null 2>&1; then | |
| 226 | + | partprobe "$DISK" || true | |
| 227 | + | fi | |
| 228 | + | if command -v udevadm >/dev/null 2>&1; then | |
| 229 | + | udevadm settle || true | |
| 230 | + | fi | |
| 231 | + | blockdev --rereadpt "$DISK" 2>/dev/null || true | |
| 232 | + | ||
| 233 | + | ESP_A="$(partition_path "$DISK" 1)" | |
| 234 | + | ESP_B="$(partition_path "$DISK" 2)" | |
| 235 | + | ||
| 236 | + | if command -v mkfs.fat >/dev/null 2>&1; then | |
| 237 | + | echo "Formatting Android ESP partitions as FAT32..." | |
| 238 | + | mkfs.vfat -n EFI "$ESP_A" | |
| 239 | + | mkfs.vfat -n EFI "$ESP_B" | |
| 240 | + | else | |
| 241 | + | echo "warning: mkfs.fat not found; format $ESP_A and $ESP_B as FAT32 manually" >&2 | |
| 242 | + | fi | |
| 243 | + | ||
| 244 | + | if [[ -n "$EFI_PAYLOAD" ]]; then | |
| 245 | + | echo "Copying GBL EFI payload to Android ESP partitions..." | |
| 246 | + | ESP_A_MNT="$(mktemp -d /tmp/gbl-esp-a.XXXXXX)" | |
| 247 | + | ESP_B_MNT="$(mktemp -d /tmp/gbl-esp-b.XXXXXX)" | |
| 248 | + | ||
| 249 | + | mount "$ESP_A" "$ESP_A_MNT" | |
| 250 | + | mount "$ESP_B" "$ESP_B_MNT" | |
| 251 | + | ||
| 252 | + | mkdir -p "$ESP_A_MNT/EFI/BOOT" | |
| 253 | + | mkdir -p "$ESP_B_MNT/EFI/BOOT" | |
| 254 | + | cp "$EFI_PAYLOAD" "$ESP_A_MNT/EFI/BOOT/BOOTAA64.EFI" | |
| 255 | + | cp "$EFI_PAYLOAD" "$ESP_B_MNT/EFI/BOOT/BOOTAA64.EFI" | |
| 256 | + | sync | |
| 257 | + | ||
| 258 | + | umount "$ESP_A_MNT" | |
| 259 | + | umount "$ESP_B_MNT" | |
| 260 | + | rmdir "$ESP_A_MNT" "$ESP_B_MNT" | |
| 261 | + | ESP_A_MNT="" | |
| 262 | + | ESP_B_MNT="" | |
| 263 | + | fi | |
| 264 | + | ||
| 265 | + | echo | |
| 266 | + | echo "Done. Resulting partition table:" | |
| 267 | + | sfdisk -d "$DISK" | |
| 268 | + | echo | |
| 269 | + | if [[ -n "$EFI_PAYLOAD" ]]; then | |
| 270 | + | echo "GBL EFI payload copied to both ESPs as /EFI/BOOT/BOOTAA64.EFI." | |
| 271 | + | else | |
| 272 | + | echo "Copy GBL to both ESPs as /EFI/BOOT/BOOTAA64.EFI before booting." | |
| 273 | + | fi | |
Novější
Starší