17.4. USB 儲存裝置

Contributed by Marc Fonvieille.

許多外部儲存裝置的解決方案,例如硬碟、USB 隨身碟及 CDDVD 燒錄機皆使用通用序列匯流排 (Universal Serial Bus, USB),FreeBSD 提供了對 USB 1.x, 2.0 及 3.0 裝置的支援。

注意:

部份硬體尚不相容 USB 3.0,包含 Haswell (Lynx point) 晶片組,若 FreeBSD 開機出現 failed with error 19 訊息,請在系統 BIOS 關閉 xHCI/USB3。

USB 儲存裝置的支援已內建於 GENERIC 核心,若為自訂的核心,請確定在核心設定檔中有下列幾行設定:

device scbus	# SCSI bus (required for ATA/SCSI)
device da	# Direct Access (disks)
device pass	# Passthrough device (direct ATA/SCSI access)
device uhci	# provides USB 1.x support
device ohci	# provides USB 1.x support
device ehci	# provides USB 2.0 support
device xhci	# provides USB 3.0 support
device usb	# USB Bus (required)
device umass	# Disks/Mass storage - Requires scbus and da
device cd	# needed for CD and DVD burners

FreeBSD 使用 umass(4) 驅動程式透過 SCSI 子系統來存取 USB 儲存裝置,因此任何在系統的 USB 裝置都會以 SCSI 裝置呈現,若 USB 裝置是 CDDVD 燒錄機,請不要在自訂核心設定檔中引用 device atapicam

本節後續的部份將示範如何檢查 FreeBSD 能夠辦識 USB 儲存裝置以及如何設定該裝置。

17.4.1. 裝置設定

要測試 USB 設定,請先插入 USB 裝置,然後使用 dmesg 來確認系統訊息緩衝區中有出現該磁碟機,該訊息如下:

umass0: <STECH Simple Drive, class 0/0, rev 2.00/1.04, addr 3> on usbus0
umass0:  SCSI over Bulk-Only; quirks = 0x0100
umass0:4:0:-1: Attached to scbus4
da0 at umass-sim0 bus 0 scbus4 target 0 lun 0
da0: <STECH Simple Drive 1.04> Fixed Direct Access SCSI-4 device
da0: Serial Number WD-WXE508CAN263
da0: 40.000MB/s transfers
da0: 152627MB (312581808 512 byte sectors: 255H 63S/T 19457C)
da0: quirks=0x2<NO_6_BYTE>

不同的裝置會有不同的廠牌、裝置節點 (da0)、速度與大小。

USB 裝置可以做為 SCSI 檢視時,便可使用 camcontrol 來列出連接到系統的 USB 儲存裝置:

# camcontrol devlist
<STECH Simple Drive 1.04>          at scbus4 target 0 lun 0 (pass3,da0)

或者,可以使用 usbconfig 來列出裝置,請參考 usbconfig(8) 來取得更多有關此指令的資訊。

# usbconfig
ugen0.3: <Simple Drive STECH> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (2mA)

若該裝置尚未被格式化,請參考 節 17.2, “加入磁碟” 中有關如何在 USB 磁碟格式化與建立分割區的說明。若磁碟中有檔案系統,可由 root 依據 節 3.7, “掛載與卸載檔案系統” 中的說明掛載磁碟。

警告:

要允許未被信任的使用者掛載任意媒體,可開啟 vfs.usermount,詳細說明如下。從安全性的角度來看這並不是安全的,大多的檔案系統並不會防範惡意裝置。

要讓裝置可讓一般使用者掛載,其中一個解決方案便是使用 pw(8) 讓所有裝置的使用者成為 operator 群組的成員。接著,將下列幾行加入 /etc/devfs.rules 來確保 operator 能夠讀取與寫入裝置:

[localrules=5]
add path 'da*' mode 0660 group operator

注意:

若系統也同時安裝了內建 SCSI 磁碟,請更改第二行如下:

add path 'da[3-9]*' mode 0660 group operator

這會從 operator 群組中排除前三個 SCSI 磁碟 (da0da2),接著取代 3 為內部 SCSI 磁碟的編號。請參考 devfs.rules(5) 來取得更多有關此檔案的資訊。

接著,在 /etc/rc.conf 開啟規則:

devfs_system_ruleset="localrules"

然後,加入以下行到 /etc/sysctl.conf 指示系統允許正常使用者掛載檔案系統:

vfs.usermount=1

這樣只會在下次重新開機時生效,可使用 sysctl 來立即設定這個變數:

# sysctl vfs.usermount=1
vfs.usermount: 0 -> 1

最後一個步驟是建立要掛載檔案系統要的目錄,要掛載檔案系統的使用者需要擁有這個目錄。其中一個辦法是讓 root 建立由該使用者擁有的子目錄 /mnt/username。在下面的例子,將 username 替換為該使用者的登入名稱並將 usergroup 替換為該使用者的主要群組:

# mkdir /mnt/username
# chown username:usergroup /mnt/username

假如已經插入 USB 隨身碟,且已出現 /dev/da0s1 裝置。若裝置使用 FAT 格式的檔案系統,則使用者可使用以下指令掛載該檔案系統:

% mount -t msdosfs -o -m=644,-M=755 /dev/da0s1 /mnt/username

