In this post I will provide an overview of the steps required to build a PXE-enabled RDP client using Thinstation.
Overview
Thinstation is an open source thin client-solution based on Crux Linux. The framework can be used to build streamlined network-bootable images that support a range of connectivity options, such as Microsoft RDP, Citrix ICA, and VMware View.
In this post I will describe how to configure two thin-client images. The first image will allow users to establish a Remote Desktop session to a Windows Server using the FreeRDP client. The second image will allow users to launch individual applications published using RemoteApp (also served via a FreeRDP client). The applications will be accessed via a Remote Desktop Web Access Portal using Google Chrome running in "kiosk" mode.
Requirements
The scenarios presented in this article require the following:
- A server with the Windows Deployment Services (WDS) and IIS features enabled (where the WDS root folder is
C:\RemoteInstall
and the IIS document root isC:\Inetpub\wwwroot
).
As an alternative to (standalone) WDS, you could also use a PXE-enabled Microsoft SCCM distribution point, a dedicated deployment of PXELINUX, or some other PXE service provider. You can also switch out IIS for another web server if you prefer.
Note: If you use a PXE-enabled distribution point, ensure that you don't enable unknown computer support, as this will prevent SCCM from passing all PXE requests through to WDS (even when using DHCP option 67 to target a specific boot program).
A DHCP server (including the ability to create DHCP reservations and configure scope/client options).
A hypervisor that can be used for running a virtual Linux client (I will use VMware Fusion).
A computer that will be used as the thin-client workstation.
A functional Remote Desktop Server farm (required for testing the second thin-client image).
Windows Deployment Services
Even though we are using WDS, we still require access to components of PXELINUX to support the network boot of a Linux image. The relevant files can be obtained via syslinux. We will use version 4.07 (as external dependencies are required with later releases).
Extract the syslinux package to C:\syslinux-4.07
on the WDS server, and perform these steps:
Copy the following files to
C:\RemoteInstall\Boot\x64
:C:\syslinux-4.07\core\pxelinux.0
C:\syslinux-4.07\com32\menu\vesamenu.c32
C:\syslinux-4.07\com32\chain\chain.c32
C:\syslinux-4.07\memdisk\memdisk
- Rename
C:\RemoteInstall\Boot\x64\pxelinux.0
topxelinux.com
. - Copy
C:\RemoteInstall\Boot\x64\abortpxe.com
toabortpxe.0
. - Copy
C:\RemoteInstall\Boot\x64\pxeboot.n12
topxeboot.0
. - Repeat the above steps, replacing all references to x64 with x86.
- Create a folder named
C:\RemoteInstall\Boot\pxelinux.cfg
(yes, it is a folder). - From an elevated command prompt, change into
C:\RemoteInstall\Boot\x64
and create a junction:mklink /J pxelinux.cfg C:\RemoteInstall\Boot\pxelinux.cfg
- Repeat the previous step from
C:\RemoteInstall\Boot\x86
. - Create a folder named
C:\RemoteInstall\Images\Linux
. - From an elevated command prompt, change into
C:\RemoteInstall\Boot\x64
and create a junction:mklink /J Linux C:\RemoteInstall\Images\Linux
- Repeat the previous step from
C:\RemoteInstall\Boot\x86
. Create a file named default under
C:\RemoteInstall\Boot\pxelinux.cfg
and add the following content:DEFAULT RDP PROMPT 0 NOESCAPE 1 ALLOWOPTIONS 0 LABEL RDP MENU DEFAULT KERNEL /Linux/vmlinuz APPEND initrd=/Linux/initrd splash=silent,theme:default load_ramdisk=1 ramdisk_blocksize=4096 root=/dev/ram0 ramdisk_size=786432 loglevel=3 console=tty1 vt.global_cursor_default=0 LM=3
To switch the default boot programs used by WDS to PXELINUX, you could run the following commands from an elevated command prompt on the WDS server:
wdsutil /set-server /bootprogram:boot\x86\pxelinux.com /architecture:x86
wdsutil /set-server /N12bootprogram:boot\x86\pxelinux.com /architecture:x86
wdsutil /set-server /bootprogram:boot\x64\pxelinux.com /architecture:x64
wdsutil /set-server /N12bootprogram:boot\x64\pxelinux.com /architecture:x64
This step isn't required if you are using a PXE-enabled distribution point, as SCCM takes over WDS and ignores the natively configured settings. Nor is the step required if you will use DHCP options 66 and 67 to specifically direct a client to use the PXELINUX boot program (more on this later).
Note: The following commands will restore the default WDS boot programs (in case you need to roll back):
wdsutil /set-server /bootprogram:boot\x86\pxeboot.com /architecture:x86
wdsutil /set-server /N12bootprogram:boot\x86\pxeboot.n12 /architecture:x86
wdsutil /set-server /bootprogram:boot\x64\pxeboot.com /architecture:x64
wdsutil /set-server /N12bootprogram:boot\x64\pxeboot.n12 /architecture:x64
Build Environment
The next step is to configure the environment we will use for creating our thin-client image. Fortunately, Thinstation comes with a pre-configured build environment called DevStation (direct download of approx. 180MB).
Note: The notes in this article were based on DevStation 5.4.2.
I created a virtual machine on my Mac using VMware Fusion for hosting DevStation. I used an x64 Linux 2.6.x operating system profile with the following specifications: 2 cores, 2GB RAM, and a 20GB disk. You can of course achieve the same effect with another hypervisor, such as VirtualBox, VMware Workstation or Hyper-V.
After booting the virtual machine from the downloaded media, follow these steps to install DevStation (internet access is required):
- Acknowledge the installation notes.
- Agree to use disk
/dev/sda
. - Set a timezone. I used Australia/Sydney.
- Set a locale. I used en_US.
- Agree to erasing the disk.
- Wait until the installation is completed (approx. 20 minutes).
- Acknowledge the post-installation notes.
After rebooting the virtual machine (you will be logged in automatically), double-click the Terminal Chroot shortcut on the desktop and then change into the /build
directory.
At this point we are ready to create a custom thin-client image.
Device Drivers
The first step is to identify the device drivers required by our target platform (i.e. the system that will run the thin-client). In the context of this article, I will assume the client is a Hyper-V virtual machine, but in practice, you would probably use a lightweight desktop or thin-client terminal.
To identify the specific drivers required by our client we will:
- Build an image that includes all drivers natively supported by Thinstation.
- Boot the image on our target device and run a script that identifies which of the available drivers are loaded.
- Use the information collected in the previous step to build a hardware profile within DevStation.
- Build a new image based on the custom hardware profile.
To start, from our existing Terminal session, run the following two commands to create a clean build configuration:
rm build.conf
cp build.con.example build.conf
Edit build.conf (use vi or vim) and uncomment (remove the #) from the line containing package extensions-x. Save the file and use the following command to build an image that includes all available drivers: ./build --allmodules
Note: Enter Y when prompted to install Chrome.
Although we intend to use WDS to boot our thin-client image, in this instance we will actually use the PXE server built into DevStation. This is because we need the hardware profile data to be copied to DevStation, and the script we will use to collect the data is preconfigured to post the results back to the PXE server that booted the client.
To direct the client to use the PXE server on the DevStation system, create a DHCP reservation for the client and configure DHCP options 66 and 67. Set option 66 to the name or IP address assigned to DevStation, and set option 67 to boot/pxelinux/pxelinux.0
.
Note: To get the IP address of the DevStation system, run ifconfig from the Terminal.
There are a few additional requirements:
- The client system must be configured for network boot (may require a change to the boot order in the BIOS).
- The system must be able to retrieve an IP address from a DHCP server.
- If using Hyper-V, the guest must be configured with a legacy network adapter.
Now boot the client. If you've configured everything correctly, the system should receive an IP address and immediately commence booting from the network. After a short delay during which the image is downloaded, you should see the default Thinstation desktop.
Before we proceed further, switch back to DevStation, and from the Terminal, run the following command to allow write access to the TFTP root directory: chmod 777 /build/boot-images/pxe
Now, back on the client, assuming it booted as planned, open a Terminal session (from the Applications menu, select Utilities and Terminal Emulator) and run the following command to generate a hardware profile: /bin/hwlister.sh
The results should be posted back to the TFTP root on the DevStation system. In my case, a file named module.list was created, but you may also see package.list and/or firmware.list.
At this point you can shutdown the client (e.g. shutdown -halt
).
On the DevStation system, run the following commands to create a new hardware profile named Hyper-V based on the collected data (replace Hyper-V with a name representing your target device model):
mkdir /build/machine/Hyper-V
cd /build/machine/Hyper-V
mv /build/boot-images/pxe/*.list .
chmod 755 /build/boot-images/pxe
We will modify the build to incorporate the new hardware profile in the next section.
RDP Client
We will now modify the build to create a minimal RDP-enabled thin-client.
Change back to the /build
directory and edit build.conf:
- Under the #!Hardware section, comment out all lines beginning with machine, and add a new line of machine Hyper-V (replacing Hyper-V with the name of the profile created in the previous section).
- Under the #!!File System Support section, comment out module usb-storage, isofs and udf.
- Under #Miscellaneous comment out package network manager and add a new line of package autonet. Also re-comment out package extensions-x.
- Under #!!X related comment out package xorg7-vmware.
- Under #!!Locale comment out all locale packages other than package locale-en_US.
- Under #!Applications comment out package chrome and package open-vm-tools.
- Under #!!Window Managers comment out package xfwm4, package xfce4-power-manager, package terminal and package thunar.
- Under #!!Basic uncomment param fastboot and modify the value assigned to param rootpasswd.
The remainder of the configuration will occur in a file named thinstation.conf.buildtime. First, let's take a backup of the original: cp thinstation.conf.buildtime thinstation.conf.buildtime.original
Now edit thinstation.conf.buildtime and:
- Delete the line: SESSION_0_TYPE=xfwm4
- Change TIME_ZONE=America/Los_Angeles to TIME_ZONE=Australia/Sydney (or a value appropriate for your environment).
- Delete the line: USB_STORAGE_SYNC=on
- Add the following lines:
SESSION_0_TITLE="RDP"
SESSION_0_TYPE=freerdp
SESSION_0_FREERDP_SERVER="rdp.lab.hinchley.net"
SESSION_0_FREERDP_OPTIONS="/d:'lab.hinchley.net' /u:'' /bpp:16 /cert-ignore -sec-nla"
FASTBOOT_URL="http://10.0.0.100/"
Note: Replace rdp.lab.hinchley.net with the name of the target RDP server, replace lab.hinchley.net with the name of your Active Directory domain (against which users will authenticate), and replace 10.0.0.100 with the name or IP address of your IIS web server.
By default, the FreeRDP client will attempt to automatically connect to the target RDP server. To prevent this behaviour, and to show an X-window logon dialog instead, run the following command: touch /build/packages/freerdp/etc/cmd/freerdp.getuser
We will now apply some simple branding. Firstly, to use a custom splash screen (shown during boot), replace the file named silent.jpg within every folder under /build/utils/tools/splash/default
(i.e. there is a separate folder for every supported resolution). The dimensions of the image should be based upon the name of the folder.
Next, to customise the logo displayed on the RDP logon dialog, change the following image: /build/packages/freerdp/lib/icons/hicolor/32x32/apps/freerdp.png
. Note: The dimensions of the image must be 32x32 pixels.
Finally, to customise the title of the RDP logon dialog (changing from "Preparing to Run FreeRDP"), edit /build/packages/base/etc/dialog.functions
and replace Preparing to run '$DIALOG_TITLE' with something appropriate. I used Connect to LAB.
We are now ready to build the thin-client image. From the /build
directory run: ./build
When the build completes, copy the initrd and vmlinuz files from /thinstation/build/boot-images/pxe/boot/
to C:\RemoteInstall\Boot\x64\Linux
on the WDS server. The vmlinuz file will be approximately 10MB.
Note: If using File Manager on the DevStation system to copy the files, enter a path of smb://wds/c$/RemoteInstall/Boot/x64/Linux
(where wds is the address of your WDS server).
Fast Boot and IIS
In the previous section, we enabled support for fastboot in build.conf. This feature allows us to download a significant portion of the thin-client image via HTTP (instead of TFTP) - thereby reducing boot time. For this to work, there are a few prerequisites:
- Firstly, we need a web server. I will assume you are using IIS.
- Secondly, we need to add support into IIS for the .squash file type. To do this, using IIS Manager, select the Default Web Site, click the option to add a new MIME type, and set the filename extension to .squash and the MIME type to application/octet-stream.
- Confirm that Anonymous access is enabled (at least on the web site root).
- Using File Manager on the DevStation system, copy
/thinstation/build/boot-images/pxe/boot/lib.squash
toC:\Inetpub\wwwroot
on the IIS web server (approx. 75MB).
RDP Server
Our thin-client will use the FreeRDP client to connect to our target RDP server. To ensure that users connecting via the client are prompted to change their password when it is expired, we will need to disable NLA on the RDP server. This setting can be configured by opening Control Panel, System and Security, System, selecting Remote Settings, and then deselecting the option to Allow connections only from computers running Remote Desktop with Network Level Authentication.
PXE Configuration
We are almost ready to boot the thin-client. If you are using a standard WDS instance, it should be sufficient to just remove DHCP options 66 and 67 from the client reservation previously created. However, if you are using a PXE-enabled distribution point, or you just want to be explicit (and avoid DevStation from responding ahead of WDS), reconfigure DHCP options 66 and 67 so that option 66 references the name or IP address of the WDS server, and option 67 is set to boot/x64/pxelinux.com
.
Testing
Start the client. Just as before, it should obtain an IP address and then immediately initiate a network boot. Unlike before, the TFTP download will complete in only a few seconds, after which the custom splash screen will be displayed, and then the remainder of the thin-client image will be downloaded from IIS over HTTP.
If everything works as expected, the splash screen will be replaced by a single RDP logon dialog. Enter the username and password of a user authorised for access to the configured server, and click OK (the domain should not be entered, as this was configured within thinstation.conf.buildtime). With any luck, you will be seamlessly authenticated to a full-screen session on the server.
Remote Desktop Web Access
Now that we have a working RDP thin-client solution, let's create another image that can be used to connect to a Microsoft Remote Desktop Server farm.
This is a summary of the approach:
- We will create a new image that includes the FreeRDP client and Google Chrome.
- Google Chrome will be configured to run in "kiosk" mode.
- The browser will be configured to automatically connect to a Remote Desktop Web Access Portal.
- After the user authenticates to the Portal (typically via forms-based authentication), they will be presented with a list of published applications.
- Upon clicking the shortcut to an application, an RDP file will be downloaded (it will contain the required connection details).
- Chrome will be configured to automatically invoke the FreeRDP client when an RDP file is downloaded.
- The path to the RDP file will be passed to the client (along with other default connection parameters).
- The client will use the RemoteApp protocol to display the requested application (running as an independent window).
Unfortunately, as of the present time, there are a few shortcomings in this solution:
- I wasn't able to enable single sign-on between the Remote Desktop Web Access Portal and a RemoteApp session. Nor was I able to enable single sign-on between RemoteApp sessions. i.e. A user must authenticate to retrieve the list of published applications, and then re-authenticate whenever an application is launched.
- Due to a bug in the FreeRDP client packaged with Thinstation 5.4.2, the mouse did not work properly within a RemoteApp session. Note: This issue could be addressed by using the most recent version of FreeRDP (i.e. compiling form the latest source).
Note: This article will not describe the steps required to setup or configure a Remote Desktop solution; only the steps required to configure the Thinstation image are presented.
Let's start by saving the previously modified build.conf and thinstation.conf.buildtime configuration files:
cd /build
cp build.conf build.conf.rdp
cp thinstation.conf.buildtime thinstation.conf.buildtime.rdp
Now edit build.conf and under #!Applications uncomment #package chrome.
Edit thinstation.conf.buildtime and replace the SESSION_0 lines previously added with the following:
SESSION_0_TITLE="KIOSK"
SESSION_0_TYPE=chrome
SESSION_0_CHROME_HOMEPAGE="https://rdp.lab.hinchley.net/RDWeb"
SESSION_0_CHROME_OPTIONS="--ignore-certificate-errors --kiosk --start-full-screen --test-type"
You will also need to replace https://rdp.lab.hinchley.net/RDWeb
with the URL of your Remote Desktop Web Access server.
The final step is to configure Chrome to automatically invoke the FreeRDP client when an RDP file is downloaded. We can do this by editing /build/packages/gnome-core/bin/xdg-open
and adding the following code immediately under the line which executes detectDE:
if test ${url##*.} = "rdp"; then
/bin/xfreerdp "$url" /cert-ignore /sec:rdp
exit 0
fi
We also need to ensure the above association is invoked automatically (to avoid the user from being prompted to open RDP files). This is controlled via a preference in Chrome which can be configured by creating a file named /build/packages/chrome/etc/chrome/Default/Preferences
with the following content:
{"account_id_migration_state":2,"account_tracker_service_last_update":"13097285309636958","download":{"directory_upgrade":true,"extensions_to_open":"rdp"}}
To build the new image, rerun: ./build
Note: The introduction of Chrome will add approximately 70MB to the image.
Dual Boot
At this point we could deploy our new image by copying the updated initrd to the WDS server, and lib.squash to the web server (vmlinuz won't be changed by the rebuild). However, we can also make a few changes to our WDS configuration to allow users to boot either image.
Let's start by editing C:\RemoteInstall\Boot\x64\pxelinux.cfg\default
on the WDS server and replacing the existing content with the following:
DEFAULT vesamenu.c32
PROMPT 0
NOESCAPE 1
ALLOWOPTIONS 0
TIMEOUT 300
MENU MARGIN 10
MENU ROWS 16
MENU TABMSGROW 21
MENU TIMEOUTROW 26
MENU COLOR BORDER 30;44 #20ffffff #00000000 none
MENU COLOR SCROLLBAR 30;44 #20ffffff #00000000 none
MENU COLOR TITLE 0 #ffffffff #00000000 none
MENU COLOR SEL 30;47 #40000000 #20ffffff
MENU TITLE Boot Menu
#---
LABEL RDP
MENU DEFAULT
KERNEL /Linux/vmlinuz
APPEND initrd=/Linux/initrd splash=silent,theme:default load_ramdisk=1 ramdisk_blocksize=4096 root=/dev/ram0 ramdisk_size=786432 loglevel=3 console=tty1 vt.global_cursor_default=0 LM=3
#---
LABEL KIOSK
MENU LABEL Kiosk
KERNEL /Linux/vmlinuz
APPEND initrd=/Linux/initrdk splash=silent,theme:default load_ramdisk=1 ramdisk_blocksize=4096 root=/dev/ram0 ramdisk_size=786432 loglevel=3 console=tty1 vt.global_cursor_default=0 LM=3
Now, go back to DevStation and edit thinstation.conf.build and update FASTBOOT_URL to end in kiosk (for example: http://10.0.0.100/kiosk
), and then rebuild the solution.
After the build completes, rename /thinstation/build/boot-images/pxe/boot/initrd
to initrdk and copy it to the following folder on the WDS server: C:\RemoteInstall\Boot\x64\Linux
Also copy lib.squash to a new folder named C:\inetpub\wwwroot\kiosk
on the web server.
Now when you boot the client you should see a boot menu with two options. The first, named RDP, will initiate the boot of our first image, and the second, name Kiosk, will initiate the build of the image with Chrome. The first option is configured as the default, and will be automatically invoked after 30 seconds.
Try booting the client, select Kiosk from the boot menu, and cross your fingers. If all goes well, Chrome should open fullscreen at the logon page of your Remote Desktop Web Access Portal. Log in, and open an application. Assuming you have disabled NLA on your farm, after you (re)authenticate, the requested application will be displayed.
Extend Boot Menu
It's possible to extend the boot menu (by modifying C:\RemoteInstall\Boot\x64\pxelinux.cfg\default
) to include additional options, such as booting an ISO, or a binary image, passing through to WDS (if your PXE server is using WDS), or cancelling the PXE request and booting off the local hard drive. The following example configuration includes all of these options:
DEFAULT vesamenu.c32
PROMPT 0
NOESCAPE 1
ALLOWOPTIONS 0
TIMEOUT 300
MENU MARGIN 10
MENU ROWS 16
MENU TABMSGROW 21
MENU TIMEOUTROW 26
MENU COLOR BORDER 30;44 #20ffffff #00000000 none
MENU COLOR SCROLLBAR 30;44 #20ffffff #00000000 none
MENU COLOR TITLE 0 #ffffffff #00000000 none
MENU COLOR SEL 30;47 #40000000 #20ffffff
#MENU BACKGROUND MyMenuBackgroundPicture640x480.jpg
MENU TITLE Boot Menu
#---
LABEL RDP
MENU DEFAULT
KERNEL /Linux/vmlinuz
APPEND initrd=/Linux/initrd splash=silent,theme:default load_ramdisk=1 ramdisk_blocksize=4096 root=/dev/ram0 ramdisk_size=786432 loglevel=3 console=tty1 vt.global_cursor_default=0 LM=3
#---
LABEL KIOSK
MENU LABEL Kiosk
KERNEL /Linux/vmlinuz
APPEND initrd=/Linux/initrdk splash=silent,theme:default load_ramdisk=1 ramdisk_blocksize=4096 root=/dev/ram0 ramdisk_size=786432 loglevel=3 console=tty1 vt.global_cursor_default=0 LM=3
#---
LABEL wds
MENU LABEL Windows Deployment Services
KERNEL pxeboot.0
#---
LABEL memtest86+bin
MENU LABEL Memtest86+ Binary
KERNEL /Linux/memtest86+
#---
LABEL memtest86+iso
MENU LABEL Memtest86+ ISO
KERNEL /Linux/memtest86+.iso
#---
LABEL Abort
MENU LABEL AbortPXE
Kernel abortpxe.0
#---
LABEL local
MENU DEFAULT
MENU LABEL Boot from Harddisk
LOCALBOOT 0
Type 0x80
That will do for today. Drop me an email if you have any questions.
Addendum
A few random dot points regarding enhancements implemented to enable network-based dynamic configuration (including the use of multiple monitors and low resolution displays):
- Create a folder on an IIS web server named
C:\Inetpub\wwwroot\TS5.4
and add three files: thinstation.conf.network, thinstation.hosts, and thinstation.conf.group-blind. - The file thinstation.conf.network supplements thinstation.conf.buildtime and contains configuration commands for all hosts.
- The file thinstation.hosts is used to map specific hosts to groups (via MAC address).
- The file thinstation.conf.group-blind is a configuration file for computers in the group named "blind" (as determined from thinstation.hosts).
- To support multiple monitors (both connected to a computer using Display Port) and to configure FreeRDP, I added the following commands to thinstation.conf.network (and
removed the
SESSION_0_*
elements from thinstation.conf.buildtime):
USE_XRANDR=TRUE
XRANDR_OPTIONS="--output DisplayPort-0 --output DisplayPort-1 --left-of DisplayPort-0"
SESSION_0_TITLE="RDP"
SESSION_0_TYPE=freerdp
SESSION_0_FREERDP_SERVER="rdp.lab.hinchley.net"
SESSION_0_FREERDP_OPTIONS="/d:'lab.hinchley.net' /u:'' /cert-ignore /sec:tls /multimon"
- To get the names of the monitors (if using something other than Display Port), boot up a thinstation system, and from the Terminal, run xrandr.
- For testing, I added the following to thinstation.hosts (which adds the host with the specified MAC address to the group named BLIND):
# HOST MAC GROUPS COMMENTS
Ts1 7cd30a1da71f BLIND # Force low resolution display.
- I then specified a resolution in thinstation.conf.group-blind via the following:
SCREEN_RESOLUTION="800x600"
- If using IIS, don't forget to add MIME-type entries for each of the file extensions added above (i.e. .network, .hosts and .group-blind should all be mapped to text/plain).
- To enable network based configuration I enabled
package ts-classic
in build.conf and setparam baseurl
tohttp://pxe.lab.hinchley.net
(wherepxe.lab.hinchley.net
maps to the IIS web server identified above). - I also added
NET_FILE_ENABLED=On
andNET_FILE_METHOD=wget
to thinstation.conf.buildtime. - It isn't possible to use a DNS entry for resolving
FASTBOOT_URL
. Therefore, if you want to avoid tying the variable to a specific IP address (i.e. allowing you to scale the solution to include multiple PXE servers across multiple subnets), you can set a specific address per PXE server by modifyingpxelinux.cfg/default
. In particular, modify the kernel startup parameters by appending theFASTBOOT_URL
parameter. For example:
LABEL RDP
MENU DEFAULT
KERNEL /Linux/vmlinuz
APPEND initrd=/Linux/initrd splash=silent,theme:default load_ramdisk=1 ramdisk_blocksize=4096 root=/dev/ram0 ramdisk_size=786432 loglevel=3 console=tty1
vt.global_cursor_default=0 LM=3 FASTBOOT_URL=http://10.0.0.10/
Troubleshooting
In a "real world" deployment of the Thinstation solution I've described in this post, I encountered a couple of issues when using a monitor connected to the terminal via a KVM switch box with a DisplayPort connector:
- When the KVM was used to switch between the terminal and another system, and then back again, the monitor would enter a disconnected state.
- (After resolving issue 1) When the KVM was used to switch between the terminal and another system, and then back again, the mouse cursor would disappear. The mouse was active (the system would respond to mouse movement and button clicks), but the cursor was invisible. This issue did not occur when using dual monitors.
The solution to both issues was to run a custom script when the terminal detected a change to the status of the DisplayPort (i.e. after the monitor(s) were reconnected when the KVM was switched back to the terminal).
Within DevStation, under /build/packages/automount/etc/udev/rules.d
I created a file named 70-monitor.rules with the following content:
KERNEL=="card0", SUBSYSTEM=="drm", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/root/.Xauthority", RUN+="/etc/udev/scripts/monitor.sh"
Then, under /build/packages/automount/etc/udev/scripts
I created a file named monitor.sh with the following content:
#! /bin/sh
xrandr --auto
xrandr --output DisplayPort-0 --output DisplayPort-1 --left-of DisplayPort-0
chvt 1 && chvt 5
Note: Use chmod 755 monitor.sh
to make the script executable.
This script uses xrandr with the --auto
switch to detect (and activate) the monitor(s) connected to the terminal via the KVM. It then reconfigures the dual screen layout previously configured at boot (this works when using either one or two monitors). Finally, the script uses chvt to swtich between TTY1 and 5, which was sufficient to force the cursor to reappear. The udev rule, and corresponding script, execute in real-time, and are unnoticed by the user.