Saturday, 1 August 2015

Linux Device Drivers - Part 13 : More on Device Numbers


In this session, we are going to discuss following topics
    1. Allocating and freeing Device Numbers
    2. Best way to allocate Device Numbers
    3. Disadvantage of dynamic assignment of device numbers
    4. Allocating device numbers to scull device driver

Source code of Linux Device Driver examples of O'reilly can be downloaded from below link

http://examples.oreilly.com/linuxdrive3/

Watch video here:

0 comments

Linux Device Drivers Part - 12 : Major and Minor Numbers in Linux Device Driver Programming

In this session we will discuss following topics

1. Books to refer for Linux Device Driver Programming
2. Our mail Goal to achieve in up coming sessions
3. Steps to follow while Linux Device Driver Programming
Under this particular topic we will learn about
  •      Gathering information about a Linux Device Driver
  •      Gathering information of SCULL Device Driver
  •      Identifying and defining Major and Minor Number 
  •      Representation of Device numbers

You can download a softcopy of LDD http://www.oreilly.com/openbook/linuxdrive3/book/

Watch video here :
0 comments

Thursday, 2 July 2015

Linux Device Drivers Part 11: Device Driver Types

In this video session, we will discuss about
1. /dev directory Device Driver types (Character Devices, Block devices and Network Devices)
Practical session included at the end.
Please subscribe for more videos.


0 comments

Linux Device Drivers Part 10: Module Parameters

In this video session we will discuss following topics

1.What are Module parameters ?
2.Ways to change these module parameters?
3.Module_param macro
4.Array Module parameters

0 comments

Monday, 15 June 2015

Linux Device Drivers Part 9 - More about Symbol tables

In this part we will discuss about following topics
  • About undefined symbol error and steps to solve it
  • Is it mandatory to export the symbols ?
  • Location of symbol table
  • About system.map file in Linux

1. About undefined symbol error and steps to solve it
The most common and most frustrating failure in loading an LKM is unresolved symbol, like this:
 insmod: error inserting 'helloworld.ko': -1 Unknown symbol in module  
To debug this error,
1. Use nm utility
2. Know symbol definitions (in next slide)

Lets say my module is helloworld.ko
In order to display symbol table, we use following command.
 $nm helloworld.ko.  

Output of this command is
 00000000 r ____versions  
 0000002c r __mod_author22  
 00000000 r __mod_description24  
 00000020 r __mod_license23  
 00000040 r __mod_srcversion30  
 00000080 r __mod_vermagic5  
 00000063 r __module_depends  
 00000000 D __this_module  
 00000000 r _rheldata  
 00000000 T cleanup_module  
 00000000 B g_value  
 00000000 t hello_exit  
 00000000 t hello_init  
 00000000 T init_module  
      U printk  

In this list, try to find the Undefined symbol tag / Unknown symbol tag (in second column of symbol table).

Once Symbol table is handy, we need to know about  symbol types.

Some of these types are: 
A for absolute
B or b for uninitialized data section (called BSS)
D or d for initialized data section
G or g for initialized data section for small objects (global)
i for sections specific to DLLs
N for debugging symbol
p for stack unwind section
R or r for read only data section
S or s for uninitialized data section for small objects
T or t for text (code) section
U for undefined
V or v for weak object
W or w for weak objects which have not been tagged so
- for stabs symbol in an a.out object file

2. Is it mandatory to export the symbols ?
Now with symbol table and symbol types in hand,  we need to check which symbol type is relevant to our error. From above symbol types, "U for undefined" is relevant "Unknown symbol in module".

So, the symbols which are having U in the symbol table (second column) displayed are g_value and printk. printk will be resolved by Kernel while loading the module because relevant header files are included. So, we need to concentrate on g_value and why its displayed.

In order to resolve this, you need to either export this in any other module where the definition exists or you need to make this local to this module.

To know answer for this question, you can think of kernel symbols as being visible at three different levels in the Kernel source code:

"static", -  visible only within their own source file (just like standard user space programming),
"external" - potentially visible to any other code built into the kernel itself, and
"exported -  visible and available to any loadable module

