forked from Imagelibrary/rtems
@@ -20,11 +20,6 @@ CFLAGS_OPTIMIZE_V = -O2 -g
|
|||||||
CFLAGS_OPTIMIZE_V += -ffunction-sections -fdata-sections
|
CFLAGS_OPTIMIZE_V += -ffunction-sections -fdata-sections
|
||||||
|
|
||||||
LDFLAGS = -Wl,--gc-sections
|
LDFLAGS = -Wl,--gc-sections
|
||||||
|
|
||||||
# Here is the rule to actually build a $(ARCH)/foo$(EXEEXT)
|
|
||||||
# It also builds $(ARCH)/foo.sr and $(ARCH)/foo.nm
|
|
||||||
# Usage ref: src/tests/sptest/sp1/Makefile
|
|
||||||
|
|
||||||
#+--------------------------------------------------------------------------+
|
#+--------------------------------------------------------------------------+
|
||||||
#| Set the value of RELOCADDR to the address where you want your image to
|
#| Set the value of RELOCADDR to the address where you want your image to
|
||||||
#| load. If you'll be using GRUB to load the images it will have to be >=
|
#| load. If you'll be using GRUB to load the images it will have to be >=
|
||||||
@@ -36,23 +31,4 @@ LDFLAGS = -Wl,--gc-sections
|
|||||||
#+--------------------------------------------------------------------------+
|
#+--------------------------------------------------------------------------+
|
||||||
RELOCADDR=0x00100000
|
RELOCADDR=0x00100000
|
||||||
|
|
||||||
START16FILE=$(PROJECT_RELEASE)/lib/start16$(LIB_VARIANT).bin
|
|
||||||
START16ADDR=0x00097C00
|
|
||||||
HEADERADDR=0x00097E00
|
|
||||||
|
|
||||||
LDFLAGS += -Wl,-Ttext,$(RELOCADDR)
|
LDFLAGS += -Wl,-Ttext,$(RELOCADDR)
|
||||||
|
|
||||||
define bsp-post-link
|
|
||||||
$(default-bsp-post-link)
|
|
||||||
$(OBJCOPY) -O elf32-i386 \
|
|
||||||
--remove-section=.comment \
|
|
||||||
--remove-section=.note \
|
|
||||||
--strip-unneeded $(basename $@)$(EXEEXT) $(basename $@).nxe
|
|
||||||
$(OBJCOPY) -O binary $(basename $@).nxe $(basename $@).bin
|
|
||||||
$(PROJECT_TOOLS)/bin2boot -v $(basename $@)$(DOWNEXT) $(HEADERADDR)\
|
|
||||||
$(START16FILE) $(START16ADDR) 0 $(basename $@).bin $(RELOCADDR) 0
|
|
||||||
rm -f $(basename $@).nxe
|
|
||||||
endef
|
|
||||||
|
|
||||||
# BSP-specific tools
|
|
||||||
BIN2BOOT=$(PROJECT_TOOLS)/bin2boot
|
|
||||||
|
|||||||
@@ -16,32 +16,10 @@ dist_project_lib_DATA = ../../../../../../bsps/i386/pc386/start/bsp_specs
|
|||||||
|
|
||||||
noinst_PROGRAMS =
|
noinst_PROGRAMS =
|
||||||
|
|
||||||
_SUBDIRS = . tools
|
|
||||||
|
|
||||||
TMPINSTALL_FILES =
|
|
||||||
|
|
||||||
start.$(OBJEXT): ../../../../../../bsps/i386/pc386/start/start.S
|
start.$(OBJEXT): ../../../../../../bsps/i386/pc386/start/start.S
|
||||||
$(CPPASCOMPILE) -o $@ -c $<
|
$(CPPASCOMPILE) -o $@ -c $<
|
||||||
project_lib_DATA = start.$(OBJEXT)
|
project_lib_DATA = start.$(OBJEXT)
|
||||||
|
|
||||||
start16.$(OBJEXT): ../../../../../../bsps/i386/pc386/start/start16.S
|
|
||||||
$(CPPASCOMPILE) $(AM_CPPFLAGS) -DHEADERADDR=$(HEADERADDR) -o $@ -c $<
|
|
||||||
|
|
||||||
start16-elf32.$(OBJEXT): start16.$(OBJEXT)
|
|
||||||
$(LD) -N -Ttext $(START16ADDR) -e start16 -nostdlib \
|
|
||||||
--oformat=elf32-i386 \
|
|
||||||
-o $@ $<
|
|
||||||
|
|
||||||
start16.bin: start16-elf32.$(OBJEXT)
|
|
||||||
$(OBJCOPY) -O binary $< $@
|
|
||||||
CLEANFILES += start16.bin
|
|
||||||
|
|
||||||
$(PROJECT_LIB)/start16.bin: start16.bin $(PROJECT_LIB)/$(dirstamp)
|
|
||||||
$(INSTALL_DATA) $< $(PROJECT_LIB)/start16.bin
|
|
||||||
TMPINSTALL_FILES += $(PROJECT_LIB)/start16.bin
|
|
||||||
|
|
||||||
project_lib_DATA += start16.bin
|
|
||||||
|
|
||||||
project_lib_DATA += linkcmds
|
project_lib_DATA += linkcmds
|
||||||
|
|
||||||
project_lib_LIBRARIES = librtemsbsp.a
|
project_lib_LIBRARIES = librtemsbsp.a
|
||||||
|
|||||||
@@ -142,8 +142,6 @@ AM_CONDITIONAL(RTEMS_GAS_CODE16,[test "$RTEMS_GAS_CODE16" = "yes"])
|
|||||||
|
|
||||||
AC_SUBST([RTEMS_ROOT],[${rtems_updir}'$(top_builddir)'])
|
AC_SUBST([RTEMS_ROOT],[${rtems_updir}'$(top_builddir)'])
|
||||||
|
|
||||||
RTEMS_CONFIG_BUILD_SUBDIRS(tools)
|
|
||||||
|
|
||||||
AC_SUBST(RTEMS_BSP)
|
AC_SUBST(RTEMS_BSP)
|
||||||
|
|
||||||
RTEMS_BSP_CLEANUP_OPTIONS
|
RTEMS_BSP_CLEANUP_OPTIONS
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
ACLOCAL_AMFLAGS = -I ../../../../../aclocal
|
|
||||||
|
|
||||||
|
|
||||||
# HACK: autoconf wants to transform the name, but RTEMS *.cfgs are not able
|
|
||||||
# to deal with it.
|
|
||||||
# FIXME: The installation directory is arguable
|
|
||||||
transform =
|
|
||||||
bsptools_bindir = ${exec_prefix}/@RTEMS_BSP@/build-tools
|
|
||||||
bsptools_bin_PROGRAMS = bin2boot
|
|
||||||
|
|
||||||
bin2boot_SOURCES = bin2boot.c
|
|
||||||
|
|
||||||
## HACK: install into build-tree
|
|
||||||
all-local: $(TMPINSTALL_FILES)
|
|
||||||
|
|
||||||
TMPINSTALL_FILES =
|
|
||||||
|
|
||||||
$(PROJECT_ROOT)/@RTEMS_BSP@/build-tools/$(dirstamp):
|
|
||||||
@$(MKDIR_P) $(PROJECT_ROOT)/@RTEMS_BSP@/build-tools
|
|
||||||
@: > $(PROJECT_ROOT)/@RTEMS_BSP@/build-tools/$(dirstamp)
|
|
||||||
TMPINSTALL_FILES += $(PROJECT_ROOT)/@RTEMS_BSP@/build-tools/$(dirstamp)
|
|
||||||
|
|
||||||
$(PROJECT_ROOT)/@RTEMS_BSP@/build-tools/bin2boot$(EXEEXT): bin2boot$(EXEEXT) $(PROJECT_ROOT)/@RTEMS_BSP@/build-tools/$(dirstamp)
|
|
||||||
$(INSTALL_PROGRAM) $< $(PROJECT_ROOT)/@RTEMS_BSP@/build-tools/bin2boot$(EXEEXT)
|
|
||||||
TMPINSTALL_FILES += $(PROJECT_ROOT)/@RTEMS_BSP@/build-tools/bin2boot$(EXEEXT)
|
|
||||||
|
|
||||||
CLEANFILES = $(TMPINSTALL_FILES)
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../../../automake/host.am
|
|
||||||
@@ -1,353 +0,0 @@
|
|||||||
2-28-1995 GK
|
|
||||||
|
|
||||||
In order to provide more functionality to the boot rom code I changed
|
|
||||||
Jamie's draft a little bit. All my changes have a bar sign (|) in the
|
|
||||||
79th column.
|
|
||||||
|
|
||||||
Gero Kuhlmann
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
|
|
||||||
|
|
||||||
0. Numbering
|
|
||||||
|
|
||||||
This is Draft Net Boot Image Proposal 0.2, February 28, 1995 |
|
|
||||||
|
|
||||||
|
|
||||||
1. Preamble - the why
|
|
||||||
|
|
||||||
Whilst researching what other boot proms do (at least those implementing
|
|
||||||
TCP/IP protocols) it is clear that each 'does their own thing' in
|
|
||||||
terms of what they expect in a boot image.
|
|
||||||
|
|
||||||
If we could all agree on working toward an open standard, O/S suppliers
|
|
||||||
and boot rom suppliers can build their products to this norm, and be confident
|
|
||||||
that they will work with each other.
|
|
||||||
|
|
||||||
This is a description of how I will implement the boot rom for
|
|
||||||
Linux. I believe it to be flexible enough for any OS that will be loaded
|
|
||||||
when a PC boots from a network in the TCP/IP environment.
|
|
||||||
|
|
||||||
It would be good if this could be turned into some form of standard.
|
|
||||||
|
|
||||||
This is very much a first draft. I am inviting comment.
|
|
||||||
|
|
||||||
The ideas presented here should be independant of any implementation.
|
|
||||||
In the end, where there is a conflict between the final of this draft, and an
|
|
||||||
implementation, this description should prevail.
|
|
||||||
|
|
||||||
The terms I use are defined at the end.
|
|
||||||
|
|
||||||
|
|
||||||
2. The target
|
|
||||||
|
|
||||||
The target is to have a PC retrieve a boot image from a network in the TCP/IP
|
|
||||||
environment.
|
|
||||||
|
|
||||||
The boot may take place from a network adaptor rom, from a boot floppy, or
|
|
||||||
from a program in MSDOS.
|
|
||||||
|
|
||||||
|
|
||||||
3. Net Boot Process Description.
|
|
||||||
|
|
||||||
The net boot process can be started either as a result of the PC
|
|
||||||
boot process, or through normal DOS execution of a program. The net boot
|
|
||||||
program can reside on a rom, e.g. on an adaptor card, or in ram, either
|
|
||||||
as a result of reading off disk or transferred from ram.
|
|
||||||
|
|
||||||
The boot process may execute in any mode (e.g. 8086, 80386) it desires.
|
|
||||||
When it jumps to the start location in the boot image, it must be in
|
|
||||||
8086 mode and be capable of going into any mode supported by the
|
|
||||||
underlying processor.
|
|
||||||
|
|
||||||
The image cannot be loaded into address spaces below 10000h, or between
|
|
||||||
A0000h through FFFFFh, or between 98000h through 9FFFFh. Once the image
|
|
||||||
starts executing, all the memory is available to it, so it can relocate
|
|
||||||
parts of itself to these areas.
|
|
||||||
|
|
||||||
The boot process must be capable of loading the image into all other
|
|
||||||
memory locations. Specifically, where the machine supports this, this means
|
|
||||||
memory over 100000h.
|
|
||||||
|
|
||||||
The net boot process must execute the bootp protocol, followed by
|
|
||||||
the tftp protocol, as defined in the relevant rfc's.
|
|
||||||
|
|
||||||
The file name used in the tftp protocol must be that given by the bootp
|
|
||||||
record.
|
|
||||||
|
|
||||||
If less than 512 bytes are loaded, the net boot process attempts to display
|
|
||||||
on the screen any ascii data at the start of the image. The net boot
|
|
||||||
process then exits in the normal manner. For a boot prom, this will
|
|
||||||
allow normal disk booting. For DOS programs, this will mean a normal return
|
|
||||||
to DOS.
|
|
||||||
|
|
||||||
When the first 512 bytes have been loaded, the boot process checks
|
|
||||||
for an initial magic number, which is defined later. If this number
|
|
||||||
is present, the net process continues loading under the control
|
|
||||||
of the image format. The image, which is described later, tells the
|
|
||||||
net boot process where to put this record and all subsequent data.
|
|
||||||
|
|
||||||
If no initial magic number is present the net boot process checks for a second
|
|
||||||
magic number at offset 510. If the magic number 510 = 55h, 511 = AAh,
|
|
||||||
then the net process continues. If this second magic number is not
|
|
||||||
present, then the net boot process terminates the tftp protocol, displays
|
|
||||||
an error message and exits in the normal manner.
|
|
||||||
|
|
||||||
If no initial magic number is present and the second one is, the net boot
|
|
||||||
process relocates the 512 bytes to location 7c00h. The net boot process
|
|
||||||
continues to load any further image data to 10000h up. This data can overwrite
|
|
||||||
the first 512 boot bytes. If the image reaches 98000h, then any further data is
|
|
||||||
continued to be loaded above 100000h. When all the data has been loaded, the
|
|
||||||
net boot process jumps to location 0:7c00.
|
|
||||||
|
|
||||||
When the net boot process calls the image, it places 2 far pointers onto |
|
|
||||||
the stack, in standard intel order (e.g. segment:offset representation). |
|
|
||||||
The first far pointer which immediately follows the return address on |
|
|
||||||
the stack, points to the loaded boot image header. The second far pointer |
|
|
||||||
which is placed above the first one, shows to the memory area where the |
|
|
||||||
net boot process saved the bootp reply. |
|
|
||||||
|
|
||||||
|
|
||||||
4. Image Format with Initial Magic Number.
|
|
||||||
|
|
||||||
The first 512 bytes of the image file contain the image header,
|
|
||||||
and image loading information records. This contains all the
|
|
||||||
information needed by the net boot process as to where data
|
|
||||||
is to be loaded.
|
|
||||||
|
|
||||||
The magic number (in time-honoured tradition (well why not?)) is:
|
|
||||||
|
|
||||||
0 = 36h
|
|
||||||
1 = 13h
|
|
||||||
2 = 03h
|
|
||||||
3 = 1Bh
|
|
||||||
|
|
||||||
Apart from the two magic numbers, all words and double words are in PC
|
|
||||||
native endian.
|
|
||||||
|
|
||||||
Including the initial magic number the header record is:
|
|
||||||
|
|
||||||
+---------------------+
|
|
||||||
| |
|
|
||||||
| Initial Magic No. | 4 bytes
|
|
||||||
+---------------------+
|
|
||||||
| |
|
|
||||||
| Flags and length | double word
|
|
||||||
+---------------------+
|
|
||||||
| |
|
|
||||||
| Location Address | double word in ds:bx format
|
|
||||||
+---------------------+
|
|
||||||
| |
|
|
||||||
| Execute Address | double word in cs:ip format
|
|
||||||
+---------------------+
|
|
||||||
|
|
||||||
The Location address is where to place the 512 bytes. The net boot
|
|
||||||
process does this before loading the rest of the image. The location
|
|
||||||
address cannot be one of the reserved locations mentioned above, but
|
|
||||||
must be an address lower than 100000h.
|
|
||||||
|
|
||||||
The rest of the image must not overwrite these initial 512 bytes, placed
|
|
||||||
at the required location. The writing of data by the net boot process
|
|
||||||
into these 512 bytes is deprecated. These 512 bytes must be available for
|
|
||||||
the image to interogate once it is loaded and running.
|
|
||||||
|
|
||||||
The execute address is the location in cs:ip of the initial instruction
|
|
||||||
once the full image has been loaded. This must be lower than 100000h,
|
|
||||||
since the initial instructions will be executed in 8086 mode. When the
|
|
||||||
jump (actaully a far call) is made to the boot image, the stack contains a
|
|
||||||
far return address, with a far pointer parameter above that, pointing
|
|
||||||
to the location of this header.
|
|
||||||
|
|
||||||
The flags and length field is broken up in the following way:
|
|
||||||
|
|
||||||
Bits 0 to 3 (lowest 4 bits) define the length of the non vendor header in
|
|
||||||
double words. Currently the value is 4.
|
|
||||||
|
|
||||||
Bits 4 to 7 define the length required by the vendor extra information
|
|
||||||
in double words. A value of zero indicates no extra vendor information.
|
|
||||||
|
|
||||||
Bits 8 to 31 are reserved for future use and must be set to zero.
|
|
||||||
|
|
||||||
After this header, and any vendor header, come the image loading information
|
|
||||||
records. These specify where data is to be loaded, how long it is, and
|
|
||||||
communicates to the loaded image what sort of data it is.
|
|
||||||
|
|
||||||
The format of each image loading information record is :
|
|
||||||
|
|
||||||
|
|
||||||
+---------------------+
|
|
||||||
| Flags, tags and | double word
|
|
||||||
| lengths |
|
|
||||||
+---------------------+
|
|
||||||
| |
|
|
||||||
| Load Address | double word
|
|
||||||
+---------------------+
|
|
||||||
| |
|
|
||||||
| Image Length | double word
|
|
||||||
+---------------------+
|
|
||||||
| |
|
|
||||||
| Memory Length | double word
|
|
||||||
+---------------------+
|
|
||||||
|
|
||||||
Each image loading information record follows the previous, or the header.
|
|
||||||
|
|
||||||
The memory length, image length and load address fields are unsigned 32
|
|
||||||
numbers. They do not have the segment:offset format used by the 8086.
|
|
||||||
|
|
||||||
The flags, tags and lengths field is broken up as follows:
|
|
||||||
|
|
||||||
Bits 0 to 3 (lowest 4 bits) are the length of the non vendor part of this
|
|
||||||
header in double words. Currently this value is 4.
|
|
||||||
|
|
||||||
Bits 4 to 7 indicate the length of any vendor information, in double words.
|
|
||||||
|
|
||||||
Bits 8 to 15 are for vendor's tags. The vendor tag is a private number that
|
|
||||||
the loaded image can use to determine what sort of image is at this particular
|
|
||||||
location.
|
|
||||||
|
|
||||||
Bits 16 to 23 are for future expansion and should be set to zero.
|
|
||||||
|
|
||||||
Bits 24 to 31 are for flags, which are defined later.
|
|
||||||
|
|
||||||
Vendors may place further information after this information record, and
|
|
||||||
before the next. Each information record may have a different vendor
|
|
||||||
length.
|
|
||||||
|
|
||||||
There are two restrictions on vendor information.
|
|
||||||
|
|
||||||
One is that the header and all information records that the net boot process
|
|
||||||
is to use fall within the first 512 bytes.
|
|
||||||
|
|
||||||
The second restriction is that the net boot process must ignore all
|
|
||||||
vendor additions. The net boot process may not overwrite vendor supplied
|
|
||||||
information, or other undefined data in the initial 512 bytes.
|
|
||||||
|
|
||||||
The flags are used to modify the load address field, and to indicate
|
|
||||||
that this is the last information record that the net boot process should
|
|
||||||
use.
|
|
||||||
|
|
||||||
Bit 24 works in conjunction with bit 25 to specify the meaning of the
|
|
||||||
load address.
|
|
||||||
|
|
||||||
B24 B25
|
|
||||||
|
|
||||||
0 0 load address is an absolute 32 number
|
|
||||||
|
|
||||||
1 0 add the load address to the location one past the last byte
|
|
||||||
of the memory area required by the last image loaded.
|
|
||||||
If the first image, then add to 512 plus the location
|
|
||||||
where the 512 bytes were placed
|
|
||||||
|
|
||||||
0 1 subtract the load address from the one past the
|
|
||||||
last writeable location in memory. Thus 1 would
|
|
||||||
be the last location one could write in memory.
|
|
||||||
|
|
||||||
1 1 load address is subtracted from the start of
|
|
||||||
the last image loaded. If the first image, then
|
|
||||||
subtract from the start of where the 512 bytes were
|
|
||||||
placed
|
|
||||||
|
|
||||||
(For convenience bit 24 is byte 0 of the flag field)
|
|
||||||
|
|
||||||
Bit 26 is the end marker for the net boot process. It is set when
|
|
||||||
this is the last information record the net boot process should
|
|
||||||
look at. More records may be present, but the net boot process will not
|
|
||||||
look at them. (Vendors can continue information records out past the 512
|
|
||||||
boundary for private use in this manner).
|
|
||||||
|
|
||||||
The image length tells the net boot process how many bytes are to be loaded.
|
|
||||||
Zero is a valid value. This can be used to mark memory areas such as
|
|
||||||
shared memory for interprocessor communication, flash eproms, data in eproms.
|
|
||||||
|
|
||||||
The image length can also be different from the memory length. This allows
|
|
||||||
decompression programs to fluff up the kernel image. It also allows a file
|
|
||||||
system to be larger then the loaded file system image.
|
|
||||||
|
|
||||||
Bits 27 through 31 are not defined as yet and must be set to zero until
|
|
||||||
they are.
|
|
||||||
|
|
||||||
|
|
||||||
6. Boot prom entry points.
|
|
||||||
|
|
||||||
I have not defined boot entry points, and means of obtaining them.
|
|
||||||
It could be useful to down load part of an image, and have that image
|
|
||||||
load more of itself by using handy parts of the net boot program.
|
|
||||||
|
|
||||||
This can be considered 'for further study'.
|
|
||||||
|
|
||||||
|
|
||||||
7. Example of a boot image.
|
|
||||||
|
|
||||||
Here is an example of how the boot image would look for Linux:
|
|
||||||
|
|
||||||
0x1B031336, /* magic number */
|
|
||||||
0x4, /* length of header is 16 bytes, no vendor info */
|
|
||||||
0x90000000, /* location in ds:bx format */
|
|
||||||
0x90000200, /* execute address in cs:ip format */
|
|
||||||
|
|
||||||
/* 2048 setup.S bytes */
|
|
||||||
0x4, /* flags, not end, absolute address, 16 bytes this
|
|
||||||
record, no vendor info */
|
|
||||||
0x90200, /* load address - note format */
|
|
||||||
0x800, /* 4 8 512 byte blocks for linux */
|
|
||||||
0x800,
|
|
||||||
|
|
||||||
/* kernel image */
|
|
||||||
0x4, /* flags, not end, absolute address, 16 bytes this
|
|
||||||
record, no vendor info */
|
|
||||||
0x10000, /* load address - note format */
|
|
||||||
0x80000, /* 512K (this could be shorter */
|
|
||||||
0x80000,
|
|
||||||
|
|
||||||
/* ramdisk for root file system */
|
|
||||||
0x04000004, /* flags = last, absolute address, 16 bytes this
|
|
||||||
record, no vendor info *//
|
|
||||||
0x100000, /* load address - in extended memory */
|
|
||||||
0x80000, /* 512K for instance */
|
|
||||||
0x80000,
|
|
||||||
|
|
||||||
/* Then follows linux specific information */
|
|
||||||
|
|
||||||
|
|
||||||
8. Terms
|
|
||||||
|
|
||||||
When I say 'the net boot process', I mean the act of loading the image into
|
|
||||||
memory, setting up any tables, up until the jump to the required location
|
|
||||||
in the image.
|
|
||||||
|
|
||||||
The net booting program executes the net boot process. The net boot program
|
|
||||||
may be a rom, but not neccassarily. It is a set of instructions and data
|
|
||||||
residing on the booting machine.
|
|
||||||
|
|
||||||
The image, or boot image, consists of the data loaded by the net boot process.
|
|
||||||
|
|
||||||
When I say 'the PC boot process', I mean the general PC rom bios boot process,
|
|
||||||
the setting up of hardware, the scanning for adaptor roms, the execution
|
|
||||||
of adaptor roms, the loading in of the initial boot track. The PC boot
|
|
||||||
process will include the net boot process, if one is present.
|
|
||||||
|
|
||||||
When I say client, I mean the PC booting up.
|
|
||||||
|
|
||||||
When I say 'image host', I mean the host where the boot image is comming from.
|
|
||||||
This may not have the same architecture as the client.
|
|
||||||
|
|
||||||
The bootp protocol is defined in RFC951 and RFC1084. The tftp protocol
|
|
||||||
is defined in RFC783. These are available on many sites.
|
|
||||||
See Comer 1991 for details on how to obtain them.
|
|
||||||
|
|
||||||
A bootp server is the machine that answers the bootp request. It is not
|
|
||||||
neccassarily the image host.
|
|
||||||
|
|
||||||
'Can' and 'may' means doesn't have to, but is allowed to and might.
|
|
||||||
'Must' means just that. 'Cannot' means must not.
|
|
||||||
|
|
||||||
|
|
||||||
9 References
|
|
||||||
|
|
||||||
Comer, D.E. 1991, Internetworking with TCP/IP Vol I: Principles, Protocols,
|
|
||||||
and Architecture Second Edition, Prentice Hall, Englewood Cliffs, N.J., 1991
|
|
||||||
|
|
||||||
Stevens, W.R 1990, Unix Network Programming, Prentice Hall,
|
|
||||||
Englewood Cliffs, N.J., 1990
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,403 +0,0 @@
|
|||||||
/*
|
|
||||||
* Simplyfied version of original bin2boot
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
int c, verbose;
|
|
||||||
extern int optind;
|
|
||||||
FILE *ofp, *ifp;
|
|
||||||
uintptr_t headerAddr, addr1, addr2;
|
|
||||||
int size1, size2, len1, len2, len, imageCnt, cnt;
|
|
||||||
char *ofile, *ifile, *end;
|
|
||||||
|
|
||||||
len2 = 0; /* avoid warning */
|
|
||||||
size2 = 0; /* avoid warning */
|
|
||||||
addr2 = 0; /* avoid warning */
|
|
||||||
verbose = 0;
|
|
||||||
|
|
||||||
/* 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, "wb");
|
|
||||||
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);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy the first image */
|
|
||||||
optind++;
|
|
||||||
ifile = argv[optind];
|
|
||||||
ifp = fopen(ifile,"rb");
|
|
||||||
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%08zx\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,"rb");
|
|
||||||
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%08" PRIxPTR ", its memory size 0x%08zx\n",
|
|
||||||
headerAddr, sizeof(buf));
|
|
||||||
printf("first image address 0x%08" PRIxPTR ", its memory size 0x%08x\n",
|
|
||||||
addr1, size1);
|
|
||||||
printf("second image address 0x%08" PRIxPTR ", 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%08" PRIxPTR ", its memory size 0x%08zx\n",
|
|
||||||
headerAddr, sizeof(buf));
|
|
||||||
printf("first image address 0x%08" PRIxPTR ", its memory size 0x%08x\n",
|
|
||||||
addr1, size1);
|
|
||||||
printf("second image address 0x%08" PRIxPTR ", its memory size 0x%08x\n",
|
|
||||||
addr2, size2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
## Process this file with autoconf to produce a configure script.
|
|
||||||
|
|
||||||
AC_PREREQ([2.69])
|
|
||||||
AC_INIT([rtems-c-src-lib-libbsp-i386-pc386-tools],[_RTEMS_VERSION],[https://devel.rtems.org/newticket])
|
|
||||||
RTEMS_TOP(../../../../../../..)
|
|
||||||
RTEMS_SOURCE_TOP
|
|
||||||
RTEMS_BUILD_TOP
|
|
||||||
|
|
||||||
CFLAGS="-g -O2 -Wall"
|
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE([no-define foreign subdir-objects 1.12.2])
|
|
||||||
AM_MAINTAINER_MODE
|
|
||||||
|
|
||||||
RTEMS_ENV_RTEMSBSP
|
|
||||||
AC_PROG_CC
|
|
||||||
|
|
||||||
AC_CHECK_FUNCS(strtoul)
|
|
||||||
|
|
||||||
RTEMS_PROJECT_ROOT
|
|
||||||
RTEMS_TOOLPATHS
|
|
||||||
|
|
||||||
# Explicitly list all Makefiles here
|
|
||||||
AC_CONFIG_FILES([Makefile])
|
|
||||||
AC_OUTPUT
|
|
||||||
Reference in New Issue
Block a user