I needed stable /dev names for several USB–serial adapters. For genuine FT232R devices you can store a short serial string in the chip EEPROM (up to 16 characters), then point udev rules at ATTRS{serial}==....
On a fresh Debian desktop the annoying failure was the linker error cannot find -lftd2xx: that is FTDI’s D2XX library, not libftdi-dev from apt. After installing the correct libftd2xx.so for x86_64, a small helper script had to unload pl2303 / cp210x (and friends) before usbserial, otherwise rmmod usbserial fails while other UART drivers still depend on it.
Below is a real run from 2026-04-18 showing the full happy path plus verification with only_read_serial.sh.
ATTRS{serial}).ttyUSBn rotation.libftdi-dev → open-source libFTDI (ftdi.h, -lftdi). Different stack.libftd2xx.so, ftd2xx.h, link with -lftd2xx. Download the Linux tarball from FTDI’s D2XX drivers page and install the .so (for amd64 use the x86_64 archive, not the x86_32 one).On Debian with multiarch, installing under /usr/lib/x86_64-linux-gnu/ plus ldconfig is fine; the tooling I use also searches /usr/local/lib.
usbserial still in useread_then_write_serial.sh has to drop ftdi_sio and usbserial so userspace D2XX can talk to the device during the write. On my box usbserial was still referenced by pl2303 and cp210x, so rmmod usbserial failed until those client modules were removed first. The script now unloads those dependents, performs the EEPROM write, then reloads usbserial → clients → ftdi_sio in a sane order.
$ sudo ./read_then_write_serial.sh SERTAC-WS7
[1/7] Current tty serial via udevadm (/dev/ttyUSB0)
ID_SERIAL=FTDI_FT232R_USB_UART_BG02PQ2N
ID_SERIAL_SHORT=BG02PQ2N
[2/7] Building EEPROM read tool
make: Nothing to be done for 'all'.
[3/7] Building EEPROM write tool
[4/7] Unloading kernel drivers (rmmod)
Unloaded: ftdi_sio
Unloaded usbserial client: pl2303
Unloaded usbserial client: cp210x
Unloaded: usbserial
[5/7] Writing new serial: SERTAC-WS7
=== FTDI EEPROM Serial Programmer ===
Found 1 FTDI device(s)
Current serial: BG02PQ2N
Programming new serial: SERTAC-WS7
✅ EEPROM updated successfully.
[7/7] Reloading kernel drivers (modprobe)
Loaded: usbserial
Loaded usbserial client: pl2303
Loaded usbserial client: cp210x
Loaded: ftdi_sio
…
$ ./only_read_serial.sh
Reading serial info from /dev/ttyUSB0
ID_SERIAL=FTDI_FT232R_USB_UART_SERTAC-WS7
ID_SERIAL_SHORT=SERTAC-WS7
So udevadm now sees ID_SERIAL_SHORT=SERTAC-WS7 without any extra rename tricks—this is coming from the device itself after reprogramming.
The scripts and README live in a small public repo (fork-friendly if you want to PR improvements):
read_then_write_serial.sh, only_read_serial.sh, and the EEPROM read/write sources under linux-x86_64/.Highlights from the README worth repeating here:
uname -m and the ELF class of libftd2xx.so).-lftd2xx (lab convenience; disable with FTDI_D2XX_NO_AUTO_DOWNLOAD=1 if you do not want network installs as root).Once the hardware serial is what you want, add or adjust rules under /etc/udev/rules.d/, run udevadm control --reload-rules && udevadm trigger, and usually replug once so the kernel and udev pick up the new attributes cleanly.
This post is a field note from my own desk setup; YMMV on kernels, module names, and counterfeit hardware.