Monday, 28 November 2011

System Call In Linux

                                                          System calls provide a layer in between the hardware and the application programs. The system calls server for 3 primary purposes.
1. it provides a abstracted hardware interface to the user process.
2. it provides the system security and stability.
3. it provides a virtualized system to process.
The system calls are the only legal entry point to the kernel other than exceptions and traps.

Api and System call.






                                   When an application programmer calls a printf or some other api the corresponding funtion in the c library will be invoked and that in turn will call some system call which is implimented in the c library and which in turn will call the kernel's system call using the system call number. Syscalls are often accessed by the function calls defined in the c library . They can be called with zero one or more arguments , and might result in one or more side effects. System call provides a return value of long. The return value will indicate a success or failure of the system call. Usually zero is a success. and negative value is an error . When an error occurs a global errorno variable is set to a error code and it can be transformed to a user readable format by using perror function.
A system call definition looks like this.
asmlinkage long sys_mysyscall(void)

The asmlinkage directive tells the compiler to look only on the stack for that function's arguments.
mysyscall is defined as sys_mysyscall this is the naming convention .

system call read is implemented in kernel as sys_read.


System call number.
In linux each system call has a unique number. When a user space process  executes a system call, the system call number identifies which system call was executed. The process does not refer to the system call by name. Kernel keeps track of all registered system calls in a system call table. In my system it is in the file arch/x86/kernel/syscall_table_32.S 

System call handler.
It is not possible for a user space process to execute a kernel space code by calling a function because kernel resides in a special memory protected area . If an application program were allowed to write, to read or call a kernel space method or function it would become a security loophole . So what user process does is that they signal the kernel saying that they need to execute a system call, kernel on getting this signal will execute the system call on behalf of the user space application . The mechanism to do this signaling is called the software interrupts . It is somewhat like an exception when user signals a software interrupt the process will be switched to kernel mode and the corresponding exception handler will be executed. In this case it is called as a system call handler. In x86 architecture the sotware interrupt has the number 0x80 and it can be triggered using the instruction int $0x80. The system called handler is a named function called system_call(). its implementation can be found in arch/x86/kernel/entry_32.S 
After entering to the kernel space  there are so many system calls the user will have to pass the system call number to the kernel before the software interrupt is executed. this is done by in x86 by filling eax register with the system call number and then calling int 0x80 ;if the system call number is a valid number the the system_call execute the corresponding systemcall by doing 
call *sys_call_table(,%rax,4)
each element in the system call table is 4 byte in a 32 bit processor so the the kernel multiplies the given value with four to arrive at correct location in the system call table.





                              The parameters to the system call are passed to the kernel before the software interrupt by filling them in the registers 
ebx,ecx,edx,esi,edi
if more than 5 arguments are needed to then we use a single register to fill the pointer to user space where all the parameters are stored. The return value is also send to user space via register eax.

NOW LETS IMPLEMENT A SYSTEM CALL!!!
Step 1:
create a folder in the root of your kernel source tree and go to that directory.


step 2:
write your system call in a file like mycall.c

#include<linux/linkage.h>

#include<linux/kernel.h>

asmlinkage long sys_myscall(void)

{

    printk(<1>"Hell, world\n");

    return 0;

}



step 3:
Create a Makefile which contains ,
obj-y := myscall.o

step 4:
add a line like given below to the file  arch/x86/kernel/syscall_table_32.h .
.long sys_myscall






















step 5:
add a line like given below to the file arch/x86/include/asm/unistd_32.h
#define __NR_myscall
and also change the NR_syscalls to the previous number + 1


























step 6:
add a line like given below to the file include/linux/syscalls.h
asmlinkage long sys_myscall(void);



step 7:
add your system call files folder i.e, test to the core-y variable in Makefile













step 8: 
compile the kernel.

Testing your system call 

Thursday, 10 November 2011

