Building Linux Kernel

1) Obtain Linux Source code
——-> 1.1) Obtain as a single file

Kernel is hosted at kernel.org. You can download the latest kernel from
ftp://ftp.kernel.org/pub/linux/kernel/

$ wget -c https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.13.5.tar.xz

——-> 1.2) Clone using git

$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git linux-git

2) Configure
——-> 2.1) Old Config

$ make oldconfig

——-> 2.2) Custom Config

$ make menuconfig

3) Building

$ make -j4

4) Installing

# make modules_install install

Building Busybox to get root file system to Linux kernel

Previously, we have built linux kernel, Qemu and booted them using qemu.

But, in previous attempts, we loaded a simple hello world program in the kernel.

Now, we can try to create a further more improved linux system.

For that, we need to get a Root FileSystem.

Here is a explanation on what is a Root File System.

So, we need a set of utilities according to our need to run using the linux kernel.

To create all these utilities, it will take certain effort. To make it simple, we can use a project called,

BusyBox – The Swiss Army Knife of Embedded Linux

Busybox, is a set of utilities, compiled into a single executable and shown as multiple executable’s are available, by creating soft links with different names.

TODO : Here is a example of how it can be achieved.

Creating Busybox based Root FS.

Here is an overview of what we are going to do.

  1. Download the busybox source.
  2. Configure
  3. Build
  4. Create Root File System image
  5. Load using Qemu.

Here, its detailed.

1) Download the busybox source.

Busybox source can be downloaded from busybox FTP site, here.

mkdir src;
cd src;
wget -c http://www.busybox.net/downloads/busybox-1.21.0.tar.bz2
tar -xf busybox-1.21.0.tar.bz2
cd busybox-1.21.0;

2) Configure busybox

BusyBox has menu based configuration. Any ways, to make it simpler to configure, busybox provides a set of configurations, as below.

make target Description
help Show the complete list of make options
defconfig Enable a default (generic) configuration
allnoconfig Disable all applications (empty configuration)
allyesconfig Enable all applications (complete configuration)
allbareconfig Enable all applications, but no subfeatures
config Text-based configurator
menuconfig N-curses (menu-based) configurator
all Build the BusyBox binary and documentation (./docs)
install Build and make it ready to install at INSTALL PREFIX directory (./_install)
busybox Build the BusyBox binary
clean Clean the source tree
distclean Completely clean the source tree
sizes Emit the text/data sizes of the enabled applications

Out of these, we are going to use, defconfig.

export ARCH=arm;
export CROSS_COMPILE=arm-none-linux-gnueabi-;
make defconfig;

Now, we need to customize this busybox, so that we can run it along with linux kernel as individual.

Build busybox as a static library, as we wont have libc in the linux kernel we are booting.

This can be done by following.

make menuconfig
# Enable   Busybox Settings--->Build Options---> [*] Build BusyBox as a static binary (no shared libs)

3) Build busybox

Now, we can build the busybox, using make install command

make -j4 install

Now,after build, we would have got the busybox install directory at busyboz-1.21.0/_install/

[Update] Note : If the build fails with error as below, Source

