diff options
| -rwxr-xr-x | hacks/ubuntu/install-wl.sh | 57 | ||||
| -rwxr-xr-x | hacks/ubuntu/mac-drivers.sh | 101 | ||||
| -rw-r--r-- | roles/bootstrap/tasks/install-ubuntu-mac.yml | 74 | ||||
| -rw-r--r-- | roles/bootstrap/tasks/install-ubuntu.yml | 6 | ||||
| -rw-r--r-- | roles/bootstrap/tasks/main.yml | 3 | ||||
| -rw-r--r-- | roles/bootstrap/vars/ubuntu.yml | 2 |
6 files changed, 238 insertions, 5 deletions
diff --git a/hacks/ubuntu/install-wl.sh b/hacks/ubuntu/install-wl.sh new file mode 100755 index 0000000..04e1768 --- /dev/null +++ b/hacks/ubuntu/install-wl.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Builds and loads the Broadcom BCM4360 wl driver on a Ubuntu live ISO. +# Must be run with access to the debs downloaded by mac-drivers.sh. +# gcc/make/binutils are extracted from the downloaded debs — not assumed pre-installed. +# +# Usage: bash install-wl.sh <path-to-debs-dir> + +usage() { + echo "Usage: $0 <debs-dir>" + echo " debs-dir: directory containing broadcom-sta-dkms and linux-headers debs" + exit 1 +} + +[[ $# -ne 1 ]] && usage + +DEBS_DIR="$1" +KERNEL_VERSION="$(uname -r)" + +if [[ ! -d "$DEBS_DIR" ]]; then + echo "ERROR: $DEBS_DIR is not a directory" >&2 + exit 1 +fi + +echo "Extracting packages to / (overlayfs — changes are in RAM, lost on reboot)..." +for deb in "$DEBS_DIR"/*.deb; do + echo " $(basename "$deb")" + sudo dpkg -x "$deb" / +done + +SRC_DIR=$(find /usr/src -maxdepth 1 -name "broadcom-sta-*" -type d 2>/dev/null | head -1) +if [[ -z "$SRC_DIR" ]]; then + echo "ERROR: broadcom-sta source not found in /usr/src/ after extraction" >&2 + exit 1 +fi + +if [[ ! -d "/lib/modules/$KERNEL_VERSION/build" ]]; then + echo "ERROR: /lib/modules/$KERNEL_VERSION/build not found" >&2 + echo " Expected linux-headers-$KERNEL_VERSION to be extracted" >&2 + exit 1 +fi + +echo "Building wl.ko for kernel $KERNEL_VERSION from $SRC_DIR..." +sudo KBUILD_NOPEDANTIC=1 make \ + -C "/lib/modules/$KERNEL_VERSION/build" \ + M="$SRC_DIR" \ + -j1 + +echo "Unloading conflicting modules..." +sudo rmmod wl 2>/dev/null || true +sudo rmmod b43 ssb bcma brcmfmac brcmutil 2>/dev/null || true + +echo "Loading wl.ko..." +sudo insmod "$SRC_DIR/wl.ko" +sudo rfkill unblock all +echo "Done." diff --git a/hacks/ubuntu/mac-drivers.sh b/hacks/ubuntu/mac-drivers.sh new file mode 100755 index 0000000..248e9c0 --- /dev/null +++ b/hacks/ubuntu/mac-drivers.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + echo "Usage: $0 <kernel-version>" + echo " kernel-version: output of 'uname -r' on target machine" + echo " Example: $0 6.11.0-17-generic" + exit 1 +} + +[[ $# -ne 1 ]] && usage + +KERNEL_VERSION="$1" +OUTPUT_DIR="/tmp/bcmwl-drivers" +BASE_URL="http://archive.ubuntu.com/ubuntu" +DISTRO="noble" +INDEX_DIR=$(mktemp -d) + +cleanup() { rm -rf "$INDEX_DIR"; } + +fetch_index() { + local pocket="$1" component="$2" + local dest="${INDEX_DIR}/${pocket}-${component}.txt" + echo "Fetching ${pocket}/${component} index..." >&2 + curl -fsSL "${BASE_URL}/dists/${pocket}/${component}/binary-amd64/Packages.gz" \ + | gzip -d > "$dest" + echo "$dest" +} + +pkg_field() { + local index="$1" pkg_name="$2" field="$3" + awk '/^Package: '"$pkg_name"'$/{found=1} found && /^'"$field"':/{print; found=0; exit}' "$index" +} + +pkg_filename() { + pkg_field "$1" "$2" "Filename" | awk '{print $2}' +} + +download_pkg() { + local pkg_name="$1" + local filename="" + for index in "${INDEXES[@]}"; do + filename=$(pkg_filename "$index" "$pkg_name") + [[ -n "$filename" ]] && break + done + if [[ -z "$filename" ]]; then + echo "WARNING: $pkg_name not found in any index, skipping" >&2 + return 0 + fi + local deb + deb=$(basename "$filename") + if [[ -f "${OUTPUT_DIR}/${deb}" ]]; then + echo " (cached) $deb" + return 0 + fi + echo "Downloading $deb..." + curl -fL -o "${OUTPUT_DIR}/${deb}" "${BASE_URL}/${filename}" +} + +# Create out directory and configure trap signal +mkdir -p "$OUTPUT_DIR" +trap cleanup EXIT + +# Fetch indexes +main_index=$(fetch_index "$DISTRO" "main") +main_updates=$(fetch_index "${DISTRO}-updates" "main") +restricted_updates=$(fetch_index "${DISTRO}-updates" "restricted") +INDEXES=("$main_updates" "$main_index" "$restricted_updates") + +# Kernel headers +download_pkg "linux-headers-${KERNEL_VERSION}" + +# Auto-discover base headers from Depends: field +BASE_HEADERS_PKG=$(pkg_field "$main_updates" "linux-headers-${KERNEL_VERSION}" "Depends" \ + | grep -o 'linux-hwe-[^ ,)]*' | head -1) +if [[ -n "$BASE_HEADERS_PKG" ]]; then + echo "Base headers: $BASE_HEADERS_PKG" + download_pkg "$BASE_HEADERS_PKG" +fi + +# Broadcom source +download_pkg "broadcom-sta-dkms" + +# Build tools (not pre-installed on Ubuntu live ISO) +echo "Downloading build tools..." +for pkg in \ + make \ + gcc-13-base \ + cpp-13-x86-64-linux-gnu cpp-13 cpp-x86-64-linux-gnu cpp \ + gcc-13-x86-64-linux-gnu gcc-13 gcc-x86-64-linux-gnu gcc \ + binutils-common libsframe1 libbinutils libctf-nobfd0 libctf0 \ + libjansson4 libgprofng0 binutils-x86-64-linux-gnu binutils \ + libcc1-0 libisl23 libmpfr6 libmpc3 libgcc-13-dev lto-disabled-list; do + download_pkg "$pkg" +done + +# Copy install script alongside the debs +cp "$(dirname "$0")/install-wl.sh" "$OUTPUT_DIR/" +chmod +x "$OUTPUT_DIR/install-wl.sh" +echo "" +echo "Downloaded to $OUTPUT_DIR:" diff --git a/roles/bootstrap/tasks/install-ubuntu-mac.yml b/roles/bootstrap/tasks/install-ubuntu-mac.yml new file mode 100644 index 0000000..005c403 --- /dev/null +++ b/roles/bootstrap/tasks/install-ubuntu-mac.yml @@ -0,0 +1,74 @@ +--- +# Apple EFI 1.x does not expose ext4 volumes via SimpleFileSystem, so the +# kernel must live on the FAT32 EFI partition where rEFInd already scans \boot\. +- name: "Ensure boot directory exists on EFI partition" + ansible.builtin.file: + path: "{{ mnt_boot_path }}/boot" + state: directory + mode: "0755" + +- name: "Copy kernel to EFI partition" + ansible.builtin.copy: + src: "{{ mnt_root_path }}/boot/{{ item }}" + dest: "{{ mnt_boot_path }}/boot/{{ item }}" + remote_src: true + follow: true + mode: "0644" + loop: + - "vmlinuz" + - "initrd.img" + +- name: "Configure rEFInd boot options on EFI partition" + ansible.builtin.template: + src: "refind_linux.conf.j2" + dest: "{{ mnt_boot_path }}/boot/refind_linux.conf" + mode: "0644" + +- name: "Ensure kernel post-install hook directory exists" + ansible.builtin.file: + path: "{{ mnt_root_path }}/etc/kernel/postinst.d" + state: directory + mode: "0755" + +- name: "Install kernel sync script for EFI partition" + ansible.builtin.copy: + dest: "{{ mnt_root_path }}/etc/kernel/postinst.d/refind-sync-kernel" + mode: "0755" + content: | + #!/bin/sh + cp /boot/vmlinuz /boot/efi/boot/ + cp /boot/initrd.img /boot/efi/boot/ + +- name: "Install bcmwl-kernel-source in chroot" + ansible.builtin.command: + cmd: "arch-chroot {{ mnt_root_path }} apt-get install -y bcmwl-kernel-source" + environment: + MAKEFLAGS: "" + changed_when: true + failed_when: false + +- name: "Configure unconfigured packages in chroot" + ansible.builtin.command: + cmd: "arch-chroot {{ mnt_root_path }} dpkg --configure -a" + environment: + MAKEFLAGS: "" + changed_when: true + failed_when: false + +- name: "Blacklist modules conflicting with broadcom-wl" + ansible.builtin.copy: + dest: "{{ mnt_root_path }}/etc/modprobe.d/broadcom-wl.conf" + mode: "0644" + content: | + blacklist brcmfmac + blacklist brcmutil + blacklist b43 + blacklist ssb + blacklist bcma + +- name: "Load wl module at boot" + ansible.builtin.lineinfile: + path: "{{ mnt_root_path }}/etc/modules" + line: "wl" + create: true + mode: "0644" diff --git a/roles/bootstrap/tasks/install-ubuntu.yml b/roles/bootstrap/tasks/install-ubuntu.yml index a121fe8..3c18b0e 100644 --- a/roles/bootstrap/tasks/install-ubuntu.yml +++ b/roles/bootstrap/tasks/install-ubuntu.yml @@ -55,12 +55,10 @@ changed_when: true - name: "Configure rEFInd boot options" - ansible.builtin.copy: + ansible.builtin.template: + src: "refind_linux.conf.j2" dest: "{{ mnt_root_path }}/boot/refind_linux.conf" mode: "0644" - content: | - "Boot with defaults" "root=PARTLABEL={{ partition_root.name }} rw" - "Boot to terminal" "root=PARTLABEL={{ partition_root.name }} rw systemd.unit=multi-user.target" - name: "Configure rEFInd settings" ansible.builtin.copy: diff --git a/roles/bootstrap/tasks/main.yml b/roles/bootstrap/tasks/main.yml index cb92f99..50e2ce2 100644 --- a/roles/bootstrap/tasks/main.yml +++ b/roles/bootstrap/tasks/main.yml @@ -20,6 +20,9 @@ - name: "Install ubuntu" ansible.builtin.include_tasks: "install-ubuntu.yml" when: ansible_facts['distribution'] == "Ubuntu" + - name: "Install ubuntu on Mac" + ansible.builtin.include_tasks: "install-ubuntu-mac.yml" + when: ansible_facts['distribution'] == "Ubuntu" and bootstrap_mac - name: "Install raspberry" ansible.builtin.include_tasks: "install-raspberry.yml" diff --git a/roles/bootstrap/vars/ubuntu.yml b/roles/bootstrap/vars/ubuntu.yml index 3c9f322..4708aff 100644 --- a/roles/bootstrap/vars/ubuntu.yml +++ b/roles/bootstrap/vars/ubuntu.yml @@ -3,7 +3,7 @@ bootstrap_distro: name: "noble" # => Ubuntu 24.04 mirror_url: "http://archive.ubuntu.com/ubuntu/" packages: - - "linux-generic-hwe-24.04" + - "linux-generic" bootstrap_opts: "" |
