Pages

Monday, December 18, 2017

All about volatile variable in C

What is volatile keyword in C?
volatile is a data type qualifier in C.

Role of volatile variable in signal handler?
When a variable is declared as volatile, the C compiler does not optimize the code where this variable involves.

It also means that someone might externally change the value of this variable over time, hence do not cache the value of this variable.

In case of interrupt handlers or signal handlers where the counter is dependent is on the incoming data, this counter variables value changes due to external factors like arrival of new data on the port. Hence even though the program did not modified the data, the value of this counter variable changed. Such variable should be declared as volatile variable, so that the C compiler does not optimize the usage of this variable and hence does not pick up the value from the cache.

Logical & and addition

What is going to be the output of this code?

  1 #include
  2 int main(void)
  3 {
  4     int a=10, b=12;
  5     int c;
  6     c = a&b + 65;
  7     printf("c=%d\n", c);

  8}

This code looks simple enough. Guess??

Friday, December 15, 2017

const behavior of a variable in C Programming Language

When you intend to not change the value of a variable you declare it as a const in C language.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
int c1()
{
  int *a;
  const int b;

  a=&amp;b;

  printf("*a=%d, b=%d\n",*a, b);
  
  *a = *a + 1;
  //b = b + 1; 

  printf("*a=%d, b=%d\n", *a, b);

//return ;
}

main()
{       
        printf("C=%d\n", c1());
}




If you execute 
  b = b + 1:
then the compiler complains:
c1.c:12:5: error: cannot assign to variable 'b' with const-qualified type 'const int'
  b = b + 1; 
  ~ ^
c1.c:5:13: note: variable 'b' declared const here
  const int b;
  ~~~~~~~~~~^

That's what is expected.
But if we declare a pointer variable and that points to the const variable, and you increment the "value" of what the pointer variable is pointing to, then the compiler does not complain. Why?

Using only 
  *a = *a + 1;
actually increments the value of b because it's same as *a.



Let's change the program slightly:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
int c1()
{
  int *a;
  const int b;

  a=&b;

  printf("*a=%d, b=%d\n",*a, b);
  
  *a = *a + 1;
  //b = b + 1; 

  printf("*a=%d, b=%d\n", *a, b);

//return ;
}

main()
{       
        printf("C=%d\n", c1());

}

This time the compiler gives an error.

s1.c:11:6: error: read-only variable is not assignable
  *a = *a + 1;
  ~~ ^

So, the rational is if you use the const identifier, then you can't update it's value.



Static variable behavior

How the static variable behaves?

#include
//int s1();
int s1()
{
  static int s;
  return s++;
}

main()
{
  int i=1;
  while (i<=2)
  {      
    i++;
    printf("S=%d\n", s1());
  }

}



Simple program. But here's the trick.
s is a static variable. 

    return s++;
the post increment is done as if:
    
    return s;
    s = s + 1;

So, when the first time s1() prints, it prints the value of s = 0, s being a static variable it's initialized to 0. But the first time s1() returns before it's being incremented. The next statement of course executes, and s is incremented. Since it's a static variable, it's not in the call stack, hence it's got incremented after the s1() function returns, but before the function actually exits.

As per Wikipedia:
When the program (executable or library) is loaded into memorystatic variables are stored in the data segment of the program's address space (if initialized), or the BSS segment (if uninitialized), and are stored in corresponding sections of object files prior to loading.

As per this 1995 Linux Journal article: http://www.linuxjournal.com/article/1059
Executable code is always placed in a section known as .text; all data variables initialized by the user are placed in a section known as .data; and uninitialized data is placed in a section known as .bss.

Hence the static variable actually increments.

Wednesday, August 12, 2015

Let's run a c program by hand

Let’s compile a C program by hand. The aim is to compile the a.c program.

$cat a.h
#define AA 100
$cat a.c
#include “a.h”
main()
{
            printf(“%d apples”, AA);
            exit(19);
}
$

So, this is the program we really wanted to compile.
$gcc a.c –o a.exe
$./a.exe
100 apples$
$

To know what’s happening behind the scene, do this:
[kongkon@cadbury ~]$ gcc -v a.c
Reading specs from /usr/lib/gcc/i386-redhat-linux/3.4.3/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=i386-redhat-linux
Thread model: posix
gcc version 3.4.3 20050227 (Red Hat 3.4.3-22.1)
 /usr/libexec/gcc/i386-redhat-linux/3.4.3/cc1 -quiet -v a.c -quiet -dumpbase a.c  -auxbase a -version -o /tmp/ccfWiYm9.s
ignoring nonexistent directory "/usr/lib/gcc/i386-redhat-linux/3.4.3/../../../../i386-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/gcc/i386-redhat-linux/3.4.3/include
 /usr/include
End of search list.
GNU C version 3.4.3 20050227 (Red Hat 3.4.3-22.1) (i386-redhat-linux)
compiled by GNU C version 3.4.3 20050227 (Red Hat 3.4.3-22.1).
GGC heuristics: --param ggc-min-expand=98 --param ggc-min-heapsize=128313
 as -V -Qy -o /tmp/ccyJwUTb.o /tmp/ccfWiYm9.s
GNU assembler version 2.15.92.0.2 (i386-redhat-linux) using BFD version 2.15.92.0.2 20040927
 /usr/libexec/gcc/i386-redhat-linux/3.4.3/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc/i386-redhat-linux/3.4.3/../../../crt1.o /usr/lib/gcc/i386-redhat-linux/3.4.3/../../../crti.o /usr/lib/gcc/i386-redhat-linux/3.4.3/crtbegin.o -L/usr/lib/gcc/i386-redhat-linux/3.4.3 -L/usr/lib/gcc                                                                /i386-redhat-linux/3.4.3 -L/usr/lib/gcc/i386-redhat-linux/3.4.3/../../.. /tmp/cc yJwUTb.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s                                                                              --no-as-needed /usr/lib/gcc/i386-redhat-linux/3.4.3/crtend.o /usr/lib/gcc/i386-redhat-linux/3.4.3/../../../crtn.o
[kongkon@cadbury ~]$
Understood? It’s really hard to understand. Let me explain a little, and then things will look simpler. The –v switch to gcc explains what gcc has done with the compilation process. Now, first of all what is gcc? gcc is the compiler like everyone would say. Yes, it is the compiler. Actually it is a wrapper, which calls different programs to compile the C program: if you look at the –v output more closely you will see that, gcc calls "cpp", the C preprocessor first, then "cc1", the C compiler, and then "as", the assembler. As an output we get the object file, the same what we get by running “gcc –c a.c”. Here we take help of the linker, "ld", to link a.o with our library for printf, since we have not written code of printf() of our own. We need to link our a.o with libc.so for printf code, as specified by -lc. This outputs a.exe, out executable. Run this, and enjoy 100 apples.

Let’s do every thing by hand. Let’s call all of them one by one. First the C preprocessor, cpp.
[kongkon@cadbury ~]$ cpp a.c
# 1 "a.c"
# 1 ""
# 1 ""
# 1 "a.c"
# 1 "a.h" 1
# 2 "a.c" 2
main()
{
 printf("%d apples",100);
exit(19);
}
[kongkon@cadbury ~]$
cpp by default dumps the output in the console, redirect it to a file, call it a.i.
[kongkon@cadbury ~]$ cpp a.c -o a.i
[kongkon@cadbury ~]$
[kongkon@cadbury ~]$ ls a.*
a.c  a.h  a.i
[kongkon@cadbury ~]$

Next is the C compiler, cc1.
[kongkon@cadbury ~]$ cc1 a.i
-bash: cc1: command not found
[kongkon@cadbury ~]$
Oops! Bash did not find  cc1, he does not know where is cc1. Take the help of gcc itself to find where cc1 is. Do this:
[kongkon@cadbury ~]$ gcc -print-prog-name=cc1
/usr/libexec/gcc/i386-redhat-linux/3.4.3/cc1
[kongkon@cadbury ~]$
Next, compile a.i, not a.c.
[kongkon@cadbury ~]$ /usr/libexec/gcc/i386-redhat-linux/3.4.3/cc1 a.i
 main

Execution times (seconds)
 parser                :   0.01 (100%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall
 TOTAL                 :   0.01             0.00             0.01
[kongkon@cadbury ~]$
[kongkon@cadbury ~]$ ls a.*
a.c  a.h  a.i  a.s
This produces a.s.
Now, call the assembler, to create the object file, a.o.
[kongkon@cadbury ~]$ as a.s -o a.o
So, we have the object file here, a.o.
[kongkon@cadbury ~]$ ls a.*
a.c  a.h  a.i  a.o  a.s
[kongkon@cadbury ~]$
Now, call the linker program, ld.
[kongkon@cadbury ~]$ ld -o a.exe a.o -e main -lc -dynamic-linker /lib/ld-linux.so.2
[kongkon@cadbury ~]$ ls a.*
a.c  a.exe  a.h  a.i  a.o  a.s
[kongkon@cadbury ~]$
So, here we have the executable binary a.exe.
Run this and you will see the same output as we did in our first step.
[kongkon@cadbury ~]$ ./a.exe
100 apples[kongkon@cadbury ~]$
 Check whether the program exited successfully.
kongkon@cadbury ~]$ echo $?
19 
[kongkon@cadbury ~]$


So, we have successfully compiler a C program. Happy programming.

The thread ends here.

Wednesday, December 03, 2014

rpm spec file magic

In Unix flavored Operating Systems various software packages are packaged along with the source file in the form of an rpm package. The rpm package contains the source rpm and the binary rpm, along with optional other dependent tools rpm packages that is needed for the main binary rpm to work. In earlier days it was achieved in the form of an tarball, which contains the configure script. The configure scripts calls the Makefile to build the final binary package that's finally ready to installed on that platform.


Here I plan to discuss some of the tricks I have learned in the rpm spec file.
The spec file contains various sections:
a) %description
b) %prep
c) %build
d) %install
e) %files
f) %package  ## This is optional section
g) %clean
h) %changelog

Some of these sections are self explanatory, like the %description, %clean and %changelog section. The most interesting things happen in the %build, %install and %files section.
In the %build and %install section you can write anything that you can write in a bash script, they understand the bash syntax and executes them.
The %files section however does not understand the bash scripting language, and only understand the rpm macros.
If you want to include addition packages in the same package.spec.in file, then the %package section comes handy, and you include a %package section for each additional rpm package you intend to produce.


The basic structure goes like this:
# This is a comment
Name:          my-package
Version:        1.0
Release:        %RPM_RELTAG%
Summary:     my package update release
Source:         %RPM_SOURCE%
License:        License info
Vendor:         The source code belong to
Packager:      The repackaging is done by
Group:          System Environment/Libraries
Requires:       my-package-tools
BuildRequires:  coreutils                  ##dependent packages needed to build this package

%description
This provides the my package which is very important for everyone.


%define debug_package %{nil}
## This is how you define a local variable (called prefix)
%define prefix  /lib/firmware/important/


%define MY_FILE_LIST %{expand:%( \
FW="" \
FW+=" a.bin" \    ## a file
FW+=" b.bin" \     ## b file
FW+=" c.bin"        ##c file
##FW+=" c1.bin" \   ##c1 file
FW+=" d.bin"        ##d file
FW+=" e.bin"    ##e file
FW+=" f.bin"    ## f file
echo $FW \
)}

%global flist() %{expand:%( \
files="%*" \
if [ -n "%{?1}" ] ; then \
for pkg in $files  \
do \
  echo "%%{prefix}/$pkg" \
done \
fi \
)}

%prep
%setup -n src



## The % build section is also common between the base rpm package and additional (tools) rpm package

%build
RM=rm
MD5SUM=/usr/bin/md5sum 
## md5sum is part of coreutils, hence it's mentioned in the BuildRequires

cd fw/
${RM} -fr checksum.txt

for FW in %{MY_FILE_LIST}; do \
        echo ${FW}; \
        ${MD5SUM} ${FW} >> checksum.txt; \
done

%install
install -d ${RPM_BUILD_ROOT}%{prefix}/
cd fw/



## This will install all the a.bin, b.bin etc files into the right place, no need list one by one
for FW in %{MY_FILE_LIST}; do \
        install ${FW} ${RPM_BUILD_ROOT}%{prefix};
done
install checksum.txt ${RPM_BUILD_ROOT}%{prefix}

## The tools rpm that this spec file produces installs the my_special_tool as part of it, and
## the % install section is common for both the base package and the addition (tools) package
# Install Tools files
install -d ${RPM_BUILD_ROOT}%{prefix}
cd ../tools
install -m 0755 -D my_special_tool ${RPM_BUILD_ROOT}%{prefix}

%files
%defattr(0664,root,root)
## This is the magic
% flist %MY_FILE_LIST
## Otherwise you have to install each individual file separately like
#% {prefix}/a.bin
#% {prefix}/b.bin
#etc

## Now comes information about the additional package
##
## Tools package
##

%package tools
Summary:        %{name} deployment tools
Group:          System Environment/Base
Requires:       special-tools >= 1.4-5

%description tools
This package provides the special deployment tool for the my software.

%files tools
%defattr(-,root,root,-)
%attr(700,root,root) %{prefix}/my_special_tool
%doc %{_mandir}/man8/my_special_tool.8.gz

%clean
rm -rf ${RPM_BUILD_ROOT}

%changelog
* Wed Dec 03 2014 Kongkon Jyoti Dutta
        - ABC-123 Releasing my special tool to the world


Tuesday, June 10, 2014

How to update the drive firmware in Linux



echo "Using firmware file $fwfile for upgrading $product on device $x…"

The process to download in Solid State Drive and Hard Disk Drive is a little different. In case of SDD we can burn the firmware in one command, but in case of HDD we need to write in a loop since there is a limitation of 0x80000 bytes on VFS module system call.



           if [ "$rev" != "$target_fw_ver" ]; then
               echo "Upgrading $disk_type firmware to version $target_fw_ver on $x i.e.$sg_dev..."
               if  [ "$disk_type" = "ssd" ]; then
                   sg_write_buffer --in=${fwfile} --mode=5 --id=0 $sg_dev
                   if [ $? -ne 0 ]; then
                       echo "Failed to upgrade SSD firmware on $x i.e.$sg_dev to version $target_fw_ver!" >&2
                       exit 1
                   fi
               else
                   # hdd firmware upgrade
                   bytes=`ls -l $fwfile | awk '{ print $5; }'`
                   start=0
       #length = 0x80000 Bytes
                   length=524288
                   while [ $start -lt $bytes ]; do
                       if let 'start+length>bytes'; then
                           let 'length=bytes-start'
                       fi
                       sg_write_buffer --in=$fwfile --skip=$start --offset=$start --length=$length --mode=0x7 --id=0 $sg_dev
                       if [ $? -ne 0 ]; then
                           echo "Failed to upgrade HDD firmware $x i.e.$sg_dev to version $target_fw_ver!" >&2
                           exit 1
                       fi
                       let start+=length
                   done
               fi

Wednesday, October 31, 2012

Let's see what you installed

Google+
To install packages in Linux:
Packages can be installed using yum, or rpm. Each one has it's own internal database that list what is already installed into the system.

To install a package using yum:
#yum install

To install a package using rpm:
#rpm -ivh
#rpm -Uvh

To check what is already installed:

To check what is yum installed:
#yum list | grep


To check what is rpm installed:
#rpm -qa | grep



HTH
--kongkon

Tuesday, October 23, 2012

How to grep in shell script...

The task is there is a file containing one column of entries. Write a script to compare the o/p of one command and check whether the output matches with any row of that file (supported.txt file).

$cat supported.txt
SAS2308_2(C1)
SAS2308_2(D1)

Assume $devInfo gives us a string that contains like the rows of support.txt file. If there is a match between the o/p of $devInfo in that file, then do nothing, else warn.

checkSupportedFwDev() {
        local supportedControllerList=`cat supported.txt`
        #Get the controller name from $devInfo and compare that with $supportedControllerList
        local currentController=`echo "${devInfo}" | grep "Controller" |grep -v Number | awk '{ print $NF }'`
        #echo "currentController=[$currentController]"
        local supported=`echo "${supportedControllerList}" | grep $currentController`
        if [ -z ${supported} ]
        then
                echo "Warning: This adapter [${currentController}] is not officially supported."
        fi
        }

