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
Tuesday, November 27, 2012
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
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
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
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
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
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
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
nonstandard directory
LIBS libraries to pass to the linker, e.g. -l
CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I
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
Subscribe to:
Posts (Atom)