cszach / linux-on-lenovo-legion

:computer: Notes for using Linux on Lenovo Legion.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using Linux on Lenovo Legion

This is a compilation of instructions and resources for those who use a Linux system (e.g. GNU plus Linux) on a Lenovo Legion laptop. More notes will be added as I discover more things.

Contributing

Any suggestion will be very appreciated. Feel free to open issues and pull requests for suggestions, comments, and questions. If you have a workaround that you do not see presented here, please, please either open an issue or pull request. The goal here is to compile all the working solutions so everyone does not have to spend countless hours digging for solutions online.

My system

  • Machine: Lenovo Legion 5 15ACH6H (Ryzen + NVIDIA)
  • Operating system: Fedora 39
  • Desktop environment: GNOME 45.1
  • Windowing system: Wayland
  • Linux kernel's version (as of latest commit): 6.5.10-300.fc39.x86_64

Table of Content

  1. Wi-Fi
  2. Brightness
  3. Battery conservation mode
  4. Launch applications on dedicated graphics card
  5. Windowing system
  6. Keyboard's RGB
  7. Fan control
  8. FPC fingerprint

Wi-Fi

Fedora 37+ update: as documented in #3 (thanks @hrkrx) and from my personal experience with Fedora 38, wi-fi seems to work out of the box now for these two Fedora versions.

This is perhaps the most frustrating issue and the problem you would want to fix first. It is likely that your system does not have the driver for Realtek RTL8852AE 802.11ax. Thus, you will need to download and install it.

Downloading and installing the driver

Get ready to work in the terminal! You don't need root permissions here; commands requiring root privileges will have sudo in them.

  1. Temporarily connect to the Internet using Ethernet or a wireless USB adapter. You may also use another computer;
  2. Download/clone this repository. You can clone any of the main, v5, v6, and v7 branches. I tried the main branch and the v7 branch, both of which worked (I am currently using the v7);
  3. Create a directory for storing a MOK (Machine Owner Key) to allow the driver to run. A good choice is ~/.MOK (we will be using it for the rest of the instructions);
mkdir ~/.MOK
  1. Open the directory you created in step 3.
cd ~/.MOK
  1. Request a new MOK key pair.
openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -nodes -days 36500 -subj "/CN=Custom MOK/"
  1. Import the MOK key.
sudo mokutil --import MOK.der
  1. Reboot. Upon seeing the splash screen with the Legion logo, you may see a blue screen that asks if you want to manage MOK keys. Select "Enroll MOK" on the menu and accept to enroll the new MOK key. After this process, your OS will boot.
  2. Open a terminal in the rtw89 repository clone. It is the directory you cloned the rtw89 repository into in step 2.
  3. Compile the driver, sign the compiled driver files with the MOK key, and install the driver.
make
/usr/src/kernels/$(uname -r)/scripts/sign-file sha256 ~/.MOK/MOK.priv ~/.MOK/MOK.der rtw89core.ko
/usr/src/kernels/$(uname -r)/scripts/sign-file sha256 ~/.MOK/MOK.priv ~/.MOK/MOK.der rtw89pci.ko
sudo make install
  1. Reboot. Your device should be able to connect to Wi-Fi networks now.

Kernel update

After you have updated your Linux kernel, you need to recompile the driver and install it again.

  1. Reboot. If you have already rebooted after updating the kernel, you may skip this step.
  2. Open the terminal in the rtw89 directory.
  3. Follow the steps below. The last 4 commands is exactly the same as the ones in step 9 of the previous section. Note that if you have deleted the MOK key, you will have to complete steps 3-7 of the previous section.
git pull
sudo make uninstall
make clean
make
/usr/src/kernels/$(uname -r)/scripts/sign-file sha256 ~/.MOK/MOK.priv ~/.MOK/MOK.der rtw89core.ko
/usr/src/kernels/$(uname -r)/scripts/sign-file sha256 ~/.MOK/MOK.priv ~/.MOK/MOK.der rtw89pci.ko
sudo make install
  1. Reboot.

A Bash script that automates this process can be found in src. Be sure to modify the paths and file names accordingly.

Acknowledgment

Thanks to @lwfinger and other contributors of the rtw89 GitHub repository for their work on the open-source driver. Many thanks to @lukinoway for sharing how they installed the driver on Fedora 34.

Brightness

Fedora 37+ update: Brightness controls work out of the box.

Having troubles changing the screen brightness? Fn + F5/F6 does not work? Here are some things I have found.

Solutions

  • Try the amdgpu.backlight=0 parameter in your kernel boot parameters. When you boot your machine, press E on your keyboard when you see the GRUB boot menu. Then insert amdgpu.backlight=0 into the kernel parameters. This addition is temporary so you can see if it works. If it does, you can add the parameter permanently e.g. using grubby:
sudo grubbby --args="amdgpu.backlight=0 --update-kernel $(sudo grubby --default-kernel)"
  • The AMD iGPU might not support for brightness control due to a bug. Thus, you can try using the NVIDIA dGPU for this. Please refer to the See also section below.

Temporary solution

If none of the solution works for you, here is a temporary workaround:

xrandr --output MONITOR --brightness BRIGHTNESS

Replace MONITOR with the correct monitor identifier (try xrandr --listmonitors for a list) and BRIGHTNESS with the appropriate brightness from 0 to 1. Values over 1 are also accepted but not recommended.

For example, here is my output of xrandr --listmonitors:

Monitors: 2
 0: +*eDP 1920/344x1080/194+0+0  eDP
 1: +HDMI-1-0 2560/597x1440/336+1920+0  HDMI-1-0

I connect my laptop to an external monitor via HDMI, which is why you see 2 entries here (the first entry is the Legion laptop's monitor). Hence, to set the laptop's monitor's brightness to 0.5, I run:

xrandr --output eDP --brightness 0.5

This solution does not work very well with night light, however. As soon as night light starts, you will lose what you have set for brightness. If you attempt to set brightness using this method again, night light will turn off.

See also

Battery conservation mode

It is not a good idea to leave your laptop plugged in when it is already 100% charged, as this will damage your laptop's battery's health. However, it is also tiresome to have to manually unplug your laptop. Ideally, you want your laptop to automatically stop the charge after the battery reaches a certain level while it is still plugged in. Battery conservation does this. Windows users enjoy enabling this feature in Lenovo Vantage.

On Linux, to enable battery conservation (requires sudo permission):

sudo bash -c "echo 1 > /sys/bus/platform/drivers/ideapad_acpi/VPC2004*/conservation_mode"

…and to disable it, replace the 1 with 0.

sudo bash -c "echo 0 > /sys/bus/platform/drivers/ideapad_acpi/VPC2004*/conservation_mode"

When battery conservation mode is on, your battery will stop charging if it is 60% full or more. If you need to charge your laptop to, say, 80% so you can use it unplugged later, you will have to disable battery conservation to let your device charge and turn conservation on when it reaches 80%. See below for a cronjob that does this for you.

Scripts

For convenience, I have written some scripts to help you control battery conservation.

  • battery-conservation: A utility to see the status of battery conservation and turn the feature on/off. Use -s to see the status, -n to turn conservation on, -f to turn off. You can run the script as normal user, it will ask for sudo when necessary;
  • auto-battery-conservation: Turns battery conservation on if the battery level is greater than or equal to a specified integer, and off if less than. You must specify the integer as the first and only command line argument to the script. This is useful if you don't like the 60% battery conservation trigger. The script is designed to be used as a cronjob; you will need to run it as root, so open the cron editor using sudo crontab -e and add the following cron entry:
*/10 * * * * auto-battery-conservation 80

Note: You might have to put bash /path/to/the/script 80 instead of just auto-battery-conservation 80 in the cron entry.

Feel free to, of course, use another number if you like.

Copy these scripts to a PATH directory. I personally use ~/.local/bin.

Launch applications on dedicated graphics card

Note: Before you read this section, please have a dedicated graphics card driver installed. This is quite dependent on your OS and desktop environment, so I don't provide the instructions here (Fedora users are better off sticking to RPM Fusion's how-to).

Which graphics card is your machine running on?

glxinfo | egrep "OpenGL vendor|OpenGL renderer"
  • If it is your dedicated graphics card (dGPU), I can think of 2 reasons (please contribute more, I am not an expert): 1. you have set the dGPU as your primary GPU; 2. you are in Legion's discrete graphics mode (configurable when boot). While this is totally fine if you know what you are doing, I find it overkill to have everything run on dGPU when I don't need it most of the time (consumes more power, increases your electricity bills, etc.);
  • If it is your integrated graphics card (iGPU), this section is for you.

While in hybrid graphics mode, we are interested in launching certain applications, such as Blender and video games, on our dGPU, to take advantage of faster graphics computing power. GNOME has already allowed you to do so by right clicking an application and selecting "Launch using Discrete Graphics Card". But there is a more universal way to launch any application on the dGPU.

If you are using an AMD dGPU, you can start an application on the dGPU from the terminal by setting the environment variable DRI_PRIME:

DRI_PRIME=1 command args...

And if you are using NVIDIA's:

__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia command args...

Try it now

Start glxgears:

glxgears -info | grep GL_RENDERER

Screenshot of glxgears

The program shows an animation of three intermeshing gears rotating. In the terminal output, you should see your iGPU. This is mine (AMD iGPU, NVIDIA dGPU):