在裝置可以被拔除前,必須先卸載:

% umount /mnt/username

裝置移除之後,系統訊息緩衝區會顯示如下的訊息:

umass0: at uhub3, port 2, addr 3 (disconnected)
da0 at umass-sim0 bus 0 scbus4 target 0 lun 0
da0: <STECH Simple Drive 1.04> s/n WD-WXE508CAN263          detached
(da0:umass-sim0:0:0:0): Periph destroyed

17.4.2. 自動掛載可移除的媒體

注意:

自 FreeBSD 10.2-RELEASE 開始 autofs(5) 支援自動掛載可移除的媒體。

可以取消註解在 /etc/auto_master 中的下行來自動掛載 USB 裝置:

/media		-media		-nosuid

然後加入這些行到 /etc/devd.conf

notify 100 {
	match "system" "GEOM";
	match "subsystem" "DEV";
	action "/usr/sbin/automount -c";
};

autofs(5) 以及 devd(8) 已經正在執行,則需重新載入設定:

# service automount reload
# service devd restart

要設定讓 autofs(5) 在開機時啟動可以加入此行到 /etc/rc.conf

autofs_enable="YES"

autofs(5) 需要開啟 devd(8),預設已經開啟。

立即啟動服務:

# service automount start
# service automountd start
# service autounmountd start
# service devd start

可以被自動掛載的檔案系統會在 /media/ 中以目錄呈現,會以檔案系統的標籤來命名目錄,若標籤遺失,則會以裝置節點命名。

檔案系統會在第一次存取時自動掛載,並在一段時間未使用後自動卸載。自動掛載的磁碟也可手動卸載:

# automount -fu

這個機制一般會用在記憶卡與 USB 隨身碟,也可用在任何 Block 裝置,包含光碟機或 iSCSI LUN

17.4.3. USB 大容量儲存目標

注意:

cfumass(4) 驅動程式是一個在 FreeBSD 12.0 之後才可用的 USB 裝置模式驅動程式。

When running on USB OTG-compliant hardware like that built into many embedded boards, the FreeBSD USB stack can run in device mode. Device mode makes it possible for the computer to present itself as different kinds of USB device classes, including serial ports, network adapters, and mass storage. A USB host like a laptop or desktop computer is able to access them just like physical USB devices.

The usb_template(4) kernel module allows the USB stack to switch between host-side and device-side automatically, depending on what is connected to the USB port. Connecting a USB device like a memory stick to the USB OTG port causes FreeBSD to switch to host mode. Connecting a USB host like a computer causes FreeBSD to switch to device mode.

What FreeBSD presents to the USB host depends on the hw.usb.template sysctl. See usb_template(4) for the list of available values. Note that for the host to notice the configuration change, it must be either physically disconnected and reconnected, or forced to rescan the USB bus in a system-specific way. When FreeBSD is running on the host, usbconfig(8) reset can be used. This also must be done after loading usb_template.ko if the USB host was already connected to the USB OTG socket.

The hw.usb.template sysctl is set to 0 by default, making FreeBSD work as a USB Mass Storage target. Both usb_template(4) and cfumass(4) kernel modules must be loaded. cfumass(4) interfaces to the CTL subsystem, the same one that is used for iSCSI or Fibre Channel targets. On the host side, USB Mass Storage initiators can only access a single LUN, LUN 0.

USB Mass Storage does not require the ctld(8) daemon to be running, although it can be used if desired. This is different from iSCSI. Thus, there are two ways to configure the target: ctladm(8), or ctld(8). Both require the cfumass.ko kernel module to be loaded. The module can be loaded manually:

# kldload cfumass

If cfumass.ko has not been built into the kernel, /boot/loader.conf can be set to load the module at boot:

cfumass_load="YES"

A LUN can be created without the ctld(8) daemon:

# ctladm create -b block -o file=/data/target0

This presents the contents of the image file /data/target0 as a LUN to the USB host. The file must exist before executing the command. To configure the LUN at system startup, add the command to /etc/rc.local.

ctld(8) can also be used to manage LUNs. Create /etc/ctl.conf, add a line to /etc/rc.conf to make sure ctld(8) is automatically started at boot, and then start the daemon.

This is an example of a simple /etc/ctl.conf configuration file. Refer to ctl.conf(5) for a more complete description of the options.

target naa.50015178f369f092 {
	lun 0 {
		path /data/target0
		size 4G
	}
}

The example creates a single target with a single LUN. The naa.50015178f369f092 is a device identifier composed of 32 random hexadecimal digits. The path line defines the full path to a file or zvol backing the LUN. That file must exist before starting ctld(8). The second line is optional and specifies the size of the LUN.

To make sure the ctld(8) daemon is started at boot, add this line to /etc/rc.conf:

ctld_enable="YES"

To start ctld(8) now, run this command:

# service ctld start

ctld(8) Daemon 啟動後,它會讀取 /etc/ctl.conf,若這個檔案在 Daemon 啟動之後才做修改,要重新載入變更的內容才能立即生效:

# service ctld reload

本文及其他文件,可由此下載: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/

若有 FreeBSD 方面疑問,請先閱讀 FreeBSD 相關文件,如不能解決的話,再洽詢 <questions@FreeBSD.org>。

關於本文件的問題,請洽詢 <doc@FreeBSD.org>。