Retaining Multi-Monitor Configs After Sleep

I recently upgraded my dual-monitor setup to include a 32″ primary monitor on DisplayPort and a 24″ secondary on HDMI. Apparently, the LG 32GP750 in primary position takes slightly longer to wake up after sleep mode than the Acer K242HYL in secondary — just long enough, in fact, that Arch’s display manager can’t work out what to do and ends up rejecting the primary monitor entirely. Enter a minute of grudgingly editing display settings and rearranging windows.

After 2 months of this nonsense, I shall put up with it no further.

Fortunately, the solution is comically simple.

Step 1: Install autorandr


sudo apt install autorandr


sudo pacman -S autorandr

Step 2: Save your configuration using the name default, unless you’re being sassy and using multiple configs:

autorandr --save default

Step 3: Prosper

There should be a file called /etc/xdg/autostart/autorandr.desktop that invokes the default configuration (see why we called it that?) upon loading of the login screen; i.e. the first step after waking up. Problem solved.

Step 4: Attribution

I definitely did not figure this out myself, but it did take an inordinate amount of googling. For reference, here’s where I got the deets.

Posted by Adam Labay, 0 comments

Gallant Sound Card is the Best Sound Card

The first PC my dad and I built together was named Thomas. It was a 66 MHz 486, and its sound card was a Gallant SC-5000.

The sound card itself was completely unremarkable, apart from the setup program. Its last step was to test the settings by playing the following file, in which a tinny, echo-y voice proclaims that Gallant Sound Card is the Best Sound Card!:

That slogan – and its rendering – became a running father-son gag for the decades that followed, albeit with one challenge: we never had a copy of the audio file, so the line existed only in our collective memory.

Until now.

Here’s how it went down.

Step 1: Find the drivers

Fundamentally, not too difficult. Download, unzip, and locate the TESTSC.EXE file, which is the post-install test program in question.

Step 2: Extract the sound file

This part was less straightforward. If this were a Win32 executable, it would just be a glorified .zip file with the various audio assets embedded. But this driver is for DOS, so the assets are baked – in binary – into the file.

MediaExtract to the rescue

Fortunately, there’s a fine person on GitHub who created a tool that specifically extracts media from executable files. I couldn’t tell you for the life of me how it works, but by golly it does. The steps are simple enough:

  1. Download the latest release and extract.
  2. Copy TESTSC.EXE into the binary-win32 folder
  3. Run mediaextract TESTSC.EXE
  4. Behold the extracted .wav file

Step 3: Immortalize the file

For his part, my dad recorded the output in a recordable greeting card. Now it’s my turn: The fine folks at ArtBlox, for a small sum, happily transcribed the waveform in acrylic. The result:

If you have fond memories of PCM audio from the DOS days, consider rendering one of them in acrylic for your dad.

Posted by Adam Labay, 0 comments

XRDP on Fedora (Budgie)

So, it seems like I’m becoming the second generation of the XRDP guy. And frankly, I’m okay with that.

At any rate, today’s adventure takes us to Fedora, with the goal of RDP’ing in. In particular, I’m using Ultramarine Linux, which is a Fedora variant, and whose flagship edition ships with the Budgie desktop. I’ll confess that I’m not a huge fan of Budgie, but I’ve decided to give it a fair shake.

And naturally, that fair shake started with an error message:

Oh no! Something has gone wrong.

Très helpful.

So let’s get this thing working.

Step 0: Install XRDP and Friends

sudo yum update -y
sudo yum install -y xrdp xorgxrdp tigervnc-server
sudo systemctl enable xrdp && sudo sytemctl start xrdp

I’m not sure whether the vnc server is strictly necessary, but it can’t hurt.

Step 1: Apply the Fixes

echo "allowed_users = anybody" | sudo tee -a /etc/X11/Xwrapper.config
echo "exec budgie-desktop" > ~/.Xclients
chmod a+x ~/.Xclients

What do they do?

  • The first line permits us to log in without being at the machine itself – important for remoting in.
  • The second line tells the X11 window manager to start a Budgie session, which is why we’re getting that error in the first place.
  • The third line sets the appropriate permissions for the above to happen.

Step 2: Have a lovely beverage

Let me know if this gives you any grief. No guarantees of help, but I’m starting to understand this XRDP whatnot better than most, so maybe I’ll be of use.

Posted by Adam Labay, 1 comment

