USB 저장 드라이버
개요
BOT(Bulk-Only Transport)와 UAS(UASP, USB Attached SCSI)의 주요 차이점:
Windows NT 커널과 Linux 커널 모두 UAS 사용 여부를 나타내는 플래그를 사용합니다. UAS는 4개의 엔드포인트(EP)를 지원하며, BOT는 2개의 엔드포인트를 사용합니다. 메인 컨트롤러가 스트림을 지원하는지 확인하고, 지원 시 UAS 프로토콜 사용을 위해 ALT 모드를 시도합니다. Windows NT 커널 드라이버는 풀 스피드 2.0 이상에서만 UAS를 시도합니다.
BOT는 단일 스레드로, Data-In/Data-Out 파이프라인을 사용하는 단방향 대기 방식이므로 고속에서 병목 현상이 발생하며, 이것이 USB 저장 장치가 최대 속도를 달성하지 못하는 이유입니다.
UAS는 다중 파이프라인(ITr/ITc/OTr/Otc) - 4개의 전송 파이프라인 + USB2/USB3 파이프라인 + UAS 정보 단위 파이프라인을 사용합니다. 일반적으로 4개의 EP: datain, dataout, cmd, status를 사용합니다.
UAS의 SCSI 기반 아키텍처
드라이버 등록
drivers/usb/storage/usb.c 파일에서 USB 스토리지 드라이버를 등록합니다:
static struct usb_driver mass_storage_driver = {
.name = DRV_NAME,
.probe = mass_storage_probe,
.disconnect = mass_disconnect,
.suspend = mass_suspend,
.resume = mass_resume,
.reset_resume = mass_reset_resume,
.pre_reset = mass_pre_reset,
.post_reset = mass_post_reset,
.id_table = mass_storage_usb_ids,
.supports_autosuspend = 1,
.soft_unbind = 1,
};
module_usb_mass_driver(mass_storage_driver, mass_host_template, DRV_NAME);
일반 BOT 등록 절차
장치가 UAS 또는 비표준 장치인 경우 storage_probe에서 종료됩니다.
drivers/usb/storage/standard-tables.c의 두 배열 리스트:
- 비표준 장치 ignore_ids[]
- UAS 목록 mass_storage_usb_ids[]
UAS 판단: uas_check_driver
/* If uas is enabled and this device can do uas then ignore it. */
#if IS_ENABLED(CONFIG_USB_UAS)
if (uas_check_driver(intf, id, NULL))
return -ENXIO;
#endif
비표준 장치 판단:
/*
* If the device isn't standard (is handled by a subdriver
* module) then don't accept it.
*/
if (mass_ignore_device(intf))
return -ENXIO;
그런 다음 mass_probe1과 mass_probe2 절차를 진행합니다.
mass_probe1 내에서 프로토콜 선택이 이루어지며, 프로토콜에 따라 읽기/쓰기 처리 함수가 전환됩니다:
/* Get standard transport and protocol settings */
get_transport(ms);
get_protocol(ms);
스트림 기반 UAS 등록
drivers/usb/storage/uas.c에서 구현됩니다.
XHCI 드라이버 재정의
주로 공식 드라이버 동작을 재정의하는 데 사용됩니다:
static const struct xhci_driver_replacements xhci_pci_replacements __initconst = {
.reset = xhci_pci_setup,
.update_hub_device = xhci_pci_update_hub_device,
};
// 초기화
xhci_init_driver(&xhci_pci_hc_driver, &xhci_pci_replacements);
원리: null이 아닌 경우 함수 포인터를 재할당합니다.
XHCI 프로토콜 사양
참고 문서: https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/extensible-host-controler-interface-usb-xhci.pdf
USB 저장 BOT(Bulk-Only Transport) CBW-UFI 명령 데이터 흐름
예시: https://www.usbzh.com/tool/bot-cbw-ufi-csw.html
SCSI 프로토콜
Seagate: https://www.seagate.com/files/staticfiles/support/docs/manual/Interface manuals/100293068j.pdf
모델은 SCSI architectural model (SAM)로 알려져 있습니다.
칩의 UASP IP
참고: https://www.synopsys.com/blogs/chip-design/uasp-faster-usb-mass-storage.html
기타 정보
sd 1:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
- FUA: Force Unit Access
- DPO: Disable Page Out
kprobe/kretprobe 후크 작성
현재 커널의 관련 함수 기호 확인:
grep uas /proc/kallsyms
uas로 시작하는 기호는 다음과 같습니다:
0000000000000000 t uas_probe
0000000000000000 t uas_disconnect
0000000000000000 t uas_suspend
0000000000000000 t uas_resume
0000000000000000 t uas_reset_resume
0000000000000000 t uas_pre_reset
0000000000000000 t uas_post_reset
0000000000000000 t uas_shutdown
0000000000000000 t uas_do_work
0000000000000000 t uas_scan_work
0000000000000000 t uas_configure_endpoints
0000000000000000 t uas_queuecommand
0000000000000000 t uas_eh_abort_handler
0000000000000000 t uas_eh_device_reset_handler
0000000000000000 t uas_slave_alloc
0000000000000000 t uas_slave_configure
0000000000000000 t uas_target_alloc
0000000000000000 t uas_submit_urbs
0000000000000000 t uas_log_cmd_state
0000000000000000 t uas_stat_cmplt
0000000000000000 t uas_sense
0000000000000000 t uas_try_complete
0000000000000000 t uas_xfer_data
0000000000000000 t uas_evaluate_response_iu
0000000000000000 t uas_data_cmplt
0000000000000000 t uas_cmd_cmplt
0000000000000000 t uas_zap_pending
0000000000000000 t uas_wait_for_pending_cmnds
0000000000000000 t uas_init
0000000000000000 t uas_exit
0000000000000000 d __initcall__kmod_uas__452_1275_uas_init6
0000000000000000 d uas_driver
0000000000000000 d uas_usb_ids
0000000000000000 d uas_host_template
드라이버 확인
# drivers 섹션에서 Driver=usb-storage 또는 uas 확인
lsusb -t
cat /sys/kernel/usb/devices
참고 자료
국내 현재 표준: ISO/IEC 14776-251:2014