Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add EL2 booting using slbounce #52

Merged
merged 1 commit into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Note that I only have the Lenovo Yoga Slim 7x, so the repo will be focused aroun
| Feature | Status | Notes |
| ----------------------- | -----: | ------------------------------------------------------------------------------------------------------------ |
| Battery Charging | ✅ | |
| Battery Indicator | ✅ | |
| Battery Indicator | ✅ | Not working in EL2. (More info [below](#running-virtual-machines-with-kvm).) |
| Bluetooth | ✅ | |
| Camera | ❌ | |
| Display | ✅ | |
Expand Down Expand Up @@ -180,6 +180,16 @@ and then use the `x1e-nixos-config.nixosModules.x1e` module.

You should be able to import [`default.nix`](/default.nix) and reference the module as its `nixosModules.x1e` attribute.

## Running virtual machines with KVM

By default the firmware runs Linux in the EL1 privilege level, but EL2 is needed for KVM. Coaxing the firmware into running Linux in EL2 is rather involved, see the [slbounce](https://github.com/TravMurav/slbounce) README for more information about the process.

`slbounce` uses `tcblaunch.exe` (this is a signed binary, and there are currently no known alternatives), which you will need to manually copy from your Windows installation from `C:\Windows\System32\tcblaunch.exe` into the root of the ESP. The SHA256 hash of my `tcblaunch.exe` is `5dfcd0253b6ee99499ab33cac221e8a9cea47f3fdf6d4e11de9a9f3c4770d03d`, I am not sure whether other versions also exist out there. If yours is different, please report its hash and whether it worked for you.

To enable the `el2` specialization, which you can then select in the systemd-boot menu, set `x1e.el2.enable = true;` in your config.

This is deliberately a separate non-default boot option, since some hardware support does not work under EL2.

## Contributing

### Code formatting
Expand Down
1 change: 1 addition & 0 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
imports = [
./modules/x1e80100.nix
./modules/pd-mapper.nix
./modules/el2.nix
];
config = {
nixpkgs.overlays = [
Expand Down
28 changes: 28 additions & 0 deletions modules/el2.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
config,
lib,
pkgs,
...
}:

{
options.x1e.el2.enable = lib.mkEnableOption ''
Enable the `el2` specialization and slbounce EFI driver. Needed to run
virtual machines using KVM.
'';
config = lib.mkIf config.x1e.el2.enable {
specialisation.el2.configuration = {
hardware.deviceTree.overlays = [
{
name = "x1e-el2";
dtboFile = "${pkgs.slbounce}/dtbo/x1e-el2.dtbo";
}
];

boot.kernelParams = [ "id_aa64mmfr0.ecv=1" ];
};

boot.loader.systemd-boot.extraFiles."EFI/systemd/drivers/slbounceaa64.efi" =
"${pkgs.slbounce}/slbounce.efi";
};
}
1 change: 1 addition & 0 deletions packages/overlay.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ final: prev: {
{ };
libqrtr = final.callPackage ./libqrtr.nix { };
pd-mapper = final.callPackage ./pd-mapper.nix { };
slbounce = final.callPackage ./slbounce.nix { };
}
35 changes: 35 additions & 0 deletions packages/slbounce-Makefile.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
diff --git a/Makefile b/Makefile
index e2b57ed..1fada67 100644
--- a/Makefile
+++ b/Makefile
@@ -92,15 +92,11 @@ DTBS := \

all: $(OUT_DIR)/sltest.efi $(OUT_DIR)/slbounce.efi $(OUT_DIR)/dtbhack.efi

-.INTERMEDIATE: $(GNUEFI_DIR)/inc/elf.h
-$(GNUEFI_DIR)/inc/elf.h:
- ln -sf /usr/include/elf.h $(GNUEFI_DIR)/inc/elf.h
-
-$(LIBEFI_A): $(GNUEFI_DIR)/inc/elf.h
+$(LIBEFI_A):
@echo [ DEP ] $@
@$(MAKE) -C$(GNUEFI_DIR) CROSS_COMPILE=$(CROSS_COMPILE) ARCH=$(ARCH) lib

-$(LIBGNUEFI_A): $(GNUEFI_DIR)/inc/elf.h
+$(LIBGNUEFI_A):
@echo [ DEP ] $@
@$(MAKE) -C$(GNUEFI_DIR) CROSS_COMPILE=$(CROSS_COMPILE) ARCH=$(ARCH) gnuefi

diff --git a/README.md b/README.md
index 9b7e526..53a4b49 100644
--- a/README.md
+++ b/README.md
@@ -44,7 +44,7 @@ Make sure `tcblaunch.exe` is placed in the root of the FS, then load the EFI dri
fs0:\> load slbounce.efi
```

-The driver will replace `BS->ExitBootServices` in the system table with it's own
+The driver will replace `BS->ExitBootServices` in the system table with its own
function. It will call EBS and perform switch to EL2 right after. Thus your bootloader
(i.e. grub or linux's efi-stub) would experence the cpu swithing to EL2 when it calls
EBS.
89 changes: 89 additions & 0 deletions packages/slbounce.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
{
stdenv,
fetchzip,
fetchgit,
fetchFromGitHub,
fetchpatch,
python3,
dtc,
}:

let
aarch64-system-register-xmls = fetchzip {
url = "https://developer.arm.com/-/media/developer/products/architecture/armv8-a-architecture/2020-06/SysReg_xml_v86A-2020-06.tar.gz";
stripRoot = false;
hash = "sha256-wpWMIdR4v4sGZ0FEn/j5+AzkpPFOF7lUKIFpVl5AMEE=";
};
arm64-sysreg-lib = stdenv.mkDerivation {
name = "arm64-sysreg-lib";
src = fetchFromGitHub {
owner = "ashwio";
repo = "arm64-sysreg-lib";
sparseCheckout = [ "/" ];
rev = "d421e249a026f6f14653cb6f9c4edd8c5d898595";
hash = "sha256-vUuV8eddYAdwXGQe+L7lKiAwyqHPYmiOdVFKvwCMWkQ=";
};
nativeBuildInputs = [
(python3.withPackages (ps: [ ps.beautifulsoup4 ]))
];
buildPhase = ''
python ./run-build.py ${aarch64-system-register-xmls}/SysReg_xml_v86A-2020-06
'';
installPhase = ''
mkdir -p $out/include
cp -r include $out/
'';
};

gnu-efi = fetchFromGitHub {
owner = "ncroxon";
repo = "gnu-efi";
rev = "3.0.15";
hash = "sha256-flQJIRPKd0geQRAtJSu4vravJG0lTB6BfeIqpUM5P2I=";
};

dtc-src = fetchgit {
url = "https://git.kernel.org/pub/scm/utils/dtc/dtc.git";
rev = "v1.7.2";
hash = "sha256-KZCzrvdWd6zfQHppjyp4XzqNCfH2UnuRneu+BNIRVAY=";
};
in
stdenv.mkDerivation {
name = "slbounce";
src = fetchFromGitHub {
owner = "TravMurav";
repo = "slbounce";
rev = "97b24ec89faa11827e7def220b0aa53dd5d5f447";
hash = "sha256-ImZHsMwLSlo2smLV7aAkmN0JbxcQbkrO/WWcK5fMfpU=";
};
nativeBuildInputs = [ dtc ];
patches = [
(fetchpatch {
url = "https://github.com/TravMurav/slbounce/commit/d930fcc584c818c2254cfdac6983af45d5935538.patch";
hash = "sha256-lTR3qonIId5mpAduwxzsf9qXux4FCpf5sAOEE+ZdR3Y=";
})
(fetchpatch {
url = "https://github.com/TravMurav/slbounce/commit/006eb5db9083530610e8323cf80b8c98c00c891e.patch";
hash = "sha256-T1XeLanrVEv6CNxptaOvA/ojs7YibySfUn0XRfpn/Zk=";
})
./slbounce-Makefile.patch
];
postPatch = ''
rmdir external/{arm64-sysreg-lib,dtc}
ln -s ${arm64-sysreg-lib} external/arm64-sysreg-lib
ln -s ${dtc-src} external/dtc

cp -r ${gnu-efi}/* external/gnu-efi/
chmod -R u+w external/gnu-efi
'';
makeFlags = [
"CROSS_COMPILE="
"all"
"dtbs"
];
installPhase = ''
mkdir -p $out
cp out/*.efi $out/
cp -r out/dtbo $out/
'';
}
Loading