networking/lib.a(inetd.o): In function `register_rpc':
inetd.c:(.text.register_rpc+0x2c): undefined reference to `pmap_unset'
inetd.c:(.text.register_rpc+0x42): undefined reference to `pmap_set'
networking/lib.a(inetd.o): In function `prepare_socket_fd':
inetd.c:(.text.prepare_socket_fd+0x52): undefined reference to
`bindresvport'
collect2: error: ld returned 1 exit status
make: *** [busybox_unstripped] Error 1

Disable RPC support as below

Via menuconfig:
 Networking Utilities  --->
   []   Support RPC services

4) Create Root Filesystem image.

[TODO] As we have seen, initramfs supports newc file format. We are going to create a cpio archive to hold the root filesystem.

$ mkdir ../init/
$ cd _install;
$ find . | cpio -o --format=newc > ../../init/rootfs.img
$ cd ../../init;
$ file rootfs.img
   ASCII cpio archive (SVR4 with no CRC)
$ cd ../

5) Booting using initramfs we have built.

Now, we have the kernel built previously, rootfs that we have built now.

Lets boot it using qemu

$ qemu-system-arm -M versatilepb -kernel zImage -initrd init/rootfs.img -append "root=/dev/ram rdinit=/bin/sh"

The system would have booted and the shell prompt would be shown.
You can try ls on this to find something like this..

/ # ls
bin    dev    linuxrc    root    sbin    usr
/ #

Voila!! Very basic utility is working!!

Building and Booting Linux using Qemu

Previously, we have Built and Booted U-Boot through Qemu.
Now, let us build and boot Linux using Qemu.
Get the latest kernel source from https://www.kernel.org/
I took Stable 3.9.3 as on writing.

mkdir original
mkdir src
cd original
wget -c https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.9.3.tar.xz
cd ../src
tar -xf ../original/linux-3.9.3.tar.xz

Let us define the enviroinment variables that kernel build uses..

export ARCH=arm
export CROSS_COMPILE=arm-none-eabi-

Now, Let us configure this kernel build for Versatile Express.
This config is available at

./arch/arm/configs/vexpress_defconfig

For list of available configs, you can further explore in arch/ directory

make vexpress_defconfig;

Now, We need to make few changes, to make this kernel usable for our
needs in latter times.For this, We can remov module support (for
simplicity) and enabled EABI support as a binary format (allowing also old ABI).
This is necessary to run software compiled with the CodeSourcery toolchain.
Enable

kernel Features ---> Use the ARM EABI to compile the kernel and  
Kernel Features ---> Allow old ABI binaries to run with this kernel 

make menuconfig

We are all set to build the kernel. Now run

make -j4 all

Here, -j4 informs the build to use 4 build Jobs == Number of cores in your machine.
It will take some time to build.

Meanwhile, let us see what is the root file system and why do we need one, and
how to boot the kernel with a simple program.

Here is a definition of Root File System from Linux Information project

	
The root filesystem is the filesystem that is contained on the same 
partition on which the root directory is located, and it is the 
filesystem on which all the other filesystems are mounted (i.e.,
logically attached to the system) as the system is booted up 
(i.e., started up). 

The exact contents of the root filesystem will vary according to the 
computer, but they will include the files that are necessary for 
booting the system and for bringing it up to such a state that
the other filesystems can be mounted as well as tools for fixing a 
broken system and for recovering lost files from backups. The 
contents will include the root directory together with a minimal set 
of subdirectories and files including /boot, /dev, /etc, /bin, /sbin 
and sometimes /tmp (for temporary files).

Hope the kernel would have been built and ready by now.
The build should have completed with a message like,

  OBJCOPY arch/arm/boot/zImage
  Kernel: arch/arm/boot/zImage is ready
rajkumar.r@14:56:56:~/kernel/3_linux_qemu/src/linux-3.9.3$

The kernel will be available at

arch/arm/boot/zImage

Now, we can try to boot the kernel using qemu as below.

qemu-system-arm -M vexpress-a9 -kernel arch/arm/boot/zImage -append\
 "console=tty1"

-M vexpress-a9 : Emulate V Express Board
-kernel arch/arm/boot/zImage : Use this file as kernel
-append "console=tty1" console acts as the tty1
- generall Linux uses tty interface to display console messages

Here, you can read what is tty

But, now, the kernel will end up in panic telling something like,

VFS: Cannot open root device "(null)" or unknown block(0,0): error -6
Please append a correct "root=" boot option;
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown 
block(0,0)

Now, What we discussed about File system comes useful.
As the kernel message is telling, we are missing a root file system. To build
a complete set of root file system is a complex task [ Relatively 😛 ] So, we
are going to generate a simple file system.

Creating a Simple Filesystem :

create file test.c in the src directory with the below content.

#include 

void main() {
	while(1) 
		printf("Hello World!\n");  
}

As the program looks, it will run continouesly as kernel expects the first
program to run forever. Compile this program, using cross compiler for Arm
running Linux
[ This is not same as bare metal toolchain. Bare metal toolchain is for ARM
which has no OS. i.e like arm-none-eabi-, which we have exported while
building kernel.]

arm-none-linux-gnueabi-gcc -static test.c -o test

This will Compile and creates an ELF, staticaly liked to all required code,
in a single binary. We need a Filesystem, but we have a binary file now.
So we need to generate Filesystem using some tool. Before that, we should know,
What is initramfs?

https://wiki.ubuntu.com/Initramfs

initramfs, as the name tells, its the Initial Ram File System. This is
introduced for Linux 2.6 kernel, before which initrd is being used.

From ubuntu Wiki

The key parts of initramfs are:

1) CPIO archive, so no filesystems at all are needed in kernel. 
   The archive is simply unpacked into a ram disk.
2) This unpacking happens before do_basic_setup is called. This means 
   that firmware files are available before in-kernel drivers load.
3) The userspace init is called instead of prepare_namespace. All 
   finding of the root device, and md setup happens in userspace.
4) An initramfs can be built into the kernel directly by adding it to 
   the  ELF archive under the section name .init.ramfs initramfs' can be
   stacked. Providing an initramfs to the kernel using the traditional
   initrd mechanisms causes it to be unpacked along side the initramfs'
   that are built into the kernel.
5) All magic naming of the root device goes away. Integrating udev into 
   the initramfs means that the exact same view of the /dev tree can be 
   used throughout the boot sequence. This should solve the majority of 
   the SATA failures that are seen where an install can succeed, but the
   initrd cannot boot.

This initramfs uses a format called newc. Now, to get the cpio archive,
initramfs from the binary, run the below command.

echo test | cpio -o --format=newc > rootfs

Now, we have the zImage kernel and rootfs – Initramfs. Let us load the kernel

qemu-system-arm -M vexpress-a9 -kernel linux-3.9.3/arch/arm/boot/zImage\
-initrd rootfs -append "root=/dev/ram rdinit=/test"

Here, 

-initrd rootfs : Qemu option which tells, rootfs is the Filesystem 
binary image.

root=/dev/ram and 
rdinit=/test are kernel options passed to the kernel we load.

rdinit=/test tells the kernel to run "test" executable we built as init.

Now, we can see the “hello world” being printed.

Voila!! Done!!

Cross Compiling – Reblog

Original Blog : http://baruch.siach.name/blog/posts/introduction_to_cross_compilation_part_1/

Introduction to Cross Compilation, Part 1

This post is the first in a series on cross compilation. In this series I’ll introduce the concept of cross compilation, and how to used it. Although there are many different uses for cross compilation, I’ll focus in this series in its use for embedded Linux systems development.

What is Cross Compilation?

When you develop a desktop or server application, almost always the development platform (the machine that runs your compiler) and the target platform (the machine that runs your application) are the same. By “platform” I mean the combination of CPU architecture, and Operating System. The process of building executable binaries on one machine, and run them on another machine when the CPU architecture or the Operating System are different is called “cross compilation”. A special compiler is needed for doing cross compilation that is called “cross compiler“, and sometimes just “toolchain”.

For example, desktop PC application developers for Windows or Linux can build and run their binaries on the very same machine. Even developers of server applications generally have the same basic architecture and Operating System on both their development machine and server machine. The compiler used in these cases is called “native compiler”.

On the other hand, developers of an embedded Linux application that runs on a non PC architecture (like ARM, PowerPC, MIPS, etc.) tend to use a cross compiler to generate executable binaries from source code. The cross compiler must be specifically tailored for doing cross compilation from the development machine’s architecture (sometimes called “host”), to the embedded machine’s architecture (called “target”).

Note: cross compilation is only needed when generating binary executables from source code written in a compiled language, like C or C++. Programs written in interpreted language, like Perl, Python, PHP, or JavaScript, do not need a cross compiler. In most cases interpreted programs should be able run unchanged on any target. You do need, however, a suitable interpreter running on the target machine.

What is Cross Compilation Good for?

I have covered above one reason for doing cross compilation, that is, the target machine has a different CPU architecture that the development host. In this case cross compilation is necessary because the binaries that the native compiler generates won’t run on the target embedded machine.

Sometimes cross compilation is not strictly necessary, but native compilation in not practical, or inconvenient. Consider, for example, a slow ARM9 based target machine running Linux. Having the compiler run on this target will make the build process painfully slow. In many cases target machine is just under-powered, in terms of storage and RAM, for the task of running a modern compiler.

Practically speaking, almost all embedded Linux development is being done with cross compilers. Strong PC workstation machines are used as development hosts to run the development environment (text editor, IDE), and the cross compiler.
Obtaining a Cross Compiler

The easiest way to obtain a cross compiler is to download a ready made pre-built one. Besides being easy to obtain a pre-built binary toolchain is the most useful for the general case of building a kernel and a userspace filesystem. Some special cases require a specially tailored toolchain built from source. I’ll show how to build a toolchain from source in the next post.

A short terminology note: in the following text I use the terms “cross compiler” and “toolchain” interchangeably. The have the same meaning in this context. The term “toolchain” seems to be more popular, however.

Sourcery

The most well known source of pre-built cross compilers is the embedded software division of Mentor Graphics, formerly known as CodeSourcery, an independent company that Mentor has acquired in 2010. They release the “Sourcery CodeBench Lite Edition” free of charge. Sourcery CodeBench is a collection of cross compilers for several CPU architectures, including ARM, PowerPC, MIPS, and Intel x86 among the others. For each architecture there are a number of target options. The one you need for embedded Linux work is the “GNU/Linux release”. Always select the latest version, unless you have a very good reason to avoid it. Then, there are a few packaging formats to choose from. I prefer the “IA32 GNU/Linux TAR” format. Installing it is just a matter of extracting the tar file in the /opt directory. For example, to install the latest MIPS toolchain do as root

tar xjf mips-2011.09-75-mips-linux-gnu-i686-pc-linux-gnu.tar.bz2 -C /opt
One big advantage of Sourcery’s toolchains is that those making them, former CodeSourcery employees, are deeply involved in upstream development of the GCC compiler.

Linaro

The Linaro organization also releases pre-built cross compilers for their target platform, newer ARM processor based on Cortex-A. Download the latest version from here. You need the “Linux binary” one.

Using the Cross Compiler

This is just a quick peek at cross compiling for the impatient new embedded Linux coder. I’ll come back to this issue later in some greater depth.

First, put your newly installed toolchain in your path. For example, the Sourcery MIPS toolchain mentioned above needs the following command:

export PATH=$PATH:/opt/mips-2011.09/bin

Create a simple “Hello World” program, and save it in hello.c:

#include 
int main (void) {
    printf ("Hello World!\n");
    return 0;
}

Compile your program using the MIPS toolchain as follows:

mips-linux-gnu-gcc -Wall -o hello hello.c

Copy the resulting hello binary file to you target machine and run it there. If all goes well you should see the expected output.

There are many details to get wrong here, ranging from ABI issues, to C library and kernel version compatibility. I’ll cover some of these issues in future posts.

Hacking BSNL router DNA-A211

Everyone who has Internet connection need a kind of router and each machine needs some operating system code to run that.

DNA-A211 is a router provided by BSNL in India, and It does have a OS Running inside and to the grace of GNU its running GNU/Linux inside, having Minimal BusyBox Pre-loaded..

So, How do I access this machine??

We all usually access this using the Web interface provided by BSNL, generally running on port number 80.
To access that, access this IP through any web browser..

http://192.168.1.1/ 

Screenshot from 2013-05-12 18:21:06
So, If its not this IP, How can I find the IP of my router?

Yeah, sure, there are many chances this IP can be different and in that case, you can find it using this command in linux shell

 raj@raj:~$ arp
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.1.1              ether   00:1b:57:a2:a6:a0   C                     wlan0
raj@raj:~$ 

Okay. I got it and able to access this through the web interface.. But how can I access the shell??

Even though it has linux under the hood and has a minimal busybox, it doesnt provide all services like SSH. But it does have telnet running inside.
So just try this with user name as admin and password as admin in-case if its not changed.

raj@raj:~$ telnet 192.168.1.1
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.
BCM96338 ADSL Router
Login: admin
Password: 
> 

Voila.. I got in… Now what next??

Get available commands using

? 

You will have an output like


> ?

?
help
logout
reboot
adsl
atm
brctl
cat
df
dumpcfg
echo
ifconfig
kill
arp
defaultgateway
dhcpserver
dns
lan
passwd
ppp
remoteaccess
restoredefault
route
save
swversion
wan
serialnum
ping
ps
pwd
sntp
sysinfo
tftp
wlctl

>

Okay.. How can I launch the Busybox shell??

Run this command in the prompt..

> sh


BusyBox v1.00 (2009.02.27-11:34+0000) Built-in shell (msh)
Enter 'help' for a list of built-in commands.

# help

Built-in commands:
-------------------
        . : break cd continue eval exec exit export help login newgrp
        read readonly set shift times trap umask wait [ busybox cat chmod
        date df dmesg echo expr false ftpget ifconfig init insmod ip
        iproute kill klogd linuxrc ln logger logread mkdir mount msh
        ping ping6 ps pwd reboot rm rmmod route sendarp sh sysinfo syslogd
        test tftpd top true tty vconfig

# 

Now you can play with the available commands in this..

What is the difference between the ‘>’ operator and ‘|’ operator in Linux?

Piping and redirection are two powerful tools in the Unix kit. | is the pipe operator. > is the redirect operator.

Piping connects the standard out of one program to the standard in of another. You can think of it as a literal pipe: There’s a stream of data from the leftmost command to the right.

For example:

$ foo | bar

This connects foo’s standard out to bar’s standard in. What foo outputs, bar receives. You can build pipelines:

$ foo | bar | baz

This connect’s foo to bar and bar to baz. For a real example, the following chains together four commands to print all of the processes that are running on your system with more than one instance:

$ ps ax | awk ‘{ print $5 }’ | sort | uniq -dc

There is a little shell work here to set things up, but pipes mostly rely on existing kernel functionality.

Redirects are about files, not just processes:

$ foo > file

The standard out from foo is stored in the file named “file” instead of displaying on the console. The shell implements this by opening the file, setting it as standard in, and then running the new process.

Summary: Piping chains together two or more processes by connecting the outputs of an antecedent process to the input of the immediately subsequent process. Redirection is a shell feature that saves a process’s output in a file or copies a file into a process’s input.

You use pipes with processes, redirects with a process and a file.

-By Robert Love on Quora

HowTo Restart a Daemon/Program in Linux if it Crashes/Killed

Most of security critical applications/services are pron to attacks and the first try is to kill/remove the process/application. Here in this post, im writing about the method to prevent the first try, to kill the service.

One method, is to restart the application when it is killed. For making an service/process to run as a daemon, In Linux, we can add a launching script at /etc/init.d/ directory, so that it will be started at the bootup init.

Here is a simple hello world program to demonstrate it.


#include
int main() {
     while(1) { /* Continue forever as a daemon */
     printf("Hello world\n");
     sleep(1); /* Sleep for one minute */
    }
}

Now compile it into hello.out and create a startup script to add it to init.d as below.

raj@08:39:10:$ gcc hello.c -o hello.out

while ! /home/raj/hello.out   #This will wait for the program to exit successfully .
do
echo “restarting”                  # Else it will restart.
done

Add this script hello.sh /etc/init.d/ to start it at boot time. But now, we can test it without rebooting.

Provide execution permission to the script and run the script on one termnial.

raj@08:39:22:$ sudo chmod +x /home/raj/hello.sh
raj@08:39:32:$ ./hello.sh

Now you can see the program running and printing Hello world string once in one minute. Now open one more terminal and kill this process by finding its pid as below.

raj@08:40:07:$ pidof hello.out
26685
raj@08:40:20:$ sudo kill 26685.

Now, you can see the process being started again.
Here is screenshot to give an overview.

Screenshot from 2012-12-02 08:40:54

 

Surely there will be may better ways, would like to know and if i come to know, i will update this. 🙂