tech_log

Wednesday, November 4, 2009

sh4 Linux cross-toolchain (by Code Sourcery)

1) Pre-build sh-linux-gcc toolchain :
Download Sourcery G++ Lite 4.4-45 for SuperH GNU/Linux from :
http://www.codesourcery.com/sgpp/lite/superh/portal/release1041
choose : IA32 GNU/Linux Installer

2) Install toolchain to Linux host :
$ /bin/sh renesas-4.4-45-sh-linux-gnu.bin
Will lounch graphical installer which will install toolchain to :
~/CodeSourcery/

3) Compile hello.c :
$ ~/CodeSourcery/Sourcery_G++_Lite/bin/sh-linux-gnu-gcc -o hello hello.c

This will already search libraries to pre-destined paths :

drasko@Marx:~/sh4_projects$ ~/CodeSourcery/Sourcery_G++_Lite/bin/sh-linux-gnu-gcc -v -o hello hello.c
Using built-in specs.
Target: sh-linux-gnu
Configured with: /scratch/ams/4.4-sh-linux-gnu-lite/src/gcc-4.4/configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=sh-linux-gnu --enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --with-cpu=sh4a --with-multilib-list=sh4al,!mb/m4al --with-endian=little,big --enable-extra-sgxxlite-multilibs --enable-incomplete-targets --with-gnu-as --with-gnu-ld --with-specs='%{O2:%{!fno-remove-local-statics: -fremove-local-statics}} %{O*:%{O|O0|O1|O2|Os:;:%{!fno-remove-local-statics: -fremove-local-statics}}}' --enable-languages=c,c++ --enable-shared --disable-lto --enable-symvers=gnu --enable-__cxa_atexit --with-pkgversion='Sourcery G++ Lite 4.4-45' --with-bugurl=https://support.codesourcery.com/GNUToolchain/ --disable-nls --prefix=/opt/codesourcery --with-sysroot=/opt/codesourcery/sh-linux-gnu/libc --with-build-sysroot=/scratch/ams/4.4-sh-linux-gnu-lite/install/sh-linux-gnu/libc --with-gmp=/scratch/ams/4.4-sh-linux-gnu-lite/obj/host-libs-4.4-45-sh-linux-gnu-i686-pc-linux-gnu/usr --with-mpfr=/scratch/ams/4.4-sh-linux-gnu-lite/obj/host-libs-4.4-45-sh-linux-gnu-i686-pc-linux-gnu/usr --with-ppl=/scratch/ams/4.4-sh-linux-gnu-lite/obj/host-libs-4.4-45-sh-linux-gnu-i686-pc-linux-gnu/usr --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --with-cloog=/scratch/ams/4.4-sh-linux-gnu-lite/obj/host-libs-4.4-45-sh-linux-gnu-i686-pc-linux-gnu/usr --disable-libgomp --enable-poison-system-directories --with-build-time-tools=/scratch/ams/4.4-sh-linux-gnu-lite/install/sh-linux-gnu/bin --with-build-time-tools=/scratch/ams/4.4-sh-linux-gnu-lite/install/sh-linux-gnu/bin
Thread model: posix
gcc version 4.4.1 (Sourcery G++ Lite 4.4-45)
COLLECT_GCC_OPTIONS='-v' '-o' 'hello'
 /home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../libexec/gcc/sh-linux-gnu/4.4.1/cc1 -quiet -v -iprefix /home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/sh-linux-gnu/4.4.1/ -isysroot /home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../sh-linux-gnu/libc hello.c -quiet -dumpbase hello.c -auxbase hello -version -o /tmp/ccTmWWcy.s
ignoring nonexistent directory "/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../sh-linux-gnu/libc/usr/local/include"
ignoring duplicate directory "/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/../../lib/gcc/sh-linux-gnu/4.4.1/include"
ignoring duplicate directory "/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/../../lib/gcc/sh-linux-gnu/4.4.1/include-fixed"
ignoring duplicate directory "/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/../../lib/gcc/sh-linux-gnu/4.4.1/../../../../sh-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/sh-linux-gnu/4.4.1/include
 /home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/sh-linux-gnu/4.4.1/include-fixed
 /home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/sh-linux-gnu/4.4.1/../../../../sh-linux-gnu/include
 /home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../sh-linux-gnu/libc/usr/include
End of search list.
GNU C (Sourcery G++ Lite 4.4-45) version 4.4.1 (sh-linux-gnu)
    compiled by GNU C version 4.3.2, GMP version 4.3.1, MPFR version 2.4.1-p5.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 6d45046fc0139f32061c226770713dae
