# Porteus Kiosk on a 2018 T2 Mac mini

## Boot the stock USB installer with Apple Wi-Fi, then install to an internal partition

Yes. The improved sequence is to create the internal `KIOSKBOOT` partition first, install GRUB plus a modified installer initrd there, and let that boot the completely stock Porteus installer USB. The bootloader itself does not inject firmware—the modified initrd it loads does.

The flow becomes:

```text
Internal KIOSKBOOT
  ├── GRUB
  ├── installer/vmlinuz
  └── installer/initrd-apple.xz
             │
             ▼
Stock Porteus installer USB
             │
             ▼
Kiosk Wizard with built-in Wi-Fi
             │
             ▼
Save final stock ISO
             │
             ▼
Write final ISO to internal KIOSKISO partition
```

## 1. Create the internal partitions first

From macOS Disk Utility, create:

- `KIOSKBOOT`: 512 MiB, FAT32
- `KIOSKISO`: 2 GiB, FAT32 placeholder

Leave `KIOSKISO` empty for now.

Make a backup and verify the partition identifiers using:

```bash
diskutil list
```

## 2. Prepare an untouched installer USB

Download a clean official Porteus Kiosk installer ISO. Do not add `007-apple-wifi.xzm` to it.

Write that ISO to the complete USB device using Etcher or:

```bash
diskutil list
diskutil unmountDisk /dev/diskN

sudo dd \
  if="/absolute/path/to/official-porteus-kiosk.iso" \
  of="/dev/rdiskN" \
  bs=4m

sync
```

Here `/dev/rdiskN` is the USB device. Be extremely careful not to select the internal SSD.

## 3. Build the installer’s modified initrd

On an x86-64 Linux live system or VM, install:

```bash
sudo apt update
sudo apt install xorriso squashfs-tools cpio xz-utils \
  grub-efi-amd64-bin grub-common
```

Set the inputs:

```bash
INSTALLER_ISO=/path/to/official-porteus-kiosk.iso
FIRMWARE_ISO=/path/to/porteus_mac.iso
BUILD=/tmp/porteus-boot

mkdir -p "$BUILD"
```

Extract the installer kernel, initrd, and original GRUB configuration:

```bash
xorriso -osirrox on -indev "$INSTALLER_ISO" \
  -extract /boot/vmlinuz "$BUILD/installer-vmlinuz"

xorriso -osirrox on -indev "$INSTALLER_ISO" \
  -extract /boot/initrd.xz "$BUILD/installer-initrd-stock.xz"

xorriso -osirrox on -indev "$INSTALLER_ISO" \
  -extract /boot/isolinux/grub.cfg "$BUILD/installer-original-grub.cfg"

cat "$BUILD/installer-original-grub.cfg"
```

Record everything appearing after `/boot/vmlinuz` on its `linux` line. It will probably resemble:

```text
quiet customer_id=XXXX-XXXX first_run
```

Preserve the ISO’s actual `customer_id` and `first_run` arguments.

### Extract your Apple firmware payload

```bash
xorriso -osirrox on -indev "$FIRMWARE_ISO" \
  -extract /xzm/007-apple-wifi.xzm "$BUILD/007-apple-wifi.xzm"

unsquashfs -d "$BUILD/apple-xzm" \
  "$BUILD/007-apple-wifi.xzm"
```

Your supplied module uses the incorrect `bcrm` spelling:

```bash
FWSRC="$BUILD/apple-xzm/lib/firmware/bcrm"

if [ ! -d "$FWSRC" ]; then
    FWSRC="$BUILD/apple-xzm/lib/firmware/brcm"
fi

test -d "$FWSRC" || {
    echo "Firmware directory not found"
    exit 1
}
```

### Unpack the installer initrd

Use a native Linux filesystem such as `/tmp`, not FAT or a macOS shared folder:

```bash
mkdir -p "$BUILD/initrd-installer"
cd "$BUILD/initrd-installer"

xz -dc ../installer-initrd-stock.xz |
  sudo cpio -idmu --no-absolute-filenames

sudo test -c dev/console ||
  echo "ERROR: dev/console was not preserved"
```

Add the firmware:

```bash
sudo mkdir -p apple-firmware/brcm
sudo cp -a "$FWSRC"/. apple-firmware/brcm/
```

