[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3. A Small Example

A simple “Hello World” program (what else) is used to show the basics

This is the cannonical small program. Here is the main program and its two subprograms (added to demonstrate a meaningful backtrace).

 
void level2() {
  simexit( 0 );
}

void level1() {
  level2();
}

main()
{
  int  i;
  int  j;

  simputs( "Hello World!\n" );
  level1();
}

It is linked with a program providing the utility functions simexit, simputc and simprints.

 
void  simexit( int  rc )
{
  __asm__ __volatile__ ( "\tl.nop\t%0" : : "K"( NOP_EXIT ));

}	/* simexit() */

void  simputc( int  c )
{
  __asm__ __volatile__ ( "\tl.nop\t%0" : : "K"( NOP_PUTC ));

}	/* simputc() */

void  simputs( char *str )
{
  int  i;

  for( i = 0; str[i] != '\0' ; i++ ) {
    simputc( (int)(str[i]) );
  }
}	/* simputs() */

Finally, a small bootloader is needed, which will be placed at the OpenRISC reset vector location (0x100) to set up a stack and jump to the main program.

 
        .org    0x100           # The reset routine goes at 0x100
        .global _start
_start:
        l.addi  r1,r0,0x7f00    # Set SP to value 0x7f00
        l.addi  r2,r1,0x0       # FP and SP are the same
        l.mfspr r3,r0,17        # Get SR value
        l.ori   r3,r3,0x10      # Set exception enable bit
        l.jal   _main           # Jump to main routine
        l.mtspr r0,r3,17        # Enable exceptions (DELAY SLOT)

        .org    0xFFC
        l.nop                   # Guarantee the exception vector space
                                # does not have general purpose code

This is compiled and linked with the OpenRISC 1000 GNU toolchain. Note that the linking must specify the bootloader first and use the -Ttext 0x0 argument.

The Or1ksim architectural simulator is configured with memory starting at location 0x0. The debugging interface is enabled by using a debug section.

 
section debug
  enabled         =          1
  gdb_enabled     =          1
  server_port     =      50000
end

The architectural simulator is started in its own terminal window. If the configuration is in rsp.cfg, then the command might be:

 
or32-uclinux-sim -f rsp.cfg
Reading script file from 'rsp.cfg'...
Building automata... done, num uncovered: 0/213.
Parsing operands data... done.
Resetting memory controller.
Resetting PIC.

Note that no program is specified - that will be loaded from GDB.

In a separate window start up GDB.

 
or32-uclinux-gdb

A local copy of the symbol table is needed, specified with the file command.

 
Building automata... done, num uncovered: 0/216.
Parsing operands data... done.
GNU gdb 6.8
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=i686-pc-linux-gnu --target=or32-uclinux".
(gdb) file hello
Reading symbols from /home/jeremy/svntrunk/GNU/gdb-6.8/progs_or32/hello...done.
(gdb) 

The connection to the target (the architectural simulator) is then established, using the port number given in the configuration file.

 
(gdb) target remote :51000
Remote debugging using :51000
0x00000100 in _start ()
(gdb) 

The program of interest can now be loaded:

 
(gdb) load hello
Loading section .text, size 0x1290 lma 0x0
Loading section .rodata, size 0xe lma 0x1290
Start address 0x100, load size 4766
Transfer rate: 5 KB/sec, 238 bytes/write.
(gdb) 

The program does not immediately start running, since on opening the connection to the target, Or1ksim stalls.

All the GDB commands (including the SPR commands are available). For example

 
(gdb) bt
#0  0x00000100 in _start ()
(gdb) info spr 0 17
SYS.SR = SPR0_17 = 32769 (0x8001)
(gdb) 

The Supervision Register shows the target is in Supervisor Mode and that SPRs have User Mode read access.

Note. The supervision register is used to provide the value for the GDB $ps processor status variable, so can also be accessed as:

 
(gdb) print $ps
$1 = 32769
(gdb)

For this example set a breakpoint at the start of main and then continue the program

 
(gdb) break main
Breakpoint 1 at 0x1264: file hello.c, line 41.
(gdb) continue
Continuing.

Breakpoint 1, main () at hello.c:41
41        simputs( "Hello World!\n" );
(gdb) 

It is now possible to step through the code:

 
(gdb) step
simputs (str=0x1290 "Hello World!\n") at utils.c:90
90        for( i = 0; str[i] != '\0' ; i++ ) {
(gdb) step
91          simputc( (int)(str[i]) );
(gdb) step
simputc (c=72) at utils.c:58
58        __asm__ __volatile__ ( "\tl.nop\t%0" : : "K"( NOP_PUTC ));
(gdb)

At this point a backtrace will show where the code has reached:

 
(gdb) bt
#0  simputc (c=72) at utils.c:58
#1  0x000011cc in simputs (str=0x1290 "Hello World!\n") at utils.c:91
#2  0x00001274 in main () at hello.c:41
#3  0x00000118 in _start ()
(gdb) 

One more step completes the call to the character output routine. Inspecting the terminal running the Or1ksim simulation, shows the output appearing:

 
JTAG Proxy server started on port 50000
Resetting PIC.
H

Let the program run to completion by giving GDB the continue command:

 
(gdb) continue
Continuing.
Remote connection closed
(gdb) 

With completion of the program, the terminal running Or1ksim shows its final output:

 
Resetting PIC.
Hello World!
exit(0)
@reset : cycles 0, insn #0
@exit  : cycles 215892308, insn #215891696
 diff  : cycles 215892308, insn #215891696

When execution exits (by execution of a l.nop 1), the connection to the target is automatically broken as the simulator exits.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Jeremy Bennett on November, 12 2008 using texi2html 1.78.