Scrape Student Contacts from Aspen

It’s  a new semeseter, and that means teachers are manually loading their students’ contacts into their phones.

If you teach for DCPS – or any other school system that uses the Aspen Student Information System – this process sucks. There’s no unified way to extract every contact for multiple students, so you’re faced with the prospect of clicking on each student and manually pulling their contacts…

Until now.

I’ve thrown together a simple Python app that logs into Aspen, pulls all of your students’ contacts into a single file, and can even format that file for importing directly into your Google contacts.

Getting/Using the App

All of the directions are on the project’s GitLab page, including installation instructions for Windows and MacOS.

Asking Questions

Is best done in the comment section of this post.

Future Work

Includes exporting of contacts to vCard format, compatible with Apple devices.

Posted by Adam Labay, 0 comments

Installing Kali Nethunter on the OnePlus (and probably other phones too)

In a fit of boredom (and a desire to up my l33t cred), I decided to install Kali Nethunter on a OnePlus 7 Pro that I stopped using about a year ago. Naturally, the first stop was the official installation instructions. Big mistake. They’re darn near incomprehensible, rely on deprecated software, and cost me about 3 days of struggle.

But, with enough time, cussing, and reflashes, anything is possible, and Nethunter is now working beautifully on the OnePlus 7 Pro. So what follow are the steps I used to pull it off. Hopefully they’ll save you some time and heartache.

Obligatory Warnings

Flashing Nethunter requires the following actions, in increasing order of risk:

  • Rooting your phone. If you don’t know what that means, you are wildly out of your depth. Stop, reconsider your choices, and go have some ice cream instead.
  • Wiping your phone, completely, about a fghjillion times. You will lose all your data.
  • Unlocking your bootloader, which, in addition to wiping your phone, makes it display an annoying security message every time you boot from here on out.
  • Disabling your phone’s encryption. That is, even without knowing your passcode, someone who possesses your phone can view all those nudes you’re probably storing on it.

Further: doing any of the above can brick your phone. Bricking your phone will result in:

  • Turning your expensive-ass phone into a shiny paperweight
  • Voiding any and all warranties
  • Earning you mockery and derision on Reddit when you explain what you did in a desperate plea for help
  • Hours spent in the XDA-Developers forums — where you will encounter less mockery and derision, but the same bleak despair when they explain what you’ve done

Still here? Let’s go.

Step 0: Learn what region your phone is

Most manufacturers have different editions of the phones – with different hardware – for various regions like the USA, Europe, China, and India. Installing the wrong edition won’t fully brick your phone, but it’ll give you a good scare and cost a few hours to fix.

Typically, the regional variant of your OS is appended to the version number. For example, my OxygenOS version (available by going to Settings | About Phone | Build Number) is, where GM21AA is the variant.

If you’re on a OnePlus like me, it gets slightly more complicated, as there is a T-Mobile variant within the USA/Global variant, and you may have to reflash your entire phone’s image before you can proceed at all. I’ll write a follow-up post on how to do that, provided I remember.

Step 1: Update your phone to the latest stock OS

Installing any updates to your operating system will result in re-enabling the encryption that we are working so hard to remove. Ergo, you will not be able to update Android after installing Nethunter unless you want to repeat the entire Nethunter installation rigmarole.

Therefore, do future you a favor and get your phone on the latest version of Android (in my case, Oxygen OS for the USA/Global edition).

Furthermore, you must use the stock version of Android that ships with your device. No custom OSes here.

Step 2: Install ADB and Fastboot

If you don’t know what these are, you should probably bail right now. At any rate, here’s how to get them:

  • Windows/Mac: Download from Google and unzip somewhere. Unless you want to get all fancy with the PATH variable, though, you’ll have to drop any files you intend to upload into this folder. This is the only time I will mention this caveat, so don’t forget it.
  • Ubuntu: sudo apt install android-tools
  • Arch: sudo pacman -S android-tools

Step 3: Enable USB Debugging and other fancy developer tools

Remember that build number from Step 0 (Settings | About Phone | Build Number if you already forgot somehow)? Tap on it 7-8 times to enable Developer Mode. Now, you can go to Settings | System | Developer Options and do the following:

  • Enable USB Debugging
  • (Optionally) enable Advanced Reboot

Step 4: Install Magisk

Magisk is a lovely app that serves multiple functions in our adventure, namely:

  • Rooting your phone
  • Disabling encryption
  • Installing Nethunter

