Tech Today

Author Archive

current Kernel version: 2.6.28-11

In /usr/src get the source and build tools by typing:

sudo apt-get install linux-source kernel-package fakeroot ncurses-dev

Unpack the source by typing:

sudo bzip2 -d linux-source-2.6.28.tar.bz2
sudo tar xvf linux-source-2.6.28.tar

Make a sym link to the linux source code by typing:

ln -s linux-source-2.6.28 linux

Enter the source directory:

cd linux

Then we are going to make a clean package using the current configuration of the current kernel since it already figured everything out for you.

sudo make-kpkg clean
sudo cp /boot/config-`uname -r` ./.config

Make any changes you want to the kernel here:

sudo make menuconfig

sudo fakeroot make-kpkg --initrd --append-to-version=-lml kernel_image kernel_headers
[NOTE]:–append-to-version” will append a string to the version number; here I am using my initials “lml”. You’re going to want to do this to distinguish your kernel builds apart.

This will give us the header and image output in /usr/src. Issuing these commands will install your new custom kernel:

sudo dpkg -i linux-image-2.6.28.9lml_2.6.28.9lml-10.00.Custom_i386.deb
sudo dpkg -i linux-headers-2.6.28.9lml_2.6.28.9lml-10.00.Custom_i386.deb

As you can see my initials “lml” have been appended in two places.

This also installs the new kernel to grub so next time you boot you will be able to select it.

To edit the grub options:

sudo nano /boot/grub/menu.lst

So, today I am working on understanding how processes communicate in the Linux OS. This code example is written in C and compiled in Ubuntu 9.04 using the Jaunty Jackalope Kernel version 2.6.28-11.

This code specifically prints out the Fibonacci sequence.

The parent process creates and attaches a shared memory segment, forks a child process (remember the child process shares the resources of the parent) , waits for the child to finish, prints out the contents of the shared memory, and finally detaches and removes the shared memory segment.

The child process runs through the Fibonacci algorithm, inserts the resultant into the next available space in shared memory and prints out the resultant to standard output.

This example accepts input from the command line with basic error checking. You know, make sure two args have been provided, they are between the min and max limits of the program; the BASICS.

CODE:

#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define MAX_SEQUENCE 10 // Max values to store in shared memory
#define MIN_SEQUENCE 2  // Min value the user can enter

//shared memory:
// 1) holds an array of numbers
// 2) holds how many numbers are in the array
typedef struct {
int fib_seq[MAX_SEQUENCE];
int sequence_size;
} shared_data;

//MAIN function
int main(int argc, char *argv[]) {

pid_t pid;    //process ID
int segment_id; //Shared Memory ID
shared_data *mem; //Shared Memory Pointer

//check to validate atleast two arguments
if(argc != 2) {
printf(“USAGE ERROR: [0-9]\n”);
exit(0);
}

//validate the input is not larger then the MAX
if(atoi(argv[1]) > MAX_SEQUENCE) {
printf(“Max Input Size: %d\n”, MAX_SEQUENCE);
exit(0);
}

//validate the input is not smaller then the MIN
if(atoi(argv[1]) < MIN_SEQUENCE) {
printf(“Min Input Size: %d\n”, MIN_SEQUENCE);
exit(0);
}

// 1) create a new shared memory location ‘IPC_PRIVATE’
// 2) the size of our shared memory structure ‘sizeof(shared_data)’
// 3) Set Modes S_IRUSR and S_IWUSR so the owner can read and write to the shared memory ‘S_IRUSR|S_IWUSR’
segment_id = shmget(IPC_PRIVATE, sizeof(shared_data), S_IRUSR|S_IWUSR);

//attach the shared memory and get the pointer to the beginning location in memory
mem = (shared_data *) shmat(segment_id,NULL,0);

//set the size of the sequence to the argument that was passed in via command line
mem->sequence_size = atoi(argv[1]);

// fork a child process
pid = fork();

if(pid < 0) { /* error occured */
fprintf(stderr, “Fork Failed\n”);
return 1;
}
else if(pid == 0) { /* child process */
int counter = 0;
printf(“Child Fibonacci Sequence: “);

while(counter < mem->sequence_size) {
if(counter == 0){
//FIB of zero is always zero
mem->fib_seq[counter] = 0;
}
else if(counter == 1){
//FIB of one is always one
mem->fib_seq[counter] = 1;
}
else {
//The Fibonacci Sequence formula ‘R = fib(n-1) + fib(n-2)’
//The first two numbers in the sequence are always 0 and 1.
//To get a value in the sequence you will want to take the previous
//two numbers and add them together. For example:
// b + a = c
// [fib(d-1) = c] + [fib(d-2) = b] = R
// fib(0) = 0
// fib(1) = 1
// fib(2): 1 + 0 = 1
// fib(3): 1 + 1 = 2
// fib(4): 2 + 1 = 3
// fib(5): 3 + 2 = 5
// The next Fibonacci number in the sequence will be ‘8’
mem->fib_seq[counter] = mem->fib_seq[counter – 1] + mem->fib_seq[counter – 2];
}
printf(“%d “, mem->fib_seq[(counter)]);
counter++;
}
}
else { /* parent process */

/* parent will wait for the child process to complete */
wait(NULL);

//Print out shared memory
int count = 0;
printf(“\nParent Fibonacci Sequence: “);
while(count < mem->sequence_size){
printf(“%d “, mem->fib_seq[count]);
count++;
}

//detach shared memory
shmdt(mem);
//remove shared memory segment
shmctl(segment_id,IPC_RMID,NULL);
printf(“\nComplete\n”);
}

return 0;
}

output:


lee@isis:~$ ./a.out 0
Min Input Size: 2
lee@isis:~$ ./a.out 1
Min Input Size: 2
lee@isis:~$ ./a.out 2
Child Fibonacci Sequence: 0 1
Parent Fibonacci Sequence: 0 1
Complete
lee@isis:~$ ./a.out 3
Child Fibonacci Sequence: 0 1 1
Parent Fibonacci Sequence: 0 1 1
Complete
lee@isis:~$ ./a.out 4
Child Fibonacci Sequence: 0 1 1 2
Parent Fibonacci Sequence: 0 1 1 2
Complete
lee@isis:~$ ./a.out 5
Child Fibonacci Sequence: 0 1 1 2 3
Parent Fibonacci Sequence: 0 1 1 2 3
Complete