Static Functions in Linux Device Driver
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.
3.
cross-compile filesystem, and port all on board.
But Interviewer is not happy with this answer.
ANS:Porting steps
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.
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.
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
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,
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.
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