COLLECT_GCC_OPTIONS='-v' '-o' 'hello'
 /home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/sh-linux-gnu/4.4.1/../../../../sh-linux-gnu/bin/as -v -little -o /tmp/ccGtcr9X.o /tmp/ccTmWWcy.s
GNU assembler version 2.19.51 (sh-linux-gnu) using BFD version (Sourcery G++ Lite 4.4-45) 2.19.51.20090709
COMPILER_PATH=/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../libexec/gcc/sh-linux-gnu/4.4.1/:/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../libexec/gcc/:/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/sh-linux-gnu/4.4.1/../../../../sh-linux-gnu/bin/
LIBRARY_PATH=/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/sh-linux-gnu/4.4.1/:/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/:/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/sh-linux-gnu/4.4.1/../../../../sh-linux-gnu/lib/:/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../sh-linux-gnu/libc/lib/:/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../sh-linux-gnu/libc/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'hello'
 /home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../libexec/gcc/sh-linux-gnu/4.4.1/collect2 --sysroot=/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../sh-linux-gnu/libc --eh-frame-hdr -m shlelf_linux -dynamic-linker /lib/ld-linux.so.2 -o hello /home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../sh-linux-gnu/libc/usr/lib/crt1.o /home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../sh-linux-gnu/libc/usr/lib/crti.o /home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/sh-linux-gnu/4.4.1/crtbegin.o -L/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/sh-linux-gnu/4.4.1 -L/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc -L/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/sh-linux-gnu/4.4.1/../../../../sh-linux-gnu/lib -L/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../sh-linux-gnu/libc/lib -L/home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../sh-linux-gnu/libc/usr/lib /tmp/ccGtcr9X.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/sh-linux-gnu/4.4.1/crtend.o /home/drasko/CodeSourcery/Sourcery_G++_Lite/bin/../sh-linux-gnu/libc/usr/lib/crtn.o
drasko@Marx:~/sh4_projects$

4) Lounch quemu test :
drasko@Marx:~/sh4_projects$ qemu-sh4 -L ~/CodeSourcery/Sourcery_G++_Lite/sh-linux-gnu/libc/ ./hello
Hello from SH4
drasko@Marx:~/sh4_projects$

Tuesday, November 3, 2009

u-boot in qemu

1) make versatile_config
2) Start u-boot.bin in qemu :
$ qemu-system-arm -M versatileab -nographic -m 256 -kernel u-boot.bin

3) Debugging:
$ qemu-system-arm -M versatileab -nographic -m 256 -kernel u-boot.bin -s -S
$ drasko@Marx:~/qemu-arm/u-boot-2009.03$ arm-linux-gnu-gdb u-boot
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i486-linux-gnu --target=arm-linux-gnu"...
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
[New Thread 1]
0x00000000 in ?? ()
(gdb)



Explanation :

Debugging with the moxie qemu simulator

I’ve finally cracked the gdb+qemu puzzle, so now we can debug code running on the qemu moxie simulator!

The last little gotcha was that the simulated $pc wasn’t being updated after single-stepping. This will get you nowhere fast! But it’s all fixed now, and here’s how it works…

$ qemu-system-moxie -s -S -kernel hello.x

This tells qemu to load our hello world program, hello.x. The “-s” option tells it to wait for a connection from GDB on port 1234. The -S option tells it to freeze on startup, and wait for a “continue” command from the debugger.

Now, in a different terminal, fire up moxie-elf-gdb on hello.x and connect to qemu like so:

(gdb) target remote localhost:1234

GDB and qemu should be talking now, and the debugger will report that the sim is waiting on __start, the entry point to our hello.x ELF file. Put a breakpoint on main, and hit ‘c’ to continue. You should be debugging as usual now. I normally run moxie-elf-gdb within emacs in order to get a nice UI, but invoking it from ddd or Eclipse should work just as well.

Wednesday, September 2, 2009

Linux development manpages on Debian [man]

Marx:/home/drasko# apt-get install manpages-posix-dev

Wednesday, August 12, 2009

Pomodoro technique and timer (applet) in Debian

http://www.pomodorotechnique.com/

http://timerapplet.sourceforge.net/
http://packages.debian.org/fr/lenny/timer-applet
http://www.flickr.com/photos/7982697@N05/sets/72157600138316537/detail/

Zero length arrays in C

http://www.mail-archive.com/freebsd-hackers@freebsd.org/msg21219.html
http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

5.14 Arrays of Length Zero

Zero-length arrays are allowed in GNU C. They are very useful as the last element of a structure which is really a header for a variable-length object:

     struct line {
       int length;
       char contents[0];
     };
    
     struct line *thisline = (struct line *)
       malloc (sizeof (struct line) + this_length);

     thisline->length = this_length;


In ISO C90, you would have to give contents a length of 1, which means either you waste space or complicate the argument to malloc.

In ISO C99, you would use a flexible array member, which is slightly different in syntax and semantics:

    * Flexible array members are written as contents[] without the 0.
    * Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero.
    * Flexible array members may only appear as the last member of a struct that is otherwise non-empty.
    * A structure containing a flexible array member, or a union containing such a structure (possibly recursively), may not be a member of a structure or an element of an array. (However, these uses are permitted by GCC as extensions.)

GCC versions before 3.0 allowed zero-length arrays to be statically initialized, as if they were flexible arrays. In addition to those cases that were useful, it also allowed initializations in situations that would corrupt later data. Non-empty initialization of zero-length arrays is now treated like any case where there are more initializer elements than the array holds, in that a suitable warning about "excess elements in array" is given, and the excess elements (all of them, in this case) are ignored.

Instead GCC allows static initialization of flexible array members. This is equivalent to defining a new structure containing the original structure followed by an array of sufficient size to contain the data. I.e. in the following, f1 is constructed as if it were declared like f2.

     struct f1 {
       int x; int y[];
     } f1 = { 1, { 2, 3, 4 } };
    
     struct f2 {
       struct f1 f1; int data[3];
     } f2 = { { 1 }, { 2, 3, 4 } };


The convenience of this extension is that f1 has the desired type, eliminating the need to consistently refer to f2.f1.

This has symmetry with normal static arrays, in that an array of unknown size is also written with [].

Of course, this extension only makes sense if the extra data comes at the end of a top-level object, as otherwise we would be overwriting data at subsequent offsets. To avoid undue complication and confusion with initialization of deeply nested arrays, we simply disallow any non-empty initialization except when the structure is the top-level object. For example:

     struct foo { int x; int y[]; };
     struct bar { struct foo z; };
    
     struct foo a = { 1, { 2, 3, 4 } };        // Valid.
     struct bar b = { { 1, { 2, 3, 4 } } };    // Invalid.

     struct bar c = { { 1, { } } };            // Valid.
     struct foo d[1] = { { 1 { 2, 3, 4 } } };  // Invalid.



-------------------


The idea is to use this zero-length array as a reference to variable

length data that’d be stored using the struct. If you are wondering why
a pointer is not used, the size of a pointer would be non-zero, whereas
the size of a zero-length array is guaranteed to be zero.


-------------------


****************    Cool explanation   *********************************

On Tue, Mar 20, 2001 at 01:03:21PM -0600, Peter Seebach wrote:
> In message <[EMAIL PROTECTED]>, Shankar Agarwal writes:

> >Can someone pls tell me if it is possible to define an array of size 0.
>
> Not in C.

Actually you can (see below).  It depends on the compiler and how strict
you have it checking things.  It only works in this case because the

memory manager is allocating an entire page for the structure, not
just the size of the structure.

It's not uncommon to use this for message-based communications where you
have a header and payload  and want to use sizeof(struct message) to get

the header size, but also want to use foo.payload to access the message
itself.  In that case, it's more likely to be used as a cast on a buffer,
(e.g., ((struct message*) buffer)->payload)

Realize, tho, there's a potential portability issue, if you use this.


What follows was done on a NetBSD 1.5 system.

[24]% cat zero.c && make zero && ./zero
#include <stdio.h>

struct zero_array {
        int header;
        int payload[0];

};

int main()
{
        struct zero_array foo;

        foo.header=1;
        foo.payload[0]=10;
        foo.payload[1]=12;
        printf("Foo:\n\theader: %d\n", foo.header);
        printf("\tpayload 0: %d\n", foo.payload[0]);

        printf("\tpayload 1: %d\n", foo.payload[1]);
        return 0;
}
cc -O2   -o zero zero.c
Foo:
        header: 1
        payload 0: 10
        payload 1: 12




****************************************************************************


In message <[EMAIL PROTECTED]>, John Franklin writes:
>On Tue, Mar 20, 2001 at 01:03:21PM -0600, Peter Seebach wrote:

