Thursday, 3 September 2015

startup_first_small.s

.global _asm_entry

.section RESET_VECTOR, "x"
_asm_entry:
    LDR sp, =stack_top    /* Set stack pointer */
    BL c_entry            /* C code entry point */
    B .                    /* Loop forever after return from C code */

linker_first.lds

ENTRY(_asm_entry) /* Entry point of the program */

SECTIONS
{
    . = 0x402F0400;            /* Internal SRAM start */
    .text :                    /* Code placement */
    {
        startup_first.o (RESET_VECTOR)
        *(.text)
    }
    .data : { *(.data) }    /* Global and static variables initialized by the application code */
    .bss : { *(.bss) }        /* Global and static variables that are not initialized by the application code.
                                The compiler initializes this data to 0. */
    . = ALIGN(8);
    . = . + 0x1000;            /* 4KiB of stack memory */
    stack_top = .;            /* stack grows upwards */
}

blink_LED.c

#include "bbb.h"
#include "common.h"

// Four LEDs connected to GPIO1_21-24
#define LED_MASK (0xF << 21)
#define LED_PATTERN     (0xA << 21)

static void init_led_output(void)
{
    // Enable the GPIO module - CM_PER_GPIO1_CLKCTRL
    *(volatile uint32_t *)(0x44e00000 + 0xAC) = (0x1 << 18) | (0x2 << 0);

    // Enable output - GPIO1_OE
    *(volatile uint32_t *)(0x4804C000 + 0x134) &= ~LED_MASK;
}

static void heartbeat_forever(void)
{
    for (;;)
    {
        // On - GPIO1_DATAOUT
        *(volatile uint32_t *)(0x4804C000 + 0x13C) |= LED_PATTERN;
        delay(500000);

        // Off - GPIO1_DATAOUT
        *(volatile uint32_t *)(0x4804C000 + 0x13C) &= ~LED_PATTERN;
        delay(380000);

        // On
        *(volatile uint32_t *)(0x4804C000 + 0x13C) |= LED_PATTERN;
        delay(240000);

        // Off
        *(volatile uint32_t *)(0x4804C000 + 0x13C) &= ~LED_PATTERN;
        delay(2400000);
    }
}

int c_entry(void)
{
    init_led_output();
    heartbeat_forever();

    return 0;
}

Makefile

SRCS := timer_test.c
#SRCS := blink_led.c leds_test.o serial_test.c switch_test.c timer_test.c eeprom_test.c fw_app.c
BINS := $(SRCS:.c=.bin)

all: ${BINS}

#show: eeprom_test_disasm
# TODO
show: timer_test_disasm

leds_test.elf: leds.o

serial_test.elf: serial.o

switch_test.elf: debug.o serial.o

#timer_test.elf: timer.o leds.o debug.o serial.o
timer_test.elf: timer.o interrupt.o leds.o debug.o serial.o

eeprom_test.elf: eeprom.o i2c.o leds.o debug.o serial.o
#eeprom_test.elf: eeprom.o i2c.o interrupt.o debug.o serial.o

#fw_app.elf: leds.o pwm.o eeprom.o debug.o serial.o

.dep: ${SRCS}
    @${CROSS_COMPILE}gcc ${CFLAGS} -MM $^ > .dep

allclean: clean
    ${RM} .dep a.out

include rules.mk
-include .dep

BARE METAL BEAGLE BONE BLACK PROGRAMMING

http://stackoverflow.com/questions/9142951/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.