Pages

Thursday, 27 April 2017

Booting Linux from NFS

Hi There!

This post is about booting your linux from Network File System.

Network File System means that the uImage, rootfs and other files resides not on the target system but on some other host system connected with target system through network. Just to clear confusion, we will call the system which has uImage, rootfs and other files as host system whereas target system (BeagleBone Black in this case) is one the on which we want to boot Linux. This host system can be anywhere in the world. Usually we use our development system as host for NFS. We use NFS for development purpose because we get rid of flashing the target system or copying system image to SD card again and again. Although you may experience minor lags when you use NFS.

As mentioned in this post, we have our uImage, rootfs and other files ready.
Before cross compiling Linux kernel, please enable following flags in config file to add NFS support in kernel.

CONFIG_NFS_FS=y #NFS filesystem support
CONFIG_ROOT_NFS=y #Root file system on NFS
CONFIG_NET_ETHERNET=y #Ethernet
CONFIG_IP_PNP=y #IP: kernel level autoconfiguration
CONFIG_IP_PNP_DHCP=y #DHCP support

Host system configuration

NFS Kernel Server: This server will be used for keeping rootfs on NFS.

$ sudo apt-get install nfs-kernel-server #install nfs-kernel-server
$ mksdir nfsroot #create directory where rootfs will reside
$ vim /etc/exports #open this file and add following line in it.
<path to nfsroot> *(rw,sync,insecure,no_root_squash,no_subtree_check)

TFTP server: This server will be used to upload kernel image and dtb file to target system.

$ sudo apt-get install tftpd #install tftp server
$ vim /etc/xinetd.d/tftp #add following content to this file
service tftp
{
protocol        = udp
port            = 69
socket_type     = dgram
wait            = yes
user            = nobody
server          = /usr/sbin/in.tftpd
server_args     = <path to tftpboot>
disable         = no
}


$ sudo mkdir tftpboot #create tftpboot directory, this directory will have uImage, dtb and other files
$ sudo chmod -R 777 tftpboot #change permissions
$ sudo chown -R nobody tftpboot #change owner

DHCP server: This server will be used to allocate IP address to target machine.

$ sudo apt-get install isc-dhcp-server #install dhcp server
$ sudo vim /etc/default/isc-dhcp-server #add ethernet interface name to this file for which dhcp server will run. This can be different from "eth0" for your system
INTERFACES="eth0"

$ sudo vim /etc/dhcp/dhcpd.conf #add following configuration lines
subnet 192.168.100.0 netmask 255.255.255.0 {
  range 192.168.100.10 192.168.100.25;
}

$ cp linux/arch/arm/boot/uImage tftpboot/ #copy uImage to tftpboot
$ cp linux/arch/arm/boot/dts/am335x-boneblack.dtb tftpboot/ #copy dtb file to tftpboot
$ sudo ifconfig eth0 192.168.100.1 netmask 255.255.255.0 #set IP address of host machine
$ sudo /etc/init.d/xinetd restart #restart xinetd
$ sudo service isc-dhcp-server restart #restart DHCP server
$ sudo service nfs-kernel-server restart #restart NFS server
$ sudo netstat -uap #check status of servers

Target system configuration

BeagleBone Black comes with a preinstalled U-Boot and Linux system in flash memory. Please ensure that U-Boot is working fine.
As soon as you switch ON the board, press any key to stop booting on U-Boot prompt.

U-Boot# setenv serverip 192.168.100.1
U-Boot# setenv a_uImage 0x82000000
U-Boot# setenv a_fdt 0x88000000
U-Boot# setenv initrd_high 0xffffffff
U-Boot# setenv dtbname am335x-boneblack.dtb
U-Boot# dhcp ${a_fdt} 192.168.100.1:${dtbname}
U-Boot# fdt addr ${a_fdt}
U-Boot# setenv fdt_high 0xffffffff
U-Boot# setenv bootargs ip=dhcp root=/dev/nfs rw nfsroot=192.168.100.1:<path to nfsroot>,nolock, wsize=1024, rsize=1024 rootwait console=ttyS0,115200n8 rootdelay=5
U-Boot# dhcp ${a_uImage} 192.168.100.1:uImage
U-Boot# bootm ${a_uImage} - ${a_fdt}

Your system will now boot and you should see Linux login prompt after few seconds.

I hope this post was helpful for you. Please share your queries, questions and feedbacks in comments section below.

Wednesday, 26 April 2017

