Add config for Librem 5
This commit is contained in:
parent
50dc4ef928
commit
9070d2340c
|
@ -232,6 +232,7 @@ See code for all available configurations.
|
|||
| [PINE64 STAR64](pine64/star64/) | `<nixos-hardware/pine64/star64>` |
|
||||
| [Purism Librem 13v3](purism/librem/13v3) | `<nixos-hardware/purism/librem/13v3>` |
|
||||
| [Purism Librem 15v3](purism/librem/13v3) | `<nixos-hardware/purism/librem/15v3>` |
|
||||
| [Purism Librem 5r4](purism/librem/5r4) | `<nixos-hardware/purism/librem/5r4>` |
|
||||
| [Raspberry Pi 2](raspberry-pi/2) | `<nixos-hardware/raspberry-pi/2>` |
|
||||
| [Raspberry Pi 4](raspberry-pi/4) | `<nixos-hardware/raspberry-pi/4>` |
|
||||
| [Samsung Series 9 NP900X3C](samsung/np900x3c) | `<nixos-hardware/samsung/np900x3c>` |
|
||||
|
|
|
@ -171,6 +171,7 @@
|
|||
pine64-star64 = import ./pine64/star64;
|
||||
purism-librem-13v3 = import ./purism/librem/13v3;
|
||||
purism-librem-15v3 = import ./purism/librem/15v3;
|
||||
purism-librem-5r4 = import ./purism/librem/5r4;
|
||||
raspberry-pi-2 = import ./raspberry-pi/2;
|
||||
raspberry-pi-4 = import ./raspberry-pi/4;
|
||||
kobol-helios4 = import ./kobol/helios4;
|
||||
|
|
133
purism/librem/5r4/README.md
Normal file
133
purism/librem/5r4/README.md
Normal file
|
@ -0,0 +1,133 @@
|
|||
# Purism Librem 5 revision 4
|
||||
|
||||
Purism's [Librem 5] is a privacy-oriented Linux-friendly smartphone.
|
||||
|
||||
[Librem 5]: https://puri.sm/products/librem-5/
|
||||
|
||||
## Installation procedure
|
||||
|
||||
> *Note*
|
||||
>
|
||||
> TODO: build a uuu-compatible installer.
|
||||
|
||||
Until there's a native installer, the easiest way to install NixOS on Librem 5 seems to be using [Jumpdrive].
|
||||
|
||||
[Jumpdrive]: https://github.com/dreemurrs-embedded/Jumpdrive
|
||||
|
||||
### Jumpdrive
|
||||
|
||||
Jumpdrive is a tiny Linux distribution which presents device's internal storage as USB mass storage when you connect it to a PC.
|
||||
It also provides a shell session over telnet.
|
||||
|
||||
Follow the instructions in the repo to boot into Jumpdrive.
|
||||
Note that `uuu` is part of `nxpmicro-mfgtools` package in nixpkgs.
|
||||
|
||||
Now, plug the device into your PC. A new block device representing Librem 5's internal MMC should appear in `/dev`.
|
||||
Note down this device path.
|
||||
|
||||
### U-Boot
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> While upstream u-boot does support Librem 5, it can only boot using `boot.scr`, for which NixOS has no native support.
|
||||
>
|
||||
> There's work on extlinux support in Librem 5's U-Boot here: https://source.puri.sm/a-wai/uboot-imx/-/tree/allow-compressed-kernel
|
||||
>
|
||||
> This U-Boot version is packaged in the [`u-boot`] directory.
|
||||
|
||||
|
||||
[`u-boot`]: ./u-boot
|
||||
|
||||
Provided you have a way to build Nix derivations for `aarch64-linux` (like a remote builder, [binfmt emulation], or you're building it on the phone itself), just run `nix-build u-boot/build.nix`.
|
||||
|
||||
[binfmt emulation]: https://search.nixos.org/options?channel=22.11&show=boot.binfmt.emulatedSystems&from=0&size=50&sort=relevance&type=packages&query=binfmt
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> Even though I've tested this myself, I can't guarantee that this will not render your device unbootable.
|
||||
> Proceed with caution.
|
||||
>
|
||||
> If it does not work, your best bet is to follow the advice here, which will flash U-Boot build by upstream: https://forums.puri.sm/t/can-someone-with-serial-console-access-try-nixos-kernel-on-librem-5/19121/27
|
||||
|
||||
To flash the device, run
|
||||
|
||||
```console
|
||||
$ sudo u-boot-install-librem5 <path to librem 5's MMC>
|
||||
```
|
||||
|
||||
At this point, if you have an OS installed on your Librem 5, it's best to reboot into it to check that the U-Boot was flashed correctly.
|
||||
If that's the case, reboot back into Jumpdrive.
|
||||
|
||||
### Partitioning
|
||||
|
||||
Now, from your host system, partition the MMC.
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> Doing this wipes all data off the phone
|
||||
|
||||
I went with 1 bootable `ext2` partition for `/boot`, and one `ext4` partition for `/`.
|
||||
It ended up looking like this (your device names will be different):
|
||||
|
||||
```console
|
||||
$ sudo fdisk -l /dev/mmcblk0
|
||||
Disk /dev/mmcblk0: 29.12 GiB, 31268536320 bytes, 61071360 sectors
|
||||
Units: sectors of 1 * 512 = 512 bytes
|
||||
Sector size (logical/physical): 512 bytes / 512 bytes
|
||||
I/O size (minimum/optimal): 512 bytes / 512 bytes
|
||||
Disklabel type: dos
|
||||
Disk identifier: 0xcec26c32
|
||||
|
||||
Device Boot Start End Sectors Size Id Type
|
||||
/dev/mmcblk0p1 * 4096 499711 495616 242M 83 Linux
|
||||
/dev/mmcblk0p2 499712 61071359 60571648 28.9G 83 Linux
|
||||
```
|
||||
|
||||
Note 2MiB of free space before the first partition.
|
||||
This is where U-Boot lives.
|
||||
|
||||
Mount the partitions on your host system, e.g. to `/mnt` and `/mnt/boot`.
|
||||
Remember that `/mnt` is the second partition, and `/mnt/boot` is the first.
|
||||
|
||||
### Installation
|
||||
|
||||
Now, write your NixOS config.
|
||||
Use `/dev/mmcblk0p1` as `fileSystems."/boot"` and `/dev/mmcblk0p2` as `fileSystems."/"`.
|
||||
Don't forget to import the [module from this directory](./default.nix).
|
||||
If you plan to use the device as a smartphone, you have a choice of two "desktop" (?) environments packaged in nixpkgs: [phosh] and [Plasma Mobile].
|
||||
|
||||
[phosh]: https://search.nixos.org/options?channel=22.11&show=services.xserver.desktopManager.phosh.enable&from=0&size=50&sort=relevance&type=packages&query=phosh
|
||||
[Plasma Mobile]: https://search.nixos.org/options?channel=22.11&show=services.xserver.desktopManager.plasma5.mobile.enable&from=0&size=50&sort=relevance&type=packages
|
||||
|
||||
Build the configuration (`nix build .#nixosConfigurations.<hostname>.config.system.build.toplevel` if you're using flakes).
|
||||
|
||||
Running `nixos-install --system ./result --root /mnt` will copy the system to the MMC.
|
||||
Unless you're running on an aarch64 system, it will fail to activate or install the bootloader, however.
|
||||
You must do this manually.
|
||||
Get a shell on Jumpdrive, mount partitions there, and activate the system:
|
||||
|
||||
```console
|
||||
$ nc 172.16.42.1 23
|
||||
# mkdir /mnt
|
||||
# mount /dev/mmcblk0p2 /mnt
|
||||
# mkdir -p /mnt/boot
|
||||
# mount /dev/mmcblk0p1 /mnt/boot
|
||||
# chroot /mnt /nix/var/nix/profiles/system/activate
|
||||
# chroot /mnt /nix/var/nix/profiles/system/bin/switch-to-configuration boot
|
||||
```
|
||||
|
||||
Provided the last command succeeds, you now should have a bootable device.
|
||||
|
||||
Unmount:
|
||||
|
||||
```console
|
||||
# sync
|
||||
# umount /mnt/boot
|
||||
# umount -l /mnt
|
||||
# echo u > /proc/sysrq-trigger
|
||||
# echo s > /proc/sysrq-trigger
|
||||
```
|
||||
|
||||
And shut the phone down by holding the power key.
|
||||
|
||||
Start it up and you should be booting straight into your NixOS installation.
|
53
purism/librem/5r4/default.nix
Normal file
53
purism/librem/5r4/default.nix
Normal file
|
@ -0,0 +1,53 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
let cfg = config.hardware.librem5;
|
||||
in {
|
||||
options = {
|
||||
hardware.librem5 = {
|
||||
wifiCard = lib.mkOption {
|
||||
type = lib.types.enum [ "redpine" "sparklan" "none" ];
|
||||
description = lib.mdDoc ''
|
||||
Which wi-fi card is installed in your phone.
|
||||
|
||||
Phones shipped before Januarly 2023 have redpine, newer phones have sparklan.
|
||||
'';
|
||||
default = "redpine";
|
||||
};
|
||||
customInitrdModules = lib.mkEnableOption (lib.mdDoc "use of custom kernel modules in the initrd.");
|
||||
installUdevPackages = lib.mkEnableOption (lib.mdDoc "installation of udev packages from librem5-base.");
|
||||
lockdownFix = lib.mkEnableOption (lib.mdDoc "fix for orientation and proximity sensors not working after lockdown.");
|
||||
};
|
||||
};
|
||||
|
||||
imports = [ ./initrd.nix ./wifi.nix ./lockdown-fix.nix ];
|
||||
|
||||
config = {
|
||||
hardware.librem5 = {
|
||||
customInitrdModules = lib.mkDefault true;
|
||||
installUdevPackages = lib.mkDefault true;
|
||||
lockdownFix = lib.mkDefault true;
|
||||
};
|
||||
|
||||
nixpkgs.overlays = [
|
||||
(import ./kernel)
|
||||
(final: prev: {
|
||||
ubootLibrem5 = final.callPackage ./u-boot { };
|
||||
|
||||
librem5-base = final.callPackage ./librem5-base { };
|
||||
})
|
||||
];
|
||||
|
||||
boot = {
|
||||
kernelParams = [ "rootwait" ];
|
||||
|
||||
loader = {
|
||||
generic-extlinux-compatible.enable = lib.mkDefault true;
|
||||
grub.enable = false;
|
||||
};
|
||||
|
||||
kernelPackages = lib.mkDefault pkgs.linuxPackages_librem5;
|
||||
};
|
||||
|
||||
services.udev.packages = lib.mkIf cfg.installUdevPackages [ pkgs.librem5-base ];
|
||||
|
||||
};
|
||||
}
|
64
purism/librem/5r4/initrd.nix
Normal file
64
purism/librem/5r4/initrd.nix
Normal file
|
@ -0,0 +1,64 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
lib.mkIf config.hardware.librem5.customInitrdModules {
|
||||
boot.initrd = {
|
||||
kernelModules = [
|
||||
"bq25890_charger"
|
||||
"dwc3"
|
||||
"imx_dcss"
|
||||
"imx_sdma"
|
||||
"mtdblock"
|
||||
"ofpart"
|
||||
"phy_fsl_imx8mq_usb"
|
||||
"snvs_pwrkey"
|
||||
"spi_nor"
|
||||
"tps6598x"
|
||||
"xhci_hcd"
|
||||
"usbcore"
|
||||
"usb_storage"
|
||||
"uas"
|
||||
"xhci_plat_hcd"
|
||||
];
|
||||
# Not all default modules (e.g. SATA ones) are present in Librem 5 kernel fork
|
||||
includeDefaultModules = false;
|
||||
availableKernelModules = [
|
||||
"ahci"
|
||||
|
||||
"sd_mod"
|
||||
"sr_mod"
|
||||
|
||||
"mmc_block"
|
||||
|
||||
"uhci_hcd"
|
||||
"ehci_hcd"
|
||||
"ehci_pci"
|
||||
"ohci_hcd"
|
||||
"ohci_pci"
|
||||
"xhci_pci"
|
||||
"usbhid"
|
||||
"hid_generic"
|
||||
"hid_lenovo"
|
||||
"hid_apple"
|
||||
"hid_roccat"
|
||||
"hid_logitech_hidpp"
|
||||
"hid_logitech_dj"
|
||||
"hid_microsoft"
|
||||
"hid_cherry"
|
||||
|
||||
"bq25890_charger"
|
||||
"dwc3"
|
||||
"imx_dcss"
|
||||
"imx_sdma"
|
||||
"mtdblock"
|
||||
"ofpart"
|
||||
"phy_fsl_imx8mq_usb"
|
||||
"snvs_pwrkey"
|
||||
"spi_nor"
|
||||
"tps6598x"
|
||||
"xhci_hcd"
|
||||
"usbcore"
|
||||
"usb_storage"
|
||||
"uas"
|
||||
"xhci_plat_hcd"
|
||||
];
|
||||
};
|
||||
}
|
14
purism/librem/5r4/kernel/6.1.10.nix
Normal file
14
purism/librem/5r4/kernel/6.1.10.nix
Normal file
|
@ -0,0 +1,14 @@
|
|||
{ buildLinux, fetchFromGitLab, ... }@args:
|
||||
buildLinux (args // rec {
|
||||
defconfig = "librem5_defconfig";
|
||||
version = "6.1.10-librem5";
|
||||
modDirVersion = version;
|
||||
src = fetchFromGitLab {
|
||||
domain = "source.puri.sm";
|
||||
owner = "Librem5";
|
||||
repo = "linux";
|
||||
rev = "pureos/6.1.10pureos1";
|
||||
hash = "sha256-Cc16vMUcJ/a2k3zMynqZ99t1LyTSs7EXKdNGF6OTS1s=";
|
||||
};
|
||||
kernelPatches = [ ];
|
||||
} // args.argsOverride or { })
|
4
purism/librem/5r4/kernel/default.nix
Normal file
4
purism/librem/5r4/kernel/default.nix
Normal file
|
@ -0,0 +1,4 @@
|
|||
final: prev: {
|
||||
linuxPackages_librem5_6_1_10 = final.linuxPackagesFor (final.callPackage ./6.1.10.nix { });
|
||||
linuxPackages_librem5 = final.linuxPackages_librem5_6_1_10;
|
||||
}
|
43
purism/librem/5r4/librem5-base/default.nix
Normal file
43
purism/librem/5r4/librem5-base/default.nix
Normal file
|
@ -0,0 +1,43 @@
|
|||
{ stdenv, fetchFromGitLab, shellcheck, kmod, lib }:
|
||||
stdenv.mkDerivation {
|
||||
pname = "librem5-udev-rules";
|
||||
version = "unstable";
|
||||
src = fetchFromGitLab {
|
||||
domain = "source.puri.sm";
|
||||
owner = "Librem5";
|
||||
repo = "librem5-base";
|
||||
rev = "f5b51beb144f76ef3bc483b74e19867bd6364d32";
|
||||
hash = "sha256-5k7e4o9ak0zik+XqRV6PPwkTDf3yH3NxtLkhTyCQj7U=";
|
||||
};
|
||||
|
||||
buildPhase = ":";
|
||||
|
||||
checkInputs = [ shellcheck ];
|
||||
doCheck = true;
|
||||
checkPhase = "make";
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p "$out/bin" "$out/lib/udev/rules.d"
|
||||
cp -v default/lockdown-support/lockdown-support.sh "$out/bin"
|
||||
chmod +x "$out/bin/lockdown-support.sh"
|
||||
cp -v default/gpsd/99-gnss.rules "$out/lib/udev/rules.d"
|
||||
|
||||
pushd debian
|
||||
for rule in librem5-base-defaults.*.udev; do
|
||||
cp -v "$rule" "$out/lib/udev/rules.d/''${rule#*.}.rules"
|
||||
done
|
||||
popd
|
||||
'';
|
||||
|
||||
postFixup = ''
|
||||
sed -i \
|
||||
-e "s@/usr/sbin/lockdown-support.sh@$out/bin/lockdown-support.sh@g" \
|
||||
-e "s@/usr/sbin/modprobe@${kmod}/bin/modprobe@g" \
|
||||
-e "s@/usr/sbin/rmmod@${kmod}/bin/rmmod@g" \
|
||||
"$out"/lib/udev/rules.d/*.udev.rules
|
||||
'';
|
||||
|
||||
# https://source.puri.sm/Librem5/librem5-base/-/issues/68
|
||||
# President@Purism promised it's under a free license: https://matrix.to/#/%23community-librem-5%3Atalk.puri.sm/%24hNCtZr7Escmr56uz1eEiaHpakteEXig7b5G8t2W6tWs?via=balsoft.ru&via=matrix.org&via=shareknot.de&via=zorix.us
|
||||
meta.license = lib.licenses.free;
|
||||
}
|
26
purism/librem/5r4/lockdown-fix.nix
Normal file
26
purism/librem/5r4/lockdown-fix.nix
Normal file
|
@ -0,0 +1,26 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
lib.mkIf config.hardware.librem5.lockdownFix {
|
||||
# We blacklist the drivers so they don't load during early boot when the sensors are disconnected,
|
||||
boot.blacklistedKernelModules = [
|
||||
"st_lsm6dsx_spi"
|
||||
"st_lsm6dsx_i2c"
|
||||
"st_lsm6dsx"
|
||||
];
|
||||
|
||||
# and load them when the phone is fully booted;
|
||||
systemd.services.librem5-lockdown-support = {
|
||||
description = "Set up drivers for the orientation and proximity sensors on Librem 5";
|
||||
serviceConfig.Type = "oneshot";
|
||||
serviceConfig.ExecStart = "${pkgs.librem5-base}/bin/lockdown-support.sh";
|
||||
wantedBy = [ "default.target" ];
|
||||
path = [ pkgs.kmod ];
|
||||
};
|
||||
|
||||
# udev rules from librem5-base handle going into "lockdown mode" and back.
|
||||
assertions = [{
|
||||
assertion = with config.hardware.librem5;
|
||||
lockdownFix -> installUdevPackages;
|
||||
message =
|
||||
"'hardware.librem5.lockdownFix' requires 'hardware.librem5.installUdevPackages', but it is not enabled.";
|
||||
}];
|
||||
}
|
1
purism/librem/5r4/u-boot/build.nix
Normal file
1
purism/librem/5r4/u-boot/build.nix
Normal file
|
@ -0,0 +1 @@
|
|||
with import <nixpkgs> { system = "aarch64-linux"; }; callPackage ./. { }
|
70
purism/librem/5r4/u-boot/default.nix
Normal file
70
purism/librem/5r4/u-boot/default.nix
Normal file
|
@ -0,0 +1,70 @@
|
|||
{ stdenv, buildUBoot, fetchurl, fetchFromGitLab, lib, flex, bison }:
|
||||
let
|
||||
firmware-imx = stdenv.mkDerivation (fa: {
|
||||
pname = "firmware-imx";
|
||||
version = "8.12";
|
||||
src = fetchurl {
|
||||
url = "https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/${fa.pname}-${fa.version}.bin";
|
||||
sha256 = "1vr2wgjac718hp48arhdvxd7gib93zhdrbrla8w3xigc6szlfrvb";
|
||||
};
|
||||
unpackPhase = ''
|
||||
cp $src firmware
|
||||
chmod +x firmware
|
||||
./firmware --auto-accept
|
||||
'';
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
cd ${fa.pname}-${fa.version}/firmware
|
||||
cp ddr/synopsys/lpddr4_pmu_train_?d_?mem.bin hdmi/cadence/signed_*_imx8m.bin $out
|
||||
'';
|
||||
meta.license = lib.licenses.unfree;
|
||||
});
|
||||
|
||||
arm-trusted-firmware-imx8mq = stdenv.mkDerivation (fa: {
|
||||
pname = "arm-trusted-firmware-bl31";
|
||||
version = "unstable-2020-07-08";
|
||||
src = fetchFromGitLab {
|
||||
domain = "source.puri.sm";
|
||||
owner = "Librem5";
|
||||
repo = "arm-trusted-firmware";
|
||||
rev = "1fd3ff86cd4a05cd3e5637bf5a6902ac58fcafb9";
|
||||
hash = "sha256-fzpUxq+Hz7pijv5Mvzz+bUkaH79YSaugVUnViF7NB3A=";
|
||||
};
|
||||
enableParallelBuilding = true;
|
||||
hardeningDisable = [ "all" ];
|
||||
NIX_LDFLAGS = "--no-warn-rwx-segments";
|
||||
buildFlags = [ "PLAT=imx8mq" "bl31" ];
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
cp build/imx8mq/release/bl31.bin $out
|
||||
'';
|
||||
dontStrip = true;
|
||||
});
|
||||
|
||||
ubootLibrem5 = buildUBoot {
|
||||
version = "2022.10-librem5.1";
|
||||
defconfig = "librem5_defconfig";
|
||||
src = fetchFromGitLab {
|
||||
domain = "source.puri.sm";
|
||||
owner = "a-wai";
|
||||
repo = "uboot-imx";
|
||||
rev = "3a836701279ed1f51063dc5da6f59adc4809093e";
|
||||
hash = "sha256-69auZ8GzyhSBxzi4jc6IyyQ6JBrTYXaOk6dZ+joUgF4=";
|
||||
};
|
||||
BL31 = "${arm-trusted-firmware-imx8mq}/bl31.bin";
|
||||
preConfigure = ''
|
||||
cp $BL31 .
|
||||
cp ${firmware-imx}/* .
|
||||
'';
|
||||
preInstall = ''
|
||||
cp flash.bin u-boot.imx
|
||||
'';
|
||||
filesToInstall = [ "u-boot.imx" ];
|
||||
postInstall = ''
|
||||
mkdir $out/bin
|
||||
sed 's|TARGET="/usr/lib/u-boot/librem5.*"|TARGET="${placeholder "out"}"|' \
|
||||
$src/debian/bin/u-boot-install-librem5 > $out/bin/u-boot-install-librem5
|
||||
'';
|
||||
};
|
||||
in
|
||||
ubootLibrem5
|
14
purism/librem/5r4/wifi.nix
Normal file
14
purism/librem/5r4/wifi.nix
Normal file
|
@ -0,0 +1,14 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
lib.mkIf (config.hardware.librem5.wifiCard == "redpine") {
|
||||
# Disable mainline rsi module
|
||||
boot.blacklistedKernelModules = [
|
||||
"rsi_91x"
|
||||
"rsi_sdio"
|
||||
];
|
||||
|
||||
# Load redpine in Wi-Fi station + BT dual mode
|
||||
boot.extraModprobeConfig = ''
|
||||
options redpine_91x dev_oper_mode=13 rsi_zone_enabled=1 antenna_diversity=1
|
||||
'';
|
||||
|
||||
}
|
Loading…
Reference in a new issue