Skip to content

Commit c594edb

Browse files
committed
Using PHZ temporary Lima code to force the use of qemu-xhci,id=usb on QEMU
1 parent 46ccc05 commit c594edb

6 files changed

Lines changed: 138 additions & 24 deletions

File tree

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,10 @@ https://github.com/user-attachments/assets/14b6d50f-5250-420e-94e4-474991113372
114114
Docker Desktop and Podman on macOS **cannot forward USB devices** (SDR dongles, HackRF, RTL-SDR, etc.) into containers. RF Swift solves this with **Lima**, which runs a QEMU VM with USB hot-plug support:
115115

116116
```bash
117-
# Install Lima
118-
brew install lima
117+
# Install Lima (PentHertz fork with USB passthrough support) + QEMU
118+
brew install qemu
119+
curl -fsSL https://github.com/PentHertz/lima/releases/download/v2.1.1/lima-2.1.1-Darwin-$(uname -m).tar.gz -o /tmp/lima.tar.gz
120+
sudo tar xz -C /usr/local -f /tmp/lima.tar.gz
119121

120122
# Attach your SDR dongle to the Lima VM
121123
rfswift macusb list # see host USB devices

get_rfswift.sh

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -980,12 +980,7 @@ offer_lima_for_usb_get_rfswift() {
980980
fi
981981
else
982982
if prompt_yes_no " Would you like to install Lima for USB passthrough?" "n"; then
983-
if command_exists brew; then
984-
brew install lima qemu
985-
color_echo "green" " Lima installed. Use 'rfswift --engine lima' when you need USB devices."
986-
else
987-
color_echo "red" " Homebrew is required. Install it first: https://brew.sh/"
988-
fi
983+
install_lima_fork
989984
fi
990985
fi
991986
}
@@ -1087,15 +1082,7 @@ check_container_engine() {
10871082
if [ "$(uname -s)" = "Darwin" ]; then
10881083
# Lima option on macOS
10891084
color_echo "blue" "🦙 Installing Lima..."
1090-
if command_exists brew; then
1091-
brew install lima qemu
1092-
color_echo "green" "✅ Lima installed."
1093-
color_echo "cyan" " RF Swift will auto-create a QEMU VM on first 'rfswift run'."
1094-
color_echo "cyan" " Or create one manually: limactl create --name rfswift lima/rfswift.yaml"
1095-
else
1096-
color_echo "red" "❌ Homebrew is required. Install it first: https://brew.sh/"
1097-
return 1
1098-
fi
1085+
install_lima_fork
10991086
else
11001087
color_echo "yellow" "⚠️ Container engine installation skipped."
11011088
color_echo "yellow" " You will need Docker or Podman before using RF-Swift."
@@ -1134,6 +1121,65 @@ check_container_engine() {
11341121
# Podman Installation
11351122
# ═══════════════════════════════════════════════════════════════════════════════
11361123

1124+
# Install Lima from PentHertz fork (with USB passthrough support) + QEMU
1125+
LIMA_VERSION="2.1.1"
1126+
LIMA_RELEASE_BASE="https://github.com/PentHertz/lima/releases/download/v${LIMA_VERSION}"
1127+
1128+
install_lima_fork() {
1129+
if [ "$(uname -s)" != "Darwin" ]; then
1130+
color_echo "yellow" "Lima is only needed on macOS for USB passthrough."
1131+
return 0
1132+
fi
1133+
1134+
if ! command_exists brew; then
1135+
color_echo "red" "Homebrew is required to install QEMU."
1136+
color_echo "yellow" "Install Homebrew: https://brew.sh/"
1137+
return 1
1138+
fi
1139+
1140+
# Install QEMU via Homebrew
1141+
if ! command_exists qemu-img; then
1142+
color_echo "blue" "Installing QEMU via Homebrew..."
1143+
brew install qemu
1144+
fi
1145+
1146+
# Remove Homebrew Lima if present (we use the PentHertz fork)
1147+
if brew list lima &>/dev/null; then
1148+
color_echo "yellow" "Removing Homebrew Lima in favor of PentHertz fork (USB support)..."
1149+
brew uninstall lima
1150+
fi
1151+
1152+
local arch
1153+
arch=$(uname -m)
1154+
case "$arch" in
1155+
arm64|aarch64) arch="arm64" ;;
1156+
x86_64|amd64) arch="x86_64" ;;
1157+
*)
1158+
color_echo "red" "Unsupported architecture: $arch"
1159+
return 1
1160+
;;
1161+
esac
1162+
1163+
local tarball="lima-${LIMA_VERSION}-Darwin-${arch}.tar.gz"
1164+
local url="${LIMA_RELEASE_BASE}/${tarball}"
1165+
local tmp="/tmp/${tarball}"
1166+
1167+
color_echo "blue" "Installing Lima ${LIMA_VERSION} (PentHertz fork with USB support)..."
1168+
curl -fsSL "$url" -o "$tmp"
1169+
sudo tar xz -C /usr/local -f "$tmp"
1170+
rm -f "$tmp"
1171+
1172+
if ! command_exists limactl; then
1173+
color_echo "red" "Lima installation failed — limactl not found in PATH."
1174+
color_echo "yellow" "Ensure /usr/local/bin is in your PATH."
1175+
return 1
1176+
fi
1177+
1178+
color_echo "green" "✅ Lima ${LIMA_VERSION} (PentHertz fork) and QEMU installed."
1179+
limactl --version
1180+
color_echo "cyan" " Use 'rfswift --engine lima' when you need USB devices."
1181+
}
1182+
11371183
install_podman() {
11381184
color_echo "blue" "🦭 Installing Podman..."
11391185

@@ -2331,7 +2377,7 @@ main() {
23312377
color_echo "cyan" " Or let RF Swift auto-create it on first 'rfswift run' when no Docker/Podman is found."
23322378
fi
23332379
else
2334-
color_echo "yellow" " Lima is not installed. Install with: brew install lima qemu"
2380+
color_echo "yellow" " Lima is not installed. Run the installer or see https://github.com/PentHertz/lima/releases"
23352381
color_echo "cyan" " After installing, RF Swift can auto-manage a QEMU VM with USB passthrough."
23362382
color_echo "cyan" " USB commands: rfswift macusb list | attach | detach | status"
23372383
fi

go/rfswift/dock/engine_lima.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ func findLimaTemplate() string {
281281
func createLimaInstanceInline(instance string) error {
282282
template := `# RF Swift Lima VM - auto-generated
283283
vmType: qemu
284+
usb: true
284285
cpus: 4
285286
memory: "8GiB"
286287
disk: "100GiB"

