Saturday, August 28, 2010

Mechanism of function calls what does a processor do when function call is made

A question on Kernel Newbies mailing list related to function calls in timer.c
prompted me to right this here.
The original thread can be seen here

To make a function call CPU has to save registers and pass on ret
instructions when ever the function call ends
if we have a small fucntion which is used in a file and a function
call via CPU then over head of saving flag registers ,saving stack and
making the called function return to the location where the call was
made is so much that it is preferred to replace that call via the
actual function itself hence if some one has such a function which has
is of very less number of lines and has been called once or twice then
it is good to declare it inline.

The overhead that CPU has to undergo if the function is not inline is saving the current context ,flag,stack,heap ,(what ever is)the state of code in execution and then load the called function from a specific memory location.
Doing this for small subroutines is resource consuming.So it is a good practise among kernel developers do declare functions inline when it is used once or twice and saves the CPU the over head involved in saving the stack,program counter flag registers and other registers which are being related to the program in execution.

By using the word in laymans language I will say that part of code (function ) is actually written where ever the function call is made.

For example following program

inline function ingen (X1,X2)
does some thing some thing
return c;

function b( )
step = function ingen ();
b ();
If you were to execute above code

call to function ingen () via function b() would replace the function ingen() by the code inside function ingen().

If you would not have declared function ingen as inline function then the CPU would jumped to some memory location where function ingen() is actually residing and then executed.

In this case CPU just have to insert that code what ever function ingen() does when ever a call to function ingen() is made via function b().

Or which ever function in the code calls function ingen().

If the keyword static is added so that if the same function has been used at any other place then it should not affect the other files.Meaning the word static before a function makes its scope limited to that file only.

If you have another program example2.c and compile

cc example1.c example2.c
then functions in exampl1.c would be available to example2.c and vice versa but use of word static restricts the function in their respective files.
i.e. if example1.c has a static function then it will not be available to example2.c

What static does is to create a label for a certain global memory chunk and give that a value at compile time, plus not making it available to the linker.

Look at these examples
static int mystatic = 6;

int main(void)
return 0;
Generated ASM is as follows:

.file "static2.c"
.align 4
.type mystatic, @object
.size mystatic, 4
.long 6
.globl main
.type main, @function
pushl %ebp
movl %esp, %ebp
movl $0, %eax
popl %ebp
.size main, .-main
.ident "GCC: (Debian 4.4.4-8) 4.4.5 20100728 (prerelease)"
.section .note.GNU-stack,"",@progbits
Compare that with declaring the global variable as non-static:

int mynonstatic = 6;

int main(void)
return 0;


.file "nonstatic2.c"
.globl mynonstatic
.align 4
.type mynonstatic, @object
.size mynonstatic, 4
.long 6
.globl main
.type main, @function
pushl %ebp
movl %esp, %ebp
movl $0, %eax
popl %ebp
.size main, .-main
.ident "GCC: (Debian 4.4.4-8) 4.4.5 20100728 (prerelease)"
.section .note.GNU-stack,"",@progbits
The only difference is that in the non-static case, there's the .globl mynonstatic that makes that symbol available to the linker.
Now, careful observation will make you notice that both global variables are declared as labels, exactly the same way as main is. ASM doesn't really distinguish between functions and variables (the @function and @object thing is just an optimization gcc does): all there is memory addresses that you conveniently can refer to with a label. So, when you declare a function static, what will happen is exactly the same: the function is given a value (its code) and make it unavailable to the linker... exactly what was done to the variable.

Here you have the C and ASM for a static function:

.file "stat_func.c"
.type something, @function
pushl %ebp
movl %esp, %ebp
movl $0, %eax
popl %ebp
.size something, .-something
.ident "GCC: (Debian 4.4.4-8) 4.4.5 20100728 (prerelease)"
.section .note.GNU-stack,"",@progbits
Again, the value for something is its code, it's a global value but not available to the linker because there's no .globl something.

What about local static variables? Actually, the idea of local variables is lost when compiling C to ASM. What you have is a global stack that each function is in charge to clean up when returning... therefore making its local values no longer available outside the function... but place a jmp and the value will be available. What happens with static variables is that the static again sets up a value at compile time and makes the symbol unavailable for the linker... as you'll see here:

int main(void)
static int mystatic = 6;

return 0;

.file "static.c"
.globl main
.type main, @function
pushl %ebp
movl %esp, %ebp
movl $0, %eax
popl %ebp
.size main, .-main
.align 4
.type mystatic.1248, @object
.size mystatic.1248, 4
.long 6
.ident "GCC: (Debian 4.4.4-8) 4.4.5 20100728 (prerelease)"
.section .note.GNU-stack,"",@progbits
The only difference here is that the .data section has been placed *after* the main "rets" (a kind of return you have in ASM...)... ASM indentation is awful here, but actually main ends at the ret, not at the mystatic.1248 label. Ok, I'm not sure why the name is "mangled" but it's clear that the variable is declared as global even when we declared it as local in C. What will happen is that the C compiler will restrict the usage of that symbol to the main function, but you clearly see that it's just a way to create the illusion of locality... It's actually a global and that's why its value is persistent across the program's execution.

