This documents my personal flow for downloading and installing a Linux kernel with my xHCI and USB 3.0 code. Until the code is in the upstream kernel and shipping in Linux distributions, you'll have to follow these directions to get Linux USB 3.0 support.
Background
This tutorial is mostly for vendors who want to test their USB 3.0 devices or xHCI host controller prototypes. This assumes you already have a standard Debian or Ubuntu installation. There are many helpful guides for installing Ubuntu or Debian, so I won't go into detail on that here.
There are also other guides for creating a custom kernel, but most walk you through creating a .deb package. Going through the extra steps of creating the package adds too much time if you're updating your kernel a lot in order to track an upstream git tree.
Pre-work
First, you need to install some extra software that may not come with a standard Ubuntu or Debian install. You can install software by using a gui installer (like synaptic). You can also open a terminal (found under the Applications menu in Gnome and under the System menu in KDE) and install software using the command line. I'll assume you're using the command line in this tutorial.
First install the packages necessary to compile the Linux kernel. If you're on Debian, type the following:
sudo aptitude install wget make git-core libncurses5-dev
If you're on Ubuntu, use this command instead:
sudo aptitude install wget make git-core lib32ncurses5-dev
Next, you'll need to add a script to install the Linux kernel.
mkdir ~/bin/
cd ~/bin/
wget http://minilop.net/~sarah/installkernel
sudo chmod a+x installkernel
A standard Debian or Ubuntu install should add the bin directory in your homedir to your path automatically whenever you start a new terminal shell. To make sure you can run that script, close your current terminal, restart a new terminal, and type
echo $PATH
You should see /home/username/bin in the output (replace username with whatever username you picked). You can also make sure the script is in your path by typing "installker" and hitting tab. If the command expands to "installkernel", then your path is set correctly and the script permissions are right. If not, follow the next instructions.
Using the installkernel script
Now add that script to your PATH in your rc file for your terminal shell of choice. Bash is the default option, so edit (or create) the .bashrc file in your home directory. You can use vim, emacs, or even OpenOffice Writer to edit this file. If you must use OpenOffice Writer, make sure you save the file with the name ".bashrc" with a Text encoded (txt) file type, and uncheck the "Automatic file name extension" box.
Add this line to your .bashrc:
PATH="~/bin:$PATH"
If you already have a line that starts with PATH, simply add the ~/bin: after the first double quote.
Downloading a custom kernel
Most custom kernels are hosted on git.kernel.org. They are kept under revision control using the VCS called "git". This means the kernels are updated often, and you may need to use git to update to the latest version. That's explained later.
In this tutorial, I'll assume you want to download my custom kernel to test USB 3.0 host controllers and devices.
First, move to your homedirectory and "clone" the git repository so you have a local copy checked out:
cd
git clone git://git.kernel.org/pub/scm/linux/kernel/git/sarah/xhci.git
Downloading the kernel may take a while. If you're behind a firewall, you may need to set the $http_proxy environment variable (by adding a "http_proxy=url" line to your .bashrc) and use http to clone the repository. In this case, replace the last command with
git clone http://www.kernel.org/pub/scm/linux/kernel/git/sarah/xhci.git
You should see output like "Initialized empty Git repository in /home/username/xhci/.git/". If nothing else happens for a couple minutes after that output, then you probably have firewall problems.
Choosing your kernel configuration
First, change directories into the newly created repository clone:
cd xhci/
Now we need to choose the configuration options for the new kernel, and compile it. A configuration file describes your system configuration, and whether you want drivers compiled into the kernel or if you want the drivers to be dynamically loadable as a module.
You can use the configuration file that the default distribution install created by typing:
cp /boot/config-`uname -r` .config
Now we need to change or add new configuration options:
make menuconfig
This will present a text-based GUI of all the configuration options for the Linux kernel. This is everything from what file systems to support (like FAT or EXT3) to what drivers to load (like SCSI, USB, or networking cards). A driver is built into the kernel if it has a star "*" by it. The driver is a dynamically loadable module if it has an "M" by it. If the option has nothing in the brackets, it won't be compiled. If you want a driver to be a module, just hit the "m" key. If you don't want a driver, hit "n"; if you want to compile a module into the kernel or say yes to a configuration option, hit "y".
To be able to use my USB 3.0 code, navigate to Device Drivers and onto the USB support menu. Make sure "Support for Host-side USB" is a dynamically loadable module by moving the cursor to that item and hitting the 'm' key. You may get a message that other drivers depend on host-side USB being built into the kernel. If so, you need to make sure all the drivers under this menu with a star by them ("*") are changed to be modules (with an "M") by them.
You need to change a few more things in this menu. Choose to compile the xHCI (USB 3.0) host controller driver as a module by hitting "m". Turn off (hit "n") on the "USB selective suspend/resume and wakeup" option, since that isn't supported by the driver yet. Turn on debugging for the USB subsystem by hitting "y" on "USB verbose debug messages" and "USB announce new devices". Also turn on the "Debugging for the xHCI host controller" option.
Compiling and installing your kernel
Now that you have your kernel configured, compile your kernel by typing
make -j4
This may take a while. Go get a cup of tea or wander off for lunch. Once that compile finishes, you're ready to install your kernel by typing
sudo make modules_install install
That will take a bit, but not as long as the compile.
Controlling when the xHCI driver is loaded
This next step is optional. If you follow the above steps exactly, the xHCI driver will be loaded automatically when you boot the new kernel. It's much easier for me to look at debug output from the driver if it's not interspersed with boot code. To do that, you should dynamically load the driver after the machine finishes booting.
First, we have to prevent the driver from being loaded automatically at boot time by black-listing the module. (Thanks to GotenXiao for the tip!) Just execute this command:
echo "blacklist xhci" > /etc/modprobe.d/xhci
Now whenever you want to load the xHCI driver, type the following (after you've rebooted into the new kernel):
sudo modprobe xhci
When you want to unload the module, type this:
sudo modprobe -r xhci
This is equivalent to enabling and then disabling the driver in the Windows system manager.
Updating your kernel
If the kernel.org tree gets patches added to it, or it's updated to a newer kernel, you'll need to update your local checkout. There are a couple ways to this, depending on if you have local changes to the files. If you haven't modified any files, it's safe to type these two commands from within your xhci directory:
git fetch
git reset --hard origin/master
This resets the local checkout to exactly what's in the remote repository. If you have local changes, you'll need to do something more complicated in order to merge in or rebase against the remote repository changes.
You'll need compile and install the new code using the steps above, and then reboot.
Debugging
I suggest that when you run the xHCI driver, you have two tabs in your terminal window open. In one tab, redirect the kernel debugging messages to a file, and display the output using the tee command (thanks to Mike for the tip!):
tail -f /var/log/kern.log | tee ~/xhci-log-`date +%Y-%m-%d-%H-%M`.txt
The date part adds the current year-month-day-hour-minute to the logfile name so you don't overwrite an old log file.
In the second tab, start the xHCI driver after 5 seconds. The slight delay allows you time to switch back to the first tab to watch the driver debug messages. In the second tab, type:
sleep 5 && sudo modprobe xhci
Send the logfile to me if you have issues. You may need to use netconsole to capture the kernel debug messages if your system is hanging because of a driver bug.
| link | 26 comment(s)
Posted by Karthik at Thu Jun 11 15:48:40 2009
Well lots of explanation about simple things ($PATH) from a kernel hacker ? If every hardware manufacturer and developer would do the same then linux would be in a different league.
Keep it up.
Posted by CompanionCube at Thu Jun 11 16:50:43 2009
While explaining how to build and install a custom kernel, I know you did /not/ just explain how to edit a text file with OOo Writer...
Also, a female Linux developer? LIES. ;)
Posted by Dr. Jochen L. Leidner at Thu Jun 11 16:51:22 2009
Thanks for this!
Did you mean to say "cd; git" in
cd git clone git://git.kernel.org/pub/scm/linux/kernel/git/sarah/xhci.git
?
Best regards
Jochen
Posted by Primefalcon at Thu Jun 11 17:35:11 2009
Ahh the sweetness of 4.8 GB/S. Wonder what USB 4 will see when it hits the streets....
Great guide Sarah, very easy to follow, Thanks for an super easy to read and follow instructions, wish everyone wrote like you, I'll definitely be subscribing to your rss feed!
Posted by GotenXiao at Thu Jun 11 22:22:19 2009
Rather than renaming the module file, why not blacklist it in modprobe?
echo "blacklist xhci" > /etc/modprobe.d/xhci
Or similar should do the trick for most recent distros.
Posted by Oliver at Fri Jun 12 00:08:49 2009
Wow, that is really a leap. I can still remember how long it took for basic USB support at all in the beginning of USB on Linux.
Thanks to Inaki from Spain, who wrote the first stack at that time, when there was Hardware but no Software / Device driver. Now it's the other way round :-)
Good luck
Posted by Peter at Fri Jun 12 05:43:52 2009
Hi,
Very impressed with the driver development and astonished at the clarity of the howto. Have O'Reilly been on the phone yet?
Peter
Posted by Mike at Fri Jun 12 06:46:59 2009
You can cut down the number of tabs to 2 by running
tail -f /var/log/kern.log | tee ~/xhci-log.txt
instead of the command you suggest. This will cause output to go both to the screen and to the file.
Cheers!
Posted by dacian at Fri Jun 12 08:31:07 2009
Hi I've put the comment in the wrong place.
Anyway all my respect and admiration for this job!
Posted by Sarah Sharp at Fri Jun 12 14:38:14 2009
Dr. Jochen L. Leidner: PyBlosxom uses an older markdown implementation, so the code examples weren't formatted right until I changed the tabs to four spaces. It should look better now.
Posted by Marc at Wed Jun 17 18:08:29 2009
Nicely done and a pleasure to read! One thing though, wouldn't "sudo apt-get install make git-core lib32ncurses5-dev" do the same on any recent Ubuntu version?
Posted by Rahul at Thu Jun 18 06:05:21 2009
Hi Sarah,
Is there any mailing list for xhci driver related discussions?
thanks!
Posted by Sarah Sharp at Fri Jun 19 07:59:35 2009
Rahul: You can subscribe to the linux-usb mailing list at http://www.linux-usb.org/mailing.html This is a public mailing list, so anyone can read your messages. If you need to email me about issues privately, email my work adress at sarah dot a dot sharp at Linux dot intel dot com.
Posted by Giles at Tue Aug 25 02:08:42 2009
Hi Sarah,
well done! Thank you.
for another,
Have you tried the NEC's USB 3.0 host controller?
Posted by Sarah Sharp at Wed Aug 26 10:36:11 2009
Giles: Yes, the NEC host controller works under the Linux xHCI driver.
Posted by Ryan at Fri Oct 23 05:26:15 2009
The first operating system to provide support for the speedier successor of USB 2.0, mainly USB 3.0, is not the Microsoft developed Windows nor is it the Apple developed Mac OS X. The first OS that will be capable of providing support for USB 3.0 is Linux.
Posted by Jo at Wed Jan 20 05:38:39 2010
Hi Sarah,
I observed that xhci hub doesn't have any support for features like "function suspend", U1 and U2 enable, basically power related feature selctors. Can you please help me where i can find that. Its urgently need it for my testing puposes.
Please reply ASAP,
Thanks,