go/rfswift/rfutils/hostcli_mac.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,24 @@ func AttachUSBToLima(vendorID, productID, instance string) error {
239239
return fmt.Errorf("failed to attach USB device %s:%s: %w", vendorID, productID, err)
240240
}
241241

242+
// If no USB bus exists, add a qemu-xhci controller and retry
243+
if result != "" && strings.Contains(result, "No 'usb-bus' bus found") {
244+
addBusCmd := "device_add qemu-xhci,id=usb-bus"
245+
busResult, busErr := qmpHumanCommand(sockPath, addBusCmd)
246+
if busErr != nil {
247+
return fmt.Errorf("failed to add USB controller: %w (ensure Lima YAML has 'usb: true')", busErr)
248+
}
249+
if busResult != "" && strings.Contains(strings.ToLower(busResult), "error") {
250+
return fmt.Errorf("failed to add USB controller: %s (ensure Lima YAML has 'usb: true')", busResult)
251+
}
252+
253+
// Retry the device attach now that the USB bus exists
254+
result, err = qmpHumanCommand(sockPath, hmpCmd)
255+
if err != nil {
256+
return fmt.Errorf("failed to attach USB device %s:%s after adding USB controller: %w", vendorID, productID, err)
257+
}
258+
}
259+
242260
if result != "" && strings.Contains(strings.ToLower(result), "error") {
243261
return fmt.Errorf("QMP device_add failed: %s", result)
244262
}

lima/rfswift.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@
1212
# rfswift macusb status # Check setup status
1313
#
1414
# IMPORTANT: vmType must be "qemu" for USB passthrough (not "vz")
15-
# Prerequisites: brew install lima qemu
15+
# Prerequisites: QEMU (brew install qemu) + Lima from https://github.com/PentHertz/lima/releases
1616

1717
# Use QEMU backend - required for USB passthrough via QMP
1818
vmType: qemu
1919

