Starting io-sock and Driver Management

Updated: April 19, 2023

You can start io-sock with or without a driver. For example:

io-sock

The io-sock command creates the following resources by default:

/dev/socket 
/dev/io-sock
/dev/pf
/dev/bpf

You can also load one or more drivers when you start io-sock. Because all io-sock drivers default to Plug and Play, you can load them without having interfaces present. For example:

io-sock -d devs-em.so

(A description of the driver resources that this command creates is provided below, with the command for loading a driver later.)

For x86_64 targets, which are usually not resource limited, you may want to start all drivers when you start io-sock. For example, when you use the following command, io-sock discovers all the interfaces it supports with the currently loaded drivers and creates them (you can specify the driver without the devs -* prefix and .so extension).

io-sock -d em -d re -d axe -d axge -d cdce

Loading a driver after starting io-sock

You can start io-sock and load a driver later. For example, the following command starts the Intel E1000 Ethernet device driver (devs-em.so) with io-sock already running:

mount -T io-sock em

This example assumes that the search path for devs-em.so is in LD_LIBRARY_PATH. The search path for the driver is the LD_LIBRARY_PATH that io-sock has in its environment (i.e., what it was when io-sock started, not the environment of mount).

You can also provide the path explicitly. For example:

mount -T io-sock /lib/dll/devs-em.so

This command creates the following resources:

/dev/io-sock/devs-em.so
/dev/io-sock/devs-em.so/em0
/dev/io-sock/devs-em.so/em1
...
/dev/io-sock/devs-em.so/emn

where n is the number of interfaces found.

The filenames under the driver directory (in this example, /dev/io-sock/devs-em.so/emn) are device names, not interface names. In some cases, the directory names and the names that ifconfig displays may not match the driver name.

To unmount, you remove all the interfaces that the mount process created first. For example:

umount /dev/io-sock/devs-em.so/em0
umount /dev/io-sock/devs-em.so/em1
umount /dev/io-sock/devs-em.so/emn
...
umount /dev/io-sock/devs-em.so 

Creating and starting an alternative stack

The io-sock networking stack allows you to create multiple instances of the stack (e.g., to provide one stack for external users and one for internal use).

To create an alternative io-sock stack, use prefix=path, which specifies a path to prepend to the default stack location (e.g., /dev/socket). For example:

io-sock -o prefix=/alt

This io-sock command creates the following resources:

/alt/dev/socket
/alt/dev/io-sock
/alt/dev/pf
/alt/dev/bpf

To mount the alternative stack, match the prefix string. For example:

mount -T io-sock -o prefix=/alt devs-em.so

This command creates the following resources:

/alt/dev/io-sock/devs-em.so
/alt/dev/io-sock/devs-em.so/em0
/alt/dev/io-sock/devs-em.so/em1
...
/alt/dev/io-sock/devs-em.so/emn

where n is the number of interfaces found.

Include the prefix when you umount. For example:

umount /alt/dev/io-sock/devs-em.so/em0
umount /alt/dev/io-sock/devs-em.so/em1
umount /alt/dev/io-sock/devs-em.so/emn
...
umount /alt/dev/io-sock/devs-em.so 

Running multiple stacks with network interface controllers of the same type

In io-sock, Plug and Play is enabled by default. With Plug and Play, an interface is automatically attached after it is inserted into the bus, provided there is a driver loaded that supports the interface.

In some cases, to run multiple instances of the stack with multiple NICs of the same type, Plug and Play should be disabled. You can then identify each interface (e.g., using the Bus:Device:Function numbers) and specify the stack it should attach to.

Depending on the type of device and how it is used, it may or may not be essential to disable Plug and Play.

PCI: Stacks connect to PCI devices via the PCI server. After it is created, the connection is exclusive, and the devices are rarely inserted and removed. With Plug and Play enabled, you can start the first stack with both NICs and umount one NIC before you start the second stack. That NIC can then be attached when starting the second stack. However, if a new device is inserted, the two stacks race to connect to it. You must disable Plug and Play if you want to control which stack connects to the device.

USB: USB devices are also connected to a stack exclusively and you can use the umount method described for multiple PCI NICs with USB NICs. However, because USB devices are inserted and removed more often, the race to connect also happens more often. You must disable Plug and Play if you want to avoid it.

OFW (Open Firmware Bus): OFW devices are not connected exclusively. Plug and Play must be disabled to work with NICs of the same type with two or more stacks. If Plug and Play is not disabled, the stacks overwrite each other’s values. This overwriting could cause the io-sock instances to crash.

Disabling Plug and Play

To start io-sock with Plug and Play disabled, see io-sock. You disable Plug and Play for specific device types (PCI, USB, OFW). For example, to disable Plug and Play for PCI devices:

io-sock -o npnp_pci

If you already started io-sock without disabling Plug and Play, you can use sysctl to disable Plug and Play for an individual device interface type. For example, to disable Plug and Play for PCI devices:

sysctl qnx.pnp.pci=0 

Attaching devices to specific stacks

After creating an alternative stack (see Creating and starting an alternative stack), you need to:

mount -T io-sock -o prefix=/alt  qnxdev=pci0:0:25:0 devs-em.so

In this example, the driver is devs-em.so, stack prefix is /alt , and qnxdev string is pci0:0:25:0.

Determining the qnxdev string

If io-sock is running, you can use devinfo to find the qnxdev string for your device (see Displaying device information).

If io-sock is not running, you can use server-specific tools to construct the qnxdev string.

PCI: You can construct the qnxdev string using pci-tool. From the pci-tool output, you can find the Bus:Device:Function numbers for the PCI device. For example, this is some sample output of pci-tool with the -v option:
B00:D05:F00 @ idx 0
        vid/did: 8086/7190
                Intel Corporation, 82443BX/ZX 440BX/ZX AGPset Host Bridge
        class/subclass/reg: 06/00/00
                Host-to-PCI Bridge Device
In this example, the qnxdev string is qnxdev=pci0:0:5:0. The pci0 represents the first instance of the PCI server (pci-server).
USB: You can construct the qnxdev string using usb. From the usb output, you can find the USB hub index, device address, and interface index for the USB device. For example, this is some sample output of usb -vv:
USB 0 (XHCI) v1.11, v1.01 DDK, v2.00 HCD, DLL: Active    ***This is the USB hub index ***
Device Address             : 1
Upstream Host Controller   : 0
Upstream Device Address    : 0
Upstream Port              : 4
Upstream Port Speed        : Full
Vendor                     : 0x0557
Product                    : 0x7000
Device Release             : r1.00
USB Spec Release           : v1.10
Serial Number              : N/A
Class                      : 0x09 (Hub)
Subclass                   : 0x00
Protocol                   : 0x00
Max PacketSize0            : 8
Languages                  : No string descriptors
Hub Number Ports           : 4
Hub Characteristics        : 0x0009 (Individual power, Individual over-current)
Hub Power On->Good         : 100 ms
Hub Power Requirements     : 100 mA
Configurations             : 1
  Configuration            : 1
    Attributes             : 0xe0 (Self-powered, Remote-wakeup)
    Max Power              : 100 mA
    Interfaces             : 1
      Interface            : 0 / 0
        Class              : 0x09 (Hub)
        Subclass           : 0x00
        Protocol           : 0x00            
In this example, the qnxdev string is qnxdev=iousb0:0:1:0. The iousb0 represents the first instance of the USB server (io-usb-otg).

OFW: To construct the qnxdev string, you need to specify the bus location and hardware address of the OFW device. You can get this information from the DTB file. For example, this is some sample DTS output:

/dts-v1/; 

/ {     
    interrupt-parent = <0x8001>;     
        #size-cells = <0x02>;
        #address-cells = <0x02>;     
        compatible = "example,dummy";     
    
    some_bus {          
        compatible = "simple-bus";         
        #address-cells = <0x02>;          
        #size-cells = <0x02>;    
        
        ethernet@1c130400 {              
            interrupts = <0x00 0x2a 0x01>;              
            reg = <0x00 0x1c130400 0x00 0x200>;             
            compatible = "net,target";          
        };      
    };      
    
    another_bus {          
        compatible = "simple-bus";     
        #address-cells = <0x02>;          
        #size-cells = <0x02>;          
        
        ethernet@1c130000 {             
            interrupts = <0x00 0x28 0x01>;             
            reg = <0x00 0x1c130000 0x00 0x200>;            
            compatible = "net,target";         
        };      
    };     
    
    intc@8000000 {          
        phandle = <0x8001>;          
        reg = <0x00 0x8000000 0x00 0x10000 0x00 0x8010000 0x00 0x10000>;          
        compatible = "arm,cortex-a15-gic";          
        ranges;          
        #size-cells = <0x02>;          
        #address-cells = <0x02>;         
        interrupt-controller;         
        #interrupt-cells = <0x03>;          
        
        v2m@8020000 {              
            phandle = <0x8002>;     
            reg = <0x00 0x8020000 0x00 0x1000>;             
            msi-controller;              
            compatible = "arm,gic-v2m-frame";     
        };      
     };  
  };  
In this example, the qnxdev string could be ofwbus0:0x1c130400 or ofwbus1:0x1c130000.

Using io-sock with a Flattened Device Tree (FDT)