To install:

  1. Go to Magisk’s GitHub page and download the .apk of the latest release. Don’t download Magisk from anywhere other than GitHub! It is known that amateurs are always looking for easier ways to root their phones, and bad actors capitalize on their naivete with malware-laden fakes.
  2. In a terminal (command prompt for your Windows folk), push the file to your phone with
    adb push Magisk-v25.2.apk /sdcard/Download
  3. On your phone, open the File Manager app and install the .apk that now resides in your phone’s Downloads folder. You’ll probably have to enable a bunch of permissions to accomplish this, but at least the menus involved are intuitive.

Step 5: Patch your Boot Image

In order for Magisk to work its rooty magic, it first needs some help by way of a patched boot image. Fortunately, Magisk will do the patching for you; all you have to do is secure that juicy .img file. To do so:

  1. Get a factory image of your OS. Two ways to do this:
    • Go to the vendor’s support site and poke around
    • Google “factory image [OS build]” where [OS build] is the build number from Step 1.
  2. Open the .zip file that you downloaded and extract payload.bin.
  3. Clone the payload_dumper repository (or just download a ZIP of it from GitHub).
  4. Move payload.bin into the payload_dumper folder.
  5. Make sure that you have Python 3 installed with the following (pip) packages:
    • protobuf
    • bsdiff4
  6. Open a terminal in the payload_dumper folder and run
    python3 payload_dumper payload.bin
  7. Once it completes, there will be an output folder containing boot.img. Push it to your phone with
    adb push boot.img /sdcard/Download

Now you can patch that boot image in Magisk. To do so:

  1. Open Magisk.
  2. In the Magisk section (i.e. not the App section), click Install.
  3. Choose Select and Patch a File as your method.
  4. Navigate to boot.img from earlier.
  5. Let Magisk do its thing. When it finishes, the last line will give the name of the output file, along the lines of
    magisk_patched_[string of stuff].img.
  6. Retrieve that patched file with
    adb pull /sdcard/Download/magisk_patched_[string of stuff].img .

Step 6: Unlock the bootloader

Reboot into the bootloader. Two ways to do this:

  • adb reboot bootloader
  • Long-press the Power button and select bootloader, which should be available if you enabled Advanced Reboot in Step 3.

Once in the bootloader, unlock it with
fastboot oem unlock

Accept that this will wipe your phone and let it proceed.

Step 7: Repeat Steps 3-4

Remember when I said you’re going to wipe your phone a fghjillion times? Yeah, you’re gonna repeat Steps 3-4 a healthy number of times as well.

Step 8: Patch your boot image

Reboot into the bootloader, same as you did in Step 6. Then, flash the boot image that Magisk produced with
fastboot flash boot magisk_patched_[string of stuff].img

Once it’s flashed, boot the phone. Your phone is now rooted!

Step 9: Disable encryption

This is where the stock Nethunter installation instructions make their first mistake. They advocate using Disable_Dm-Verity_ForceEncrypt, which is deprecated and will soft-brick your phone.

Instead, you need Disable Force Encryption NEO (hereafter DFE-Neo). You can learn all about it on the XDA-Developers forum, or you can just download it from SourceForge.

You can download the file directly to your phone, or download it to your computer and adb push it to your phone. Either way, the next steps are:

  1. Open Magisk. It may request a reboot to complete installation; let it.
  2. Tap Modules in the bottom-right.
  3. Select Install from Storage and select the DFE-NEO zip you downloaded.
  4. Use Volume Up to cycle through the languages and use Volume Down to select the language of choice.
  5. Hit Volume Down again to continue.
  6. Hit Volume Up to select the Use arguments.txt option, and Volume Down to select.
  7. Let it run its course. When you get to the end, though, don’t hit the blue Reboot nugget. Instead, reboot into the bootloader using your preferred method from Step 6.

Step 10: Wipe the Data partition

Time to enter Recovery mode. For this, you will want the latest version of TWRP Recovery. Go to, find your device, and download the most-recent .img file.

Don’t install TWRP as it will overwrite your boot partition that you worked so hard to flash. Instead, we’re just going to boot into TWRP as a one-off. To do so, use
fastboot boot twrp-[version]-[model].img

Once TWRP Recovery has loaded, select Wipe and Wipe Data. Once that’s done, reboot.

Step 11: Repeat Steps 3-4

Another wipe of the phone, another reinstallation of Magisk.

Step 12: Install Nethunter

Friggin finally. Obtain the latest Nethunter image from, either by downloading directly to the phone or pushing via adb.

Open Magisk, and install the Nethunter image the same way you installed DFE-NEO in Step 9.

Step 13: Celebrate!

You did it! l33t points will be added to your account in due course.

Posted by Adam Labay, 10 comments

XRDP on Manjaro (The Easy Way… When It Works)

I have a much lengthier post on getting XRDP to work on Manjaro, which happens to be one of the top Google results for getting the whole apparatus to work.

And to that end, I want to provide a quick and easy way of getting XRDP to work on Manjaro for folks who aren’t interested in prologue and might be afraid to edit weirdly-named files on their own.

Caveat Emptor

The easy way doesn’t always work. Reasons include:

  • The xrdp and xorgxrdp(+/- git) packages need to be in perfect alignment. If one is updated while the other is not, sadness will result.
  • The xrdp and xorgxrdp(+/- git) packages need to both be properly signed, which has been an on-and-off issue for the past couple years.
  • If you’re running a desktop environment that’s not XFCE, then you’ll have to make some modifications. Fortunately, if you’re here, you’re probably running the default Manjaro desktop environment, which happens to be XFCE.

Should the easy way fail, you may want to visit my original post on doing it the hard way.

The Steps

Assuming you can ssh into your machine, the commands are as follows:

sudo pacman -Sy base-devel xorg-server-devel yay
yay -S xrdp xorgxrdp-git
echo "allowed_users = anybody" | sudo tee -a /etc/X11/Xwrapper.config
sed -i '12s/xfce-session/xfce4-session/g' ~/.xinitrc
sed -i '42s/ --exit-with-session//g' ~/.xinitrc
sed -i '66s/\$1/\$SESSION/g' ~/.xinitrc
sudo systemctl enable xrdp
sudo systemctl start xrdp

What They Do

  • The first line installs the packages you’ll need to build and install xrdp and its friends.
  • The second line installs xrdp and xorgxrdp-git, which are sort of the point of this exercise
  • The third line permits you to enter an X (desktop) session without being at the computer – sorta important if your goal is to remote in.
  • Lines 4-6 correct some typographical issues that prevent xrdp from running normally.
  • Lines 7-8 enable and start the xrdp service.

Good Luck!

Let me know if any of this ceases to function and I’ll do my best.

Posted by Adam Labay, 3 comments

XRDP on Manjaro (fixing the blank screen issue)

Updated 22 November, 2021

Recently, I repurposed an old desktop machine to be a headless server for running machine learning and ArchiveTeam stuff. In its former life it ran Manjaro alongside Windows 10, so I figured I might as well stick with Manjaro in its new role.

Of course, since it would be running headless, I needed to install a remote desktop solution. xrdp has worked a treat in the past on my various other Debian-based systems, so what the heck.

Unfortunately, a quick Google search will confirm that running xrdp on Manjaro is anything but straightforward. The issues are twofold:

  1. A required package has a borked GPG signature, so you have to build it yourself.
  2. Even once you have all the dependencies installed, you’re greeted by a blank screen.

Fortunately, the solution is relatively straightforward. So without any further prologue, let’s go.

Note: XFCE

I’m assuming that your desktop environment is XFCE, since that’s the default Manjaro environment. If you’re using KDE or Gnome, I’m guessing the same steps apply. But don’t take my word for it.

Step 1: SSH into your machine

Since this is a headless machine, I’m doing everything via SSH. That said, other than Step 2, everything will be via the terminal anyway.

Step 2: Install some dependencies

Specifically, we’re going to install:

  • yay – which enables the installation of AUR packages. xrdp doesn’t live in the regular pacman universe, so we need yay.
  • base-devel – which enables the building of said AUR packages
  • xorg-xserver-devel – which provides necessary dependencies for xrdp.
  • xorg-server-dev – successor xorg-server-devel. Provides necessary dependencies for xrdp.
sudo pacman -Sy yay base-devel xorg-xserver-devel

Step 3: Install xrdp

Now we can install xrdp using yay.

yay -S xrdp

Agree to install all dependencies, blah blah, and you’re good.

Step 4: Download and install xorgxrdp

Normally, we’d install xorgxrdp through yay, same as xrdp. Unfortunately, the GPG keys are scuzzed up, so we have to do this the hard way: by building it ourselves.

Fortunately, this isn’t hard at all.

Step 4a: Download xorgxrdp

As of this writing, the latest release is 0.2.17. Find the current link on the AUR page under Sources and proceed accordingly.


Step 4b: Extract the files and enter the directory

tar xvf xorgxrdp-0.2.17.tar.gz
cd xorgxrdp-0.2.17

Step 4c: Configure, make, and install

sudo make install

Step 5: Create (or edit) your Xwrapper.config file

My understanding of this step is sketchy, but it goes like this: by default, X11 won’t open a session unless you’re at the display. This is understandably an issue if you’re remote.

So we either edit /etc/X11/Xwrapper.config (if it exists) or create a fresh copy (most likely the case), containing the ending (or only) line:

allowed_users = anybody

Step 6: Edit ~/.xinitrc

This is the file that is causing your blank screen woes, and likely why you’re reading this post in the first place. The stock version has a couple of typos that result in the window manager never actually being invoked. In particular, we need to make 3 edits:

  1. Change SESSION=${1:-xfce-session} to read SESSION=${1:-xfce4-session}
  2. Change local dbus_args=(–sh-syntax –exit-with-session) to read local dbus_args=(–sh-syntax)
  3. Change exec $(get_session “$1”) to read exec $(get_session “$SESSION”)

The resultant file should look like

# ~/.xinitrc
# Executed by startx (run your window manager from here)



# merge in defaults and keymaps

if [ -f $sysresources ]; then
    xrdb -merge $sysresources

if [ -f $sysmodmap ]; then
    xmodmap $sysmodmap

if [ -f "$userresources" ]; then
    xrdb -merge "$userresources"

if [ -f "$usermodmap" ]; then
    xmodmap "$usermodmap"

# start some nice programs

if [ -d /etc/X11/xinit/xinitrc.d ] ; then
    for f in /etc/X11/xinit/xinitrc.d/?*.sh ; do
        [ -x "$f" ] && . "$f"
    unset f

        #local dbus_args=(--sh-syntax --exit-with-session)
        local dbus_args=(--sh-syntax)
        case "$1" in
                awesome) dbus_args+=(awesome) ;;
                bspwm) dbus_args+=(bspwm-session) ;;
                budgie) dbus_args+=(budgie-desktop) ;;
                cinnamon) dbus_args+=(cinnamon-session) ;;
                deepin) dbus_args+=(startdde) ;;
                enlightenment) dbus_args+=(enlightenment_start) ;;
                fluxbox) dbus_args+=(startfluxbox) ;;
                gnome) dbus_args+=(gnome-session) ;;
                i3|i3wm) dbus_args+=(i3 --shmlog-size 0) ;;
                jwm) dbus_args+=(jwm) ;;
                kde) dbus_args+=(startplasma-x11) ;;
                lxde) dbus_args+=(startlxde) ;;
                lxqt) dbus_args+=(lxqt-session) ;;
                mate) dbus_args+=(mate-session) ;;
                xfce) dbus_args+=(xfce4-session) ;;
                openbox) dbus_args+=(openbox-session) ;;
                *) dbus_args+=("$1") ;;

        echo "dbus-launch ${dbus_args[*]}"

exec $(get_session "$SESSION")

Step 8: Enable and Start xrdp

sudo systemctl enable xrdp
sudo systemctl start xrdp

Step 8.1: Bypass nVidia Drivers

If you’re running nVidia drivers, there’s one more step, which I discovered courtesy of this delightful post.

In short, the nVidia drivers will cause the blank screen to resurface. We want to keep the drivers for use by applications, but deny their use by xrdp. Here’s how:

  1. Make the directory /etc/X11/nvidia.d
  2. Move the files 90-mhwd.conf and [stuff].nvidia-drm-outputclass.conf to said directory where [stuff] depends on your specific installation. For me the file was 10-amdgpu-nvidia-drm-outputclass.conf but your mileage (and CPU) will vary.
sudo mkdir /etc/X11/nvidia.d
sudo mv /etc/X11/xorg.conf.d/90-mhwd.conf /etc/X11/nvidia.d
sudo mv /etc/X11/xorg.conf.d/10-amdgpu-nvidia-drm-outputclass.conf /etc/X11/nvidia.d

Your /etc/X11 directory should look something like

├── mhwd.d
│   ├── nvidia.conf
│   └── nvidia.conf.nvidia-xconfig-original
├── nvidia.d
│   ├── 10-amdgpu-nvidia-drm-outputclass.conf
│   └── 90-mhwd.conf -> /etc/X11/mhwd.d/nvidia.conf
├── tigervnc
│   └── Xsession
├── xinit
│   ├── xinitrc
│   ├── xinitrc.d
│   │   ├──
│   │   ├──
│   │   └──
│   └── xserverrc
├── xorg.conf.d
│   └── 00-keyboard.conf
├── xrdp
│   └── xorg.conf
└── Xwrapper.config

Step 9: Prosper

Hop on in, and be greeted by the XFCE environment.

Let me know if you still have any issues, though the chances of my being able to solve them are miniscule. Godspeed!

Posted by Adam Labay, 5 comments

Update: Consistently Successful Calls on PinePhone with UBPorts

This’ll be a short one.

A short while ago I posted about my first successful outgoing calls on the PinePhone, and stated that they weren’t terribly consistent and that they had no voice:

I can get the PinePhone to ring other phones – which is still a new accomplishment – but no voice comes through. Alas.

If you’re like me, you’ll now have a 1:5 (up from 0:5) chance of being able to successfully dial out.

That has changed, due both to a software update and a trick.

Stick to the Dev Channel

I can’t speak for the Stable channel, but at least with Dev Version 61 outgoing calls have crystal-clear voice 100% of the time.

Lose the Extra G

Browsing the UBPorts Forums, folks indicated that UBPorts doesn’t have a good time with VoLTE (Voice over LTE), and thus can’t pull off 4G calls at all. Normally, the phone should be able to recognize this fact and switch automatically to 3G, and I’m guessing that’s what my phone did the 1 in 5 times that it successfully placed a call.

To up that ratio to 1:1, go to Settings | Network | Cellular Settings and select 2G/3G as the Connection Type.

Thereafter, calls should always connect.

Posted by Adam Labay, 0 comments

Creating an ARM64 Debian Image

As part of another project, I need to be able to build software for the PinePhone, and that means I need an ARM64 environment with as much oomph as possible (trying to compile stuff on the PinePhone = bad idea).

The solution is to run a Debian VM that, in turn, runs a Qemu ARM64 emulator with a Debian image.

Nearly every step that follows is taken verbatim from this guide by Blahcat, so all credit goes there.  The only reason I made my own post is because I had to change a couple lines in order to get the network working. Hopefully this brings you joy.

Get that VM going

I’m a VirtualBox guy, but you do you. You’ll also want the latest Debian ISO, which at the time of writing is Buster. I gave mine 4 cores, 4GB of RAM, and 20GB of storage.

Install Qemu

Terminal. sudo apt install qemu. Nuff said.

Download the Debian Bits

You need the initrd and kernel of the Debian installer. Blahcat’s links are outdated, so here’s the latest:


Make a disk. To hold stuff.

Blahcat recommends 20G, but that’s the size of my Debian VM. I haven’t managed to fill up 12G yet — but, as said before, you do you.

qemu-img create -f qcow2 disk.qcow2 12G

Invoke the Installer

This is where I depart the most from Blahcat. Every time I followed their instructions, the resulting image was unable to connect to the internet, even though it ran a blasted net installer. The solution, in my case, was to force the emulation of an ethernet adapter (in addition to the one that Qemu automatically creates). Some of the command that follows is likely malformed, redundant, or both, but by golly it worked.

qemu-system-aarch64 -smp 2 -M virt -cpu cortex-a57 -m 1G \
    -initrd initrd.gz \
    -kernel linux -append "root=/dev/ram console=ttyAMA0" \
    -global virtio-blk-device.scsi=off \
    -device virtio-scsi-device,id=scsi \
    -drive file=disk.qcow2,id=rootimg,cache=unsafe,if=none \
    -device scsi-hd,drive=rootimg \
    -device e1000,netdev=net0 \
    -net nic \
    -netdev user,hostfwd=tcp:,id=net0 \

During installation you’ll be asked to pick an Ethernet adapter; pick the Intel one and life is good.

Extract your fancy new kernel

Let it be known that I have no idea how half this stuff works, nor what nbd stands for. Essentially, you mount your new image, extract the kernel and initrd, and use them the next time you invoke the image.

