Перейти к содержанию

    

Сборка и настройка GCC кросс-компилятора под MIPS

Привет всем,

 

с некоторых пор я начас своё знакомство с SoftCore "Plasma" (MIPS1) и сваял для Altera DE1 небольшой тестовый проект, который включает в себя собственно сам процессор, UART, 2 таймера, SD-Card по SPI и кнопки/светодиоды. Память - 8мб SDRAM. Процессор тикает на частоте 12.85МГц, память на 90МГц. Пока нет никакого кэша.

Раньше я использовал сборку GCC от Steve Rhoads. Но эта сборка не имеет никаких библиотек, поэтому всё приходилось писать самому.

Поэтому я решил собрать GCC + Newlib.

Собирал под Win32 (MinGW).

  • Binutils 2.22
  • GCC 4.6.2
  • Newlib 1.20
  • GDB 7.4

Кое как получилось собрать :biggrin: Даже вроде заработало, но только проблемы с printf.

Вот мой start-up code:

   .text
   .align 2
   .global _start
   .ent    _start

_start:
   .set noreorder

   la    $gp, _gp             #initialize global pointer
   la    $5, __bss_start      #$5 = .sbss_start
   la    $4, _end             #$2 = .bss_end
   la    $sp, 0x7FFFF         #initialize stack pointer

$BSS_CLEAR:
   sw    $0, 0($5)
   slt   $3, $5, $4
   bnez  $3, $BSS_CLEAR
   addiu $5, $5, 4


   jal main
   nop

loop:
   j loop
   .set reorder
   .end _start

 

Скрипт LD:

ENTRY(_start)

SECTIONS
{
   . = 0x00000000;
   .text :
   {
      boot.o (.text)
      *(.text)
   }
   .data : { *(.data) }

   _gp = . + 0x7ff0;
   __bss_start = .;

   .bss : { *(.bss) }

   _end = .;
}

 

Syscalls:

#include <sys/stat.h>

#define _MR(A) (*(volatile unsigned int*)(A))
#define _MW(A,V) *(volatile unsigned int*)(A)=(V)

int fstat(int file, struct stat *st)
{
   st->st_mode = S_IFCHR;
   return 0;
}

int read(int file, char *ptr, int len)
{
   return 0;
}

int lseek(int file, int ptr, int dir)
{
   return 0;
}

int isatty(int file)
{
   return 1;
}

int close(int file)
{
   return -1;
}

int write(int file, char *ptr, int len)
{
   int todo;
   for (todo = 0; todo < len; todo++)
   {
      while(_MR(0x80000030)); // UART busy???
      _MW(0x80000020, *ptr++); // write to UART
   }
   return len;
}

caddr_t sbrk(int incr)
{
   extern char _end; /* Defined by the linker */
   static char *heap_end;
   char *prev_heap_end;
   if (heap_end == 0)
   {
      heap_end = &_end;
   }
   prev_heap_end = heap_end;
   heap_end += incr;
   return (caddr_t) prev_heap_end;
}

 

Программа:

#include <stdio.h>

int main(void)
{
   write(NULL,fff,3);
   printf("Hallo\n");
   while(1);
}

 

Прямой вызов write работает как надо, а вот printf нет.

Скорее всего, я думаю, у меня проблемы с heap/stack но так как опыта почти нет (всегда пользовался готовыми скриптами и start-up) то я завис. Почитал всё что смог найти в инете, но дальше дело не двигается.

Надеюсь на помощь знающих!

 

С уважением

Дима

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
....

Поэтому я решил собрать GCC + Newlib.

....

Прямой вызов write работает как надо, а вот printf нет.

Предположение #1:

printf сначала выводит даные во временный буфер, и только потом когда он наполнится вызавает соответствующий write. Этот функционал можно отключить.

setvbuf(stdin, NULL, _IONBF, 0);

.....

Скорее всего, я думаю, у меня проблемы с heap/stack но так как опыта почти нет (всегда пользовался готовыми скриптами и start-up) то я завис.

.....

Тоже может быть.

Советую вопросы по newlib задавать в соответствующем разделе форума (http://electronix.ru/forum/index.php?showforum=162) т.к. Ваш вопрос по бОльшей части к MIPS не относится.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А разве имена функций в syscalls не должны начинаться с нижнего подчеркивания ?

int _write(int file, char *ptr, int len)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация