in Embedded, Linux

Embedded Linux S3C2440 Application Development and Debugging

Summary

Write your own application and include the application into the final image to be downloaded into the S3C2440 board, and you can debug the application by using GDB.

User Application

Below is the simple user application, print a string, and reverse the string and print again.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void my_print(char *string)
{
  printf("The string is %s\n", string);
}

void my_print2(char *string)
{
  char *string2;
  size_t size,i;

  size = strlen(string);
  string2 = (char *) malloc(size + 1);

  for (i = 0; i < size; i++)
    string2[size - i - 1] = string[i];

  string2[size] = '\0';

  printf("The sring printed backward is %s\n", string2);
}

int main (int argc, char *argv)
{
  char my_string[] = "hello there";
  my_print(my_string);
  my_print2(my_string);
}

Building User Application

[root@localhost myapp]# vim Makefile

The Makefile is as below,


BROUTPUT = /home/iot/mini2440/buildroot-2013.2/output CC = arm-linux-gcc LDFLAGS = -L$(BROUTPUT)/target/lib CFLAGS = -g OBS = greeting.o greeting: $(OBS) $(CC) $(CFLAGS) $(LDFLAGS) $(OBS) -o greeting greeting.o: greeting.c $(CC) $(CFLAGS) -c greeting.c clean: rm greeting.o

Build the application,

[root@localhost myapp]# make clean
rm greeting.o
[root@localhost myapp]# make
arm-linux-gcc -g -c greeting.c
arm-linux-gcc -g -L/home/iot/mini2440/buildroot-2013.2/output/target/lib greeting.o -o greeting
[root@localhost myapp]# file greeting
greeting: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
[root@localhost myapp]# ls -al gree*
-rwxr-xr-x. 1 root root 7714 Apr 29 09:58 greeting
-rw-r--r--. 1 root root  537 Dec 28 14:56 greeting.c
-rw-r--r--. 1 root root 3912 Apr 29 09:58 greeting.o

Check the libraries usage of the program, the libraries are linked,

[root@localhost myapp]# arm-linux-readelf -d greeting

Dynamic section at offset 0x74c contains 18 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libc.so.0]
 0x0000000c (INIT)                       0x83a8
 0x0000000d (FINI)                       0x86e8
 0x00000019 (INIT_ARRAY)                 0x10740
 0x0000001b (INIT_ARRAYSZ)               4 (bytes)
 0x0000001a (FINI_ARRAY)                 0x10744
 0x0000001c (FINI_ARRAYSZ)               4 (bytes)
 0x00000004 (HASH)                       0x8108
 0x00000005 (STRTAB)                     0x82bc
 0x00000006 (SYMTAB)                     0x819c
 0x0000000a (STRSZ)                      177 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000015 (DEBUG)                      0x0
 0x00000003 (PLTGOT)                     0x10804
 0x00000002 (PLTRELSZ)                   56 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0x8370
 0x00000000 (NULL)                       0x0
[root@localhost myapp]# pwd
/home/iot/mini2440/myapp
[root@localhost myapp]#

The application uses library of libc.so.0, the Busybox has statically linked to the libraries, so it doesn’t need libraries to run. But this application requires dynamic libraries to run, we need to copy the libraries to the rootfs. When cross-compile tool chain, the rootfs was generated contains a complete directory structure of rootfs.

[root@localhost rootfilesystem]# ls
create_rootfs_bash.sh  initramfs.cpio  mkyaffs2image-128M  rootfs  rootfs-base  rootfs.img  yaffs2-4e188b0  yaffs2-4e188b0.tar.gz
[root@localhost rootfilesystem]# pwd
/home/iot/mini2440/rootfilesystem
[root@localhost rootfilesystem]#

The shell script “create_rootfs_bash.sh” will create initramfs.cpio, which will be compiled into the linux kernel zImage.

[root@localhost rootfilesystem]# vim create_rootfs_bash.sh

The complete shell script is as below,

#!/bin/sh
echo "------Create rootfs --------"
rm -fr rootfs
rm initramfs.cpio
mkdir rootfs
pushd rootfs

