Jump to content

    
Sign in to follow this  
SolderMan

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

Recommended Posts

Привет всем,

 

с некоторых пор я начас своё знакомство с 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) то я завис. Почитал всё что смог найти в инете, но дальше дело не двигается.

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

 

С уважением

Дима

Share this post


Link to post
Share on other sites
....

Поэтому я решил собрать 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 не относится.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this