on Implementing USB Gadget Driver for exporting Mass Storage Functionality of OMAP5912 OSK via USB protocol Under the Esteemed guidance of Submitted by Mr.Babu Krishnamurthy S.V.Ravi Chandra (E048) Dept. of Embedded Systems Sandeep Kumar Alimi (E050) CDAC,Bangalore Anil Kumar Reddy(E008) K Venu Kumar (E026) Certificate of Approval of Project work This is to certify that the project report entitled “Implementing USB Gadget Driver for exporting Mass Storage Functionality of OMAP5912 OSK via USB protocol” is a bonafide work carried out by Mr. S.V.Ravi Chandra, Mr.Sandeep Kumar Alimi, Mr.Anil Kumar Reddy and Mr.K Venu Kumar for fulfillment of academic requirement for the award of certificate “Diploma in Embedded System Design”,Feb-2011. Signature of the Guide Mr. Babu Krishnamurty Project Guide CDAC ACTS, Bangalore Bangalore Signature of the Coordinator Mrs. Savithri Course Coordinator CDAC ACTS, ACKNOWLEDGEMENTS We know that the strength of a skyscraper lies in the strength of its foundation. We pay our heartfelt thanks and gratitude to Babu Krishnamurty Sir for teaching us the “Concepts of Operating Systems” in an absolutely simple, fundamental and thorough way which prepared us to understand even the abstruse and difficult concepts of Linux Device Drivers very easily. We are also grateful to him for providing us the opportunity to carry out this project, along with the guidance and moral support extended to us throughout the duration of project. We express our gratitude to our program co-ordinator Mrs. Savithri who helped us at every step throughout the course in every possible way. Eventually we are grateful to a number of individuals who are directly and indirectly involved in this project and whose support has been instrumental in the completion of this project. S.V.Ravi Chandra (E048) Sandeep Kumar Alimi (E050) Anil Kumar Reddy (E008) K Venu Kumar (E026) Contents Page No. Nomenclature Chapter 1: Introduction Chapter 2: Feasibility Study Chapter 3: Porting an Introduction 3.1 Porting 3.2 Modules in Porting 3.3 Prerequisites of Porting Chapter 4: Minicom 4.1 Configuring Minicom Chapter 5: TFTP Server 5.1 Configuring TFTP Server at HOST 5.2 Configuting TFTP at Client Chapter 6: NFS Server 6.1 Configuring NFS Server at HOST 6.2 Few Commands to start the NFS 6.3 NFS Configuration files Chapter 7: Boot Loader Chapter 8: Root File System 8.1 How to Build Busy box 8.2 NFS based file system 8.3 INITRD based file system Chapter 9: Linux kernel for OMAP5912OSK 9.1 Compilation of Linux Kernel 9.2 Upload Linux kernel to OSK Chapter 10: Implementing Gadget Driver 10.1 Implementing the USB Gadget Driver 10.2 Procedure to make the board work standalone Chapter 11:Conclusion Chapter 12:References i NOMENCLATURE All the commands are written in Italic <HOST> -- commands starting with this keyword shows these commands has to be executed from host terminal <MINICOM_U-BOOT> -- commands starting with this keyword shows these commands has to be executed on OMAP5912OSK board at U-boot loader via minicom <MINICOM_LINUX> -- commands starting with this keyword shows these commands has to be executed from OMAP5912OSK board at linux prompt. CHAPTER 1 INTRODUCTION INTRODUCTION The main goal of the Project is to write a Gadget Driver for the OMAP5912OSK. Using this gadget driver we are exporting mass storage functionality of OMAP5912-OSK to the host side. Before writing a gadget driver for the Device side there are certain prerequisites which are to be full-filled. First requirement is porting which includes installing the U-boot loader image which sets the environment required for running Linux kernel and then the Linux Kernel image is brought into the Flash of the OMAP-5912-OSK. Porting the U-Boot loader and the Linux Kernel on the kit requires setting up the TFTP Server at the machine side and client at the Kit side. Along with the TFTP server, setting up the NFS Server is also very important; it hosts the root-file-system which provides the environment for execution of the programs on the kit which are kept on the server. To make device completely stand-alone, use initrd based file system. The kernel version being used is Linux-2.6.27. The U-BOOT version is U-BOOT-1.1.6. Busy box version 1.17.1 Gadget Driver Development This phase involves implementation of the Gadget driver which handled request right from introducing gadget and its capabilities to host to exporting a specific device functionality. CHAPTER 2 FEASIBILITY STUDY FEASIBILITY STUDY we have done feasibility study to understand the possibility of implementing it in hardware and the support available from linux kernel. This stage will ensure , the hardware selected (OMAP 5912 OSK) will support USB Device functionality and the same can be extracted from the USB port available on the board. In this stage we also studied the extent of support available in linux kernel for gadget driver sub-system. We have referred all the hardware documentation of OMAP5912 processor and OSK5912 hardware specifications to conclude that the implementation of gadget driver can be done with OSK. The documents referred for this study are mentioned below and also attached in the CD submitted with the project report. The sub-systems and files referred for this project are: USB subsystem: <Kernel source>/drivers/usb/gadget/omap_udc.c(Device controller) <Kernel source>/drivers/usb/gadget/file_storage.c(Gadget driver) <Kernel source>/arch/arm/mach-omap1/board-osk.c <Kernel source>/include/linux/usb/gadget.h <Kernel source>MTD subsystem: <Kernel source>/drivers/mtd/mtdcore.c <Kernel source>/drivers/mtd/mtdsuper.c <Kernel source>/drivers/mtd/mtdblock.c one should have thorough understanding of the following, to have clear cut picture of the project how to configure the USB controller for slave operation/Device operation How and what are gadget driver API's used, how we speak to Device controller driver. Good understanding of the USB architecture and mainly how the data transfer happens through endpoints, Good understanding of the USB device configuration procedure. As explained in the below chapters configuring and porting of linux needs to be done in two modes one as HOST and one as DEVICE While in HOST mode the omap5912 OSK board works a USB host and can detect if any usb-device is plugged into USB port. While in DEVICE mode the omap5912 OSK board will work as USB slave and shall not detect any USB device plugged into USB port. This simple needs to be done to ensure the configuration is done correctly. CHAPTER 3 PORTING- AN INTRODUCTION PORTING –AN INTRODUCTION 3.1 Porting Porting is a process of customizing an original kernel source so as to make it compatible to run on a particular architecture of a particular hardware environment. Different hardware has got different internal structure i.e. the internal implementation of the basic blocks that make that hardware board. Two different development boards can have a totally different type of memory layout, memory access methods, peripherals and other features. So the kernel that may run on one of them will not work on other because of the basic difference in the board architecture. This is the reason to customize the kernel. Customization of the kernel would include changing some parameters in the kernel source, including or excluding some kernel modules, libraries etc. Once the customization is completed the kernel is compiled to generate an image that will be ready to be downloaded to the board. This process will also invariably include the BOOTLOADER also. The bootloader may or may not be required to customize, but yes, it can also be customized. It should be noted that porting is not an atomic process. The process of porting will in turn contains many other crucial modular steps. So when working on ‘porting’ process one should work in a modular method. Complete the process module by module. 3.2 Modules in Porting The process of porting can be basically divided into following modules Study Study of Bootloader Study of ‘kernel customization' Study of Building Root-file-system from Busybox Detailed study of the relevant h/w board Study of Support system required Compiling and installation of support system required Bootloader Customizing bootloader (U-BOOT) Compiling and downloading U-BOOT(U-BOOT) Kernel Customizing Kernel Compiling and downloading kernel Busy Box Customization of Busybox Compiling and making it as NFS / INITRD based file-system The study modules sound very trivial but these modules only will decide over the success of failure of the complete process. Very good study materials on the porting and other relevant topics are available on the internet. All the required packages included in the CD with this project report. The second main module is compiling and installing the prerequisites. The porting process will require a lot of other utilities, so before start with the actual porting one should be ready with all the prerequisites on one’s system. All the required packages are also included in the CD. The third main part of the process of porting is the U-BOOT customization and compilation. Normally the U-BOOT source is not needed to be customized barring one or two very trivial changes. Once the U-BOOT image is ready download it into the intended SOC. The detailed steps are explained in the further chapters. The last part of the process of porting is customization and compilation of the kernel. This is the most crucial part of the complete process. It needs to be very sure of which features of the kernel needed and which are not. The complete process of customizing and compiling the kernel and then downloading it is explained in detail in further chapters. 3.3 Prerequisites of Porting 1) TFTP server Get it enabled using YAST Administrative services on OPENSUSE 2) NFS server Get it enabled using YAST Administrative services on OPEN SUSE 3) Cross Development tool chain. 4) Minicom (or any other serial port communication utility) Get it from the Linux OS installation CD if not available. 5) U-BOOT loader source / image. Get a U-Boot Loader from http://sourceforge.net/projects/uboot/ 6) Linux Kernel Source + OMAP patch. Get Linux source from www.kernel.org and patch from www.muru.com/linux/omap 7) Busybox Source Get a Busy box from www.busybox.net This is all needed as the procedure for porting. In the coming section all the details of the steps are provided. CHAPTER 4 MINICOM MINICOM - Interfacing with OSK In order to communicate or operate the embedded OS, serial interface utility like a hyper terminal (in windows), or Minicom (in Linux) is needed. 4.1 Configuring Minicom 1. Normally Minicom comes as a standard package with linux distribution, if not get the package installed from Linux CD/DVD 2. Open terminal and type the below command for configuration # minicom –s 3. It will open the Minicom window with option window (if option window does not appear press Ctrl-A O) 4. In option window select ‘Modem and Dialing’ and ensure ‘Init String (A)’ is clear. 5. Now select ‘serial port setup’ and change ‘serial device’ to ‘/dev/ttyS0’ also change ‘Bps/par/bits’ to 115200 baud, 8Bps, no parity, 1 stop bit, and no flow control. 6. Save setup as def. 7. Exit. NOTE: Once the settings have been saved, from next time there is no need for the '-s' option simply type the below command to directly take you to Minicom window: # minicom Please ensure that line wrap is on for minicom (CTRL-A Z W) to get the commands to be proper, mostly useful when giving the liux kernel. Note: any time while accessing the device via minicom, if we find any unknown charecters, then try rebooting the OSK, in case if the problem is persistent then please try on any other system. CHAPTER 5 TFTP Server TFTP SERVER 5.1 Configuring TFTP server at HOST Step 1: Check the IP address is properly set using ifconfig command, if not, set it <HOST> #ifconfig Step 2: Goto YAST Administrative settings TFTP server Enable Finish If it is the first time it will popup to create a ‘tftpboot’ directory in root, click yes to finsh. Step 3: Do proper settings for TFTP client i.e OSK board Before this, configure the Minicom and OSK board has to be connected to HOST, These commands are to be executed at the boot-loader prompt of the OSK board Figure configuring the TFTP server using YAST Step 4: set the ip address of the board <MINICOM_U-BOOT>#setenv ipaddr xxx.xxx.xxx.xxx The ip address should be in the same class of host Step 5: set the server ip of the board <MINICOM_U-BOOT>#setenv serverip yyy.yyy.yyy.yyy This should be the same ip of the host Step 6: save the environment variables <MINICOM_U-BOOT>#saveenv CHAPTER 6 NFS SERVER NFS SERVER This project requires a root file system to boot initially, download a root file system which was built using Busybox in the /data/rootfs2.6. Make sure that the root file system is of same version as the linux kernel you are compiling. 6.1 Configuring NFS server at HOST Step 1: Create a directory ‘data/rootfs2.6’ in root Step 2: Goto YAST Administrative settings Network services NFS Server Start Figure 6.1: Configuring NFS server. Figure 6.2: Exporting the directories using NFS SERVER. The above shown is the second snapshot where one can set the mount point /data/rootfs2.6 which one want to share with the NFS clients. Here * shows that all hosts can use NFS and the respective permissions. Edit the parameters as follows, change ro(read only) to rw(read write) change root_squash to no_root_squash. Then click finish, then at terminal issue the below command to make your filesystem globally accessible across network <HOST>#exportfs In case NFS don’t work it might also be because of firewall settings so we have to explicitly disable firewall. To disable the firewall, use YAST administrator tool. 6.2 Few commands to start the NFS:<HOST># /sbin/service nfsserver restart Shutting down kernel based NFS server: nfsd done Starting kernel based NFS server: idmapd mountd statd nfsd sm-notify done <HOST># /sbin/service nfsserver stop Shutting down kernel based NFS server: nfsd statd mountd idmapd done <HOST># rpcinfo –p Shows all the network utilities running on the system. 6.3 NFS Configuration Files vi /etc/exports {path to export or share the location} vi /etc/hosts.allow {used to add the hosts which are allowed} vi /etc/hosts.deny {used to add the hosts which should be denied access} CHAPTER 7 BOOTLOADER BOOT LOADER Before starting the porting activities the following minimum activities to be done at Host system: Step 1: Create one Project directory in root, let us refer to this folder as PRJCT_SRC here onwards. Step 2: Create four directories for Linux_source, Tool_chain, Busy_box, U-boot (this is preferred directory structure, although it can be maintained as per one's convenience). Step 3: Now download the arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linuxgnu.tar.bz2 tool chain as tar file and copy to Tool chain directory, extract it using the following commands. Note: Assuming to be in PRJCT_SRC directory <HOST>#cd Tool_chain/ <HOST>#tar xjvf arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 Now add the path of this tool chain to PATH variable of linux shell by the command <HOST>#export PATH=$PATH:/root/PRJCT_SRC/Tool_chain/arm-2007q3/bin Step 4: Now download the u-boot v1.1.6 as tar file and copy to U-boot folder, Extract it using the following commands: Note: Assuming to be in PRJCT_SRC folder <HOST>#cd U-boot/ <HOST>#tar xjvf u-boot-1.1.6.tar.bz2 Now add the path of this boot loader to PATH variable of linux shell by the command <HOST>#export PATH=$PATH:/root/PRJCT_SRC/U-boot/u-boot-1.1.6/tools/ Now the basic environment in host for cross compilation is set, then we will proceed further for compilation of U-boot loader Step 1: Now clean the previously save configuration if any by passing ‘clean’ parameter to the make command. This is the rule defined in the Makefile of the bootloader which deletes all the previous configuration files and binaries available in current bootloader. <HOST>#make distclean Step 2: Now issue the commands for setting the default configurations of OMAP5912OSK board <HOST># make omap5912osk_config Step 3: Finally start the compilation process by issuing the command <HOST># make After these steps are successful an image of u-boot.bin will be created, now it has to be burned on to OSK as explained here. These following commands are to be issued after ensuring the TFTP server is properly configured and running. Step 4: copy the image file of bootloader to TFTP directory <HOST>#cp u-boot.bin /tftpboot Step 5: Transferring the image file from TFTP server to board <MINICOM_U-BOOT>#tftpboot 0x10000000 u-boot.bin When the download is completed it will report the size of the file in hexadecimal: note this number! Then we need to remove the old U-boot and put the new one on the top: Step 6: By default the memory location of flash is write protected, so first make this area read/writed <MINICOM_U-BOOT>#protect off 1:0 Step 7: Then erase the flash memory < MINICOM_U-BOOT>#erase 0x00000000 0x00020000 Step 8: Then burn the image file which was loaded into RAM to flash memory < MINICOM_U-BOOT>#cp.b 0x10000000 0x00000000 xxxx Where xxxx is the hexadecimal number that noted earlier, now reboot OSK and the new Uboot should load. Warning: One should be very careful which erasing the flash and burning of boot-loader, as some mistake can corrupt the boot-loader and the board can become un-usable. CHAPTER 8 ROOT FILE SYSTEM ROOT FILESYSTEM Now proceed with building the file system depending upon the requirement of the project. There is one minimal file system for OMAP board which is readily available in the internet, but, this file system has very minimal number of utilities, doesn’t have much kernel thread, doesn’t support PROC, SYS, and TMPFS file systems. As this project demands all the above said requirements it is better to choose the path of using BUSYBOX to build the required file system. Before proceeding with the Build process, have a knowledge of problems we faced working with various root file systems, and this also will justify why we have chosen the approach of building root filesystem directly from Busybox. We have faced problem of init not getting called during kernel boot up, To confirm whether this is problem of rootfs or kernel, just write a simple hello world program and pass this as init to kernel in boot args by adding ‘init=<PATH of hello world program>. When you reboot if you find hello world printed at your terminal then it is clearly the problem with init of rootfs. Finally we found that the kernel we compiled s not EABI enabled but the file system we are working with is EABI compatible. Then we enabled the EABI compatibility option in linux kernel and compiled it again. Non availability of mdev in the rootfs., mdev/udev is an user daemon which runs in background and takes appropriate actions if any notifications comes to user-space. Mdev is specially developed for embedded system applications. In our project recognition of USB devices , creating of device entries in proc and sysfs filesystems are necessary. These activities will be taken care by mdev daemon. We have initially worked with various file systems and found some kind of problems like non-availability of libraries,mdev not supported,proc or sysfs not supported etc.., we need to keep all the requirements before compiling and building a roofs from Busybox. This configuration process of BUSYBOX is very similar to kernel compilation, Step 1: Download the tar file of Busybox V1.17 BUSY_BOX directory Step 2: Enter to that busy box directory <HOST>#cd BUSY_BOX Step 3: un-tar it using the following command from the internet and copy it to <HOST>#tar xjvf busybox-1.17.1-tar.bz2 Step 4: enter to the busy box directory <HOST>#cd busybox-1.17.1 Step 5: configure the busy box as per the requirement, in most cases the default configuration is enough,but we need to enable certain features like Enabling static libraries: compile the busybox first with the static libraries and then we can go to using dynamic libraries. Enable mdev <HOST>#make menuconfig Step 6: Compile this Busy box by issuing the following command <HOST>#make <HOST>#make install Step 7: Do the following finishing touches to create nodes as per our requirement. <HOST>#cd ROOTFS <HOST>#mkdir dev <HOST>#cd dev <HOST>#mknod console c 5 1 <HOST>#mknod null c 3 1 <HOST>#cd .. Step 8:Create the directories we need in the ROOTFS <HOST>#mkdir temp proc sys root etc Step 9: we need to populate startup scripts in the init.d from any other file system, emx_dev_root_fs The files to be copied are /etc/fstab, /etc/inittab, /etc/init.d/rcS Now the file system to ready for the project,this file system can be used as either NFS or initrd based file system. NFS based File System For NFS based file system, it needs to simply copy the generated root File system to /data directory which were exported earlier by NFS server. To use this it need to setup the bootargs of kernel, which was explained in the Porting of kernel chapter INITRD based File System Using NFS based file system is very convenient when the project is in development stage and we frequently require to modify some thing in the file system, but when your project has done most of the development and want to develop the board less independent of HOST, we need to follow the following steps. To use this file system as INITRD, first it needs to generate an image of this root file system based on ext2, it need to use a tool called 'genext2fs' Step 1: Download the source code from the ------------------Step 2: un-tar it using the following command <HOST>#tar xjvf genext2fs1.4.1 Step 3: Enter into the directory <HOST>#cd genext2fs1.4.1/ Step 4: Open and follow the steps in the INSTALL file Step 5: Build this tool <HOST>#./autogen.sh <HOST>#./configure <HOST>#make <HOST>#make install Step 6:Now you can use this tool to generate an image of the root filesysem Step 7:Assuming you are in Busy_box directory, issue the following command <HOST>#genext2fs -b 8192 -d ROOTFS/ -e 0 initrd.img Step 8: when this step is successfull we need to copy the image to tftpboot for loading into board This can be loaded into RAM or can be burn into flash permanently, We suggest using the initrd file system from RAM during development stage, or every time any change is made we need to burn into flash which is waste of time and efforts. when once the proper setup is ready we can finally burn the filesystem into flash.but only drawback with RAM based file system is that we need to load the image from HOST every time you re-boot. Now first we explain the INITRD filesystem from RAM. <MINICOM_U-BOOT>#tftp 0x10400000 initrd.img <MINICOM_U-BOOT>#setenv bootargs console=ttyS0,115200n8 root=/dev/ram0 rw initrd=0x10400000 mem=32M <MINICOM_U-BOOT>#saveenv The same way the procedure for setting the Initrd based filesystem permanently into flash is explained in chapter 10. CHAPTER 9 LINUX KERNEL FOR OMAP5912 OSK Linux Kernel for OMAP5912 OSK Building the Linux kernel for OMAP5912 processor is little different than building it for general purpose computers. It needs to configure the Kernel according to the requirements. This depends on what features it requires and which modules it need to include in the Linux Kernel. Following are the steps to build the bootable Kernel which can be used by the OMAP5912 processor. The latest kernel can be obtained from http://www.kernel.org/ and the necessary patch to use this kernel on an OMAP system can be found at http://www.-muru.com/linux/omap/ 9.1 Compilation of Linux Kernel:Once these files are obtained, we can compile the Linux kernel following the steps below: The steps given below are for building the linux kernel to work as Device mode. Step1: Change the current directory to the directory where one want the source of the kernel. <HOST>#cd Linux_Source/ Step2: Un-pack the source of the kernel here. <HOST>#tar xjvf linux-2.6.27.tar.bz2 Step4: Un-zip the patch file by following command <HOST>#bunzip2 patch-2.6.27-omap1.bz2 Step5: Now change directory to the kernel source directory <HOST>#cd linux-2.6.27/ Step6: Apply the OMAP5912 patch to the kernel. <HOST>#cat ../patch-2.6.27-omap1 | patch -p1 Now the linux is customised to omap5912osk with default configuration, now you should again customise to suit for project requirement <HOST>#cp arch/arm/configs/omap_osk_5912_defconfig .config Step9: Now clean the previously save configuration if any by passing ‘clean’ parameter to the make command. This is the rule defined in the Makefile of the kernel which deletes all the previous configuration files available in current Kernel. #make clean Step10: Apply default configuration on the kernel for OMAP5912 which has been obtained with the kernel source in file ‘omap_osk_5912_config’. <HOST>#cp arch/arm/configs/omap_osk_5912_defconfig .config <HOST>#make ARCH=arm oldconfig Step11: Now we can change the default configuration according to our needs by <HOST>#make ARCH=arm menuconfig This command will open a configuration window, through which we can change the Kernel configuration according to our needs. In this window we need to change following settings 1. Enable as static (*), kernel features-->Use the ARM EABI to compile the kernel sub-option: Also enable , allow old binaries to be run with this kernel. 2. Enable loadable module support -->Module unloading,Automatic kernel module loading 3. Enable Device drivers-->USB support-->USB Gadget support-->support for USB Gadgets sub options:USB Peripheral file system-->OMAP USB Device controller enable, Filebacked USB storage gadget-->File backed USB storage gadget testing version 4. Enable Device drivers-->Memory Technology Device support --> Enable MTD partitioning support -->command line partition table parsing Leave all others configurations as default and do save and exit from menuconfig. Now to double verify open the .config file and ensure all the parameters above configured are set, and also ensure the parameters CONFIG_SYSFS=y CONFIG_PROCFS=y CONFIG_TMPFS=y Step12: Now we have configured the Kernel according to our need and we can now compile it. To compile the Kernel use the make command with ‘ARCH=arm’ parameter. Here we again explicitly tells the compiler that we want the compiled Kernel for ARM architecture by specifying it as ‘ARCH=arm’. This is optional we can also compile without using this argument. <HOST>#make CROSS_COMPILE=arm-none-linux-gnueabiAfter make operation we will have vmlinux in our Kernel source tree. File vmlinux is stand alone, monolithic Kernel image but it is not in a suitable format for U-Boot to upload. To convert the file, the mkimage utility must be used which comes with UBoot. Common Errors command-not-found: check for the proper setup of PATH variable No-rule to make target: check in which directly you are currently in, this compilation process should be done from Linux source directory. Ignore if found any warnings. If everything is fine the compilation process will be completed and image file will be generated Step13: To make the kernel image suitable for U-Boot, first of all create a new binary from vmlinux which we will use to change into the suitable format for u-boot. For all this we need to apply the following operations <HOST># arm-linux-objcopy -O binary -R .note -R .comment -S arch/arm/boot/compressed/vmlinux linux.bin Step14: This linux.bin is needs to be compressed before sending to the board. To compress this image use gzip utility <HOST># gzip -9 linux.bin Step15: Now we have compressed image of Linux kernel which is ready to be changed into required format which u-boot can use to boot the kernel. The format of kernel image can be changed by the following operation <HOST>#${U-BOOTDIR}/tools/mkimage -A arm -O linux -T kernel -C gzip-a 0x10c08000 -e 0x10c08000 -n ’Linux Kernel Image’ -d linux.-bin.gz uImage-2.6.27.cc After this we will have a file ‘uImage-2.6.27.cc’ which can be upload to the OMAP5912 board. 10.2 Upload Linux Kernel to the OSK To upload the binary image of the Linux kernel we need to follow the following steps. Step1: Power up the OMAP5912 kit. When we power up the kit it start the bootloader which apply the initial setting to boot-up the board. Step2: Press any key to stop booting the kernel when prompted. Step 3: Now copy the kernel image in ‘tftpboot’ directory to upload it <HOST># cp <U-Boot Directory> uImage-2.627.cc /tftpboot/ Step 4: Send the Linux kernel image, uImage-2.6.27.cc, to the RAM in OSK <MINICOM_U-BOOT>#tftpboot 0x10000000 uImage-2.6.27.cc Step 5: This command will upload the kernel image to the board and also will show the size of our kernel image file, note down this size. The size value will be used to move the binary image to the flash. Step 6: Now un-protect the memory area of the previously loaded kernel, so that we can remove that. <MINICOM_U-BOOT>##protect off 1:8-22 Here 1 is for the memory bank and 8-22 for the sectors from 8 to 22 in that bank. Step 7: Erase the kernel by the following command. <MINICOM_U-BOOT>##erase 1:8-22 Step 8: Move our new Linux kernel image to flash. <MINICOM_U-BOOT>##cp.b 0x10000000 0x100000 <size of kernel image(in hex)> Now if we restart the OMAP5912 kit, it will boot the kit with our Linux kernel! CHAPTER 10 IMPLEMENTING GADGET DRIVER IMPLEMENTING THE GADGET DRIVER In this chapter we will explain about the process of loading the gadget driver and making the device work as USB storage device to host side and finally burning all the required images into flash and making it an standalone system. Implementing the USB Gadget Driver: First and foremost we need to create one additional partition in the flash memory, for this we need to edit the board-initialization file <Kernel source>arch/arm/mach-omap1/board-osk.c In this file we need to edit the partition table, the modified code is mentioned below: static struct mtd_partition osk_partitions[] = { /* bootloader (U-Boot, etc) in first sector */ { .name = "bootloader", .offset = 0, .size = SZ_128K, .mask_flags = MTD_WRITEABLE, /* force read-only */ }, /* bootloader params in the next sector */ { .name = "params", .offset = MTDPART_OFS_APPEND, .size = SZ_1M, .mask_flags = 0, }, { .name = "kernel", .offset = MTDPART_OFS_APPEND, .size = SZ_16M, .mask_flags = 0 }, { .name = "filesystem", .offset = MTDPART_OFS_APPEND, .size = SZ_8M, .mask_flags = 0 }, { .name = "USB_PARTITION", .offset = MTDPART_OFS_APPEND, .size = MTDPART_SIZ_FULL, .mask_flags = 0 } }; The modified file is also attached in the CD submitted with the project report. Take this as reference to do same kind of changes suitable for any related project. Now the gadget driver which we are implementing is available at <Kernel source>/drivers/usb/gadget/file_storage.c, This gadget driver provides the functionality of USB Mass storage device using any file or block device as backing storage. The below mentioned procedure is done to implement this gadget driver. When we compile the linux source code a kernel module named g_file_storage.ko is generated. This is the module we are going to use as our gadget driver. Now we need to transfer this module to /lib/modules/2.6.27.57-omap1/ directory, this can be done by using methods like tftp or nfs or directly building into file system. Now we need to load the module with appropriate parameters <MINICOM_LINUX>#modprobe g_file_storage file=/dev/mtdblock4 ro=0 transport=CB Note: The above given parameters works fine, but one could try all combinations to understand the working of this gadget driver. If the module is successfully loaded you can get success messages in dmesg and also verify this module using lsmod. Now using the USB Type A to Type A cable connect the board to PC, then first check the dmesg of HOST for USB device configuration., and then the device will appear in /dev/ directory. The problem we faced is that the device is being detected as write protect on: device.So, we cant do any kind of operation like partioning,file system etc on this device. So,We need to do some modification in the original file as follows: Open the file goto function ‘open_backing_file’ and comment this code //if (inode && S_ISBLK(inode->i_mode)) { //if (bdev_read_only(inode->i_bdev)) // ro = 1; // } Then compile this module again and copy it to /lib/modules/2.6.27.57-omap1/ directory of board. Now follow the same steps described above to load the module, this time the host detects the device with write protect off: so we can do any operations on the device. Try some of the commands as below: Assuming the device is detected as /dev/sdb <HOST>#fdisk /dev/sdb <HOST>#m (for help) <HOST>#n (for partition)—follow the default options <HOST>#w (for saving partition table) Now the partition table is written to flash and its time to create a file system. <HOST>#mke2fs /dev/sdb1 If this is successful we can mount this device to any directory <HOST>#mount /dev/sdb1 /media/OMAP/ <HOST>#cd /media/OMAP From here we can do any operation like copying, deleting,open,close etc.., on any files similar to any other storage device. Procedure to make the board work standalone: First we need to burn the kernel and initrd filesystem onto flash at specified address, Assuming the bootargs are set like this: Bootargs console=ttyS0,115200n8 mem=32M root=/dev/mtdblock4 rw initrd=0x01000000, U-boot loader loads the kernel from the flash address 0x100000 , and kernel tries to access the rootfs from flash address 0x01000000. But kernel is unable to access the file system from flash directly., To overcome this problem we have implemented the procedure of copying the file system from flash to RAM using boot-loader script Edit the boot parameters as follows for implementation <MINICOM_U-BOOT>#setenv bootcmd ‘cp.b 0x01000000 0x10400000 800000; bootm 0x100000’ <MINICOM_U-BOOT>#setenv bootargs console=ttyS0,115200n8 mem=32M root=/dev/ram0 rw initrd=0x10400000. Now we also need to edit the /etc/init.d/rcS file to add script to automatically load the module whenever the kernel boots Add the following lines of code to the init file mentioned above modprobe g_file_storage file=/dev/mtdblock4 ro=0 transport=CB status $? 0 Having done all the above steps successfully , now the board can work standalone with out any intervention from us, you can connect to any host and the device will be detected as an USB mass storage device. CHAPTER 11 CONCLUSION CONCLUSION The project covers whole life cycle of the Universal Serial BUS (USB) and gave the host and device side perspective of the technology. Milestones of the project 1. Porting: Gadget Driver was implemented on Embedded Linux platform which involved porting to the target hardware (OMAP 5912 OSK)using GNU tool chain. 2. Gadget Driver Development: This phase involved implementing the standard file backed storage Gadget driver available in linux kernel which handled request right from introducing gadget and its capabilities to host to exporting mass storage functionality. Experience: It was a team work that led to the successful completion of the project. We got hands on experience in interacting with USB subsystem Gadget APIs on the device side and porting the OS. Improvements to be done: We were able to achieve the required functionality from the board by exporting the mass storage functionality and also we were able to do standard operations as on USB storage class device. The operations possible or formatting, partitioning, making file systems, data storage, standard read/write operations etc., but what we found is that the file system is being corrupted when we power off the board completely and reboot it. There should be some kind of BUG/ some setting to be done in the file backed storage gadget driver which to be customised. Suggestions to tackle this problem: Check in the higher versions of linux and test with that driver compare any modifications done in the code study the code and identify which part of code is stopping to properly burn in the flash Going one step ahead we need to implement wear levelling feature for this driver, as we know flash memory has limited number of read/writes so we need this feature to balance the read/writes to physical memory. We need to study about the UBI sub-system available in the linux source and how can it be implemented for our driver. Implementing this UBI wearlevelling feature is import to make this driver work completely as stand alone system. CHAPTER 12 REFERENCES REFERENCES BOOKS Linux Device Drivers : Jonathan Corbet, Alessandro Rubini, & Greg Kroah-Hartman Linux Kernel Development : Robert Love Building Embedded Linux System 2nd edition - Karim Yaghmour Embedded Linux system design and development-P.Raghavan Embedded Linux Primer -Christopher Hallinan USB Design by example-John Hyde USB system architecture 2.0 Kernel Source Documentation OSK 5912 Newbie Guide - Matthew Percival USB System Architecture (USB 2.0): Don Anderson USB complete: Jan Axelson URLs http://www.denx.de for U-BOOT http://www.tldp.org for Linux Documentation http://www.-muru.com/linux/omap/ http://sourceforge.net/projects/uboot/ http://freeelectrons.com/docs/ http://linux.omap.com for OMAP related Documentation http://tali.admingilde.org/linux-docbook/gadget/index.html