You are on page 1of 4

Static functions in Linux device driver?

Is there a reason why most function definition in device driver in linux code is defined
as static? Is there a reason for this?
I was told this is for scoping and to prevent namespace pollution, could anyone
explain it in detail why static definition is used in this context?
ANS:-Functions declared static are not visible outside the translation unit they are
defined in (a translation unit is basically a .c file). If a function does not need to be called
from outside the file, then it should be made static so as to not pollute the global
namespace. This makes conflicts between names that are the same are less likely to
happen. Exported symbols are usually indentified with some sort of subsystem tag,
which further reduces scope for conflict.
Often, pointers to these functions end up in structs, so they are actually called from
outside the file they are defined in, but not by their function name.

porting linux on bare board


Yesterday I faced with an interview. In interview he asked me for steps to porting Linux
on new board. My answer was,
1.
cross-compile u-boot for board architecture.
2.

cross-compile kernel, with selecting driver for peripherals connected to board.

3.
cross-compile filesystem, and port all on board.
But Interviewer is not happy with this answer.
ANS:Porting steps

Install a cross-development environment.

Setup the board and ensure that the serial port is working so we can print data
through the serial port.

Download and install the Linux kernel, most of the porting work will be done at
this level.

Add board specific code into the kernel tree.

Build a kernel image to run on the board

Test that early kernel printk is working

Get the real printk working with the serial console.

For a new board, a new board-specific directory should be added as well as


support for interrupt handling, kernel timer services and mapping for memory areas.

Ethernet drivers are usually the next drivers to focus on as they enable setup of
NFS root file system to get access to user utilities and applications.

Filesystem can be provided in different forms which are listed on LinuxFilesystem

How to port a linux driver , which is compiled in 2.6


kernel ,without compiling in other new version of kernel

Thanks to every one,


This is the question asked in one of the interview i faced.
I have a Linux device driver which was compiled in Linux kernel version 2.6.I would
like to port the same driver in a Linux PC which has kernel 3.X without compiling in
new versions.
Is it possible ? If it is possible please let me know how. If it is not possible please let
me know why not ?
now it's not possible:

usually, a "driver" is a binary kernel-module

porting will involve code-changes to the kernel module. if you change the code,
you need to compile it, in order to get a binary.

since kernel modules run in kernel space, it is crucial that they are robust. since
parts of the kernel-API change every now and then, trying to use a module compiled
for kernel-X with another kernel-Y, might either not load because of missing symbols
(if you are lucky) or lead to a kernel panic because semantics have changed.

btw, all this is not really related to 2.6.x vs 3.y, but holds true for any kernel
version

but then: of course in theory it is possible to "write" a kernel-module as binary code in


your favourite hex-editor, without resorting to compilers and such. this would allow you to
"port" a driver from one kernel to another without recompilation. i guess this is not for
humans though..
No you cannot port module which is compiled for one version to other version.
The reason is as follows
Modules are strongly tied to the data structures and function prototypes defined in a
particular kernel version; the interface seen by a module can change significantly from
one kernel version to the next. This is especially true of development kernels, of course

The kernel does not just assume that a given module has been built against the proper
kernel version. One of the steps in the build process is to link your module against a file
(called vermagic.o) from the current kernel tree; this object contains a fair amount of
information about the kernel the module was built for, including the target kernel version,
compiler version, and the settings of a number of important configuration variables.
When an attempt is made to load a module, this information can be tested for
compatibility with the running kernel. If things dont match,

the module is not loaded; instead, you see something like:


# insmod hello.ko
Error inserting './hello.ko': -1 Invalid module format

A look in the system log file (/var/log/messages or whatever your system is configured to
use) will reveal the specific problem that caused the module to fail to load.
Kernel interfaces often change between releases. If you are writing a module that is
intended to work with multiple versions of the kernel (especially if it must work across
major releases), you likely have to make use of macros and #ifdef constructs to make
your code build properly.

What are coding conventions for using floating-point in


Linux device drivers?
Short answer: Kernel code can use floating point if this use is surrounded
by kernel_fpu_begin()/kernel_fpu_end(). These function handle saving and restoring the
fpu context. Also, they call preempt_disable()/preempt_enable(), which means no
sleeping, page faults etc. in the code between those functions. Google the function
names for more information.
If I understand correctly, whenever a KM is running, it is using a hardware context (or
hardware thread or register set -- whatever you want to call it) that has been preempted
from some application thread.
No, a kernel module can run in user context as well (eg. when userspace calls syscalls
on a device provided by the KM). It has, however, no relation to the float issue.
If you write your KM in c, the compiler will correctly insure that the general-purpose
registers are properly saved and restored (much as in an application), but that doesn't
automatically happen with floating-point registers.
That is not because of the compiler, but because of the kernel context-switching code.

Memory usage of a kernel module

While trying to estimate the amount of memory consumed by a kernel module (usually
device drivers),I tried using the size utility which gave the size of the static memory
areas of the .ko ( .bss, .data, .text etc). So I was expecting the sum of these values to be
exactly equal to the output given by the lsmod command immediately after inserting the
module.
No dynamic memory allocation(kmalloc or vmalloc) is performed in the init() function to
ensure that it isn't causing the difference.So why is there a mismatch?
Curiously the mismatch was found to be a fixed amount most of the time!!
The command outputs are listed below

size chardev.ko
text
172

data
448

bss
dec
hex filename
1024016 1024636 fa27c chardev.ko

lsmod
Module Size Used by Tainted: P
chardev 1025040 0 - Live 0xc009d000

May be the functions used by the module are counted into the module size ? Try
cat /proc/kallsyms | grep module_name

The difference between the two size is 404. Text + data + 404 = 1024. May be this is
some kind of granularity problem ? I don't know how the size is calculated inside the
kernel...
However, kernel code and data are allocated using dynamic memory. And kmalloc uses
pre-allocated block of memory, so it is quite likely that there is some rounding up when
code and data sections are allocated.
Try to increment the size of the data sections and see if the lsmod reported size change