Create simple rootfs from scratch

Hey There!

In this post, we will learn to create a bare minimum rootfs from scratch to get our development board up and running.

rootfs is a type of file system which contains all the necessary files needed to run the development board. This link gives details of different directories in a root file system.

There are various tools available(for eg. Buildroot) which can create rootfs and system image very easily. But in this post we will create rootfs without using any tool. Following steps will create rootfs for BeagleBone Black but they are mostly applicable (with some minor changes) for other development boards as well.

The first step towards creating a rootfs is to cross compile a Linux Kernel. Please read this post to cross compile Linux kernel.

After cross compiling kernel, we will cross compile BusyBox. BusyBox is a complete environment for embeddded linux. It contains almost all the utilities (with limited capabilities) required for embedded linux. BusyBox can be downloaded from here.

$ tar -xvf busybox-1.26.2.tar.bz2
$ cd busybox-1.26.2/
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig //select busybox configurations
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- CONFIG_PREFIX=<path to rootfs dir> install

Now we create core device files in newly created rootfs
$ cd <path to rootfs dir>
$ mkdir dev
$ sudo mknod dev/console c 5 1
$ sudo mknod dev/null c 1 3
After creation of core device files, we create and populate some other important files
$ mkdir etc
$ cat >> etc/inittab
::sysinit:/bin/mount -t proc proc /proc
::sysinit:/bin/hostname -F /etc/hostname
::respawn:/sbin/getty -L ttyS0 115200 vt100
null::respawn:/sbin/syslogd -n -m 0
null::respawn:/sbin/klogd -n
null::shutdown:/usr/bin/killall klogd
null::shutdown:/usr/bin/killall syslogd
null::shutdown:/bin/umount -a -r
^D

The first process to be executed after kernel completes boot process is init. init process has responsibilities to setup system configurations and start applications, shutdown system applications and serve as parent process of all child processes whose parent has exited. Default init implementation reads its instructions from /etc/inittab. The format of instructions in /etc/inittab is id:runlevel:action:command
Default init resides in sbin/init, so we also need to check and fulfill dependencies of init.

#following command lists the dependencies of init
$ readelf -d sbin/init |grep NEEDED
 0x00000001 (NEEDED)                     Shared library: [libm.so.6]
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
 0x00000001 (NEEDED)                     Shared library: [ld-linux.so.3]

We got 3 dependencies of init, i.e., libm.so.6, libc.so.6 and ld-linux.so.3. These dependencies are available in toolchain. I installed toolchain from apt-get, so these libraries are available at /usr/arm-linux-gnueabi/lib. Please copy these 3 libraries and their dependencies to lib/ directory of newly created rootfs.

#create mountpoint for proc
$ mkdir proc

#create a root user with an empty password
$ mkdir root
$ cat >> etc/passwd
root:x:0:0:root:/root:/bin/sh
^D
$ cat >> etc/shadow
root::10933:0:99999:7:::
^D
#designate a hostname for your system
$ cat >> etc/hostname
pcslinux
^D

#Install a basic udhcpc script
$ mkdir -p usr/share/udhcpc
$ cp ../busybox-1.26.2//examples/udhcp/simple.script usr/share/udhcpc/default.script

Our rootfs is ready for execution now. To use this rootfs, we need to put this rootfs along with kernel image, dtb file and other files on secondary memory. Secondary memory can be SD card, flash or NFS.
Steps to copy files and boot Linux from NFS are available here.

I hope this post was helpful. Please comment below with your queries, questions and feedback.

Tuesday, 11 April 2017

Build Linux Kernel for BeagleBone Black


Hi there!
BeagleBone Black is one of the most economical, widely used, community supported development platform available in the market. BeagleBone Black has a AM335x 1GHz ARM® Cortex-A8 processor and it is produced by Texas Instruments.
If you plan to learn/practice embedded systems and Linux Kernel, I would recommend you to buy this or any other development platform. Using a development platform gives you practical experience and increases your confidence.
This post gives details about how to build Linux Kernel for BeagleBone Black. I hope that you have cross compilation environment ready to start the task. (if not, please configure your system by following these steps.)
For keeping things simple for now, we will git clone Linux Kernel from BeagleBoard repository which contains customized Kernel for BeagleBone Black.
$ git clone git://github.com/beagleboard/linux.git
$ cd linux
$ git checkout 4.1
Download Linux Kernel version 4.1

$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- bb.org_defconfig

We need to specify which modules and subsystems do we need in our kernel, so this step configures Kernel with default configuration for BeagleBone Black. Different methods are available to configure Kernel. For eg., we can use make menuconfig command to open menu through which we can select modules, drivers and subsystems to be built in the kernel. After completion of this step, a .config file is generated in the Kernel directory. It is recommended to open and read this file to understand different kernel configurations.

Following step cross compiles Kernel for ARM architecture and toolchain prefix arm-linux-gnueabi-. j4 specifies the number of threads to be used to cross compile the Kernel.
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4

Following command creates a uImage for this Kernel. uImage is a type of Kernel image. There are various other types of Kernel images like zImage etc. LOADADDR specifies the address from where UBOOT will read Kernel image.
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- uImage dtbs LOADADDR=0x80008000 -j4


Following command cross compiles the modules which have been selected during Kernel configuration
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- modules -j4


Following command installs the cross compiled modules to path specified in INSTALL_MOD_PATH.
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- INSTALL_MOD_PATH=<path to rootfs directory> modules_install

If you have followed all the steps correctly, you would have uImage and various other cross compiled files.
But only these files will not enable you to boot up and run your system. You would need a bootloader and rootfs to get your system up and running.

Linux Kernel Cross compilation environment

Hey there!

As the title suggests, this post gives details of preparing your machine to cross compile a Linux Kernel.

I am doing this on a Ubuntu 16.04 but I hope that this will work for other versions of Ubuntu as well. However, these commands may not work on other flaours of Linux.

Open a terminal in Ubuntu and paste following commands. These commands need internet connectivity on your machine to download and install these packages.

sudo apt-get update
sudo apt-get install fakeroot build-essential kexec-tools kernel-wedge
sudo apt-get install libncurses5 libncurses5-dev libelf-dev
sudo apt-get install asciidoc binutils-dev

Following command installs cross compilation toolchain. I am cross compiling for BeagleBone Black so I have used this toolchain. For other boards this command may be different depending on SoC architecture.

sudo apt-get install gcc-arm-linux-gnueabi

If you have done no mistakes in following these simple steps, you should be ready to cross compile Linux Kernel.
For queries and questions, please comment below.

Sunday, 9 April 2017

Getting started with Linux Kernel

Hi there!

This blog post is for the beginners who want to learn Linux Kernel programming.

The first and foremost requirement to start Linux Kernel programming is to be good in C programming. If you are good in C programming then keep reading otherwise I would suggest you to first clear your C basics before diving into the Linux Kernel.

So for knowing about Linux Kernel, we first need to know about Linux.

" Linux is a Unix-like computer operating system assembled under the model of free and open-source software development and distribution. The defining component of Linux is the Linux kernel, an operating system Kernel first released on September 17, 1991 by Linus Torvalds." - Wikipedia

There are many books and websites out there which teach and explain about the details of Linux Kernel.
I would recommend following 2 books to start learning Linux Kernel Programming.
Although the above mentioned books are now old and Kernel has changed a lot since these books were written but these books will get you started on your journey with Linux Kernel.

Following is the list of useful websites.
The Linux Kernel community's primary mode of communication is email.
You should subscribe to following mailing lists.
  • Kernel newbies mailing list - This mailing list is for Kernel newbies where you may ask questions and discuss issues. Few top guns of Linux Kernel are also active on this list to help and guide newbies.
  • Kernel subsystems mailing list - This page contains mailing list for all subsystems related to Kernel. You may subscribe based on your interest. But beware that some of these lists have traffic of hundreds of mails per day.
One thing very true about learning Linux Kernel is that it can only be mastered by practicing.

There is one more reliable way to learn Linux Kernel programming. You can register for Eudyptula Challenge.
Eudyptula Challenge gives you series of tasks related to Linux Kernel programming and also prepares you for Linux community interaction.  

I hope this post would be useful for you. Please share your feedbacks about this post in the comments section below.

All the best for your adventures with ocean named Linux!!

First post!!

Hey there!

This is my first post!!
I have created this blog to share and discuss my learnings about different experiments that I do with Embedded Systems which also happens to be my bread and butter. Please feel free to get in touch for any feedback, help, projects etc or just to say hi.

I plan to have some technical stuff here related to real time system.

Thanks for reading.

Regards,
Abhishek Sharma

Booting Linux from NFS

Hi There! This post is about booting your linux from Network File System. Network File System means that the uImage, rootfs and ot...