Linux Kernel Doubly Linked circular list

                                                              In this blog post I am introducing  the most beautiful linked list I have ever seen . This linked list is taken from linux kernel. Linux kernels linked list is entirely written in a single file . To see how it is implemented you can take a look at your kernel source ,it is located in /include/linux/list.h most of the linked list operations and data structures for the linked list is written  in that file. The code is documented well . The list written there is a doubly linked circular list. You can see the structure of node linked in linked list which is defined in the file /include/linux/types.h as 
struct list_head {
        struct list_head *next, *prev;
};
almost all of the work in the linked list is done by a prepossessing macro
 #define list_entry(ptr, type, member) \
         container_of(ptr, type, member)
and if you look for what this container is doing you can see it as
#define container_of(ptr, type, member) ({                      \
         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
         (type *)( (char *)__mptr - offsetof(type,member) );})

  

I have implemented a small linked list code as a kernel module using the operations which are defined inside the list.h file.

#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/list.h>
#include<linux/slab.h>

struct node {
 int data;
 struct list_head ptr;
};

#define list_t struct list_head
static struct list_head head = {&(head),&(head)};

static void print_dll(void)
{
 list_t *q = &head;
 struct node *temp;
 while(q->next != &head) {
  temp = list_entry(q->next,struct node,ptr);
  printk("data = %d\n",temp->data);
  q = q->next;
 }
}

struct node *new(int data)
{
 struct node *temp;
 temp = (struct node *) kmalloc(sizeof(struct node),GFP_KERNEL);
 temp->data = data;
 return temp;
}

static void dll_add(int data)
{
 list_add_tail(&(new(data)->ptr),&head);
}

static void make_dll(void)
{ 
 int i;
 for(i = 0; i < 10; i++) {
  dll_add(i);
 }
}

static void dll_delete(int data) 
{
 list_t *q;
 struct node *temp;
 for(q=&head;q->next != &head; q=q->next) {
  temp =  list_entry(q->next,struct node,ptr);
  if(temp->data == data) {
   list_del(&temp->ptr);
  }
 }
}

int init_module(void)
{
 printk("inserted linked list test module\n");
 make_dll();
 print_dll();
 printk("trying to deleat the node with data %d\n",5);
 dll_delete(5);
 print_dll();
 printk("the last element of the dll is %d\n",
   list_entry((&head)->prev,struct node,ptr)->data);
 return 0;
}

void cleanup_module(void)
{
 printk("cleaned module \n");
}
 
Screen short of output

Wednesday, 2 November 2011

TASK SWITCHING IN MSP430

                                                        You might have noticed that while we are working on a computer we will be having many processes running at the same time.Actually we have only one processor, and wonder how is this magic happening ? Actually your operating system is time multiplexing your processor ie, each of the process will be allotted a time slot , after which the scheduler of the operating system will find the task which is to be executed, it will run that process for a time quantum . this process is repeated . Which is called a round robin fashion of scheduling the processes . Let us think of task as a small independent code . what we need to do is to make multiple threads for execution. And each of the thread will be executing a task. The advantage is we can concurrently execute the tasks before making multiple threads we should think
about how to make the time quantum for each task . For that we can take the help from the timer . Timer is an inbuilt peripheral device in almost all Micro controllers . A timer is used to get periodic interrupts as configured by the user. for example if the timer is configured to give interrupt in 1 second after each second our process will be interrupted and we can configure the processor in
such a way that the processor will call a function each time when the interrupt occurs . This type of function is called interrupt service routine. Before we transfer control to a thread we will have to save the current state of the currently running task . How can we do it? The current state of the task is contained in each of the processor registers. So by saving the current register of the processor we can save the current tasks state. next we need to execute the next task, for that we need to fill the registers with the save of the other task. A typical task switcher will be like this
fun isr():
 save_states_of_current_task();
 schedule_next_task();
 restore_states_of_scheduled_task();

Task Switching in MSP430
                                                  I had given an introduction about msp430 in my previous blog. I have implemented a task switching demo code for MSP40 MSP430 is having only a 128 bytes ram so we can only implement task switching up to an extend in this micro controller as we lack memory. For task switching we will keep a global array of which holds the stack pointer of each task . Also we will keep a variable which points to the current tasks index. First thing we need to do is to configure timer. Next we need to divide stack for each stack and initialise their stacks . After the initialisation is done you need to enable interrupts . At this point the timer interrupt will occur after some time. When the timer interrupt occurs, into the timer isr we first push all the registers onto the stack then we increment the task id and jump to the next task .
