Services - tools - models - for embedded software development
Embecosm divider strip
Prev  Next

5.2.  Debugging Linux

GDB can be used to debug Linux if required, but there are difficulties with handling virtual addresses with a "bare metal" debugger. A page miss would require execution of the relevant exception handler. As a consequence, all access via the current GDB implementation is to and from physical addresses, bypassing caches and MMUs if present.

The eventual solution will be to port KGDB (kgdb.linsyssoft.com), which knows how to handle memory in the kernel.

Sometimes just inserting printk statements is sufficient. The problem is that the kernel print function, printk does not work until the serial driver is up and running. Problems earlier than this (very likely during the early stages of porting) will be hidden.

The solution is to patch printk to use the internal simulator print facilities. Use of Or1ksim simprintf direct from printk is not appropriate, since its argument is a pointer and at the time of calling, the whole virtual memory system may be in flux.

However printk calls vprintk which does the complex work of building the final output string from the format string and arguments. This string can then be printed a character at a time using the Or1ksim NOP_PUTC feature. Since characters are passed in registers, not as pointers, the issue of virtual memory does not arise.

The implementation of the printk can be found in kernel/printk.c in the Linux directory. In there find the vprintk function. Immediately before it add two functions to write a string one character at a time using the Or1ksim NOP_PUTC feature.

#define NOP_PUTC  4

static void simputc( char c )
{
        asm( "l.or   r3,r0,%0" : : "r" (c));
        asm( "l.nop  %0"       : : "K" (NOP_PUTC));

}       /* simputc() */


static void simputs( char *str )
{
        int  i = 0;

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

Then find the line in vprintk where the formatted string is constructed in the printk_buf:

	printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);
      

Immediately after this use the new simputs function to print this string to the console via Or1ksim.

	simputs( printk_buf );	/* For Or1ksim */
	

Rebuild Linux (see Section 3.4) and run again under the simulator. The Linux kernel output will appear in the window from which the simulator was run.

   <... Or1ksim startup messages ...>

Copying Linux... Ok, booting the kernel.
****************** counters reset ******************
cycles 145321226, insn #9988651
****************** counters reset ******************
<5>Linux version 2.6.23-or32 (jeremy@thomas) (gcc version 3.4.4) #3 Sat Jun 28 1
9:30:06 BST 2008
Detecting Processor units:
  Signed 0x391
Setting up paging and PTEs.
write protecting ro sections (0xc0002000 - 0xc024c000)
Setting up identical mapping (0x80000000 - 0x90000000)
Setting up identical mapping (0x92000000 - 0x92002000)
Setting up identical mapping (0xb8070000 - 0xb8072000)
Setting up identical mapping (0x97000000 - 0x97002000)
Setting up identical mapping (0x99000000 - 0x9a000000)
Setting up identical mapping (0x93000000 - 0x93002000)

   <... Lots more kernel messages ...>

<5>VFS: Disk quotas dquot_6.5.1
Dquot-cache hash table entries: 2048 (order 0, 8192 bytes)
<6>Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
<6>io scheduler noop registered
<6>io scheduler anticipatory registered (default)
<6>io scheduler deadline registered
<6>io scheduler cfq registered
<6>Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing disabled
<6>serial8250.0: ttyS0 at MMIO 0x90000000 (irq = 2) is a 16550A

   <... Serial I/O now working! ...>

init started:  BusyBox v1.4.1 (2007-03-22 18:53:56 EST) multi-call binary
Starting pid 22, console /dev/ttyS0: '/etc/init.d/rcS'
	

The kernel does not lose messages, it saves them until serial I/O is available and then prints them, so once the 8250 is initialized, everything will appear on the console and on the xterm used by the Or1ksim UART.

That concludes this application note. Enjoy the tools!

Embecosm divider strip