Changeset 5d18fb0 in rtems


Ignore:
Timestamp:
Jun 27, 1998, 6:51:49 PM (22 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
cf65c408
Parents:
98100d2
Message:

PC386 BSP enhancements from Aleksey Romanov (Quality Quorum
<qqi@…>). Unfortunately after merging these,
the pc386 will not boot using grub for for. It still does not
work using netboot for me. Here is his summary of changes:

rtems/c/src/lib/libbsp/i386/pc386/Makefile.in

Added support for new sub-directory

rtems/c/src/lib/libbsp/i386/pc386/bsp_specs

Made possible to build COFF image

rtems/c/src/lib/libbsp/i386/pc386/console/console.c

Added support for serial consoles, selectable by patching
binary image, added assert(), use _IBMPC_inch_sleep()
instaed of _IMBPC_inch()

rtems/c/src/lib/libbsp/i386/pc386/console/inch.c

Added _IMBPC_inch_sleep()

rtems/c/src/lib/libbsp/i386/pc386/console/outch.c

Oops - just formatting

rtems/c/src/lib/libbsp/i386/pc386/include/Makefile.in

Added support for new files

rtems/c/src/lib/libbsp/i386/pc386/include/bsp.h

Added support for new features

rtems/c/src/lib/libbsp/i386/pc386/include/pc386uart.h

New file: definitions for serial ports

rtems/c/src/lib/libbsp/i386/pc386/include/pcibios.h

New file: definitions for PCI BIOS

rtems/c/src/lib/libbsp/i386/pc386/pc386dev/Makefile.in

New file: makefile in new directory

rtems/c/src/lib/libbsp/i386/pc386/pc386dev/i386-stub-glue.c

New file: i386-stub interface

rtems/c/src/lib/libbsp/i386/pc386/pc386dev/i386-stub.c

New file: i386-stub itself

rtems/c/src/lib/libbsp/i386/pc386/pc386dev/pc386uart.c

New file: serial ports

rtems/c/src/lib/libbsp/i386/pc386/pc386dev/pcibios.c

New file: PCI BIOS support

rtems/c/src/lib/libbsp/i386/pc386/start/start.s

Commented out DEBUG_EARLY stuff, everything is working fine

rtems/c/src/lib/libbsp/i386/pc386/start/start16.s

Cleaned up

rtems/c/src/lib/libbsp/i386/pc386/startup/bspstart.c

Added call to console_resereve_resources

rtems/c/src/lib/libbsp/i386/pc386/startup/exit.c

Added support for serial console

rtems/c/src/lib/libbsp/i386/pc386/startup/ldsegs.s

Fixed typo in comments

rtems/c/src/lib/libbsp/i386/pc386/tools/Makefile.in

Changed to reflect cnages in code

rtems/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c

Trivialized, problem - I do not know how to make patch
remove obsolete files - there are a lot of them there

rtems/c/src/lib/libbsp/i386/pc386/tools/binpatch.c

New file: utility to do binary patches

rtems/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in

Added support for new directory

rtems/make/custom/pc386.cfg

Add COFF image building

Files:
2 added
15 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/i386/pc386/Makefile.in

    r98100d2 r5d18fb0  
    1414# wrapup is the one that actually builds and installs the library
    1515#  from the individual .rel files built in other directories
    16 SUB_DIRS=include tools start startup clock console timer wrapup
     16SUB_DIRS=include tools start startup clock console timer pc386dev wrapup
  • c/src/lib/libbsp/i386/pc386/bsp_specs

    r98100d2 r5d18fb0  
    2020
    2121*link:
    22 %{!qrtems: %(old_link)} %{qrtems: -dc -dp -N -e start --oformat=elf32-i386}
     22%{!qrtems: %(old_link)} %{qrtems: -dc -dp -N -e start}
    2323
  • c/src/lib/libbsp/i386/pc386/console/console.c

    r98100d2 r5d18fb0  
    3434
    3535#include <stdlib.h>
     36#include <assert.h>
    3637
    3738#include <bsp.h>
    3839#include <irq.h>
    3940#include <rtems/libio.h>
     41#include <termios.h>
     42#include <pc386uart.h>
     43
     44int PC386ConsolePort = PC386_CONSOLE_PORT_CONSOLE;
     45
     46static int conSetAttr(int minor, const struct termios *);
    4047
    4148/*-------------------------------------------------------------------------+
     
    5259
    5360
    54 /*-------------------------------------------------------------------------+
    55 | Functions
    56 +--------------------------------------------------------------------------*/
    57 /*-------------------------------------------------------------------------+
    58 |         Function: console_cleanup
    59 |      Description: This routine is called at exit to clean up the console
    60 |                   hardware.
    61 | Global Variables: None.
    62 |        Arguments: None.
    63 |          Returns: Nothing.
    64 +--------------------------------------------------------------------------*/
    65 void
    66 console_cleanup(void)
    67 {
    68   /* nothing */
    69 } /* console_cleanup */
    70 
    71 
    72 /*-------------------------------------------------------------------------+
    73 |         Function: is_character_ready
    74 |      Description: Check if a character is available for input, and if so
    75 |                   return it.
    76 | Global Variables: None.
    77 |        Arguments: c - character read if available, otherwise unchanged.
    78 |          Returns: TRUE if there was a character available for input,
    79 |                   FALSE otherwise.
    80 +--------------------------------------------------------------------------*/
    81 rtems_boolean
    82 is_character_ready(char *c)
    83 {
    84   return (_IBMPC_chrdy(c) ? TRUE : FALSE);
    85 } /* is_character_ready */
    86 
    87 
    88 /*-------------------------------------------------------------------------+
    89 |         Function: inbyte
    90 |      Description: Read a character from the console (keyboard).
    91 | Global Variables: None.
    92 |        Arguments: None.
    93 |          Returns: Caracter read from the console.
    94 +--------------------------------------------------------------------------*/
    95 unsigned char
    96 inbyte(void)
    97 {
    98   char c = _IBMPC_inch();
    99 
    100   /* Echo character to screen */
    101   _IBMPC_outch(c);
    102   if (c == '\r')
    103     _IBMPC_outch('\n');  /* CR = CR + LF */
    104 
    105   return c;
    106 } /* inbyte */
    107 
    108 
    109 /*-------------------------------------------------------------------------+
    110 |         Function: outbyte
    111 |      Description: Write a character to the console (display).
    112 | Global Variables: None.
    113 |        Arguments: Character to be written.
    114 |          Returns: Nothing.
    115 +--------------------------------------------------------------------------*/
    116 void
    117 outbyte(char c)
    118 {
    119   _IBMPC_outch(c);
    120 } /* outbyte */
    121 
     61void console_reserve_resources(rtems_configuration_table *conf)
     62{
     63  if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
     64    {
     65      rtems_termios_reserve_resources(conf, 1);
     66    }
     67  return;
     68}
     69
     70void __assert(const char *file, int line, const char *msg)
     71{
     72  printk("assert failed: %s: ", file);
     73  printk("%d: ", line);
     74  printk("%s\n", msg);
     75
     76  exit(1);
     77
     78  return;
     79}
    12280
    12381/*-------------------------------------------------------------------------+
     
    13694  _IBMPC_initVideo();
    13795
    138   /* Install keyboard interrupt handler */
    139   status = PC386_installRtemsIrqHandler(KEYBOARD_IRQ, _IBMPC_keyboard_isr);
    140 
    141   if (status != RTEMS_SUCCESSFUL)
    142   {
    143     printk("Error installing keyboard interrupt handler!\n");
    144     rtems_fatal_error_occurred(status);
    145   }
    146 
    147   status =
    148     rtems_io_register_name("/dev/console", major, (rtems_device_minor_number)0);
    149  
    150   if (status != RTEMS_SUCCESSFUL)
    151   {
    152     printk("Error registering console device!\n");
    153     rtems_fatal_error_occurred(status);
    154   }
    155  
    156   atexit(console_cleanup);
    157 
     96  if(PC386ConsolePort == PC386_CONSOLE_PORT_CONSOLE)
     97    {
     98
     99      /* Install keyboard interrupt handler */
     100      status = PC386_installRtemsIrqHandler(KEYBOARD_IRQ, _IBMPC_keyboard_isr);
     101
     102      if (status != RTEMS_SUCCESSFUL)
     103        {
     104          printk("Error installing keyboard interrupt handler!\n");
     105          rtems_fatal_error_occurred(status);
     106        }
     107     
     108      status = rtems_io_register_name("/dev/console", major, 0);
     109      if (status != RTEMS_SUCCESSFUL)
     110        {
     111          printk("Error registering console device!\n");
     112          rtems_fatal_error_occurred(status);
     113        }
     114      printk("Initialized console on port CONSOLE\n\n");
     115    }
     116  else
     117    {
     118      /*
     119       * Set up TERMIOS
     120       */
     121      rtems_termios_initialize ();
     122     
     123      /*
     124       * Do device-specific initialization
     125       */
     126     
     127      /* 9600-8-N-1 */
     128      PC386_uart_init(PC386ConsolePort, 9600, 0);
     129     
     130     
     131      /* Set interrupt handler */
     132      if(PC386ConsolePort == PC386_UART_COM1)
     133        {
     134          status = PC386_installRtemsIrqHandler(PC386_UART_COM1_IRQ,
     135                                                PC386_uart_termios_isr_com1);
     136        }
     137      else
     138        {
     139          assert(PC386ConsolePort == PC386_UART_COM2);
     140
     141          status = PC386_installRtemsIrqHandler(PC386_UART_COM2_IRQ,
     142                                                PC386_uart_termios_isr_com2);
     143        }
     144      /*
     145       * Register the device
     146       */
     147      status = rtems_io_register_name ("/dev/console", major, 0);
     148      if (status != RTEMS_SUCCESSFUL)
     149        {
     150          printk("Error registering console device!\n");
     151          rtems_fatal_error_occurred (status);
     152        }
     153
     154      if(PC386ConsolePort == PC386_UART_COM1)
     155        {
     156          printk("Initialized console on port COM1 9600-8-N-1\n\n");
     157        }
     158      else
     159        {
     160          printk("Initialized console on port COM2 9600-8-N-1\n\n");
     161        }
     162    }
     163 
    158164  return RTEMS_SUCCESSFUL;
    159165} /* console_initialize */
     
    165171rtems_device_driver
    166172console_open(rtems_device_major_number major,
    167              rtems_device_minor_number minor,
    168              void                      *arg)
    169 {
     173                rtems_device_minor_number minor,
     174                void                      *arg)
     175{
     176  rtems_status_code              status;
     177  static rtems_termios_callbacks cb =
     178  {
     179    NULL,                     /* firstOpen */
     180    NULL,                     /* lastClose */
     181    NULL,                     /* pollRead */
     182    PC386_uart_termios_write_com1, /* write */
     183    conSetAttr,               /* setAttributes */
     184    NULL,                     /* stopRemoteTx */
     185    NULL,                     /* startRemoteTx */
     186    1                         /* outputUsesInterrupts */
     187  };
     188
     189  if(PC386ConsolePort == PC386_CONSOLE_PORT_CONSOLE)
     190    {
     191      return RTEMS_SUCCESSFUL;
     192    }
     193
     194  if(PC386ConsolePort == PC386_UART_COM2)
     195    {
     196      cb.write = PC386_uart_termios_write_com2;
     197    }
     198
     199  status = rtems_termios_open (major, minor, arg, &cb);
     200
     201  if(status != RTEMS_SUCCESSFUL)
     202    {
     203      printk("Error openning console device\n");
     204      return status;
     205    }
     206
     207  /*
     208   * Pass data area info down to driver
     209   */
     210  PC386_uart_termios_set(PC386ConsolePort,
     211                         ((rtems_libio_open_close_args_t *)arg)->iop->data1);
     212 
     213  /* Enable interrupts  on channel */
     214  PC386_uart_intr_ctrl(PC386ConsolePort, PC386_UART_INTR_CTRL_TERMIOS);
     215
    170216  return RTEMS_SUCCESSFUL;
    171 } /* console_open */
    172 
     217}
    173218
    174219/*-------------------------------------------------------------------------+
     
    180225              void                      *arg)
    181226{
     227  if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
     228    {
     229      return rtems_termios_close (arg);
     230    }
     231
    182232  return RTEMS_SUCCESSFUL;
    183233} /* console_close */
     
    197247  char                  *buffer  = rw_args->buffer;
    198248  int            count, maximum  = rw_args->count;
     249
     250  if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
     251    {
     252      return rtems_termios_read (arg);
     253    }
    199254 
    200255  for (count = 0; count < maximum; count++)
    201256  {
    202     buffer[count] = inbyte();
     257    /* Get character */
     258    buffer[count] = _IBMPC_inch_sleep();
     259
     260    /* Echo character to screen */
     261    _IBMPC_outch(buffer[count]);
     262    if (buffer[count] == '\r')
     263      {
     264        _IBMPC_outch('\n');  /* CR = CR + LF */
     265      }
     266
    203267    if (buffer[count] == '\n' || buffer[count] == '\r')
    204268    {
     
    228292  char                  *buffer  = rw_args->buffer;
    229293  int            count, maximum  = rw_args->count;
     294
     295  if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
     296    {
     297      return rtems_termios_write (arg);
     298    }
    230299 
    231300  for (count = 0; count < maximum; count++)
    232301  {
    233     outbyte(buffer[count]);
     302    _IBMPC_outch(buffer[count]);
    234303    if (buffer[count] == '\n')
    235       outbyte('\r');            /* LF = LF + CR */
     304      _IBMPC_outch('\r');            /* LF = LF + CR */
    236305  }
    237306
     
    241310
    242311
    243 /*-------------------------------------------------------------------------+
    244 | Console device driver CONTROL entry point
    245 +--------------------------------------------------------------------------*/
    246 rtems_device_driver
     312 
     313/*
     314 * Handle ioctl request.
     315 */
     316rtems_device_driver
    247317console_control(rtems_device_major_number major,
    248                 rtems_device_minor_number minor,
    249                 void                      *arg)
    250 {
     318                rtems_device_minor_number minor,
     319                void                      * arg
     320)
     321{
     322  if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
     323    {
     324      return rtems_termios_ioctl (arg);
     325    }
     326
    251327  return RTEMS_SUCCESSFUL;
    252 } /* console_control */
     328}
     329
     330static int
     331conSetAttr(int minor, const struct termios *t)
     332{
     333  int baud;
     334
     335  switch (t->c_cflag & CBAUD)
     336    {
     337    case B50:   
     338      baud = 50;
     339      break;
     340    case B75:   
     341      baud = 75;       
     342      break;
     343    case B110: 
     344      baud = 110;       
     345      break;
     346    case B134: 
     347      baud = 134;       
     348      break;
     349    case B150: 
     350      baud = 150;       
     351      break;
     352    case B200:
     353      baud = 200;       
     354      break;
     355    case B300: 
     356      baud = 300;
     357      break;
     358    case B600: 
     359      baud = 600;       
     360      break;
     361    case B1200:
     362      baud = 1200;
     363      break;
     364    case B1800:
     365      baud = 1800;     
     366      break;
     367    case B2400:
     368      baud = 2400;
     369      break;
     370    case B4800:
     371      baud = 4800;
     372      break;
     373    case B9600:
     374      baud = 9600;
     375      break;
     376    case B19200:
     377      baud = 19200;
     378      break;
     379    case B38400:
     380      baud = 38400;
     381      break;
     382    case B57600:       
     383      baud = 57600;
     384      break;
     385    case B115200:
     386      baud = 115200;
     387      break;
     388    default:
     389      baud = 0;
     390      rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
     391      return 0;
     392    }
     393
     394  PC386_uart_set_baud(PC386ConsolePort, baud);
     395
     396  return 0;
     397}
     398
     399
     400
     401
     402
     403
     404
     405
     406
  • c/src/lib/libbsp/i386/pc386/console/inch.c

    r98100d2 r5d18fb0  
    7171static rtems_unsigned16 kbd_first = 0;
    7272static rtems_unsigned16 kbd_last  = 0;
     73static rtems_unsigned16 kbd_end   = KBD_BUF_SIZE - 1;
    7374
    7475/*-------------------------------------------------------------------------+
     
    8283{
    8384  /* shutdown and reboot */
    84   outport_byte(0x64, 0xFE);        /* use keyboard controler to do the job... */
     85  outport_byte(0x64, 0xFE);      /* use keyboard controler to do the job... */
    8586} /* rtemsReboot */
    8687
     
    224225  {
    225226    /* Got one; save it if there is enough room in buffer. */
    226     unsigned int next = (kbd_last + 1) % KBD_BUF_SIZE;
     227    unsigned int next = (kbd_last == kbd_end) ? 0 : kbd_last + 1;
    227228
    228229    if (next != kbd_first)
    229       kbd_last = next;
     230      {
     231        kbd_last = next;
     232      }
    230233  }
    231234
     
    278281    return c;
    279282} /* _IBMPC_inch */
     283
     284/*-------------------------------------------------------------------------+
     285|         Function: _IBMPC_inch_sleep
     286|      Description: If charcter is ready return it, otherwise sleep until
     287|                   it is ready
     288| Global Variables: None.
     289|        Arguments: None.
     290|          Returns: character read from keyboard.
     291+--------------------------------------------------------------------------*/
     292char
     293_IBMPC_inch_sleep(void)
     294{
     295    char c;
     296    extern rtems_interval _TOD_Ticks_per_second; /* XXX should not do this */
     297    rtems_interval ticks_to_delay;
     298
     299    ticks_to_delay = (_TOD_Ticks_per_second + 24) / 25;
     300
     301    for(;;)
     302      {
     303        if(_IBMPC_chrdy(&c))
     304          {
     305            return c;
     306          }
     307        rtems_task_wake_after(ticks_to_delay);
     308      }
     309       
     310    return c;
     311} /* _IBMPC_inch */
     312
     313
     314
     315
     316
     317
  • c/src/lib/libbsp/i386/pc386/console/outch.c

    r98100d2 r5d18fb0  
    3434static unsigned int   nLines;
    3535
    36     static void
    37 scroll()
     36static void
     37scroll(void)
    3838{
    3939    int i, j;                               /* Counters */
     
    5656}
    5757
    58     static void
    59 endColumn()
     58static void
     59endColumn(void)
    6060{
    6161    if (++row == maxRow) {
     
    7171
    7272
    73     static void
     73static void
    7474videoPutChar(char car)
    7575{
     
    118118}       
    119119
    120     void
    121 clear_screen()
     120void
     121clear_screen(void)
    122122{
    123123    int i,j;
  • c/src/lib/libbsp/i386/pc386/include/Makefile.in

    r98100d2 r5d18fb0  
    99PROJECT_ROOT = @PROJECT_ROOT@
    1010
    11 H_FILES = $(srcdir)/bsp.h $(srcdir)/coverhd.h  $(srcdir)/irq.h $(srcdir)/crt.h
     11H_FILES = $(srcdir)/bsp.h $(srcdir)/coverhd.h  $(srcdir)/irq.h \
     12          $(srcdir)/crt.h $(srcdir)/pc386uart.h $(srcdir)/pcibios.h
    1213
    1314#
  • c/src/lib/libbsp/i386/pc386/include/bsp.h

    r98100d2 r5d18fb0  
    134134| External Variables.
    135135+--------------------------------------------------------------------------*/
    136 extern i386_IDT_slot Interrupt_descriptor_table[256];
    137 extern i386_GDT_slot Global_descriptor_table   [8192];
     136extern i386_IDT_slot Interrupt_descriptor_table[];
     137extern i386_GDT_slot Global_descriptor_table   [];
    138138 
    139139extern rtems_configuration_table BSP_Configuration;
     
    150150rtems_boolean _IBMPC_chrdy    (char *);  /* from 'inch.c'   */
    151151char          _IBMPC_inch     (void);    /* from 'inch.c'   */
     152char          _IBMPC_inch_sleep (void);  /* from 'inch.c'   */
    152153
    153154void printk(char *fmt, ...);             /* from 'printk.c' */
    154155
    155156void rtemsReboot(void);                  /* from 'exit.c'   */
     157
     158/* Definitions for PC386ConsolePort */
     159#define PC386_CONSOLE_PORT_CONSOLE (-1)
     160#define PC386_CONSOLE_PORT_COM1    (PC386_UART_COM1)
     161#define PC386_CONSOLE_PORT_COM2    (PC386_UART_COM2)
     162
     163/* GDB stub stuff */
     164void i386_stub_glue_init(int uart);
     165void i386_stub_glue_init_breakin(void);
     166void set_debug_traps(void);
     167void breakpoint(void);
    156168
    157169#ifdef __cplusplus
     
    161173#endif /* __BSP_H_ */
    162174/* end of include file */
     175
     176
     177
     178
     179
     180
  • c/src/lib/libbsp/i386/pc386/start/start.s

    r98100d2 r5d18fb0  
    7171 * the following variable:
    7272 */
    73 #define DEBUG_EARLY_START
     73/* #define DEBUG_EARLY_START */
    7474
    7575SYM (start):
  • c/src/lib/libbsp/i386/pc386/startup/bspstart.c

    r98100d2 r5d18fb0  
    127127  rtemsFreeMemStart += BSP_Configuration.work_space_size;
    128128
     129  console_reserve_resources(&BSP_Configuration);
     130
    129131  /*
    130132   *  The following information is very useful when debugging.
  • c/src/lib/libbsp/i386/pc386/startup/exit.c

    r98100d2 r5d18fb0  
    3434
    3535#include <stdio.h>
     36#include <bsp.h>
     37#include <pc386uart.h>
    3638
    37 #include <bsp.h>
     39/*-------------------------------------------------------------------------+
     40 | Which console is in use: either (-1) which means normal console or
     41 | uart id if uart was used
     42 +-------------------------------------------------------------------------*/
     43extern int PC386ConsolePort;
    3844
    3945/*-------------------------------------------------------------------------+
     
    5157void _exit(int status)
    5258{
    53   unsigned char ch;
    54   puts("\nEXECUTIVE SHUTDOWN! Any key to reboot...");
     59  unsigned char ch, *cp;
     60  static   char line[]="EXECUTIVE SHUTDOWN! Any key to reboot...";
    5561
    56   while(!_IBMPC_scankey(&ch))
    57     ;
     62  if(PC386ConsolePort == PC386_CONSOLE_PORT_CONSOLE)
     63    {
     64
     65      printk("\n");
     66      printk(line);
     67      while(!_IBMPC_scankey(&ch))
     68        ;
     69      printk("\n\n");
     70    }
     71  else
     72    {
     73      PC386_uart_intr_ctrl(PC386ConsolePort, PC386_UART_INTR_CTRL_DISABLE);
     74     
     75      PC386_uart_polled_write(PC386ConsolePort, '\r');
     76      PC386_uart_polled_write(PC386ConsolePort, '\n');
     77     
     78      for(cp=line; *cp != 0; cp++)
     79        {
     80          PC386_uart_polled_write(PC386ConsolePort, *cp);
     81        }
     82
     83      PC386_uart_polled_read(PC386ConsolePort);
     84
     85      PC386_uart_polled_write(PC386ConsolePort, '\r');
     86      PC386_uart_polled_write(PC386ConsolePort, '\n');
     87      PC386_uart_polled_write(PC386ConsolePort, '\r');
     88      PC386_uart_polled_write(PC386ConsolePort, '\n');
     89    }
    5890
    5991  rtemsReboot();
    6092} /* _exit */
     93
     94
     95
     96
     97
     98
     99
  • c/src/lib/libbsp/i386/pc386/startup/ldsegs.s

    r98100d2 r5d18fb0  
    6767|      Description: Current environment is standard PC booted by grub.
    6868|                   So, there is no value in saving current GDT and IDT
    69 |                   Settings we have to set it up ourseves. (Naturally
     69|                   settings we have to set it up ourseves. (Naturally
    7070|                   it will be not so in case we are booted by some
    7171|                   boot monitor, however, then it will be different
    72 |                   BSP), After that we have to load board segment registers
     72|                   BSP). After that we have to load board segment registers
    7373|                   with apropriate values +  reprogram PIC.
    7474| Global Variables: None.
  • c/src/lib/libbsp/i386/pc386/tools/Makefile.in

    r98100d2 r5d18fb0  
    2323
    2424# C source names, if any, go here -- minus the .c
    25 C_PIECES=bin2boot Header Image
     25C_PIECES= bin2boot binpatch
    2626C_FILES=$(C_PIECES:%=%.c)
    2727C_O_FILES=$(C_PIECES:%=$(ARCH)/%.o)
     
    3131CC_O_FILES=$(CC_PIECES:%=$(ARCH)/%.o)
    3232
    33 H_FILES=bytetype.h Header.h Image.h
     33H_FILES=
    3434
    3535SRCS=$(C_FILES) $(CC_FILES) $(H_FILES)
    3636OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
    3737
    38 PGMS=$(ARCH)/bin2boot
     38PGMS=$(ARCH)/bin2boot $(ARCH)/binpatch
    3939
    4040include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
     
    6767        $(INSTALL) -m 555 $(PGMS) ${PROJECT_RELEASE}/build-tools
    6868
    69 $(ARCH)/bin2boot: $(OBJS)
    70         $(CC) $(LDFLAGS) $^ -o $@ $(LD_LIBS)
    71 $(ARCH)/bin2boot.o: bin2boot.c Header.h Image.h bytetype.h
    72 $(ARCH)/Header.o: Header.c Header.h bytetype.h
    73 $(ARCH)/Image.o: Image.c Image.h bytetype.h
     69$(ARCH)/bin2boot: $(srcdir)/bin2boot.c
     70        $(CC) $(LDFLAGS) -o $@ $(srcdir)/bin2boot.c $(LD_LIBS)
    7471
     72$(ARCH)/binpatch: $(srcdir)/binpatch.c
     73        $(CC) $(LDFLAGS) -o $@ $(srcdir)/binpatch.c $(LD_LIBS)
     74
     75
  • c/src/lib/libbsp/i386/pc386/tools/bin2boot.c

    r98100d2 r5d18fb0  
    1 /*-------------------------------------------------------------------------+
    2 | bin2boot.c v1.0 - PC386 BSP - 1998/04/09
    3 +--------------------------------------------------------------------------+
    4 | This file contains the i386 binary to boot image filter.
    5 +--------------------------------------------------------------------------+
    6 | (C) Copyright 1997 -
    7 | - NavIST Group - Real-Time Distributed Systems and Industrial Automation
    8 |
    9 | http://pandora.ist.utl.pt
    10 |
    11 | Instituto Superior Tecnico * Lisboa * PORTUGAL
    12 +--------------------------------------------------------------------------+
    13 | Disclaimer:
    14 |
    15 | This file is provided "AS IS" without warranty of any kind, either
    16 | expressed or implied.
    17 +--------------------------------------------------------------------------*/
    18  
    19 #include "Image.h"
    20 #include "Header.h"
    21 #include "bytetype.h"
     1
     2/*
     3 * Simplyfied version of original bin2boot
     4 */
    225
    236#include <stdio.h>
    247#include <stdlib.h>
    25 
    26 /*-------------------------------------------------------------------------+
    27 | Constants
    28 +--------------------------------------------------------------------------*/
    29 
    30 #define MAX_IMAGES 15
    31 
    32 /*-------------------------------------------------------------------------+
    33 | Global Variables
    34 +--------------------------------------------------------------------------*/
    35 
    36 // Help message for users
    37 const char UsageMsg[] = "\
    38 Usage: bin2boot <outFile> <locAddr> <inFile1> <startAddr1> <memSize1> \\\n\
    39                [<infile2> <startAddr2> <memSize2>][...][-v][-h][-?]\n\
    40 \n\
    41 <outFile>    : output file name (mandatory)\n\
    42 <locAddr>    : location address in memory of image header (mandatory)\n\
    43 <inFileX>    : name of Xth input file\n\
    44 <startAddrX> : start address of Xth image\n\
    45 <memSizeX>   : actual size (for compressed images), use 0 if uncompressed\n\
    46 -v           : verbose output\n\
    47 -h, -?       : this help message\n\
    48 \n\
    49 At least one set of <inFile> <startAddr> and <memSize> is mandatory!\n\
    50 <locAddr>, <startAddrX> and <memSizeX> can be in Decimal, Hexadecimal or Octal.\n\
    51 The maximum number of input files is 15.\n";
    52 
    53 /*-------------------------------------------------------------------------+
    54 | External Prototypes (for use with getopt)
    55 +--------------------------------------------------------------------------*/
    56 
    57 extern char *optarg;
    58 
    59 int getopt(int, char *const[], const char *);
    60 
    61 /*-------------------------------------------------------------------------+
    62 | Auxiliary Functions
    63 +--------------------------------------------------------------------------*/
    64 
    65 static DWord
    66 getNumArg(char *arg)
     8#include <unistd.h>
     9#include <memory.h>
     10
     11
     12static unsigned char buf[512];
     13
     14static void usage(void)
    6715{
    68   char *dummy;
    69 
    70   if (arg[0] == '0') {
    71     if ((arg[1] == 'x') || (arg[1] == 'X'))  /* Hexadecimal */
    72       return (DWord)strtol(arg, &dummy, 16);
    73     else  /* Octal */
    74       return (DWord)strtol(arg, &dummy, 8);
    75   } else  /* Decimal */
    76       return (DWord)strtol(arg, &dummy, 10);
    77 } /* getNumArg */
    78 
    79 /*-------------------------------------------------------------------------+
    80 | Main
    81 +--------------------------------------------------------------------------*/
     16  printf("usage: bin2boot [-h][-v] <outFile> <headerAddr> \n");
     17  printf("<imFile1> <imAddr1> <imSize1> [<imFile2> <imAddr2> <imSize2>]\n");
     18  printf("this function makes image bootable by netboot\n");
     19  printf("from one or two binary images\n");
     20  printf("-h         - prints this message\n");
     21  printf("-v         - verbose output\n");
     22  printf("outFile    - output file\n");
     23  printf("headerAddr - address to place header in memory\n");
     24  printf("             it should be below or equal 0x97e00\n");
     25  printf("imFile1    - first image\n");
     26  printf("imAddr1    - its start address, image has to be placed whole\n");
     27  printf("             below 0x98000 and should not overlap with header\n");
     28  printf("imSize1    - actual size of compressed image, 0 for uncompressed\n");
     29  printf("imFile2    - second image\n");
     30  printf("imAddr2    - its start address\n");
     31  printf("imSize2    - actual size of compressed image, 0 for uncompressed\n");
     32
     33  return;
     34}
     35
    8236
    8337int main(int argc, char* argv[])
    8438{
    85   Image    img[MAX_IMAGES]; /* array to store up to MAX_IMAGE images */
    86   Header   hdr;             /* boot image file header                */
    87   FILE*    outFile;         /* boot image file stream                */
    88   char*    outFileName;     /* name of boot image file               */
    89 
    90   int  argPos = 1, numImages, i;
    91   int  verboseFlag = 0, helpFlag = 0; /* flags for command line options */
    92 
    93   /*-------------------------------------------------------------------------+
    94   | Parse command line arguments and options
    95   +-------------------------------------------------------------------------*/
    96  
    97   {
    98     char opt;
    99 
    100     /* parse command line options */
    101     while ((opt = getopt(argc, argv, "vh?")) >= 0)
    102     {
    103       argPos++;
    104       switch (opt)
    105       {
    106         case 'v' : verboseFlag = 1; break;
    107         case 'h' : case '?' : helpFlag = 1; break;
    108       }
    109     }
    110   }
    111 
    112   if (helpFlag)
    113   {
    114     fprintf(stderr, "%s\n", UsageMsg);
    115     if (argc == 2)
    116       exit(0);
    117   }
    118 
    119   numImages = (argc - argPos - 2) / 3;
    120  
    121   if (numImages < 1)
    122   {
    123     fprintf(stderr,
    124            "ERROR!!! Not enough command line arguments.\n\n%s\n",
    125            UsageMsg);
    126     exit(1);
    127   }
    128   if (numImages > 15)
    129   {
    130     fprintf(stderr, "ERROR!!! Too many input files.\n\n%s\n", UsageMsg);
    131     exit(1);
    132   }
    133 
    134   newHeader(&hdr); /* initialize hdr */
    135 
    136   argPos = 1;
    137 
    138   while (argv[argPos][0] == '-') argPos++; /* discard options */
    139   if(!(outFile = fopen((outFileName = argv[argPos++]), "w")))
    140   {
    141     fprintf(stderr,
    142             "ERROR!!! While opening file '%s' for output.\n",
    143             outFileName);
    144     exit(1);
    145   }
    146   reserveSpaceHeader(outFile);
    147 
    148   while (argv[argPos][0] == '-') argPos++; /* discard options */
    149   setLocAddrHeader(&hdr, getNumArg(argv[argPos++]));
    150 
    151   /*-------------------------------------------------------------------------+
    152   | Parse command line arguments concerning images
    153   +-------------------------------------------------------------------------*/
    154 
    155   for(i = 0; i < numImages; i++)
    156   {
    157     newImage(&img[i]);
    158     while (argv[argPos][0] == '-') argPos++; /* discard options */
    159     setImageFile(&img[i], argv[argPos++]);
    160     while (argv[argPos][0] == '-') argPos++; /* discard options */
    161     setLoadAddrImage(&img[i], getNumArg(argv[argPos++]));
    162     while (argv[argPos][0] == '-') argPos++; /* discard options */
    163     setMemSizeImage(&img[i], getNumArg(argv[argPos++]));
    164   }
    165 
    166   setLstImgFlagImage(&img[numImages - 1]);        /* set flag on last image */
    167   setExecAddrHeader(&hdr, getLoadAddrImage(&img[0]));
    168                 /* boot file execution address is the same as first image's */
    169   if (verboseFlag)
    170   {
    171     fprintf(stderr, "BootImage file '%s' info:\n\n", outFileName);
    172     fprintHeader(stderr, &hdr);
    173     fprintf(stderr, "\n");
    174   }
    175 
    176   /*-------------------------------------------------------------------------+
    177   | Dump images and header to file
    178   +-------------------------------------------------------------------------*/
    179 
    180   for(i = 0; i < numImages; i++)
    181   {
    182     addImageToHeader(&hdr, &img[i]);
    183     dumpImageToFileAndPad(outFile, &img[i]);
    184 
    185     if (verboseFlag)
    186       fprintImage(stderr, &img[i]);
    187 
    188     /* kill image. we don't need anymore and should free its resources */
    189     killImage(&img[i]);
    190   }
    191 
    192   dumpHeaderToFile(outFile, &hdr);
    193 
    194   fclose(outFile);
    195 
    196   exit(0);
    197 } /* main */
    198 
     39  int      c, verbose;
     40  extern   int optind;
     41  FILE     *ofp, *ifp;
     42  unsigned long headerAddr, addr1, addr2;
     43  int      size1, size2, len1, len2, len, imageCnt, cnt;
     44  char     *ofile, *ifile, *end;
     45 
     46  verbose = 0;
     47
     48  /* parse command line options */
     49  while ((c = getopt(argc, argv, "hv")) >= 0)
     50    {
     51      switch (c)
     52        {
     53        case 'v':
     54          verbose = 1;
     55          break;
     56        case 'h':
     57          usage();
     58          return 0;
     59        default:
     60          usage();
     61          return 1;
     62        }
     63    }
     64 
     65  if((argc - optind) != 8 && (argc - optind) != 5)
     66    {
     67      usage();
     68      return 1;
     69    }
     70 
     71  ofile = argv[optind];
     72  ofp   = fopen(ofile, "w");
     73  if(ofp == NULL)
     74    {
     75      fprintf(stderr, "unable to open file %s\n", ofile);
     76      return 1;
     77    }
     78 
     79  /*
     80   * Layout is very simple first 512 is header shared by all
     81   * images, then images at 512 bytes border
     82   */
     83 
     84  /* Fill buffer with 0's */
     85  memset(buf, 0, sizeof(buf));
     86 
     87  fwrite(buf, 1, sizeof(buf), ofp);
     88
     89  optind++;
     90  headerAddr = strtoul(argv[optind], &end, 0);
     91  if(end == argv[optind])
     92    {
     93      fprintf(stderr, "bad headerAddr %s\n", argv[optind]);
     94      fclose(ofp);
     95      return 1;
     96    }
     97
     98  if(headerAddr > 0x97e00)
     99    {
     100      fprintf(stderr, "headerAddr is too high 0x%08lx\n", headerAddr);
     101      fclose(ofp);
     102      return 1;
     103    }
     104 
     105  /* Copy the first image */
     106  optind++;
     107  ifile = argv[optind];
     108  ifp   = fopen(ifile,"r");
     109  if(ifp == NULL)
     110    {
     111      fprintf(stderr, "unable to open output file %s\n", ifile);
     112      fclose(ofp);
     113      return 1;
     114    }
     115
     116  optind++;
     117  addr1 = strtoul(argv[optind], &end, 0);
     118  if(end == argv[optind])
     119    {
     120      fprintf(stderr, "bad image address %s\n", argv[optind]);
     121      fclose(ofp);
     122      return 1;
     123    }
     124
     125  optind++;
     126  size1 = strtoul(argv[optind], &end, 0);
     127  if(end == argv[optind])
     128    {
     129      fprintf(stderr, "bad image size %s\n", argv[optind]);
     130      fclose(ofp);
     131      return 1;
     132    }
     133
     134
     135  /* Copy first image out and remember its length */
     136  cnt  = 0;
     137  for(;;)
     138    {
     139      len = fread(buf, 1, sizeof(buf), ifp);
     140
     141      if(len != 0)
     142        {
     143          fwrite(buf, 1, len, ofp);
     144          cnt += sizeof(buf);
     145
     146          if(len != sizeof(buf))
     147            {
     148              memset(buf, 0, sizeof(buf) - len);
     149              fwrite(buf, 1, sizeof(buf) - len, ofp);
     150              break;
     151            }
     152
     153        }
     154      else
     155        {
     156          break;
     157        }
     158    }
     159
     160  fclose(ifp);
     161
     162  len1 = cnt;
     163
     164  if(size1 == 0)
     165    {
     166      size1 = cnt;
     167    }
     168  else
     169    {
     170      memset(buf, 0, sizeof(buf));
     171
     172      while(cnt < size1)
     173        {
     174          fwrite(buf, 1, sizeof(buf), ofp);
     175          cnt += sizeof(buf);
     176        }
     177
     178      size1 = cnt;
     179    }
     180
     181
     182  /* Let us check agains overlapping */
     183  if(!(addr1 >= (headerAddr + sizeof(buf)) || (headerAddr >= addr1+size1)))
     184    {
     185      /* Areas overlapped */
     186      printf("area overlapping: \n");
     187      printf("header address      0x%08lx, its memory size 0x%08x\n",
     188             headerAddr, sizeof(buf));
     189      printf("first image address 0x%08lx, its memory size 0x%08x\n",
     190             addr1, size1);
     191
     192      fclose(ofp);
     193      return 1;
     194    }
     195
     196  if((addr1 + size1) > 0x98000)
     197    {
     198      fprintf(stderr, "imAddr1 is too high 0x%08lx\n", addr1);
     199      fclose(ofp);
     200      return 1;
     201    }
     202     
     203
     204  if(optind == (argc - 1))
     205    {
     206      imageCnt = 1;
     207      goto writeHeader;
     208    }
     209
     210  imageCnt = 2;
     211
     212  /* Copy Second Image */
     213  optind++;
     214  ifile = argv[optind];
     215  ifp   = fopen(ifile,"r");
     216  if(ifp == NULL)
     217    {
     218      fprintf(stderr, "unable to open output file %s\n", ifile);
     219      fclose(ofp);
     220      return 1;
     221    }
     222
     223  optind++;
     224  addr2 = strtoul(argv[optind], &end, 0);
     225  if(end == argv[optind])
     226    {
     227      fprintf(stderr, "bad image address %s\n", argv[optind]);
     228      fclose(ofp);
     229      return 1;
     230    }
     231
     232  optind++;
     233  size2 = strtoul(argv[optind], &end, 0);
     234  if(end == argv[optind])
     235    {
     236      fprintf(stderr, "bad image size %s\n", argv[optind]);
     237      fclose(ofp);
     238      return 1;
     239    }
     240
     241  /* Copy second image out and remember its length */
     242  cnt  = 0;
     243  for(;;)
     244    {
     245      len = fread(buf, 1, sizeof(buf), ifp);
     246     
     247      if(len != 0)
     248        {
     249          fwrite(buf, len, 1, ofp);
     250          cnt  += sizeof(buf);
     251         
     252          if(len != sizeof(buf))
     253            {
     254              memset(buf, 0, sizeof(buf) - len);
     255              fwrite(buf, 1, sizeof(buf) - len, ofp);
     256              break;
     257            }
     258        }
     259      else
     260        {
     261          break;
     262        }
     263    }
     264
     265  fclose(ifp);
     266
     267  len2 = cnt;
     268
     269  if(size2 == 0)
     270    {
     271      size2 = cnt;
     272    }
     273  else
     274    {
     275      memset(buf, 0, sizeof(buf));
     276
     277      while(cnt < size2)
     278        {
     279          fwrite(buf, 1, sizeof(buf), ofp);
     280          cnt += sizeof(buf);
     281        }
     282
     283      size2 = cnt;
     284    }
     285
     286  /* Let us check against overlapping */
     287  if(!((addr2 >= (addr1 + size1) && addr2 >= (headerAddr + sizeof(buf))) ||
     288       (addr2 < addr1 && addr2 < headerAddr) ||
     289       (addr1 > headerAddr && addr2 > (headerAddr + sizeof(buf)) &&
     290        (addr2 + size2) <= addr1) ||
     291       (addr1 < headerAddr && addr2 > (addr1 + size1) &&
     292        (addr2 + size2) <= headerAddr)))
     293     
     294    {
     295      /* Areas overlapped */
     296      printf("area overlapping: \n");
     297      printf("header address       0x%08lx, its memory size 0x%08x\n",
     298             headerAddr, sizeof(buf));
     299      printf("first  image address 0x%08lx, its memory size 0x%08x\n",
     300             addr1, size1);
     301      printf("second image address 0x%08lx, its memory size 0x%08x\n",
     302             addr2, size2);
     303
     304      fclose(ofp);
     305      return 1;
     306    }
     307
     308writeHeader:
     309
     310  /* We know everything so it is time to write buffer */
     311  memset(buf, 0, 0x30);
     312
     313  buf[0x0]  = 0x36;
     314  buf[0x1]  = 0x13;
     315  buf[0x2]  = 0x03;
     316  buf[0x3]  = 0x1b;
     317
     318  buf[0x4]  = 4;
     319
     320  /* Header address in ds:bx format */
     321  buf[0x8]  = headerAddr & 0xf;
     322  buf[0x9]  = 0;
     323  buf[0xa]  = (headerAddr >> 4) & 0xff;
     324  buf[0xb]  = (headerAddr >> 12) & 0xff;
     325
     326  /*
     327   * Execute address in cs:ip format, which addr1
     328   */
     329  buf[0xc] = addr1 & 0xf;
     330  buf[0xd] = 0;
     331  buf[0xe] = (addr1 >> 4) & 0xff;
     332  buf[0xf] = (addr1 >> 12) & 0xff;
     333
     334  /* Flags, tags and lengths */
     335  buf[0x10] = 4;
     336
     337  if(imageCnt == 1)
     338    {
     339      buf[0x13] = 4;
     340    }
     341
     342  /* Load address */
     343  buf[0x14] = addr1 & 0xff;
     344  buf[0x15] = (addr1 >> 8) & 0xff;
     345  buf[0x16] = (addr1 >> 16) & 0xff;
     346  buf[0x17] = (addr1 >> 24) & 0xff;
     347
     348  /* Image Length */
     349  buf[0x18] = len1 & 0xff;
     350  buf[0x19] = (len1 >> 8) & 0xff;
     351  buf[0x1a] = (len1 >> 16) & 0xff;
     352  buf[0x1b] = (len1 >> 24) & 0xff;
     353
     354  /* Memory Size */
     355  buf[0x1c] = size1 & 0xff;
     356  buf[0x1d] = (size1 >> 8) & 0xff;
     357  buf[0x1e] = (size1 >> 16) & 0xff;
     358  buf[0x1f] = (size1 >> 24) & 0xff;
     359
     360  if(imageCnt != 1)
     361    {
     362
     363      /* Flags, tags and lengths */
     364      buf[0x20] = 4;
     365     
     366      buf[0x23] = 4;
     367
     368
     369      /* Load address */
     370      buf[0x24] = addr2 & 0xff;
     371      buf[0x25] = (addr2 >> 8) & 0xff;
     372      buf[0x26] = (addr2 >> 16) & 0xff;
     373      buf[0x27] = (addr2 >> 24) & 0xff;
     374     
     375      /* Image Length */
     376      buf[0x28] = len2 & 0xff;
     377      buf[0x29] = (len2 >> 8) & 0xff;
     378      buf[0x2a] = (len2 >> 16) & 0xff;
     379      buf[0x2b] = (len2 >> 24) & 0xff;
     380     
     381      /* Memory Size */
     382      buf[0x2c] = size2 & 0xff;
     383      buf[0x2d] = (size2 >> 8) & 0xff;
     384      buf[0x2e] = (size2 >> 16) & 0xff;
     385      buf[0x2f] = (size2 >> 24) & 0xff;
     386    }
     387
     388  rewind(ofp);
     389
     390  fwrite(buf, 1, 0x30, ofp);
     391
     392  fclose(ofp);
     393
     394  if(verbose)
     395    {
     396      printf("header address       0x%08lx, its memory size 0x%08x\n",
     397             headerAddr, sizeof(buf));
     398      printf("first  image address 0x%08lx, its memory size 0x%08x\n",
     399             addr1, size1);
     400      printf("second image address 0x%08lx, its memory size 0x%08x\n",
     401             addr2, size2);
     402    }
     403
     404  return 0;
     405}
     406
     407
     408
     409
     410
     411
     412
     413
     414
  • c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in

    r98100d2 r5d18fb0  
    99PROJECT_ROOT = @PROJECT_ROOT@
    1010
    11 BSP_PIECES=startup clock console timer
     11BSP_PIECES=startup clock console timer pc386dev
    1212GENERIC_PIECES=
    1313
  • make/custom/pc386.cfg

    r98100d2 r5d18fb0  
    103103        $(SIZE) $(basename $@).obj
    104104        $(INSTALL_VARIANT) -m 555 $(basename $@).bt ${PROJECT_RELEASE}/BootImgs
     105        $(CC) $(CFLAGS) $(CFLAGS_LD) -Wl,-Ttext,$(RELOCADDR) \
     106            -o $(basename $@).coff $(LINK_OBJS) $(LINK_LIBS)
    105107endef
    106108endif
     
    108110# Miscellaneous additions go here
    109111
     112
     113
Note: See TracChangeset for help on using the changeset viewer.