Edit the init script:

```bash
sudo nano init
```

Immediately before:

```sh
# Setup overlayfs:
```

insert:

```sh
# Inject Apple T2 Broadcom firmware into the writable overlay.
if [ -d /apple-firmware/brcm ]; then
    mkdir -p /memory/changes/lib64/firmware/brcm
    cp -a /apple-firmware/brcm/. \
        /memory/changes/lib64/firmware/brcm/
fi
```

Repack it:

```bash
sudo find . -print0 |
  sudo cpio --null -o --format=newc |
  xz --check=crc32 --x86 --lzma2 \
  > ../installer-initrd-apple.xz

xz -t ../installer-initrd-apple.xz
```

## 4. Create an editable GRUB bootloader

For this version, use a tiny embedded configuration that loads the real configuration from `KIOSKBOOT`. This lets you add the installed-system entry later without rebuilding `BOOTX64.EFI`.

Create `$BUILD/bootstrap.cfg`:

```grub
search --no-floppy --label KIOSKBOOT --set=kboot
set prefix=($kboot)/boot/grub
configfile ($kboot)/boot/grub/grub.cfg
```

Build GRUB:

```bash
grub-mkstandalone \
  --format=x86_64-efi \
  --output="$BUILD/BOOTX64.EFI" \
  --locales="" \
  --fonts="" \
  --modules="part_gpt fat search search_label normal configfile linux" \
  "boot/grub/grub.cfg=$BUILD/bootstrap.cfg"
```

Create the real configuration:

```bash
mkdir -p "$BUILD/stage/EFI/BOOT"
mkdir -p "$BUILD/stage/boot/grub"
mkdir -p "$BUILD/stage/boot/installer"

cp "$BUILD/BOOTX64.EFI" \
  "$BUILD/stage/EFI/BOOT/BOOTX64.EFI"

cp "$BUILD/installer-vmlinuz" \
  "$BUILD/stage/boot/installer/vmlinuz"

cp "$BUILD/installer-initrd-apple.xz" \
  "$BUILD/stage/boot/installer/initrd-apple.xz"
```

Create `$BUILD/stage/boot/grub/grub.cfg`:

```grub
set timeout=8
set default=0

menuentry "Porteus Kiosk Wizard from USB" {
    search --no-floppy --label KIOSKBOOT --set=kboot

    linux ($kboot)/boot/installer/vmlinuz \
        quiet \
        customer_id=REPLACE-WITH-THE-ORIGINAL-VALUE \
        first_run \
        intel_iommu=on \
        iommu=pt \
        pm_async=off \
        brcmfmac.feature_disable=0x82000

    initrd ($kboot)/boot/installer/initrd-apple.xz
}

menuentry "Porteus Kiosk Wizard from USB - debug" {
    search --no-floppy --label KIOSKBOOT --set=kboot

    linux ($kboot)/boot/installer/vmlinuz \
        debug \
        loglevel=7 \
        customer_id=REPLACE-WITH-THE-ORIGINAL-VALUE \
        first_run \
        intel_iommu=on \
        iommu=pt \
        pm_async=off \
        brcmfmac.feature_disable=0x82000

    initrd ($kboot)/boot/installer/initrd-apple.xz
}
```

Do not invent the `customer_id`; copy it from `installer-original-grub.cfg`. Also preserve any other installer arguments found there.

## 5. Copy the bootloader to `KIOSKBOOT`

Return to macOS and mount the internal FAT partition:

```bash
diskutil mount /dev/diskXsZ
```

Copy the staged tree:

```bash
sudo mkdir -p /Volumes/KIOSKBOOT/EFI/BOOT
sudo mkdir -p /Volumes/KIOSKBOOT/boot

sudo cp -R "/path/to/stage/EFI" \
  /Volumes/KIOSKBOOT/

sudo cp -R "/path/to/stage/boot" \
  /Volumes/KIOSKBOOT/

sync
```

Optionally bless it:

```bash
sudo bless \
  --mount /Volumes/KIOSKBOOT \
  --file /Volumes/KIOSKBOOT/EFI/BOOT/BOOTX64.EFI \
  --setBoot \
  --shortform
```

## 6. Boot the stock installer USB through the internal GRUB