Another approach to do the same:

checkSupportedFwDev() { 
        #Get the controller name from $devInfo and compare that with $supportedControllerList
        local currentController=`echo "${devInfo}" | grep "Controller" |grep -v Number | awk '{ print $NF }'`

        if ! grep "^${currentController}\$" supported.txt >/dev/null 2>&1;
        then
                echo "Warning: This adapter [${currentController}] is not officially supported."
        fi

}

Which approach you like and why?





Friday, October 12, 2012

Vi tricks

How to set the line numbers into vi editor?
Everyone knows this:
a) cd
-- go to home directory
b) edit(create if not there) a file called .exrc, and all this line
set nu
or set number
Simple.

But, what I al now looking at is how to set the vi line numbering in only a special work directory, say /home/kdutta/mywork. I do not want to set vi line numbering to all directories, at times this is annoying.
Putting a .exrc file into /home/kdutta/mywork/.exrc does not seem to work, here, even if I source it.

Do you know, how to do that?

Thursday, September 27, 2012

Difference between $variable and ${variable} in (bash) shell scripting

Many often we do shell scripting, but small small ignorance at times cost a lot. Here is an example of what we mean and what it become.
[/tmp]$ cat try.sh #! /bin/sh a=12 b=34 echo $a_$b echo ${a}_$b [vivarkey@/tmp]$ sh try.sh 34 12_34 [/tmp]$


In the above shell script we intended to print "variableA_variableB", in the shell script on last but one line. But since we missed the braces around the variable it actually truncated the previous variable along with the '-' symbol.

NB: This code snippet is tried in bash shell on Linux, on mac it gives different result.

HTH
Kongkon

Playing with RPM

Ever wondered after running the rpm --install (or rpm -ivh) command what happened, what sort of files created in the file system.

To find out the list of files that an already installed rpm spawned:
rpm -ql
NB: there is no .rpm after the package name here in this command.

[root@localhost release]# rpm -qa|grep lsifw-tools-xrtx
lsifw-tools-xrtx-1-1.xrtx.1872.noarch
[root@localhost release]# rpm -ql lsifw-tools-xrtx-1-1.xrtx.1872.noarch
/lib/firmware/lsi/.NOT_RELEASE_DIR
/lib/firmware/lsi/FirmwareID.sh
/lib/firmware/lsi/xrtx_lsifw.sh
/usr/share/man/man8/xrtx_lsifw.8.gz
[root@localhost release]# 



To find out the list of files that an rpm will generate once you install the rpm:
rpm -qlp

[root@localhost tmp]# rpm -qlp /tmp/lsifw-tools-xrtx-1-1.xrtx.1872.src.rpm
lsifw-tools-xrtx-source.spec
lsifw-tools-xrtx.tgz
[root@localhost tmp]#


HTH
Kongkon

Monday, June 18, 2012

C++ Library Problem

Google+

C++ Library Problem

You have a library provided by the vendor. All you have is header files and library files. Library contains the class "Shape" and there is whole hierarchy tree (I mean classes which derive from this base class).

Now you want to add some function "getArea" (not originally present in the class or any of its derived class) in the class "Shape" , you don't have the source code.
Using this library, you have written a lot of code. Now, you have to make some changes so that, any object of "Shape" class (or its derived class) will be able to call this function.

With your strategy, you should be able to override the definition of this function in the derived class.

http://www.careercup.com/question?id=13872673


Wednesday, December 14, 2011

A simple C program

Let's talk about simplicity. And let's look at a simple C program today. Why not, every day we deal with complex problem, so let's talk about a simple C program now. Here is the program;

main()

{

    char *p1="name";

    char *p2;

    p2=(char*)malloc(20);

    memset (p2, 0, 20);

    while(*p2++ = *p1++);

    printf("%s\n", p2);

}

Well, what does this program do. This is the topic of today's blog.

Ans:

Looks like this program output's the string name , but that's not true.

What do you think about this program?

Write your comments about it.

Thursday, November 24, 2011

All about C++ templates





