Programming Kernel Modules

download Programming Kernel Modules

If you can't read please download the document

description

Kernel Module Programming

Transcript of Programming Kernel Modules

When we runmakeon command line only the first target (Label or Argument) is executed, remaining are not, to execute the other targets we have to usemakealong with label name. In the previous example we have three labelsall,installandclean. The label all will be automatically executed by make as it is the first target to execute the other targets we must initiate them usingmake Ex:-make install//to use the target installmake clean//to use the target cleanThe purpose ofinstallis to make an out-of-tree module an in-tree module. When we saymake installwhicheverout-of-treemodules.kosthat are created will be copied intolib/modules//build/extra.Make cleanwill removeall the intermediary files generated.i.e. it will remove .o and .ko files generated in the current directory.If we dont mention any thing and simply usemakethe default is always first one.The first target, irrespective of we give the label or not. Default execution always is defined.Programming Kernel Modules:-Modules are special object files which are used to dynamically extend kernel services.While implementing source code for a kernel module following issues are to be considered.None of the APIs of the user space are not used for module.Source should not contain calls to user mode functions (including APIs), standard C Library.Module sources must include kernel headers only./lib/modules//build/includeIt is good programming practice to include following kernel headers in every module.#include#include#include#includeLink-loaderis the shared object manager. It is responsible to bind, un-bind shared object with an application.Similar toLink Loaderkernel also has a sub-system calledKmod. Thismodule.hheader file is to interact with that sub-system. If at all the module wants to configure some of the attributes, it needs to interact with the Kmod. To interact withKmodthere are some MACROs and Functions, which are calledKmod interfaces. In case we want to use those MACROs and Functions then they must be verified for that we use module.h. Module.h contains interfaces for Kmod.Kmodinterfacecontains the signatures of the routines and MACROs through which we can talk to Kmod.Init.hcontains interfaces for initialization sequenceMACROs.Any binary file that loads must have aconstructoranddestructor.Module will have one function calledinit_module ()as a constructor,cleanup_module ()as a destructor. Initialization and exit routines.In shared object also we may implement them or not implement them, they are optional. If we dont implement default are provided which are empty files.These are always optional if we want we can over write them by default. Theinit_moduleroutine is run when the module is deployed. When it is about to get binded with the kernel process address space or kernel address space. Exit will run when the module is to be detached.Init_modulefunction will have a signatureint init_module(void);Thecleanup_modulewill have a signaturevoid cleanup_module(void);If we skip them empty functions will be added by default.Module source can contain initialization and Exit routines.#include#include#include#include

Initialization routine of a moduleintinit_module(void){printk("%s : Module inserted\n",__func__);return 0;}

Exit routine of a modulevoidcleanup_module(void){printk("%s : Module Detached\n",__func__);}We cannot useprintfas it is user library, alternative toprintfin kernel spaceisprintk.Init routine is executed when module is deployed (Loaded).Exit function is executed when the module is unloaded.Init function of the module is run in the context ofinsmod(Assuminginsmodis used to loadthe module).Insmoduses a kernel APIinit_modulewhich loads module image into kernel address spaceand executes init function of the module.Modules are unloaded usingdelete_modulesystem call.The purpose of comments is readability (we want to make it easy for anyone looking at our code.). Some comments will be describing our syntax. Some are not describing our syntax.There are basically two categories of commenting, one category is called code information commenting, code information means which project, which module, who is the owner of that module, modification lock, which license it is under, and so on. Rest of the comments which are used for code description are called code description modules.When the program is converted to binary file all the comments are removed.In case of open-source community we must find some way to add some essential comments to binary files, because the owners of the modules maydistribute the binary files to clients. From within the binary file they should be able to pull out some information about, who is the owner, which license, when was it written some information which license and all that. Here, we need at least the few comments to go into binary file. Those Macros we see below are a method of that. Those Macros are nothing but whichever comments we think the user should have access to, those comments we pass arguments to MACROs. Kmod will give usthose Macros, pass those Macros and retain those comments into binary file.This particular header file calledmodule.hof Kmod provides us a set of comment Macros. Using them is purely optional, using MODULE_LICENSE is mandatory for every module we write.We must declare at least one License.There are two category of licenses one category is called copyright, and the other is called copy left.Most of the closed copy of licenses are called copyrights. Proprietary licenses are copy rights. User only gets the binary file if user has any problem with the binary file, he has to go to the main author from where he has got. This is known as vendor locking.In the open source code the license is called a copy left. The user will have access to binary as well as source code. The reason why source is given is to complete the ownership part. The user now can goto anyone who understands the source for help,need not go to only that particular author. Free term in open source community means freedom to access of source.Module can be either copy left or copyright, if I specify proprietary the license will become copyright. Specifying Module license is mandatory, default is proprietary and Linux will throw a warning module license not specified.Modules can use appropriate commenting MACROs to retain essential code information and description into binary file.

