summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i386/pc386
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-06-27 18:51:49 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-06-27 18:51:49 +0000
commit5d18fb057a9158336a79953b88d481c74c6eb0ae (patch)
tree5762f11ed095f1236aa83bf386637423afb7638c /c/src/lib/libbsp/i386/pc386
parentMonstrous patch from Ralf Corsepius <corsepiu@faw.uni-ulm.de>. I have (diff)
downloadrtems-5d18fb057a9158336a79953b88d481c74c6eb0ae.tar.bz2
PC386 BSP enhancements from Aleksey Romanov (Quality Quorum
<qqi@world.std.com>). 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
Diffstat (limited to 'c/src/lib/libbsp/i386/pc386')
-rw-r--r--c/src/lib/libbsp/i386/pc386/Makefile.in2
-rw-r--r--c/src/lib/libbsp/i386/pc386/bsp_specs2
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/console.c346
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/inch.c44
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/outch.c14
-rw-r--r--c/src/lib/libbsp/i386/pc386/include/Makefile.in3
-rw-r--r--c/src/lib/libbsp/i386/pc386/include/bsp.h22
-rw-r--r--c/src/lib/libbsp/i386/pc386/start/start.s2
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/bspstart.c2
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/exit.c49
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/ldsegs.s4
-rw-r--r--c/src/lib/libbsp/i386/pc386/tools/Makefile.in17
-rw-r--r--c/src/lib/libbsp/i386/pc386/tools/bin2boot.c586
-rw-r--r--c/src/lib/libbsp/i386/pc386/tools/binpatch.c168
-rw-r--r--c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in2
15 files changed, 950 insertions, 313 deletions
diff --git a/c/src/lib/libbsp/i386/pc386/Makefile.in b/c/src/lib/libbsp/i386/pc386/Makefile.in
index 9e5e08f345..763c759d26 100644
--- a/c/src/lib/libbsp/i386/pc386/Makefile.in
+++ b/c/src/lib/libbsp/i386/pc386/Makefile.in
@@ -13,4 +13,4 @@ include $(RTEMS_ROOT)/make/directory.cfg
# wrapup is the one that actually builds and installs the library
# from the individual .rel files built in other directories
-SUB_DIRS=include tools start startup clock console timer wrapup
+SUB_DIRS=include tools start startup clock console timer pc386dev wrapup
diff --git a/c/src/lib/libbsp/i386/pc386/bsp_specs b/c/src/lib/libbsp/i386/pc386/bsp_specs
index f131fa1d9c..61dac86b53 100644
--- a/c/src/lib/libbsp/i386/pc386/bsp_specs
+++ b/c/src/lib/libbsp/i386/pc386/bsp_specs
@@ -19,5 +19,5 @@
%{qrtems_debug: start_g.o%s}}
*link:
-%{!qrtems: %(old_link)} %{qrtems: -dc -dp -N -e start --oformat=elf32-i386}
+%{!qrtems: %(old_link)} %{qrtems: -dc -dp -N -e start}
diff --git a/c/src/lib/libbsp/i386/pc386/console/console.c b/c/src/lib/libbsp/i386/pc386/console/console.c
index 1689f5c546..8698ea8136 100644
--- a/c/src/lib/libbsp/i386/pc386/console/console.c
+++ b/c/src/lib/libbsp/i386/pc386/console/console.c
@@ -33,10 +33,17 @@
#include <stdlib.h>
+#include <assert.h>
#include <bsp.h>
#include <irq.h>
#include <rtems/libio.h>
+#include <termios.h>
+#include <pc386uart.h>
+
+int PC386ConsolePort = PC386_CONSOLE_PORT_CONSOLE;
+
+static int conSetAttr(int minor, const struct termios *);
/*-------------------------------------------------------------------------+
| Constants
@@ -51,74 +58,25 @@ extern rtems_isr _IBMPC_keyboard_isr(rtems_vector_number);
/* keyboard (IRQ 0x01) Interrupt Service Routine (defined in 'inch.c') */
-/*-------------------------------------------------------------------------+
-| Functions
-+--------------------------------------------------------------------------*/
-/*-------------------------------------------------------------------------+
-| Function: console_cleanup
-| Description: This routine is called at exit to clean up the console
-| hardware.
-| Global Variables: None.
-| Arguments: None.
-| Returns: Nothing.
-+--------------------------------------------------------------------------*/
-void
-console_cleanup(void)
+void console_reserve_resources(rtems_configuration_table *conf)
{
- /* nothing */
-} /* console_cleanup */
-
-
-/*-------------------------------------------------------------------------+
-| Function: is_character_ready
-| Description: Check if a character is available for input, and if so
-| return it.
-| Global Variables: None.
-| Arguments: c - character read if available, otherwise unchanged.
-| Returns: TRUE if there was a character available for input,
-| FALSE otherwise.
-+--------------------------------------------------------------------------*/
-rtems_boolean
-is_character_ready(char *c)
-{
- return (_IBMPC_chrdy(c) ? TRUE : FALSE);
-} /* is_character_ready */
-
+ if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
+ {
+ rtems_termios_reserve_resources(conf, 1);
+ }
+ return;
+}
-/*-------------------------------------------------------------------------+
-| Function: inbyte
-| Description: Read a character from the console (keyboard).
-| Global Variables: None.
-| Arguments: None.
-| Returns: Caracter read from the console.
-+--------------------------------------------------------------------------*/
-unsigned char
-inbyte(void)
+void __assert(const char *file, int line, const char *msg)
{
- char c = _IBMPC_inch();
-
- /* Echo character to screen */
- _IBMPC_outch(c);
- if (c == '\r')
- _IBMPC_outch('\n'); /* CR = CR + LF */
+ printk("assert failed: %s: ", file);
+ printk("%d: ", line);
+ printk("%s\n", msg);
- return c;
-} /* inbyte */
-
-
-/*-------------------------------------------------------------------------+
-| Function: outbyte
-| Description: Write a character to the console (display).
-| Global Variables: None.
-| Arguments: Character to be written.
-| Returns: Nothing.
-+--------------------------------------------------------------------------*/
-void
-outbyte(char c)
-{
- _IBMPC_outch(c);
-} /* outbyte */
+ exit(1);
+ return;
+}
/*-------------------------------------------------------------------------+
| Console device driver INITIALIZE entry point.
@@ -135,26 +93,74 @@ console_initialize(rtems_device_major_number major,
/* Initialize video */
_IBMPC_initVideo();
- /* Install keyboard interrupt handler */
- status = PC386_installRtemsIrqHandler(KEYBOARD_IRQ, _IBMPC_keyboard_isr);
-
- if (status != RTEMS_SUCCESSFUL)
- {
- printk("Error installing keyboard interrupt handler!\n");
- rtems_fatal_error_occurred(status);
- }
+ if(PC386ConsolePort == PC386_CONSOLE_PORT_CONSOLE)
+ {
- status =
- rtems_io_register_name("/dev/console", major, (rtems_device_minor_number)0);
-
- if (status != RTEMS_SUCCESSFUL)
- {
- printk("Error registering console device!\n");
- rtems_fatal_error_occurred(status);
- }
+ /* Install keyboard interrupt handler */
+ status = PC386_installRtemsIrqHandler(KEYBOARD_IRQ, _IBMPC_keyboard_isr);
+
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ printk("Error installing keyboard interrupt handler!\n");
+ rtems_fatal_error_occurred(status);
+ }
+
+ status = rtems_io_register_name("/dev/console", major, 0);
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ printk("Error registering console device!\n");
+ rtems_fatal_error_occurred(status);
+ }
+ printk("Initialized console on port CONSOLE\n\n");
+ }
+ else
+ {
+ /*
+ * Set up TERMIOS
+ */
+ rtems_termios_initialize ();
+
+ /*
+ * Do device-specific initialization
+ */
+
+ /* 9600-8-N-1 */
+ PC386_uart_init(PC386ConsolePort, 9600, 0);
+
+
+ /* Set interrupt handler */
+ if(PC386ConsolePort == PC386_UART_COM1)
+ {
+ status = PC386_installRtemsIrqHandler(PC386_UART_COM1_IRQ,
+ PC386_uart_termios_isr_com1);
+ }
+ else
+ {
+ assert(PC386ConsolePort == PC386_UART_COM2);
+
+ status = PC386_installRtemsIrqHandler(PC386_UART_COM2_IRQ,
+ PC386_uart_termios_isr_com2);
+ }
+ /*
+ * Register the device
+ */
+ status = rtems_io_register_name ("/dev/console", major, 0);
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ printk("Error registering console device!\n");
+ rtems_fatal_error_occurred (status);
+ }
+
+ if(PC386ConsolePort == PC386_UART_COM1)
+ {
+ printk("Initialized console on port COM1 9600-8-N-1\n\n");
+ }
+ else
+ {
+ printk("Initialized console on port COM2 9600-8-N-1\n\n");
+ }
+ }
- atexit(console_cleanup);
-
return RTEMS_SUCCESSFUL;
} /* console_initialize */
@@ -164,12 +170,51 @@ console_initialize(rtems_device_major_number major,
+--------------------------------------------------------------------------*/
rtems_device_driver
console_open(rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg)
+ rtems_device_minor_number minor,
+ void *arg)
{
- return RTEMS_SUCCESSFUL;
-} /* console_open */
+ rtems_status_code status;
+ static rtems_termios_callbacks cb =
+ {
+ NULL, /* firstOpen */
+ NULL, /* lastClose */
+ NULL, /* pollRead */
+ PC386_uart_termios_write_com1, /* write */
+ conSetAttr, /* setAttributes */
+ NULL, /* stopRemoteTx */
+ NULL, /* startRemoteTx */
+ 1 /* outputUsesInterrupts */
+ };
+
+ if(PC386ConsolePort == PC386_CONSOLE_PORT_CONSOLE)
+ {
+ return RTEMS_SUCCESSFUL;
+ }
+ if(PC386ConsolePort == PC386_UART_COM2)
+ {
+ cb.write = PC386_uart_termios_write_com2;
+ }
+
+ status = rtems_termios_open (major, minor, arg, &cb);
+
+ if(status != RTEMS_SUCCESSFUL)
+ {
+ printk("Error openning console device\n");
+ return status;
+ }
+
+ /*
+ * Pass data area info down to driver
+ */
+ PC386_uart_termios_set(PC386ConsolePort,
+ ((rtems_libio_open_close_args_t *)arg)->iop->data1);
+
+ /* Enable interrupts on channel */
+ PC386_uart_intr_ctrl(PC386ConsolePort, PC386_UART_INTR_CTRL_TERMIOS);
+
+ return RTEMS_SUCCESSFUL;
+}
/*-------------------------------------------------------------------------+
| Console device driver CLOSE entry point
@@ -179,6 +224,11 @@ console_close(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
+ if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
+ {
+ return rtems_termios_close (arg);
+ }
+
return RTEMS_SUCCESSFUL;
} /* console_close */
@@ -196,10 +246,24 @@ console_read(rtems_device_major_number major,
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
char *buffer = rw_args->buffer;
int count, maximum = rw_args->count;
+
+ if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
+ {
+ return rtems_termios_read (arg);
+ }
for (count = 0; count < maximum; count++)
{
- buffer[count] = inbyte();
+ /* Get character */
+ buffer[count] = _IBMPC_inch_sleep();
+
+ /* Echo character to screen */
+ _IBMPC_outch(buffer[count]);
+ if (buffer[count] == '\r')
+ {
+ _IBMPC_outch('\n'); /* CR = CR + LF */
+ }
+
if (buffer[count] == '\n' || buffer[count] == '\r')
{
/* What if this goes past the end of the buffer? We're hosed. [bhc] */
@@ -227,12 +291,17 @@ console_write(rtems_device_major_number major,
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
char *buffer = rw_args->buffer;
int count, maximum = rw_args->count;
+
+ if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
+ {
+ return rtems_termios_write (arg);
+ }
for (count = 0; count < maximum; count++)
{
- outbyte(buffer[count]);
+ _IBMPC_outch(buffer[count]);
if (buffer[count] == '\n')
- outbyte('\r'); /* LF = LF + CR */
+ _IBMPC_outch('\r'); /* LF = LF + CR */
}
rw_args->bytes_moved = maximum;
@@ -240,13 +309,98 @@ console_write(rtems_device_major_number major,
} /* console_write */
-/*-------------------------------------------------------------------------+
-| Console device driver CONTROL entry point
-+--------------------------------------------------------------------------*/
-rtems_device_driver
+
+/*
+ * Handle ioctl request.
+ */
+rtems_device_driver
console_control(rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg)
-{
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
+ {
+ return rtems_termios_ioctl (arg);
+ }
+
return RTEMS_SUCCESSFUL;
-} /* console_control */
+}
+
+static int
+conSetAttr(int minor, const struct termios *t)
+{
+ int baud;
+
+ switch (t->c_cflag & CBAUD)
+ {
+ case B50:
+ baud = 50;
+ break;
+ case B75:
+ baud = 75;
+ break;
+ case B110:
+ baud = 110;
+ break;
+ case B134:
+ baud = 134;
+ break;
+ case B150:
+ baud = 150;
+ break;
+ case B200:
+ baud = 200;
+ break;
+ case B300:
+ baud = 300;
+ break;
+ case B600:
+ baud = 600;
+ break;
+ case B1200:
+ baud = 1200;
+ break;
+ case B1800:
+ baud = 1800;
+ break;
+ case B2400:
+ baud = 2400;
+ break;
+ case B4800:
+ baud = 4800;
+ break;
+ case B9600:
+ baud = 9600;
+ break;
+ case B19200:
+ baud = 19200;
+ break;
+ case B38400:
+ baud = 38400;
+ break;
+ case B57600:
+ baud = 57600;
+ break;
+ case B115200:
+ baud = 115200;
+ break;
+ default:
+ baud = 0;
+ rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
+ return 0;
+ }
+
+ PC386_uart_set_baud(PC386ConsolePort, baud);
+
+ return 0;
+}
+
+
+
+
+
+
+
+
+
diff --git a/c/src/lib/libbsp/i386/pc386/console/inch.c b/c/src/lib/libbsp/i386/pc386/console/inch.c
index bcb9a17312..f29f6124c8 100644
--- a/c/src/lib/libbsp/i386/pc386/console/inch.c
+++ b/c/src/lib/libbsp/i386/pc386/console/inch.c
@@ -70,6 +70,7 @@ static char shift_map[] =
static char kbd_buffer[KBD_BUF_SIZE];
static rtems_unsigned16 kbd_first = 0;
static rtems_unsigned16 kbd_last = 0;
+static rtems_unsigned16 kbd_end = KBD_BUF_SIZE - 1;
/*-------------------------------------------------------------------------+
| Function: rtemsReboot
@@ -81,7 +82,7 @@ static rtems_unsigned16 kbd_last = 0;
void rtemsReboot(void)
{
/* shutdown and reboot */
- outport_byte(0x64, 0xFE); /* use keyboard controler to do the job... */
+ outport_byte(0x64, 0xFE); /* use keyboard controler to do the job... */
} /* rtemsReboot */
/*-------------------------------------------------------------------------+
@@ -223,10 +224,12 @@ _IBMPC_keyboard_isr(rtems_vector_number vector)
if (_IBMPC_scankey(&kbd_buffer[kbd_last]))
{
/* Got one; save it if there is enough room in buffer. */
- unsigned int next = (kbd_last + 1) % KBD_BUF_SIZE;
+ unsigned int next = (kbd_last == kbd_end) ? 0 : kbd_last + 1;
if (next != kbd_first)
- kbd_last = next;
+ {
+ kbd_last = next;
+ }
}
PC386_ackIrq(vector - PC386_IRQ_VECTOR_BASE); /* Mark interrupt as handled. */
@@ -277,3 +280,38 @@ _IBMPC_inch(void)
return c;
} /* _IBMPC_inch */
+
+/*-------------------------------------------------------------------------+
+| Function: _IBMPC_inch_sleep
+| Description: If charcter is ready return it, otherwise sleep until
+| it is ready
+| Global Variables: None.
+| Arguments: None.
+| Returns: character read from keyboard.
++--------------------------------------------------------------------------*/
+char
+_IBMPC_inch_sleep(void)
+{
+ char c;
+ extern rtems_interval _TOD_Ticks_per_second; /* XXX should not do this */
+ rtems_interval ticks_to_delay;
+
+ ticks_to_delay = (_TOD_Ticks_per_second + 24) / 25;
+
+ for(;;)
+ {
+ if(_IBMPC_chrdy(&c))
+ {
+ return c;
+ }
+ rtems_task_wake_after(ticks_to_delay);
+ }
+
+ return c;
+} /* _IBMPC_inch */
+
+
+
+
+
+
diff --git a/c/src/lib/libbsp/i386/pc386/console/outch.c b/c/src/lib/libbsp/i386/pc386/console/outch.c
index e4c45c2166..1d5c1f9c38 100644
--- a/c/src/lib/libbsp/i386/pc386/console/outch.c
+++ b/c/src/lib/libbsp/i386/pc386/console/outch.c
@@ -33,8 +33,8 @@ static unsigned char column;
static unsigned short attribute;
static unsigned int nLines;
- static void
-scroll()
+static void
+scroll(void)
{
int i, j; /* Counters */
unsigned short *pt_scroll, *pt_bitmap; /* Pointers on the bit-map */
@@ -55,8 +55,8 @@ scroll()
}
}
- static void
-endColumn()
+static void
+endColumn(void)
{
if (++row == maxRow) {
scroll(); /* Scroll the screen now */
@@ -70,7 +70,7 @@ endColumn()
- static void
+static void
videoPutChar(char car)
{
unsigned short *pt_bitmap = bitMapBaseAddr + row * maxCol;
@@ -117,8 +117,8 @@ videoPutChar(char car)
}
}
- void
-clear_screen()
+void
+clear_screen(void)
{
int i,j;
diff --git a/c/src/lib/libbsp/i386/pc386/include/Makefile.in b/c/src/lib/libbsp/i386/pc386/include/Makefile.in
index 8f02fc9b25..49e4168eca 100644
--- a/c/src/lib/libbsp/i386/pc386/include/Makefile.in
+++ b/c/src/lib/libbsp/i386/pc386/include/Makefile.in
@@ -8,7 +8,8 @@ VPATH = @srcdir@
RTEMS_ROOT = @top_srcdir@
PROJECT_ROOT = @PROJECT_ROOT@
-H_FILES = $(srcdir)/bsp.h $(srcdir)/coverhd.h $(srcdir)/irq.h $(srcdir)/crt.h
+H_FILES = $(srcdir)/bsp.h $(srcdir)/coverhd.h $(srcdir)/irq.h \
+ $(srcdir)/crt.h $(srcdir)/pc386uart.h $(srcdir)/pcibios.h
#
# Equate files are for including from assembly preprocessed by
diff --git a/c/src/lib/libbsp/i386/pc386/include/bsp.h b/c/src/lib/libbsp/i386/pc386/include/bsp.h
index b404003d92..c7920f385b 100644
--- a/c/src/lib/libbsp/i386/pc386/include/bsp.h
+++ b/c/src/lib/libbsp/i386/pc386/include/bsp.h
@@ -133,8 +133,8 @@ extern "C" {
/*-------------------------------------------------------------------------+
| External Variables.
+--------------------------------------------------------------------------*/
-extern i386_IDT_slot Interrupt_descriptor_table[256];
-extern i386_GDT_slot Global_descriptor_table [8192];
+extern i386_IDT_slot Interrupt_descriptor_table[];
+extern i386_GDT_slot Global_descriptor_table [];
extern rtems_configuration_table BSP_Configuration;
/* User provided BSP configuration table. */
@@ -149,14 +149,32 @@ void _IBMPC_initVideo(void); /* from 'outch.c' */
void _IBMPC_outch (char); /* from 'outch.c' */
rtems_boolean _IBMPC_chrdy (char *); /* from 'inch.c' */
char _IBMPC_inch (void); /* from 'inch.c' */
+char _IBMPC_inch_sleep (void); /* from 'inch.c' */
void printk(char *fmt, ...); /* from 'printk.c' */
void rtemsReboot(void); /* from 'exit.c' */
+/* Definitions for PC386ConsolePort */
+#define PC386_CONSOLE_PORT_CONSOLE (-1)
+#define PC386_CONSOLE_PORT_COM1 (PC386_UART_COM1)
+#define PC386_CONSOLE_PORT_COM2 (PC386_UART_COM2)
+
+/* GDB stub stuff */
+void i386_stub_glue_init(int uart);
+void i386_stub_glue_init_breakin(void);
+void set_debug_traps(void);
+void breakpoint(void);
+
#ifdef __cplusplus
}
#endif
#endif /* __BSP_H_ */
/* end of include file */
+
+
+
+
+
+
diff --git a/c/src/lib/libbsp/i386/pc386/start/start.s b/c/src/lib/libbsp/i386/pc386/start/start.s
index 111962f0c5..fae56137e5 100644
--- a/c/src/lib/libbsp/i386/pc386/start/start.s
+++ b/c/src/lib/libbsp/i386/pc386/start/start.s
@@ -70,7 +70,7 @@ BEGIN_CODE
* to video mode set by the loader, you may try to define
* the following variable:
*/
-#define DEBUG_EARLY_START
+/* #define DEBUG_EARLY_START */
SYM (start):
/*
diff --git a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
index d952457485..607e816d6d 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
+++ b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
@@ -126,6 +126,8 @@ void bsp_start( void )
BSP_Configuration.work_space_start = (void *)rtemsFreeMemStart;
rtemsFreeMemStart += BSP_Configuration.work_space_size;
+ console_reserve_resources(&BSP_Configuration);
+
/*
* The following information is very useful when debugging.
*/
diff --git a/c/src/lib/libbsp/i386/pc386/startup/exit.c b/c/src/lib/libbsp/i386/pc386/startup/exit.c
index 85b5282c36..328a0afa76 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/exit.c
+++ b/c/src/lib/libbsp/i386/pc386/startup/exit.c
@@ -33,8 +33,14 @@
#include <stdio.h>
-
#include <bsp.h>
+#include <pc386uart.h>
+
+/*-------------------------------------------------------------------------+
+ | Which console is in use: either (-1) which means normal console or
+ | uart id if uart was used
+ +-------------------------------------------------------------------------*/
+extern int PC386ConsolePort;
/*-------------------------------------------------------------------------+
| External Prototypes
@@ -50,11 +56,44 @@ extern rtems_boolean _IBMPC_scankey(char *); /* defined in 'inch.c' */
+--------------------------------------------------------------------------*/
void _exit(int status)
{
- unsigned char ch;
- puts("\nEXECUTIVE SHUTDOWN! Any key to reboot...");
+ unsigned char ch, *cp;
+ static char line[]="EXECUTIVE SHUTDOWN! Any key to reboot...";
+
+ if(PC386ConsolePort == PC386_CONSOLE_PORT_CONSOLE)
+ {
- while(!_IBMPC_scankey(&ch))
- ;
+ printk("\n");
+ printk(line);
+ while(!_IBMPC_scankey(&ch))
+ ;
+ printk("\n\n");
+ }
+ else
+ {
+ PC386_uart_intr_ctrl(PC386ConsolePort, PC386_UART_INTR_CTRL_DISABLE);
+
+ PC386_uart_polled_write(PC386ConsolePort, '\r');
+ PC386_uart_polled_write(PC386ConsolePort, '\n');
+
+ for(cp=line; *cp != 0; cp++)
+ {
+ PC386_uart_polled_write(PC386ConsolePort, *cp);
+ }
+
+ PC386_uart_polled_read(PC386ConsolePort);
+
+ PC386_uart_polled_write(PC386ConsolePort, '\r');
+ PC386_uart_polled_write(PC386ConsolePort, '\n');
+ PC386_uart_polled_write(PC386ConsolePort, '\r');
+ PC386_uart_polled_write(PC386ConsolePort, '\n');
+ }
rtemsReboot();
} /* _exit */
+
+
+
+
+
+
+
diff --git a/c/src/lib/libbsp/i386/pc386/startup/ldsegs.s b/c/src/lib/libbsp/i386/pc386/startup/ldsegs.s
index a8eb935322..f2171575ce 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/ldsegs.s
+++ b/c/src/lib/libbsp/i386/pc386/startup/ldsegs.s
@@ -66,10 +66,10 @@ SYM(delay):
| Function: _load_segments
| Description: Current environment is standard PC booted by grub.
| So, there is no value in saving current GDT and IDT
-| Settings we have to set it up ourseves. (Naturally
+| settings we have to set it up ourseves. (Naturally
| it will be not so in case we are booted by some
| boot monitor, however, then it will be different
-| BSP), After that we have to load board segment registers
+| BSP). After that we have to load board segment registers
| with apropriate values + reprogram PIC.
| Global Variables: None.
| Arguments: None.
diff --git a/c/src/lib/libbsp/i386/pc386/tools/Makefile.in b/c/src/lib/libbsp/i386/pc386/tools/Makefile.in
index f62a47bb69..0924a4afca 100644
--- a/c/src/lib/libbsp/i386/pc386/tools/Makefile.in
+++ b/c/src/lib/libbsp/i386/pc386/tools/Makefile.in
@@ -22,7 +22,7 @@ VPATH=@srcdir@
USE_HOST_COMPILER=yes
# C source names, if any, go here -- minus the .c
-C_PIECES=bin2boot Header Image
+C_PIECES= bin2boot binpatch
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=$(ARCH)/%.o)
@@ -30,12 +30,12 @@ CC_PIECES=
CC_FILES=$(CC_PIECES:%=%.cc)
CC_O_FILES=$(CC_PIECES:%=$(ARCH)/%.o)
-H_FILES=bytetype.h Header.h Image.h
+H_FILES=
SRCS=$(C_FILES) $(CC_FILES) $(H_FILES)
OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
-PGMS=$(ARCH)/bin2boot
+PGMS=$(ARCH)/bin2boot $(ARCH)/binpatch
include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
include $(RTEMS_ROOT)/make/leaf.cfg
@@ -66,9 +66,10 @@ CLOBBER_ADDITIONS +=
all: $(ARCH) $(SRCS) $(PGMS)
$(INSTALL) -m 555 $(PGMS) ${PROJECT_RELEASE}/build-tools
-$(ARCH)/bin2boot: $(OBJS)
- $(CC) $(LDFLAGS) $^ -o $@ $(LD_LIBS)
-$(ARCH)/bin2boot.o: bin2boot.c Header.h Image.h bytetype.h
-$(ARCH)/Header.o: Header.c Header.h bytetype.h
-$(ARCH)/Image.o: Image.c Image.h bytetype.h
+$(ARCH)/bin2boot: $(srcdir)/bin2boot.c
+ $(CC) $(LDFLAGS) -o $@ $(srcdir)/bin2boot.c $(LD_LIBS)
+
+$(ARCH)/binpatch: $(srcdir)/binpatch.c
+ $(CC) $(LDFLAGS) -o $@ $(srcdir)/binpatch.c $(LD_LIBS)
+
diff --git a/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c b/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c
index d8d19b4166..a47ca2cee3 100644
--- a/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c
+++ b/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c
@@ -1,198 +1,414 @@
-/*-------------------------------------------------------------------------+
-| bin2boot.c v1.0 - PC386 BSP - 1998/04/09
-+--------------------------------------------------------------------------+
-| This file contains the i386 binary to boot image filter.
-+--------------------------------------------------------------------------+
-| (C) Copyright 1997 -
-| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
-|
-| http://pandora.ist.utl.pt
-|
-| Instituto Superior Tecnico * Lisboa * PORTUGAL
-+--------------------------------------------------------------------------+
-| Disclaimer:
-|
-| This file is provided "AS IS" without warranty of any kind, either
-| expressed or implied.
-+--------------------------------------------------------------------------*/
-
-#include "Image.h"
-#include "Header.h"
-#include "bytetype.h"
+
+/*
+ * Simplyfied version of original bin2boot
+ */
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <memory.h>
-/*-------------------------------------------------------------------------+
-| Constants
-+--------------------------------------------------------------------------*/
-
-#define MAX_IMAGES 15
-
-/*-------------------------------------------------------------------------+
-| Global Variables
-+--------------------------------------------------------------------------*/
-
-// Help message for users
-const char UsageMsg[] = "\
-Usage: bin2boot <outFile> <locAddr> <inFile1> <startAddr1> <memSize1> \\\n\
- [<infile2> <startAddr2> <memSize2>][...][-v][-h][-?]\n\
-\n\
-<outFile> : output file name (mandatory)\n\
-<locAddr> : location address in memory of image header (mandatory)\n\
-<inFileX> : name of Xth input file\n\
-<startAddrX> : start address of Xth image\n\
-<memSizeX> : actual size (for compressed images), use 0 if uncompressed\n\
--v : verbose output\n\
--h, -? : this help message\n\
-\n\
-At least one set of <inFile> <startAddr> and <memSize> is mandatory!\n\
-<locAddr>, <startAddrX> and <memSizeX> can be in Decimal, Hexadecimal or Octal.\n\
-The maximum number of input files is 15.\n";
-
-/*-------------------------------------------------------------------------+
-| External Prototypes (for use with getopt)
-+--------------------------------------------------------------------------*/
-
-extern char *optarg;
-
-int getopt(int, char *const[], const char *);
-
-/*-------------------------------------------------------------------------+
-| Auxiliary Functions
-+--------------------------------------------------------------------------*/
-
-static DWord
-getNumArg(char *arg)
-{
- char *dummy;
- if (arg[0] == '0') {
- if ((arg[1] == 'x') || (arg[1] == 'X')) /* Hexadecimal */
- return (DWord)strtol(arg, &dummy, 16);
- else /* Octal */
- return (DWord)strtol(arg, &dummy, 8);
- } else /* Decimal */
- return (DWord)strtol(arg, &dummy, 10);
-} /* getNumArg */
+static unsigned char buf[512];
+
+static void usage(void)
+{
+ printf("usage: bin2boot [-h][-v] <outFile> <headerAddr> \n");
+ printf("<imFile1> <imAddr1> <imSize1> [<imFile2> <imAddr2> <imSize2>]\n");
+ printf("this function makes image bootable by netboot\n");
+ printf("from one or two binary images\n");
+ printf("-h - prints this message\n");
+ printf("-v - verbose output\n");
+ printf("outFile - output file\n");
+ printf("headerAddr - address to place header in memory\n");
+ printf(" it should be below or equal 0x97e00\n");
+ printf("imFile1 - first image\n");
+ printf("imAddr1 - its start address, image has to be placed whole\n");
+ printf(" below 0x98000 and should not overlap with header\n");
+ printf("imSize1 - actual size of compressed image, 0 for uncompressed\n");
+ printf("imFile2 - second image\n");
+ printf("imAddr2 - its start address\n");
+ printf("imSize2 - actual size of compressed image, 0 for uncompressed\n");
+
+ return;
+}
-/*-------------------------------------------------------------------------+
-| Main
-+--------------------------------------------------------------------------*/
int main(int argc, char* argv[])
{
- Image img[MAX_IMAGES]; /* array to store up to MAX_IMAGE images */
- Header hdr; /* boot image file header */
- FILE* outFile; /* boot image file stream */
- char* outFileName; /* name of boot image file */
+ int c, verbose;
+ extern int optind;
+ FILE *ofp, *ifp;
+ unsigned long headerAddr, addr1, addr2;
+ int size1, size2, len1, len2, len, imageCnt, cnt;
+ char *ofile, *ifile, *end;
+
+ verbose = 0;
- int argPos = 1, numImages, i;
- int verboseFlag = 0, helpFlag = 0; /* flags for command line options */
+ /* parse command line options */
+ while ((c = getopt(argc, argv, "hv")) >= 0)
+ {
+ switch (c)
+ {
+ case 'v':
+ verbose = 1;
+ break;
+ case 'h':
+ usage();
+ return 0;
+ default:
+ usage();
+ return 1;
+ }
+ }
+
+ if((argc - optind) != 8 && (argc - optind) != 5)
+ {
+ usage();
+ return 1;
+ }
+
+ ofile = argv[optind];
+ ofp = fopen(ofile, "w");
+ if(ofp == NULL)
+ {
+ fprintf(stderr, "unable to open file %s\n", ofile);
+ return 1;
+ }
+
+ /*
+ * Layout is very simple first 512 is header shared by all
+ * images, then images at 512 bytes border
+ */
+
+ /* Fill buffer with 0's */
+ memset(buf, 0, sizeof(buf));
+
+ fwrite(buf, 1, sizeof(buf), ofp);
- /*-------------------------------------------------------------------------+
- | Parse command line arguments and options
- +-------------------------------------------------------------------------*/
+ optind++;
+ headerAddr = strtoul(argv[optind], &end, 0);
+ if(end == argv[optind])
+ {
+ fprintf(stderr, "bad headerAddr %s\n", argv[optind]);
+ fclose(ofp);
+ return 1;
+ }
+
+ if(headerAddr > 0x97e00)
+ {
+ fprintf(stderr, "headerAddr is too high 0x%08lx\n", headerAddr);
+ fclose(ofp);
+ return 1;
+ }
- {
- char opt;
-
- /* parse command line options */
- while ((opt = getopt(argc, argv, "vh?")) >= 0)
- {
- argPos++;
- switch (opt)
- {
- case 'v' : verboseFlag = 1; break;
- case 'h' : case '?' : helpFlag = 1; break;
- }
- }
- }
-
- if (helpFlag)
- {
- fprintf(stderr, "%s\n", UsageMsg);
- if (argc == 2)
- exit(0);
- }
-
- numImages = (argc - argPos - 2) / 3;
-
- if (numImages < 1)
- {
- fprintf(stderr,
- "ERROR!!! Not enough command line arguments.\n\n%s\n",
- UsageMsg);
- exit(1);
- }
- if (numImages > 15)
- {
- fprintf(stderr, "ERROR!!! Too many input files.\n\n%s\n", UsageMsg);
- exit(1);
- }
-
- newHeader(&hdr); /* initialize hdr */
-
- argPos = 1;
-
- while (argv[argPos][0] == '-') argPos++; /* discard options */
- if(!(outFile = fopen((outFileName = argv[argPos++]), "w")))
- {
- fprintf(stderr,
- "ERROR!!! While opening file '%s' for output.\n",
- outFileName);
- exit(1);
- }
- reserveSpaceHeader(outFile);
-
- while (argv[argPos][0] == '-') argPos++; /* discard options */
- setLocAddrHeader(&hdr, getNumArg(argv[argPos++]));
-
- /*-------------------------------------------------------------------------+
- | Parse command line arguments concerning images
- +-------------------------------------------------------------------------*/
-
- for(i = 0; i < numImages; i++)
- {
- newImage(&img[i]);
- while (argv[argPos][0] == '-') argPos++; /* discard options */
- setImageFile(&img[i], argv[argPos++]);
- while (argv[argPos][0] == '-') argPos++; /* discard options */
- setLoadAddrImage(&img[i], getNumArg(argv[argPos++]));
- while (argv[argPos][0] == '-') argPos++; /* discard options */
- setMemSizeImage(&img[i], getNumArg(argv[argPos++]));
- }
-
- setLstImgFlagImage(&img[numImages - 1]); /* set flag on last image */
- setExecAddrHeader(&hdr, getLoadAddrImage(&img[0]));
- /* boot file execution address is the same as first image's */
- if (verboseFlag)
- {
- fprintf(stderr, "BootImage file '%s' info:\n\n", outFileName);
- fprintHeader(stderr, &hdr);
- fprintf(stderr, "\n");
- }
-
- /*-------------------------------------------------------------------------+
- | Dump images and header to file
- +-------------------------------------------------------------------------*/
-
- for(i = 0; i < numImages; i++)
- {
- addImageToHeader(&hdr, &img[i]);
- dumpImageToFileAndPad(outFile, &img[i]);
-
- if (verboseFlag)
- fprintImage(stderr, &img[i]);
-
- /* kill image. we don't need anymore and should free its resources */
- killImage(&img[i]);
- }
-
- dumpHeaderToFile(outFile, &hdr);
-
- fclose(outFile);
-
- exit(0);
-} /* main */
+ /* Copy the first image */
+ optind++;
+ ifile = argv[optind];
+ ifp = fopen(ifile,"r");
+ if(ifp == NULL)
+ {
+ fprintf(stderr, "unable to open output file %s\n", ifile);
+ fclose(ofp);
+ return 1;
+ }
+
+ optind++;
+ addr1 = strtoul(argv[optind], &end, 0);
+ if(end == argv[optind])
+ {
+ fprintf(stderr, "bad image address %s\n", argv[optind]);
+ fclose(ofp);
+ return 1;
+ }
+
+ optind++;
+ size1 = strtoul(argv[optind], &end, 0);
+ if(end == argv[optind])
+ {
+ fprintf(stderr, "bad image size %s\n", argv[optind]);
+ fclose(ofp);
+ return 1;
+ }
+
+
+ /* Copy first image out and remember its length */
+ cnt = 0;
+ for(;;)
+ {
+ len = fread(buf, 1, sizeof(buf), ifp);
+
+ if(len != 0)
+ {
+ fwrite(buf, 1, len, ofp);
+ cnt += sizeof(buf);
+
+ if(len != sizeof(buf))
+ {
+ memset(buf, 0, sizeof(buf) - len);
+ fwrite(buf, 1, sizeof(buf) - len, ofp);
+ break;
+ }
+
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ fclose(ifp);
+
+ len1 = cnt;
+
+ if(size1 == 0)
+ {
+ size1 = cnt;
+ }
+ else
+ {
+ memset(buf, 0, sizeof(buf));
+
+ while(cnt < size1)
+ {
+ fwrite(buf, 1, sizeof(buf), ofp);
+ cnt += sizeof(buf);
+ }
+
+ size1 = cnt;
+ }
+
+
+ /* Let us check agains overlapping */
+ if(!(addr1 >= (headerAddr + sizeof(buf)) || (headerAddr >= addr1+size1)))
+ {
+ /* Areas overlapped */
+ printf("area overlapping: \n");
+ printf("header address 0x%08lx, its memory size 0x%08x\n",
+ headerAddr, sizeof(buf));
+ printf("first image address 0x%08lx, its memory size 0x%08x\n",
+ addr1, size1);
+
+ fclose(ofp);
+ return 1;
+ }
+
+ if((addr1 + size1) > 0x98000)
+ {
+ fprintf(stderr, "imAddr1 is too high 0x%08lx\n", addr1);
+ fclose(ofp);
+ return 1;
+ }
+
+
+ if(optind == (argc - 1))
+ {
+ imageCnt = 1;
+ goto writeHeader;
+ }
+
+ imageCnt = 2;
+
+ /* Copy Second Image */
+ optind++;
+ ifile = argv[optind];
+ ifp = fopen(ifile,"r");
+ if(ifp == NULL)
+ {
+ fprintf(stderr, "unable to open output file %s\n", ifile);
+ fclose(ofp);
+ return 1;
+ }
+
+ optind++;
+ addr2 = strtoul(argv[optind], &end, 0);
+ if(end == argv[optind])
+ {
+ fprintf(stderr, "bad image address %s\n", argv[optind]);
+ fclose(ofp);
+ return 1;
+ }
+
+ optind++;
+ size2 = strtoul(argv[optind], &end, 0);
+ if(end == argv[optind])
+ {
+ fprintf(stderr, "bad image size %s\n", argv[optind]);
+ fclose(ofp);
+ return 1;
+ }
+
+ /* Copy second image out and remember its length */
+ cnt = 0;
+ for(;;)
+ {
+ len = fread(buf, 1, sizeof(buf), ifp);
+
+ if(len != 0)
+ {
+ fwrite(buf, len, 1, ofp);
+ cnt += sizeof(buf);
+
+ if(len != sizeof(buf))
+ {
+ memset(buf, 0, sizeof(buf) - len);
+ fwrite(buf, 1, sizeof(buf) - len, ofp);
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ fclose(ifp);
+
+ len2 = cnt;
+
+ if(size2 == 0)
+ {
+ size2 = cnt;
+ }
+ else
+ {
+ memset(buf, 0, sizeof(buf));
+
+ while(cnt < size2)
+ {
+ fwrite(buf, 1, sizeof(buf), ofp);
+ cnt += sizeof(buf);
+ }
+
+ size2 = cnt;
+ }
+
+ /* Let us check against overlapping */
+ if(!((addr2 >= (addr1 + size1) && addr2 >= (headerAddr + sizeof(buf))) ||
+ (addr2 < addr1 && addr2 < headerAddr) ||
+ (addr1 > headerAddr && addr2 > (headerAddr + sizeof(buf)) &&
+ (addr2 + size2) <= addr1) ||
+ (addr1 < headerAddr && addr2 > (addr1 + size1) &&
+ (addr2 + size2) <= headerAddr)))
+
+ {
+ /* Areas overlapped */
+ printf("area overlapping: \n");
+ printf("header address 0x%08lx, its memory size 0x%08x\n",
+ headerAddr, sizeof(buf));
+ printf("first image address 0x%08lx, its memory size 0x%08x\n",
+ addr1, size1);
+ printf("second image address 0x%08lx, its memory size 0x%08x\n",
+ addr2, size2);
+
+ fclose(ofp);
+ return 1;
+ }
+
+writeHeader:
+
+ /* We know everything so it is time to write buffer */
+ memset(buf, 0, 0x30);
+
+ buf[0x0] = 0x36;
+ buf[0x1] = 0x13;
+ buf[0x2] = 0x03;
+ buf[0x3] = 0x1b;
+
+ buf[0x4] = 4;
+
+ /* Header address in ds:bx format */
+ buf[0x8] = headerAddr & 0xf;
+ buf[0x9] = 0;
+ buf[0xa] = (headerAddr >> 4) & 0xff;
+ buf[0xb] = (headerAddr >> 12) & 0xff;
+
+ /*
+ * Execute address in cs:ip format, which addr1
+ */
+ buf[0xc] = addr1 & 0xf;
+ buf[0xd] = 0;
+ buf[0xe] = (addr1 >> 4) & 0xff;
+ buf[0xf] = (addr1 >> 12) & 0xff;
+
+ /* Flags, tags and lengths */
+ buf[0x10] = 4;
+
+ if(imageCnt == 1)
+ {
+ buf[0x13] = 4;
+ }
+
+ /* Load address */
+ buf[0x14] = addr1 & 0xff;
+ buf[0x15] = (addr1 >> 8) & 0xff;
+ buf[0x16] = (addr1 >> 16) & 0xff;
+ buf[0x17] = (addr1 >> 24) & 0xff;
+
+ /* Image Length */
+ buf[0x18] = len1 & 0xff;
+ buf[0x19] = (len1 >> 8) & 0xff;
+ buf[0x1a] = (len1 >> 16) & 0xff;
+ buf[0x1b] = (len1 >> 24) & 0xff;
+
+ /* Memory Size */
+ buf[0x1c] = size1 & 0xff;
+ buf[0x1d] = (size1 >> 8) & 0xff;
+ buf[0x1e] = (size1 >> 16) & 0xff;
+ buf[0x1f] = (size1 >> 24) & 0xff;
+
+ if(imageCnt != 1)
+ {
+
+ /* Flags, tags and lengths */
+ buf[0x20] = 4;
+
+ buf[0x23] = 4;
+
+
+ /* Load address */
+ buf[0x24] = addr2 & 0xff;
+ buf[0x25] = (addr2 >> 8) & 0xff;
+ buf[0x26] = (addr2 >> 16) & 0xff;
+ buf[0x27] = (addr2 >> 24) & 0xff;
+
+ /* Image Length */
+ buf[0x28] = len2 & 0xff;
+ buf[0x29] = (len2 >> 8) & 0xff;
+ buf[0x2a] = (len2 >> 16) & 0xff;
+ buf[0x2b] = (len2 >> 24) & 0xff;
+
+ /* Memory Size */
+ buf[0x2c] = size2 & 0xff;
+ buf[0x2d] = (size2 >> 8) & 0xff;
+ buf[0x2e] = (size2 >> 16) & 0xff;
+ buf[0x2f] = (size2 >> 24) & 0xff;
+ }
+
+ rewind(ofp);
+
+ fwrite(buf, 1, 0x30, ofp);
+
+ fclose(ofp);
+
+ if(verbose)
+ {
+ printf("header address 0x%08lx, its memory size 0x%08x\n",
+ headerAddr, sizeof(buf));
+ printf("first image address 0x%08lx, its memory size 0x%08x\n",
+ addr1, size1);
+ printf("second image address 0x%08lx, its memory size 0x%08x\n",
+ addr2, size2);
+ }
+
+ return 0;
+}
+
+
+
+
+
+
+
+
diff --git a/c/src/lib/libbsp/i386/pc386/tools/binpatch.c b/c/src/lib/libbsp/i386/pc386/tools/binpatch.c
new file mode 100644
index 0000000000..ab0900702a
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/tools/binpatch.c
@@ -0,0 +1,168 @@
+/*
+ * $Id$
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * This function will patch binary file
+ */
+
+
+static char buf[512];
+
+static void
+usage(void)
+{
+ printf("usage: binpatch [-h] <ofile> <ifile> <reloc> <off> <byte0> "
+ "[<byte1> [<byte2> [<byte3>]]]\n");
+ printf("this function patches binary file at specified offset with\n");
+ printf("up to 4 bytes provided on command line \n");
+ printf("-h - prints this message\n\n");
+ printf("<ofile> - output file\n");
+ printf("<ifile> - input ifile\n");
+ printf("<reloc> - relocation address of image\n");
+ printf("<off> - offset of patch, offset in file is at off - reloc\n");
+ printf("<byte0> - byte 0 of patch\n");
+ printf("<byte1> - byte 1 of patch\n");
+ printf("<byte2> - byte 1 of patch\n");
+ printf("<byte3> - byte 1 of patch\n");
+
+ return;
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ FILE *ofp, *ifp;
+ char patch[4], *end;
+ int patchLen, tmp, i, off, cnt, patched, len, reloc;
+
+
+ /* parse command line options */
+ while ((c = getopt(argc, argv, "h")) >= 0)
+ {
+ switch (c)
+ {
+ case 'h':
+ usage();
+ return 0;
+ default:
+ usage();
+ return 1;
+ }
+ }
+
+ if(argc < 6)
+ {
+ usage();
+ return 1;
+ }
+
+ /* Let us get offset in file */
+ reloc = strtol(argv[3], &end, 0);
+ if(end == argv[3] || off < 0)
+ {
+ fprintf(stderr, "bad reloc value %s\n", argv[3]);
+ return 1;
+ }
+
+ off = strtol(argv[4], &end, 0);
+ if(end == argv[4] || off < 0 || off < reloc)
+ {
+ fprintf(stderr, "bad offset value %s\n", argv[4]);
+ return 1;
+ }
+
+ off -= reloc;
+
+ /* Let us get patch */
+ patchLen = argc - 5;
+
+ for(i=0; i<patchLen; i++)
+ {
+ tmp = strtol(argv[5+i], &end, 0);
+
+ if(end == argv[4+i] || tmp < 0 || tmp > 0xff)
+ {
+ fprintf(stderr, "bad byte value %s\n", argv[5+i]);
+ return 1;
+ }
+ patch[i] = tmp;
+ }
+
+ ifp = fopen(argv[2], "r");
+ if(ifp == NULL)
+ {
+ fprintf(stderr, "unable to open file %s\n", argv[2]);
+ return 1;
+ }
+
+ ofp = fopen(argv[1], "w");
+ if(ofp == NULL)
+ {
+ fprintf(stderr, "unable to open file %s\n", argv[1]);
+ return 1;
+ }
+
+ cnt = 0;
+ patched = 0;
+ for(;;)
+ {
+ len = fread(buf, 1, sizeof(buf), ifp);
+
+ if(len == 0)
+ {
+ break;
+ }
+
+ if(cnt <= off && (cnt + len) > off)
+ {
+ /* Perform patch */
+ for(i=0; i<patchLen && (off+i)<(cnt+len); i++)
+ {
+ buf[off-cnt+i] = patch[i];
+ }
+ patched = 1;
+ }
+ else if(cnt > off && cnt < (off + patchLen))
+ {
+ /* Perform patch */
+ for(i=cnt-off; i<patchLen; i++)
+ {
+ buf[off-cnt+i] = patch[i];
+ }
+ patched = 1;
+ }
+
+ fwrite(buf, 1, len, ofp);
+
+ cnt += len;
+ }
+
+ fclose(ifp);
+ fclose(ofp);
+
+ if(!patched)
+ {
+ fprintf(stderr, "warning: offset is beyond input file length\n");
+ fprintf(stderr, " no patch is performed\n");
+ }
+
+ return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in b/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in
index 2adbda5433..eea0a83229 100644
--- a/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in
+++ b/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in
@@ -8,7 +8,7 @@ VPATH = @srcdir@
RTEMS_ROOT = @top_srcdir@
PROJECT_ROOT = @PROJECT_ROOT@
-BSP_PIECES=startup clock console timer
+BSP_PIECES=startup clock console timer pc386dev
GENERIC_PIECES=
# bummer; have to use $foreach since % pattern subst rules only replace 1x