You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
533 lines
14 KiB
533 lines
14 KiB
---
|
|
gitea: none
|
|
include_toc: true
|
|
---
|
|
|
|
# linux-on-desktop
|
|
|
|
My journey to get Alpine + Wayland + River to work on ThinkPad T14 G3 AMD (21CF004PGE)
|
|
|
|
## Preparing hardware
|
|
|
|
Disable secure boot and fn-lock in bios (so that F-keys work as F-keys by default and require Fn for their secondary multimedia functions).
|
|
|
|
## Installing Alpine
|
|
|
|
Follow https://wiki.alpinelinux.org/wiki/Installation
|
|
|
|
Note that you will need to use Rufus; Ventoy does not work on this laptop (hangs after choosing the image).
|
|
|
|
## Postinstall
|
|
|
|
In `/etc/apk/repositories`, comment out 3.16, uncomment edge (main, community, testing),
|
|
since some of the packages we're going to install (river, element-desktop)
|
|
only exist in testing.
|
|
|
|
Then
|
|
```
|
|
doas apk update
|
|
doas apk upgrade
|
|
```
|
|
|
|
## Installing river
|
|
|
|
```
|
|
doas apk add eudev
|
|
doas setup-udev
|
|
doas apk add mesa-dri-gallium mesa-va-gallium
|
|
doas apk add river river-doc mandoc
|
|
doas apk add adwaita-icon-theme foot ttf-dejavu
|
|
doas rc-update add seatd
|
|
doas rc-service seatd start
|
|
doas addgroup YOURUSER audio
|
|
doas addgroup YOURUSER input
|
|
doas addgroup YOURUSER seat
|
|
doas addgroup YOURUSER video
|
|
doas addgroup YOURUSER wheel
|
|
install -Dm0755 /usr/share/doc/river/examples/init -t ~/.config/river
|
|
```
|
|
|
|
Also:
|
|
```
|
|
doas apk add xwayland
|
|
```
|
|
because the latest river in testing is built in a way that requires xwayland.
|
|
|
|
Try to run with
|
|
```
|
|
XDG_RUNTIME_DIR=/tmp river
|
|
```
|
|
|
|
You should see the blue screen of river. Try to open terminal with Win+Shift+Enter. Try to exit with Win+Shift+E.
|
|
|
|
### Login manager
|
|
|
|
To enter username/password in GUI, get to river after that, and get back to logon screen after exiting river:
|
|
|
|
```
|
|
doas apk add elogind polkit-elogind
|
|
doas rc-update add elogind
|
|
doas rc-service elogind start
|
|
doas apk add greetd greetd-gtkgreet cage
|
|
doas addgroup greetd video
|
|
doas rc-update add greetd
|
|
```
|
|
|
|
change `/etc/greetd/config.toml`
|
|
|
|
```
|
|
command = "cage -s -- gtkgreet"
|
|
```
|
|
|
|
and create `/etc/greetd/environments` with a single line `river`
|
|
|
|
and reboot.
|
|
|
|
I didn't find a way to make cage+gtkgreet handle HiDPI, the text is very tiny.
|
|
|
|
An alternative is agreety, but for some reason it seems that both greeter and standard linux login prompt
|
|
run at the same time on the same terminal, making it impossible to actually login.
|
|
|
|
### Installing Waybar
|
|
|
|
```
|
|
doas apk add waybar
|
|
```
|
|
|
|
and add startup section at the end of river init file (`~/.config/river/init`):
|
|
|
|
```
|
|
# startup
|
|
riverctl spawn "waybar"
|
|
```
|
|
|
|
For time to work,
|
|
```
|
|
doas apk add tzdata
|
|
```
|
|
|
|
### HiDPI
|
|
|
|
```
|
|
doas apk add kanshi
|
|
mkdir .config/kanshi
|
|
```
|
|
|
|
and create `.config/kanshi/config` with the following:
|
|
```
|
|
profile {
|
|
output eDP-1 enable scale 2.5
|
|
}
|
|
```
|
|
|
|
(`eDP-1` identifier was obtained by installing sway, running sway (by adding it to `/etc/greetd/environments`,
|
|
and in terminal inside sway executing `swaymsg -t get_outputs`).
|
|
|
|
#### HiDPI - cursors
|
|
|
|
And in order to have decently sized mouse cursors instead of the tiniest ones, add the following line to the top of `.config/river/init`:
|
|
|
|
```
|
|
riverctl xcursor-theme Adwaita 24
|
|
```
|
|
|
|
This will only affect river itself, the cursor will stay tiny in waybar and firefox and maybe other applications. To solve this:
|
|
```
|
|
doas apk add gsettings-desktop-schemas
|
|
gsettings set org.gnome.desktop.interface cursor-theme 'Adwaita'
|
|
```
|
|
|
|
### Environment
|
|
|
|
In order to not have to create wrapper scripts for all apps:
|
|
|
|
Create `/usr/local/bin/inga-river` (and later `chmod +x /usr/local/bin/inga-river`) with the following (found in google):
|
|
|
|
```
|
|
#!/bin/sh
|
|
|
|
export GDK_BACKEND=wayland,x11
|
|
export MOZ_ENABLE_WAYLAND=1
|
|
export CLUTTER_BACKEND=wayland
|
|
export QT_QPA_PLATFORM=wayland-egl
|
|
export ECORE_EVAS_ENGINE=wayland-egl
|
|
export ELM_ENGINE=wayland_egl
|
|
export SDL_VIDEODRIVER=wayland
|
|
export _JAVA_AWT_WM_NONREPARENTING=1
|
|
export NO_AT_BRIDGE=1
|
|
export BEMENU_BACKEND=wayland
|
|
|
|
river $@
|
|
```
|
|
|
|
and replace `river` with `inga-river` in `/etc/greetd/environments`.
|
|
|
|
### Launcher
|
|
|
|
`doas apk add bemenu`, and then add this line into your river config:
|
|
|
|
```
|
|
riverctl map normal Super R spawn 'pidof bemenu-run || bemenu-run -i -n'
|
|
```
|
|
|
|
### Screenshots
|
|
|
|
`doas apk add wayshot`, then add this line to river config:
|
|
```
|
|
riverctl map normal None Print spawn 'wayshot --stdout | wl-copy'
|
|
```
|
|
|
|
### Clipboard
|
|
|
|
Works by default, use Ctrl+Shift+C and Ctrl+Shift+V in foot
|
|
|
|
### Emoji keyboard
|
|
|
|
`doas apk add rofi-emoji rofi-emoji-wayland wtype` and add this line to your river config
|
|
```
|
|
riverctl map normal Super period spawn 'rofi -modi emoji -show emoji'
|
|
```
|
|
|
|
## Other software
|
|
|
|
### Firefox
|
|
|
|
```
|
|
doas apk add firefox
|
|
firefox
|
|
```
|
|
go to `about:support` and make sure that Window Protocol is wayland, not xwayland.
|
|
(it should be wayland because MOZ_ENABLE_WAYLAND is set to 1 by inga-river)
|
|
|
|
For some reason, while sound in general works fine in firefox (after following the steps from Hardware section),
|
|
in WebRTC pages there is crackling much louder than the actual voices, making it unusable for voice/video calls/meetings.
|
|
|
|
### Chrome
|
|
|
|
```
|
|
doas apk add chromium
|
|
```
|
|
|
|
It should also be wayland by default, but you can check it by `doas apk add xeyes && xeyes`.
|
|
|
|
In order for screen sharing to work, go to `chrome://flags/#enable-webrtc-pipewire-capturer` and enable it.
|
|
Note though that every time you screenshare, there will be two promps from xdg-desktop-portal, one for picking a source, and another for actually sharing.
|
|
|
|
### Git
|
|
|
|
```
|
|
doas apk install git
|
|
git config --global credential.helper --store
|
|
```
|
|
|
|
### Telegram
|
|
|
|
```
|
|
doas apk install telegram-desktop
|
|
```
|
|
|
|
### Element
|
|
|
|
```
|
|
doas apk install element-desktop
|
|
```
|
|
|
|
## Hardware
|
|
|
|
### Sleep
|
|
|
|
With default settings, laptop goes to sleep after some idle period. When it wakes up, the root fs is readonly, meaning that I have to restart the laptop.
|
|
|
|
Adding `acpiphp.disable=1` and `pcie_aspm=off` to grub config does not solve the issue.
|
|
|
|
Disabling S0ix in UEFI only made things worse: even though `cat /sys/power/mem_sleep` reported that S3 (deep) is default,
|
|
after system goes to sleep it is impossible to wake it up, it does not react to key or power button presses.
|
|
|
|
What did solve the issue was:
|
|
* reenable S0ix in BIOS,
|
|
* `doas apk add linux-firmware-amdgpu`,
|
|
* editing `GRUB_CMDLINE_LINUX_DEFAULT` in `/etc/default/grub` to add the following options:
|
|
`acpiphp.disable=1 pcie_aspm=off acpi_osi='Windows 2020' iommu=soft`.
|
|
|
|
Now after waking up (after being suspended with `doas pm-suspend` from `pm-utils` package) root fs is still readwrite.
|
|
But sometimes network disappears after wakeup.
|
|
|
|
For suspend on lid close and unsuspend on open, follow https://wiki.alpinelinux.org/wiki/Suspend_on_LID_close :
|
|
```
|
|
doas mkdir -p /etc/acpi/LID
|
|
doas nano /etc/acpi/LID/00000080
|
|
```
|
|
should have the following content
|
|
```
|
|
#!/bin/sh
|
|
exec pm-suspend
|
|
```
|
|
and then
|
|
```
|
|
doas chmod +x /etc/acpi/LID/00000080
|
|
doas rc-service acpid restart
|
|
```
|
|
|
|
### WiFi
|
|
|
|
At the moment Linux kernel does not support Qualcomm NFA725.
|
|
|
|
Otherwise, alpine wiki describes how to configure WiFi using `iwd`.
|
|
|
|
### Backlight
|
|
|
|
```
|
|
doas apk add light
|
|
doas nano /etc/udev/rules.d/backlight.rules
|
|
```
|
|
add the following lines into backlight.rules to make it possible for all users in video group (not just superusers) to control backlight:
|
|
```
|
|
ACTION=="add", SUBSYSTEM=="backlight", KERNEL=="amdgpu_bl0", RUN+="/bin/chgrp video /sys/class/backlight/%k/brightness"
|
|
ACTION=="add", SUBSYSTEM=="backlight", KERNEL=="amdgpu_bl0", RUN+="/bin/chmod g+w /sys/class/backlight/%k/brightness"
|
|
```
|
|
and then
|
|
```
|
|
doas rc-service udev restart
|
|
```
|
|
Backlight control with Fn+F5/F6 should work now.
|
|
|
|
(`amdgpu_bl0` is specific for this laptop; value for others can be obtained from `/sys/class/backlight/`)
|
|
|
|
### Trackpoint
|
|
|
|
Disregard this:
|
|
|
|
> ```
|
|
>find /sys/devices/platform/i8042/ -name name | xargs grep -Fl TrackPoint
|
|
> ```
|
|
> to find which serio corresponds to trackpoint, then
|
|
> ```
|
|
> echo 70 | doas tee /sys/devices/platform/i8042/serio1/sensitivity
|
|
> ```
|
|
> for reasonably low sensitivity (does not persist; for persistence TODO separate udev rule).
|
|
|
|
Instead of configuring sensitivity, it's probably better to configure pointer speed in river.
|
|
|
|
Find your trackpoint with `riverctl list-inputs | grep -i trackpoint`,
|
|
it will look like `2:10:TPPS/2_Elan_TrackPoint`.
|
|
|
|
Then add the following to your river config:
|
|
```
|
|
riverctl input 2:10:TPPS/2_Elan_TrackPoint accel-profile adaptive
|
|
riverctl input 2:10:TPPS/2_Elan_TrackPoint pointer-accel -0.5
|
|
```
|
|
|
|
### Sound
|
|
|
|
Based on https://wiki.alpinelinux.org/wiki/PipeWire
|
|
|
|
```
|
|
doas apk add dbus dbus-openrc
|
|
doas rc-service dbus start
|
|
doas apk add pipewire wireplumber rtkit alsa-utils pipewire-alsa
|
|
doas addgroup YOURUSER rtkit
|
|
doas addgroup root audio
|
|
alsamixer
|
|
```
|
|
|
|
In alsamixer, use F6 to find the target sound card (most likely 0 is HDMI and 1 is ordinary).
|
|
Remember its number, and in `/usr/share/alsa/alsa.conf`,
|
|
replace `defaults.ctl.card` and `defaults.pcm.card` with the target number.
|
|
|
|
In `/usr/local/bin/inga-river`, replace `river $@` with `dbus-run-session -- river $@`,
|
|
relogin (Ctrl+Shift+E).
|
|
|
|
Then
|
|
```
|
|
doas rc-service alsa start
|
|
doas rc-update add alsa
|
|
/usr/libexec/pipewire-launcher
|
|
```
|
|
|
|
Make sure that everything works (with `wpctl status`, `pw-cat -p YOURFILE.flac`
|
|
or just opening YouTube in FF).
|
|
|
|
Then make pipewire start automatically: in river config, add another startup line:
|
|
```
|
|
riverctl spawn "/usr/libexec/pipewire-launcher"
|
|
```
|
|
|
|
Control microphone and volume with `alsamixer`.
|
|
And change the handlers for XF86Audio (adding `-repeat` and replacing the spawned command):
|
|
```
|
|
riverctl map -repeat $mode None XF86AudioRaiseVolume spawn 'amixer set "Master" 5%+'
|
|
riverctl map -repeat $mode None XF86AudioLowerVolume spawn 'amixer set "Master" 5%-'
|
|
riverctl map $mode None XF86AudioMute spawn 'amixer set "Master" toggle'
|
|
```
|
|
|
|
Note that the internal microphone does not work and is not detected by pipewire.
|
|
Only external microphones work.
|
|
|
|
Mic in browser didn't work, but then it started to work at some point,
|
|
without me seemingly changing anything.
|
|
|
|
#### Mic mute button
|
|
|
|
Create `/etc/acpi/events/lenovo-mutemic` with the following content:
|
|
```
|
|
event=button/micmute MICMUTE 00000080 00000000 K
|
|
action=amixer --card 1 set 'Capture' toggle
|
|
```
|
|
where card number is the one obtained in previous section; and event could be determined by running `acpi_listen` and pressing mic button.
|
|
|
|
Then, after `doas rc-service acpid restart`, mic button should control internal mic capture in alsa and switch internal mic led on and off.
|
|
|
|
### Webcam
|
|
|
|
Should work after following the steps for "Audio".
|
|
|
|
Can be tested in https://webrtc.github.io/test-pages
|
|
|
|
## Additional
|
|
|
|
### Screen sharing
|
|
|
|
```
|
|
doas apk add xdg-desktop-portal xdg-desktop-portal-wlr
|
|
```
|
|
|
|
and DO NOT add to your river config
|
|
```
|
|
riverctl spawn "/usr/libexec/xdg-desktop-portal-wlr"
|
|
```
|
|
|
|
(for some reason it does not work when spawned by river during init (process is running, but screensharing attempts lead to nothing),
|
|
but `/usr/libexec/xdg-desktop-portal-wlr &` from shell works fine)
|
|
|
|
### Prevent firefox sharing indicator from taking the entire tile
|
|
|
|
Add the following lines to river config (before the last `exec` line):
|
|
|
|
```
|
|
riverctl float-filter-add title "Firefox — Sharing Indicator"
|
|
riverctl float-filter-add title 'Firefox — Sharing Indicator'
|
|
```
|
|
|
|
(TODO: check which kind of quotes works)
|
|
|
|
## Development (containers)
|
|
|
|
### Unprivileged LXC with routing
|
|
|
|
(based on https://linuxcontainers.org/lxc/getting-started and https://wiki.alpinelinux.org/wiki/LXC)
|
|
|
|
#### Networking (host)
|
|
|
|
(assuming that your internet-connected interface is eth0,
|
|
and that you want to use 10.157.1.0/24 subnet for the container)
|
|
|
|
```
|
|
doas apk add bridge
|
|
doas modprobe dummy
|
|
doas brctl addbr br0
|
|
doas brctl setfd br0 0
|
|
doas brctl addif br0 dummy0
|
|
doas ifconfig br0 10.157.1.1 netmask 255.255.255.0 up
|
|
echo 1 | doas tee -a /proc/sys/net/ipv4/ip_forward
|
|
doas apk add iptables
|
|
doas rc-update add iptables
|
|
doas iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE
|
|
doas iptables --append FORWARD --in-interface br0 -j ACCEPT
|
|
```
|
|
|
|
to persist:
|
|
```
|
|
echo dummy | doas tee -a /etc/modules
|
|
doas /etc/init.d/iptables save
|
|
```
|
|
|
|
#### Containers support
|
|
|
|
```
|
|
doas apk add lxc lxcfs lxc-download xz gnupg
|
|
echo "$(id -un):2000000:65536" | doas tee -a /etc/subuid
|
|
echo "$(id -un):2000000:65536 | doas tee -a /etc/subgid
|
|
echo "$(id -un) veth br0 10" | doas tee -a /etc/lxc/lxc-usernet
|
|
```
|
|
|
|
#### Creating container
|
|
|
|
Create `~/.config/lxc/CONTAINERNAME.conf" with the following content:
|
|
```
|
|
lxc.net.0.type = veth
|
|
lxc.net.0.flags = up
|
|
lxc.net.0.link = br0
|
|
lxc.net.0.ipv4.address = 10.157.1.2/24 10.157.1.255
|
|
lxc.net.0.ipv4.gateway = 10.157.1.1
|
|
lxc.net.0.veth.pair = veth-if-0
|
|
lxc.idmap = u 0 2000000 65536
|
|
lxc.idmap = g 0 2000000 65536
|
|
```
|
|
|
|
Then:
|
|
```
|
|
lxc-create -n CONTAINERNAME -f .config/lxc/CONTAINERNAME.conf -t download
|
|
# pick OS (alpine/edge/amd64 in my case)
|
|
lxc-start -n CONTAINERNAME # make sure it does not produce any errors
|
|
lxc-attach -n CONTAINERNAME
|
|
```
|
|
|
|
You'll get into a container root console.
|
|
|
|
#### Networking (container)
|
|
|
|
In container root console, check if network is up with `ifconfig`.
|
|
If there are no IPv4 address for eth0, you'll have to configure it manually,
|
|
by editing `/etc/network/interfaces` either with VI or with cat/echo.
|
|
|
|
In the end it should look like
|
|
```
|
|
auto eth0
|
|
iface eth0 inet static
|
|
address 10.157.1.2
|
|
netmask 255.255.255.0
|
|
gateway 10.157.1.1
|
|
hostname ........
|
|
```
|
|
|
|
Then `rc-service networking restart`, and check `ifconfig`.
|
|
If everything is right, there should be an ipv4 address in `ifconfig`,
|
|
and `ping 10.157.1.1` inside container and `ping 10.157.1.2` inside host should work.
|
|
|
|
`ping 8.8.8.8` inside container should work too, thanks for routing.
|
|
|
|
Now, if `ping google.com` does not work, configure DNS in container:
|
|
|
|
```
|
|
echo nameserver 8.8.8.8 >> /etc/resolv.conf
|
|
echo nameserver 8.8.4.4 >> /etc/resolv.conf
|
|
```
|
|
|
|
Make sure `ping 8.8.8.8` works.
|
|
APK should work too: `apd add nano neofetch`
|
|
|
|
#### Creating an user inside container
|
|
|
|
In container root shell:
|
|
```
|
|
adduser -g USERNAME USERNAME
|
|
adduser USERNAME wheel
|
|
echo "permit persist :wheel" > /etc/doas.d/doas.conf
|
|
```
|
|
|
|
Now exit root shell (just with `exit`), and try `lxc-console -n CONTAINERNAME`.
|
|
You should be able to log in using the new username and password.
|
|
(To exit lxc console, use Ctrl+A, Q)
|
|
|
|
## TODO
|
|
|
|
* Fix internal mic
|
|
* Docker
|
|
* IDE
|
|
* Notifications
|
|
* Make river usable
|
|
* Make waybar usable (+waybar fonts)
|
|
* nushell + starship instead of ash
|
|
* Mail client
|
|
* Fix call audio in firefox
|
|
* WiFi
|
|
|