본 포스팅은 tinypilot 도커 컨테이너화 과정의 일부로 tinypilot 에서 라즈베리 파이 의 usb 포트를 키보드, 마우스 처럼 주변 장치로 인식 하게 만들기 위한 과정을 담고 있음.
용어 정리
- dwc2 (DesignWare USB 2.0)
- 정의:
dwc2
는 Synopsys사의 DesignWare USB 2.0 호스트/디바이스 컨트롤러 IP를 위한 Linux 커널 드라이버임. - 역할: 라즈베리 파이와 같은 장치가 USB Device 모드(즉, 주변 장치 모드)에서 작동할 수 있도록 지원함.
- 호스트 모드: 라즈베리 파이가 USB 키보드, 마우스 등의 주변 장치를 연결해 사용할 수 있는 기본 모드.
- 디바이스 모드: 라즈베리 파이가 USB 주변 장치로 동작할 수 있는 모드. 예를 들어, USB 키보드, 마우스, 가상 네트워크 어댑터 등으로 변신할 수 있음.
- 용도: 라즈베리 파이가 USB 장치로 작동하도록 하려면
dwc2
모듈을 활성화해야 함. 이를 통해 라즈베리 파이를 USB 주변 장치처럼 사용할 수 있게 됨.
- 정의:
- g_ether (USB Gadget Ethernet)
- 정의:
g_ether
는 Linux USB Gadget 프레임워크의 드라이버로, USB 포트를 통해 가상 네트워크 인터페이스를 제공함. 이를 통해 라즈베리 파이가 USB 이더넷 어댑터처럼 동작할 수 있음. - 역할: USB 포트를 사용하여 호스트 시스템과 네트워크 연결을 제공함. 라즈베리 파이와 호스트 컴퓨터 간에 네트워크 통신이 가능해짐.
- 용도:
g_ether
를 사용하면 라즈베리 파이를 USB로 연결된 네트워크 인터페이스처럼 사용할 수 있으며, 이를 통해 네트워크 액세스, 파일 전송, 네트워크 디버깅 등을 수행할 수 있음. - 주의점:
g_ether
가 활성화되면, USB Device Controller(UDC)를 점유하게 되어 다른 USB Gadget 드라이버(예: HID 장치)를 사용할 수 없게 됨. 따라서g_ether
를 사용하려면 다른 USB Gadget 드라이버와의 충돌을 피하기 위해 적절히 관리해야 함.
- 정의:
- UDC (USB Device Controller)
- 정의: UDC(USB Device Controller)는 USB 장치 모드에서 USB 통신을 관리하는 하드웨어 컨트롤러임.
- 역할: USB 디바이스 모드에서 라즈베리 파이의 USB 포트를 관리하고, 호스트 시스템과의 데이터 통신을 담당함. USB Gadget 드라이버(
g_ether
,hid
, 등)가 UDC를 통해 USB 연결을 설정하고 유지함. - 용도: 라즈베리 파이와 같은 장치에서 다양한 USB 장치 기능(HID, Mass Storage, Ethernet 등)을 수행할 수 있도록 함. 하지만, UDC는 한 번에 하나의 드라이버만 지원하므로, 여러 USB Gadget 드라이버를 동시에 사용하려면 이를 고려하여 적절히 관리해야 함.
- 상태 관리: UDC가 "busy" 상태가 되면, 현재 다른 USB Gadget 드라이버가 UDC를 사용하고 있음을 의미함. 따라서 새로운 USB 기능을 추가하려면 "busy" 상태를 해제해야 함.
계층 구조에 대한 설명
UDC
(USB Device Controller) — 저급 계층- 정의: USB 하드웨어 컨트롤러로, USB 통신을 물리적으로 처리하는 장치.
- 역할: USB 호스트(예: PC)와의 직접적인 데이터 전송 및 통신을 담당함.
- 위치: USB 제어의 가장 저급 계층에서 작동하여 하드웨어 단에서 직접적인 USB 통신을 처리함.
dwc2
(USB 컨트롤러 드라이버) — 중간 계층- 정의: UDC를 관리하고 제어하는 소프트웨어 드라이버.
- 역할: UDC의 하드웨어 기능을 제어하고, USB 디바이스 모드에서의 동작을 가능하게 함.
- 위치: USB 제어의 미들 계층에 위치하여, UDC를 직접 제어하는 역할을 수행함.
g_ether
(USB Gadget 드라이버) — 상위 계층(고급 계층)- 정의: USB Gadget 프레임워크의 드라이버로, USB를 통해 가상 네트워크 인터페이스를 제공함.
- 역할: USB 이더넷 어댑터를 에뮬레이트하여 네트워크 연결을 설정하고, USB를 통해 네트워크 통신을 수행함.
- 위치: 가장 상위 계층에 존재하며,
dwc2
를 통해 UDC와 상호작용하여 USB 장치 모드에서 동작함. 이는 HTTP, SMTP, SMB와 같은 네트워크 프로토콜이 TCP/IP 위에서 동작하는 방식과 유사한 개념임.
1. g_ether
모듈 제거
UDC는 동시에 하나의 USB Gadget 드라이버만 사용할 수 있음. g_ether 모듈이 로드되면, UDC는 가상 네트워크 인터페이스를 위한 USB 장치로 설정됨. 이 경우, UDC는 g_ether가 제어하고 있는 상태가 되어, 다른 USB Gadget 드라이버가 UDC를 사용할 수 없게 됨. 즉, g_ether가 활성화되어 있는 동안 UDC는 "busy" 상태로 표시됨.
g_ether
모듈은 우리가 설정할 usb_gadget 드라이버의 일종으로 활성화되어 있으면 커스컴 gadget을 설정할수 없음. 따라서 비활성화 가 필요함.
sudo modprobe -r g_ether
1.1 dwc2
모듈 설정
먼저, USB Gadget 기능을 위해 dwc2
모듈을 활성화함. /boot/firmware/config.txt
와 /boot/firmware/cmdline.txt
파일을 편집하여 설정함.
1.2 /boot/firmware/config.txt
파일 수정
sudo nano /boot/firmware/config.txt
파일에 다음 내용을 추가함:
dtoverlay=dwc2
1.3 /boot/firmware/cmdline.txt
파일 수정
sudo nano /boot/firmware/cmdline.txt
rootwait
뒤에 modules-load=dwc2
를 추가하여, dwc2
모듈만 로드되도록 설정함: g_ether를 설정하면 g_ehther 가 udc 를 점유하고 있어
... rootwait modules-load=dwc2 ...
1.4 라즈베리 파이 재부팅
설정을 적용하기 위해 라즈베리 파이를 재부팅함:
sudo reboot
1.5 udc 상태 확인
재부팅 후 udc가 정상적으로 활성화 되었는지 확인하기 위해 아래 명령을 사용하여 확인함.
ls /sys/class/udc
# 결과
fe980000.usb # 이와같이 뜬다면 정상적으로 인식된것 이다.
2. USB Gadget 설정 스크립트 작성
USB Gadget을 설정하는 스크립트를 작성하여, 라즈베리 파이를 USB HID(주변창치) 장치로 구성함. 라즈베리 파이 의 usb포트 를 주변 장치로 인식하여 라즈베리파이의 usb와 연결된 서버에 키보드 마우스 캡쳐 정보를 전달하기 위함.
2.1 스크립트 작성
스크립트를 작성하여 USB Gadget을 설정함:
sudo nano /usr/local/bin/setup_usb_gadget.sh
스크립트 내용:
#!/bin/bash
# USB Gadget 설정 디렉토리
GADGET_DIR="/sys/kernel/config/usb_gadget/g1"
sudo modprobe libcomposite
# 기존 설정 제거
if [ -d "$GADGET_DIR" ]; then
echo "Removing existing gadget configuration..."
# UDC 설정 해제
echo "" | sudo tee $GADGET_DIR/UDC || true
sleep 1
# 기능 및 구성 해제
sudo find $GADGET_DIR -type f -exec sh -c 'echo "" > "$1"' sh {} \; || true
sudo rm -rf $GADGET_DIR
fi
echo "Creating USB Gadget configuration..."
# USB Gadget 기본 설정
sudo mkdir -p $GADGET_DIR
cd $GADGET_DIR
echo 0x1d6b | sudo tee idVendor # Linux Foundation Vendor ID
echo 0x0104 | sudo tee idProduct # Multifunction Composite Gadget Product ID
echo 0x0100 | sudo tee bcdDevice # Device release number
echo 0x0200 | sudo tee bcdUSB # USB 2.0
sudo mkdir -p strings/0x409
echo "1234567890" | sudo tee strings/0x409/serialnumber
echo "My Manufacturer" | sudo tee strings/0x409/manufacturer
echo "My Composite HID Device" | sudo tee strings/0x409/product
# 첫 번째 HID 기능 설정 (키보드)
sudo mkdir -p functions/hid.usb0
echo 1 | sudo tee functions/hid.usb0/protocol # 1 = Keyboard
echo 1 | sudo tee functions/hid.usb0/subclass # Subclass (1 for Boot Interface)
echo 8 | sudo tee functions/hid.usb0/report_length
# 첫 번째 HID Report Descriptor 설정 (키보드)
echo -ne "\\x05\\x01\\x09\\x06\\xA1\\x01\\x05\\x07\\x19\\xE0\\x29\\xE7\\x15\\x00\\x25\\x01\\x95\\x08\\x75\\x01\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xC0" | sudo tee functions/hid.usb0/report_desc
# 두 번째 HID 기능 설정 (마우스)
MOUSE_FUNCTIONS_DIR="functions/hid.mouse"
mkdir -p "$MOUSE_FUNCTIONS_DIR"
echo 0 > "${MOUSE_FUNCTIONS_DIR}/protocol" # 0 = 마우스 부트 프로토콜
echo 0 > "${MOUSE_FUNCTIONS_DIR}/subclass" # 0 = 일반 마우스 장치
echo 5 > "${MOUSE_FUNCTIONS_DIR}/report_length" # 리포트 길이 설정
# 마우스 HID Report Descriptor 작성
D=$(mktemp)
{
echo -ne \\x05\\x01 # USAGE_PAGE (Generic Desktop)
echo -ne \\x09\\x02 # USAGE (Mouse)
echo -ne \\xA1\\x01 # COLLECTION (Application)
# 8-buttons
echo -ne \\x05\\x09 # USAGE_PAGE (Button)
echo -ne \\x19\\x01 # USAGE_MINIMUM (Button 1)
echo -ne \\x29\\x08 # USAGE_MAXIMUM (Button 8)
echo -ne \\x15\\x00 # LOGICAL_MINIMUM (0)
echo -ne \\x25\\x01 # LOGICAL_MAXIMUM (1)
echo -ne \\x95\\x08 # REPORT_COUNT (8)
echo -ne \\x75\\x01 # REPORT_SIZE (1)
echo -ne \\x81\\x02 # INPUT (Data,Var,Abs)
# x,y absolute coordinates
echo -ne \\x05\\x01 # USAGE_PAGE (Generic Desktop)
echo -ne \\x09\\x30 # USAGE (X)
echo -ne \\x09\\x31 # USAGE (Y)
echo -ne \\x16\\x00\\x00 # LOGICAL_MINIMUM (0)
echo -ne \\x26\\xFF\\x7F # LOGICAL_MAXIMUM (32767)
echo -ne \\x75\\x10 # REPORT_SIZE (16)
echo -ne \\x95\\x02 # REPORT_COUNT (2)
echo -ne \\x81\\x02 # INPUT (Data,Var,Abs)
# vertical wheel
echo -ne \\x09\\x38 # USAGE (wheel)
echo -ne \\x15\\x81 # LOGICAL_MINIMUM (-127)
echo -ne \\x25\\x7F # LOGICAL_MAXIMUM (127)
echo -ne \\x75\\x08 # REPORT_SIZE (8)
echo -ne \\x95\\x01 # REPORT_COUNT (1)
echo -ne \\x81\\x06 # INPUT (Data,Var,Rel)
# horizontal wheel
echo -ne \\x05\\x0C # USAGE_PAGE (Consumer Devices)
echo -ne \\x0A\\x38\\x02 # USAGE (AC Pan)
echo -ne \\x15\\x81 # LOGICAL_MINIMUM (-127)
echo -ne \\x25\\x7F # LOGICAL_MAXIMUM (127)
echo -ne \\x75\\x08 # REPORT_SIZE (8)
echo -ne \\x95\\x01 # REPORT_COUNT (1)
echo -ne \\x81\\x06 # INPUT (Data,Var,Rel)
echo -ne \\xC0 # END_COLLECTION
} >> "$D"
cp "$D" "${MOUSE_FUNCTIONS_DIR}/report_desc"
# 위의 mouse descriptor 는 기본적으로 사용되는 버튼 3개의 마우스 디스크립터를 사용하면 동작이 안됨. tintpilot은 ustreamer를 활용해 캡쳐된 화면을 스트리밍 하기 때문에 마우스의 좌표를 인식하는 위치 에 차이가 있음. 따라서 위의 descriptor 는 tinypilot 코어 에서 추출해서 사용함
# 관련 링크
ansible-role-tinypilot/files/init-usb-gadget at ed29bacf132625c26b24898c7a08376ba3d22c61 · tiny-pilot/ansible-role-tinypilot
# USB 구성 연결
sudo mkdir -p configs/c.1/strings/0x409
echo "Configuration 1" | sudo tee configs/c.1/strings/0x409/configuration
echo 250 | sudo tee configs/c.1/MaxPower
# 첫 번째 HID 장치 링크 (키보드)
sudo ln -s functions/hid.usb0 configs/c.1/
# 두 번째 HID 장치 링크 (마우스)
sudo ln -s functions/hid.mouse configs/c.1/
# UDC 활성화 및 상태 확인
UDC_DEVICE=$(ls /sys/class/udc | head -n 1)
if [ -z "$UDC_DEVICE" ]; then
echo "UDC가 발견되지 않음. USB 장치가 올바르게 연결되었는지 확인하십시오."
exit 1
fi
echo $UDC_DEVICE | sudo tee
UDC
echo "USB HID Gadget 설정이 완료되었습니다."
위 스크립트의 gadget 설정 경로는 /sys 경로 임, 이는 재부팅시 초기화 되기 때문에 rc.d 에 지정해서 자동 실행 하거나 재부팅시 재실행 하여 설정해줘 야함.
2.2 스크립트 저장 및 실행
스크립트를 저장하고 실행 권한을 부여함:
sudo chmod +x /usr/local/bin/setup_usb_gadget.sh
스크립트를 실행함:
sudo /usr/local/bin/setup_usb_gadget.sh
2.3 최종 확인
최종적으로 tinypilot 이 가상 디바이스 파일에 접근하여 다비이스를 제어할수 있도록 해야함 따라서 가상 디바이스 파일이 정상적으로 /dev/hidg 경로에 생성 되었는지 확인
ls /dev/hidg**
'Server' 카테고리의 다른 글
[TInypilot] Tinypilot 도커로 컨테이너화 해보기 (2) | 2024.09.01 |
---|---|
우분투 시스템 에 lxc 설정하기 (1) | 2024.08.31 |
tinypilot 도커 이미지로 배포 하기 (0) | 2024.07.25 |
ubuntu ssh key-pair 생성 및 적용 (6) | 2024.07.23 |
Server_Chroot_nginx start 실패시 대응법 (1) | 2024.07.08 |