Tuesday, November 27, 2012

The Essential Of Hacking Methodology From The Perspective Of Embedded Hacker

The Essential Of Hacking Methodology From The Perspective Of Embedded Hacker

by cawan (cawan[at]ieee.org or chuiyewleong[at]hotmail.com)

on 27/11/2012

Hacking is about an action to a system. The system can be a single box or machine,
or can be a group of boxes or machines to be interconnected via a center communication
bus, which is usually known as network. For the case of single box or machine,
in fact, it can be assumed as a group of peripherals which are managed by a center
processing unit, over the system communication bus, such as PCI, PCIe, I2C, SPI, USB,
and etc. The group of peripherals can be in chip form or card form. In chip form, it
can be sound interface, network interface, video interface, or RAM interface, which is
defined as the lowest level of interface within the system. So, their communication
bus should be I2C, SPI, USB, or some variation of such standard communication bus. On
the other hand, in card form, it can be enhanced version of sound interface, video
interface, network interface, or some forms of extended features such as I/O card,
optical interface, or RF interface. Besides, there are also some custom communication
interface such as Cobranet, Ethersound, LonWorks, ARCNET, and etc. Well, they are
connected via PCI or PCIe. Regarding to the storage access such as hard disk, optical
driver, or SSD, they are connected via PATA (IDE), SATA, or SCSI bus. Since there are
so many types of buses in the same box or machine, the processor needs a chipset to
manage those buses in performing multiple access or multiplexing in order to allow
those peripherals can be run accordingly. In fact, the chipset is only necessary for
those systems which their processors are in von neumann architecture, where its
address bus and data bus are shared to the same physical bus. On the other hand, for
harvard architecture based processor, its address bus and data bus are separated, and
hence the chipset can be skipped.

For the case of a group of boxes or machines being interconnected via the network,
each of them must comply to a standard protocol among each others. In link layer, they
might need to comply ethernet, wifi, pppoe, or mpls, which is depending to the
physical medium of the associated communication bus. In higher layer, let's say the
network layer, almost all of them comply to TCP/IP. So, the TCP/IP is undoubtedly the
protocol glue among all the boxes or machines. From here onwards, the rest of the
issues are about application layer such as HTTP, HTTPS, FTP, TFTP, Telnet, SNMP, SMTP,
POP3, IMAP, and etc... which are the most common names in networking. On the other
hand, for the case of industrial networking, there are a huge variety of them, which
are dependent to the application domains. For example, in building automation industry,
there are bacnet, modbus, lontalk, profibus, and some others which are manufacturer
proprietary. Besides, in scada industry, there are modbus, iec60870, iec61850, and a
lot of others proprietary implemented items.

In order to run the hardware, we need software. So, we need something to manage the
hardware in overall, and this is kernel. The kernel will control various types of
hardware with appropriate kernel module or device driver. The kernel executive will
ensure the interoperability among the hardware resources. From application point of
view, the hardware resources are operated in transparent way via appropriate system
call. Of course, there are some protections imposed such as the kernel space is
prohibited to be accessed from user mode. Besides, each process space is isolated
among each other to avoid data collision or overwrite intentionally or unintentionally.

From hacker perspective, there are a lot of exploitation points can be considered to
launch the attacks. In general hacking methodology, majority of the attacks are about
exploiting the buffer to overwrite some system structures or registers, and causes
the system run unexpectedly. The buffer exploitation can be about the stack or the
heap. Besides, it is possible to exploit the kernel stack or heap from user mode via
some vulnerable kernel modules or device drivers. In order to control the system
once it is exploited, we need a piece of shellcode. The shellcode is something highly
customized which is dependent to the processor platform, OS platform, operation mode
(kernel/user), intentional action, avoidance of illegal characters, and etc. So, all
the attacks need to start from a target application. If the application runs locally,
then the malform local user input is the root cause to incur exploitation. In addition,
if the application is network savvy, then the attack can be launched from anywhere
within the network. Before launching any attack on the system at another part of the
same network, it is important to understand the protocol being used by the system.
So, a sniffer is necessary in this case to study the protocol based on the network
packets being captured. If the protocol is proprietary, then it needs some times to
analyze the packets sequence in understanding the protocol in details. However, if
the protocol is open source, then the analysis process will getting much easier by
referring the specification from time to time. On the other hand, it is possible to
perform fuzzing process to the system. With some level of understanding to the
protocol, it is possible to manipulate the data in different fields in the network
packet automatically and observe the reaction of the system. Yes, the fuzzing process
is some kind of trial and error or brute-force approach, but it is really effective.
Besides, it is possible to perform code analysis to the application to find any
vulnerability to be exploited, but it is really time-consuming.

From embedded hacker perspective, the hacking methodology suppose to be much simpler.
Due to the reduced hardware resources in embedded system, it is impossible to implement
full security protection which is really resouce-intensive. In fact, a large portion
of embedded linux system even didn't implement NX and ASLR all together. So, in this
case, ROP can be skipped when we are designing the exploit and shellcode for such
systems. Besides, for some very special cases, some network applications are even
don't have sanity check to the network packets. Thus, it is simpler to be exploited.
However, due to the nature of embedded system which is highly customized, it is a
need to master the skill of shellcode design for RISC processors such as ARM, MIPS,
and PPC. So, it is important to make those different types of instruction sets at
your own disposal. Besides, it is important to note that the peripherals being used
in embedded system are not something in standard or in generic. Instead, they are
something special with customized device driver. From the angle of embedded enginners
who designing the device driver, they just need to ensure the device driver can run
in the most stable way but not in the most secure way. Hence, it is most probably the
device driver is vulnerable to be exploited. Besides, the security concern to the
embedded system is really less as compared to the proper computer system. The reason
is simple, it is really not many people can imagine a headless embedded system is
hackable and the value behind to abuse the hacked embedded system. It is really hard
to convince somebody about an embedded system product can be changed into a proprietary
sniffer to perform dedicated MITM attack to the network. On the other hand, regarding
to the physical attack, it is really not hard to duplicate the data image from flash
chip. Besides, from higher level perspective, the ramdisk file can be manipulated
which is a remarkable security breach. In addition, the simple implementation of
bootloader does not has good security implication to block unauthorized access to
the system. In other words, once the configuration interface of the bootloader is
getting accessed, then it is just a few of commands to duplicate certain partitions in
flash to a network drive as data image. It is crucial to remember the term of readonly
in certain file system for embedded system is really nothing to do with the security.
It just means we can't simply add or remove a file from the file system, but we can
definitely overwrite the whole partition by using the device file in /dev. Nothing
special here.

Now, what is the essential of hacking methodology from the perspective of embedded
hacker ? Well, we already know hacking is just an action to a box or to a system.
Then what is the core of embedded system hacking ? In order to have a substantial
idea to start any meaningful attack to an embedded system, it is necessary to
understand the system and protocol internals. So, reverse engineering should be the
core of embedded system hacking methodology. When talking about the reversing of
binary, it comprises static and dynamic approaches. In static approach, it is about
to perform disassembly of the binary with any type of disassemblers. However, IDA Pro
should be the one with highest ranking to master with. Yes, it is really good in
generating comprehensive output in assembly language level with proper formatting.
But, in most of the times, we are only interested to some portions of the codes. So,
it is a little bit hard to find those little portions of codes from the big pool of
assembly instructions in IDA Pro enviroment. Of course, we can based on some special
pattern of string to do the job, but the existence of such string is not always true.
So, we need to cooperate with the dynamic approach. By using a good debugger such as
gdb, it is possible to set a breakpoint at an interesting address of symbol, and let
the program counter hit on the breakpoint. Then, it is easy to backtrace or to dump
some meaningful information from memory as guideline in locating the code portion
that we are interested with from the big pool of assembly instructions under the
IDA Pro environment. Yes, both of the static and dynamic approaches should be worked
together in proper way, and this is the fundamental skill of an embedded hacker.
On the other hand, the architecture of RISC processors should be in good
understanding. So, the concepts of calling conventions, registers, addressing modes,
operation modes, and memory management for each of the RISC processors should be in
our disposal. In addition, it is important to understand the linux kernel in detail.
Hence, the internals of runtime, loader, shared library, kernel module, and system
call should be with good understanding. Besides, it is also important to understand
the communication bus of the peripherals such as I2C, SPI, PCI, USB, and etc. By
understanding them, it is really helpful to interpret the communication data being
captured in signal level. Well, it is crucial in doing injection to find vulnerability
in signal level or in bus level. The possibility is only limited by our imagination.
As conclusion, reversing techniques in terms of hardware and software should be the
core of hacking methodology for a serious embedded hacker.

pdf version:

http://www.scribd.com/doc/114591513/The-Essential-of-Hacking-Methodology-From-the-Perspective-of-Embedded-Hacker

Monday, November 26, 2012

A Simple Lab Guide of Using GDB in Embedded Linux System

A Simple Lab Guide of Using GDB in Embedded Linux System

by cawan (cawan[at]ieee.org or chuiyewleong[at]hotmail.com)

on 27/11/2012

GDB is a useful debugging tool for linux developer as well as linux hacker in
understanding the binary running in the system. So, it is a need for embedded linux
developer to master the skill of GDB too. However, due to the nature of embedded
system which is highly customized in term of processor platform, it is a little bit
tricky in applying the basic GDB skill in embedded platform. First, it is important
to cross compile the version of GDB which is compatible to the embedded platform.
Well, this has been discussed in the previous paper in this blog, "How To Cross
Compile GDB and Run in Embedded System". Second, it is always a necessity to
understand the architecture internal of the RISC processor, such as MIPS, ARM, PPC,
and etc. Besides, for each RISC platform, it is crucial to know the registers,
instruction sets, addressing modes, operation modes, calling conventions, status
control, and much much more in detail. Third, it is also a need to understand how
linux works such as the boot process, file system, runtime, shared library, system
call, and etc. In addition, it is an advantage to know more about the linux kernel.
So, in order use GDB for relevant jobs in proper, it is important to have some level
of fundamental knowledges in the aforementioned topics. On the other hand, the GDB is
also a precious tool to assist in understanding the system internal in further
details. Yes, it is bidirectional. Besides, it is really recommended to perform local
debugging with GDB, instead of remote debugging with GDBServer. Well, the reasons are
from a number of aspects, but we will show in examples in our discussion later. So,
without wasting any more time, let us start our demonstration of GDB in embedded
linux system right now. We are having a not responding process and we need to figure
out the root cause of the problem. Our embedded platform is MIPS.

