{"id":1,"date":"2024-02-28T09:05:16","date_gmt":"2024-02-28T09:05:16","guid":{"rendered":"https:\/\/rethinkit.blog\/?p=1"},"modified":"2025-01-16T07:38:05","modified_gmt":"2025-01-16T07:38:05","slug":"hello-world","status":"publish","type":"post","link":"https:\/\/rethinkit.blog\/?p=1","title":{"rendered":"Linux USB ConfigFS"},"content":{"rendered":"\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n<div class=\"wp-block-post-excerpt has-urbanist-font-family\"><p class=\"wp-block-post-excerpt__excerpt\">Learn about the basics of USB ConfigFS and how to utilize it to create your own USB composition! <\/p><\/div>\n\n\n<h4 class=\"wp-block-heading has-urbanist-font-family\" id=\"dtprf\"><strong>Table of Contents<\/strong><\/h4>\n\n\n\n<ol style=\"margin-right:var(--wp--preset--spacing--20);margin-left:var(--wp--preset--spacing--20)\" id=\"nybb4ygjzuyjat31\" class=\"wp-block-list has-urbanist-font-family\">\n<li><a href=\"#mywrm213\"><u>Summary<\/u><\/a><\/li>\n\n\n\n<li><a href=\"#a2alg97823\"><u>How to Initialize USB ConfigFS<\/u><\/a><\/li>\n\n\n\n<li><a href=\"#hn5a3192333\"><u>USB ConfigFS Parameters<\/u><\/a><\/li>\n\n\n\n<li><a href=\"#ny0xn259414\"><u>Creating a USB Configuration<\/u><\/a><\/li>\n\n\n\n<li><a href=\"#bu9fq10922\"><u>Trigger USB Enumeration<\/u><\/a><\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading has-urbanist-font-family\" id=\"mywrm213\"><strong>Summary<\/strong><\/h4>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69f8dd7eadd2b&quot;}\" data-wp-interactive=\"core\/image\" class=\"wp-block-image size-full wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"1920\" height=\"1080\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on-async--click=\"actions.showLightbox\" data-wp-on-async--load=\"callbacks.setButtonStyles\" data-wp-on-async-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/rethinkit.blog\/wp-content\/uploads\/2024\/03\/Flowchart-1-1.png\" alt=\"\" class=\"wp-image-22\"\/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge image\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on-async--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p class=\"has-urbanist-font-family\">As seen in the diagram, the USB configFS resides alongside the USB composite driver. The USB composite driver is the standard interface which interacts with the UDC core SW layers. This post won&#8217;t go over the details on USB composite, and focus solely on USB configFS, but there are callbacks registered between USB configFS and UDC core that utilize USB composite.<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/rethinkit.blog\/wp-content\/uploads\/2024\/03\/COM5-PuTTY-2024-02-18-02-47-56.mp4\"><\/video><\/figure>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"zz00o25949\">The basis and backbone behind USB configFS is utilizing the configFS filesystem, in order to define USB gadget parameters using files, directories, and links. The implementation comprises of the following:<\/p>\n\n\n\n<ul id=\"12estygjzuyjat50\" class=\"wp-block-list has-urbanist-font-family\">\n<li><strong>ConfigFS<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>File Directory<\/strong>: fs\/configfs\/dir.c<\/li>\n\n\n\n<li><strong>Comments<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Filesystem driver that enables file and link creation for different functionalities, such as USB.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<ul id=\"rl0igygjzuyjat62\" class=\"wp-block-list has-urbanist-font-family\">\n<li><strong>USB ConfigFS<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>File Directory<\/strong>: drivers\/usb\/gadget\/configfs.c<\/li>\n\n\n\n<li><strong>Comments<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Registers USB configFS callbacks to the configFS filesystem. Exposes different configFS files to userspace\/application, in order to configure the USB configuration. This entity interacts closely with USB composite.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading has-urbanist-font-family\" id=\"a2alg97823\"><strong>How to Initialize USB ConfigFS<\/strong><\/h4>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"nihu582836\">Since USB configFS is a filesystem, applications\/users can use file commands to initialize an empty instance.<\/p>\n\n\n\n<pre class=\"wp-block-code has-urbanist-font-family\"><code><strong># mounts the configFS filesystem \n<\/strong>mount -t configfs none \/sys\/kernel\/config \n\n<strong># initialize USB configFS <\/strong>\nmkdir \/sys\/kernel\/config\/usb_gadget \nmkdir \/sys\/kernel\/config\/usb_gadget\/g1<\/code><\/pre>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"nihu582836\">Once the &#8220;g1&#8221; directory is created, users will find files and directories already present within it. Technical details and code references for interested folks can be found in the Technical Details section.<\/p>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"9rp6z73626\"><strong>Sample USB ConfigFS Layout:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"662\" height=\"1024\" src=\"https:\/\/rethinkit.blog\/wp-content\/uploads\/2024\/03\/Copy-of-Flowchart-1-1-662x1024.png\" alt=\"\" class=\"wp-image-27\" style=\"width:309px;height:auto\" srcset=\"https:\/\/rethinkit.blog\/wp-content\/uploads\/2024\/03\/Copy-of-Flowchart-1-1-662x1024.png 662w, https:\/\/rethinkit.blog\/wp-content\/uploads\/2024\/03\/Copy-of-Flowchart-1-1-194x300.png 194w, https:\/\/rethinkit.blog\/wp-content\/uploads\/2024\/03\/Copy-of-Flowchart-1-1.png 698w\" sizes=\"auto, (max-width: 662px) 100vw, 662px\" \/><\/figure>\n\n\n\n<h4 class=\"wp-block-heading has-urbanist-font-family\" id=\"hn5a3192333\"><strong>USB ConfigFS Parameters<\/strong><\/h4>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"1hvty4282\">There are several USB configFS parameters throughout the hierarchy, but there are only a few that need to be populated in order to trigger USB enumeration.<\/p>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"1piqp373845\"><strong><u>Base Directory<\/u><\/strong> = \/sys\/kernel\/config\/<\/p>\n\n\n\n<p class=\"has-urbanist-font-family\"><\/p>\n\n\n\n<figure style=\"margin-top:0;margin-bottom:0;padding-top:0;padding-right:0;padding-bottom:0;padding-left:0;font-size:13px\" class=\"wp-block-table has-urbanist-font-family\"><table><thead><tr><th><strong>Directory\/File<\/strong><\/th><th><strong>Software Defined?<\/strong><\/th><th><strong>Multiple Instances?<\/strong><\/th><th><strong>Comments<\/strong><\/th><\/tr><\/thead><tbody><tr><td>&lt;base&gt;\/<strong>usb_gadget<\/strong><\/td><td>Yes<\/td><td>No<\/td><td>Mount-point for USB configFS files and directories.<\/td><\/tr><tr><td>&lt;base&gt;\/usb_gadget\/<strong>&lt;g1&gt;<\/strong><\/td><td>No<\/td><td>Yes<\/td><td>Can define multiple USB gadget instances. Each instance will have its own set of files and directories.<br><br><strong>&#8220;g1&#8221;<\/strong> can be named differently.<\/td><\/tr><tr><td>&lt;base&gt;\/usb_gadget\/g1\/<strong>UDC<\/strong><\/td><td>Yes<\/td><td>No<\/td><td>Carries the UDC device the USB gadget is binded to. The UDC string is defined within the software.<\/td><\/tr><tr><td>&lt;base&gt;\/usb_gadget\/g1\/<strong>idVendor<\/strong><\/td><td>Yes<\/td><td>No<\/td><td><\/td><\/tr><tr><td>&lt;base&gt;\/usb_gadget\/g1\/<strong>idProduct<\/strong><\/td><td>Yes<\/td><td>No<\/td><td><\/td><\/tr><tr><td>&lt;base&gt;\/usb_gadget\/g1\/functions\/<strong>*<\/strong><\/td><td>Yes<\/td><td>No<\/td><td>Objects within the <strong>&#8220;functions&#8221; directory define the available USB function drivers available. Examples can be:<\/strong><br>  &#8211; ncm.&lt;0&gt;<br>  &#8211; ffs.&lt;adb&gt;<br>  &#8211; mass_storage.&lt;0&gt;<br><br>Function drivers are identified with software defined strings when utilizing USB configFS.<\/td><\/tr><tr><td>&lt;base&gt;\/usb_gadget\/g1\/configs\/<strong>&lt;c.1&gt;<\/strong><\/td><td>No<\/td><td>Yes<\/td><td>Defines a set of USB functions that are included in your USB configuration.<br><br>USB devices can have multiple USB configurations (if required)<\/td><\/tr><tr><td>&lt;base&gt;\/usb_gadget\/g1\/configs\/c.1\/<strong>*<\/strong><\/td><td>No<\/td><td>No<\/td><td>Softlinks to USB function driver files under the <strong>&#8220;functions&#8221; <\/strong>folder.<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">USB configFS files\/parameters<\/figcaption><\/figure>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"he98o293251\">The above table highlights the bare minimum settings that will need to be added for defining a USB configuration, and binding to the USB UDC.<\/p>\n\n\n\n<h4 class=\"wp-block-heading has-urbanist-font-family\" id=\"ny0xn259414\"><strong>Creating a USB Configuration<\/strong><\/h4>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"px5353245\">Once initializing USB configFS, the following code snippet can be used to initialize a connection with the host. <\/p>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"fjytz2085\">It creates a USB device that exposes a USB composition which includes:<\/p>\n\n\n\n<pre class=\"wp-block-code has-urbanist-font-family\"><code><code>echo 0xa410 &gt; \/sys\/kernel\/config\/usb_gadget\/g1\/idVendor<\/code><code>echo 0x0001 &gt; \/sys\/kernel\/config\/usb_gadget\/g1\/idProduct<\/code><code>mkdir \/sys\/kernel\/config\/usb_gadget\/g1\/functions\/mass_storage.0 <\/code><code>mkdir \/sys\/kernel\/config\/usb_gadget\/g1\/functions\/adb.0<\/code><code>mkdir \/sys\/kernel\/config\/usb_gadget\/g1\/functions\/rndis.0<\/code><code>mkdir \/sys\/kernel\/config\/usb_gadget\/g1\/configs\/c.1<\/code><code>ln -s \/sys\/kernel\/config\/usb_gadget\/g1\/functions\/mass_storage.0 <\/code><code>\/sys\/kernel\/config\/usb_gadget\/g1\/configs\/c.1\/f1<\/code><code>ln -s \/sys\/kernel\/config\/usb_gadget\/g1\/functions\/adb.0 <\/code><code>\/sys\/kernel\/config\/usb_gadget\/g1\/configs\/c.1\/f2<\/code><\/code><\/pre>\n\n\n\n<div class=\"wp-block-group has-urbanist-font-family is-vertical is-layout-flex wp-container-core-group-is-layout-1 wp-block-group-is-layout-flex\">\n<ul id=\"944q4ygjzuyjat218\" class=\"wp-block-list\">\n<li><span style=\"text-decoration: underline;\">USB VID<\/span>: 0xa410<\/li>\n\n\n\n<li><span style=\"text-decoration: underline;\">USB PID<\/span>: 0x0001<\/li>\n\n\n\n<li><span style=\"text-decoration: underline;\">USB Configuration<\/span> #1\n<ul class=\"wp-block-list\">\n<li>USB Interface (function) #1 &#8211; USB mass storage<\/li>\n\n\n\n<li>USB Interface (function) #2 &#8211; USB Android Debug Bridge (ADB)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading has-urbanist-font-family\" id=\"bu9fq10922\"><strong>Trigger USB Enumeration<\/strong><\/h4>\n<\/div>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"gs5v123303\">After setting up the USB configuration, the device can now attempt to enumerate with the host. In terms of USB, the USB device controller (UDC) is the hardware which initiates and handles device mode operations. For the device to be able to connect to a host, the USB software must have a UDC driver enabled.<\/p>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"ws2rx215005\">Users can check if there is an available UDC by looking at the following directory:<\/p>\n\n\n\n<pre class=\"wp-block-code has-urbanist-font-family\"><code><code><strong># check for any available UDCs<\/strong><\/code><code>ls -l \/sys\/class\/udc<\/code><\/code><\/pre>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"91x1n261391\">If there is an available UDC, this will be the string users will echo to the UDC configfs file.<\/p>\n\n\n\n<pre class=\"wp-block-code has-urbanist-font-family\"><code><strong># USB configFS currently has no associated UDC\n<\/strong>root@raspberrypi0-wifi:\/sys\/kernel\/config\/usb_gadget\/g1# cat UDC\n\n<strong># check for available UDCs \n<\/strong>root@raspberrypi0-wifi:\/sys\/kernel\/config\/usb_gadget\/g1# ls -l \/sys\/class\/udc \n\nlrwxrwxrwx 1 root root 0 Jan 4 07:58 <strong>20980000.usb<\/strong> -> ..\/..\/devices\/platform\/soc\/20980000.usb\/udc\/20980000.usb \n\n<strong># trigger USB enumeration on the desired UDC \n<\/strong>root@raspberrypi0-wifi:\/sys\/kernel\/config\/usb_gadget\/g1# echo 20980000.usb > UDC \n\nroot@raspberrypi0-wifi:\/sys\/kernel\/config\/usb_gadget\/g1# cat UDC \n20980000.usb<\/code><\/pre>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"z7rlt357014\">Once a valid UDC is written, the PC\/host should now have a device appear. In the previous examples, users would see a device that includes mass storage + adb interfaces\/functions.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn about the basics of USB ConfigFS and how to utilize it to create your own USB composition!<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-1","post","type-post","status-publish","format-standard","hentry","category-technical"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/rethinkit.blog\/index.php?rest_route=\/wp\/v2\/posts\/1","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rethinkit.blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rethinkit.blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rethinkit.blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rethinkit.blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1"}],"version-history":[{"count":20,"href":"https:\/\/rethinkit.blog\/index.php?rest_route=\/wp\/v2\/posts\/1\/revisions"}],"predecessor-version":[{"id":343,"href":"https:\/\/rethinkit.blog\/index.php?rest_route=\/wp\/v2\/posts\/1\/revisions\/343"}],"wp:attachment":[{"href":"https:\/\/rethinkit.blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rethinkit.blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rethinkit.blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}