Search code examples
carmbeagleboardomap

Hello world, bare metal Beagleboard


I'm trying to get a 'hello world' type program running on my Beagleboard-xm rev. C, by calling a C puts function from assembly.

So far I've been using this as a reference: http://wiki.osdev.org/ARM_Beagleboard

Here's what I have so far, but there's no output.

hello.c

volatile unsigned int * const UART3DR = (unsigned int *)0x49020000;

void puts(const char *s) {
  while(*s != '\0') { 
    *UART3DR = (unsigned int)(*s); 
    s++; 
  }
}

void hello() {
  puts("Hello, Beagleboard!\n");
}

boot.asm

.global start
start:
   ldr sp, =stack_bottom
   bl hello
   b .

linker.ld

ENTRY(start)

MEMORY
{
    ram : ORIGIN = 0x80200000, LENGTH = 0x10000
}

SECTIONS
{
    .hello : { hello.o(.text) } > ram
    .text : { *(.text) } > ram
    .data : { *(.data) } > ram
    .bss : { *(.bss) } > ram
     . = . + 0x5000; /* 4kB of stack memory */
    stack_bottom = .;

}

Makefile

ARMGNU = arm-linux-gnueabi

AOPS = --warn --fatal-warnings
COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding

boot.bin: boot.asm
   $(ARMGNU)-as boot.asm -o boot.o
   $(ARMGNU)-gcc-4.6 -c $(COPS) hello.c -o hello.o
   $(ARMGNU)-ld -T linker.ld hello.o boot.o -o boot.elf
   $(ARMGNU)-objdump -D boot.elf > boot.list
   $(ARMGNU)-objcopy boot.elf -O srec boot.srec
   $(ARMGNU)-objcopy boot.elf -O binary boot.bin

Using just the asm file like this works.

.equ UART3.BASE,        0x49020000
start:
   ldr r0,=UART3.BASE
   mov r1,#'c'

Here are some Beagleboard/minicom related info: http://paste.ubuntu.com/829072/

Any pointers? :)


I also tried

void hello() {
  *UART3DR = 'c';
}

I'm using minicom and send the file via ymodem, then I try to run it with:

go 0x80200000

Hardware and software control flow in minicom are off.


Solution

  • that should have worked for you. Here is some code I dug up from way back when, did not try it on a beagleboard tonight just made sure it compiled, it had worked at one time...

    startup.s:

        .code 32
    
    .globl _start
    _start:
    
        bl main
    hang: b hang
    
    .globl PUT32
    PUT32:
        str r1,[r0]
        bx lr
    
    .globl GET32
    GET32:
        ldr r0,[r0]
        bx lr
    

    hello.c :

    extern void PUT32 ( unsigned int, unsigned int );
    extern unsigned int GET32 ( unsigned int );
    void uart_send ( unsigned char x )
    {
        while((GET32(0x49020014)&0x20)==0x00) continue;
        PUT32(0x49020000,x);
    }
    void hexstring ( unsigned int d )
    {
        //unsigned int ra;
        unsigned int rb;
        unsigned int rc;
    
        rb=32;
        while(1)
        {
            rb-=4;
            rc=(d>>rb)&0xF;
            if(rc>9) rc+=0x37; else rc+=0x30;
            uart_send(rc);
            if(rb==0) break;
        }
        uart_send(0x0D);
        uart_send(0x0A);
    }
    int main ( void )
    {
        hexstring(0x12345678);
        return(0);
    }
    

    memmap (linker script):

    MEMORY
    {
        ram : ORIGIN = 0x82000000, LENGTH = 256K
    }
    
    SECTIONS
    {
        ROM : { startup.o } > ram
    }
    

    Makefile :

    CROSS_COMPILE = arm-none-eabi
    
    AOPS = --warn --fatal-warnings 
    COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding 
    
    all : hello.bin
    
    hello.bin : startup.o hello.o memmap
        $(CROSS_COMPILE)-ld startup.o hello.o -T memmap -o hello.elf  
        $(CROSS_COMPILE)-objdump -D hello.elf > hello.list
        $(CROSS_COMPILE)-objcopy hello.elf -O binary hello.bin
    
    startup.o : startup.s
        $(CROSS_COMPILE)-as $(AOPS) startup.s -o startup.o
    
    hello.o : hello.c 
        $(CROSS_COMPILE)-gcc -c $(COPS) hello.c -o hello.o
    
    clean :
        rm -f *.o
        rm -f *.elf
        rm -f *.bin
        rm -f *.list
    

    Looks like I just left the stack pointer wherever the bootloader had it. Likewise, as you, assumed the bootloader had initialized the serial port.

    I assume you have serial port access working, you see uboot and you are able to type commands in order to download this program (xmodem, or whatever) into the boards ram? If you cant do that then it may be you are not connected to the serial port right. the beagleboards serial port is screwy, might need to make your own cable.