tango3[gdb]# ./gdb
GNU gdb (GDB) 7.1
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
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 "mips-linux-gnu".
For bug reporting instructions, please see:
.
Setting up the environment for debugging gdb.
No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n])
[answered N; input not from terminal]
No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n])
[answered N; input not from terminal]
/root/cawan/mips-4.3/bin/gdb-7.1/gdb/.gdbinit:8: Error in sourced command file:
No breakpoint number 0.
(gdb) attach 766
Attaching to process 766
Reading symbols from /bin/busybox...(no debugging symbols found)...done.
Reading symbols from /lib/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/ld.so.1
0x2ac050a8 in nanosleep () from /lib/libc.so.6
(gdb)

Well, the pid of the not responding process is 766 and we attach into it now. From
the message output, it seems the program counter is stucked at nanosleep() in
/lib/libc.so.6. Let's do a backtrace.

(gdb) bt
#0  0x2ac050a8 in nanosleep () from /lib/libc.so.6
#1  0x2ac04d8c in sleep () from /lib/libc.so.6
#2  0x0045b2bc in ?? ()

Yes, the nanosleep() is being called by sleep(). How to know how long it will sleep ?
We know that sleep() will accept a single parameter in the unit of second. But, what
is the situation when the sleep() calls nanosleep() ? Let us check the function
prototype of nanosleep().

int nanosleep(const struct timespec *req, struct timespec *rem);

struct timespec {
    time_t tv_sec;        /* seconds */
    long   tv_nsec;       /* nanoseconds */
};

Well, the nanosleep() accepts 2 parameters in the format of timespec structure. Now,
we need to know a little bit about the calling convention in MIPS environment. In
general, the first 4 paramenters will be stored in register $a0 to $a3, and the rest
will be in stack. So, while nanosleep() accepts 2 parameters, then they are should be
in $a0 and $a1. Let us check now.

(gdb) info reg
          zero       at       v0       v1       a0       a1       a2       a3
 R0   00000000 fffffff8 00000204 00000000 7fb737f8 7fb737f8 00000000 00000001
            t0       t1       t2       t3       t4       t5       t6       t7
 R8   00000031 2ab67540 00000000 7fb73878 ffffffff 7fb737d0 2aab1b84 00000000
            s0       s1       s2       s3       s4       s5       s6       s7
 R16  000003e8 00020000 00000000 7fb73800 7fb737f8 7fb73880 80000000 7fffffff
            t8       t9       k0       k1       gp       sp       s8       ra
 R24  000000be 2ac05084 00000000 00000000 2acc9950 7fb737e0 2ac05084 2ac04d8c
        status       lo       hi badvaddr    cause       pc
      00001c13 0002af19 000001e5 2ac9a570 50808020 2ac050a8
          fcsr      fir  restart
      00000000 01739300 00000204

Fine, both $a0 and $a1 share a single parameter, 7fb737f8. So, we should dump the
address and it should be the timespec structure. Let's verify.

(gdb) x/16x $a0
0x7fb737f8:     0x000003d3      0x344b26ae      0x00020000      0x00000000
0x7fb73808:     0x00000000      0x00000000      0x00000000      0x00000000
0x7fb73818:     0x00000000      0x00000000      0x00000000      0x00000000
0x7fb73828:     0x00000000      0x00000000      0x00000000      0x00000000
(gdb) x/16d $a0
0x7fb737f8:     979     877340334       131072  0
0x7fb73808:     0       0       0       0
0x7fb73818:     0       0       0       0
0x7fb73828:     0       0       0       0

Yes, it seems the not responding process will sleep for 979 seconds or 877340334 in
nano seconds. However, in fact, the not responding process is created by a simple
command line.

tango3[gdb]# sleep 1000 &
766

So, we suppose to get 1000 seconds in timespec structure, but why we get 979 seconds
now ? Let's check again.

(gdb) quit
A debugging session is active.

        Inferior 1 [process 766] will be detached.

Quit anyway? (y or n) y
Detaching from program: /bin/busybox, process 766

tango3[gdb]# ps
PID   USER     TIME   COMMAND
    1 root       0:01 init      
    2 root       0:00 [kthreadd]
    3 root       0:00 [ksoftirqd/0]
    4 root       0:00 [events/0]
    5 root       0:00 [khelper]
   41 root       0:00 [kblockd/0]
   42 root       0:00 [ata/0]
   43 root       0:00 [ata_aux]
   46 root       0:00 [khubd]
   48 root       0:00 [kseriod]
   49 root       0:00 [kmmcd]
   61 root       0:00 [pdflush]
   62 root       0:00 [pdflush]
   63 root       0:00 [kswapd0]
   64 root       0:00 [kprefetchd]
   65 root       0:00 [aio/0]
  658 root       0:00 [scsi_eh_0]
  662 root       0:00 [scsi_eh_1]
  699 root       0:00 [sigmblockd]
  717 root       0:00 [sigm_write_cach]
  724 root       0:00 /sbin/hotplug2 --no-coldplug --persistent --override --ma
  731 root       0:00 /sbin/watchdog -t 20 -T 30 /dev/watchdog
  738 root       0:00 -sh
  739 root       0:00 /sbin/syslogd -n -m 0
  740 root       0:00 /sbin/klogd -n
  751 root       0:00 [rpciod/0]
  773 root       0:00 ps
tango3[gdb]#

Well, it seems the sleep timer has been expired and the process is returned. We
should take an important note here, unlike debuggers in windows environment, while
GDB is detached from a process, the process will not be closed. Let us verify now.

tango3[gdb]# sleep 1000 &
774
tango3[gdb]# ps
PID   USER     TIME   COMMAND
    1 root       0:01 init      
    2 root       0:00 [kthreadd]
    3 root       0:00 [ksoftirqd/0]
    4 root       0:00 [events/0]
    5 root       0:00 [khelper]
   41 root       0:00 [kblockd/0]
   42 root       0:00 [ata/0]
   43 root       0:00 [ata_aux]
   46 root       0:00 [khubd]
   48 root       0:00 [kseriod]
   49 root       0:00 [kmmcd]
   61 root       0:00 [pdflush]
   62 root       0:00 [pdflush]
   63 root       0:00 [kswapd0]
   64 root       0:00 [kprefetchd]
   65 root       0:00 [aio/0]
  658 root       0:00 [scsi_eh_0]
  662 root       0:00 [scsi_eh_1]
  699 root       0:00 [sigmblockd]
  717 root       0:00 [sigm_write_cach]
  724 root       0:00 /sbin/hotplug2 --no-coldplug --persistent --override --ma
  731 root       0:00 /sbin/watchdog -t 20 -T 30 /dev/watchdog
  738 root       0:00 -sh
  739 root       0:00 /sbin/syslogd -n -m 0
  740 root       0:00 /sbin/klogd -n
  751 root       0:00 [rpciod/0]
  774 root       0:00 sleep 1000
  786 root       0:00 ps
tango3[gdb]# ./gdb
GNU gdb (GDB) 7.1
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
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 "mips-linux-gnu".
For bug reporting instructions, please see:
.
Setting up the environment for debugging gdb.
No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n])
[answered N; input not from terminal]
No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n])
[answered N; input not from terminal]
/root/cawan/mips-4.3/bin/gdb-7.1/gdb/.gdbinit:8: Error in sourced command file:
No breakpoint number 0.
(gdb) attach 774
Attaching to process 774
Reading symbols from /bin/busybox...(no debugging symbols found)...done.
Reading symbols from /lib/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/ld.so.1
0x2ac050a8 in nanosleep () from /lib/libc.so.6
(gdb) detach
Detaching from program: /bin/busybox, process 774
(gdb) quit
tango3[gdb]# ps
PID   USER     TIME   COMMAND
    1 root       0:01 init      
    2 root       0:00 [kthreadd]
    3 root       0:00 [ksoftirqd/0]
    4 root       0:00 [events/0]
    5 root       0:00 [khelper]
   41 root       0:00 [kblockd/0]
   42 root       0:00 [ata/0]
   43 root       0:00 [ata_aux]
   46 root       0:00 [khubd]
   48 root       0:00 [kseriod]
   49 root       0:00 [kmmcd]
   61 root       0:00 [pdflush]
   62 root       0:00 [pdflush]
   63 root       0:00 [kswapd0]
   64 root       0:00 [kprefetchd]
   65 root       0:00 [aio/0]
  658 root       0:00 [scsi_eh_0]
  662 root       0:00 [scsi_eh_1]
  699 root       0:00 [sigmblockd]
  717 root       0:00 [sigm_write_cach]
  724 root       0:00 /sbin/hotplug2 --no-coldplug --persistent --override --ma
  731 root       0:00 /sbin/watchdog -t 20 -T 30 /dev/watchdog
  738 root       0:00 -sh
  739 root       0:00 /sbin/syslogd -n -m 0
  740 root       0:00 /sbin/klogd -n
  751 root       0:00 [rpciod/0]
  774 root       0:00 sleep 1000
  791 root       0:00 ps
tango3[gdb]#

Well, the process being attached will not exit when it is detached from GDB. So,
by attach and detach the sleeping process for several times, we should realize
something meaningful.