Module.hprovides various macros for this.For Ex.:MODULE_AUTHOR();MODULE_DESCRIPTION();MODULE_LICENSE();Modules can be composed of various data and functions.Module is the means of loading something into kernel. Module itself is not a driver. A body of module can be a driver. Body of a module can be a file system. What we are trying to add to kernel is the body of a module. Module is the means of loading a service dynamically. The service is then referred to as body of a module. Its the carrier through which we are loading some pay load (Service). This part of the code will repeat in every module only body will change depending on what we are trying to do. Module is not a process its a carrier, it is a method to wrap some code and carry into kernel space. In the below example body is a func ().#include#include#include#include

voidfunc(void)Body of the module{printk("%s : Body of the Module\n",__func__);}

Initialization routine of a moduleintinit_module(void){printk("%s : Module inserted\n",__func__);return 0;}

Exit routine of a modulevoidcleanup_module(void){printk("%s : Module Detached\n",__func__);}

Normal, GCC creates a normal Relocatable, this is the reason why we use the build script, it creates a customized Relocatable,and ELFformat internally is modified to suite the module deployment. Though it shows relocatable it is not equivalent to .o file. Thats reason build script is mandatory.Enduser if he has a .ko he can retrieve those comments using a tool calledmodinfo.Modinfowill show all the details about the module. Modinfowe have to use on.kofile. It also gives us which kernel version this module was build for.This module can be used only on this kernel. Even if the release version is different we cant use this kernel. Module once build is specific to kernel. Modules are not portable.This is for testing purpose only.One of the methods to load a module is calledinsmod.Useinsmodand mention module name it will deploy the module into kerneladdress space.# insmodIf it is successful prompt will return.Otherwise,insmodfailsdeploying it, immediately, it will show us appropriate error code. This we must do as a root user,sudois mandatory for this. Only administrators can load a module.lsmodis a toolthat will show us list ofmodulesthatare currently loaded. If our module is loaded successfully it must be displayed in the list of modules currently shown bylsmod.First one is always the latest module deployed. The others are loaded by the kernel at the boot time. For testing we are dynamically loadingmodule.If we createan in-tree module and build a kernel it will get loaded automatically by the kernel at boot time.Same can be verified using cat/proc/modules. Bothlsmodand this are sameTheinitfunction is run when module is deployed. We can use the tool calleddmesgto print the messages that are in the kernel buffer.Initfunction has already executed if the message appears indmesgthats the confirmation.Kernel print statements will not be shown on console. We must use a tool to print that printks.dmesgis the tool to print this messages.Usedmesg Cto clear all the previous messages.The exit functioncleanup_moduleis run when we unload the module.In memory there is only image.We must use the toolrmmodto unload module from theLinux kernel.When we add a module it gets added to kernels code segment. When we say detach it will get removed from kernels code segment.We can usestraceto view all the system callstaken to run this file.Initmodule loads ELF into kernel space and runs the modules init function.Initfunction of the module will run inthe context ofinsmod.Init function until completedinsmodwill not come to user mode.Insmod is going into kernel mode, loading our module.insmodwill fail if we return -1 from init_module (). If we return 0 in init_module () then, insmod will commit the module and then return. It means init_module function after it is executed then it is committed, whether to commit the module or abort it. If init function is 0 module is committed to process address space. If init function return negativenumbermodule is aborted. Return value of insmod is nothing but return value of init_module().Why is it designed like this?May be we are trying to load a driver, before loading a driver we want to check if device is there. Where to write that code now? Init_module (). Init function we write a code to detect the device is present or not,if it is present we will commit, else we will abort. It will give us flexibility to do lot of conditional checking before we commit our resource.If we dont want init_module () and cleanup_module () names as function names we can change them as we wish but we must tell the kmod that this is myinit_module ()and this is mycleanup_module ()in the following manner:module_init(myinit);module_exit(myexit);