Привет мир, голый металл Beagleboard
Я пытаюсь получить программу типа "hello world", запущенную на моем Beagleboard-xm rev. C, вызывая функцию C puts
из сборки.
До сих пор я использовал это как ссылку: http://wiki.osdev.org/ARM_Beagleboard
Вот что я до сих пор, но нет выхода.
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
Использование только 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
Поток аппаратного и программного управления в миникомпьюте отключен.
Ответы
Ответ 1
который должен был сработать для вас. Вот какой-то код, который я откопал с того пути, когда сегодня не пробовал его на 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
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 (компоновщик 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
Похоже, я только что оставил указатель стека везде, где имел загрузчик. Аналогично, как и вы, предполагается, что загрузчик инициализировал последовательный порт.
Я предполагаю, что у вас есть доступ к последовательному порту, вы видите uboot, и вы можете вводить команды, чтобы загрузить эту программу (xmodem или что-то еще) в панель ram? Если вы не можете этого сделать, возможно, вы не подключены к последовательному порту вправо. последовательный порт beagleboards является винтовой, возможно, потребуется создать собственный кабель.
Ответ 2
Вы не можете просто вслепую написать строку символов в UART - вам нужно проверить статус на каждом символе - он работает в примере с одним символом, потому что UART всегда будет готов для первого символа, но для второй и последующие символы, которые необходимо опросить (или лучше использовать ISR, но пропустите, прежде чем мы запустим).
Здесь есть хороший код примера: http://hardwarefreak.wordpress.com/2011/08/30/some-experience-with-the-beagleboard-xm-part-2/
Ответ 3
У меня недостаточно повторений для комментариев.
Но мой ответ на
Работает в любом случае. Теперь странно, что я могу печатать отдельные символы с помощью uart_send ('c'), но не могут печатать strings print_string (char * str) {while (* str!= '\ 0') uart_send (* Ул ++); } print_string ( "Тест" );, Любые мысли об этом?
является:
Вы пишете быстрее в выходном буфере, поскольку UART может отправлять.
Поэтому перед отправкой нового символа вы должны проверить, если выходной буфер пуст.
Я сделал это в коде в своем блоге (http://hardwarefreak.wordpress.com/2011/08/30/some-experience-with-the-beagleboard-xm-part-2/)