sudo apt install nbd-client
sudo modprobe nbd max_part=8
sudo qemu-nbd --connect=/dev/nbd0 disk.qcow2
mkdir mnt
sudo mount /dev/nbd0p1 mnt
cp mnt/initrd.img-4.19.0-9-arm64 mnt/vmlinuz-4.19.0-9-arm64 .
sudo umount /dev/nbd0p1
sudo nbd-client -d /dev/nbd0


You should now be able to run your new, emulated system – and have internet access too!

qemu-system-aarch64 -smp 2 -M virt -cpu cortex-a57 -m 1G \
    -initrd initrd.img-4.19.0-9-arm64 \
    -kernel vmlinuz-4.19.0-9-arm64 \
    -append "root=/dev/sda2 console=ttyAMA0" \
    -global virtio-blk-device.scsi=off \
    -device virtio-scsi-device,id=scsi \
    -drive file=disk.qcow2,id=rootimg,cache=unsafe,if=none \
    -device scsi-hd,drive=rootimg \
    -device e1000,netdev=net0 \
    -net nic \
    -netdev user,hostfwd=tcp:,id=net0 \

Posted by Adam Labay, 0 comments

Extending onto a USB Monitor with Manjaro

Normally, my ASUS MB169B USB Monitor lives in my briefcase, to be used when I need two screens at a coffee shop or a client. But, given the new work-from-home reality, it’s found a new life as a dedicated spot for tiles showing email, calendar, and Slack…

…at least it does when I’m running Windows. When running Manjaro, the USB monitor has sat idle, unused, and sad.

That’s not to say that Manjaro doesn’t support the use of DisplayLink to attach USB monitors — it’s just that, like all things Arch Linux, you have to work for it; doubly so if you’re running an nVidia card.

So, here’s how I got mine working.

1. Install DisplayLink and EVDI drivers.

Do you need both? Beats me, but this is what I have and it works. Purists will do this via pacman but I’m lazy and used the GUI.

2. Install the nVidia drivers, even though they’re not very good.

This turned out to be the key step. Normally, I use modesetting as my graphics driver, mainly because it doesn’t suck. With the nVidia drivers, I get some annoying mouse flickering that I haven’t yet been able to address.

However, the USB monitor also uses modesetting, and with both on the same driver, xrandr returns the following when you try to link them up:

X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  139 (RANDR)
  Minor opcode of failed request:  21 (RRSetCrtcConfig)
  Value in failed request:  0x0
  Serial number of failed request:  22
  Current serial number in output stream:  22

What does it mean? No idea.

How do we fix it? Bust out those crap-ass proprietary drivers.

Enter Manjaro Settings Manger, choose Hardware Configuration, and attain the following setup (the video-linux drivers may be optional, but they’re doing no harm so whatev):

3. Enable and configure the DisplayLink service

Per the instructions in the Arch Wiki, enable DisplayLink by typing in the terminal
sudo systemctl enable displaylink.service

Then, create a file at
with the contents

Section "OutputClass"
	Identifier "DisplayLink"
	MatchDriver "evdi"
	Driver "modesetting"
	Option  "AccelMethod" "none"

Note: It’s entirely possible that this step is obviated by use of the nVidia drivers, but I’m not taking chances.

4. Reboot

Just to make sure.

5. List the displays in xrandr

In the terminal, enter
xrandr --listproviders

With luck, you should see both displays, with their respective drivers:

Providers: number : 2
Provider 0: id: 0x1b8 cap: 0x1, Source Output crtcs: 4 outputs: 7 associated providers: 1 name:NVIDIA-0
Provider 1: id: 0x238 cap: 0x2, Sink Output crtcs: 1 outputs: 1 associated providers: 1 name:modesetting

6. Connect the displays in xrandr

In the terminal, enter
xrandr --setprovideroutputsource 1 0

If you’re lucky, this will mirror your displays. Of course, that’s probably not what you want, so let’s get them extended.

7. Configure Manjaro to extend your displays

Open Display Settings and declare your primary monitor as such (I’ve found that the USB monitor tends to be marked as primary, initially).

Uncheck Mirror Displays for obvious reasons.

Choose a resolution for your USB monitor that makes sense (probably not the same as your big-ass desktop monitor).

8. Have a lovely beverage

Celebrate your success. Or let me know if it failed. I probably can’t help, but hey who knows.

Posted by Adam Labay, 2 comments