echo "--------Create root,dev....----------"
mkdir root dev etc boot tmp usr var sys proc lib mnt home
mkdir etc/init.d etc/rc.d etc/sysconfig lib/modules
mkdir usr/sbin usr/bin usr/lib usr/modules
echo "---------Copy from busybox, rootfs-base, libs -----------"
cp -aP /home/iot/mini2440/busybox-1.19.4/_install/* .
ln -s bin/busybox init
ln -s /proc/mounts etc/mtab
cp -arP ../rootfs-base/* /home/iot/mini2440/rootfilesystem/rootfs/
cp /home/iot/mini2440/linux-3.8.7/System.map boot/

#Copy applications
cp /home/iot/mini2440/myapp/greeting usr/bin
cp /home/iot/mini2440/myapp/thread_demo* usr/bin

cp $TARGET_DIR/usr/bin/gdbserver usr/bin
cp $TARGET_DIR/usr/bin/op* usr/bin
cp $TARGET_DIR/usr/bin/ldd usr/bin
cp $TARGET_DIR/usr/bin/objcopy usr/bin
cp $TARGET_DIR/usr/bin/objdump usr/bin

cp /home/iot/mini2440/buildroot-2013.02/output/target/usr/bin/gdbserver usr/bin

cp /home/iot/mini2440/buildroot-2013.02/output/target/usr/bin/ldd usr/bin

cp -P /home/iot/mini2440/buildroot-2013.02/output/target/lib/* lib/

cp -P $TARGET_DIR/lib/* lib/
cp -P $TARGET_DIR/usr/lib/libpopt* usr/lib
cp -P $TARGET_DIR/usr/lib/libbfd* usr/lib
cp -P $TARGET_DIR/usr/lib/libintl* usr/lib
cp -P $TARGET_DIR/usr/lib/libstdc++* usr/lib
cp -P $TARGET_DIR/usr/lib/libz* usr/lib
cp -P $TARGET_DIR/usr/lib/libopcodes* usr/lib

chown -R root.root ../rootfs

echo "---------make node dev/console dev/null-----------------"
mknod -m 600 dev/console c 5 1
mknod -m 600 dev/null c 1 3
chmod 666 dev/console
chmod 666 dev/null
mknod /dev/ptmx c 5 2
mkdir mnt/etc mnt/yaffs mnt/data mnt/temp
mkdir var/lib var/lock var/run var/tmp
chmod 1777 tmp
chmod 1777 var/tmp

# Create cpio image
find . | cpio -H newc -o > ../initramfs.cpio

# Move out of working directory
popd


Copy the library greeting.c used below lines:

#Copy applications
cp /home/iot/mini2440/myapp/greeting usr/bin

cp $TARGET_DIR/usr/bin/gdbserver usr/bin

cp /home/iot/mini2440/buildroot-2013.02/output/target/usr/bin/gdbserver usr/bin

cp /home/iot/mini2440/buildroot-2013.02/output/target/usr/bin/ldd usr/bin

cp -P /home/iot/mini2440/buildroot-2013.02/output/target/lib/* lib/

Create “initramfs.cpio” and build Linux kernel to include the new “initramfs.cpio” into zImage.

[root@localhost rootfilesystem]# echo $TARGET_DIR
/home/iot/mini2440/buildroot-2013.02/output/target
[root@localhost rootfilesystem]#
[root@localhost rootfilesystem]# pwd
/home/iot/mini2440/rootfilesystem
[root@localhost rootfilesystem]# ./create_rootfs_bash.sh
[root@localhost rootfilesystem]# cd /home/iot/mini2440/linux-3.8.7/
[root@localhost linux-3.8.7]# pwd
/home/iot/mini2440/linux-3.8.7
[root@localhost linux-3.8.7]# make clean
[root@localhost linux-3.8.7]# make

The new zImage will be built under folder: “/home/iot/mini2440/linux-3.8.7/arch/arm/boot/zImage”

Using new zImage to Boot the mini2440 board

[root@localhost linux-3.8.7]# ll initramfs.cpio
lrwxrwxrwx. 1 root root 32 Apr 25 16:18 initramfs.cpio -> ../rootfilesystem/initramfs.cpio
[root@localhost linux-3.8.7]#

Connect the USB cable and Serial port cable, and use minicom to set up the connection, switch on the S3C2440 board.

[root@localhost mini2440]# ./download_image.sh

In the minicom interface:

Enter your selection: k
USB host is connected. Waiting a download.

Now, Downloading [ADDRESS:30000000h,TOTAL:5143250]
RECEIVED FILE SIZE: 5143250 (18KB/S, 270S)
Downloaded file at 0x30000000, size = 5143240 bytes
Found block size = 0x00500000
Erasing...    ... done
Writing...    ... done
Written 5143240 bytes

##### FriendlyARM BIOS 2.0 for 2440 #####
[x] format NAND FLASH for Linux
[v] Download vivi 
[k] Download linux kernel 
[y] Download root_yaffs image 
[a] Absolute User Application
[n] Download Nboot for WinCE 
[l] Download WinCE boot-logo
[w] Download WinCE NK.bin 
[d] Download & Run 
[z] Download zImage into RAM 
[g] Boot linux from RAM 
[f] Format the nand flash 
[b] Boot the system 
[s] Set the boot parameters 
[u] Backup NAND Flash to HOST through USB(upload) 
[r] Restore NAND Flash from HOST through USB 
[q] Goto shell of vivi 
[i] Version: 1026-2K
Enter your selection: 

Boot up the S3C2440 board with the new zImage included the greeting application. The on board testing result is as below,

[root@mini2440 bin]# ./greeting
The string is hello there
The sring printed backward is ereht olleh
[root@mini2440 bin]#
[root@mini2440 bin]# pwd
/usr/bin
[root@mini2440 bin]#

Debugging the new application

GDB server has already been included into zImage, in the directory /usr/bin

The board IP address is 192.168.0.11.

[root@mini2440 bin]# pwd
/usr/bin
[root@mini2440 bin]# ifconfig
eth0      Link encap:Ethernet  HWaddr 08:90:90:90:90:90
          inet addr:192.168.0.11  Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1375 errors:0 dropped:0 overruns:0 frame:0
          TX packets:989 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:146472 (143.0 KiB)  TX bytes:85521 (83.5 KiB)
          Interrupt:51 Base address:0xc300

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

[root@mini2440 bin]#

Start the gdbserver using “gdbsever :1234 greeting”, or use command “gdbserver 192.168.0.11:1234 greeting”, there is only one Ethernet port and on IP address, it is equivalent.

[root@mini2440 bin]# gdbserver 192.168.0.11:1234 greeting
Process greeting created; pid = 481
Listening on port 1234

Debug the application on the host,

[root@localhost myapp]# arm-linux-gdb greeting
GNU gdb (GDB) 7.5.1
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-buildroot-linux-uclibcgnueabi".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/iot/mini2440/myapp/greeting...done.

Now you can use debugging command at gdb command prompt.

(gdb) target remote 192.168.0.11:1234
Remote debugging using 192.168.0.11:1234

On the S3C2440 mini2440 board console will show,

[root@mini2440 bin]# gdbserver :1234 greeting
Process greeting created; pid = 476
Listening on port 1234
Remote debugging from host 192.168.0.1

On the host, there is a warning,

Remote debugging using 192.168.0.11:1234
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
0xb6ff1e40 in ?? ()

GDB doesn’t know where to find the dynamic libraries, use below command to tell GDB the information,

(gdb) set sysroot /home/iot/mini2440/buildroot-2013.02/output/target
Reading symbols from /home/iot/mini2440/buildroot-2013.02/output/target/lib/ld-uClibc.so.0...(no debugging symbols found)...done.
Loaded symbols for /home/iot/mini2440/buildroot-2013.02/output/target/lib/ld-uClibc.so.0

Continue to use GDB commands to debug the application.

(gdb) target remote 192.168.0.11:1234
Remote debugging using 192.168.0.11:1234
Reading symbols from /home/iot/mini2440/buildroot-2013.02/output/target/lib/ld-uClibc.so.0...(no debugging symbols found)...done.
Loaded symbols for /home/iot/mini2440/buildroot-2013.02/output/target/lib/ld-uClibc.so.0
0xb6ff1e40 in _start () from /home/iot/mini2440/buildroot-2013.02/output/target/lib/ld-uClibc.so.0
(gdb) list
13    size_t size,i;
14
15    size = strlen(string);
16    string2 = (char *) malloc(size + 1);
17
18    for (i = 0; i < size; i++)
19      string2[size - i - 1] = string[i];
20
21    string2[size] = '\0';
22
(gdb) list
23    printf("The sring printed backward is %s\n", string2);
24  }
25
26  int main (int argc, char *argv)
27  {
28    char my_string[] = "hello there";
29    my_print(my_string);
30    my_print2(my_string);
31  }
(gdb) list
Line number 32 out of range; greeting.c has 31 lines.
(gdb) b 18
Note: breakpoint 1 also set at pc 0x8614.
Breakpoint 2 at 0x8614: file greeting.c, line 18.
(gdb) b 19
Breakpoint 3 at 0x8620: file greeting.c, line 19.
(gdb) c
Continuing.

Breakpoint 1, my_print2 (string=0xbefffcbc "hello there") at greeting.c:18
18    for (i = 0; i < size; i++)
(gdb) pirnt i
Undefined command: "pirnt".  Try "help".
(gdb) print i
$2 = 3204447420
(gdb) c
Continuing.

Breakpoint 3, my_print2 (string=0xbefffcbc "hello there") at greeting.c:19
19      string2[size - i - 1] = string[i];
(gdb) print i
$3 = 0
(gdb) c
Continuing.

Breakpoint 3, my_print2 (string=0xbefffcbc "hello there") at greeting.c:19
19      string2[size - i - 1] = string[i];
(gdb) print i
$4 = 1
(gdb) c
Continuing.

Breakpoint 3, my_print2 (string=0xbefffcbc "hello there") at greeting.c:19
19      string2[size - i - 1] = string[i];
(gdb) print i
$5 = 2
(gdb) print string
$6 = 0xbefffcbc "hello there"
(gdb) c
Continuing.

Breakpoint 3, my_print2 (string=0xbefffcbc "hello there") at greeting.c:19
19      string2[size - i - 1] = string[i];
(gdb) print i
$7 = 3
(gdb) c
Continuing.

Breakpoint 3, my_print2 (string=0xbefffcbc "hello there") at greeting.c:19
19      string2[size - i - 1] = string[i];
(gdb) print i
$8 = 4
(gdb) c
Continuing.

Breakpoint 3, my_print2 (string=0xbefffcbc "hello there") at greeting.c:19
19      string2[size - i - 1] = string[i];
(gdb) print i
$9 = 5
(gdb) c
Continuing.

Breakpoint 3, my_print2 (string=0xbefffcbc "hello there") at greeting.c:19
19      string2[size - i - 1] = string[i];
(gdb) c
Continuing.

Breakpoint 3, my_print2 (string=0xbefffcbc "hello there") at greeting.c:19
19      string2[size - i - 1] = string[i];
(gdb) c
Continuing.

Breakpoint 3, my_print2 (string=0xbefffcbc "hello there") at greeting.c:19
19      string2[size - i - 1] = string[i];
(gdb) c
Continuing.

Breakpoint 3, my_print2 (string=0xbefffcbc "hello there") at greeting.c:19
19      string2[size - i - 1] = string[i];
(gdb) c
Continuing.

Breakpoint 3, my_print2 (string=0xbefffcbc "hello there") at greeting.c:19
19      string2[size - i - 1] = string[i];
(gdb) clear
Deleted breakpoint 3
(gdb) c
Continuing.
[Inferior 1 (process 481) exited normally]
(gdb) quit
[root@localhost myapp]

At the end, the S3C2440 mini2440 board will show,

[root@mini2440 bin]# gdbserver :1234 greeting
Process greeting created; pid = 476
Listening on port 1234
Remote debugging from host 192.168.0.1
The string is hello there
The sring printed backward is ereht olleh

Reference

Embedded Linux S3C2440 environment setup

Write a Comment

Comment

Webmentions

  • Embedded Linux S3C2440 Networking – Xiong Hui Lin's Personal page May 23, 2019

    […] to Embedded Linux S3C2440 Application Development and Debugging for detail on the script […]