.include "msp430g2x31.inc"

#define TASK_ID 0x270
#define TASK_ARRAY 0x214

org 0xf800

;;;start routeine.
start:
         mov.w #(WDTPW|WDTHOLD), &WDTCTL    ;disable watchdog timer
         mov.w #0x280, SP                   ;initialise stack pointer
         eint                               ;enable interrupt
         mov r2,r4                          ;copy status register to r4
         dint                               ;disable interrupt
         mov.b #255,&P1DIR                  ;configure all pins of port1 as output
         mov.b #0,&P1OUT                    ;make all the pins off
         mov.b #1,&TASK_ID                  ;initialise current task id as 1
         mov.w #(TASSEL_2|MC_1|ID_3), &TACTL;configure timer control register
         mov.w #(CCIE), &TACCTL0            ;enable capture compate interrupt.
         mov.w #100, &TACCR0                ;set capture compare threshold.

  
;;;initialise the stack of task1
       mov.w #0x258,SP  
       push #task1
       push r4
       push 0
       push 0
       mov.w SP,&TASK_ARRAY

;;;intialise the stack of task2
       mov.w #0x230,SP
       mov.w SP,&(TASK_ARRAY - 0x02)

       eint                           ;enable interrupt.
      jmp task2                       ;jump to task1.
gg:   jmp gg                          ;trap in a while loop.

;;;timer isr
isr:
      push.w r4                       ;push r4 because it was used by other tasks
      push.w r7                       ;push r7 because it was used by other tasks
      mov.b &TASK_ID ,r4              ;copy current task's id to r4
      add r4,r4                       ;r4 <- r4 * 2
      mov.w SP,TASK_ARRAY(r4)         ;update the stack pointer of task array
      add #1,&TASK_ID                 ;add 1 to the current task id
      mov.b &TASK_ID,r4               ;move current task id to r4
      cmp #2,r4                       ;compare the current task id with the maximum tasks
      jne non_zero    
      mov.w #0,&TASK_ID               ;if they are equal then make task_id to zero 
      mov.w #0,r4                     ;r4 to zero
non_zero:
     add r4,r4                        ;multiply r4 by 2
     mov.w TASK_ARRAY(r4),SP         ;load stack pointer with new task's SP 
     mov.w SP,r5                     ;mov sp to r5
     add #8,r5                       ;add sp with 8
     mov.w r5,TASK_ARRAY(r4)         ;save back the top of stack to task_array
 
     pop.w r7                        ;pop to r7 
     pop.w r4                        ;pop to r4
     pop.w r2                        ;pop to r2
     pop.w r0                        ;pop to r0 control gone to next task

;;;task1 to execute.
task1:
    xor.b #1,&P1OUT
    mov #50000,r4
    loop1:
       dec r4
       jnz loop1
    jmp task1
 
;;;task2 to execute.
task2:
    xor.b #(1<<6),&P1OUT
    mov #10000,r4
    loop2:
        dec r4
        jnz loop2
    jmp task2

;;vector table.
org 0xfffe                                      ;reset vector
       dw start
org 0xfff2
       dw isr



INTRODUCTION TO MSP430

                                                            The Texas Instruments MSP430 is a series of ultra low power micro controllers which  I have come across as a very low price development of board of Texas Instruments called launchpad. MSP430 has a powerful 16 bit RISC processor which has 16 bit general purpose registers and a constant generator. I have come across the MSPs G series of micro controllers which had a the following features.
 *) 16 timer.
*) 10 bit ADC
*) 2 IO PORTS.
*) I2C
*) SPI


 Setting up a Linux development environment.
                                          For compiling the C programs you have to install the tool chain which includes cross compilers, assemblers . In linux you have two options you can either build the cross compiler from source and install it to or you can search for a binary file. The first one may take some time and you may get messed up with some nasty errors . If you want to do it in a hard way you can go for it, in my case I would be select the easy one . I got the binary of the msp430-gcc,msp430-binutils etc from the following site The package was for ubuntu . I am using debian and that packages worked for me. You can download the packages from that site and install them . After installing the tool chain you will have to install another tool "mspdebug" which is used for debugging and burning the code to the micro controller.
 Led Blinking Code
