Adding new driver code to linux source code - linux-kernel

I have developed a Linux device driver. As of now I am compiling it on Ubuntu 12.04 with cross-compiler for arm and then insmoding it in my arm Linux image. But I want to learn how I can add it in Linux source code and give and option to add/remove through configuration of arm Linux, so that I can compile it with Linux source code compilation?
Any ideas?

To cross compile your own driver in the arm architecture you have to follow some steps as mentioned below.
Create a directory like my_drvr inside drivers(which is in the Linux source code) for your driver and put your driver (my_driver.c) file inside this directory. It will looks like
/linux_source_code/drivers/my_drvr/my_driver.c
Create one Makefile inside your driver directory (using vi any editor) and inside this put obj-$(CONFIG_MY_DRIVER) += my_driver.o
and save this file. This will appears like /linux_source_code/drivers/my_drvr/Makefile
Create one Kconfig file inside your driver directory (using vi any editor) and inside this put
config MY_DRIVER
tristate "my driver" //gives your driver description like vendor name etc.
depends on ARM
default y if ARM
help
my driver module.
Save this file, this will appears like /linux_source_code/drivers/my_drvr/Kconfig
Add both Makefile and Kconfig file in the Linux source drivers Makefile and Kconfig file which are at /linux_source_code/drivers/Makefile
and /linux_source_code/drivers/Kconfig
In the Makefile add below in last line
obj-y += my_drvr/
or
obj-$(CONFIG_MY_DRIVER) += my_drvr/
In Kconfig file add below in last line
source "drivers/my_drvr/Kconfig"
Finally have to add Kconfig file into architecture specific config file which will be at kernel_source/arch/arm/configs/--defconfig in this add below line in the last
CONFIG_MY_DRIVER=y
Note:- Last step will differ according to your architecture, so that you have take care.
Now you can compile your driver by using make command.
(eg: sun7i_defconfig)

You need to add a config option in the Kconfig file of the kernel source subdirectory in which your device driver will be put. You also need to add lines to the Makefile of that directory. Obviously you need to copy the source files to that directory too.
Since your driver depends on the ARM architecture, in the Kconfig, you need to put an option of 'depends on' like:
config SND_ARMAACI
tristate "ARM PrimeCell PL041 AC Link support"
depends on ARM_AMBA
and your Makefile will look like
obj-$(CONFIG_SND_ARMAACI) += snd-aaci.o
snd-aaci-objs := aaci.o
So now when you do a make menuconfig in your kernel source tree, you will find the config option you put in the Kconfig and you will be able to select it to be compiled into the kernel or built as a module or not compiled at all.
Look for examples in the subsystem directory your driver is meant for.

Create patch and add applying of this patch as a step after decompressing kernel tarball and before configuring/compilation.

Related

Linux-Kernel-Modules : Built-in module working with the old modules.dep file in the file-system

I have built a modules as built-in and correspondingly modified the 'dtb' file to make the hrdware discoverable to the kernel. The process which is being followed is as,
Modified kernel configuration for 'xyz' driver to built the same as built-in module
Correspondingly modified the dtb file
In the target device placed the new 'uImage' and 'dtb' file through scp command
Here the file i.e. 'modules.dep' is not replaced and it's old
Question: Is modules.dep file required to be updated for built-in module to work and appear on '/sys/class/drm/' folder

Adding and compiling new code in the linux kernel