Use dtb=path to specify a flattened device tree blob (DTB) file, and use –d to specify the driver to load. For example, the following command points to the DTB fsl-imx8-mek.dtb and loads the devs-ffec.so driver:

io-sock -o dtb=/path/to/dtb/file/fsl-imx8-mek.dtb -d ffec

Alternatively, start io-sock and mount the driver later using mount. In the following example, the devs-ffec.so driver is in LD_LIBRARY_PATH:

io-sock -o dtb=/path/to/dtb/file/fsl-imx8-mek.dtb

... 
mount -T io-sock ffec 

Displaying driver information

Use ls to display which drivers are loaded. For example:

ls /dev/io-sock/ 
devs-axe.so        devs-cdce.so       devs-re.so 
devs-axge.so       devs-em.so 

Alternatively, use find. For example:

find /dev/io-sock/    
/dev/io-sock/ 
/dev/io-sock/devs-cdce.so 
/dev/io-sock/devs-axge.so 
/dev/io-sock/devs-axe.so 
/dev/io-sock/devs-re.so 
/dev/io-sock/devs-em.so 
/dev/io-sock/devs-em.so/em1 
/dev/io-sock/devs-em.so/em0 

Displaying device information

Use cat to retrieve information about the devices in the driver directories. For example:

cat /dev/io-sock/devs-em.so/em0
device=em0,interface=em0,options="" 

Alternatively, you can display information for the entire directory. For example:

cat /dev/io-sock/*/*
device=em0,interface=em0,options=""
device=em1,interface=em1,options=""
device=axe0,interface=axe0,options="" 

You can use devinfo to display more detailed information about devices, which is useful for attaching specific interfaces when Plug and Play is disabled. For example:

devinfo -v  
nexus0 
   pci0 
     unknown pnpinfo vendor=0x8086 device=0x153a subvendor=0x17aa subdevice=0x3097 revid=0x04 class=0x020000 at pci0:0:25:0 
     unknown pnpinfo vendor=0x8086 device=0x15d1 subvendor=0x8086 subdevice=0x0002 revid=0x01 class=0x020000 at pci0:1:0:0 
     unknown pnpinfo vendor=0x10ec device=0x8168 subvendor=0x10ec subdevice=0x0123 revid=0x06 class=0x020000 at pci0:3:0:0 
     unknown pnpinfo vendor=0x168c device=0x0013 subvendor=0x1186 subdevice=0x3a13 revid=0x01 class=0x020000 at pci0:5:0:0 
     em0 pnpinfo vendor=0x8086 device=0x105e subvendor=0x103c subdevice=0x7044 revid=0x06 class=0x020000 at pci0:6:0:0 
     em1 pnpinfo vendor=0x8086 device=0x105e subvendor=0x103c subdevice=0x7044 revid=0x06 class=0x020000 at pci0:6:0:1 
   iousb0 
     uhub0 at iousb0 (default path) 
       unknown pnpinfo vendor=0x0557 product=0x7000 class=0x09 subclass=0x00 at iousb0:0:1:0 
       unknown pnpinfo vendor=0x046d product=0xc31c class=0x00 subclass=0x00 at iousb0:0:2:0 
       unknown pnpinfo vendor=0x046d product=0xc31c class=0x00 subclass=0x00 at iousb0:0:2:1 
     uhub1 at iousb0 (default path) 
       unknown pnpinfo vendor=0x8087 product=0x8008 class=0x09 subclass=0x00 at iousb0:1:1:0 
     uhub2 at iousb0 (default path) 
       unknown pnpinfo vendor=0x8087 product=0x8000 class=0x09 subclass=0x00 at iousb0:2:1:0

Additional interface information is available using ifconfig. For example:

ifconfig 
enc0: flags=0<> metric 0 mtu 1536 
     groups: enc 
     nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL> 
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384 
     options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6> 
     inet 127.0.0.1 netmask 0xff000000 
     inet6 ::1 prefixlen 128 
     inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 
     groups: lo 
     nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL> 
pfsync0: flags=0<> metric 0 mtu 1500 
     syncpeer: 0.0.0.0 maxupd: 128 defer: off 
     groups: pfsync 
pflog0: flags=0<> metric 0 mtu 33144 
     groups: pflog 
em0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500 
     options=81049b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,LRO,VLAN_HWFILTER> 
     ether 00:26:55:db:1b:0e 
     media: Ethernet autoselect 
     status: no carrier 
     nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL> 
em1: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500 
     options=81049b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,LRO,VLAN_HWFILTER> 
     ether 00:26:55:db:1b:0f 
     media: Ethernet autoselect 
     status: no carrier 
     nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>