KEMBAR78
Hands on with embedded linux using zero hardware | PDF
Hands on with embedded Linux
using zero hardware
v2016.03
Released under Creative Commons BY­SA 3.0 license
By
Rajesh Sola
CDAC­ACTS,Pune
Rajesh Sola,CDAC-ACTS,Pune 2
License
● This content is released under
Creative Commons Attribution Share Alike 3.0
https://creativecommons.org/licenses/by­sa/3.0/
https://creativecommons.org/licenses/by­sa/3.0/legalcode
Under this license terms you are free
– to copy, distribute, display, and perform the work
– to make derivative works
– to make commercial use of the work
● Under the following conditions
– Attribution:. You must give the original author credit.
– Share Alike:. If you remix, transform, or build upon the material, you must
distribute your contributions under the same license as the original.
– No additional restrictions
Rajesh Sola,CDAC-ACTS,Pune 3
Disclaimer
● These slides are not meant for beginners as a sole reference in quick mode.
● You may use this content as a checklist once you undergone basic course of
embedded Linux or please refer suggested resources along with these if you
are comfortable with self learning or explore more on listed concepts,
techniques.
● The documented steps are verified under specified versions only,some tuning
may be required with other versions
● Certain steps are less detailed in current version, planning to elaborate in
further versions.
● Please report any corrections, enhancements,additions towards this content
for improvements in further versions
Rajesh Sola,CDAC-ACTS,Pune 4
Objectives
● Understanding cross development, cross toolchain
● Using various tools under a typical toolchain
● Building Linux Kernel,Applications for target architecture
● ARM Versatile Express family board as a reference platform
● Preparing file system for target platform
● Emulating built kernel, applications under QEMU
● Building and working with u­boot – sdcard,network approach
● Creating and linking with libraries – static, dynamic
● Writing simple modules for target kernel – external, internal
● Adding system calls(ARM specific)
Rajesh Sola,CDAC-ACTS,Pune 5
Contents
● 1. Prerequisites
● 2. Building kernel
– 2.1 For Development
– 2.2 For analysis
● 3. Preparing rootfs
● 4.U­boot approach
– 4.1 Using sdcard image
– 4.2 Using tftp
● Cross compiling applications
● Writing simple modules
● Adding system call
● References
Rajesh Sola,CDAC-ACTS,Pune 6
Package Dump – checklist
● Linaro toolchain from https://releases.linaro.org/14.09/components/toolchain/binaries/
gcc­linaro­arm­linux­gnueabihf­4.9­2014.09_linux.tar.xz
● Kernel source from https://www.kernel.org/pub/linux/kernel/v3.x/
linux­4.1.8.tar.xz
● Qemu source from http://wiki.qemu.org/download/
qemu­2.0.0.tar.bz2
● Prebuilt rootfs from http://downloads.yoctoproject.org/releases/yocto/yocto­
2.0/machines/qemu/qemuarm/
core­image­minimal­qemuarm.tar.bz2 (or) core­image­minimal­qemuarm.ext4
● U­boot source code from ftp://ftp.denx.de/pub/u­boot/
u­boot­2016.01.tar.bz2
Rajesh Sola,CDAC-ACTS,Pune 7
Setting up QEMU
● Extract source code and switch into
tar ­jxvf qemu­2.0.0.tar.bz2
cd qemu­2.0.0
● Configure, build and install
./configure –target­list=arm­softmmu,arm­linux­user 
­­enable­sdl –prefix=/opt/qemu­2.0
make
make install
● Update path to Qemu binaries
export PATH=/opt/qemu­2.0/bin:$PATH
#you may add above line to ~/.bash_profile or ~/.bashrc
Rajesh Sola,CDAC-ACTS,Pune 8
Setting up toolchain
● Linaro toolchain
tar ­xvf gcc­linaro­arm­linux­gnueabihf­4.9­2014.09_linux.tar.xz ­C /opt
export PATH=/opt/gcc­linaro­linux­gnueabihf­4.9­2014.09_linux/bin:$PATH
#you may add above line to ~/.bash_profile or ~/.bashrc for further
use
● Simple check
arm­linux­gnueabihf­gcc #should work
Rajesh Sola,CDAC-ACTS,Pune 9
Building Kernel
● Extract kernel source and switch into, call it as KSRC
tar ­jxvf linux­4.1.8.tar.bz2
cd linux­4.1.8 #KSRC now onwards
● Configuring kernel
make mrproper
make ARCH=arm vexpress_defconfig
make ARCH=arm menuconfig
#change local version under general setup during menuconfig
#or copy tested configuration file as .config under KSRC
● Building
make ARCH=arm CROSS_COMPILE=arm­linux­gnueabihf­
zImage modules dtbs
#skipping modules_install for time being
Rajesh Sola,CDAC-ACTS,Pune 10
Building kernel
● Copy the following files to a temp dir for quick boot
KSRC/arch/arm/boot/zImage
KSRC/arch/arm/boot/dts/vexpress­v2p­ca9.dtb
● Refer Device tree for dummies from free­electrons.com
for better understanding of Flattened Device Tree(FDT) concepts.
Rajesh Sola,CDAC-ACTS,Pune 11
Preparing rootfs
● Preparing rootfs image from prebuilt contents
qemu­img create ­f raw rootfs.img 64M
mkfs.ext4 rootfs.img
mount ­o loop,rw,sync rootfs.img /mnt/image
tar ­jxvf core­image­minimal­qemuarm.tar.bz2 ­C /mnt/image
umount /mnt/image
#or use provided rootfs initially
#or download core­image­minimal­qemuarm.ext4 from same link and rename as
#rootfs.img, but this has very less free space left out
Rajesh Sola,CDAC-ACTS,Pune 12
Copying files to rootfs
● Copying files to home dir rootfs
mount -o loop,rw,sync rootfs.img /mnt/image
cp <source-files> /mnt/image/home/root
eg:- cp test.out /mnt/image/home/root
umount /mnt/image
● Rebuild kernel for initrd support,upto 64MB size
make ARCH=arm menuconfig
Device Drivers → Block Devices →
(*) RAM Block device support
(16) Default number of RAM disks
(65536) Default RAM disk size
Rajesh Sola,CDAC-ACTS,Pune 13
Tuning for dynamic libs
mount -o loop,rw,sync rootfs.img /mnt/image
mkdir /mnt/image/lib/hardfp
cp /opt/gcc­linaro­linux­gnueabihf­4.9­2014.09_linux/arm­linux­gnueabihf/libc/lib/ld­linux­
armhf.so.3 /mnt/image/lib/hardfp/
cp /opt/gcc­linaro­linux­gnueabihf­4.9­2014.09_linux/arm­linux­gnueabihf/libc/lib/arm­
linux­gnueabihf/libc­2.19­2014.04.so /mnt/image/lib/hardfp/
vi /mnt/image/etc/ld.so.conf #add the line “/lib/hardfp”
umount /mnt/image
#or use provided dynrootfs.img initially
● Rebuild kernel to prevent read only mounting for large rootfs
make ARCH=arm menuconfig
General Setup → Enable the block layer
Support for large(2TB+) block devices and files
● Run “ldconfig” once in target to configure and update added libraries
ldconfig (or)
ldconfig ­n /lib/hardfp
Rajesh Sola,CDAC-ACTS,Pune 14
Quick boot
● Checklist
zImage
vexpress­v2p­ca9.dtb
rootfs.img
● Booting with sdcard
qemu­system­arm ­M vexpress­a9 ­m 1024 ­serial stdio 
­kernel zImage ­dtb vexpress­v2p­ca9.dtb ­sd rootfs.img 
­append “console=ttyAMA0 root=/dev/mmcblk0 rw”
● Initrd approach
qemu­system­arm ­M vexpress­a9 ­m 1024 ­serial stdio 
­kernel zImage ­dtb vexpress­v2p­ca9.dtb ­initrd rootfs.img 
­append “console=ttyAMA0 root=/dev/ram0 rw”
Rajesh Sola,CDAC-ACTS,Pune 15
Post boot
● Try the following commands in booted system
uname ­r
uname ­v
cat /proc/cpuinfo
lsmod
cat /proc/modules
cat /proc/kallsyms
Rajesh Sola,CDAC-ACTS,Pune 16
Building u-boot
● Extract and switch into
tar ­jxvf u­boot­2016.01.tar.bz2
cd u­boot­2016.01
● Configure and build
make ARCH=arm vexpress_ca9x4_defconfig
make ARCH=arm CROSS_COMPILE=arm­linux­gnueabihf­
cp tools/mkimage /usr/local/bin
#copy generated “u­boot” to tempdir
● Preparing kernel image for u­boot format
make ARCH=arm CROSS_COMPILE=arm­linux­gnueabihf­ 
uImage LOADADDR=0x60008000
Rajesh Sola,CDAC-ACTS,Pune 17
U-Boot approach using SD card
● Prepare SD card image
qemu­img create ­f raw sdcard.img 128M
mkfs.vfat sdcard.img
mkdir /mnt/sdcard
mount ­o loop,rw,sync sdcard.img /mnt/sdcard
#copy uImage, vexpress­v2p­ca9.dtb, rootfs.img to /mnt/sdcard
umount /mnt/sdcard
● Boot from u­boot using SD card image
qemu­system­arm ­M vexpress­a9 ­m 1024 ­kernel u­boot 
­serial stdio ­sd sdcard.img
#stop auto boot or wait for u­boot prompt
Rajesh Sola,CDAC-ACTS,Pune 18
U-Boot approach using SD card
● Enter the following commands in u­boot prompt
mmcinfo
fatls mmc 0:0
fatload mmc 0:0 0x82000000 rootfs.img #note down size
fatload mmc 0:0 0x80600000 uImage
fatload mmc 0:0 0x80400000 vexpress­v2p­ca9.dtb
setenv bootargs 'console=ttyAMA0 root=/dev/ram0 rw
rootfstype=ext4 initrd=0x82000000,8388608'
bootm 0x80600000 ­ 0x80400000
Rajesh Sola,CDAC-ACTS,Pune 19
U-Boot approach using tftp
● Preparing QEMU with network support
mkdir /dev/net #skip if exists already
mknod /dev/net/tun c 10 200 #skip if exists already
modprobe tun
#copy qemu­ifup,qemu­ifdown under /etc
#modify ETH0IPADDR, GATEWAY,BROADCAST in /etc/qemu­ifup
chmod +x /etc/qmu­ifup /etc/qemu­ifdown
qemu­system­arm ­M vexpress­a9 ­m 1024 ­kernel u­boot 
­serial stdio ­net nic ­net tap,ifname=tap0
● Enable TFTP server in your host using tempdir as server root
YaST → Network Services → TFTP Server in case of opensuse
Rajesh Sola,CDAC-ACTS,Pune 20
U-Boot approach using tftp
● Network setup in u­boot
setenv ipaddr 192.168.0.5
setenv serverip 192.168.0.1 #ETH0IPADDR in /etc/qemu­ifup
ping 192.168.0.1
● Loading & Booting via tftp
tftp 0x82000000 rootfs.img
tftp 0x80600000 uImage
tftp 0x80400000 vexpress­v2p­ca9.dtb
setenv bootargs 'console=ttyAMA0 root=/dev/ram0 rw
rootfstype=ext4 initrd=0x82000000,8388608'
bootm 0x80600000 ­ 0x80400000
Rajesh Sola,CDAC-ACTS,Pune 21
Cross compiling sample code
● Simple Program
arm-linux-gnueabihf-gcc hello.c -c
arm-linux-gnueabihf-gcc hello.o -o h.out
● Multifile example
arm-linux-gnueabihf-gcc test.c -c
arm-linux-gnueabihf-gcc sum.c -c
arm-linux-gnueabihf-gcc sqr.c -c
arm-linux-gnueabihf-gcc test.o sum.o sqr.o -o all.out
● Copy h.out, all.out as described in previous slide and test them
Rajesh Sola,CDAC-ACTS,Pune 22
Static Linking
● Creating static library
arm-linux-gnueabihf-gcc sum.c -c
arm-linux-gnueabihf-gcc sqr.c -c
arm-linux-gnueabihf-ar rc libsample.a sum.o sqr.o
● Linking with static library
arm-linux-gnueabihf-gcc test.c -c
arm-linux-gnueabihf-gcc -L. test.o -lsample -o p.out
arm-linux-gnueabihf-gcc -L. test.o -lsample -o s.out -static
● Testing
Copy p.out, s.out to rootfs and try executing them
Rajesh Sola,CDAC-ACTS,Pune 23
Dynamic linking
● Creating static library
arm-linux-gnueabihf-gcc sum.c -c
arm-linux-gnueabihf-gcc sqr.c -c
arm-linux-gnueabihf-gcc -shared sum.o sqr.o -o libsample.so
● Linking with static library
arm-linux-gnueabihf-gcc test.c -c
arm-linux-gnueabihf-gcc -L. test.o -lsample -o d.out
● Testing
#copy d.out to home dir of rootfs
#copy libsample.so to ~/mylibs of rootfs
LD_LIBRARY_PATH=~/mylibs ./d.out
#Adding ~/mylibs to /etc/ld.so.conf eliminates the need of
LD_LIBRARY_PATH
Rajesh Sola,CDAC-ACTS,Pune 24
Analysis
● Analysis
file s.out p.out d.out
ls ­sh s.out p.out d.out
arm­linux­gnueabihf­readelf ­h s.out p.out d.out
arm­linux­gnueabihf­ldd ­­root /mnt/image s.out p.out d.out
arm­linux­gnueabihf­strings s.out p.out d.out
Rajesh Sola,CDAC-ACTS,Pune 25
Writing simple modules
● Makefile
obj­m += hello.o
● hello.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int __init hello_init(void)
{
printk("Hello World..welcomen");
return 0;
}
static void __exit hello_exit(void)
{
printk("Bye,Leaving the worldn");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your name");
MODULE_DESCRIPTION("A Hello, World Module");
Rajesh Sola,CDAC-ACTS,Pune 26
Building and testing
● Building
make ­C <path­of­ksrc> M=$PWD modules 
ARCH=arm CROSS_COMPI:LE=arm­linux­gnueabihf­
● Copy generated hello.ko to rootfs
● Better Makefile, Now simple run “make”
obj­m += hello.o
all:
make ­C <path­of­ksrc> M=$PWD modules 
ARCH=arm CROSS_COMPI:LE=arm­linux­gnueabihf­
clean:
make ­C <path­of­ksrc> M=$PWD clean 
ARCH=arm CROSS_COMPI:LE=arm­linux­gnueabihf­
Rajesh Sola,CDAC-ACTS,Pune 27
Testing the module
● Testing in host
file hello.ko
arm­linux­gnueabihf­objdump ­d hello.ko
arm­linux­gnueabihf­readelf ­h hello.ko
modinfo hello.ko
● Testing in target
dmesg ­c
insmod hello.ko
dmesg
lsmod
cat /proc/modules
rmmod hello
dmesg
Rajesh Sola,CDAC-ACTS,Pune 28
Module parameters,dependency
● Module parameters
int ndevices=0;
module_param(ndevices,int,S_IRUGO);
insmod simple.ko ndevices=3
● Exporting symbols (eg:­ from simple.c)
EXPORT_SYMBOL_GPL(ndevices);
EXPORT_SYMBOL_GPL(sayHello);
● Accessing symbols from other modules(eg:­ complex.c)
extern int ndevices;
extern void sayHello();
● GPL symbols are accessible from GPL modules only
MODULE_LICENSE("GPL");
Rajesh Sola,CDAC-ACTS,Pune 29
Internal modules - dynamic
● drivers/char/mtest/ ==> simple.c, complex.c
● drivers/char/mtest/Makefile
obj­m += simple.o complex.o
● drivers/char/Makefile
obj­m += dtest/
● Rebuild the kernel with modules_install
make ARCH=arm CROSS_COMPILE=arm­linux­gnueabihf­ 
modules_install INSTALL_MOD_PATH=/mnt/image
● Testing
ls /lib/modules/$(uname ­r)/kernel/drivers/mtest
modprobe complex #loads simple also due to dependency
lsmod
cat /proc/modules
modprobe ­r complex
modprobe ­r simple
Rajesh Sola,CDAC-ACTS,Pune 30
Internal modules - static
● drivers/char/mtest/ ==> simple.c, complex.c
● drivers/char/mtest/Makefile
obj­y += simple.o complex.o
● drivers/char/Makefile
obj­y += mtest/
● Rebuild the kernel
● Testing in host
arm­linux­gnueabihf­nm KSRC/vmlinux #try with objdump also
● Testing in target
ls /lib/modules/$(uname ­r)/kernel/drivers/char
cat /proc/kallsyms #check for init methods of modules
dmesg #check for printk output in static modules
Rajesh Sola,CDAC-ACTS,Pune 31
Adding Kconfig entries
● drivers/char/mtest/Kconfig
#menu "My Modules"
config SIMPLE
tristate "A simple module"
default m
help
This is a simple module
config COMPLEX
tristate "A complex module"
depends on SIMPLE
default m
help
This is a sample module dependending on simple
#endmenu
● drivers/char/Kconfig
source “drivers/char/mtest/Kconfig”
Rajesh Sola,CDAC-ACTS,Pune 32
Testing Kconfig entries
● make ARCH=arm menuconfig
drivers → char → custom modules
● verify .config
● driver/char/mtest/Makefile
obj­$(CONFIG_SIMPLE)+=simple.o
obj­$(CONFIG_COMPLEX)+=complex.o
● driver/char/Makefile
obj­y += mtest/
Rajesh Sola,CDAC-ACTS,Pune 33
Adding system calls
● Changes to kernel – adding entry
arch/arm/include/uapi/asm/unistd.h
arch/arm/kernel/calls.S
arch/arm/include/asm/unistd.h
include/linux/syscalls.h
● Changes to kernel – defining system call
KSRC/kernel/mysyscall.c
asmlinkage long sys_testcall(void)
{
printk("This is my system calln");
}
KSRC/kernel/Makefile
obj­y += mysyscalls.o
Rajesh Sola,CDAC-ACTS,Pune 34
Building & Testing system calls
● Rebuild the kernel
● Verifying system call under new kernel
arm­linux­gnueabihf­nm KSRC/vmlinux | grep sys_testcall #in host
cat /proc/kallsyms | grep sys_testcall #in target
● Testing system call using C code
#include<unistd.h>
#define SYS_mycall 388
int main()
{
syscall(SYS_mycall);
return 0;
}
● arm­linux­gnueabihf­gcc systest.c ­o s1.out
Rajesh Sola,CDAC-ACTS,Pune 35
Testing system calls
● Assembly code – asmtest.s
mov r7,#388
mov r0,#25
mov r1,#35
SWI 0
mov r7,#1
mov r0,#5
SWI 0
● arm­linux­gnueabihf­as asmtest.c ­o asmtest.o
● arm­linux­gnueabihf­ld asmtest.o ­o s2.out
#Copy the binaries s1.out,s2.out to rootfs and test them
Rajesh Sola,CDAC-ACTS,Pune 36
Appendix - Environment Variables
● PATH
Holds list of directories holding external commands
Updating PATH(QEMU binaries as an example):­
export PATH=/opt/qemu­2.0/bin:$PATH
Can add above line to ~/.bash_profile, ~/.bashrc
Or write the settings in a script and invoke script using source
command
● LD_LIBRARY_PATH
List of directories holding dependent dynamic libraries
export LD_LIBRARY_PATH=~/mylib:$LD_LIBRARY_PATH
(or) add ~/mylibs to /etc/ld.so.conf and run ldconfig once or reboot
Rajesh Sola,CDAC-ACTS,Pune 37
Appendix - Appending dtb file to kernel image
● Configure kernel
● Append kernel image and dtb file
cd arch/arm/boot
cat zImage vexpress­v2p­ca9.dtb > zImage­dtb
● Convert to u­boot format
mkimage ­A arm ­O linux ­C none ­T kernel ­a 0x60008000 
­e 0x60008000 ­n 'Linux­4.1.2­vexpress' ­d zImage­dtb uImage­dtb
● Copy zImage­dtb, uImage­dtb as desired
● Reference:­ Device Tree for Dummies, Free Electrons
Rajesh Sola,CDAC-ACTS,Pune 38
Appendix – ELF Format, Tools
● Executable and Linkable Format, applicable for relocatable object
files, executables, shared object files etc.
https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
http://elinux.org/Executable_and_Linkable_Format_(ELF)
● Tools for ELF files
file
arm­linux­gnueabihf­nm
arm­linux­gnueabihf­objdump # ­d, ­t, ­S
arm­linux­gnueabihf­readelf # ­h
arm­linux­gnueabihf­ldd # ­­root /mnt/image
arm­linux­gnueabihf­strings
arm­linux­gnueabihf­strip
Rajesh Sola,CDAC-ACTS,Pune 39
References, Acknowledgments
● Building Embedded Linux Systems, Karim Yaghmour, O'Reilly Media
● Device Tree for Dummies, Thomas Petazzoni, Free Electrons
● How to Cross Compile the Linux Kernel with Device Tree Support,
Rajesh Sola, Open Source For You Magazine(EFY Group), September
2014
● Thanks to Mr.Babu Krishnamurthy for his valuable inputs on working
with Beagle Board xM, Beagle Bone Black.
● Thanks to the following presentation template
http://templates.libreoffice.org/template­center/university­course­mate
rial­template
● Thanks to the community,contributors of opensuse,libreoffice and
other open source components listed in beginning.
https://www.opensuse.org/
https://www.libreoffice.org/
Rajesh Sola,CDAC-ACTS,Pune 40
Thank You
rajeshsola@gmail.com

Hands on with embedded linux using zero hardware

  • 1.
    Hands on withembedded Linux using zero hardware v2016.03 Released under Creative Commons BY­SA 3.0 license By Rajesh Sola CDAC­ACTS,Pune
  • 2.
    Rajesh Sola,CDAC-ACTS,Pune 2 License ●This content is released under Creative Commons Attribution Share Alike 3.0 https://creativecommons.org/licenses/by­sa/3.0/ https://creativecommons.org/licenses/by­sa/3.0/legalcode Under this license terms you are free – to copy, distribute, display, and perform the work – to make derivative works – to make commercial use of the work ● Under the following conditions – Attribution:. You must give the original author credit. – Share Alike:. If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. – No additional restrictions
  • 3.
    Rajesh Sola,CDAC-ACTS,Pune 3 Disclaimer ●These slides are not meant for beginners as a sole reference in quick mode. ● You may use this content as a checklist once you undergone basic course of embedded Linux or please refer suggested resources along with these if you are comfortable with self learning or explore more on listed concepts, techniques. ● The documented steps are verified under specified versions only,some tuning may be required with other versions ● Certain steps are less detailed in current version, planning to elaborate in further versions. ● Please report any corrections, enhancements,additions towards this content for improvements in further versions
  • 4.
    Rajesh Sola,CDAC-ACTS,Pune 4 Objectives ●Understanding cross development, cross toolchain ● Using various tools under a typical toolchain ● Building Linux Kernel,Applications for target architecture ● ARM Versatile Express family board as a reference platform ● Preparing file system for target platform ● Emulating built kernel, applications under QEMU ● Building and working with u­boot – sdcard,network approach ● Creating and linking with libraries – static, dynamic ● Writing simple modules for target kernel – external, internal ● Adding system calls(ARM specific)
  • 5.
    Rajesh Sola,CDAC-ACTS,Pune 5 Contents ●1. Prerequisites ● 2. Building kernel – 2.1 For Development – 2.2 For analysis ● 3. Preparing rootfs ● 4.U­boot approach – 4.1 Using sdcard image – 4.2 Using tftp ● Cross compiling applications ● Writing simple modules ● Adding system call ● References
  • 6.
    Rajesh Sola,CDAC-ACTS,Pune 6 PackageDump – checklist ● Linaro toolchain from https://releases.linaro.org/14.09/components/toolchain/binaries/ gcc­linaro­arm­linux­gnueabihf­4.9­2014.09_linux.tar.xz ● Kernel source from https://www.kernel.org/pub/linux/kernel/v3.x/ linux­4.1.8.tar.xz ● Qemu source from http://wiki.qemu.org/download/ qemu­2.0.0.tar.bz2 ● Prebuilt rootfs from http://downloads.yoctoproject.org/releases/yocto/yocto­ 2.0/machines/qemu/qemuarm/ core­image­minimal­qemuarm.tar.bz2 (or) core­image­minimal­qemuarm.ext4 ● U­boot source code from ftp://ftp.denx.de/pub/u­boot/ u­boot­2016.01.tar.bz2
  • 7.
    Rajesh Sola,CDAC-ACTS,Pune 7 Settingup QEMU ● Extract source code and switch into tar ­jxvf qemu­2.0.0.tar.bz2 cd qemu­2.0.0 ● Configure, build and install ./configure –target­list=arm­softmmu,arm­linux­user ­­enable­sdl –prefix=/opt/qemu­2.0 make make install ● Update path to Qemu binaries export PATH=/opt/qemu­2.0/bin:$PATH #you may add above line to ~/.bash_profile or ~/.bashrc
  • 8.
    Rajesh Sola,CDAC-ACTS,Pune 8 Settingup toolchain ● Linaro toolchain tar ­xvf gcc­linaro­arm­linux­gnueabihf­4.9­2014.09_linux.tar.xz ­C /opt export PATH=/opt/gcc­linaro­linux­gnueabihf­4.9­2014.09_linux/bin:$PATH #you may add above line to ~/.bash_profile or ~/.bashrc for further use ● Simple check arm­linux­gnueabihf­gcc #should work
  • 9.
    Rajesh Sola,CDAC-ACTS,Pune 9 BuildingKernel ● Extract kernel source and switch into, call it as KSRC tar ­jxvf linux­4.1.8.tar.bz2 cd linux­4.1.8 #KSRC now onwards ● Configuring kernel make mrproper make ARCH=arm vexpress_defconfig make ARCH=arm menuconfig #change local version under general setup during menuconfig #or copy tested configuration file as .config under KSRC ● Building make ARCH=arm CROSS_COMPILE=arm­linux­gnueabihf­ zImage modules dtbs #skipping modules_install for time being
  • 10.
    Rajesh Sola,CDAC-ACTS,Pune 10 Buildingkernel ● Copy the following files to a temp dir for quick boot KSRC/arch/arm/boot/zImage KSRC/arch/arm/boot/dts/vexpress­v2p­ca9.dtb ● Refer Device tree for dummies from free­electrons.com for better understanding of Flattened Device Tree(FDT) concepts.
  • 11.
    Rajesh Sola,CDAC-ACTS,Pune 11 Preparingrootfs ● Preparing rootfs image from prebuilt contents qemu­img create ­f raw rootfs.img 64M mkfs.ext4 rootfs.img mount ­o loop,rw,sync rootfs.img /mnt/image tar ­jxvf core­image­minimal­qemuarm.tar.bz2 ­C /mnt/image umount /mnt/image #or use provided rootfs initially #or download core­image­minimal­qemuarm.ext4 from same link and rename as #rootfs.img, but this has very less free space left out
  • 12.
    Rajesh Sola,CDAC-ACTS,Pune 12 Copyingfiles to rootfs ● Copying files to home dir rootfs mount -o loop,rw,sync rootfs.img /mnt/image cp <source-files> /mnt/image/home/root eg:- cp test.out /mnt/image/home/root umount /mnt/image ● Rebuild kernel for initrd support,upto 64MB size make ARCH=arm menuconfig Device Drivers → Block Devices → (*) RAM Block device support (16) Default number of RAM disks (65536) Default RAM disk size
  • 13.
    Rajesh Sola,CDAC-ACTS,Pune 13 Tuningfor dynamic libs mount -o loop,rw,sync rootfs.img /mnt/image mkdir /mnt/image/lib/hardfp cp /opt/gcc­linaro­linux­gnueabihf­4.9­2014.09_linux/arm­linux­gnueabihf/libc/lib/ld­linux­ armhf.so.3 /mnt/image/lib/hardfp/ cp /opt/gcc­linaro­linux­gnueabihf­4.9­2014.09_linux/arm­linux­gnueabihf/libc/lib/arm­ linux­gnueabihf/libc­2.19­2014.04.so /mnt/image/lib/hardfp/ vi /mnt/image/etc/ld.so.conf #add the line “/lib/hardfp” umount /mnt/image #or use provided dynrootfs.img initially ● Rebuild kernel to prevent read only mounting for large rootfs make ARCH=arm menuconfig General Setup → Enable the block layer Support for large(2TB+) block devices and files ● Run “ldconfig” once in target to configure and update added libraries ldconfig (or) ldconfig ­n /lib/hardfp
  • 14.
    Rajesh Sola,CDAC-ACTS,Pune 14 Quickboot ● Checklist zImage vexpress­v2p­ca9.dtb rootfs.img ● Booting with sdcard qemu­system­arm ­M vexpress­a9 ­m 1024 ­serial stdio ­kernel zImage ­dtb vexpress­v2p­ca9.dtb ­sd rootfs.img ­append “console=ttyAMA0 root=/dev/mmcblk0 rw” ● Initrd approach qemu­system­arm ­M vexpress­a9 ­m 1024 ­serial stdio ­kernel zImage ­dtb vexpress­v2p­ca9.dtb ­initrd rootfs.img ­append “console=ttyAMA0 root=/dev/ram0 rw”
  • 15.
    Rajesh Sola,CDAC-ACTS,Pune 15 Postboot ● Try the following commands in booted system uname ­r uname ­v cat /proc/cpuinfo lsmod cat /proc/modules cat /proc/kallsyms
  • 16.
    Rajesh Sola,CDAC-ACTS,Pune 16 Buildingu-boot ● Extract and switch into tar ­jxvf u­boot­2016.01.tar.bz2 cd u­boot­2016.01 ● Configure and build make ARCH=arm vexpress_ca9x4_defconfig make ARCH=arm CROSS_COMPILE=arm­linux­gnueabihf­ cp tools/mkimage /usr/local/bin #copy generated “u­boot” to tempdir ● Preparing kernel image for u­boot format make ARCH=arm CROSS_COMPILE=arm­linux­gnueabihf­ uImage LOADADDR=0x60008000
  • 17.
    Rajesh Sola,CDAC-ACTS,Pune 17 U-Bootapproach using SD card ● Prepare SD card image qemu­img create ­f raw sdcard.img 128M mkfs.vfat sdcard.img mkdir /mnt/sdcard mount ­o loop,rw,sync sdcard.img /mnt/sdcard #copy uImage, vexpress­v2p­ca9.dtb, rootfs.img to /mnt/sdcard umount /mnt/sdcard ● Boot from u­boot using SD card image qemu­system­arm ­M vexpress­a9 ­m 1024 ­kernel u­boot ­serial stdio ­sd sdcard.img #stop auto boot or wait for u­boot prompt
  • 18.
    Rajesh Sola,CDAC-ACTS,Pune 18 U-Bootapproach using SD card ● Enter the following commands in u­boot prompt mmcinfo fatls mmc 0:0 fatload mmc 0:0 0x82000000 rootfs.img #note down size fatload mmc 0:0 0x80600000 uImage fatload mmc 0:0 0x80400000 vexpress­v2p­ca9.dtb setenv bootargs 'console=ttyAMA0 root=/dev/ram0 rw rootfstype=ext4 initrd=0x82000000,8388608' bootm 0x80600000 ­ 0x80400000
  • 19.
    Rajesh Sola,CDAC-ACTS,Pune 19 U-Bootapproach using tftp ● Preparing QEMU with network support mkdir /dev/net #skip if exists already mknod /dev/net/tun c 10 200 #skip if exists already modprobe tun #copy qemu­ifup,qemu­ifdown under /etc #modify ETH0IPADDR, GATEWAY,BROADCAST in /etc/qemu­ifup chmod +x /etc/qmu­ifup /etc/qemu­ifdown qemu­system­arm ­M vexpress­a9 ­m 1024 ­kernel u­boot ­serial stdio ­net nic ­net tap,ifname=tap0 ● Enable TFTP server in your host using tempdir as server root YaST → Network Services → TFTP Server in case of opensuse
  • 20.
    Rajesh Sola,CDAC-ACTS,Pune 20 U-Bootapproach using tftp ● Network setup in u­boot setenv ipaddr 192.168.0.5 setenv serverip 192.168.0.1 #ETH0IPADDR in /etc/qemu­ifup ping 192.168.0.1 ● Loading & Booting via tftp tftp 0x82000000 rootfs.img tftp 0x80600000 uImage tftp 0x80400000 vexpress­v2p­ca9.dtb setenv bootargs 'console=ttyAMA0 root=/dev/ram0 rw rootfstype=ext4 initrd=0x82000000,8388608' bootm 0x80600000 ­ 0x80400000
  • 21.
    Rajesh Sola,CDAC-ACTS,Pune 21 Crosscompiling sample code ● Simple Program arm-linux-gnueabihf-gcc hello.c -c arm-linux-gnueabihf-gcc hello.o -o h.out ● Multifile example arm-linux-gnueabihf-gcc test.c -c arm-linux-gnueabihf-gcc sum.c -c arm-linux-gnueabihf-gcc sqr.c -c arm-linux-gnueabihf-gcc test.o sum.o sqr.o -o all.out ● Copy h.out, all.out as described in previous slide and test them
  • 22.
    Rajesh Sola,CDAC-ACTS,Pune 22 StaticLinking ● Creating static library arm-linux-gnueabihf-gcc sum.c -c arm-linux-gnueabihf-gcc sqr.c -c arm-linux-gnueabihf-ar rc libsample.a sum.o sqr.o ● Linking with static library arm-linux-gnueabihf-gcc test.c -c arm-linux-gnueabihf-gcc -L. test.o -lsample -o p.out arm-linux-gnueabihf-gcc -L. test.o -lsample -o s.out -static ● Testing Copy p.out, s.out to rootfs and try executing them
  • 23.
    Rajesh Sola,CDAC-ACTS,Pune 23 Dynamiclinking ● Creating static library arm-linux-gnueabihf-gcc sum.c -c arm-linux-gnueabihf-gcc sqr.c -c arm-linux-gnueabihf-gcc -shared sum.o sqr.o -o libsample.so ● Linking with static library arm-linux-gnueabihf-gcc test.c -c arm-linux-gnueabihf-gcc -L. test.o -lsample -o d.out ● Testing #copy d.out to home dir of rootfs #copy libsample.so to ~/mylibs of rootfs LD_LIBRARY_PATH=~/mylibs ./d.out #Adding ~/mylibs to /etc/ld.so.conf eliminates the need of LD_LIBRARY_PATH
  • 24.
    Rajesh Sola,CDAC-ACTS,Pune 24 Analysis ●Analysis file s.out p.out d.out ls ­sh s.out p.out d.out arm­linux­gnueabihf­readelf ­h s.out p.out d.out arm­linux­gnueabihf­ldd ­­root /mnt/image s.out p.out d.out arm­linux­gnueabihf­strings s.out p.out d.out
  • 25.
    Rajesh Sola,CDAC-ACTS,Pune 25 Writingsimple modules ● Makefile obj­m += hello.o ● hello.c #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> static int __init hello_init(void) { printk("Hello World..welcomen"); return 0; } static void __exit hello_exit(void) { printk("Bye,Leaving the worldn"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your name"); MODULE_DESCRIPTION("A Hello, World Module");
  • 26.
    Rajesh Sola,CDAC-ACTS,Pune 26 Buildingand testing ● Building make ­C <path­of­ksrc> M=$PWD modules ARCH=arm CROSS_COMPI:LE=arm­linux­gnueabihf­ ● Copy generated hello.ko to rootfs ● Better Makefile, Now simple run “make” obj­m += hello.o all: make ­C <path­of­ksrc> M=$PWD modules ARCH=arm CROSS_COMPI:LE=arm­linux­gnueabihf­ clean: make ­C <path­of­ksrc> M=$PWD clean ARCH=arm CROSS_COMPI:LE=arm­linux­gnueabihf­
  • 27.
    Rajesh Sola,CDAC-ACTS,Pune 27 Testingthe module ● Testing in host file hello.ko arm­linux­gnueabihf­objdump ­d hello.ko arm­linux­gnueabihf­readelf ­h hello.ko modinfo hello.ko ● Testing in target dmesg ­c insmod hello.ko dmesg lsmod cat /proc/modules rmmod hello dmesg
  • 28.
    Rajesh Sola,CDAC-ACTS,Pune 28 Moduleparameters,dependency ● Module parameters int ndevices=0; module_param(ndevices,int,S_IRUGO); insmod simple.ko ndevices=3 ● Exporting symbols (eg:­ from simple.c) EXPORT_SYMBOL_GPL(ndevices); EXPORT_SYMBOL_GPL(sayHello); ● Accessing symbols from other modules(eg:­ complex.c) extern int ndevices; extern void sayHello(); ● GPL symbols are accessible from GPL modules only MODULE_LICENSE("GPL");
  • 29.
    Rajesh Sola,CDAC-ACTS,Pune 29 Internalmodules - dynamic ● drivers/char/mtest/ ==> simple.c, complex.c ● drivers/char/mtest/Makefile obj­m += simple.o complex.o ● drivers/char/Makefile obj­m += dtest/ ● Rebuild the kernel with modules_install make ARCH=arm CROSS_COMPILE=arm­linux­gnueabihf­ modules_install INSTALL_MOD_PATH=/mnt/image ● Testing ls /lib/modules/$(uname ­r)/kernel/drivers/mtest modprobe complex #loads simple also due to dependency lsmod cat /proc/modules modprobe ­r complex modprobe ­r simple
  • 30.
    Rajesh Sola,CDAC-ACTS,Pune 30 Internalmodules - static ● drivers/char/mtest/ ==> simple.c, complex.c ● drivers/char/mtest/Makefile obj­y += simple.o complex.o ● drivers/char/Makefile obj­y += mtest/ ● Rebuild the kernel ● Testing in host arm­linux­gnueabihf­nm KSRC/vmlinux #try with objdump also ● Testing in target ls /lib/modules/$(uname ­r)/kernel/drivers/char cat /proc/kallsyms #check for init methods of modules dmesg #check for printk output in static modules
  • 31.
    Rajesh Sola,CDAC-ACTS,Pune 31 AddingKconfig entries ● drivers/char/mtest/Kconfig #menu "My Modules" config SIMPLE tristate "A simple module" default m help This is a simple module config COMPLEX tristate "A complex module" depends on SIMPLE default m help This is a sample module dependending on simple #endmenu ● drivers/char/Kconfig source “drivers/char/mtest/Kconfig”
  • 32.
    Rajesh Sola,CDAC-ACTS,Pune 32 TestingKconfig entries ● make ARCH=arm menuconfig drivers → char → custom modules ● verify .config ● driver/char/mtest/Makefile obj­$(CONFIG_SIMPLE)+=simple.o obj­$(CONFIG_COMPLEX)+=complex.o ● driver/char/Makefile obj­y += mtest/
  • 33.
    Rajesh Sola,CDAC-ACTS,Pune 33 Addingsystem calls ● Changes to kernel – adding entry arch/arm/include/uapi/asm/unistd.h arch/arm/kernel/calls.S arch/arm/include/asm/unistd.h include/linux/syscalls.h ● Changes to kernel – defining system call KSRC/kernel/mysyscall.c asmlinkage long sys_testcall(void) { printk("This is my system calln"); } KSRC/kernel/Makefile obj­y += mysyscalls.o
  • 34.
    Rajesh Sola,CDAC-ACTS,Pune 34 Building& Testing system calls ● Rebuild the kernel ● Verifying system call under new kernel arm­linux­gnueabihf­nm KSRC/vmlinux | grep sys_testcall #in host cat /proc/kallsyms | grep sys_testcall #in target ● Testing system call using C code #include<unistd.h> #define SYS_mycall 388 int main() { syscall(SYS_mycall); return 0; } ● arm­linux­gnueabihf­gcc systest.c ­o s1.out
  • 35.
    Rajesh Sola,CDAC-ACTS,Pune 35 Testingsystem calls ● Assembly code – asmtest.s mov r7,#388 mov r0,#25 mov r1,#35 SWI 0 mov r7,#1 mov r0,#5 SWI 0 ● arm­linux­gnueabihf­as asmtest.c ­o asmtest.o ● arm­linux­gnueabihf­ld asmtest.o ­o s2.out #Copy the binaries s1.out,s2.out to rootfs and test them
  • 36.
    Rajesh Sola,CDAC-ACTS,Pune 36 Appendix- Environment Variables ● PATH Holds list of directories holding external commands Updating PATH(QEMU binaries as an example):­ export PATH=/opt/qemu­2.0/bin:$PATH Can add above line to ~/.bash_profile, ~/.bashrc Or write the settings in a script and invoke script using source command ● LD_LIBRARY_PATH List of directories holding dependent dynamic libraries export LD_LIBRARY_PATH=~/mylib:$LD_LIBRARY_PATH (or) add ~/mylibs to /etc/ld.so.conf and run ldconfig once or reboot
  • 37.
    Rajesh Sola,CDAC-ACTS,Pune 37 Appendix- Appending dtb file to kernel image ● Configure kernel ● Append kernel image and dtb file cd arch/arm/boot cat zImage vexpress­v2p­ca9.dtb > zImage­dtb ● Convert to u­boot format mkimage ­A arm ­O linux ­C none ­T kernel ­a 0x60008000 ­e 0x60008000 ­n 'Linux­4.1.2­vexpress' ­d zImage­dtb uImage­dtb ● Copy zImage­dtb, uImage­dtb as desired ● Reference:­ Device Tree for Dummies, Free Electrons
  • 38.
    Rajesh Sola,CDAC-ACTS,Pune 38 Appendix– ELF Format, Tools ● Executable and Linkable Format, applicable for relocatable object files, executables, shared object files etc. https://en.wikipedia.org/wiki/Executable_and_Linkable_Format http://elinux.org/Executable_and_Linkable_Format_(ELF) ● Tools for ELF files file arm­linux­gnueabihf­nm arm­linux­gnueabihf­objdump # ­d, ­t, ­S arm­linux­gnueabihf­readelf # ­h arm­linux­gnueabihf­ldd # ­­root /mnt/image arm­linux­gnueabihf­strings arm­linux­gnueabihf­strip
  • 39.
    Rajesh Sola,CDAC-ACTS,Pune 39 References,Acknowledgments ● Building Embedded Linux Systems, Karim Yaghmour, O'Reilly Media ● Device Tree for Dummies, Thomas Petazzoni, Free Electrons ● How to Cross Compile the Linux Kernel with Device Tree Support, Rajesh Sola, Open Source For You Magazine(EFY Group), September 2014 ● Thanks to Mr.Babu Krishnamurthy for his valuable inputs on working with Beagle Board xM, Beagle Bone Black. ● Thanks to the following presentation template http://templates.libreoffice.org/template­center/university­course­mate rial­template ● Thanks to the community,contributors of opensuse,libreoffice and other open source components listed in beginning. https://www.opensuse.org/ https://www.libreoffice.org/
  • 40.
    Rajesh Sola,CDAC-ACTS,Pune 40 ThankYou rajeshsola@gmail.com