>> In message <[EMAIL PROTECTED]>, Shankar Agarwal writes:
>> >Can someone pls tell me if it is possible to define an array of size 0.

 
>> Not in C.

>Actually you can (see below).  It depends on the compiler and how strict
>you have it checking things.

The C language doesn't allow zero-sized objects.  Some systems may, but

C itself doesn't.

>What follows was done on a NetBSD 1.5 system.

More importantly, it was done with gcc, which (by default) compiles a
language called "GNU C", which is very similar to C, but has some extensions.


In C99, you can do this "portably" (C99 isn't exactly universally adopted yet)
by saying
        struct message {
                int header;
                char payload[];
        };


and then doing
        struct message *p;
        p = malloc(sizeof(struct message) + 10);
        p->header = 10;
        strcpy(p->payload, "123456789");


>int main()
>{

>        struct zero_array foo;
>
>        foo.header=1;
>        foo.payload[0]=10;
>        foo.payload[1]=12;


This isn't even a result of the page management, you're just overwriting

other space.

If you did
        struct zero_array foo;
        int a[2];

you would probably find that a[0] was 10, and a[1] was 12.  Probably.
The behavior is totally undefined, and it's not exactly reliable.  :)




-------


On Fri, Mar 30, 2001 at 10:37:28AM -0500, Lord Isildur wrote:
> sine one knows the size of the struct, who need the pointer? just
> take the displacement.
>

> char* buf; /* some buffer */
> struct foo{
> int header;
> struct funkystruct blah;
> };
>
> (struct foo*)buf; /*your headers are here */
> (struct foo*)buf+1; /* and your data is here */


Could, true. Buf if foo is:

struct foo{
 struct header head;
 struct funcystruct data[0];
}

you can say:
        mesg->head->headerbits;
        mesg->data[x]->databits;


A bit more readable, IMHO.

Tuesday, August 11, 2009

Debug TRACE() with variadic arguments

Define :

#ifdef DEBUG
#define TRACE(...) printf("DBG MESSAGE: " __VA_ARGS__)
#else
#define TRACE(...)
#endif


and then in program, you can use something like :

TRACE("my_array[%d]=%x\n", i , arr_val);


All the argument from TRACE() will be taken and substitued in the place of __VA_ARGS__, which will make printf to work well and print this message, with sentence DBG MESSAGE: in the begining.

Friday, August 7, 2009

strtoul() result begins with ffffffff

How is it possible that:
char bin[64];
char test[10] = "74";

bin[0] = strtoul (test, &e, 16);
printf("bin[0]=%#x\n", bin[0]);

is giving:
bin[0]=0x74

and if we put:
char test[10] = "84";

result printed is:
bin[0]=0xffffff84

Well, for all X in char test[10] = "X4"; that are less than 8, digit X starts with binary "0". For 8 and more, it will start with binary "1". Since we put "=" between char bin[64], thus SIGNED, and result that strtoul()  signed. Two things happen here:

1) Assignment conversion
An assignment conversion makes the value of the right operand have the same data type as the left operand.
(In assignment operations, the type of the value being assigned is converted to the type of the variable that receives the assignment. C allows conversions by assignment between integral and floating types, even if information is lost in the conversion.)
That means that our unsigned long return value of strtoul() becomes signed char.

2) Conversions from Unsigned Integral Types
An unsigned integer is converted to a shorter unsigned or signed integer by truncating the high-order bits, or to a longer unsigned or signed integer by zero-extending.
When the value with integral type is demoted to a signed integer with smaller size, or an unsigned integer is converted to its corresponding signed integer, the value is unchanged if it can be represented in the new type. However, the value it represents changes if the sign bit is set, as in the following example.

int j;
unsigned short k = 65533;

j = k;
printf_s( "%hd\n", j );   // Prints -3


Let's look at char. The highest positive value you can represent with one char is +127, i.e. 0x7F. Anything above this is represented as a negative. For example, 0x80 is actually -128, the biggest (in amplitude) negative number you can represent with char (and 0xFF is -1).

So, printing our result like this:
char test[10] = "80";
bin[0] = strtoul (test, &e, 16);
printf("bin[0]=%d\n", bin[0]);
drasko@Lenin:~/stuff$ ./test
bin[0]=-128

Makes more sense, because %#x switch was additional confusion, because it printed additional (starting) 3 bytes for negaitve number, putting them all into F.

RESOLUTION OF THE PROBLEM:
The buffer that takes result of assignment must be decleared as unsigned char, and not as signed char!

If we change
char bin[64];
to
unsigned char bin[64];
results will be good.