qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] standalone C program "Hello World" on qemu-system-mipsel


From: Leo Chen.
Subject: [Qemu-devel] standalone C program "Hello World" on qemu-system-mipsel
Date: Sat, 2 Jul 2011 14:13:03 +0800

Hi, all

I am trying to run a standalone C program "Hello World" on qemu-system-mipsel,
but it failed to print the message via serial port.

What I have done now (step by step):
1. Successfully run a standalone C program "Hello World" on qemu-system-arm, by
following this guide:
http://balau82.wordpress.com/2010/02/14/simplest-bare-metal-program-for-arm/

2. Try to run the same standalone C program on qemu-system-mipsel, but
it failed.
I used GDB to trace the program, and I can make sure the program is
working fine, it just failed
to print the message via serial port, which mapped to address 0x3f8.

I know the qemu MIPS system emulator -m "mipssim" has a PC style
serial port (8250 UART).
And my code about operating the serial port is following the 8250 spec
(http://wiki.osdev.org/Serial_ports)

But now, I am stuck to make the 8250 serial port work, any suggestion
or sample codes will be appreciated.


Here is my compile/link/run commands, and the codes:

mips-linux-gnu-gcc -mips32 -EL -c startup.s -o obj/startup.o
mips-linux-gnu-gcc -mips32 -EL -static -Wall -Werror -g -msoft-float
-nostdlib -fno-exceptions -fno-builtin -nostartfiles -nodefaultlibs
-fno-stack-protector  -c test.c -o obj/test.o
mips-linux-gnu-ld -mips32 -EL -T test.ld obj/startup.o obj/test.o -o
bin/test.elf
mips-linux-gnu-objcopy -O binary bin/test.elf bin/test.bin

qemu-system-mipsel -M mipssim -nographic -kernel bin/test.elf
or
qemu-system-mipsel -M malta -nographic -kernel bin/test.elf


file: test.ld
---------------
ENTRY(_Reset)
SECTIONS
{
    . = 0x80100400;
    .startup . : { obj/startup.o(.text) }
    .text : { *(.text) }
    .data : { *(.data) }
    .bss : { *(.bss) }
    . = . + 0x1000; /* 4kB of stack memory */
    stack_top = .;
}

file: startup.s
-----------------------
    .text
    .globl _Reset
_Reset:
    lui     $sp, %hi(stack_top)
    addiu   $sp, $sp, %lo(stack_top)
    lui     $t9, %hi(c_entry)
    addiu   $t9, %lo(c_entry)
    jalr    $t9
    nop
hang:
    b       hang

file: test.c
---------------
void c_entry()
{
#if 1
    init_serial();
    print_uart0("Hello world!\n");
#endif
#if 0
    *(char *)0x3f8 = 'H';  //this also failed too
#endif
}

#define UART0_BASE 0x3f8  /* 8250 COM1 */
void init_serial() {
    volatile char * addr;
    addr = (volatile char*)(UART0_BASE + 1);
    *addr = 0x00;
    addr = (volatile char*)(UART0_BASE + 3);
    *addr = 0x80;
    addr = (volatile char*)(UART0_BASE + 0);
    *addr = 0x03;
    addr = (volatile char*)(UART0_BASE + 1);
    *addr = 0x00;
    addr = (volatile char*)(UART0_BASE + 3);
    *addr = 0x03;
    addr = (volatile char*)(UART0_BASE + 2);
    *addr = 0xc7;
    addr = (volatile char*)(UART0_BASE + 4);
    *addr = 0x0b;
}
int is_transmit_empty()
{
    volatile char *addr = (volatile char *)(UART0_BASE + 5);
    return *addr & 0x20;
}
void write_serial(char a)
{
    while (is_transmit_empty() == 0);
    volatile char *addr = (volatile char*)UART0_BASE;
    *addr = a;
}
void print_uart0(const char *s)
{
    while(*s != '\0') { /* Loop until end of string */
        write_serial( *s );
        s++; /* Next char */
    }
}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]