Skip to content

Instantly share code, notes, and snippets.

@Ferdi265
Last active May 28, 2025 09:48
Show Gist options
  • Save Ferdi265/d79f879b635c31c0dfdf7cd9dba510e9 to your computer and use it in GitHub Desktop.
Save Ferdi265/d79f879b635c31c0dfdf7cd9dba510e9 to your computer and use it in GitHub Desktop.
Onda Oliver Book A1 -- Getting Arch Linux to Work properly
# /etc/X11/xorg.conf.d/10-monitors.conf
# rotate monitor correctly on X11
Section "Monitor"
Identifier "DSI-1"
Option "Rotate" "right"
EndSection
# rotate touchscreen input correctly on X11
Section "InputClass"
Identifier "Touchscreen DSI-1"
MatchIsTouchscreen "on"
MatchDevicePath "/dev/input/event*"
MatchDriver "libinput"
Option "TransformationMatrix" "0 1 0 -1 0 1 0 0 1"
EndSection
# /etc/X11/xorg.conf.d/20-touchpad.conf
# enable touchpad tapping on X11
Section "InputClass"
Identifier "Touchpad"
MatchIsTouchpad "on"
MatchDevicePath "/dev/input/event*"
Driver "libinput"
Option "Tapping" "on"
EndSection
# /etc/sddm.conf.d/10-virtualkbd.conf
# if you want a virtual keyboard in X11 SDDM
# don't use this if you use Wayland SDDM
[General]
InputMethod=qtvirtualkeyboard
# /etc/sddm.conf.d/10-wayland.conf
# if you want Wayland SDDM
# don't use this if you use X11 SDDM
[General]
DisplayServer=wayland
GreeterEnvironment=QT_WAYLAND_SHELL_INTEGRATION=layer-shell
[Wayland]
CompositorCommand=kwin_wayland --drm --no-lockscreen --no-global-shortcuts --locale1 --inputmethod maliit-keyboard
# /etc/udev/hwdb.d/70-accelerometer.hwdb
# needs package iio-sensor-proxy
sensor:modalias:acpi:KIOX0009*:dmi:*:svnOndaTLCGmbH:pnOliverBookA1:*
ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
# /etc/udev/rules.d/70-touchscreen.rules
# calibration matrix for touchscreen to scale it to the whole screen and fix orientation
ACTION=="add", SUBSYSTEM=="input", ENV{ID_PATH}=="pci-0000:00:17.2-platform-i2c_designware-3", ENV{LIBINPUT_CALIBRATION_MATRIX}="0 2.7 0 2.1 0 0"
# /etc/systemd/system/fix-mode.service
# fix graphical glitches at boot; resetting the CRTC makes the next modeset work
[Unit]
Description=Fix DRM Mode
DefaultDependencies=no
[email protected]
Before=sddm.service
Before=plymouth-start.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/yeet DSI-1
[Install]
WantedBy=multi-user.target
# /etc/default/grub
# quiet splash ... enable plymouth boot screen
# video ... rotate the panel on plymouth/wayland
# fbcon ... rotate the panel on tty
# i915.modeset ... disable modesetting, for initial install to set things up
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash video=DSI-1:panel_orientation=right_side_up fbcon=rotate:1"
#GRUB_CMDLINE_LINUX_DEFAULT="i915.modeset=0 fbcon=rotate:1"
# /var/lib/sddm/.config/kcminputrc
# copy over from ~/.config/kcminputrc after configuring
# /usr/lib/firmware/silead/mssl1680.fw
# copy over from https://github.com/Ferdi265/gsl-firmware at firmware/linux/silead/gsl1680-onda-oliver-book.fw
// /usr/local/bin/yeet
// needs package libdrm
// compile with gcc -Os -ldrm -I/usr/include/libdrm/ -o yeet yeet.c
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <sys/ioctl.h>
#include <linux/kd.h>
uint64_t get_property_value(int drm_fd, uint32_t object_id,
uint32_t object_type, const char *prop_name) {
drmModeObjectProperties *props =
drmModeObjectGetProperties(drm_fd, object_id, object_type);
for (uint32_t i = 0; i < props->count_props; i++) {
drmModePropertyRes *prop = drmModeGetProperty(drm_fd, props->props[i]);
uint64_t val = props->prop_values[i];
if (strcmp(prop->name, prop_name) == 0) {
drmModeFreeProperty(prop);
drmModeFreeObjectProperties(props);
return val;
}
drmModeFreeProperty(prop);
}
printf("Failed to find property %s\n", prop_name);
exit(1);
}
void add_property(int drm_fd, drmModeAtomicReq *req, uint32_t object_id,
uint32_t object_type, const char *prop_name, uint64_t value) {
uint32_t prop_id = 0;
drmModeObjectProperties *props =
drmModeObjectGetProperties(drm_fd, object_id, object_type);
for (uint32_t i = 0; i < props->count_props; i++) {
drmModePropertyRes *prop = drmModeGetProperty(drm_fd, props->props[i]);
if (strcmp(prop->name, prop_name) == 0) {
prop_id = prop->prop_id;
break;
}
}
if (prop_id == 0) {
printf("Failed to find property %s\n", prop_name);
exit(1);
}
drmModeAtomicAddProperty(req, object_id, prop_id, value);
}
char * get_connector_name(drmModeConnector *conn) {
const char *type_name = drmModeGetConnectorTypeName(conn->connector_type);
if (type_name == NULL) return NULL;
char *str = NULL;
asprintf(&str, "%s-%d", type_name, conn->connector_type_id);
return str;
}
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("usage: yeet <CONNECTOR>\n");
return 1;
}
char *conn_name = argv[1];
printf("Opening DRM fd\n");
int drm_fd = open("/dev/dri/card1", O_RDWR | O_NONBLOCK);
if (drm_fd < 0) {
perror("open failed");
return 1;
}
if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) != 0) {
perror("drmSetClientCap(UNIVERSAL_PLANES) failed");
return 1;
}
if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1) != 0) {
perror("drmSetClientCap(ATOMIC) failed");
return 1;
}
printf("Finding connector %s\n", conn_name);
drmModeRes *resources = drmModeGetResources(drm_fd);
drmModeConnector *conn = NULL;
drmModeCrtc *crtc = NULL;
for (int i = 0; i < resources->count_connectors; i++) {
uint32_t conn_id = resources->connectors[i];
conn = drmModeGetConnector(drm_fd, conn_id);
if (conn->connection != DRM_MODE_CONNECTED) {
drmModeFreeConnector(conn);
conn = NULL;
continue;
}
char *name = get_connector_name(conn);
if (name == NULL || strcmp(name, conn_name) != 0) {
free(name);
drmModeFreeConnector(conn);
conn = NULL;
continue;
}
uint64_t crtc_id = get_property_value(drm_fd, conn_id, DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID");
crtc = drmModeGetCrtc(drm_fd, crtc_id);
if (crtc == NULL) {
printf("Connector %s has no CRTC\n", name);
free(name);
drmModeFreeConnector(conn);
conn = NULL;
return 1;
}
printf("Connector %s has CRTC %zd\n", name, crtc_id);
free(name);
break;
}
drmModeFreeResources(resources);
// Yeet the CRTC
printf("Yeeting the CRTC\n");
drmModeAtomicReq *req = drmModeAtomicAlloc();
add_property(drm_fd, req, conn->connector_id, DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID", 0);
add_property(drm_fd, req, crtc->crtc_id, DRM_MODE_OBJECT_CRTC, "MODE_ID", 0);
add_property(drm_fd, req, crtc->crtc_id, DRM_MODE_OBJECT_CRTC, "ACTIVE", 0);
uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
int ret = drmModeAtomicCommit(drm_fd, req, flags, NULL);
if (ret != 0) {
printf("Failed to yeet the CRTC\n");
return 1;
}
printf("Restoring text mode\n");
int fd = open("/dev/tty", O_RDWR | O_NOCTTY);
ioctl(fd, KDSETMODE, KD_TEXT);
return 0;
}
@Ferdi265
Copy link
Author

Ferdi265 commented Oct 2, 2023

The race condition in fix-mode can be fixed by adding this patch to seatd. The issue is that seatd doesn't start up fast enough and doesn't notify systemd that it is running, leading to fix-mode not finding a seat.

The use of sway in fix-mode can also be replaced with a stripped-down version of the simple example program from wlroots that doesn't render anything and exits once it renders its first frame. This can likely be stripped down even more.

@Ferdi265
Copy link
Author

Ferdi265 commented Oct 2, 2023

Race condition and dependencies fixed in latest version. Now only needs a simple C program (yeet) and libdrm.

@Ferdi265
Copy link
Author

Ferdi265 commented Oct 5, 2023

Added Accelerometer transformation Matrix

@gborzi22
Copy link

Thank you very much for this page. I recently bought one Oliver Book A1 on aliexpress and using your information I've installed Arch on it. Now sound and the accelerometer work out of the box. Strangely the touchscreen doesn't work with your firmware, I extracted the firmware from the windows driver and it worked.

Thanks again.

@Ferdi265
Copy link
Author

Ferdi265 commented Jan 21, 2025

Thank you very much for this page. I recently bought one Oliver Book A1 on aliexpress and using your information I've installed Arch on it. Now sound and the accelerometer work out of the box. Strangely the touchscreen doesn't work with your firmware, I extracted the firmware from the windows driver and it worked.

Thanks again.

I'm glad the configs help!

Nice to see that sound now works. I had put the Oliver book aside because of the sound issues, great to know that it works now, might even use it now.

Is the fix-mode / yeet libdrm CRTC hack still necessary? I haven't checked since a few kernel revisions.

The touchscreen firmware I also got from a windows driver, but maybe something changed over the last year, I'm also no longer sure exactly what I did, nice to see you got a working driver now.

@gborzi22
Copy link

Yes, yeet is still needed. Since I use lightdm+xfce I modified fix-mode to call yeet after lightdm. It is possible that on newer models some hardware component has been changed.

@syntaxbender
Copy link

syntaxbender commented Jan 24, 2025

thanks a lot for this work, looks amazing! im trying to debug yeet.c in kubuntu 22.04. i have output like this in journalctl:


Oca 24 23:08:11 tiny-pc yeet[305]: Finding connector DSI-1

Oca 24 23:08:11 tiny-pc yeet[305]: Connector DSI-1 has CRTC 68

Oca 24 23:08:11 tiny-pc yeet[305]: Yeeting the CRTC

Oca 24 23:08:11 tiny-pc yeet[305]: Debug Info:

Oca 24 23:08:11 tiny-pc yeet[305]:   drm_fd: 3

Oca 24 23:08:11 tiny-pc yeet[305]:   flags: 0x400

Oca 24 23:08:11 tiny-pc yeet[305]:   Connector ID: 165

Oca 24 23:08:11 tiny-pc yeet[305]:   CRTC ID: 68

Oca 24 23:08:11 tiny-pc yeet[305]:   Request Properties Count: 3

Oca 24 23:08:11 tiny-pc yeet[305]: Failed to yeet the CRTC (errno: 13)

do you have any idea for fix?i hate windows haha, i need to fix this bug.

@gborzi22
Copy link

@syntaxbender
You may try using sway, as Ferdi265 describes here: https://askubuntu.com/questions/1456462/onda-oliver-book-ubuntu-lines-on-screen. It worked on my A1.

@Ferdi265
Copy link
Author

Ferdi265 commented Jan 24, 2025

thanks a lot for this work, looks amazing! im trying to debug yeet.c in kubuntu 22.04. i have output like this in journalctl:


Oca 24 23:08:11 tiny-pc yeet[305]: Finding connector DSI-1

Oca 24 23:08:11 tiny-pc yeet[305]: Connector DSI-1 has CRTC 68

Oca 24 23:08:11 tiny-pc yeet[305]: Yeeting the CRTC

Oca 24 23:08:11 tiny-pc yeet[305]: Debug Info:

Oca 24 23:08:11 tiny-pc yeet[305]:   drm_fd: 3

Oca 24 23:08:11 tiny-pc yeet[305]:   flags: 0x400

Oca 24 23:08:11 tiny-pc yeet[305]:   Connector ID: 165

Oca 24 23:08:11 tiny-pc yeet[305]:   CRTC ID: 68

Oca 24 23:08:11 tiny-pc yeet[305]:   Request Properties Count: 3

Oca 24 23:08:11 tiny-pc yeet[305]: Failed to yeet the CRTC (errno: 13)

do you have any idea for fix?i hate windows haha, i need to fix this bug.

Errno 13 is EPERM, aka permission denied.

yeet needs to run as root, and only works if no other application uses that DRM device already, that means on a raw tty, before plymouth, sddm, or wayland/X11.

If you run yeet via the fix-mode.service above, double-check that the getty / sddm / plymouth services on Ubuntu are named the same way as they are in the service file (that file was made for the Arch Linux service names). Otherwise you might get race conditions and a conflicting service could start before yeet does.

It might also be that on Ubuntu you need /dev/dri/card0 instead of /dev/dri/card1, (which one it is depends on whether your distro uses simpledrm before loading the i915 graphics driver, I'm not sure if Ubuntu does that).

@Ferdi265
Copy link
Author

Ferdi265 commented Jan 24, 2025

I just updated my own Arch Linux system on the Oliver book, and it seems the yeet hack is less reliable than it was previously: It's not enough any more to have it start before SDDM. Manually switching to tty2, logging in as root, and running yeet, then switching back to tty1 fixes the screen, but automatically starting it before SDDM no longer works (yeet claims no errors, but the screen stays broken).

The touchpad also doesn't work until the keyboard attachment is disconnected/reconnected once, something that wasn't like this before the update. Sound still doesn't work,.

I'll see if I can make this work again.

@gborzi22
Copy link

@Ferdi265 In fact I had to modify fix-mode to start after lightdm. As for sound, alsamixer reports sof-essx8336 on my system it worked once I installed sof-firmware.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment