你好,世界,裸金属Beagleboard



我正试图通过从汇编中调用一个puts函数,在我的Beagleboard xm rev.C上运行一个"hello-world"类型的程序。

到目前为止,我一直将此作为参考:http://wiki.osdev.org/ARM_Beagleboard

这是我到目前为止所拥有的,但没有输出。

你好。c

volatile unsigned int * const UART3DR = (unsigned int *)0x49020000;
void puts(const char *s) {
  while(*s != '') { 
    *UART3DR = (unsigned int)(*s); 
    s++; 
  }
}
void hello() {
  puts("Hello, Beagleboard!n");
}

引导.asm

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

链接器.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 = .;
}

生成文件

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

像这样只使用asm文件就可以了。

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

以下是一些与Beagleboard/minicom相关的信息:http://paste.ubuntu.com/829072/

有指针吗?:)


我也试过

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

我使用minicom并通过ymodem发送文件,然后我尝试使用运行它

go 0x80200000

微型通信中的硬件和软件控制流关闭。

应该对您有效。这是我从很久以前挖到的一些代码,今晚没有在beagleboard上尝试,只是确保它被编译了,它曾经工作过。。。

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

你好。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(链接器脚本):

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

看起来我只是把堆栈指针留在了引导程序所在的位置。同样,就像你一样,假设引导程序已经初始化了串行端口。

我假设你有串行端口访问功能,你看到uboot了,你可以键入命令来将这个程序(xmodem或其他什么)下载到板ram中吗?如果你不能做到这一点,那么可能是你没有正确连接到串行端口。beagleboard的串行端口很奇怪,可能需要自己制作电缆。

您不能只是盲目地将字符串写入UART-您需要检查每个字符的状态-它在单字符示例中有效,因为UART总是为第一个字符做好准备,但对于第二个和后续字符,您需要轮询(或者更好地使用ISR,但让我们在运行之前先走好)。

这里有一些很好的示例代码:http://hardwarefreak.wordpress.com/2011/08/30/some-experience-with-the-beagleboard-xm-part-2/

我没有足够的重复来评论。。但我对的答复

无论哪种方式都有效。现在奇怪的是,我可以打印个人例如,带有uart_send('c')的字符,但无法打印字符串print_string(char*str){while(*str!='\0')uart_send(*str++);}print_string("测试")。对此有什么想法吗?

是:

您在输出缓冲区中的写入速度更快,因为UART能够发送。。因此,在发送新字符之前,必须检查输出缓冲区是否为空。

我已经在博客上的代码中做到了这一点(http://hardwarefreak.wordpress.com/2011/08/30/some-experience-with-the-beagleboard-xm-part-2/)

相关内容

  • 没有找到相关文章

最新更新