From above statement it’s obvious that if you are writing a Linux Kernel Module, it’s mandatory to export your module symbols if you want other module to benefit using them.

3. Location of Symbol tables
The symbol exported by the statically Linked kernel and all linked-in modules can be retrieved by reading the /proc/kallsyms file or  using the query_modue() system call.

Take a look at /proc/kallsyms entry by typing following command in your terminal.
 cat /proc/kallsyms  

Every entry in this file represents an exported (public) kernel symbol, which can be accessed by a Linux Kernel Module.

If you would like to get symbol table of a particular module or kernel object, you can use “nm” command
 $nm KernelModule.ko.  

4.About System.map file in Linux
Every kernel image that you build has a symbol table with it . The linux kernel symbol table contains names and addresses of all the kernel symbols.

In Linux, the System.map file is a symbol table used by the kernel.

Because addresses may change from one build to the next, a new System.map is generated for each build of the kernel.

The System.map is required when the address of a symbol name, or the symbol name of an address, is needed. It is especially useful for debugging kernel panics and kernel oopses.

After building the Linux kernel, System.map is located in the root of the source directory.  Try typing “locate System.map” command in terminal.
 locate System.map  

These topics are also explained in detail with practical session in below video.
If you like it, please do subscribe and shed your comments.

0 comments

Sunday, 7 June 2015

Linux Device Drivers - Part 8 : Kernel Symbol Tables

In this session we learn about
1. A symbol in Linux
2. How it is exported ?
3. Symbol and Symbol Table relationship
4. Idea behind exporting a Symbol

1. A Symbol in Linux
In Linux, symbols are nothing but variables and functions that are needed to implement modularised drivers. Note that each and every symbol has its address in the memory.

To make our understanding clear, lets draw a small diagram which shows a Linux Kernel Module with symbols ( Variables and functions ) in it.
So in short, symbol is nothing but a variable or function in LKM

How Symbols are Exported ?
Exporting Kernel Symbols is typically done with 
  • EXPORT_SYMBOL()
  • EXPORT_SYMBOL_GPL()
EXPORT_SYMBOL(), which exports a given symbol to all loadable modules 

EXPORT_SYMBOL_GPL(), which exports a given symbol to only those modules that have a GPL-compatible license. (The first variation is far more common).

GPL here is General Public License is widely used for free software license.

EXPORT_SYMBOL_GPL functionality is same as EXPORT_SYMBOL, but it marks the exported symbol as usable only in modules licensed through either the General public License or a compatible one.

So, whenever you write a driver, it should be GPL licensed. That will be a great facility in case your module wants to use any other module’s functions that are already exported using GPL. 

3.Symbol and Symbol Table relation
Now we know about a symbol and how it is exported in Linux Kernel module. Lets learn about Kernel Symbol Table (also called Symbol Table in short).

Kernel symbol table is nothing but a look-up table between symbol names and their addresses in memory.

When a module is loaded into Kernel memory using insmod or modprobe utility, any symbol exported by the module becomes part of the Kernel symbol table. Exported symbols will become public Kernel symbols.

While insmoding, the insmod utility resolves undefined symbols against the table of public Kernel symbols. 

Kernel Symbol tables hold all the information needed to find program symbols, assign value to them, and relocate them.

Primary task of symbol is to associate a string with a value. For ex, printk symbol represents the address of the printk function in virtual address space where the function machine code resides.

This Kernel symbol table is loaded into memory as part of the Kernel boot process.

We will be learning more about Kernel Symbol Tables in coming Sessions.

4. Idea behind Exporting a Symbol
Whole idea of exporting a symbol is to make other modules benefit using them.
New modules can use symbols exported by your module, and you can stack new modules on top of other modules.  This concept is called Module stacking.
Module stacking is implemented in the mainstream kernel sources as well: like each input USB device module stacks on the usbcore and input modules.
Module loading order can be important, particularly if they are stacked (dependent on the symbols defined in other modules)
This mechanism help reduce development time by simplifying each layer

Check out video on this topi in my youtube channel. Don't forget to subscribe.

0 comments

Saturday, 6 June 2015

