Categories
AI Fun Linux Nerd Sniped Projects

Snooping USB with GPT

I mentioned in my previous post about the Juicy Crumb DockLite G4 that there were two shortcomings with the product:

  1. Their software to control the brightness of the display was macOS only.
  2. The display doesn’t support sleep, so you’re required to press a physical button to turn off the backlight.

Thanks to some USB packet snooping and GPT, both of these problems were solved quickly. 😎

I wanted Linux software control

What started this exploration was that I wanted to control the display from Linux because it’s currently connected to a Raspberry Pi, not a Mac.

Step 0: Check for an open source repo

Negative. I didn’t spot anything, so it’ll take a little more grunt work. I did run their helper app through a disassembler and spotted functions like getting and setting the backlight via IOKit which were all expected. It wasn’t necessary to go this far, it just confirms that we have some USB packet snooping to do.

Step 1: Get lsusb output

Running lsusb with the display connected to the RPi showed:

Bus 001 Device 009: ID 4a43:1d8a Juicy Crumb Systems DockLite

So I grabbed the output of lsusb -v -d 4a43:1d8a to feed it to the LLM later to provide more details about its USB specs.

Step 2: Capture USB packets on the Mac

The double-edged sword of Apple’s security is that it introduces all sorts of challenges for devs who need to get to lower level functionality, like capturing raw data from interfaces.

To successfully USB capture packets on a Mac I had to:

  1. Disable SIP
  2. Bring up the USB controller interface (in my case there were a couple, so through trial-and-error I found the right one)
  3. Tell Wireshark to capture on that interface
  4. Change the brightness using the Juicy-Link app to generate packets
  5. Save the capture to a file

Step 3: Feed the LLM

With the data from steps 1 and 2 I:

  • Fed them to ChatGPT
  • Mentioned that the capture was from a utility setting the brightness
  • Asked for an equivalent Python script

Here’s what it produced.

Step 4: Run the script in Linux

After installing the pyusb module I could run python set-brightness.py 700 and it worked from Linux! The range from lowest backlight brightness to highest is around 700 – 5000.

The extra bonus (which I’m most excited about) is that sending a value of 0 will truly turn off the backlight! This isn’t even (currently) possible with their software. (Obligatory “do this at your own risk”)

Now I can hook into something like D-Bus signals to potentially toggle the display depending on the desktop’s locked state.

Success

✅ The display’s brightness can be set from any OS, not just macOS.

✅ The display’s backlight can be turned off via software.

Thanks GPT! 🤖

Categories
Linux Tutorials

LVM to the rescue

Root problem

I’ve been running Debian 12 for a while on my Linux desktop and recently ran into a big issue: My root volume ran out of space. Never good.

In the past I would’ve taken the path of least discomfort (for me): Clean install, repartition differently, start fresh. Because I’d used LVM when installing, however, I had another option this time:

On small systems (like a desktop), instead of having to estimate at installation time how big a partition might need to be, LVM allows filesystems to be easily resized as needed.

Wikipedia

Goal

I want to expand the root volume by shrinking the home volume a little bit. Let’s see how easy it really is with LVM!

Prerequisites

My environment was an x64 box running Debian 12 containing a single 1TB SSD. I didn’t add any physical drives, I only adjusted the space allotted to the LVM volumes.

Live image

I used a live install image to boot Linux without installing anything. After downloading the image I used dd to copy it to a USB flash drive. When booting on Debian, you’ll need to select the “Rescue mode” and follow the menus to get to a shell. When asked about using a root filesystem, tell it not to mount anything.

Figure out paths and numbers

To make this tutorial generic, we’re going to define four variables. Two for the volume paths, one for the amount we’re going to grow the smaller volume, and one for the amount we’re going to shrink the bigger volume.

Paths

There are plenty of ways to figure out the paths to the volumes you’ll be using, but lvdisplay works well.

shrinkPath = path of volume to want to shrink
growPath = path of volume to want to grow

Numbers

We’ll also need to define the growth amount of the growing volume and the new size of the shrinking volume.

growthAmount = how much we want the volume at growPath to grow
newShrinkSize = current size of the volume at shrinkPathgrowthAmount

Example

We have a root volume we want to grow by 30GB as well as a home volume (currently 900GB) that we need to shrink.

shrinkPath = /dev/debian-vg/home
growPath = /dev/debian-vg/root
growthAmount = 30G
newShrinkSize = 870G (which is 900-30)

Note: Gigabyte units are assumed in this example, hence the G after the 30 and 870.

Steps

⚠️ Complete these at your own risk! Any time you change filesystems you run the risk of data loss, so backup your stuff!

  1. Boot into a recovery mode without mounting any filesystems.
  2. e2fsck -f {shrinkPath} to check for errors.
    • Example: e2fsck -f /dev/debian-vg/home
  3. resize2fs {shrinkPath} {newShrinkSize} to shrink the filesystem.
    • Example: resize2fs /dev/debian-vg/home 870G
    • Important: Be sure to include the appropriate size unit after the new shrink size, like G for gigabytes. See the resize2fs man page.
  4. lvreduce -L -{growthAmount} {shrinkPath} to shrink the LVM volume.
    • Example: lvreduce -L -30G /dev/debian-vg/home
    • Note: Some tutorials accomplish steps 4 and 5 in one go via lvreduce --resizefs but this did not work for me, so I had to break it out into two steps.
    • Important: Be sure to include the appropriate size unit after the growth amount, like G for gigabytes. See the lvreduce man page.
  5. resize2fs {shrinkPath} to extend the partition to fit the volume.
    • Example: resize2fs /dev/debian-vg/home
  6. vgdisplay -C should show {growthAmount} free.
  7. e2fsck -f {growPath} to check for errors.
    • Example: e2fsck -f /dev/debian-vg/root
  8. lvextend -l +100%FREE {growPath} to grow the volume to 100% of the available Volume Group size.
    • Example: lvextend -l +100%FREE /dev/debian-vg/root
  9. resize2fs {growPath} to grow the filesystem to the available space.
    • Example: resize2fs /dev/debian-vg/root
  10. vgdisplay -C should show no free space
  11. You should be all done and free to reboot!