Templates in C++ can be of class template or function template.
A template is used as a mechanism to generalize the parameter type we pass to either the class or function. This extends the function overloading concept of C++. Template takes the C++ concept of polymorphism to the next level.


Here is a example of function templates:
Let's say we have a swap function that swaps two variables of type T.

void f(int a, int b, float m, float n)
{
    swap(a, b);      //swap two integer values
    swap(m, n);      //swaps two float values
}

We can write a template function to do this as below:

template <class T>
void swap (T &x, T &y)
{
    T temp = x;
    x = y;
    y = T;
}

Similarly we have class template where we can pass any type of parameter using the template T.

template < class T>
class vector
{
     T *v; //type T vector, T can be int, float, anything
     int size;
   public:
     vector (int m)
     {
     v = new T[size = m]; // v is an array of type T
     //initialize the array
       for (int i = 0; i < size; i++)
         v[i] = 0;
    }

}


This is an example of a class vector which initialize an object of type T of array. Invoke it this way:
     vector < int> v1(10);    //a vector class of int
     vector < float> v2(20);    //a vector class of float



Q1. Find the o/p of the code snippet:
template < class T, int l=7> class Foo {
     static const T k = l;
     int q;

   public:
     Foo(int x = l) : q(x)
     { }
     T GetQ() const { return q; }
}

void f() {
     Foo < long, 9> foo(10);
     std :: cout << foo.GetQ();

}

Ans:
Explaination:
Default values for template parameters

Template parameters may have default values, and when instantiating the template these values can be omitted. Here’s an example:

template <typename T=int, int N=10>
class Foo {
};

Foo<float, 42> foo1;
Foo<double> foo2;
Foo<> foo3;

Note specifically the strange syntax for the definition of foo3, which means that it instantiates the Foo template with all parameters assigned their default values. Default values may only be specified for class templates.

Q2. What is STL?
Ans: STL is the C++ Standard Template Library. Instead of writing your own, you can use templates from STL just like other library functions that we use from any other C/C++ library. It is a collections of class templates and function templates. We sahould use template library as it is bug free rather than writing our own like inventing the wheel again.


In tehnical terms:
The Standard Template Libraries (STL's) are a set of C++ template classes to provide common programming data structures and functions such as doubly linked lists (list), paired arrays (map), expandable arrays (vector), large string storage and manipulation (rope), etc. The STL library is available from the STL home page. This is also your best detailed reference for all of the STL class functions available. STL can be categorized into the following groupings:

Here is the greatest post about C++ Templates:
http://eli.thegreenplace.net/2011/04/22/c-template-syntax-patterns/

Q3. What is partial specialization or template specialization?

Q4. How can you force instantiation of a template?

Q5. What is an iterator?

Q6. What is an algorithm (in terms of the STL/C++ standard library)?

Saturday, October 22, 2011




Hello World!

How about compiling a C programming right from the browser itself.
Here it is:

Best C/C++/Data Structure Programming books




C/C++ Programming Questions This blog is for C/C++ Programming
Here is my collection of some of the best Programming books.

No 1 has to be this:






Then comes the rest of them.
When it comes to data structure there is a book written in simple English, very easy to comprehend the basic fundamentals of computer science.


There are couple of C++ books. But I find this to be the best:


        C++
        How to Program by Deitel and Deitel


And here a list of best Linux programming books:
a) Linux Kernel



b) Linux Device Driver Programming


Enjoy, happy reading.

Regards,
Kongkon


Friday, October 21, 2011

Free Linux Machine with C compiler




Hello World!
Many of us wanted their own Linux machine to do some C programming or at least to get a feel of the Linux Operating System.

Here is a Linux machine which can be accessible over the internet free of cost only for you :-). 

Just type the following URL in the browser and here you are in your own Linux machine:


http://bellard.org/jslinux/


This is an amaizing work by Bellard. There is also a clipboard facility to copy/paste your work back and forth between your local system and the Linux machine.

Copy your file to the clipboard:
cat myfile > /dev/clipboard

Explore this machine, and I am sure you will have lots of fun. The best part is that there is a C Compiler to test your own C programs.
It's a tiny version of a C compiler called "tcc".


To have a deep dive into the booting process of this OS, look at the booting sequence:

Linux version 2.6.20 (bellard@voyager) (gcc version 3.4.6 20060404 (Red Hat 3.4.6-9)) #2 Mon Aug 8 23:51:02 CEST 2011
BIOS-provided physical RAM map:
sanitize start
sanitize bail 0
 BIOS-e801: 0000000000000000 - 000000000009f000 (usable)
 BIOS-e801: 0000000000100000 - 0000000001000000 (usable)
16MB LOWMEM available.
Entering add_active_range(0, 0, 4096) 0 entries of 256 used
Zone PFN ranges:
  DMA             0 ->     4096
  Normal       4096 ->     4096
early_node_map[1] active PFN ranges
    0:        0 ->     4096
On node 0 totalpages: 4096
  DMA zone: 32 pages used for memmap
  DMA zone: 0 pages reserved
  DMA zone: 4064 pages, LIFO batch:0
  Normal zone: 0 pages used for memmap
DMI not present or invalid.
Allocating PCI resources starting at 10000000 (gap: 01000000:ff000000)
Detected 3.333 MHz processor.
Built 1 zonelists.  Total pages: 4064
Kernel command line: console=ttyS0 root=/dev/ram0 rw init=/sbin/init notsc=1
Initializing CPU#0
Disabling TSC...
PID hash table entries: 64 (order: 6, 256 bytes)
Console: colour dummy device 80x25
Dentry cache hash table entries: 2048 (order: 1, 8192 bytes)
Inode-cache hash table entries: 1024 (order: 0, 4096 bytes)
Memory: 11956k/16384k available (1265k kernel code, 4040k reserved, 324k data, 124k init, 0k highmem)
virtual kernel memory layout:
    fixmap  : 0xffffc000 - 0xfffff000   (  12 kB)
    vmalloc : 0xc1800000 - 0xffffa000   ( 999 MB)
    lowmem  : 0xc0000000 - 0xc1000000   (  16 MB)
      .init : 0xc0290000 - 0xc02af000   ( 124 kB)
      .data : 0xc023c503 - 0xc028d854   ( 324 kB)
      .text : 0xc0100000 - 0xc023c503   (1265 kB)
Checking if this processor honours the WP bit even in supervisor mode... Ok.
Calibrating delay using timer specific routine.. 20.22 BogoMIPS (lpj=101116)
Mount-cache hash table entries: 512
CPU: After generic identify, caps: 00000010 00000000 00000000 00000000 00000000 00000000 00000000
Intel Pentium with F0 0F bug - workaround enabled.

CPU: After all inits, caps: 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Compat vDSO mapped to ffffe000.
CPU: Intel Pentium MMX stepping 03
Checking 'hlt' instruction... OK.
NET: Registered protocol family 16
Setting up standard PCI resources
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 1024 (order: 0, 4096 bytes)
TCP bind hash table entries: 512 (order: -1, 2048 bytes)
TCP: Hash tables configured (established 1024 bind 512)
TCP reno registered
checking if image is initramfs...it isn't (bad gzip magic numbers); looks like an initrd
Freeing initrd memory: 2048k freed
Total HugeTLB memory allocated, 0
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered (default)
Real Time Clock Driver v1.12ac
JS clipboard: I/O at 0x03c0
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing disabled
serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16450
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
loop: loaded (max 8 devices)
TCP cubic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
Using IPI Shortcut mode
Time: pit clocksource has been installed.
RAMDISK: ext2 filesystem found at block 0
RAMDISK: Loading 2048KiB [1 disk] into ram disk... | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ | / - \ done.
EXT2-fs warning: maximal mount count reached, running e2fsck is recommended
VFS: Mounted root (ext2 filesystem).
Freeing unused kernel memory: 124k freed
 


Enjoy this. We shall explore more later.







RIP Dennis Ritchie




Dennis Ritchie

 

The great Dennis Ritchie, the creator of C Programming Language, the reason behind which this programming blog exist today, died on 12th October 2011, at the age of 70.  

Here is a small C program as a tribute to Dennis Ritchie.

 

main() {

        printf("1941: Hello World!\n");

        printf("2011: RIP Dennis Ritchie\n");

}