Linux Device Drivers Part -7 : Kernel Modules vs Applications

In this part, we are going to discus about ,

The difference between Kernel Modules (KM) and Applications (APs) in brief.

Before proceeding further, I strongly recommend to watch my earlier videos from "Linux Device Drivers Part -1 to Part 6".

Though there are many differences, to keep it simple and to explain in brief , I have hand picked few differences and listed them as topics form, which can be easily remembered and recollected when required

We compare below 6 topics between Kernel Modules (KM) and Applications (APs)

1. Initialisation
2. Which are Event Driven KM's or AP’s   
3. About Exit Procedure in  KM's or AP’s  
4. Ability to unload a module   
5. Linking stage   
6. Handling faults   

This tutorial covers only brief description of all topics listed. This will help us to understand upcoming sessions with ease

Lets start with our first topic,

1. Initialisation
When we invoke a application, it starts and proceed ahead till end .
Most small and medium sized application programs perform a single task from beginning to end. Take any application in your PC, they start and run till you end them

Whereas every Kernel module registers itself with Kernel in order to serve future requests, and its initialisation function terminates immediately.

In other words, the task of the module's initialisation function is to prepare for later invocation of the module's functions when required.

2. Which are Event Driven KMs or APs
To understand in simple way, say if something happens, an event is raised and that should be served. So, with our current understanding, do you think Kernel is event driven ?

Yes, when a Kernel module is loaded, it invokes init function (hello_init) which conveys Kernel “Here I am, and this is what I can do”.   Its conveying kernel, if some events occurs, just let me know i will serve

When  Kernel module is unloaded, it invokes exit (hello_exit) which conveys  Kernel “I am not there anymore; don’t ask me to do anything else”.

This kind of approach to programming is similar to event-driven programming, but while not all applications are event-driven, each and every Kernel module is even driven.

3. About Exit Procedure in  KM or AP’s
 I have mentioned earlier, not all applications are event-driven . Imagine we have event driven application

Major difference between event-driven applications and Kernel code is in the exit function.

When an application terminates, it can be lazy in releasing resources or avoids clean up altogether, the exit function of a module must carefully undo everything the init function built up, or the pieces remain around until the system is rebooted.

Sometimes , we end out of memory situations and system may totally crash. Note when application crashes, system can run without any issue, if kernel module crashes, it will kill the process or whole system needs to be rebooted

4. Ability to unload a module
Incidentally, the ability to unload a module is one of the features of modularisation that you'll most appreciate, because it helps cut down development time; you can test successive versions of your new driver without going through the lengthy shutdown/reboot cycle each time.

If you have driver programming experience, you will really appreciate this feature. It save lot of time and effort

With application, you need to either exit it completely and rerun the application. You will not be sure if the memory allocated is dealloated or the task initiated is exited cleanly. It all depends on how you implement the application.

5. Linking Stage
An application can call functions it doesn't define: the linking stage resolves external references using the appropriate library of functions.

printf is one of those callable functions and is defined in libc.

A module, on the other hand, is linked only to the Kernel, and the only functions it can call are the ones exported by the Kernel; there are no libraries to link to. This point is very important. Keep in mind that there are no libraries for kernel modules to link to

The printk function used in hello.c earlier, for example, is the version of printf defined within the kernel and exported to modules. It behaves similarly to the original function, with a few minor differences.

Because no library is linked to kernel modules, source files should never include the usual header files. There are special exceptions like <stdarg.h> .

Only functions that are actually part of the Kernel itself may be used in Kernel modules. Anything related to the Kernel is declared in headers found in the Kernel source tree had to be set up and configured.

Most of the relevant headers live in "include/linux" and "include/asm", but other sub directories of include have been added to host material associated to specific Kernel subsystems.

6. Handling Faults 
Another important difference between kernel programming and application programming is in how each environment handles faults.

As briefed earlier , Segmentation fault is harmless during application development and a debugger can always be used to trace the error to the problem in the source code, a kernel fault kills the current process at least, if not the whole system.  

Hey don't forget to check out youtube version of this article here. 

If you like, please dont forget to give a thumbsup :)
0 comments