20+
# Enable USB controller (qemu-xhci) for USB device passthrough without requiring a display
21+
usb: true
22+
2023
# VM resources - adjust as needed for your SDR workloads
2124
cpus: 4
2225
memory: "8GiB"

scripts/common.sh

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,15 +1264,20 @@ is_lima_instance_running() {
12641264
limactl list --json 2>/dev/null | grep "\"name\":\"${instance}\"" | grep -q "\"status\":\"Running\""
12651265
}
12661266

1267-
# Install Lima and QEMU on macOS via Homebrew
1267+
# Lima version and release URL (PentHertz fork with USB passthrough support)
1268+
LIMA_VERSION="2.1.1"
1269+
LIMA_RELEASE_BASE="https://github.com/PentHertz/lima/releases/download/v${LIMA_VERSION}"
1270+
1271+
# Install the PentHertz fork of Lima (with usb: true support) and QEMU on macOS
12681272
install_lima() {
12691273
if [[ "$(uname -s)" != "Darwin" ]]; then
12701274
echo -e "${YELLOW}Lima is only needed on macOS for USB passthrough.${NC}"
12711275
return 0
12721276
fi
12731277

1278+
# QEMU still comes from Homebrew
12741279
if ! command_exists brew; then
1275-
echo -e "${RED}Homebrew is required to install Lima.${NC}"
1280+
echo -e "${RED}Homebrew is required to install QEMU.${NC}"
12761281
echo -e "${YELLOW}Install Homebrew: /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"${NC}"
12771282
return 1
12781283
fi
@@ -1282,9 +1287,47 @@ install_lima() {
12821287
return 0
12831288
fi
12841289

1285-
echo -e "${BLUE}Installing Lima and QEMU for USB passthrough support...${NC}"
1286-
brew install lima qemu
1287-
echo -e "${GREEN}Lima and QEMU installed successfully.${NC}"
1290+
# Install QEMU via Homebrew
1291+
if ! command_exists qemu-img; then
1292+
echo -e "${BLUE}Installing QEMU via Homebrew...${NC}"
1293+
brew install qemu
1294+
fi
1295+
1296+
# Remove Homebrew Lima if present (we use the PentHertz fork)
1297+
if brew list lima &>/dev/null; then
1298+
echo -e "${YELLOW}Removing Homebrew Lima in favor of PentHertz fork (USB support)...${NC}"
1299+
brew uninstall lima
1300+
fi
1301+
1302+
# Install PentHertz Lima from GitHub release
1303+
local arch
1304+
arch=$(uname -m)
1305+
case "$arch" in
1306+
arm64|aarch64) arch="arm64" ;;
1307+
x86_64|amd64) arch="x86_64" ;;
1308+
*)
1309+
echo -e "${RED}Unsupported architecture: $arch${NC}"
1310+
return 1
1311+
;;
1312+
esac
1313+
1314+
local tarball="lima-${LIMA_VERSION}-Darwin-${arch}.tar.gz"
1315+
local url="${LIMA_RELEASE_BASE}/${tarball}"
1316+
local tmp="/tmp/${tarball}"
1317+
1318+
echo -e "${BLUE}Installing Lima ${LIMA_VERSION} (PentHertz fork with USB support)...${NC}"
1319+
curl -fsSL "$url" -o "$tmp"
1320+
sudo tar xz -C /usr/local -f "$tmp"
1321+
rm -f "$tmp"
1322+
1323+
if ! command_exists limactl; then
1324+
echo -e "${RED}Lima installation failed — limactl not found in PATH.${NC}"
1325+
echo -e "${YELLOW}Ensure /usr/local/bin is in your PATH.${NC}"
1326+
return 1
1327+
fi
1328+
1329+
echo -e "${GREEN}Lima ${LIMA_VERSION} (PentHertz fork) and QEMU installed successfully.${NC}"
1330+
limactl --version
12881331
}
12891332

12901333
# Offer to update the Lima template if a newer one ships with the installation.
@@ -1445,6 +1488,7 @@ setup_lima_instance() {
14451488
local tmp_template=$(mktemp /tmp/rfswift-lima-XXXXXX.yaml)
14461489
cat > "$tmp_template" << 'LIMAEOF'
14471490
vmType: qemu
1491+
usb: true
14481492
cpus: 4
14491493
memory: "8GiB"
14501494
disk: "100GiB"

0 commit comments

Comments
 (0)