#include<msp430.h>
void sleep(int i)
{
 while(i--);
}

void main(void)
{
 WDTCTL = WDTPW | WDTHOLD;
 P1DIR = 0xFF;
 while(1) {
   P1OUT ^= 0x01;
   sleep(50000);
 }
}
In the main function first line of the code disables the watch dog timer. next we have to set the direction of the i/o port 1 as the out-put port . After setting port-1 as output port we just toggle the first pin of the i/o port 1.
 compiling the code
To compile the above code you can use the cross compiler which is msp430-gcc
tonylijo@tonylijo:~$ msp430-gcc new.c
after executing the command you will get a file a.out. 
Burning the code to the Micro controller
                                                To burn the code to micro controller you have to use the tool mspdebug after executing the command you will get like given below.
root@tonylijo:/home/tonylijo# mspdebug rf2500
MSPDebug version 0.16 - debugging tool for MSP430 MCUs
Copyright (C) 2009-2011 Daniel Beer dlbeer@gmail.com
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Trying to open interface 1 on 003
rf2500: warning: can't detach kernel driver: No data available
Initializing FET...
FET protocol version is 30001000
Configured for Spy-Bi-Wire
Set Vcc: 3000 mV
fet: FET returned error code 4 (Could not find device (or device not supported))
fet: command C_IDENT1 failed
fet: identify failed
Trying again...
Initializing FET...
FET protocol version is 30001000
Configured for Spy-Bi-Wire
Sending reset...
Set Vcc: 3000 mV
Device ID: 0xf201
Device: MSP430G2231
Code memory starts at 0xf800
Number of breakpoints: 1

Available commands:
    =         delbreak  gdb       load      opt       reset     simio     
    alias     dis       help      locka     prog      run       step      
    break     erase     hexout    md        read      set       sym       
    cgraph    exit      isearch   mw        regs      setbreak  

Available options:
    color           gdb_loop        iradix          
    fet_block_size  gdbc_xfer_size  quiet           

Type "help topic" for more information.
Press Ctrl+D to quit.
(mspdebug)
after that to erase the code which is currently inside the micro controller you can use the command erase to burn the code to the micro controller you can use the command
(mspdebug) prog a.out

Monday, 10 October 2011

PYTHON BYTECODE

                                                        In this blog post we are going to look at the internal representation of the python byte code.When we try to execute a python script there a some common steps which will happen.
1. compile the code and transform the code script to an intermediate representation called byte code .
2. The byte code will be executed by a virtual machine.
By doing this python will become platform independent as the python byte code is not interpreted by the real hardware.

    Internals of python bytecode

Now let us dig into the internals of a python bytecode . The python bytecode is divided into 3 parts mainly
1. first four byte magic number.
The starting of four bytes of a python byte code will be a magic number . The magic number will unique for a version python .
2. second four byte time stamp.
The time stamp field will modified each time the script file is modified . If the script file is modified the python script should be recompiled
and a new byte code should be produced .
3. rest of the code will be the marshelling code .
Thre rest of the code is the marshelling code . Means python byte code instructions along with its operands will be sequencially encoded in this
region.

    Manually compiling a python script.

To manually compile a python code you can use py_compile module.
for example make a python script .

$vim test.py
i = 1


now to compile test.py you can use this script given below.
import sys,py_compile

def main():
  py_compile.compile(argv[1])

if __name__ == '__main__':
  main(sys.argv)
let us call the above script file as compile.py
$python compile.py test.py
This will produce a file named test.pyc in the directory where you have executed the above script .

if you want to see what is inside the test.pyc you can do it by using the linux command.
$od -tx1 test.pyc
0000000 d1 f2 0d 0a fb 73 8e 4e 63 00 00 00 00 00 00 00
0000020 00 01 00 00 00 40 00 00 00 73 0a 00 00 00 64 00
0000040 00 5a 00 00 64 01 00 53 28 02 00 00 00 69 01 00
0000060 00 00 4e 28 01 00 00 00 74 01 00 00 00 69 28 00 
0000100 00 00 00 28 00 00 00 00 28 00 00 00 00 73 07 00
0000120 00 00 74 65 73 74 2e 70 79 74 08 00 00 00 3c 6d
0000140 6f 64 75 6c 65 3e 01 00 00 00 73 00 00 00 00
0000157
The above thing is the hex dump of my test.pyc file . as you can see the first 4 bytes.
is the magic number.
is the time stamp.

to understand the rest of the part we need to see the python byte_code instructions opcode. you can see all the python byte code and its opcode
hear


    Disassembling the python bytecodes

To dis assemble the python code you can use dis module.
$python -m dis test.py

0 LOAD_CONST 0 (1)
3 STORE_NAME 0 (i)
6 LOAD_CONST 1 (None)
9 RETURN_VALUE
this is the internal representaion of the code i = 1 in python byte code
if you wan tot see the full dis assembly of the bytecode test.pyc you can use the script which is given below.

import sys,dis

def main(argv):
  fp = open(argv[1],'r')
  byte_code_string = fp.read()
  dis.dis(byte_code_string)

if __name__ == '__main__':
  if len(sys.argv) &lt; 2:
    print 'usage: python pydis.py '
  else:
    main(sys.argv)
    Writing your own dis assembler

Now with the above details given if you are interested try to make a dis assembler . you can also check this code
https://github.com/tonylijo/python-byte-code-disassembler

Wednesday, 21 September 2011

Linux kernel module programming

                                                           A kernel module is a piece of code which can be dynamically loaded or unloaded from the system to extend its functionality . There is no need to compile the whole kernel source code for adding a single functionality. also you need not reboot the system after adding the module . This is one of the features of the micro kernel architecture.
so let us write our conventional starting code .
Hello world module.
#include
int int_module(void)
{
   printk(" Hello, world \n");
   return 0;
}

void cleanup_module(void)
{
   printk(" bye bye world \n");
}
as you can see in the code above there are two functions
1) init_module .
2) cleanup_module
init_moudule is some what like the main fuction in the usual code this is where the kernel module starts working .It is called immidiately after insmod command is executed.
The cleanup_module is the exit function it is called immidiately after the rmmod comman is executed.
As given in the code above , we are using printk function instead of printf function .Heare our module is going to run in kernel space not as a user program so we don't use the user library functions so we need the kernels own printf and that is our printk function .



Compiling the kernel module
for compiling the kernel module you need to compile the kernel module. For this you need to create a make file

Makefile:
obj-m: hello-world.o


now you need to execute the command
make -C /usr/src/linux-3.0/ M=`pwd` modules
After executing the above command do an ls in the current directory you can see that there will be a file named hello-world.ko

Loading the kernel module to the running kernel.

To load the kernel to the currently running kernel we need to use some commands

commands for loading

1)insmod
2)modprob

command for unloading the module

1)rmmod

now use the command
insmod hello-world.ko
if you didnot see a print

Wednesday, 31 August 2011

Configuring UML kernel For Linux Kernel Development.

It is always a good idea to create a simulated environment while doing kernel programming, because playing with kernel may lead to data corruption, system hang-ups and all such nasty things. This post may help you to configure User Mode Linux . User Mode Linux is just like an operating system which is running in user space. So you can do all your experiments on this user space kernel with a less probability of serious damages.


Installing/downloading The appropriate Packages.
You should download / install the following packages.
1)Linux kernel Source 2.6.xx
2)UML Utilities
You can download a latest kernel from www.kernel.org
Extract the kernel to a directory and change your current working directory to that directory.
In my case I have installed the kernel from the Debian's package manager
host# apt-get install kernel-source
host# apt-get install uml-utilities
host# cd /usr/src/
host# bunzip2 linux-source-2.6.32.tar.bz
host# tar -xvf linux-source-2.6.32.tar
host# cd linux-source-2.6.32/

