Yago Fernandes.
POST_LOG

The Piece of Garbage: Cross-Compiling Wi-Fi for a Dying Laptop

The Day I Had to Compile a Wi-Fi Driver Without Internet

My mom has this laptop she recently started using for work.

Problem is, it was already slow and badly built when she bought it — about eight years ago — and even then it was probably new old stock. The CPU is from 2014. So yeah, we’re dealing with a 12-year-old machine that’s basically falling apart.

And I mean that literally.

First the webcam died. Then the trackpad. Then the hard drive started failing — I swapped that for an SSD. Then the Wi-Fi card died — I gave her a long Ethernet cable. Then the Ethernet port died.

At that point, she panicked.

So I said: okay, buy a USB wireless card — you’ll even get your Wi-Fi freedom back. She did and when it arrived about a day later, it didn’t work on her laptop. At this point I panicked. The adapter doesn’t start as a Wi-Fi device. It boots in USB mode with a tiny partition that contains Windows drivers. You’re supposed to install those, and then it “switches modes” into a proper wireless card.

That’s already annoying, but it becomes even more annoying when we add this detail: When I swapped the hdd for a ssd I made quite a fuss about migrating to Linux Mint on her laptop because Windows 10 was unusable on that hardware.

So now we have:

no built-in Wi-Fi no Ethernet a USB device that needs drivers drivers that assume Windows and a machine with no internet access

How do you make a device perform a mode-switch handshake on a machine that has no network, can’t download drivers, and doesn’t support the default installation path?

You don’t. Not directly.

Long story short, I couldn’t do it on her laptop. So I brought the device to my machine (Arch btw) found a repo with the driver online, compiled it and got it working. So i’m thinking “Success”, I’ll just copy the repo to a USB stick and compile it on her laptop, so there no cross-compiling shenanigans.

And that worked wonderfully for about 1 minute, untill it hit a missing dependency to compile the driver. Then I realized, the missing dependency will likely have other dependencies, so i’ll end up shuttling dependencies with a thumb drive for a eternity. We need a better solution.

Then I remember from a video fom Network Chuck where he ran full on vms with docker, it’s worth the watch: ()[https://www.youtube.com/watch?v=RUqGlWr5LBA&t=1430s]

From there on it actually pretty smooth sailing, with a ubuntu vm in docker you can get the entire toolchain in one go. You copy everything, and this time you know it’s actually everything, compile and install it there.

Okay. That’s the story. Here’s what actually happened under the hood.


First problem: the dongle wasn’t broken, it was pretending to be a CD-ROM.

Running lsusb showed ID a69c:5721 — AIC MSC. In that state, Linux just sees a 4MB flash drive with Windows drivers on it. No Wi-Fi, nothing to negotiate with.

To get it to flip into Wi-Fi mode, you use usb_modeswitch and send it a specific magic string to the firmware:

sudo usb_modeswitch -v 0xa69c -p 0x5721 \
  -M "5553424312345678000000000000061b000000020000000000000000000000"

After that, lsusb confirms the flip to a69c:8d80 — AIC Wlan. Now it’s a Wi-Fi chipset. Except the kernel has no driver for it. And the machine, as established, has no internet to go get one.

This is where it gets annoying.

Target environment: Linux Mint 22, kernel 6.17.0-14-generic. No internet. No build tools. No kernel headers. To compile a driver, you need all three, plus the driver source itself.

The approach: don’t try to fix it on her machine. Simulate her environment on mine.

docker run -it --rm -v ~/moms-driver/bundle:/bundle ubuntu:24.04 bash

Inside the container, use apt with --download-only to grab the .deb files for her exact kernel — nothing gets installed on my machine, everything lands in the shared volume:

apt update
apt install --download-only \
  build-essential dkms git linux-headers-6.17.0-14-generic
cp /var/cache/apt/archives/*.deb /bundle

Then drop the AIC8800 driver source in the same folder, move the whole bundle to her laptop via USB, and:

# Install the dependencies we just pre-fetched
sudo dpkg -i *.deb

# Build and install the driver
cd aic8800
make && sudo make install
sudo depmod -a
sudo modprobe aic8800_fdrv

Then sudo rfkill unblock all to bring the interface up. And it worked.

While I was in there — the machine is a 2014 Atom N2830, so a few more tweaks were worth doing. Blacklisted the dying internal Realtek card (rtl8192ce in /etc/modprobe.d/) so it stops competing. Set vm.swappiness=10 to reduce how aggressively it hits the SSD. Enabled zram-tools to give the 4GB RAM some extra breathing room. None of these are glamorous but the difference on a machine this old is real.

The thing that made this satisfying wasn’t the result — it’s just Wi-Fi. It was the shape of the solution. No hacks on her machine, no random guessing. Just: reproduce the environment somewhere else, build exactly what you need, carry it over. The container was the insight. Everything else was just execution.

COMMENTS