uhubctl
uhubctl는 스마트 USB 허브에서 포트별 USB 전원을 제어하는 유틸리티입니다.
스마트 허브는 포트별 전원 스위칭을 구현하는 허브로 정의됩니다.
이 코드의 원래 아이디어는 Niibe Yutaka의 hub-ctrl.c에서 영감을 받았습니다:
https://www.gniibe.org/development/ac-power-control-by-USB-hub
호환 USB 허브
포트별 전원 스위칭을 올바르게 지원하는 USB 허브는 많지 않습니다.
일부는 더 이상 생산되지 않아 구하기 어려울 수 있습니다.
다음은 알려진 호환 USB 허브 목록입니다:
| 제조사 | 제품 | 포트 | USB | VID:PID | 출시 | 단종 |
|---|
| Acer | BE270U 모니터 (참조) | 4 | 3.0 | 2109:2811 | 2016 | |
| AmazonBasics | HU3641V1 (RPi 문제) | 4 | 3.0 | 2109:2811 | 2013 | |
| AmazonBasics | HU3770V1 (RPi 문제) | 7 | 3.0 | 2109:2811 | 2013 | |
| AmazonBasics | HU9003V1EBL, HUC9003V1EBL | 7 | 3.1 | 2109:2817 | 2018 | |
| AmazonBasics | HU9002V1SBL, HU9002V1EBL, HU9002V1ESL, HHU9002V1EZPR01 (참고) | 10 | 3.1 | 2109:2817 | 2018 | |
| AmazonBasics | HUC9002V1SBL, HUC9002V1EBL, HUC9002V1ESL | 10 | 3.1 | 2109:2817 | 2018 | |
| AmazonBasics | U3-7HUB (충전 포트 1개에서만 작동) | 7 | 3.0 | 2109:2813 | 2020 | |
| Anker | AK-68ANHUB-BV7A-0004 (참고) | 7 | 3.0 | 2109:0812 |
이 표가 완전한 것은 아닙니다.
허브가 uhubctl에서 작동하지만 위 목록에 없다면
https://github.com/mvp/uhubctl/issues 에 새 이슈를 열어 보고해 주세요.
지원 표에 추가할 수 있습니다. 보고서에는 정확한 제품 모델을 제공하고
uhubctl의 출력을 추가해 주세요.
또한 아래 FAQ에 설명된 대로 VBUS off 지원을 테스트해 주세요.
상당수의 최신 마더보드에는 이 기능을 지원하는 내장 루트 허브가 있습니다.
외부 허브를 구매할 필요조차 없을 수도 있습니다.
USB 3.0 이중성 참고
USB 3.0 허브를 USB3 업스트림 포트에 연결하면 USB2와 USB3라는 두 개의 독립적인 가상 허브로 감지되며, USB 장치는 해당 장치의 기능과 연결 속도에 따라 USB2 또는 USB3 가상 허브에 연결됩니다.
이러한 허브의 전원을 제어하려면 전원 끄기/켜기 변경이 적용되도록 USB2와 USB3 가상 허브 모두의 전원을 꺼야/켜야 합니다. uhubctl은 이 작업을 자동으로 수행하려고 시도합니다 (-e 옵션으로 이 동작을 비활성화하지 않은 경우).
불행히도 대부분의 허브는 USB 데이터 연결을 차단하지만 일부는 포트에 대한 VBUS를 차단하지 않을 수 있습니다.
즉, 연결된 휴대폰이 uhubctl로 전원이 꺼진 포트에서 계속 충전될 수 있습니다.
설치
Linux 및 MacOS에서 uhubctl은 표준 패키지 관리자에서 사용할 수 있으며
다음 명령으로 설치할 수 있습니다:
- MacOS:
brew install uhubctl 또는 sudo port install uhubctl
- ⚠️ MacOS 26+는 libusb 1.0.30 이상이 필요합니다!
- Ubuntu/Debian/Raspbian:
sudo apt install uhubctl
- Redhat/EPEL/Fedora/CentOS:
sudo yum install uhubctl
- OpenSUSE:
sudo zypper install uhubctl
- FreeBSD:
cd /usr/ports/sysutils/uhubctl && sudo make install
그러나 표준 패키지 관리자에서 설치한 uhubctl이 반드시 최신 버전은 아닐 수 있으며, 현재 버전보다 크게 뒤처져 있을 수도 있습니다.
최신 릴리스 버전이 패키지 관리자가 제공하는 버전보다 최신이라면 아래 설명대로 소스에서 컴파일하여 설치해야 할 수 있습니다.
컴파일
이 유틸리티는 Linux (Ubuntu/Debian/Raspbian, Redhat/EPEL/Fedora/CentOS, Arch Linux, Gentoo, openSUSE, Buildroot), FreeBSD, NetBSD, SunOS 및 MacOS에서 컴파일 및 작동이 테스트되었습니다.
uhubctl은 Windows에서 컴파일되지만, libusb가 winusb.sys 드라이버를 사용하기 때문에 Windows에서는 USB 전원 스위칭이 작동하지 않습니다. Microsoft에 따르면 이 드라이버는 필요한 USB 제어 요청을 지원하지 않습니다.
libusb가 Windows에서 다른 드라이버를 지원하기 시작하면 이 문제가 해결될 수 있습니다.
pkgconf(또는 pkg-config) 유틸리티를 설치하는 것이 좋습니다 (기본적으로 설치되어 있는 경우가 많습니다).
먼저 libusb-1.0 라이브러리를 설치해야 합니다 (버전 1.0.13 이상 필요, 1.0.23 이상 권장):
- Ubuntu:
sudo apt-get install libusb-1.0-0-dev pkgconf
- Redhat:
sudo yum install libusb1-devel pkgconf
- OpenSUSE:
sudo zypper install libusb-1_0-devel pkgconf
- MacOS:
brew install libusb pkgconf, 또는 sudo port install libusb-devel pkgconf
- FreeBSD:
pkg install gmake pkgconf (libusb는 기본적으로 포함됩니다)
- NetBSD:
sudo pkgin install libusb1 gmake pkgconf
- Windows: 미정?
uhubctl 소스를 가져와 컴파일하려면:
git clone https://github.com/mvp/uhubctl
cd uhubctl
make
이렇게 하면 uhubctl 바이너리가 생성됩니다.
다음을 사용하여 시스템에 /usr/sbin/uhubctl로 설치할 수 있습니다:
일부 OS(예: FreeBSD/NetBSD)에서는 대신 gmake를 사용하여 빌드해야 합니다.
사용법
⚠️ Linux에서는 아래 설명대로 sudo를 사용하거나 USB 권한을 구성하세요!
지원되는 모든 허브를 나열하려면:
다음과 같이 USB 포트의 전원을 제어할 수 있습니다:
이는 기본 스마트 허브에서 포트 2(-p 2)의 전원을 끄는(-a off 또는 -a 0) 것을 의미합니다. 지원되는 동작은 off/on/cycle/toggle (또는 0/1/2/3)입니다.
cycle은 전원을 끈 후 -d로 구성 가능한 지연 시간을 기다렸다가 다시 켜는 것을 의미합니다.
포트는 쉼표로 구분된 목록일 수 있으며 범위에는 -를 사용할 수 있습니다. 예: 2, 2,4, , .> ⚠️ 내장 USB 포트를 끄면 키보드나 마우스가 끊길 수 있으므로,
어떤 포트를 끄는지 주의하세요!
스마트 USB 허브가 여러 개 연결되어 있다면 -l(위치) 매개변수를 사용하여
제어할 특정 허브를 선택해야 합니다.
허브 위치를 찾으려면 매개변수 없이 uhubctl을 실행하면 됩니다.
허브 위치는 b-x.y.z 형태입니다. 여기서 b는 USB 버스 번호이고, x, y, z...
는 해당 USB 버스의 루트 허브부터 시작하는 체인에 있는 모든 허브의 포트 번호입니다.
이 주소는 준안정적입니다. 동일한 물리적 USB 포트에 USB 장치를 뽑았다 다시 꽂거나(또는 껐다 켜도)
변경되지 않습니다(이 방법은 Linux 커널에서도 사용됩니다).
Linux USB 권한
Linux에서는 udev USB 권한을 구성해야 합니다(그렇지 않으면 sudo uhubctl을 사용하여 root로 실행해야 합니다).
Linux Kernel 6.0부터 USB 허브 포트를 켜거나 끌 수 있는 표준 인터페이스가 있으며,
uhubctl은 포트 상태를 설정하기 위해 (libusb 대신) 이를 사용하려고 시도합니다.
이것이 6.0+ 커널에 대한 추가 규칙이 있는 이유입니다.
이러한 규칙을 이전 커널 버전을 실행하는 시스템에 두어도 문제는 없습니다.
USB 권한을 수정하려면 먼저 sudo uhubctl을 실행하고 제어해야 할 허브의 모든 vid:pid를 기록하세요.
그런 다음 아래와 같은 udev 규칙을 /etc/udev/rules.d/52-usb.rules 파일에 추가하세요.
(2001을 허브 공급업체 ID로 바꾸거나, 모든 USB 허브 접근을 허용하려면 ATTR{idVendor} 필터를 완전히 제거하세요):
SUBSYSTEM=="usb", DRIVER=="hub|usb", MODE="0666", ATTR{idVendor}=="2001"
# Linux 6.0 or later (its ok to have this block present for older Linux kernels):
SUBSYSTEM=="usb", DRIVER=="hub|usb", \
RUN="/bin/sh -c \"chmod -f 666 $sys$devpath/*port*/disable || true\""
USB3 허브의 경우 일부 허브는 동일한 칩의 USB2 구성 요소와 USB3 구성 요소에 대해 서로 다른 공급업체 ID를 사용합니다.
uhubctl이 제대로 작동하려면 두 구성 요소 모두 권한이 필요합니다.
예를 들어 Raspberry Pi 4B의 경우 다음 2줄을 추가해야 합니다(또는 idVendor 필터를 제거하세요):
SUBSYSTEM=="usb", DRIVER=="hub|usb", MODE="0666", ATTR{idVendor}=="2109"
SUBSYSTEM=="usb", DRIVER=="hub|usb", MODE="0666", ATTR{idVendor}=="1d6b"
완전히 개방된 모드 0666이 마음에 들지 않으면 다음과 같이 그룹별로 접근을 제한할 수 있습니다:
SUBSYSTEM=="usb", DRIVER=="hub|usb", MODE="0664", GROUP="dialout"
# Linux 6.0 or later (its ok to have this block present for older Linux kernels):
SUBSYSTEM=="usb", DRIVER=="hub|usb", \
RUN+="/bin/sh -c \"chown -f root:dialout $sys$devpath/*port*/disable || true\"" \
RUN+="/bin/sh -c \"chmod -f 660 $sys$devpath/*port*/disable || true\""
그런 다음 허용할 사용자를 dialout 그룹에 추가하세요:
sudo usermod -a -G dialout $USER
udev 규칙 변경 사항을 적용하려면 재부팅하거나 다음을 실행하세요:
sudo udevadm trigger --attr-match=subsystem=usb
편의를 위해 바로 사용할 수 있는 udev 규칙이 여기에 제공됩니다.
FAQ
USB 포트별 전원 스위칭이란 무엇인가요?
USB 2.0 사양에 따르면 USB 허브는 전원 스위칭 없음,
갱(ganged, 모든 포트를 동시에) 전원 스위칭 또는 포트별(개별) 전원 스위칭을 광고할 수 있습니다.
기본적으로 uhubctl은 포트별 전원 스위칭을 지원하는 USB 허브만 감지합니다.
(-f 옵션을 사용하면 지원되지 않는 허브에서도 작동을 시도하도록 강제할 수 있습니다.)
하드웨어가 지원하는 전원 스위칭 종류는 sudo lsusb -v를 사용하여 확인할 수 있습니다:
전원 스위칭 없음:
wHubCharacteristic 0x000a
No power switching (usb 1.0)
Per-port overcurrent protection
갱 전원 스위칭:
wHubCharacteristic 0x0008
Ganged power switching
Per-port overcurrent protection
포트별 전원 스위칭:
wHubCharacteristic 0x0009
Per-port power switching
Per-port overcurrent protection
uhubctl이 내 USB 허브를 지원하는지 어떻게 확인하나요?
sudo uhubctl을 실행하세요. 허브가 나열되지 않으면 지원되지 않는 것입니다.
또는 sudo lsusb -v를 실행하고 Per-port power switching이 있는지 확인하세요.
lsusb 출력에서 해당 줄을 볼 수 없다면
허브는 지원되지 않습니다.
- VBUS(전압) 차단 지원을 확인하세요: 휴대폰, USB 조명
또는 USB 팬을 허브의 USB 포트에 연결하세요.
uhubctl을 사용하여 해당 포트의 전원을 끄고,
휴대폰 충전이 중지되고 USB 조명이 꺼지거나 USB 팬이 멈추는지 확인하세요.
VBUS가 꺼지지 않는다면, 허브 제조사가 실제로 전원을 차단하는 회로를
포함하지 않은 것입니다. 이러한 허브는 여전히 USB 데이터 연결을 차단하는 데는
작동하지만, 전원을 끌 수는 없으며,
우리는 이를 지원되는 장치로 간주하지 않습니다.
- 위 테스트가 성공했다면, 허브를 보고해 주세요.
https://github.com/mvp/uhubctl/issues 에 새 이슈를 열어
지원 장치 목록에 추가할 수 있도록 해주세요.
이미 나열된 지원 모델의 다른 하드웨어 개정판이 아니라면 지원되지 않는 허브를
보고하지 마세요.
Linux에서 포트 전원을 끈 후에도 USB 장치가 제거되지 않습니다
USB 포트의 전원을 끈 후에는 udev가 어떤 이벤트도 받지 못하므로 장치 파일을 계속 유지합니다.
그러나 장치 파일에 접근하려고 하면 IO 오류가 발생합니다.
이것은 Linux 커널 이슈이며, Linux 커널 6.0 이상 시스템에서 uhubctl 2.5.0부터 수정되었습니다.
여전히 Linux 5.x 이하를 사용 중이라면 이 문제에 대한 다음 해결 방법을 사용할 수 있습니다:
sudo uhubctl -a off -l ${location} -p ${port}
sudo udevadm trigger --action=remove /sys/bus/usb/devices/${location}.${port}/
장치 파일은 udev에 의해 제거되지만 USB 장치는 lsusb에서 여전히 보입니다.
/sys/bus/usb/devices/${location}.${port} 경로는 해당 포트에서 장치가 감지된 경우에만 존재합니다.
전원을 다시 켜면 장치가 제대로 다시 열거됩니다(udevadm을 다시 호출할 필요 없음).
Linux에서 몇 초 후에 전원이 다시 켜집니다
일부 커널의 장치 드라이버는 USB 장치가 꺼지는 것에 놀라서 자동으로 전원을 다시 켜려고 시도합니다.
이것은 Linux 커널 이슈이며, Linux 커널 6.0 이상 시스템에서 uhubctl 2.5.0부터 수정되었습니다.
여전히 Linux 5.x 이하를 사용 중이라면:
-r N 옵션을 사용할 수 있습니다. 여기서 N은 10에서 1000 사이의 숫자로, 이 문제를 해결합니다.
uhubctl은 빠르게 연속해서 여러 번 전원을 끄려고 시도하며, 이로 인해 전원 복구를 억제할 수 있어야 합니다.
전원을 끄기 전에 해당 장치의 USB 인증을 비활성화하는 것도 도움이 될 수 있습니다:
echo 0 > sudo tee /sys/bus/usb/devices/${location}.${port}/authorized
장치가 USB 대용량 저장소라면 uhubctl을 호출하기 전에 udisksctl을 호출하는 것도 도움이 됩니다:
sudo udisksctl power-off --block-device /dev/disk/...`
sudo uhubctl -a off ...
4포트 허브 여러 개가 감지되는데 7포트 허브 하나만 연결했습니다
많은 허브 제조사는 기본 4포트 USB 칩을 사용하여 USB 허브를 만듭니다.
예를 들어 7포트 허브를 만들기 위해 4포트 허브 두 개를 데이지 체인으로 연결합니다. 체인 연결에 1포트가 사용되므로
4+4-1=7포트 허브가 됩니다. 마찬가지로 10포트 허브는 4포트 허브 3개를 데이지 체인으로 연결하여
4+4+4-2=10개의 사용 가능한 포트를 제공합니다.
내부 허브를 서로 데이지 체인으로 연결하는 데 사용되는 포트의 전원 상태를 절대 변경하려고 시도하지 마세요.
그렇게 하면 내부 허브 회로가 혼란스러워져 예측할 수 없는 동작이 발생합니다.
Raspberry Pi가 지정한 포트뿐만 아니라 모든 포트의 전원을 끕니다
이것은 Raspberry Pi 하드웨어 설계의 한계입니다.
해결 방법으로 위의 지원 목록에 있는 외부 USB 허브를 구입하여 Raspberry Pi의 아무 USB 포트에 연결하고,
각 포트의 전원을 독립적으로 제어할 수 있습니다.
또한 Raspberry Pi 전용으로 설계된 지원 허브도 있습니다(예: UUGear MEGA4).
참고로 지원되는 Raspberry Pi 모델의 내부 USB 토폴로지는 다음과 같습니다:
Raspberry Pi B+,2B,3B
-
단일 허브 1-1, 포트 2-5는 갱(ganged)으로 연결되며 모두 포트 2로 제어됩니다:
포트 3,4,5를 제어하려고 해도 아무 일도 일어나지 않습니다.
포트 1은 Ethernet+WiFi의 전원을 제어합니다.
Raspberry Pi 3B+
-
메인 허브 1-1, 4개 포트 모두 갱(ganged)이며 모두 포트 2로 제어됩니다(보조 허브 포트도 꺼집니다).
포트 1은 아래 허브 1-1.1에 연결되며, 포트 2와 3은 외부로 배선되고 포트 4는 배선되지 않습니다.
-
보조 허브 1-1.1(메인에 데이지 체인 연결): 3개 포트,
포트 1은 Ethernet+WiFi에 사용되고 포트 2와 3은 외부로 배선됩니다.
Raspberry Pi 4B
⚠️ VL805 펌웨어가 00137ad보다 오래된 경우(sudo rpi-eeprom-update로 확인),
RPi 4B에서 전원 스위칭이 작동하도록 펌웨어를 업데이트해야 합니다.
-
USB2 허브 1, 1개 포트, 아래 허브 1-1에만 연결됩니다.
-
USB2 허브 1-1, 4개 포트 갱(ganged), 아래 USB3 허브 2와 이중(dual)입니다:
-
USB3 허브 2, 4개 포트 갱(ganged), 위 USB2 허브 1-1과 이중(dual)입니다:
-
USB2 허브 3, 1개 포트, OTG 컨트롤러. 전원 스위칭은 지원되지 않습니다.
Raspberry Pi 5
Raspberry Pi 5에는 USB2 포트 2개와 USB3 포트 2개(총 4개)가 있습니다.
이 포트들은 정말 이상한 구성으로 4개의 서로 다른 USB 허브 1,2,3,4에 연결됩니다.
(하지만 OS와 HW 개정판에 따라 관심 있는 허브는 2,3,4,5일 수 있습니다.)
USB3 장치가 파란색 소켓에 연결되면 USB3 허브 2 또는 4에서 감지됩니다.
USB2 장치가 어떤 소켓에 연결되거나 USB3 장치가 검은색 소켓에 연결되면
USB2 허브 1 또는 3에서 감지됩니다.
USB2/USB3 연결 유형과 관계없이 파란색 소켓은 항상 포트 1이고,
검은색 소켓은 항상 포트 2입니다.
온보드 USB 허브 4개 각각은 포트별 전원 스위칭을 지원한다고 광고하지만 이는 사실이 아닙니다.
실제로 Raspberry Pi 5의 4개 포트는 모두 하나의 그룹으로 갱(ganged)되어 있으며,
4개의 서로 다른 논리적 USB 허브에 속해 있습니다.
VBUS 전원을 끄려면 모든 온보드 허브와 포트에서 VBUS를 비활성화해야 합니다: ```
uhubctl -l 2 -a 0
uhubctl -l 4 -a 0
다시 켜려면: ```
uhubctl -l 2 -a 1
uhubctl -l 4 -a 1
참고: VBUS 전원은 모든 포트가 꺼진 경우에만 차단됩니다. 포트 하나만 활성화해도 4개 포트 모두에 VBUS 전원이 다시 공급됩니다.
uhubctl을 사용하는 주요 프로젝트
저작권
Copyright (C) 2009-2026 Vadim Mikhailov
이 파일은 GNU General Public License 버전 2의 약관 및 조건에 따라 배포할 수 있습니다.