GL_RENDERER   = AMD Radeon Graphics (renoir, LLVM 14.0.0, DRM 3.48, 6.0.18-200.fc36.x86_64)

Kill the application. Now set the appropriate environment variable(s) and launch it again. So for example, I would use the following command:

__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia glxgears -info | grep GL_RENDERER

And the result:

GL_RENDERER   = NVIDIA GeForce RTX 3060 Laptop GPU/PCIe/SSE2

Steam

The technique also applies to Steam games. In your Library, edit the Properties of the game that you wish to run on your graphics card. Under launch options, edit the launch command, and use %command% as the placeholder for the actual game command. For example, here is my launch command for Quake II RTX (NVIDIA dGPU):

__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia %command%

Aliases

It would be a pain to have to set the variables every time. For convenience, put this in your .bashrc, or wherever you set your Shell's configuration:

  • AMD:
alias amd="DRI_PRIME=1"
  • NVIDIA:
alias nvidia="__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia"

I can then start glxgears on my dGPU just by typing nvidia glxgears. Happy computing!

Google Chrome and WebGPU

Web applications could benefit from GPU computing too! Launch Google Chrome on your dedicated graphics card (see instructions above), go to chrome://gpu, and navigate to the Driver Information section to verify that Chrome is using the dGPU, and you are good to go!

Google Chrome 113+ ships with WebGPU, a new web graphics API that is the successor to WebGL. To enable WebGPU:

  1. In chrome://settings, make sure that hardware acceleration is enabled;
  2. Go to chrome://flags, and enable the WebGPU and Vulkan flags;
  3. Close all Chrome windows, and relaunch Google Chrome on dedicated graphics card with the --enable-unsafe-webgpu option:
# nvidia here is the alias from the previous section
nvidia google-chrome --enable-unsafe-webgpu

To make sure that WebGPU is working, go to chrome://gpu. It should say "WebGPU: Hardware accelerated" in the Graphics Feature Status section. Try out some WebGPU samples!

Firefox and WebGPU

I could not make Firefox Developer Edition run on my dGPU. However, Firefox Nightly works (just by launching on dedicated graphics card, see instructions above). Go to about:support, navigate to the Graphics section and verify that Firefox is using dGPU.

Firefox Nightly also comes with WebGPU enabled by default (check that dom.webgpu.enabled is set to true in about:config). Visit the WebGPU samples and see if WebGPU is working.

Windowing system

This section is reported on a Legion with NVIDIA dGPU. Please contribute to it especially if you have experience dealing with an AMD dGPU.

Pick your poison.

X11

Pros:

  • handles night light on the external monitor correctly;
  • lets you use nvidia-settings.

Cons:

  • external monitor is very laggy, even when set with high FPS, making it nearly unusable.

Wayland

Pros:

  • no external monitor lag.

Cons:

  • night light does not apply on external monitor (at least with my conf.);
  • nvidia-settings is not supported;
  • no hardware-accelerated video encoding with VDPAU.

Note: Having troubles with monitor displays on Wayland? Try enabling KMS by adding nvidia-drm.modeset=1 to your kernel parameters. Case in point, I connected my external monitor to my Legion through an HDMI cable and somehow only the external monitor was working; the laptop monitor was empty. After making this fix, both monitors started to work normally. Read more here. NVIDIA drivers only.

See also

Keyboard's RGB

@4JX created an awesome cross-platform application for controlling the RGB lights of Lenovo Legion laptops' keyboards. You can choose from one of the presets (some of which require manual color setting) or even create your own effects (please see the project on GitHub for more details). You can also set the speed of the effect being used and the lights' brightness. The program can be run in the CLI or the GUI and works out of the box on my machine.

Screenshot of the application

Fan control

@johnfanv2 created a tool that lets you create custom fan curves, monitor fan speeds and temperatures, switch between power modes, and more! It is called LenovoLegionLinux and I highly recommending checking out and starring the project. Thanks for letting me know about this great project!

Screenshot of LenovoLegionLinux's fan curve configuration GUI

Screenshot of LenovoLegionLinux's fan monitor

Screenshots courtesy of @johnfanv2.

FPC fingerprint

Contributed by @kasra3422 for Ubuntu, thanks.

$ sudo add-apt-repository ppa:libfprint-tod1-group/ppa
$ sudo apt update
$ ubuntu-drivers list
libfprint-2-tod1-fpc
$ sudo apt install libfprint-2-tod1-fpc
$ sudo reboot

Read more here.

About

:computer: Notes for using Linux on Lenovo Legion.

License:Creative Commons Zero v1.0 Universal


Languages

Language:Shell 100.0%