ttyU0 "/usr/libexec/getty 3wire" vt100 onifconsole secure ttyU1 "/usr/libexec/getty 3wire" vt100 onifconsole secure
Edward Tomasz Napierala <[email protected]>
This chapter covers the use of USB Device Mode and USB On The Go (USB OTG
) in FreeBSD.
This includes virtual serial consoles, virtual network interfaces, and virtual USB drives.
When running on hardware that supports USB device mode or USB OTG
, 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, or a combination thereof.
A USB
host like a laptop or desktop computer is able to access them just like physical USB
devices.
Device mode is sometimes called the “USB gadget mode”
.
There are two basic ways the hardware can provide the device mode functionality: with a separate "client port", which only supports the device mode, and with a USB OTG port, which can provide both device and host mode.
For USB OTG
ports, the USB
stack switches between host-side and device-side automatically, depending on what is connected to the port.
Connecting a USB
device like a memory stick to the port causes FreeBSD to switch to host mode.
Connecting a USB
host like a computer causes FreeBSD to switch to device mode.
Single purpose "client ports" always work in device mode.
What FreeBSD presents to the USB
host depends on the hw.usb.template
sysctl.
Some templates provide a single device, such as a serial terminal; others provide multiple ones, which can all be used at the same time.
An example is the template 10, which provides a mass storage device, a serial console, and a network interface.
See usb_template(4)
for the list of available values.
Note that in some cases, depending on the hardware and the hosts operating system, 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.
After reading this chapter, you will know:
How to set up USB Device Mode functionality on FreeBSD.
How to configure the virtual serial port on FreeBSD.
How to connect to the virtual serial port from various operating systems.
How to configure FreeBSD to provide a virtual USB
network interface.
How to configure FreeBSD to provide a virtual USB
storage device.
Virtual serial port support is provided by templates number 3, 8, and 10. Note that template 3 works with Microsoft Windows 10 without the need for special drivers and INF files. Other host operating systems work with all three templates. Both usb_template(4) and umodem(4) kernel modules must be loaded.
To enable USB device mode serial ports, add those lines to /etc/ttys
:
ttyU0 "/usr/libexec/getty 3wire" vt100 onifconsole secure ttyU1 "/usr/libexec/getty 3wire" vt100 onifconsole secure
Then add these lines to /etc/devd.conf
:
notify 100 { match "system" "DEVFS"; match "subsystem" "CDEV"; match "type" "CREATE"; match "cdev" "ttyU[0-9]+"; action "/sbin/init q"; };
Reload the configuration if devd(8) is already running:
# service devd restart
Make sure the necessary modules are loaded and the correct template is set at boot by adding those lines to /boot/loader.conf
, creating it if it does not already exist:
umodem_load="YES" hw.usb.template=3
To load the module and set the template without rebooting use:
# kldload umodem # sysctl hw.usb.template=3
To connect to a board configured to provide USB device mode serial ports, connect the USB host, such as a laptop, to the boards USB OTG or USB client port.
Use pstat -t
on the host to list the terminal lines.
Near the end of the list you should see a USB serial port, eg "ttyU0". To open the connection, use:
# cu -l /dev/ttyU0
After pressing the Enter key a few times you will see a login prompt.
To connect to a board configured to provide USB device mode serial ports, connect the USB host, such as a laptop, to the boards USB OTG or USB client port. To open the connection, use:
# cu -l /dev/cu.usbmodemFreeBSD1
To connect to a board configured to provide USB device mode serial ports, connect the USB host, such as a laptop, to the boards USB OTG or USB client port. To open the connection, use:
# minicom -D /dev/ttyACM0
To connect to a board configured to provide USB device mode serial ports, connect the USB host, such as a laptop, to the boards USB OTG or USB client port.
To open a connection you will need a serial terminal program, such as PuTTY
.
To check the COM port name used by Windows, run Device Manager, expand "Ports (COM & LPT)". You will see a name similar to "USB Serial Device (COM4)". Run serial terminal program of your choice, for example PuTTY
.
In the PuTTY
dialog set "Connection type" to "Serial", type the COMx obtained from Device Manager in the "Serial line" dialog box and click Open.
Virtual network interfaces support is provided by templates number 1, 8, and 10. Note that none of them works with Microsoft Windows. Other host operating systems work with all three templates. Both usb_template(4) and if_cdce(4) kernel modules must be loaded.
Make sure the necessary modules are loaded and the correct template is set at boot by adding those lines to /boot/loader.conf
, creating it if it does not already exist:
if_cdce_load="YES" hw.usb.template=1
To load the module and set the template without rebooting use:
# kldload if_cdce # sysctl hw.usb.template=1
The cfumass(4)
driver is a |
Mass Storage target is provided by templates 0 and 10.
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.
The simplest way to set up a read-only USB storage target is to use the cfumass
rc script.
To configure it this way, copy the files to be presented to the USB host machine into the /var/cfumass
directory, and add this line to /etc/rc.conf
:
cfumass_enable="YES"
To configure the target without restarting, run this command:
# service cfumass start
Differently from serial and network functionality, the template should not be set to 0 or 10 in /boot/loader.conf
.
This is because the LUN must be set up before setting the template.
The cfumass startup script sets the correct template number automatically when started.
The rest of this chapter provides detailed description of setting the target without using the cfumass rc file. This is necessary if eg one wants to provide a writeable LUN.
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
.
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
As the ctld(8)
daemon is started, it reads /etc/ctl.conf
.
If this file is edited after the daemon starts, reload the changes so they take effect immediately:
# service ctld reload