Friday, March 21, 2014

Finding and Installing the right device driver for your HW in Linux

The biggest problem making any hardware work is finding the right driver, how many of us spent days trying different driver packages and finally nothing works, especially in windows!

Because i get lots of queries in this area, here's a tutorial to find the right driver for your WiFi card, of course in Linux. 

The below procedure is automated and happens when you insert a device, creating a network interface ready to use (Will explain this in another article). 

But, for some reason if that's happening, this procedure helps us to find the kernel version which/from which that HW is supported.

Steps:

1) Insert the device :-)

2) Depending on the BUS interface it uses, issue the command "lsusb/lspci", check for the device in the list. 
For Eg: Lets take a belkin WiFi adapter.

# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 003: ID 413c:2107 Dell Computer Corp.
Bus 001 Device 004: ID 04ca:0061 Lite-On Technology Corp.
Bus 001 Device 028: ID 050d:615a Belkin Components F7D4101 / F9L1101 802.11abgn Wireless Adapter [Broadcom BCM4323]

If it is not appearing in this list, check dmesg for any errors. If not pray to god. (This will probably be another article :-))

Make a note of the ID, in this case 050d:615a the first part is Vendor ID representing the maker of the chipset, second part identifies the chipset itself the Product ID.

We will use these ID's to find the right driver for this chipset.

3)  As discussed in earlier articles the depmod comes to our aid, it creates a mapping file called "modules.alias" which has the mapping information of ID to driver.

Refer depmod and modules.alias (go to DETAILS section).

Now we will check the file modules.alias in all kernel version to check for any supported driver for this chipset.

grep -irn "v050dp615a" /lib/modules/<kernel version>/modules.alias

Note: Append "v" before vendor ID and "p" before product ID. 

4) Ff no results are found, best thing is to check for latest vanilla kernel and do a binary search from there, generally if its not supported in latest it will be not supported, unless its an old HW for which support was removed in latest.

The problem here is to access the modules.alias (which will be in the kernel installation directory, generally /lib/modules) we need a compiled kernel, so it might take time if the latest kernel is not already compiled and installed.

(Any scripts are welcome here).

5) If you find a driver, just do a modprobe -v <driver name>. 

Eg: 

alias usb:v0B05p1761d*dc*dsc*dp*ic*isc*ip*in* rt2800usb
modprobe rt2800usb.

If still the driver is not found, probably that chipset is not supported in Linux, is that even possible? Linux has a very good support for supporting different HW's.

Don't worry we still have ways to make it work. NDISWrapper comes to the rescue. We can use NDIS wrapper in below scenarios (from #4)


  1. No open source driver provided in the Ubuntu repositories.
  2. The driver provided by default in Ubuntu is not working out.
  3. The proprietary driver provided by the card vendor is not working out.
  4. Test ndiswrapper performance versus alternative driver(s).
  5. Test hardware failure for your card.


NDIS Wrapper:

NDIS is similar to mac80211 in Windows, all the network drivers Ethernet, wireless, Bluetooth use this layer which implements the entire WDM driver model and make life easier for windows network device driver developers.

This functionality is ported to linux, where we can take any NDIS based windows driver (any windows network driver) and make it work in linux.

(Detailed discussion in another article, lets not deviate here. For those of you cant wait, see #5 for some basic idea on how it works, summary here.)


  • NDISwrapper is composed of two main parts, 

    • Command line tool used at installation time 
    • Windows subsystem used when an application calls the Wi-Fi subsystem.

  • "compile" a couple or more of Windows files, and the NDISwrapper's version of Windows DDK into a Linux Kernel Module. This is done with a tool named "ndiswrapper". 

  •  A Linux application can then send request to this Linux driver that automatically does the needed adaptations to call its—now—internal Windows driver and DDK.


Please follow the below steps, to install the windows driver in linux.



  1. wget <Link to the windows driver binaries, *.sys, *.inf>
  2. cd <Directory>
  3. ndiswrapper -i <INF file name>
    • This command will install the windows driver in Linux through the ndiswrapper utility.
  4. ndiswrapper -l
    • check the list of windows driver installed using ndis wrapper.
  5. Install the ndiswrapper Linux driver if not already installed (Distro Specific installation/ download from source).

    1. depmod -a
      • rebuild the modules database, so that next step will work.
    2. modprobe ndiswrapper
      • Load the ndiswrapper driver
    3. Steps from #1 for reference. 



Now download this file to your desktop:http://downloads.sourceforge.net/project/ndiswrapper/stable/ndiswrapper-1.59.tar.gz Right-click it and select 'Extract Here.' Then do:
cd ~/Desktop/ndiswrapper-1.59
make
sudo make install
sudo modprobe ndiswrapper

Note: Even the though the example is related to a wifi device driver, but the same procedure can be applied to any device driver.

Happy Device Driving!

References: 

1) http://askubuntu.com/questions/394159/belkin-n600-usb-wireless-adapter-on-ubuntu-12-04 

2) http://www.cyberciti.biz/faq/linux-ndiswrapper-wpa_supplicant-howto/

3) http://sourceforge.net/apps/mediawiki/ndiswrapper/index.php?title=Main_Page

4) https://help.ubuntu.com/community/WifiDocs/Driver/Ndiswrapper 

5) http://en.wikipedia.org/wiki/NDISwrapper#Use