diff --git a/.gitignore b/.gitignore index 951c0fc6..b41afbf1 100644 --- a/.gitignore +++ b/.gitignore @@ -16,12 +16,10 @@ config/*.old *~ crossgcc clean -*.map *.sec *.dep *.ffs *.vol *.lz *.fv -*.bin *.bad diff --git a/blobs/librem_jail/README b/blobs/librem_jail/README index 25e13c2c..7daf685c 100644 --- a/blobs/librem_jail/README +++ b/blobs/librem_jail/README @@ -1 +1,17 @@ -This directory contains firmware/microcode needed for the Intel AX200 WiFi module, its Bluetooth counterparts, and the Bluetooth component (ar3k) of Ath9k WiFi modules. It is synchronized via the main system firmware (Pureboot) at each boot, and should not be modified. +# Librem Blob Jail + +This directory contains firmware/microcode needed for peripherals in some Librem boards, for OSes that do not provide device firmware. + +When the blob jail feature is enabled, PureBoot provides device firmware to the OS by adding it to the initrd, then copying it to /run/firmware (see initrd/bin/inject_firmware.sh). + +## Librem Mini v2 + +Librem Mini v2 ships with an Atheros Wi-Fi/Bluetooth card, which does not require firmware for Wi-Fi (but it does for Bluetooth). However, some whitelabel variants ship with Intel AX200, which requires firmware for both Wi-Fi and Bluetooth. + +Device firmware is provided in a preconfigured variant build for librem_mini_v2, the basic_usb_autoboot_blob_jail build. + +## Librem 11 + +Librem 11 includes an Intel AX201 Wi-Fi/Bluetooth card, which requires firmware. All builds for librem_11 include the device firmware. + +Display microcontroller firmware is also provided to enable power management. diff --git a/blobs/librem_jail/librem_11/i915/icl_dmc_ver1_09.bin b/blobs/librem_jail/librem_11/i915/icl_dmc_ver1_09.bin new file mode 100644 index 00000000..06faf413 Binary files /dev/null and b/blobs/librem_jail/librem_11/i915/icl_dmc_ver1_09.bin differ diff --git a/blobs/librem_jail/intel/ibt-20-1-3.ddc b/blobs/librem_jail/librem_11/intel/ibt-19-0-0.ddc similarity index 100% rename from blobs/librem_jail/intel/ibt-20-1-3.ddc rename to blobs/librem_jail/librem_11/intel/ibt-19-0-0.ddc diff --git a/blobs/librem_jail/librem_11/intel/ibt-19-0-0.sfi b/blobs/librem_jail/librem_11/intel/ibt-19-0-0.sfi new file mode 100644 index 00000000..e8761f3f Binary files /dev/null and b/blobs/librem_jail/librem_11/intel/ibt-19-0-0.sfi differ diff --git a/blobs/librem_jail/librem_11/iwlwifi-QuZ-a0-jf-b0-72.ucode b/blobs/librem_jail/librem_11/iwlwifi-QuZ-a0-jf-b0-72.ucode new file mode 100644 index 00000000..e56c7af0 Binary files /dev/null and b/blobs/librem_jail/librem_11/iwlwifi-QuZ-a0-jf-b0-72.ucode differ diff --git a/blobs/librem_jail/ar3k/AthrBT_0x11020100.dfu b/blobs/librem_jail/librem_mini_v2/ar3k/AthrBT_0x11020100.dfu similarity index 100% rename from blobs/librem_jail/ar3k/AthrBT_0x11020100.dfu rename to blobs/librem_jail/librem_mini_v2/ar3k/AthrBT_0x11020100.dfu diff --git a/blobs/librem_jail/ar3k/ramps_0x11020100_40.dfu b/blobs/librem_jail/librem_mini_v2/ar3k/ramps_0x11020100_40.dfu similarity index 100% rename from blobs/librem_jail/ar3k/ramps_0x11020100_40.dfu rename to blobs/librem_jail/librem_mini_v2/ar3k/ramps_0x11020100_40.dfu diff --git a/blobs/librem_jail/librem_mini_v2/intel/ibt-20-1-3.ddc b/blobs/librem_jail/librem_mini_v2/intel/ibt-20-1-3.ddc new file mode 100644 index 00000000..6e067796 Binary files /dev/null and b/blobs/librem_jail/librem_mini_v2/intel/ibt-20-1-3.ddc differ diff --git a/blobs/librem_jail/intel/ibt-20-1-3.sfi b/blobs/librem_jail/librem_mini_v2/intel/ibt-20-1-3.sfi similarity index 100% rename from blobs/librem_jail/intel/ibt-20-1-3.sfi rename to blobs/librem_jail/librem_mini_v2/intel/ibt-20-1-3.sfi diff --git a/blobs/librem_jail/iwlwifi-cc-a0-59.ucode b/blobs/librem_jail/librem_mini_v2/iwlwifi-cc-a0-59.ucode similarity index 100% rename from blobs/librem_jail/iwlwifi-cc-a0-59.ucode rename to blobs/librem_jail/librem_mini_v2/iwlwifi-cc-a0-59.ucode diff --git a/boards/librem_11/initrd/bin/board-init.sh b/boards/librem_11/initrd/bin/board-init.sh new file mode 100755 index 00000000..0e999e09 --- /dev/null +++ b/boards/librem_11/initrd/bin/board-init.sh @@ -0,0 +1,3 @@ +#! /bin/bash +set -e -o pipefail +loadkeys /etc/librem_11.map diff --git a/boards/librem_11/initrd/etc/librem_11.map b/boards/librem_11/initrd/etc/librem_11.map new file mode 100644 index 00000000..78fbdc49 --- /dev/null +++ b/boards/librem_11/initrd/etc/librem_11.map @@ -0,0 +1,5 @@ +keymaps 0-2,4-5,8,12 +# Use volume and power keys on tablet to navigate menus +keycode 114 = Up +keycode 115 = Down +keycode 116 = Return diff --git a/boards/librem_11/librem_11.config b/boards/librem_11/librem_11.config new file mode 100644 index 00000000..d4a4a79f --- /dev/null +++ b/boards/librem_11/librem_11.config @@ -0,0 +1,51 @@ +# Configuration for librem_11 +CONFIG_LINUX_CONFIG=config/linux-librem_common-6.1.8.config +CONFIG_COREBOOT_CONFIG=config/coreboot-librem_11.config + +export CONFIG_COREBOOT=y +export CONFIG_COREBOOT_VERSION=purism +export CONFIG_LINUX_VERSION=6.1.8 + +CONFIG_CRYPTSETUP2=y +CONFIG_FLASHROM=y +CONFIG_FLASHTOOLS=y +CONFIG_GPG2=y +CONFIG_KEXEC=y +CONFIG_UTIL_LINUX=y +CONFIG_KBD=y +CONFIG_KBD_LOADKEYS=y +CONFIG_LVM2=y +CONFIG_MBEDTLS=y +CONFIG_PCIUTILS=y +CONFIG_POPT=y +CONFIG_QRENCODE=y +CONFIG_TPMTOTP=y + +CONFIG_CAIRO=y +CONFIG_FBWHIPTAIL=y +CONFIG_HOTPKEY=y + +CONFIG_LINUX_USB=y + +export CONFIG_TPM=n +export CONFIG_TPM_NO_LUKS_DISK_UNLOCK=y +export CONFIG_TOTP_SKIP_QRCODE=y +export CONFIG_OEMRESET_OFFER_DEFAULTS=y + +export CONFIG_BOOTSCRIPT=/bin/gui-init +export CONFIG_BOOT_REQ_HASH=n +export CONFIG_BOOT_REQ_ROLLBACK=n +export CONFIG_BOOT_KERNEL_ADD="" +export CONFIG_BOOT_KERNEL_REMOVE="" +export CONFIG_BOOT_DEV="/dev/nvme0n1p1" +export CONFIG_BOARD_NAME="Librem 11" +export CONFIG_FLASHROM_OPTIONS="-p internal" +export CONFIG_USB_KEYBOARD=y +export CONFIG_AUTO_BOOT_TIMEOUT=5 +export CONFIG_ROOT_DEV="/dev/nvme0n1p2" +export CONFIG_ROOT_DIRLIST="bin boot lib sbin usr" +export CONFIG_ROOT_CHECK_AT_BOOT="n" + +# Librem 11 builds include firmware for integrated AX201 Wi-Fi, Bluetooth, and +# graphics microcontroller. +export CONFIG_SUPPORT_BLOB_JAIL=y diff --git a/config/coreboot-librem_11.config b/config/coreboot-librem_11.config new file mode 100644 index 00000000..ac2f54a2 --- /dev/null +++ b/config/coreboot-librem_11.config @@ -0,0 +1,16 @@ +CONFIG_VENDOR_PURISM=y +CONFIG_IFD_BIN_PATH="3rdparty/purism-blobs/mainboard/purism/librem_jsl/librem_11/flashdescriptor.bin" +CONFIG_ME_BIN_PATH="3rdparty/purism-blobs/mainboard/purism/librem_jsl/librem_11/me.bin" +CONFIG_HAVE_IFD_BIN=y +CONFIG_BOARD_PURISM_LIBREM_11=y +CONFIG_LINUX_COMMAND_LINE="quiet loglevel=2" +CONFIG_FSP_M_FILE="3rdparty/purism-blobs/mainboard/purism/librem_jsl/librem_11/fspm.bin" +CONFIG_FSP_S_FILE="3rdparty/purism-blobs/mainboard/purism/librem_jsl/librem_11/fsps.bin" +CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_BINS=y +CONFIG_CPU_UCODE_BINARIES="3rdparty/purism-blobs/mainboard/purism/librem_jsl/cpu_microcode_blob.bin" +CONFIG_HAVE_ME_BIN=y +CONFIG_ADD_FSP_BINARIES=y +CONFIG_PAYLOAD_LINUX=y +CONFIG_PAYLOAD_FILE="@BOARD_BUILD_DIR@/bzImage" +CONFIG_LINUX_INITRD="@BOARD_BUILD_DIR@/initrd.cpio.xz" +CONFIG_CBFS_SIZE=0xC00000 diff --git a/initrd/.ash_history b/initrd/.ash_history index 99690053..69c0f491 100644 --- a/initrd/.ash_history +++ b/initrd/.ash_history @@ -15,3 +15,6 @@ seal-totp #Verify Intel ME state: cbmem --console | grep '^ME' cbmem --console | less +# Reboot/power off (important for devices with no keyboard to escape recovery shell) +reboot # Press Enter with this command to reboot +poweroff # Press Enter with this command to power off diff --git a/initrd/bin/inject_firmware.sh b/initrd/bin/inject_firmware.sh index 452e931f..251d48eb 100755 --- a/initrd/bin/inject_firmware.sh +++ b/initrd/bin/inject_firmware.sh @@ -55,26 +55,36 @@ if ! grep -E -q '^exec run-init .*\$\{rootmnt\}' "$INITRD_ROOT/init"; then exit 0 fi -# The initrd's /init has to copy the firmware to /run/firmware, so it will be -# present when the real root is moved to /. -# * Wi-Fi/BT firmware loading doesn't happen during the initrd - these modules -# aren't in the initrd anyway, typically. -# * /run is a tmpfs mount, so this works even if the root filesystem is -# read-only, and it doesn't persist anything. +# In general, firmware files must be available _both_ during the initrd _and_ +# once root is moved to /. Firmware loading may happen in either phase (e.g. +# i915 GUC firmware is usually loaded in the initrd because i915 is used there, +# but Wi-Fi/BT modules typically are not in the initrd, they're loaded later). # -# kexec-boot will add a kernel parameter for the kernel to look for firmware in -# /run/firmware. +# We want to place the firmware after boot in /run, since this is a tmpfs mount +# - it works even if the root filesystem is read-only and does not persist +# anything. But we cannot place it there for the initrd, since the initrd also +# mounts a tmpfs on /run. We can only specify one custom firmware path, but we +# can change it at runtime. +# +# So during the initrd, the firmware is in /firmware, and we provide that path +# on the kernel command line. Just before invoking the real init (after root is +# mounted), we copy it to /run/firmware and also change the firmware path. # # Debian's init script ends with an "exec run-init ..." (followed by a few lines # to print a message in case it fails). At that point, root is mounted, and -# run-init will move it to / and then exec init. We can copy the firmware just -# before that, so we don't have to know anything about how root was mounted. +# run-init will move it to / and then exec init. We can insert the firmware +# actions just before that, so we don't have to know anything about how root was +# mounted. # # The root path is in ${rootmnt}, which should appear in the run-init command. # If it doesn't, then we don't understand the init script. AWK_INSERT_CP=' BEGIN{inserted=0} -/^exec run-init .*\$\{rootmnt\}/ && inserted==0 {print "cp -r /firmware ${rootmnt}/run/firmware"; inserted=1} +/^exec run-init .*\$\{rootmnt\}/ && inserted==0 { + print "cp -r /firmware ${rootmnt}/run/firmware" + print "echo -n /run/firmware >${rootmnt}/sys/module/firmware_class/parameters/path" + inserted=1 +} {print $0}' awk -e "$AWK_INSERT_CP" "$INITRD_ROOT/init" >"$INITRD_ROOT/init_fw" diff --git a/initrd/bin/kexec-boot b/initrd/bin/kexec-boot index d112c791..3609c2d8 100755 --- a/initrd/bin/kexec-boot +++ b/initrd/bin/kexec-boot @@ -35,7 +35,7 @@ cmdadd="$CONFIG_BOOT_KERNEL_ADD $cmdadd" cmdremove="$CONFIG_BOOT_KERNEL_REMOVE $cmdremove" if [ "$(load_config_value CONFIG_USE_BLOB_JAIL)" = "y" ]; then - cmdadd="$cmdadd firmware_class.path=/run/firmware/" + cmdadd="$cmdadd firmware_class.path=/firmware/" fi fix_file_path() { diff --git a/initrd/init b/initrd/init index 2acd93fe..202acd7a 100755 --- a/initrd/init +++ b/initrd/init @@ -98,7 +98,7 @@ export GPG_TTY=/dev/console [ -x /bin/bash ] && /bin/key-init # Override CONFIG_USE_BLOB_JAIL if needed and persist via user config -if lspci -n | grep -q "8086:2723"; then +if lspci -n | grep -E -q "8086:(2723|4df0)"; then if ! cat /etc/config.user 2>/dev/null | grep -q "USE_BLOB_JAIL"; then echo "CONFIG_USE_BLOB_JAIL=y" >> /etc/config.user fi diff --git a/modules/coreboot b/modules/coreboot index 3f4892ca..639c38e2 100644 --- a/modules/coreboot +++ b/modules/coreboot @@ -82,7 +82,7 @@ $(eval $(call coreboot_module,talos_2,)) # Similarly, purism is based on 4.21, but nothing builds against 4.21 itself # or any other fork - no benefit to sharing the toolchain yet. coreboot-purism_repo := https://source.puri.sm/firmware/coreboot.git -coreboot-purism_commit_hash := 24e2f7e46c933b0764b245f7f0b4c54554881950 +coreboot-purism_commit_hash := 0d57cff58fba2f3a4d3a714a4eae65753e58c6ff $(eval $(call coreboot_module,purism,)) #Nitrokey nv41/ns50 are based on Dasharo coreboot port, diff --git a/modules/fbwhiptail b/modules/fbwhiptail index 431013f4..4516e8f7 100644 --- a/modules/fbwhiptail +++ b/modules/fbwhiptail @@ -2,11 +2,11 @@ modules-$(CONFIG_FBWHIPTAIL) += fbwhiptail fbwhiptail_depends := cairo $(musl_dep) -fbwhiptail_version := 1b3ee5ca1e297a977d9ebab49df942c51d619ecd +fbwhiptail_version := 1.3 fbwhiptail_dir := fbwhiptail-$(fbwhiptail_version) fbwhiptail_tar := fbwhiptail-$(fbwhiptail_version).tar.gz fbwhiptail_url := https://source.puri.sm/firmware/fbwhiptail/-/archive/$(fbwhiptail_version)/fbwhiptail-$(fbwhiptail_version).tar.gz -fbwhiptail_hash := f7691a82dac3aca6592ca85cbd7ec116bd7c2eae5b834f95c76967532c9aec79 +fbwhiptail_hash := 2eb8fadfd3e2d574de52327bbc80ed6313739a3db9f4d87840c534352c66df5a fbwhiptail_target := \ $(MAKE_JOBS) \ diff --git a/modules/kbd b/modules/kbd index 6067a996..f6d3f405 100644 --- a/modules/kbd +++ b/modules/kbd @@ -1,3 +1,11 @@ +# kbd: Linux keyboard tools +# +# Provides: +# - setfont - set the Linux console font +# - loadkeys - load a key map for the Linux console (CONFIG_KBD_LOADKEYS) +# +# To also provide showkey and dumpkeys (normally only needed for development), +# set CONFIG_KBD_DEVTOOLS=y. modules-$(CONFIG_KBD) += kbd kbd_version := 2.6.1 @@ -21,4 +29,12 @@ kbd_target := \ kbd_output := \ src/setfont +ifeq "$(CONFIG_KBD_LOADKEYS)" "y" + kbd_output += src/loadkeys +endif + +ifeq "$(CONFIG_KBD_EXTRATOOLS)" "y" + kbd_output += src/showkey src/dumpkeys +endif + kbd_depends := $(musl_dep)