tango3[gdb]# sleep 1000 &
795
tango3[gdb]# ./gdb
GNU gdb (GDB) 7.1
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
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 "mips-linux-gnu".
For bug reporting instructions, please see:
.
Setting up the environment for debugging gdb.
No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n])
[answered N; input not from terminal]
No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n])
[answered N; input not from terminal]
/root/cawan/mips-4.3/bin/gdb-7.1/gdb/.gdbinit:8: Error in sourced command file:
No breakpoint number 0.
(gdb) attach 795
Attaching to process 795
Reading symbols from /bin/busybox...(no debugging symbols found)...done.
Reading symbols from /lib/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/ld.so.1
0x2ac050a8 in nanosleep () from /lib/libc.so.6
(gdb) x/16d $a0
0x7fc837f8:     985     817127037       131072  0
0x7fc83808:     0       0       0       0
0x7fc83818:     0       0       0       0
0x7fc83828:     0       0       0       0
(gdb) detach
Detaching from program: /bin/busybox, process 795
(gdb) attach 795
Attaching to program: /bin/busybox, process 795
Reading symbols from /lib/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/ld.so.1
0x2ac050a8 in nanosleep () from /lib/libc.so.6
(gdb) x/16d $a0
0x7fc837f8:     942     6108777 131072  0
0x7fc83808:     0       0       0       0
0x7fc83818:     0       0       0       0
0x7fc83828:     0       0       0       0
(gdb) detach
Detaching from program: /bin/busybox, process 795
(gdb) attach 795
Attaching to program: /bin/busybox, process 795
Reading symbols from /lib/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/ld.so.1
0x2ac050a8 in nanosleep () from /lib/libc.so.6
(gdb) x/16d $a0
0x7fc837f8:     911     935667926       131072  0
0x7fc83808:     0       0       0       0
0x7fc83818:     0       0       0       0
0x7fc83828:     0       0       0       0
(gdb)

Nice, it seems the values in timespec structure keep deducting even though the process
itself is being debugged. So, we can say that once the counter in timespec reach to 0,
the process will automatically exit once we detach the process from GDB. Let's verify.

(gdb) detach   
Detaching from program: /bin/busybox, process 795
(gdb) attach 795
Attaching to program: /bin/busybox, process 795
Reading symbols from /lib/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/ld.so.1
0x2ac050a8 in nanosleep () from /lib/libc.so.6
(gdb) x/16d $a0
0x7fc837f8:     0       652534296       131072  0
0x7fc83808:     0       0       0       0
0x7fc83818:     0       0       0       0
0x7fc83828:     0       0       0       0
(gdb) detach   
Detaching from program: /bin/busybox, process 795
(gdb) attach 795
Attaching to program: /bin/busybox, process 795
ptrace: No such process.
(gdb)

Yes, we are in the right way. Now, let's have a look to source level debugging with
GDB. Before that, let us create a simple cawan.c first.

Host:# cat cawan.c
#include
main()
{
  int flag=0;
  char *string="cawan";
  if(flag==0)
    printf("hello world %s\n",string);
  else
    printf("You should not see this !\n");
}
Host:# mips-linux-gnu-gcc -EL -g -o cawan cawan.c
Host:# ls cawan*
cawan  cawan.c
Host:#

Well, we have cross compiled the cawan.c with debugging symbols, and the executable
is cawan. Let us run it in MIPS environment with GDB.

tango3[gdb]# ./gdb       
GNU gdb (GDB) 7.1
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
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 "mips-linux-gnu".
For bug reporting instructions, please see:
.
Setting up the environment for debugging gdb.
No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
/root/cawan/mips-4.3/bin/gdb-7.1/gdb/.gdbinit:8: Error in sourced command file:
No breakpoint number 0.
(gdb) file cawan
Reading symbols from /root/cawan/mips-4.3/bin/gdb-7.1/gdb/cawan...done.
(gdb) list -
During symbol reading, DW_AT_name missing from DW_TAG_base_type.
(gdb) list 
1       #include
2       main()
3       {
4         int flag=0;
5         char *string="cawan";
6         if(flag==0)
7           printf("hello world %s\n",string);
8         else
9           printf("You should not see this !\n");
10      }
(gdb) run
Starting program: /root/cawan/mips-4.3/bin/gdb-7.1/gdb/cawan
hello world cawan

Program exited with code 022.
(gdb)

Good, the executable runs as usual. Let us set a breakpoint at line 7.

(gdb) b 7
Breakpoint 1 at 0x40068c: file cawan.c, line 7.
(gdb) run
Starting program: /root/cawan/mips-4.3/bin/gdb-7.1/gdb/cawan

Breakpoint 1, main () at cawan.c:7
7           printf("hello world %s\n",string);
(gdb) p string
During symbol reading, incomplete CFI data; unspecified registers
(e.g., zero) at 0x400670.
$1 = 0x400850 "cawan"
(gdb) n
hello world cawan
10      }
(gdb)

Nice, once the breakpoint be hit, we can check the value of "string", and it is
definitely equal to "cawan" as what we have defined in proper. Now, we make another
breakpoint at line 6, and run the executable again.

(gdb) b 6    
Breakpoint 2 at 0x400680: file cawan.c, line 6.
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /root/cawan/mips-4.3/bin/gdb-7.1/gdb/cawan

Breakpoint 2, main () at cawan.c:6
6         if(flag==0)
(gdb) p flag
During symbol reading, incomplete CFI data; unspecified registers
(e.g., zero) at 0x400670.
$3 = 0
(gdb) set variable flag = 1
(gdb) n
9           printf("You should not see this !\n");
(gdb) n
You should not see this !
10      }
(gdb)

Excellent, we can simply change the value of "flag" and let the executable runs in
different path, which is not the normal track. Well, that's all about our discussion
of GDB in performing local debugging. Then how about remote debugging ? Let's try and
we expect it works as usual.

tango3[gdb]# ./gdbserver/gdbserver :8888 ./cawan
Process ./cawan created; pid = 756
Listening on port 8888

Well, the gdbserver should be running at the MIPS platform now. Let's connect it from
the host machine with mips-linux-gnu-gdb.

Host:# mips-linux-gnu-gdb ./cawan
GNU gdb (Sourcery G++ Lite 4.3-51) 6.8.50.20080821-cvs
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
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=mips-linux-gnu".
For bug reporting instructions, please see:
...
(gdb) target remote 192.168.10.2:8888
Remote debugging using 192.168.10.2:8888
warning: Architecture rejected target-supplied description
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
0x2aaa8810 in ?? ()
(gdb) list
1    #include
2    main()
3    {
4      int flag=0;
5      char *string="cawan";
6      if(flag==0)
7        printf("hello world %s\n",string);
8      else
9        printf("You should not see this !\n");
10    }
(gdb) c
Continuing.
warning: .dynamic section for "/lib/libc.so.6" is not at the expected address
(wrong library or version mismatch?)
Error while mapping shared library sections:
/lib/ld.so.1: No such file or directory.

Program exited with code 022.
(gdb)

Nice, it seems the executable has been run in MIPS environment. Let's check the
MIPS console.

Remote debugging from host 192.168.10.1
hello world cawan

Child exited with status 18
GDBserver exiting

tango3[gdbserver]#

Good, the executable has been run once. In order to allow the target executable to
restart without restarting the GDBServer, we should use "target extended-remote"
instead of "target remote". So, let us do the same thing as what we did in local
debugging section. First, run the GDBServer at MIPS environment.

tango3[gdbserver]# ./gdbserver :8888 ./cawan
Process ./cawan created; pid = 762
Listening on port 8888

Then, at host machine, connect to MIPS environment with mips-linux-gnu-gdb.

Host:# mips-linux-gnu-gdb ./cawan
GNU gdb (Sourcery G++ Lite 4.3-51) 6.8.50.20080821-cvs
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
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=mips-linux-gnu".
For bug reporting instructions, please see:
...
(gdb) target extended-remote 192.168.10.2:8888
Remote debugging using 192.168.10.2:8888
warning: Architecture rejected target-supplied description
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
0x2aaa8810 in ?? ()
(gdb) list
1    #include
2    main()
3    {
4      int flag=0;
5      char *string="cawan";
6      if(flag==0)
7        printf("hello world %s\n",string);
8      else
9        printf("You should not see this !\n");
10    }
(gdb) b 7
Breakpoint 1 at 0x40068c: file cawan.c, line 7.
(gdb) c
Continuing.

Program received signal SIGINT, Interrupt.
0x2aaa8810 in ?? ()
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/smp383/mips-4.3/bin/testgdb/gdb-7.0/gdb/gdbserver/cawan
warning: Architecture rejected target-supplied description
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
warning: .dynamic section for "/lib/libc.so.6" is not at the expected address
(wrong library or version mismatch?)
Error while mapping shared library sections:
/lib/ld.so.1: No such file or directory.
[Switching to Thread 763]

Breakpoint 1, main () at cawan.c:7
7        printf("hello world %s\n",string);
(gdb) p string
$1 = 0x400850 "cawan"
(gdb) b 6
Breakpoint 2 at 0x400680: file cawan.c, line 6.
(gdb) c
Continuing.

Program exited with code 022.
(gdb) run
Starting program: /home/smp383/mips-4.3/bin/testgdb/gdb-7.0/gdb/gdbserver/cawan
warning: Architecture rejected target-supplied description
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
warning: .dynamic section for "/lib/libc.so.6" is not at the expected address
(wrong library or version mismatch?)
Error while mapping shared library sections:
/lib/ld.so.1: No such file or directory.
[Switching to Thread 764]

Breakpoint 2, main () at cawan.c:6
6      if(flag==0)
(gdb) p flag
$2 = 0
(gdb) set variable flag = 1
(gdb) n
9        printf("You should not see this !\n");
(gdb) n
10    }
(gdb)

