Tutorials/CompileKernelModulesForTheWDTV
Compile Kernel Modules for the WDTV
This tutorial explains how to compile new kernel modules for the Western Digital TV HD (WDTV) with the help of the WDTV Tools VMware image. As an example an application that adds Bluetooth support will be created.
Prerequisites
As already mentioned this tutorial is based on the WDTV Tools VMware image, for download links and details like username / password please take a look at WDTV Tools VMware image (if you use another Linux see the note below). Also it is assumed that you have a good understanding of Linux, the command line and ideally know a thing or two about compilation under Linux. The latter point probably won't hurt that much for the tutorial, but you won't understand a few things and in case any problems occurs you might be stuck. But anyway, read ahead, have fun and try, its the fastest way to learn.
Note: If you don't want to use the WDTV Tools VMware image you can still use this tutorial but you should have checked out the WDTV Tools Subversion repository if you don't want to gather every piece of software and sources yourself. (svn co https://wdtvtools.svn.sourceforge.net/svnroot/wdtvtools/trunk wdtv)
This tutorial assumes that you are logged in as the user wdtv and the SVN repository is checked out into the user's home directory as wdtv. If you use the WDTV Tools image this is already the case.
Setting Up the Environment
First we need a few things that are not included in the WDTV Tools VMware image from the start. You must install gawk and ncurses, a program and a library the kernel compilation depends upon. Install them with:
# sudo apt-get install gawk libncurses5-dev
Note: If you are asked for a password it is the same as your user password ("!develop" (without "") if you did not change it).
The second thing mandatory are of course the kernel sources, you can check them out from the repository with
# svn up ~/wdtv/kernel
You can get a coffee or any other beverage with caffeine content now because this will take a while.
Configuring the Kernel
Note: The WDTV kernel version at the time of this writing is 2.6.15, so we use the directory linux-2.6.15 for the kernel. In case this changes in the future and this tutorial is not adapted in time just change the version number.
Now that everything is in place we can adapt the kernel configuration. First its advisable to use a default configuration which we then modify. You can use the default configuration from the WDTV Tools repository, it is the one from Zorander's ext3-boot.
cd ~/wdtv/kernel/linux-2.6.15 cp ../linux-2.6.15-default.config .config
As you might have guessed the current kernel configuration is stored in the .config file of the kernel working directory. There are two ways to modify the kernel configuration, the first way is fast but useless for this tutorial: edit the .config file with your preferred editor. We will do it the comfortable way with a graphical editor. To start it type
make menuconfig
into the command line. After the graphical editor is compiled and started, you should see an image like the following:
You can navigate through the menus to see what kind of options there are and which ones are enabled to familiarize yourself with the tool. Navigation is done with the arrow keys, to selected an entry press Enter, to navigate back select Exit and to change a value press space. There are three possible values for any kernel module: yes (marked with a *), no (empty box) and module (marked by an M). Some options can only be added or not, there the module option is not available. Since we cannot replace the kernel on the WDTV you must always compile new stuff as a module.
Adding Bluetooth Support
Since you now know the basics we can start with our example and add Bluetooth support. Navigate to "Networking" and mark "Bluetooth subsystem support" with an M. Then enter into "Bluetooth subsystem support" and mark everything as a module and the module options with yes. Afterwards do the same step with the menu entry "Bluetooth device drivers". The following three screen shots illustrate the process.
Finally exit the menu configuration tool by selecting exit and saying "yes" to whether the options should be saved. Now our new configuration options where stored in the .config file.
Compiling the Kernel
After the configuration is done you can compile the kernel by invoking "make" in the kernel directory. You should see an output like the following example:
# make CHK include/linux/version.h CHK include/linux/compile.h CHK usr/initramfs_list [...] CC init/version.o LD init/built-in.o LD vmlinux SYSMAP System.map Building modules, stage 2. MODPOST
Again get something to drink, this will take a few minutes too.
Note: You can ignore any warnings in the form of *** Warning: "add_input_randomness" [drivers/input/input.ko] undefined! for now
Using the Modules
The modules are compiled as .ko files in different sub directories in the kernel working directory. The general procedure to use a new module is simple: find the .ko file (e.g. foo.ko), copy it to the WDTV and activate it with insmod foo.ko.
Finding the Modules
In case you don't know what the name of your module is or in case you have several modules you need to find it / them. The easiest way to do this is to list all modules and them remove the ones that are already included in the firmware by default because you won't need to distribute them.
You can find all modules with the following command:
find | grep \\.ko$ | sort
When you do this with the default configuration, i.e. compile the kernel with the linux-2.6.18-default.config, the following modules are available.
./drivers/char/fipkernel.ko ./drivers/char/irkernel.ko ./drivers/char/sckernel.ko ./drivers/net/mii.ko ./drivers/net/phy/libphy.ko ./drivers/net/tango2_enet.ko ./drivers/usb/net/asix.ko ./drivers/usb/net/catc.ko ./drivers/usb/net/cdc_ether.ko ./drivers/usb/net/kaweth.ko ./drivers/usb/net/pegasus.ko ./drivers/usb/net/rtl8150.ko ./drivers/usb/net/usbnet.ko ./fs/cifs/cifs.ko ./fs/jffs2/jffs2.ko ./fs/lockd/lockd.ko ./fs/nfs/nfs.ko ./fs/reiserfs/reiserfs.ko ./fs/xfs/xfs.ko ./lib/zlib_deflate/zlib_deflate.ko ./net/sunrpc/sunrpc.ko
Doing this with our Bluetooth configuration results in:
./drivers/base/firmware_class.ko ./drivers/bluetooth/bcm203x.ko ./drivers/bluetooth/bfusb.ko ./drivers/bluetooth/bpa10x.ko ./drivers/bluetooth/hci_uart.ko ./drivers/bluetooth/hci_usb.ko ./drivers/bluetooth/hci_vhci.ko ./drivers/char/fipkernel.ko ./drivers/char/irkernel.ko ./drivers/char/sckernel.ko ./drivers/input/input.ko ./drivers/input/keyboard/atkbd.ko ./drivers/input/mousedev.ko ./drivers/input/mouse/psmouse.ko ./drivers/input/serio/i8042.ko ./drivers/input/serio/libps2.ko ./drivers/input/serio/serio.ko ./drivers/input/serio/serport.ko ./drivers/net/mii.ko ./drivers/net/phy/libphy.ko ./drivers/net/tango2_enet.ko ./drivers/usb/net/asix.ko ./drivers/usb/net/catc.ko ./drivers/usb/net/cdc_ether.ko ./drivers/usb/net/kaweth.ko ./drivers/usb/net/pegasus.ko ./drivers/usb/net/rtl8150.ko ./drivers/usb/net/usbnet.ko ./fs/cifs/cifs.ko ./fs/jffs2/jffs2.ko ./fs/lockd/lockd.ko ./fs/nfs/nfs.ko ./fs/reiserfs/reiserfs.ko ./fs/xfs/xfs.ko ./lib/zlib_deflate/zlib_deflate.ko ./net/bluetooth/bluetooth.ko ./net/bluetooth/bnep/bnep.ko ./net/bluetooth/hidp/hidp.ko ./net/bluetooth/l2cap.ko ./net/bluetooth/rfcomm/rfcomm.ko ./net/bluetooth/sco.ko ./net/sunrpc/sunrpc.ko
The resulting differences, i.e. the modules we need for Bluetooth support, are:
./drivers/base/firmware_class.ko ./drivers/bluetooth/bcm203x.ko ./drivers/bluetooth/bfusb.ko ./drivers/bluetooth/bpa10x.ko ./drivers/bluetooth/hci_uart.ko ./drivers/bluetooth/hci_usb.ko ./drivers/bluetooth/hci_vhci.ko ./net/bluetooth/bluetooth.ko ./net/bluetooth/bnep/bnep.ko ./net/bluetooth/hidp/hidp.ko ./net/bluetooth/l2cap.ko ./net/bluetooth/rfcomm/rfcomm.ko ./net/bluetooth/sco.ko
Note: Some modules are missing because they are superfluous for most things and would only complicate this tutorial. Simply take it as that or read up on it somewhere.
To better work with the modules we will copy them to a new directory and continue our work from there:
mkdir ~/bluetooth cp ./drivers/base/firmware_class.ko ~/bluetooth/ cp ./drivers/bluetooth/bcm203x.ko ~/bluetooth/ cp ./drivers/bluetooth/bfusb.ko ~/bluetooth/ cp ./drivers/bluetooth/bpa10x.ko ~/bluetooth/ cp ./drivers/bluetooth/hci_uart.ko ~/bluetooth/ cp ./drivers/bluetooth/hci_usb.ko ~/bluetooth/ cp ./drivers/bluetooth/hci_vhci.ko ~/bluetooth/ cp ./net/bluetooth/bluetooth.ko ~/bluetooth/ cp ./net/bluetooth/bnep/bnep.ko ~/bluetooth/ cp ./net/bluetooth/hidp/hidp.ko ~/bluetooth/ cp ./net/bluetooth/l2cap.ko ~/bluetooth/ cp ./net/bluetooth/rfcomm/rfcomm.ko ~/bluetooth/ cp ./net/bluetooth/sco.ko ~/bluetooth/
Module Dependencies
Some kernel modules, including the Bluetooth modules, have dependencies. This means that in order to activate a module another module must be activated before it. This is done by loading the modules in the correct order. There are a automatic ways to do this but they are not supported by the WDTV firmware from the beginning, so we will do it the hard way. It basically means that you copy all the modules to your WDTV box, via ftp or scp, and then try to insert them manually. If the insert fails another module is required. A quick example is below:
# scp -r ~/bluetooth root@wdtv1.home:/tmp/
Copy files to the WDTV (replace wdtv1.home with the IP of your WDTV).
wdtv@wdtv-devel:~/bluetooth$ ssh root@wdtv1.home root@wdtv1.home's password: BusyBox v1.10.0 (2009-02-15 05:09:42 CST) built-in shell (msh) Enter 'help' for a list of built-in commands. # cd /tmp/bluetooth/ # insmod bnep.ko insmod: cannot insert 'bnep.ko': Success # dmesg | tail [...] bnep: Unknown symbol l2cap_load # insmod l2cap.ko # insmod bnep.ko
Note: Although the insmod command says "Success" it means there has been an error, you can check it with dmesg | tail. If insmod does not give any output the operation has been really successful.
Note: As you can see above the error is usually something in the form of "Unknown symbol foo_bar". In most cases you can guess the missing module based on the name of the symbol, as done with l2cap above. Sometimes however you are stuck because the name has nothing to do with the module name. In those cases you can either try all modules until it works, or if you know how, you can search the kernel sources for the module where the symbol / function is defined in.
After some try and error you will be able to get the following loading sequence
firmware_class.ko bluetooth.ko hci_vhci.ko hci_usb.ko hci_uart.ko sco.ko l2cap.ko bnep.ko hidp.ko rfcomm.ko bfusb.ko bcm203x.ko bpa10x.ko
Your's might be slightly different, because not all modules have dependencies. Note: the module firmware_class can give you always an error when you have wireless network support on your WDTV. You can ignore the error message in that case because the module has already been loaded.
To use this again simply create a shell script, e.g. insert.sh:
#!/bin/sh
insmod firmware_class.ko
insmod bluetooth.ko
insmod hci_vhci.ko
insmod hci_usb.ko
insmod hci_uart.ko
insmod sco.ko
insmod l2cap.ko
insmod bnep.ko
insmod hidp.ko
insmod rfcomm.ko
insmod bfusb.ko
insmod bcm203x.ko
insmod bpa10x.ko
Create an Application Image
After the previous section you are able to use the modules by copying them to the WDTV and executing a script. However, it is not very convienient because after a reboot everything has to be done again. Do work around this lets create an application image that loads the modules at start up.
Working from our copy of the Bluetooth modules in ~/bluetooth you can do it this way:
mkdir -p ~/bluetooth/etc/init.d cat > ~/bluetooth/etc/init.d/S10bluetooth-modules <<EOF #!/bin/sh insmod /apps/bluetooth-modules/firmware_class.ko insmod /apps/bluetooth-modules/bluetooth.ko insmod /apps/bluetooth-modules/hci_vhci.ko insmod /apps/bluetooth-modules/hci_usb.ko insmod /apps/bluetooth-modules/hci_uart.ko insmod /apps/bluetooth-modules/sco.ko insmod /apps/bluetooth-modules/l2cap.ko insmod /apps/bluetooth-modules/bnep.ko insmod /apps/bluetooth-modules/hidp.ko insmod /apps/bluetooth-modules/rfcomm.ko insmod /apps/bluetooth-modules/bfusb.ko insmod /apps/bluetooth-modules/bcm203x.ko insmod /apps/bluetooth-modules/bpa10x.ko EOF sudo chown root:root -R ~/bluetooth sudo mkcramfs ~/bluetooth ~/bluetooth-modules.app.bin
The above commands create a start script that inserts the modules in the correct order and creates an application image name bluetooth-modules.app.bin in the user's home directory. The application image can be distributed to add the Bluetooth modules to the WDTV.
Recap
This tutorial showed you how to use the WDTV Tools VMware image to compile kernel modules for the WDTV and use them. As an example Bluetooth support was added by compiling the modules and creating an application image that inserts them during the boot of the WDTV.
Note: This tutorial only added support for bluetooth modules, to use them you still need some software. You can install the Linux Bluetooth stack if you have optware with ipkg install bluez2-utils. A discussion thread is over at the WDTV Forum, there are some tips and tricks on the issue.
Attachments
- kernel-menuconfig-bt-device-drivers.png (58.8 KB) - added by elmar_weber 3 years ago.
- kernel-menuconfig-bt-network.png (57.0 KB) - added by elmar_weber 3 years ago.
- kernel-menuconfig-bt-subsystem.png (59.2 KB) - added by elmar_weber 3 years ago.
- kernel-menuconfig-main.png (76.8 KB) - added by elmar_weber 3 years ago.