So, in summary, it seems that the real effective meaning (I don't care what the standard says) of static is "Make a global memory address not be available to the linker"... therefore we can explain why is it used both for functions and variables.

Of course, tutorials are doing fine to explain this the way they do... As you see, you have to step down to ASM in order to make some sense of this. Also, this is another great reason of why C is such a pain to use: in the end you still have to understand the basics of ASM... while to use bash, Perl, Python you don't need to know C (or the language the implementation is written in).

Since Linux kernel is made up of C and to make sure functions with similar names(if any) exist then they are not conflicting it is a good practice to declare a function as static.

Declaring it inline reduces the overhead that CPU would have to do in actually calling a function.

To have more digging about this you need to understand mechanism of function call as what does
processor do when a function call is made.

Clearly if you have a large code to execute the
instruction is in memory and it has to come to cache so if you have
large code and you declare that as inline it has disadvantage that
cache miss will more.

What I wanted to
say is if you have a function is used at 10 places and you declare it
inline 10 times then there would be cache miss more (because that inline part of code would not be in cache) and this will
have disadvantage.

Some good links worth mentioning are if you want to dig into

Linux Kernel Development by Robert Love, page 18 ,Chapter2, 2nd edition of book has discussed about it.
By the time you will read this blog third edition of book would have released.

Tuesday, August 24, 2010

Accessing Linux Kernel Via /proc

Was the starting point,

Monday, August 23, 2010

make errors

make -C /lib/modules/2.6.28-11-generic/build M=/g/temp/ modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.28-11-generic'
Building with KERNELRELEASE =2.6.28-11-generic
CC [M] /g/temp/ /crash5.o
/g/temp/modu.c: In function ‘syms_out’:
/g/temp/modu.c:13: error: ‘KERNE_INFO’ undeclared (first use in this function)
/g/temp/modu.c:13: error: (Each undeclared identifier is reported only once
/g/temp/modu.c:13: error: for each function it appears in.)
/g/temp/modu.c:13: error: expected ‘)’ before string constant
/g/temp/modu.c:13: warning: format not a string literal and no format arguments
make[2]: *** [/g/temp/ /crash5.o] Error 1
make[1]: *** [_module_/g/temp/ ] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-2.6.28-11-generic'

Such errors in make file can be resolved by
1)Checking KERNELRELEASE variable missing in Makefile or mistyped
2) Checking module_exit code missing or module_init repeated 2 times
3) KERNE_INFO should not be used KERN_INFO to be used.

Friday, August 20, 2010

Voyage to Linux Kernel Day 12 program errors

I am trying the program from Linux For You magazine Day 12 of Voyage to Linux Kernel
June 2009 edition.
From Aasis Vinayaks column following is the program on my Ubuntu laptop

extern void *sys_table[];
asmlinkage int(*main_sys_exit)(int);
asmlinkage int alt_exit_function(int err_code)
printk("Sys_exit called with err_code=%d\n",err_code);
return main_sys_exit(err_code);

int init_module()
void cleanup_module()

Has given a lot of errors discussed on Kernel Newbies mailing list.
Seems to have been the longest discussion in the history of Linux Kernel Newbies mailing list.
Please do suggest if you feel any correction is needed in the program.

Monday, August 16, 2010

hello kernel

Here is the program
static int hello_init(void)
printk(KERN_ALERT "Hello,world tapas\n");
return 0;
static void hello_exit(void)
printk(KERN_ALERT "Good Bye,cruel world\n");

and the corresponding make file for this is

make -C /lib/modules/$(uname -r)/build/M=$(PWD) modules
make -C /lib/modules/$(uname -r)/build/M=$(PWD) clean

and to compile
make -C /lib/modules/`uname -r`/build/ M=`pwd`

thats it.

I got following output

tapas@tapas-laptop:~/LKP/pandora/temp$ make -C /lib/modules/`uname -r`/build/ M=`pwd`
make: Entering directory `/usr/src/linux-headers-2.6.28-11-generic'
LD /home/tapas/LKP/pandora/temp/built-in.o
CC [M] /home/tapas/LKP/pandora/temp/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/tapas/LKP/pandora/temp/hello.mod.o
LD [M] /home/tapas/LKP/pandora/temp/hello.ko
make: Leaving directory `/usr/src/linux-headers-2.6.28-11-generic'

