User:Keks24/drafts/Non root Xorg
To-do
- Fighting for Schmusis (most likely) intentionally failed operation
- general
- user sticky (4711) bit on "/usr/bin/Xorg" has still to be set to make an autologin via openrc work or is it just "/dev/tty7"?
- Automatic_login_to_virtual_console
- .zprofile autologin
Current version of pixman: 0.40.0 Before reporting problems, check http://wiki.x.org to make sure that you have the latest version. Markers: (--) probed, (**) from config file, (==) default setting, (++) from command line, (!!) notice, (II) informational, (WW) warning, (EE) error, (NI) not implemented, (??) unknown. (==) Log file: "/home/ramon/.local/share/xorg/Xorg.0.log", Time: Tue Jul 28 06:15:41 2020 (==) Using config directory: "/etc/X11/xorg.conf.d" (==) Using system config directory "/usr/share/X11/xorg.conf.d" (II) [KMS] Kernel modesetting enabled. Unable to retrieve master (EE) Fatal server error: (EE) AddScreen/ScreenInit failed for driver 0 (EE) (EE) Please consult the The X.Org Foundation support at http://wiki.x.org for help. (EE) Please also check the log file at "/home/ramon/.local/share/xorg/Xorg.0.log" for additional information. (EE) (EE) Server terminated with error (1). Closing log file. xinit: giving up xinit: unable to connect to X server: Connection refused xinit: server error
- test non-root without any patches
- look for error messages
- test
amdgpu
patch with Plasma - drm_master_util-9999.ebuild
- make postinst work
- user sticky (4711) bit on "/usr/bin/Xorg" has still to be set to make an autologin via openrc work or is it just "/dev/tty7"?
- wiki article
- instead of referencing to the forum, upload the files to the wiki to make them persistent
- upload evidences about publishing the diff files under GPLv2 and reference to them
- adapt new references
- message
- kajzer: When the wiki article is done, so he can remove his repository
- ch1p: When the wiki article is done. Just because and that's why.
- Ask for permissions to upload below diff files and evidence files about publishing under GPLv2
For discussion page
== Non_root_Xorg ==
{{Talk|open|date=27 July 2020}}
Hello <some_username>,
I am currently working on [[Non_root_Xorg#Handling_of_DRM_ioctls]] and I would like to persist the diff files on the article, instead of only referncing to them.
I do not want to blow up the article, therefore I was about to upload them here, but I am only allowed to upload picture files.
Could you please give the permissions to upload the files?
Thank you!
[[User:Keks24/drafts/Non_root_Xorg#Files|My current draft]]
PS. I also would like to upload and reference to the evidences from Evgeny "ch1p" Zinoviev and "kajzersoze", that they agreed to publish their work under "GPLv2".
~~~~
author tree
- rootless_modesetting_1.20.3.patch: Evgeny "ch1p" Zinoviev, license: GPL2 (see e-mail history)
- adapted from modesetting
- amdgpu-non-root.diff: "GitHub: kajzersoze", license: GPL2 (see private forum message)
- radeon-non-root.diff: "GitHub: kajzersoze", license: GPL2 (see private forum message)
- adapted from modesetting
- new patch names
- rootless_modesetting_1.20.3.patch -> xorg-server-non-root-modesetting-1.20.4.diff
- amdgpu-non-root.diff -> amdgpu-non-root-drm_19.1.0.diff
- radeon-non-root.diff -> radeon-non-root-drm_19.1.0.diff
Actual wiki article
https://wiki.gentoo.org/wiki/Non_root_Xorg
Handling of DRM ioctls
No management of group membership can grant the CAP_SYS_ADMIN
capability needed to perform the DRM ioctls. However, a simple program named drm_master_util has been made available in GitHub[1], which must be installed with the set-user-ID on execution file mode bit set (i.e. ls -l would show -rwsr-xr-x
or -rws--x--x
), and can perform ioctl()
calls on behalf of other processes, with the help of libdrm (from package x11-libs/libdrm). The program gets open file descriptors for character special files from a UNIX domain socket via file descriptor passing (SCM_RIGHTS
control messages sent as ancillary data with a POSIX sendmsg()
call), and command-line options specify the requested ioctl. Several ebuilds suitable for a custom repository are available for the package in the Gentoo Forums[2]
Patches are available[3][4] for making the modesetting, amdgpu and ati X.Org video drivers work with drm_master_util. The ebuilds for their corresponding packages (x11-base/xorg-server, x11-drivers/xf86-video-amdgpu and x11-drivers/xf86-video-ati, respectively) can apply them as user patches in the usual way.
Use custom ebuild repository
- Display ebuild file in a filebox
- Use a more recent ebuid. Reference to gentoo overlay??. Use at your own risk: https://codeberg.org/keks24/gentoo-overlay
- Reference to forum posts
- file upload should be considered as latest version
- ebuild: https://forums.gentoo.org/viewtopic-t-1092792-postdays-0-postorder-asc-start-75.html#8478520
modesetting
: https://forums.gentoo.org/viewtopic-p-8329654.html#8329654x11-drivers/xf86-video-amdgpu
: https://forums.gentoo.org/viewtopic-p-8376782.html#8376782x11-drivers/xf86-video-ati
: https://forums.gentoo.org/viewtopic-p-8448466.html#8448466
- Instructions to add the overlay manually?
- Mask all packages /etc/portage/package.mask
- Unmask wanted packages. Research: Has an alternative been implemented yet?
- Add entry in /etc/portage/package.accept_keywords
# custom - 20200726 - rfischer: unmask "x11-misc/drm_master_util", in order to use "x11-base/xorg-server" without root privileges >=x11-misc/drm_master_util-9999 ~amd64
[keks24] location = /var/db/repos/keks24-overlay sync-type = git sync-uri = https://codeberg.org/keks24/gentoo-overlay.git auto-sync = yes
- emerge --sync / eix-sync
- emerge --ask x11-misc/drm_master_util
Apply patch files
- Only apply the patch file for the video driver, which is currently in use
- Upload and reference evidence about the agreement to apply GPL2 to patch files
Modesetting: x11-base/xorg-server
- Instructions to apply the patch files
- Put download link here
AMDGPU: x11-drivers/xf86-video-amdgpu
- Instructions to apply the patch files
- Put download link here
Radeon: x11-drivers/xf86-video-ati
- Instructions to apply the patch files
- Put download link here
Verification
- Read and get debugging information
- startx output
- /home/username/.local/share/xorg/Xorg.0.log
Files
ebuild: drm_master_util-9999.ebuild
/var/db/repos/localrepo/x11-misc/drm_master_util/drm_master_util-9999.ebuild
Modesetting: x11-base/xorg-server
https://ch1p.io/non-root-xorg-modesetting/
###################################################################################
# Copyright (C) 2020 Evgeny "ch1p" Zinoviev #
# #
# This program is free software; you can redistribute it and/or #
# modify it under the terms of the GNU General Public License #
# as published by the Free Software Foundation; either version 2 #
# of the License, or (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program; if not, write to the Free Software #
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #
###################################################################################
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 8d29b13..1034ef9 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -34,6 +34,11 @@
#endif
#include <unistd.h>
+#include <stdio.h>
+#include <sys/wait.h>
+#include <pthread.h>
+#include <sys/socket.h>
+#include <sys/un.h>
#include <fcntl.h>
#include "xf86.h"
#include "xf86Priv.h"
@@ -62,6 +67,8 @@
#include "driver.h"
+#define DRM_HACK_SOCKET_NAME "xorg_drm_master_util"
+
static void AdjustFrame(ScrnInfoPtr pScrn, int x, int y);
static Bool CloseScreen(ScreenPtr pScreen);
static Bool EnterVT(ScrnInfoPtr pScrn);
@@ -1513,11 +1520,66 @@ msSharedPixmapNotifyDamage(PixmapPtr ppix)
return ret;
}
+static int
+send_fd(int sock, int fd)
+{
+ // This function does the arcane magic for sending
+ // file descriptors over unix domain sockets
+ struct msghdr msg;
+ struct iovec iov[1];
+ struct cmsghdr *cmsg = NULL;
+ char ctrl_buf[CMSG_SPACE(sizeof(int))];
+ char data[1];
+
+ memset(&msg, 0, sizeof(struct msghdr));
+ memset(ctrl_buf, 0, CMSG_SPACE(sizeof(int)));
+
+ data[0] = ' ';
+ iov[0].iov_base = data;
+ iov[0].iov_len = sizeof(data);
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_controllen = CMSG_SPACE(sizeof(int));
+ msg.msg_control = ctrl_buf;
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+
+ *((int *) CMSG_DATA(cmsg)) = fd;
+
+ return sendmsg(sock, &msg, 0);
+}
+
+static void*
+thread_func(void* argument)
+{
+ int ret;
+ int option = *(int *)argument;
+ char cmd[32];
+ sprintf(cmd, "/usr/bin/drm_master_util %s -r", (!option ? "-s" : "-d"));
+
+ ret = system(cmd);
+ if (ret == -1 || WEXITSTATUS(ret) != 0) {
+ fprintf(stderr, "%s\n", strerror(errno));
+ //exit(1);
+ }
+
+ pthread_exit(NULL); // you could also return NULL here to exit no difference
+}
+
static Bool
SetMaster(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
- int ret;
+ int ret = 0;
+ pthread_t my_thread;
+ struct sockaddr_un addr;
+ int sock, conn, option = 0;
#ifdef XF86_PDEV_SERVER_FD
if (ms->pEnt->location.type == BUS_PLATFORM &&
@@ -1528,10 +1590,21 @@ SetMaster(ScrnInfoPtr pScrn)
if (ms->fd_passed)
return TRUE;
- ret = drmSetMaster(ms->fd);
- if (ret)
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "drmSetMaster failed: %s\n",
- strerror(errno));
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strcpy(&addr.sun_path[1], DRM_HACK_SOCKET_NAME);
+ bind(sock, (struct sockaddr *)&addr, sizeof(addr));
+
+ listen(sock, 1);
+ pthread_create(&my_thread, NULL, thread_func, &option);
+
+ conn = accept(sock, NULL, 0);
+ send_fd(conn, ms->fd);
+ close(conn);
+ close(sock);
+
+ pthread_join(my_thread, NULL);
return ret == 0;
}
@@ -1769,6 +1842,9 @@ static void
LeaveVT(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
+ pthread_t my_thread;
+ struct sockaddr_un addr;
+ int sock, conn, option = 1;
xf86_hide_cursors(pScrn);
@@ -1780,8 +1856,21 @@ LeaveVT(ScrnInfoPtr pScrn)
return;
#endif
- if (!ms->fd_passed)
- drmDropMaster(ms->fd);
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strcpy(&addr.sun_path[1], DRM_HACK_SOCKET_NAME);
+ bind(sock, (struct sockaddr *)&addr, sizeof(addr));
+
+ listen(sock, 1);
+ pthread_create(&my_thread, NULL, thread_func, &option);
+
+ conn = accept(sock, NULL, 0);
+ send_fd(conn, ms->fd);
+ close(conn);
+ close(sock);
+
+ pthread_join(my_thread, NULL);
}
/*
AMDGPU: x11-drivers/xf86-video-amdgpu
https://github.com/kajzersoze/patches/blob/master/amdgpu-nonroot.diff
###################################################################################
# Copyright (C) 2020 Evgeny "ch1p" Zinoviev, "kajzersoze" #
# #
# This program is free software; you can redistribute it and/or #
# modify it under the terms of the GNU General Public License #
# as published by the Free Software Foundation; either version 2 #
# of the License, or (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program; if not, write to the Free Software #
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #
###################################################################################
--- a/src/amdgpu_kms.c 2019-03-19 18:49:55.000000000 +0100
+++ b/src/amdgpu_kms.c 2019-10-06 18:44:29.338375483 +0200
@@ -24,6 +24,13 @@
* Dave Airlie <airlied@redhat.com>
*
*/
+#include <stdio.h>
+#include <sys/wait.h>
+#include <pthread.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#define DRM_HACK_SOCKET_NAME "xorg_drm_master_util"
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -62,6 +69,59 @@
#include <gbm.h>
+static int
+send_fd(int sock, int fd)
+{
+ // This function does the arcane magic for sending
+ // file descriptors over unix domain sockets
+ struct msghdr msg;
+ struct iovec iov[1];
+ struct cmsghdr *cmsg = NULL;
+ char ctrl_buf[CMSG_SPACE(sizeof(int))];
+ char data[1];
+
+ memset(&msg, 0, sizeof(struct msghdr));
+ memset(ctrl_buf, 0, CMSG_SPACE(sizeof(int)));
+
+ data[0] = ' ';
+ iov[0].iov_base = data;
+ iov[0].iov_len = sizeof(data);
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_controllen = CMSG_SPACE(sizeof(int));
+ msg.msg_control = ctrl_buf;
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+
+ *((int *) CMSG_DATA(cmsg)) = fd;
+
+ return sendmsg(sock, &msg, 0);
+}
+
+static void*
+thread_func(void* argument)
+{
+ int ret;
+ int option = *(int *)argument;
+ char cmd[32];
+ sprintf(cmd, "/usr/bin/drm_master_util %s -r", (!option ? "-s" : "-d"));
+
+ ret = system(cmd);
+ if (ret == -1 || WEXITSTATUS(ret) != 0) {
+ fprintf(stderr, "%s\n", strerror(errno));
+ //exit(1);
+ }
+
+ pthread_exit(NULL); // you could also return NULL here to exit no difference
+}
+
+
static DevPrivateKeyRec amdgpu_window_private_key;
static DevScreenPrivateKeyRec amdgpu_client_private_key;
DevScreenPrivateKeyRec amdgpu_device_private_key;
@@ -1820,7 +1880,12 @@
static Bool amdgpu_set_drm_master(ScrnInfoPtr pScrn)
{
AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
- int err;
+ int err = 0;
+ pthread_t my_thread;
+ struct sockaddr_un addr;
+ int sock, conn, option = 0;
+
+
#ifdef XF86_PDEV_SERVER_FD
if (pAMDGPUEnt->platform_dev &&
@@ -1828,9 +1893,21 @@
return TRUE;
#endif
- err = drmSetMaster(pAMDGPUEnt->fd);
- if (err)
- ErrorF("Unable to retrieve master\n");
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strcpy(&addr.sun_path[1], DRM_HACK_SOCKET_NAME);
+ bind(sock, (struct sockaddr *)&addr, sizeof(addr));
+
+ listen(sock, 1);
+ pthread_create(&my_thread, NULL, thread_func, &option);
+
+ conn = accept(sock, NULL, 0);
+ send_fd(conn, pAMDGPUEnt->fd);
+ close(conn);
+ close(sock);
+
+ pthread_join(my_thread, NULL);
return err == 0;
}
@@ -1838,6 +1915,10 @@
static void amdgpu_drop_drm_master(ScrnInfoPtr pScrn)
{
AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
+ pthread_t my_thread;
+ struct sockaddr_un addr;
+ int sock, conn, option = 1;
+
#ifdef XF86_PDEV_SERVER_FD
if (pAMDGPUEnt->platform_dev &&
@@ -1845,7 +1926,23 @@
return;
#endif
- drmDropMaster(pAMDGPUEnt->fd);
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strcpy(&addr.sun_path[1], DRM_HACK_SOCKET_NAME);
+ bind(sock, (struct sockaddr *)&addr, sizeof(addr));
+
+ listen(sock, 1);
+ pthread_create(&my_thread, NULL, thread_func, &option);
+
+ conn = accept(sock, NULL, 0);
+ send_fd(conn, pAMDGPUEnt->fd);
+ close(conn);
+ close(sock);
+
+ pthread_join(my_thread, NULL);
+
+
}
Radeon: x11-drivers/xf86-video-ati
https://github.com/kajzersoze/patches/blob/master/radeon-nonroot.diff
###################################################################################
# Copyright (C) 2020 Evgeny "ch1p" Zinoviev, "kajzersoze" #
# #
# This program is free software; you can redistribute it and/or #
# modify it under the terms of the GNU General Public License #
# as published by the Free Software Foundation; either version 2 #
# of the License, or (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program; if not, write to the Free Software #
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #
###################################################################################
--- a/src/radeon_kms.c 2020-04-24 12:56:35.767706045 +0200
+++ b/src/radeon_kms.c 2020-04-24 14:47:37.049171521 +0200
@@ -24,6 +24,13 @@
* Dave Airlie <airlied@redhat.com>
*
*/
+#include <stdio.h>
+#include <sys/wait.h>
+#include <pthread.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#define DRM_HACK_SOCKET_NAME "xorg_drm_master_util"
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -66,6 +73,60 @@
#include "radeon_cs_gem.h"
#include "radeon_vbo.h"
+static int
+send_fd(int sock, int fd)
+{
+ // This function does the arcane magic for sending
+ // file descriptors over unix domain sockets
+ struct msghdr msg;
+ struct iovec iov[1];
+ struct cmsghdr *cmsg = NULL;
+ char ctrl_buf[CMSG_SPACE(sizeof(int))];
+ char data[1];
+
+ memset(&msg, 0, sizeof(struct msghdr));
+ memset(ctrl_buf, 0, CMSG_SPACE(sizeof(int)));
+
+ data[0] = ' ';
+ iov[0].iov_base = data;
+ iov[0].iov_len = sizeof(data);
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_controllen = CMSG_SPACE(sizeof(int));
+ msg.msg_control = ctrl_buf;
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+
+ *((int *) CMSG_DATA(cmsg)) = fd;
+
+ return sendmsg(sock, &msg, 0);
+}
+
+static void*
+thread_func(void* argument)
+{
+ int ret;
+ int option = *(int *)argument;
+ char cmd[32];
+ sprintf(cmd, "/usr/bin/drm_master_util %s -r", (!option ? "-s" : "-d"));
+
+ ret = system(cmd);
+ if (ret == -1 || WEXITSTATUS(ret) != 0) {
+ fprintf(stderr, "%s\n", strerror(errno));
+ //exit(1);
+ }
+
+ pthread_exit(NULL); // you could also return NULL here to exit no difference
+}
+
+
+
static DevScreenPrivateKeyRec radeon_client_private_key;
DevScreenPrivateKeyRec radeon_device_private_key;
@@ -2160,7 +2221,10 @@
static Bool radeon_set_drm_master(ScrnInfoPtr pScrn)
{
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- int err;
+ int err = 0;
+ pthread_t my_thread;
+ struct sockaddr_un addr;
+ int sock, conn, option = 0;
#ifdef XF86_PDEV_SERVER_FD
if (pRADEONEnt->platform_dev &&
@@ -2168,9 +2232,21 @@
return TRUE;
#endif
- err = drmSetMaster(pRADEONEnt->fd);
- if (err)
- ErrorF("Unable to retrieve master\n");
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strcpy(&addr.sun_path[1], DRM_HACK_SOCKET_NAME);
+ bind(sock, (struct sockaddr *)&addr, sizeof(addr));
+
+ listen(sock, 1);
+ pthread_create(&my_thread, NULL, thread_func, &option);
+
+ conn = accept(sock, NULL, 0);
+ send_fd(conn, pRADEONEnt->fd);
+ close(conn);
+ close(sock);
+
+ pthread_join(my_thread, NULL);
return err == 0;
}
@@ -2178,6 +2254,9 @@
static void radeon_drop_drm_master(ScrnInfoPtr pScrn)
{
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+ pthread_t my_thread;
+ struct sockaddr_un addr;
+ int sock, conn, option = 1;
#ifdef XF86_PDEV_SERVER_FD
if (pRADEONEnt->platform_dev &&
@@ -2185,7 +2264,21 @@
return;
#endif
- drmDropMaster(pRADEONEnt->fd);
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strcpy(&addr.sun_path[1], DRM_HACK_SOCKET_NAME);
+ bind(sock, (struct sockaddr *)&addr, sizeof(addr));
+
+ listen(sock, 1);
+ pthread_create(&my_thread, NULL, thread_func, &option);
+
+ conn = accept(sock, NULL, 0);
+ send_fd(conn, pRADEONEnt->fd);
+ close(conn);
+ close(sock);
+
+ pthread_join(my_thread, NULL);
}
/* Called at the end of each server generation. Restore the original
References and stuff
- ↑ Git repository of drm_master_util at GitHub. Retrieved on July 17th, 2020.
- ↑ Gentoo Forums thread "Non root Xorg on AMD video cards", starting from page 4. Retrieved on July 17th, 2020.
- ↑ Gentoo Forums thread "Non root Xorg on AMD video cards", post #8329654 (for the modesetting driver) and post #8376782 (for the amdgpu driver). Retrieved on July 17th, 2020.
- ↑ Gentoo Forums thread "Unable to start X as user without dbus, elogind..", post #8448466 (ati driver). Retrieved on July 17th, 2020.