Compiling The UML Kernel
Now you have to compile your linux kernel source for uml architecture . The compilation is similar to the usual compilation.
host# make mrproper
host# make mrproper ARCH=um
host# make defconfig ARCH=um
if you have to compile with a customized config file you can use make menuconfig or make xconfig and customize the config file.
host# make Linux ARCH=um
The above command will create an executable kernel file called Linux.
host# make modules ARCH=um
The above command will create the loadable modules

Creating the Filesystem
Now lets create a root filesystem for our uml kernel.
host# dd if=/dev/zero of=root_fs bs=4k count=1M
this will create a file named root_fs of size around 4G, after this we can write a filesystem onto this root_fs file
host# mkfs.ext3 root_fs
now you have an ext3 file system in the file root_fs. so you can mount that file to a directory .
host# mkdir rootdir/
host# mount -o loop root_fs rootdir/
now you need all the root directory tree should be place on to this directory in our case say rootdir.For this we can use debootstrap command.
host# debootstrap squeeze rootdir/ file:/media/cdrom0/
I created a root file system for the squeeze release from the installation dvd of Debian Squeeze.if you don't have a installation DVD you retrieve the files form the Debian squeeze remote repository. for this you can read the man page of debootstrap.After completion of debootstraping if you go to that directory<rootdir> you can see the complete root directory structure in that directory. now you have a complete directory structure so you can now install the modules to the existing directory structure.
host# make modules_install INSTALL_MOD_PATH=rootdir/ ARCH=um
now your compiled loadable module files will the copied to rootdir/lib/modules/ . now you have to set the password for the root in the filesystem.
host# cd rootdir
host# chroot .
by executing the above command your root of the filesystem tree of the host will be changed to the current working directory . now by executing the passwd command you can update the passward .
host# passwd
set the passward .
host# exit
now you have to create a swap filesystem.
host# dd if=/dev/zero of=swap_file bs=4k count=50k
host# mkswap swap_file

now we should edit some of the configuration files of our newly created filesytem .
1.etc/inittab
2.etc/fstab
3.etc/udev/links.conf

edit file etc/inittab keep the line given below and  delete all such similar lines.

1:2345:respawn:/sbin/getty 38400 tty1


edit file etc/fstab as

/dev/ubd0    /    ext3    defaults 0    0
/dev/ubd1    none    swap    sw     0    0
proc        /proc     proc    defaults 0     0


edit file etc/udev/links.conf

M ubd0    b 98 0
M ubd1    b 98 16
M ubd2    b 98 32
M ubd3    b 98 48
M ubd4    b 98 64
M ubd5    b 98 80
M ubd6    b 98 96

#host umount rootdir/
Networking
To configure networking in uml machine we will use the tuntap methord.
<to--do > write what is tuntap</to--do>
you can create a tap0 interface using the tunctl coammdn
#host tunctl -t tap0
#host ifconfig tap0 192.168.2.33 up
now you are redy to run the code uml kernel
#host ./linux ubd0=root_fs ubd1=swap_file mem=256M eth0=tuntap,tap0
after executing the above command you will get a console on which you can login with the password that you have set using the passwd command
now in the virtual machine you have to set up the the ip of eth0
#host ifconfig eth0 192.168.2.2
#host route add default gw 192.168.2.33

now you have to write some rules for iptable if we want to connect to some public network.
host# echo 1 > /proc/sys/net/ipv4/ip_forward
host# iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
host# iptables -A FORWARD -i eth1 -o tap0 -m state --state RELATED,ESTABLISHED -j ACCEPT
host# iptables -A FORWARD -i tap0 -o eth1 -j ACCEPT
now to start the virtual machine
host# ifup tap0
host# ./linux ubd0=root_fs ubd1=swap_file mem=256M eth0=tuntap,tap0
now you will get a login window if all the above things works fine.To check the whether the connection is ok you can ping to the host machine
virtual-machine# ping 192.168.2.33
virtual-machine# ping 192.168.1.7
virtual-machine# ping google.com