Now you can see it
log in as root
dmesg -c > /dev/null

sudo insmod hello.ko

and following output

sudo dmesg
[ 6134.945901] Good Bye,cruel world
[ 6158.783790] Hello,world tapas

Wednesday, August 11, 2010

Replacing newline character in vi
I faced this problem to replace new line character.

Use \r instead of \n.
in vi command so

Tuesday, August 10, 2010

adding java script ,object elements to educommons,plone

Allowing javascript or embed tags to your eduCommons website

Problem of accessing a course after building it,

Slow eduCommons website

If Zope is not able to load website properly

Installation problems in eduCommons

Changing the admin password

Stale pid problem

Monday, August 9, 2010

running a cloud of streaming servers

This is the current problem I am working at.
The discussion can be found here

Xen Cloud Platform Guide

I was scrolling through Xen mailing lists.
Suddenly a discussion drew my attention.
Here it is

They have mentioned about a guide
I found it interesting.

Saturday, August 7, 2010

Excluding the unwanted directories from the search on Linux

If you want to search and exclude a particluar directory in your search then you can do it in following three ways

Method 1
Suppose I want to search a file lighttpd but exclude that search from my home directory
find / -name lighttpd | grep -v "^/home/" | xargs ls -l

Method 2
a for-loop and the command "dirname" will help here...
(if [ ! `dirname $i` = "/home" ]; then ...)

Method 3
Excluding the unwanted directories from the search
find / -wholename /home -prune -o -name lighttpd -exec echo rm {} \;

Explanation of method 3

The action -prune just tells find to not descend into directories. Let's look at every single
step of method 3 above

a. Look for a directory whose whole name is /home
$ find / -wholename /home

The name is relative to the specified search path, in this case / (root). This tell us that there is (obviously) only one item whose name is /home.

b. Add -prune
$ find / -wholename /home -prune

Nothing different here, because the action -prune alone is evaluated as true and the result is to print the directory name. Actually the rule here is: if the expression contains no actions other than -prune, -print is performed on all files for which the expression is true.

c. Add an alternative (logical OR)
$ find / -wholename /home -prune -o -name lighttpd -print

Note that the expression here contains at least one action other than -prune (-print), so that the rule cited above does not apply. For this reason, when find encounters /home the left-hand-side of the expression is true and the output is null now. Instead for all the other directories, the left-hand-side of the expression is false and the right-hand-side is evaluated (in this case every file whose name is lighttpd is printed out).

Note that if you omit -print (without adding any other action) the rule above is applied and -prune still has the effect to not descend into the directory, but the directory name is printed out:

$ find / -wholename /home -prune -o -name lighttpd

In my previous example the action -exec prevents this behaviour.

Finally you can omit multiple directories from the search by expanding the left-hand-side of the expression with other alternatives (embedded in escaped parentheses). For example:
$ find / \( -wholename /home -o -wholename /etc \) -prune -o -name lighttpd -print

d. If you want to know what {} do read man find and search for -exec section