Let's verify the message output at MIPS console.

Remote debugging from host 192.168.10.1
Killing all inferiors
Process ./cawan created; pid = 763
hello world cawan

Child exited with status 18
Process ./cawan created; pid = 764
You should not see this !

Well, it seems we can do the same thing as in local debugging mode. However, if we
do something unknown by the GDBServer, the GDB at the host machine will get into
infinity loop... and there are quite a number of such booby traps. Let's show an
example when we try to step into printf().

(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/smp383/mips-4.3/bin/testgdb/gdb-7.0/gdb/gdbserver/cawan
warning: Architecture rejected target-supplied description
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
warning: .dynamic section for "/lib/libc.so.6" is not at the expected address
(wrong library or version mismatch?)
Error while mapping shared library sections:
/lib/ld.so.1: No such file or directory.
[Switching to Thread 765]

Breakpoint 2, main () at cawan.c:6
6      if(flag==0)
(gdb) n

Breakpoint 1, main () at cawan.c:7
7        printf("hello world %s\n",string);
(gdb) s
warning: GDB can't find the start of the function at 0x2aabe06c.

    GDB is unable to find the start of the function at 0x2aabe06c
and thus can't determine the size of that function's stack frame.
This means that GDB may be unable to access that stack frame, or
the frames below it.
    This problem is most likely caused by an invalid program counter or
stack pointer.
    However, if you think GDB should simply search farther back
from 0x2aabe06c for code which looks like the beginning of a
function, you can increase the range of the search using the `set
heuristic-fence-post' command.
warning: GDB can't find the start of the function at 0x2aabe06b.
warning: GDB can't find the start of the function at 0x2aabe06c.
warning: GDB can't find the start of the function at 0x2aabe06b.
warning: GDB can't find the start of the function at 0x2aabe06c.
warning: GDB can't find the start of the function at 0x2aabe06b.
warning: GDB can't find the start of the function at 0x2aabe06c.
warning: GDB can't find the start of the function at 0x2aabe06b.
warning: GDB can't find the start of the function at 0x2aabe06c.
warning: GDB can't find the start of the function at 0x2aabe06b.
warning: GDB can't find the start of the function at 0x2aabe06c.
warning: GDB can't find the start of the function at 0x2aabe06b.
warning: GDB can't find the start of the function at 0x2aabe06c.
warning: GDB can't find the start of the function at 0x2aabe06b.
warning: GDB can't find the start of the function at 0x2aabe06c.

Yes, it is quite annoying whenever we are concentrating to troubleshoot our binary,
or designing our shellcode for embedded linux system. So, again, it is really
recommended to use local debugging method, instead of the remote debugging, under
the embedded platform. Besides, it is important to note that the version of cross
compiler being used should match to the dedicated version of GDB. For our example
here, the cross compiler that we are using is CodeSourcery v4.3, and it should work
together with GDB v7.0. Otherwise, if we use CodeSourcery v4.3 to compile GDB v7.1,
we will get the error as similar to this,

tango3[gdbserver]# ./gdbserver :8888 ./cawan
Process ./cawan created; pid = 757
Listening on port 8888

Host:# mips-linux-gnu-gdb ./cawan
GNU gdb (Sourcery G++ Lite 4.3-51) 6.8.50.20080821-cvs
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
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=mips-linux-gnu".
For bug reporting instructions, please see:
...
(gdb) target remote 192.168.10.2:8888
Remote debugging using 192.168.10.2:8888
warning: Architecture rejected target-supplied description
Malformed packet(b) (missing colon): ore:0;
Packet: 'T051d:30bba07f;25:1088aa2a;thread:2f5;core:0;'

(gdb)

So, the latest version of a tool doesn't mean it will always work in embedded system.
Instead, the matching of the version number among each others should always be alert.


pdf version:

http://www.scribd.com/doc/114458156/A-Simple-Lab-Guide-of-Using-GDB-in-Embedded-System

Saturday, November 24, 2012

Understanding Disk Partition in Flash For Embedded Linux System

Understanding Disk Partition in Flash For Embedded Linux System

by cawan (cawan[at]ieee.org or chuiyewleong[at]hotmail.com)

on 25/11/2012

Flash chip is divided in blocks. So, the block number is equivalent to page frame
number of RAM. However, due to the physical characteristic of flash chip, it is
really not easy to operate the flash in term of block number. In addition, there
are variety of flash technology, nand flash, nor flash, slc, mlc..., and they have
quite different physical characteristic among each others. In embedded system design,
the physical access of specific flash chip is usually managed by respective device
driver, which is normally known as MTD driver. So, the MTD driver will treat the
flash in block level, and the rest in higher level will treat the flash in logical
address level. In other words, the MTD driver will perform mapping of logical address
to the appropriate block number of the flash. Therefore, those incontinuous blocks
in flash can be mapped into a series of continuous logical addresses in high level.
Well, it is something similar to the flat model of memory management with MMU support.
So, we know that linux kernel will talk to flash chip by using logical address right
now. Hence, in order to create partition, it is just about to define the partition
info somewhere in the flash and allows global access. For most of the cases in
embedded system, the first few blocks of the flash are normally the candidates to
store global environment variables, including the partition info. Besides, it is
important to note that block 0 is usually reserved for bootloader. Sometimes, the
global environment variables are just simply coexist with bootloader in block 0.
So, the question right now is how to manipulate the global environment variables,
let's say how we can define new partition ? The answer is simple, it is bootloader.
As what we know, most of the bootloader supports a configuration interface to let
user to perform certain operations to the hardware such as to format the flash chip
or to verify the checksum of a range of memory. Of course, it is available to define
partition by manipulating the appropriate global environment variable. For each
partition, it just needs to define the start address and length of the partition in
flash, yes, that's it. Let's show an example in MIPS platform.

(0x00)    4 l.cs0_size 0x08000000
(0x00)    4 l.cs0_parts 0x00000007
(0x00)    4 l.cs0_part1_offset 0x00000000
(0x00)    4 l.cs0_part1_size 0x00080000
(0x00)    4 l.cs0_part2_offset 0x00080000
(0x00)    4 l.cs0_part2_size 0x00040000
(0x00)    4 l.cs0_part3_offset 0x000c0000
(0x00)    4 l.cs0_part3_size 0x00740000
(0x00)    4 l.cs0_part4_offset 0x00800000
(0x00)    4 l.cs0_part4_size 0x01000000
(0x00)    4 l.cs0_part5_offset 0x01800000
(0x00)    4 l.cs0_part5_size 0x00800000
(0x00)    4 l.cs0_part6_offset 0x02000000
(0x00)    4 l.cs0_part6_size 0x03200000
(0x00)    4 l.cs0_part7_offset 0x05200000
(0x00)    4 l.cs0_part7_size 0x00200000
(0x00)    4 l.cs0_part8_offset 0x05400000
(0x00)    4 l.cs0_part8_size 0x03200000
(0x00)    4 l.cs0_part9_offset 0x08600000
(0x00)    4 l.cs0_part9_size 0x03200000

Well, the flash chip is at chip select 0 (cs0), and its size is 128 MB (0x08000000).
Besides, there are 7 system partitions as defined in (l.cs0_parts). For each of the
system partition, the offset and size are clearly defined. In addition, there are
2 user partitions are defined as cs0_part8 and cs0_part9, with respective offset and
size individually. With such info in global environment variables, it is just a
simple job to implement a kernel module in linux to create block devices for
partitions. Of course it is just dealing with logical address, and the MTD driver
will do the rest of the jobs for us. So, once the partition are represented in block
device, then any ramdisk image file can be duplicated onto it and make ready to be
mounted by the system for general operation. Regarding how to create ramdisk image
file and duplicate it onto a partition, please refer my previous paper in this blog,
"How To Create A Ramdisk File and Make Use in Embedded System ?".

pdf version:

http://www.scribd.com/doc/114285765/Understanding-Disk-Partition-in-Flash-for-Embedded-Linux-System

How To Create A Ramdisk File and Make Use in Embedded System ?

How To Create A Ramdisk File and Make Use in Embedded System ?

by cawan (cawan[at]ieee.org or chuiyewleong[at]hotmail.com)

on 24/11/2012

A ramdisk file is simply a file image with file system. The variety of file system
in embedded scope is quite chaotic, there are CRAMFS, JFFS, JFFS2, SquashFS, ROMFS,
and etc. Each of them has their own pros and cons to the embedded design, well, it
is depends to the application. However, the issue right now is how we can create
such ramdisk file ? It is simple, let us make use of ext3 as an example here.

Host:# dd if=/dev/zero of=./cawan.img bs=1k count=1024
1024+0 records in
1024+0 records out
1048576 bytes (1.0 MB) copied, 0.0107335 s, 97.7 MB/s
Host:# hd cawan.img
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00100000
Host:# mkfs.ext3 -F -m0 ./cawan.img
mke2fs 1.41.3 (12-Oct-2008)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
128 inodes, 1024 blocks
0 blocks (0.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=1048576
1 block group
8192 blocks per group, 8192 fragments per group
128 inodes per group

Writing inode tables: done                           

Filesystem too small for a journal
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 23 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

Well, the -F option in mkfs means to force the formatting process to run on a file.
Besides, the -m0 option means to reserve zero block for super user on the file
system. It is reasonable because embedded system is normally a single-user system.
Now, let us check the hexdump of cawan.img again.

Host:# hd ./cawan.img
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400  80 00 00 00 00 04 00 00  00 00 00 00 da 03 00 00  |................|
00000410  75 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00  |u...............|
00000420  00 20 00 00 00 20 00 00  80 00 00 00 00 00 00 00  |. ... ..........|
00000430  0d 82 b0 50 00 00 17 00  53 ef 01 00 01 00 00 00  |...P....S.......|
00000440  0d 82 b0 50 00 4e ed 00  00 00 00 00 01 00 00 00  |...P.N..........|
00000450  00 00 00 00 0b 00 00 00  80 00 00 00 38 00 00 00  |............8...|
00000460  02 00 00 00 01 00 00 00  0a 80 ba 2c 4f 6b 48 e1  |...........,OkH.|
00000470  ab 02 2a 9d 01 fa 14 e5  00 00 00 00 00 00 00 00  |..*.............|
00000480  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000004c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 03 00  |................|
000004d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000004e0  00 00 00 00 00 00 00 00  00 00 00 00 4a ad 9b 21  |............J..!|
000004f0  6f 8c 49 a6 a6 1d 0d 98  0a 38 a9 d8 01 00 00 00  |o.I......8......|
00000500  00 00 00 00 00 00 00 00  0d 82 b0 50 00 00 00 00  |...........P....|
00000510  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000560  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000570  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000800  06 00 00 00 07 00 00 00  08 00 00 00 da 03 75 00  |..............u.|
00000810  02 00 04 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000820  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001800  ff ff ff ff 1f 00 00 00  00 00 00 00 00 00 00 00  |................|
00001810  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001870  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 80  |................|
00001880  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00001c00  ff 07 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00001c10  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00002000  00 00 00 00 00 00 00 00  0d 82 b0 50 0d 82 b0 50  |...........P...P|
00002010  0d 82 b0 50 00 00 00 00  00 00 00 00 00 00 00 00  |...P............|
00002020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002080  ed 41 00 00 00 04 00 00  0d 82 b0 50 0d 82 b0 50  |.A.........P...P|
00002090  0d 82 b0 50 00 00 00 00  00 00 03 00 02 00 00 00  |...P............|
000020a0  00 00 00 00 00 00 00 00  18 00 00 00 00 00 00 00  |................|
000020b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002300  80 81 00 00 00 30 04 04  0d 82 b0 50 0d 82 b0 50  |.....0.....P...P|
00002310  0d 82 b0 50 00 00 00 00  00 00 01 00 08 00 00 00  |...P............|
00002320  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002350  00 00 00 00 00 00 00 00  00 00 00 00 25 00 00 00  |............%...|
00002360  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002500  c0 41 00 00 00 30 00 00  0d 82 b0 50 0d 82 b0 50  |.A...0.....P...P|
00002510  0d 82 b0 50 00 00 00 00  00 00 02 00 18 00 00 00  |...P............|
00002520  00 00 00 00 00 00 00 00  19 00 00 00 1a 00 00 00  |................|
00002530  1b 00 00 00 1c 00 00 00  1d 00 00 00 1e 00 00 00  |................|
00002540  1f 00 00 00 20 00 00 00  21 00 00 00 22 00 00 00  |.... ...!..."...|
00002550  23 00 00 00 24 00 00 00  00 00 00 00 00 00 00 00  |#...$...........|
00002560  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00006000  02 00 00 00 0c 00 01 02  2e 00 00 00 02 00 00 00  |................|
00006010  0c 00 02 02 2e 2e 00 00  0b 00 00 00 e8 03 0a 02  |................|
00006020  6c 6f 73 74 2b 66 6f 75  6e 64 00 00 00 00 00 00  |lost+found......|
00006030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00006400  0b 00 00 00 0c 00 01 02  2e 00 00 00 02 00 00 00  |................|
00006410  f4 03 02 02 2e 2e 00 00  00 00 00 00 00 00 00 00  |................|
00006420  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00006800  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00006810  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00006c00  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00006c10  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00007000  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00007010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00007400  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00007410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00007800  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00007810  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00007c00  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00007c10  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00008000  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00008010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00008400  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00008410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00008800  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00008810  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00008c00  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00008c10  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00009000  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00009010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00009400  00 00 00 00 03 00 00 00  04 00 00 00 05 00 00 00  |................|
00009410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00100000

Nice, it seems the file system already created. Let us mount onto it and add some
files into it.

Host:# mkdir cawan
Host:# mount -o loop ./cawan.img ./cawan
Host:# cd cawan
Host:# ls
lost+found
Host:# echo hello cawan > cawan.txt
Host:# ls -l
total 13
-rw-r--r-- 1 root root    12 2012-11-24 16:29 cawan.txt
drwx------ 2 root root 12288 2012-11-24 16:15 lost+found
Host:# cat ./cawan.txt
hello cawan
Host:# cd ..
Host:# umount ./cawan
Host:#

Fine, we make use of loop device to mount onto the cawan.img. After that, we create
a cawan.txt into the ramdisk file and the content of cawan.txt is "hello cawan".
Let us check the hexdump of cawan.img again.

Host:# hd ./cawan.img
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400  80 00 00 00 00 04 00 00  00 00 00 00 d9 03 00 00  |................|
00000410  74 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00  |t...............|
00000420  00 20 00 00 00 20 00 00  80 00 00 00 30 85 b0 50  |. ... ......0..P|
00000430  81 85 b0 50 01 00 17 00  53 ef 01 00 01 00 00 00  |...P....S.......|
00000440  0d 82 b0 50 00 4e ed 00  00 00 00 00 01 00 00 00  |...P.N..........|
00000450  00 00 00 00 0b 00 00 00  80 00 00 00 38 00 00 00  |............8...|
00000460  02 00 00 00 01 00 00 00  0a 80 ba 2c 4f 6b 48 e1  |...........,OkH.|
00000470  ab 02 2a 9d 01 fa 14 e5  00 00 00 00 00 00 00 00  |..*.............|
00000480  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000004c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 03 00  |................|
000004d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000004e0  00 00 00 00 00 00 00 00  00 00 00 00 4a ad 9b 21  |............J..!|
000004f0  6f 8c 49 a6 a6 1d 0d 98  0a 38 a9 d8 01 00 00 00  |o.I......8......|
00000500  00 00 00 00 00 00 00 00  0d 82 b0 50 00 00 00 00  |...........P....|
00000510  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000560  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000570  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000800  06 00 00 00 07 00 00 00  08 00 00 00 d9 03 74 00  |..............t.|
00000810  02 00 04 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000820  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001800  ff ff ff ff 3f 00 00 00  00 00 00 00 00 00 00 00  |....?...........|
00001810  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001870  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 80  |................|
00001880  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00001c00  ff 0f 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00001c10  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00002000  00 00 00 00 00 00 00 00  0d 82 b0 50 0d 82 b0 50  |...........P...P|
00002010  0d 82 b0 50 00 00 00 00  00 00 00 00 00 00 00 00  |...P............|
00002020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002080  ed 41 00 00 00 04 00 00  5f 85 b0 50 53 85 b0 50  |.A......_..PS..P|
00002090  53 85 b0 50 00 00 00 00  00 00 03 00 02 00 00 00  |S..P............|
000020a0  00 00 00 00 00 00 00 00  18 00 00 00 00 00 00 00  |................|
000020b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002300  80 81 00 00 00 30 04 04  0d 82 b0 50 0d 82 b0 50  |.....0.....P...P|
00002310  0d 82 b0 50 00 00 00 00  00 00 01 00 08 00 00 00  |...P............|
00002320  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002350  00 00 00 00 00 00 00 00  00 00 00 00 25 00 00 00  |............%...|
00002360  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002500  c0 41 00 00 00 30 00 00  0d 82 b0 50 0d 82 b0 50  |.A...0.....P...P|
00002510  0d 82 b0 50 00 00 00 00  00 00 02 00 18 00 00 00  |...P............|
00002520  00 00 00 00 00 00 00 00  19 00 00 00 1a 00 00 00  |................|
00002530  1b 00 00 00 1c 00 00 00  1d 00 00 00 1e 00 00 00  |................|
00002540  1f 00 00 00 20 00 00 00  21 00 00 00 22 00 00 00  |.... ...!..."...|
00002550  23 00 00 00 24 00 00 00  00 00 00 00 00 00 00 00  |#...$...........|
00002560  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002580  a4 81 00 00 0c 00 00 00  67 85 b0 50 53 85 b0 50  |........g..PS..P|
00002590  53 85 b0 50 00 00 00 00  00 00 01 00 02 00 00 00  |S..P............|
000025a0  00 00 00 00 00 00 00 00  26 00 00 00 00 00 00 00  |........&.......|
000025b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000025e0  00 00 00 00 6b f9 df 6c  00 00 00 00 00 00 00 00  |....k..l........|
000025f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00006000  02 00 00 00 0c 00 01 02  2e 00 00 00 02 00 00 00  |................|
00006010  0c 00 02 02 2e 2e 00 00  0b 00 00 00 14 00 0a 02  |................|
00006020  6c 6f 73 74 2b 66 6f 75  6e 64 00 00 0c 00 00 00  |lost+found......|
00006030  d4 03 09 01 63 61 77 61  6e 2e 74 78 74 00 00 00  |....cawan.txt...|
00006040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00006400  0b 00 00 00 0c 00 01 02  2e 00 00 00 02 00 00 00  |................|
00006410  f4 03 02 02 2e 2e 00 00  00 00 00 00 00 00 00 00  |................|
00006420  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00006800  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00006810  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00006c00  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00006c10  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00007000  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00007010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00007400  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00007410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00007800  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00007810  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00007c00  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00007c10  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00008000  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00008010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00008400  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00008410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00008800  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00008810  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00008c00  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00008c10  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00009000  00 00 00 00 00 04 00 00  00 00 00 00 00 00 00 00  |................|
00009010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00009400  00 00 00 00 03 00 00 00  04 00 00 00 05 00 00 00  |................|
00009410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00009800  68 65 6c 6c 6f 20 63 61  77 61 6e 0a 00 00 00 00  |hello cawan.....|
00009810  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00100000
Host:#

Good, it seems everything fine and the cawan.txt is already in the cawan.img.
But, how we can make use of it ? Let us get to embedded environment now.

tango3[bin]# ls -l ./cawan.img
-rw-r--r--    1 root     root      1048576 Nov 24  2012 ./cawan.img
tango3[bin]# cat ./cawan.img > /dev/sigmblockh
tango3[bin]# cd cawan     
tango3[cawan]# ls
tango3[cawan]# cd ..
tango3[bin]# mount /dev/sigmblockh ./cawan       
tango3[bin]# cd cawan
tango3[cawan]# ls
cawan.txt   lost+found/
tango3[cawan]# cat cawan.txt
hello cawan
tango3[cawan]#

Well, once we cat the cawan.img into partition /dev/sigmblockh, the partition should
be ready to mount now. After it is being mounted, we can see our cawan.txt and of
course the content of it should be "hello cawan". By applying the same technique, if
the cawan.img is being mapped into RAM, then it is a volatile ramdisk. Of course, in
real implementation, it is up to you to choose what type of file system to be used in
you embedded system design.

pdf version:

http://www.scribd.com/doc/114266495/How-to-Create-a-Ramdisk-File-and-Make-Use-in-Embedded-System

Friday, November 23, 2012

Linux in Softcore Processor

Linux in Softcore Processor

by cawan (cawan[at]ieee.org or chuiyewleong[at]hotmail.com)

on 24/11/2012

Software processor is about the logical implementation of RISC architecture in FPGA.
Based on the fundamental unit of LUT, it is possible to construct any type of
combinational or sequential logic circuit. In addition, the logic design can be
represented in the way of Verilog or VHDL code. In order to implement the digital
design, the code will be synthesized into gate level format and later being
placed-and-routed as final implementation image. For those who are not familiar to
FPGA system design, just assume the synthesis process as code compilation in software.
Regarding to the place-and-route process, just assume it as similar to object code
linking in generating executable. Well, simple assumption. So, by representing the
logic design in HDL code, it is efficient to design high complexity digital circuit,
and RISC processor is a very good example. The 2 mainstream FPGA manufacturers,
Altera and Xilinx, have their own proprietary softcode processors, which are NIOS
and Microblaze, respectively. In earlier generation of those softcore processors,
they are just simple 16-bit RISC without MMU support. So, from the angle of embedded
system design, uClinux is the only choice. Despite of the limitation of uClinux in
supporting open source applications in the community, the availability of custom
peripheral and custom instruction are really outstanding to optimize the performance
of certain algorithms implementation from hardware point of view. In contemporary
generation of softcore processors, they are normally at least 32-bit with MMU as
optional feature. Hence, it is possible to let a full linux kernel running in a
softcore processor with MMU support under the FPGA environment. For the case of
Altera, NIOS2 has superseded the legacy NIOS1 with its new 32-bit architecture with
MMU support as optional feature. So, instead of the legacy uClinux running in NIOS1,
Altera has proposed the new NIOS2 linux which is a full linux kernel with MMU support
to be run in NIOS2 processor. Hence, it is convenient to migrate those familiar open
source applications into NIOS2 environment. On the other hand, for the case of Xilinx,
the new Microblaze is also in 32-bit architecture with MMU support. However, Xilinx
does not provide any linux kernel package to the end customer. Instead, there is a
stable version of linux kernel for Microblaze in the market, which is known as
petalinux. The performance of petalinux running in Microblaze is pretty good and it
is really recommended for embedded system design under FPGA environment. Finally, as
an advice to those embedded system designers who are not familiar with FPGA system
design, do not simply choose FPGA as your design platform unless you have a very
substantial reason such as the requirement of performance optimization with DSP
algorithm or something similar which is dealing with custom hardware implementation.
Otherwise, it is just a violation to the principle of cost-effectiveness.

pdf version:

http://www.scribd.com/doc/114259884/Linux-in-Softcore-Processor

What is Non-MMU or MMU-less Linux ?

What is Non-MMU or MMU-less Linux ?

by cawan (cawan[at]ieee.org or chuiyewleong[at]hotmail.com)

on 23/11/2012

In olden days, embedded system is always assumed as equivalent to microcontroller
based system design. On the other hand, the development of RISC based microprocessor
is still not mature in terms of technology and production cost. Hence, in those days,
MMU is something luxury to be implemented in both microcontroller or microprocessor.
However, in nowadays, MMU is almost a built-in feature in majority of RISC processors.
Of course, some low-end RISC processor such as ARM-M4 does not come with MMU, but it
is almost a legacy. In fact, the unit price of a standard RISC processor such as
ARM-A5 is almost closed to $5, therefore, there is no more substantial reason to use
those low-end RISC processors which are without MMU. Yes, this is from the angle of
embedded system, however, the existence of MMU in microcontroller is still an
argument. Due to the demand of low-cost in microcontroller, it is normally with much
lower clock speed, memory space support, number of register, and etc. So, it is a
little bit unreasonable to implement MMU in microcontroller. On the other hand, from
software perspective, code reusability is really a trend in reducing the time-to-market
of a product. Besides, the complexity of its features are getting higher and higher.
Try to imagine, is it a standard feature for an embedded product to access remote
shared folder which is hosted in a PC within the same network ? Is it a daunting
process to develop NFS or SAMBA by your own again and again in different platform ?
Yes, it is really terrible, and that's why we need a linux kernel. With the linux
kernel, then it is up to your cross-compilation skill to migrate those useful modules
such as FUSE, SAMBA, NFS and USB into your own platform in a short period of time.

Well, the discussion come to linux kernel now. As what we know, linux kernel is
designed for PC based platform, not embedded platform. In other words, linux kernel
expects to have MMU to run in proper. However, due to the power of open source, it
has been modified to run in non-MMU platform, and it is known as uClinux. In uClinux,
the memory address is directly mapped to the physical address, and there is no
protection among different processes. So, it is very possible for a process to
corrupt another process and causes the system crash. Anyway, let us assume the
uClinux itself is robust to run, and we focus our discussion in user application.
Majority of the user applications use fork() to spawn new child process. In the
process of fork(), the parent process will be duplicated to the new process.
After that, both of the process with run together. However, in most of the times,
the child process will eventually call execve(), and pass the process environment
to the new program. Yes, such action is really wasting the precious memory space.
So, in recent version of linux kernel, the fork() process has been rectified to
make use the concept of copy-on-write. Thus, the parent process will not be forced
to duplicate over to the child process, unless any write action being detected. Fine,
the fork() process is much optimized now. But, in order to perform copy-on-write,
MMU is necessary. So, fork() must be changed to support non-MMU platform. In uClinux,
vfork() is the alternative. With vfork(), the child process will borrow the address
space of the parent process. While the child process is running, the parent process
will be suspended until the child process calls _exit() or execve(). In this case,
only one process is running at a specific time. But, since they are both running in
the same process space, it is easily for a child process to corrupt the structure of
the parent process. The blame is reasonable because majority of the open source
applications are developed under the environment with MMU. In fact, they are valid
for "full" linux, but not for such "customized" linux. So, in order to run an
existing open source application in uClinux, heavy and serious modification is needed
for the attempt. Well, this is a very subjective issue to justify either is it worth
to spend times and resources in doing such modification. However, for the case of
developing new application, then uClinux is really a good choice. By implementing the
codes in proper, it should work well in uClinux. In fact, we suppose to say that the
codes can run in all uClinux compatible platform with minor modification such as the
redefinition of I/O addresses and etc. Anyway, such so called non-MMU or MMU-less
linux is really a legacy in embedded system. Instead, with a cost-effective RISC
processor in mid-range feature such as ARM-A8, it is no problem at all to support
full linux kernel. So, with full linux kernel, it is comfortable to perform cross
compilation of open source applications as usual again, and let them to work together
with our own codes.
 
pdf version:

http://www.scribd.com/doc/114197048/What-is-Non-MMU-or-MMU-Less-Linux

Wednesday, November 21, 2012

How To Cross Compile GDB and Run in Embedded System

How To Cross Compile GDB and Run in Embedded System

by cawan (cawan[at]ieee.org or chuiyewleong[at]hotmail.com)

on 21/11/2012

GDB is a useful tool to debug applications running in linux system. For the case of
embedded linux system, it is important have a version of GDB that can run in proper
in the embedded environment. As oppose to x86 environment which is mostly being used
in PC platform, embedded system adopts a large variety of RISC architecture to run
the system. There are ARM, MIPS, PPC... and each of them might run in little or big
endian mode. So, it is a little bit hard to have a generic version of GDB that can
run in all embedded platforms. Therefore, it is crucial to harness the power of cross
compilation in all the ways in order to make use of those useful tools such as GDB in
embedded environment. Regarding to the fundamental knowledge of cross compilation,
please refer my previous paper in this blog, "What is Cross Compilation ? Cross
Compilation Demystified For Embedded Linux System". So, let us start to cross compile
the GDB for our embedded platform right now. The embedded platform that we are going
to use is MIPS 24k, little-endian mode, 500MHz, with 256MB DDR2 RAM.

Host:# ./configure --help
`configure' configures this package to adapt to many kinds of systems.

Usage: ./configure [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

Configuration:
  -h, --help              display this help and exit
      --help=short        display options specific to this package
      --help=recursive    display the short help of all the included packages
  -V, --version           display version information and exit
  -q, --quiet, --silent   do not print `checking...' messages
      --cache-file=FILE   cache test results in FILE [disabled]
  -C, --config-cache      alias for `--cache-file=config.cache'
  -n, --no-create         do not create output files
      --srcdir=DIR        find the sources in DIR [configure dir or `..']

Installation directories:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [/usr/local]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [PREFIX]

By default, `make install' will install all the files in
`/usr/local/bin', `/usr/local/lib' etc.  You can specify
an installation prefix other than `/usr/local' using `--prefix',
for instance `--prefix=$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR            user executables [EPREFIX/bin]
  --sbindir=DIR           system admin executables [EPREFIX/sbin]
  --libexecdir=DIR        program executables [EPREFIX/libexec]
  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
  --libdir=DIR            object code libraries [EPREFIX/lib]
  --includedir=DIR        C header files [PREFIX/include]
  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
  --infodir=DIR           info documentation [DATAROOTDIR/info]
  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
  --mandir=DIR            man documentation [DATAROOTDIR/man]
  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]
  --htmldir=DIR           html documentation [DOCDIR]
  --dvidir=DIR            dvi documentation [DOCDIR]
  --pdfdir=DIR            pdf documentation [DOCDIR]
  --psdir=DIR             ps documentation [DOCDIR]

Program names:
  --program-prefix=PREFIX            prepend PREFIX to installed program names
  --program-suffix=SUFFIX            append SUFFIX to installed program names
  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names

System types:
  --build=BUILD     configure for building on BUILD [guessed]
  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
  --target=TARGET   configure for building compilers for TARGET [HOST]

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --enable-gold           use gold instead of ld
  --enable-libada         build libada directory
  --enable-libssp         build libssp directory
  --enable-build-with-cxx build with C++ compiler instead of C compiler
  --disable-ppl-version-check    disable check for PPL version
  --disable-cloog-version-check  disable check for CLooG version
  --enable-lto            enable link time optimization support
  --enable-stage1-languages[=all]   choose additional languages to build during
                          stage1.  Mostly useful for compiler development.
  --enable-objc-gc        enable use of Boehm's garbage collector with the
                          GNU Objective-C runtime
  --enable-bootstrap      enable bootstrapping [yes if native build]
  --enable-serial-[{host,target,build}-]configure
                          force sequential configuration of
                          sub-packages for the host, target or build
                          machine, or all sub-packages
  --enable-maintainer-mode enable make rules and dependencies not useful
                          (and sometimes confusing) to the casual installer
  --enable-stage1-checking[=all]   choose additional checking for stage1
                          of the compiler
  --enable-werror         enable -Werror in bootstrap stage2 and later

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-build-libsubdir=DIR  Directory where to find libraries for build system
  --with-mpc=PATH        specify prefix directory for installed MPC package.
                          Equivalent to --with-mpc-include=PATH/include
                          plus --with-mpc-lib=PATH/lib
  --with-mpc-include=PATH
                          specify directory for installed MPC include files
  --with-mpc-lib=PATH    specify directory for the installed MPC library
  --with-mpfr-dir=PATH    this option has been REMOVED
  --with-mpfr=PATH        specify prefix directory for installed MPFR package.
                          Equivalent to --with-mpfr-include=PATH/include
                          plus --with-mpfr-lib=PATH/lib
  --with-mpfr-include=PATH
                          specify directory for installed MPFR include files
  --with-mpfr-lib=PATH    specify directory for the installed MPFR library
  --with-gmp-dir=PATH     this option has been REMOVED
  --with-gmp=PATH         specify prefix directory for the installed GMP package.
                          Equivalent to --with-gmp-include=PATH/include
                          plus --with-gmp-lib=PATH/lib
  --with-gmp-include=PATH specify directory for installed GMP include files
  --with-gmp-lib=PATH     specify directory for the installed GMP library
  --with-host-libstdcxx=L Use linker arguments L to link with libstdc++
                          when linking with PPL
  --with-stage1-ldflags=FLAGS Linker flags for stage1
  -with-stage1-libs=LIBS      Libraries for stage1
  --with-boot-libs=LIBS     Libraries for stage2 and later
  --with-boot-ldflags=FLAGS Linker flags for stage2 and later
  --with-ppl=PATH         Specify prefix directory for the installed PPL package
                          Equivalent to --with-ppl-include=PATH/include
                          plus --with-ppl-lib=PATH/lib
  --with-ppl-include=PATH Specify directory for installed PPL include files
  --with-ppl-lib=PATH     Specify the directory for the installed PPL library
  --with-cloog=PATH       Specify prefix directory for the installed CLooG-PPL package
                          Equivalent to --with-cloog-include=PATH/include
                          plus --with-cloog-lib=PATH/lib
  --with-cloog-include=PATH Specify directory for installed CLooG include files
  --with-cloog-lib=PATH   Specify the directory for the installed CLooG library
  --with-libelf=PATH       Specify prefix directory for the installed libelf package
                          Equivalent to --with-libelf-include=PATH/include
                          plus --with-libelf-lib=PATH/lib
  --with-libelf-include=PATH Specify directory for installed libelf include files
  --with-libelf-lib=PATH   Specify the directory for the installed libelf library
  --with-build-sysroot=SYSROOT
                          use sysroot as the system root during the build
  --with-debug-prefix-map='A=B C=D ...'
                             map A to B, C to D ... in debug information
--with-build-config='NAME NAME2...'
                          Use config/NAME.mk build configuration
  --with-build-time-tools=PATH
                          use given path to find target tools during the build

Some influential environment variables:
  CC          C compiler command
  CFLAGS      C compiler flags
  LDFLAGS     linker flags, e.g. -L if you have libraries in a
              nonstandard directory
  LIBS        libraries to pass to the linker, e.g. -l
  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I if
              you have headers in a nonstandard directory
  CXX         C++ compiler command
  CXXFLAGS    C++ compiler flags
  CPP         C preprocessor
  AR          AR for the host
  AS          AS for the host
  DLLTOOL     DLLTOOL for the host
  LD          LD for the host
  LIPO        LIPO for the host
  NM          NM for the host
  RANLIB      RANLIB for the host
  STRIP       STRIP for the host
  WINDRES     WINDRES for the host
  WINDMC      WINDMC for the host
  OBJCOPY     OBJCOPY for the host
  OBJDUMP     OBJDUMP for the host
  CC_FOR_TARGET
              CC for the target
  CXX_FOR_TARGET
              CXX for the target
  GCC_FOR_TARGET
              GCC for the target
  GCJ_FOR_TARGET
              GCJ for the target
  GFORTRAN_FOR_TARGET
              GFORTRAN for the target
  AR_FOR_TARGET
              AR for the target
  AS_FOR_TARGET
              AS for the target
  DLLTOOL_FOR_TARGET
              DLLTOOL for the target
  LD_FOR_TARGET
              LD for the target
  LIPO_FOR_TARGET
              LIPO for the target
  NM_FOR_TARGET
              NM for the target
  OBJDUMP_FOR_TARGET
              OBJDUMP for the target
  RANLIB_FOR_TARGET
              RANLIB for the target
  STRIP_FOR_TARGET
              STRIP for the target
  WINDRES_FOR_TARGET
              WINDRES for the target
  WINDMC_FOR_TARGET
              WINDMC for the target

Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.

Report bugs to the package provider.
Host:#

Well, let's define --host, --target, and CC for our first try of GDB cross
compilation.

Host:# ./configure --host=mips-linux-gnu --target=mips-linux-gnu CC="mips-linux-gnu-gcc -EL"

Host:# make

After a while, we get the following error.

configure: WARNING: no enhanced curses library found; disabling TUI
checking for library containing tgetent... no
configure: error: no termcap library found
make[1]: *** [configure-gdb] Error 1
make[1]: Leaving directory `/home/smp383/mips-4.3/bin/gdb-7.1'
make: *** [all] Error 2

No termcap library found... It seems GDB needs termcap library to complete the
cross compilation. So, we need to cross compile a termcap library first.

Host:# wget http://gnuwin32.sourceforge.net/downlinks/termcap-src-zip.php

Host:# ls *.zip
termcap-1.3.1-src.zip
Host:# mkdir libtermcap
Host:# cp termcap-1.3.1-src.zip ./libtermcap/
Host:# cd libtermcap/
Host:# ls
termcap-1.3.1-src.zip
Host:# unzip termcap-1.3.1-src.zip
Archive:  termcap-1.3.1-src.zip
TermCap 1.3.1: sources
TermCap: terminal-capability library
  inflating: src/COPYING            
  inflating: src/ChangeLog          
  inflating: src/INSTALL            
  inflating: src/Makefile           
  inflating: src/Makefile.in        
  inflating: src/NEWS               
  inflating: src/README             
  inflating: src/config.cache       
  inflating: src/config.log         
  inflating: src/config.status      
  inflating: src/configure          
  inflating: src/configure.in       
  inflating: src/configure_help.txt 
  inflating: src/install-sh         
  inflating: src/makefile.mingw     
  inflating: src/mkinstalldirs      
  inflating: src/termcap.c          
  inflating: src/termcap.h          
  inflating: src/termcap.info       
  inflating: src/termcap.info-1     
  inflating: src/termcap.info-2     
  inflating: src/termcap.info-3     
  inflating: src/termcap.info-4     
  inflating: src/termcap.src        
  inflating: src/termcap.texi       
  inflating: src/texinfo.te_        
  inflating: src/tparam.c           
  inflating: src/version.c          
  inflating: manifest/termcap-1.3.1-src.ver 
  inflating: manifest/termcap-1.3.1-src.mft 
Host:# ls
manifest  src  termcap-1.3.1-src.zip
Host:# cd src
Host:# ls
ChangeLog           configure.in  makefile.mingw  termcap.info    termcap.texi
config.cache        COPYING       mkinstalldirs   termcap.info-1  texinfo.te_
config.log          INSTALL       NEWS            termcap.info-2  tparam.c
config.status       install-sh    README          termcap.info-3  version.c
configure           Makefile      termcap.c       termcap.info-4
configure_help.txt  Makefile.in   termcap.h       termcap.src
Host:# ./configure --help
bash: ./configure: Permission denied
Host:# ls -l ./configure
-rw-r--r-- 1 root root 30285 1995-07-27 03:52 ./configure
Host:# chmod 755 ./configure
Host:# ls -l ./configure
-rwxr-xr-x 1 root root 30285 1995-07-27 03:52 ./configure
Host:# ./configure --help
Usage: configure [options] [host]
Options: [defaults in brackets after descriptions]
Configuration:
  --cache-file=FILE       cache test results in FILE
  --help                  print this message
  --no-create             do not create output files
  --quiet, --silent       do not print `checking...' messages
  --version               print the version of autoconf that created configure
Directory and file names:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [/usr/local]
  --exec-prefix=PREFIX    install architecture-dependent files in PREFIX
                          [same as prefix]
  --srcdir=DIR            find the sources in DIR [configure dir or ..]
  --program-prefix=PREFIX prepend PREFIX to installed program names
  --program-suffix=SUFFIX append SUFFIX to installed program names
  --program-transform-name=PROGRAM run sed PROGRAM on installed program names
Host type:
  --build=BUILD           configure for building on BUILD [BUILD=HOST]
  --host=HOST             configure for HOST [guessed]
  --target=TARGET         configure for TARGET [TARGET=HOST]
Features and packages:
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --x-includes=DIR        X include files are in DIR
  --x-libraries=DIR       X library files are in DIR
--enable and --with options recognized:
  --enable-install-termcap install the termcap data file
  --with-termcap=FILE     use data file FILE instead of /etc/termcap
Host:# ./configure --host=mips-linux-gnu --target=mips-linux-gnu CC="mips-linux-gnu-gcc -EL"
configure: warning: CC=mips-linux-gnu-gcc -EL: invalid host type
loading cache ./config.cache
checking for gcc... (cached) gcc
checking whether we are using GNU C... (cached) yes
checking for ranlib... (cached) ranlib
checking for a BSD compatible install... /usr/bin/install -c
checking how to run the C preprocessor... (cached) gcc -E
checking for string.h... (cached) no
checking for unistd.h... (cached) no
checking whether cross-compiling... (cached) no
checking for ANSI C header files... (cached) yes
updating cache ./config.cache
creating ./config.status
creating Makefile
Host:# make
gcc -c  -DTERMCAP_FILE=\"/etc/termcap\" -I. -I. -g termcap.c
termcap.c:44: warning: conflicting types for built-in function ‘malloc’
termcap.c:45: warning: conflicting types for built-in function ‘realloc’
termcap.c: In function ‘memory_out’:
termcap.c:96: warning: incompatible implicit declaration of built-in function ‘exit’
termcap.c: In function ‘tgetent’:
termcap.c:511: warning: incompatible implicit declaration of built-in function ‘strcpy’
termcap.c:541: warning: incompatible implicit declaration of built-in function ‘strlen’
termcap.c:549: warning: incompatible implicit declaration of built-in function ‘strcpy’
termcap.c:550: warning: incompatible implicit declaration of built-in function ‘strlen’
termcap.c:559: warning: incompatible implicit declaration of built-in function ‘free’
termcap.c:567: warning: incompatible implicit declaration of built-in function ‘free’
termcap.c:597: warning: incompatible implicit declaration of built-in function ‘free’
termcap.c: In function ‘gobble_line’:
termcap.c:747: warning: incompatible implicit declaration of built-in function ‘bcopy’
gcc -c  -DTERMCAP_FILE=\"/etc/termcap\" -I. -I. -g tparam.c
tparam.c:32: warning: conflicting types for built-in function ‘malloc’
tparam.c:33: warning: conflicting types for built-in function ‘realloc’
tparam.c: In function ‘memory_out’:
tparam.c:52: warning: incompatible implicit declaration of built-in function ‘exit’
tparam.c: In function ‘tparam1’:
tparam.c:161: warning: incompatible implicit declaration of built-in function ‘bcopy’
tparam.c:222: warning: incompatible implicit declaration of built-in function ‘strlen’
tparam.c:300: warning: incompatible implicit declaration of built-in function ‘abort’
tparam.c:310: warning: incompatible implicit declaration of built-in function ‘strcat’
gcc -c  -DTERMCAP_FILE=\"/etc/termcap\" -I. -I. -g version.c
ar rc libtermcap.a termcap.o tparam.o version.o
ranlib libtermcap.a

Well, the libtermcap.a is generated, but based on the output message, the binary
is suspicious to be MIPS compatible. Let's check.

Host:# ls *.o
termcap.o  tparam.o  version.o
Host:# file termcap.o
termcap.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped

Yes, our suspicion is correct, the binary is in x86 format. Let us define the CC flag
in explicit way under the make process.

Host:# make distclean
rm -f *.a *.o core
rm -f Makefile config.status config.cache config.log
Host:# ./configure --host=mips-linux-gnu --target=mips-linux-gnu CC="mips-linux-gnu-gcc -EL"
configure: warning: CC=mips-linux-gnu-gcc -EL: invalid host type
creating cache ./config.cache
checking for gcc... gcc
checking whether we are using GNU C... yes
checking whether gcc accepts -g... yes
checking for ranlib... ranlib
checking for a BSD compatible install... /usr/bin/install -c
checking how to run the C preprocessor... gcc -E
checking for string.h... yes
checking for unistd.h... yes
checking whether cross-compiling... no
checking for ANSI C header files... yes
updating cache ./config.cache
creating ./config.status
creating Makefile
Host:# make CC="mips-linux-gnu-gcc -EL"
mips-linux-gnu-gcc -EL -c  -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DSTDC_HEADERS=1 
-DTERMCAP_FILE=\"/etc/termcap\" -I. -I. -g termcap.c
mips-linux-gnu-gcc -EL -c  -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DSTDC_HEADERS=1 
-DTERMCAP_FILE=\"/etc/termcap\" -I. -I. -g tparam.c
mips-linux-gnu-gcc -EL -c  -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DSTDC_HEADERS=1 
-DTERMCAP_FILE=\"/etc/termcap\" -I. -I. -g version.c
ar rc libtermcap.a termcap.o tparam.o version.o
ranlib libtermcap.a
Host:# file termcap.o
termcap.o: ELF 32-bit LSB relocatable, MIPS, MIPS32 rel2 version 1 (SYSV), not stripped
Host:#

Well, we got our libtermcap.a now. Let us back to the cross compilation process of
GDB. In order to let the cross compiler can locate the exact location of our termcap
library, let us define it in explicit way.

Host:# make distclean

Host:# ./configure --host=mips-linux-gnu --target=mips-linux-gnu CC="mips-linux-gnu-gcc -EL"
--with-libtermcap="$PWD"

Host:# make

However, after a while, we still get the same error. It seems the explicit definition
of termcap library didn't work properly. Let's us get to the respective configuration
file and do the explicit definition of termcap library again.

Host:# find . -type f -name "configure" -exec grep -il "no termcap library found" {} \;
./gdb/configure
Host:# cd gdb
Host:# ./configure --host=mips-linux-gnu --target=mips-linux-gnu CC="mips-linux-gnu-gcc -EL"
--with-libtermcap="/home/smp383/mips-4.3/bin/gdb-7.1"

Unfortunately, the error still there... It seems the problem can't be solved in graceful
way. So, we should consider to modify the configuration file directly. Let's start now.

Host:# nano configure

Well, the string "no termcap library found" is at line 8714. After some reading on
that portion of codes, it seems the variable "ac_cv_search_tgetent" needs to be
defined. At line 8644, it is defined as "../libtermcap/libtermcap.a". But, it seems
line 8644 will not getting executed in the case statement. Hence, we should hard
define it at the outer section of the case statement. So, let us put a new line of
"ac_cv_search_tgetent="../libtermcap.a" at line 8638. Therefore, from line 8635 to
line 8645 of the configuration file should look something similar to this.

# Since GDB uses Readline, we need termcap functionality.  In many
# cases this will be provided by the curses library, but some systems
# have a seperate termcap library, or no curses library at all.
ac_cv_search_tgetent="../libtermcap.a"

case $host_os in
  cygwin*)
    if test -d $srcdir/libtermcap; then
      LIBS="../libtermcap/libtermcap.a $LIBS"
      ac_cv_search_tgetent="../libtermcap/libtermcap.a"
    fi ;;

Fine, let us start the make process again.

Host:# make
...
...
make[4]: Leaving directory `/home/smp383/mips-4.3/bin/gdb-7.1/gdb/gdbserver'
make[3]: Leaving directory `/home/smp383/mips-4.3/bin/gdb-7.1/gdb'
make[2]: Leaving directory `/home/smp383/mips-4.3/bin/gdb-7.1/gdb'
make[1]: Nothing to be done for `all-target'.
make[1]: Leaving directory `/home/smp383/mips-4.3/bin/gdb-7.1'
Host:#

Excellent, the cross compilation process has been completed. Let's check the generated
binary is MIPS compatible or not.

Host:# cd gdb
Host:# file gdb
gdb: ELF 32-bit LSB executable, MIPS, MIPS32 rel2 version 1, for GNU/Linux 2.6.12,
dynamically linked (uses shared libs), not stripped
Host:#

It seems everything so far is fine. Let us test it in MIPS environment.

tango3[gdb-7.1]# cd gdb
tango3[gdb]# ./gdb
GNU gdb (GDB) 7.1
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
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 "mips-linux-gnu".
For bug reporting instructions, please see:
.
Setting up the environment for debugging gdb.
No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n])
[answered N; input not from terminal]
No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n])
[answered N; input not from terminal]
/root/cawan/mips-4.3/bin/gdb-7.1/gdb/.gdbinit:8: Error in sourced command file:
No breakpoint number 0.
(gdb)

Excellent, the GDB version 7.1 is successfully running in our MIPS platform now.




pdf version:

http://www.scribd.com/doc/114002450/How-to-Cross-Compile-GDB-and-Run-in-Embedded-System