1. Insert the untouched Porteus installer USB.
2. Start the Mac while holding Option/⌥.
3. Select the internal `EFI Boot` entry corresponding to `KIOSKBOOT`.
4. In GRUB, choose **Porteus Kiosk Wizard from USB**.

The custom initrd will:

- Notice the `first_run` kernel argument.
- Search attached ISO9660 devices for `/docs/first_run`.
- Find the untouched installer USB.
- Mount its stock XZM modules.
- Add the Apple firmware to the in-memory overlay.
- Start the Kiosk Wizard with `brcmfmac` firmware available.

At this point Wi-Fi should be available during the Wizard.

The internal `KIOSKISO` partition is still FAT and therefore will not be mistaken for a Porteus ISO.

## 7. Save the final ISO—don’t run the normal installer

Complete the Wizard, then select **Save ISO**.

Save the final ISO to another FAT-formatted USB drive. Do not select the internal SSD as the installer target, because Porteus’s normal installer treats the selected target as an entire device.

For this custom layout, configure:

```text
automatic_updates=no
```

Automatic updates can otherwise replace the internal ISO without updating the separate kernel/initrd on `KIOSKBOOT`.

## 8. Prepare the final system files

Back in Linux, extract the final ISO’s matching kernel and initrd:

```bash
FINAL_ISO=/path/to/Porteus-Kiosk-final.iso

xorriso -osirrox on -indev "$FINAL_ISO" \
  -extract /boot/vmlinuz "$BUILD/final-vmlinuz"

xorriso -osirrox on -indev "$FINAL_ISO" \
  -extract /boot/initrd.xz "$BUILD/final-initrd-stock.xz"

xorriso -osirrox on -indev "$FINAL_ISO" \
  -extract /boot/isolinux/grub.cfg "$BUILD/final-original-grub.cfg"
```

Compare them with the installer files:

```bash
sha256sum \
  "$BUILD/installer-vmlinuz" \
  "$BUILD/final-vmlinuz"

sha256sum \
  "$BUILD/installer-initrd-stock.xz" \
  "$BUILD/final-initrd-stock.xz"
```

If both pairs match, the existing modified initrd can be reused.

If the final initrd differs, repeat the injection procedure using `final-initrd-stock.xz`, producing:

```text
final-initrd-apple.xz
```

That is the safest approach.

## 9. Add the installed-system GRUB entry

Place the final files on `KIOSKBOOT`:

```text
/boot/kiosk/vmlinuz
/boot/kiosk/initrd-apple.xz
```

Then append this to `/boot/grub/grub.cfg`:

```grub
menuentry "Porteus Kiosk - internal SSD" {
    search --no-floppy --label KIOSKBOOT --set=kboot

    linux ($kboot)/boot/kiosk/vmlinuz \
        quiet \
        intel_iommu=on \
        iommu=pt \
        pm_async=off \
        brcmfmac.feature_disable=0x82000

    initrd ($kboot)/boot/kiosk/initrd-apple.xz
}

menuentry "Porteus Kiosk - internal SSD debug" {
    search --no-floppy --label KIOSKBOOT --set=kboot

    linux ($kboot)/boot/kiosk/vmlinuz \
        debug \
        loglevel=7 \
        intel_iommu=on \
        iommu=pt \
        pm_async=off \
        brcmfmac.feature_disable=0x82000

    initrd ($kboot)/boot/kiosk/initrd-apple.xz
}
```

If `final-original-grub.cfg` contains additional kernel arguments other than `first_run`, copy those into these entries. Do not put `first_run` in the installed-system entry.

## 10. Write the final ISO to `KIOSKISO`

From macOS, identify the exact partition again:

```bash
diskutil list
diskutil info /dev/diskXsY
```

Then write only to the `KIOSKISO` partition:

```bash
diskutil unmount /dev/diskXsY

sudo dd \
  if="/absolute/path/to/Porteus-Kiosk-final.iso" \
  of="/dev/rdiskXsY" \
  bs=4m

sync
```

Never omit the partition suffix.

Remove both USB drives and boot the internal entry.

This gives the desired progression: the same internal bootloader provides Apple Wi-Fi to the USB-based Wizard first, then boots the finished Kiosk system directly from the internal SSD.