-exec command ;
Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of
`;' is encountered. The string `{}' is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just
in arguments where it is alone, as in some versions of find. Both of these constructions might need to be escaped (with a `\') or quoted to protect them
from expansion by the shell. See the EXAMPLES section for examples of the use of the -exec option. The specified command is run once for each matched
file. The command is executed in the starting directory. There are unavoidable security problems surrounding use of the -exec action; you should use
the -execdir option instead.

Thursday, August 5, 2010

Network programming on C

Unix Network Programming
A good link from LQ
keeping the packets to QUE and then modifying the headers.

Seems Good

Sunday, August 1, 2010

Installing Red5 on Ubuntu 9.04 32 bit

Installing Red5 on Ubuntu 9.04

Assuming you do not know what ant,svn,Red5 are and you have just installed Ubuntu 9.04 on your desktop.

Now you are wondering where in the world you should be doing all these things.
If you are trying this blog and some thing does not works for you drop me a mail so that I can understand what you missed and try to help you.

Before we begin
If you are a complete newcomer then read

you need to know what is
3) how to set class paths in Linux

Let us begin with creating an environment to be able to install Red5.
Red5 is based on Java.
So you need to have Java installed in your computer.
If you do not have

then Start here otherwise you can jump to Step 14

Install JAVA for Red5

Step1) Check
and enable or add following lines if you do not have already note the partner word at the end

deb jaunty partner
deb-src jaunty partner

Step2) Do an apt-get update
and type
apt-get install sun-jdk6-java

it should work
if you have any problems
I will strongly recommend to check following links (I faced problems which got solution on these links)

Please do not install jre for Red5 as Red5 needs jdk and not jre as you will read below in this post.

Step 3) Now go to /etc/profile.d/ and create a file named

export JAVA_HOME=/usr/lib/jvm/java-6-sun
export PATH=$JAVA_HOME/bin:$PATH

Install ant

I will strongly recommend to install latest ant binary from apache website do not use old versions I had some errrors which actually were resolved when I used the latest ones
Step 4) Download the latest binary for your Linux
if by the time of reading this blog it is one year or more and you by chance have come across and the above link does not works do Google apache ant binary download
I will suggest Google ant apache download and use the latest version because in my case I got this problem from some blog old links were not working

It is a good practise to install these type of packages in
(although not necessary)
so you should have some thing like


Step 5) go back to /etc/profile.d and create
/etc/profile.d/ and its content will be

export ANT_HOME=/usr/lib/apache-ant-1.8.1
export PATH=$ANT_HOME/bin:$PATH

Step6) I installed in /usr/lib both Jdk and Ant so my JAVA_HOME and ANT_HOME are like that.

upto this step do a check
you should get

root@tapas-laptop:/etc/apt# echo $ANT_HOME

Step 7) If you do not get upto the above mentioned steps 6 then do not proceed further first resolve the above issues.
Here are a few links which I feel will be useful to you since I had problems from Step1 to Step6 which got resolved
following links you can read

Step 8) Assuming that if you type which java and which ant on command prompt you are getting following output
root@tapas-laptop:/etc/apt# which java

root@tapas-laptop:/etc/apt# which ant

Step 9) Check ant -version

you should get an output like this

root@tapas-laptop:/etc/apt# ant -version
Apache Ant version 1.8.1 compiled on April 30 2010

Step 10) check java -version

root@tapas-laptop:/etc/apt# java -version
java version "1.6.0_13"
Java(TM) SE Runtime Environment (build 1.6.0_13-b03)
Java HotSpot(TM) Server VM (build 11.3-b02, mixed mode)

Step 11) If upto above you have got exactly what mentioned only then proceed further.
Otherwise resolve the above errors first.

If you get an error like
Error: JAVA_HOME is not defined correctly. We cannot execute /usr/lib/jvm/java-6-sun/bin/bin/java

check this thread

or if you get an error like


Unable to locate tools.jar. Expected to find it in /usr/lib/jvm/java-6-sun-
Buildfile: build.xml does not exist!
Build failed

check this thread

Step 12) Install subversion
apt-get install subversion

you do not need to know what subversion is to be able to use it although it will help if you know it
When I used I did not knew what it is.

Step13) Now go to
since they can move the repositories if you hit this blog at a later date and then do Google svn red5 trunk

Step 14)
Go to /opt (not necessary to be in opt but I prefer)
type following command
svn checkout red5-read-only

after some minutes depending upon your internet connection you will see a directory named

red5-read-only in /opt or where ever you executed this command say for example you executed
svn checkout red5-read-only
from your home directory i.e.
then you will see

Rename red5-read-only to red5
If you do not know how to rename do following from your
directory where you executed svn command

mv red5-read-only red5

Step 15) now go to /opt/red5 and type
cd /opt/red5
and type

please note if you get an error like this

Buildfile: /opt/red5/build.xml
Target "build" does not exist in the project "Red5".

then you do not need to type ant build for building any thing
just type ant from /opt/red5 and the above error should go I got this information here
if this does not solves your problem you should Google the error message

Step 16) Thats it.

Now go to /opt/red5/dist and you should see
on command prompt ./ should give you some output do not close the terminal and check in
browser http://localhost:5080/

I have not explained how to create a startup script for this but if you want to read check the following blog
I will post it and give a link to my blog also.
Just want your confusion to be less :)

Red5 init script for Ubuntu

#The script to start Red 5 Tapas Mishra
##Begin some thing some thing
# Provides: Red5
# Required-Start: No idea
# Required-Stop: No idea
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Red5 Streaming Server
# Description: Ubuntu init script for Red5 server

DESC="Tapas Red5 Server"

. /lib/lsb/init-functions
set -e


case "$1" in
log_daemon_msg "Starting $DESC" "$NAME"
start-stop-daemon --start --pidfile $PIDFILE \
--chdir $RED5_HOME --background --make-pidfile \
--exec $DAEMON
log_end_msg $?
log_daemon_msg "Stopping $DESC" "$NAME"
start-stop-daemon --stop --quiet --pidfile $PIDFILE \

--name java
rm -f $PIDFILE
log_end_msg $?
echo -n "Restarting $DESC: $NAME"
start-stop-daemon --stop --quiet --pidfile $PIDFILE \
--name java
rm -f $PIDFILE
sleep 1
echo -e
$0 start
echo "Usage: $0 {start|stop|restart|force-reload}" >&2
exit 1

exit 0

This is my script for starting and stopping Red5 on Ubuntu in case you want to have some thing else here are good sources