This may sound like a very noob question.
I'm trying to implement a UDP-based protocol in the linux kernel. I was following the UDPLite protocol implementation as a reference.
Step 1
I created a new_protocol.c in net/ipv4/
This file has a function
void _init protocol_init(void){*Code here*}
I also used
#include "udp_impl.h"
in this file as I was using some functions from the UDP protocol
Step 2
I modified the file net/ipv4/udp_impl.h to include net/new_protocol.h
Step 3
I created the file include/net/new_protocol.h where I defined the function
void protocol_init(void);
Step 4
Finally, I called the function in net/ipv4/af_inet.c. Also, I gave an include statement in this file for net/new_protocol.h
Now when I try to build the kernel, I get an error saying
undefined reference to `protocol_init()'
What am I missing here? Is my way of including header files incorrect? Do I need to include some info in the makefile to pick up the new net/ipv4/protocol.c?
Do I need to include some info in the makefile to pick up the new net/ipv4/protocol.c?
Yes, you need. Kernel build system doesn't autodetect source files, all of them should be listed explicitely in appropriate Makefile. In you case you need to modify net/ipv4/Makefile.
Makefiles used for kernel build are described in file Documentation/kbuild/makefiles.txt.
I just needed to add protocol.o in the makefile in net/ipv4/

How do I generate loadable modules during Linux kernel build?

I seem to successfully build a kernel image, but I can not generate all the modules I expect. I expect more modules since I see them enabled in the gconfig window. Here is a copy of my make session. Seems like make goes into the devices directories. I can not figure out why it is not create the .ko files. I expect to see .ko files. I have checked the Makefile in /drivers directory, and I can see that it is configured with a number of lines like
obj-$(CONFIG_PCI) += pci/
Which directs make to build the pci module for instance. I think this implies that I should see a number .ko files. But I do not. I have seen just one .ko file for scsi module. I like to be able to build all of modules selected.
I also verified that a number of mudules are enabled when I issued:
make VARIANT_DEFCONFIG=msm8974_sec_hlte_spr_defconfig msm8974_sec_defconfig SELINUX_DEFCONFIG=selinux_defconfig gconfig
But as I said, I do not see any of them. What am I missing please?
#Subin - Thanks. I just tried make modules_install. I have to mention that I am cross compiling this for an arm target. I believe modules_install is for the purpose of installing the driver for the machine you are on? I got a message about needing to be in root, and I did not proceed. I have been wondering when I need to run it. What does it do exactly please?
Re: the make modules; I have run it before. I'll run it again and post the result. Since I got one .ko file I figured the issue is something different between that one module, and every other one enabled in my config. Here is what I got when I ran make modules:
sansari#ubuntu:~/WORKING_DIRECTORY$ make modules
CHK include/linux/version.h
CHK include/generated/utsrelease.h
make[1]: `include/generated/mach-types.h' is up to date.
CALL scripts/checksyscalls.sh
Building modules, stage 2.
MODPOST 1 modules
Re: your comment on the location of .ko files, I am doing a find to see if perhaps I am not looking at the right place, it only finds the one which was built. Not the other ones. Here is the output:
sansari#ubuntu:~/WORKING_DIRECTORY$ find . -type f -name "*.ko"
./drivers/scsi/scsi_wait_scan.ko
sansari#ubuntu:~/WORKING_DIRECTORY$
Should I perhaps run make v=1, in verbose mode that is? Would that provide more information on why the other modules are not built?
#Gil Hamilton - Thanks. You are right. Here is an excerpt of the .config file:
#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
CONFIG_CHR_DEV_SG=y
CONFIG_CHR_DEV_SCH=y
CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_SCSI_WAIT_SCAN=m
This entry is the only one set to 'm'.
Most device driver modules in the linux kernel build system use a tristate (3-valued) configuration setting. The options are
'n' (don't build at all),
'y' (build and link statically into the main kernel object), and
'm' (build as module for dynamic loading).
The values are determined by the content of .config. The values in .config are usually generated from an existing config file (look in arch/<ARCH>/configs for your <ARCH>). Also check the output of 'make help' for interesting configuration targets.
If you're not seeing the .ko files being created, that indicates the corresponding configuration variable is either set to 'y' or 'n'.

Need help in enable configuration when compile Kernel module

I am using 3.10.x kernel tree. My kernel module needs config VIDEOBUF2.
That is defined in drivers/media/v4l2-core/Kconfig:
# Used by drivers that need Videobuf2 modules
config VIDEOBUF2_CORE
select DMA_SHARED_BUFFER
tristate
So I put 'CONFIG_VIDEOBUF2_CORE=y' in my Kernel config file and
compile. From the Kconfig it has CONFIG_VIDEOBUF2_CORE has no
dependency and I think adding CONFIG_VIDEOBUF2_CORE=y to my kernel
config should work. I am modify the right kernel config file since I
set other flags like CONFIG_VIDEO_DEV=y and that works.
The generated .config does not contain 'CONFIG_VIDEOBUF2_CORE=y'
and the compilation fails with a bunch of
undefined reference to `vb2_buffer_done'
undefined reference to `vb2_buffer_done'
undefined reference to `vb2_buffer_done'
undefined reference to `vb2_buffer_done'
I really appreciate if someone can help me with this.
Thank you.
I cant directly comment on the subject as it requires 50 reputations to have this privilege. You can do : make ARCH = target_architecture CROSS_COMPILE = toolchain defconfig_file. This command execution will create a .config file in home directory of your kernel source. This file would contain default configuration for the peripherals on your target SOC ( I assume you have knowledge pertaining to defconfig files). Now if you wish to manipulate it and want to add your device support to it do : make menuconfig and you could add your device support by selecting configuration say like VIDEOBUF2_CORE in your case and then your kernel soure is ready to be compiled/cross-compiled. PS: Avoid editing .config file manually.

How to "make" existing Linux kernel module driver after modifying the driver source code

I have made some trivial modifications to a Linux USB Wi-Fi card driver to insert some logging (printk statements). I am loosely following a guide on how to recompile/load the module, which states that I need to execute make in order to build the .ko file. There is an existing Makefile in the working directory (/usr/src/linux/drivers/net/wireless/rtl818x/rtl8187/), which reads:
rtl8187-objs := dev.o rtl8225.o leds.o rfkill.o
obj-$(CONFIG_RTL8187) += rtl8187.o
ccflags-y += -Idrivers/net/wireless/rtl818x
When I execute make inside this directory, I get:
make: *** No targets. Stop.
According to this, this means "that some makefile was found, but it didn't contain any default goal and none was given on the command line. GNU make has nothing to do in these situations."
So my question is, what does this mean in the context of what I am trying to do, and how do I go about generating the .ko file which I am purported to need for the next step?
You must run make from the top directory of the Linux source (/usr/src/linux/). Be sure that your driver is included in your /usr/src/linux/.config file. So, build the kernel with your driver.
If you don't want to rebuild the entire kernel, read more :)
If you want to re-build all modules inside the directory:
make M=drivers/net/wireless/rtl818x/rtl8187/
If you want to re-build a single module inside the directory:
make M=drivers/net/wireless/rtl818x/ CONFIG_RTL8187=m
The *CONFIG_RTL8187* name can be found in drivers/net/wireless/rtl818x/Kconfig (CONFIG_ + RTL8187)
It should works also this:
make drivers/net/wireless/rtl818x/rtl8187/rtl8187.ko

Resources