forked from Imagelibrary/rtems
Update from Pedro Romano <pmcnr@camoes.rnl.ist.utl.pt>.
This commit is contained in:
@@ -1,37 +1,87 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
Joel's Note:
|
||||
+-----------------------------------------------------------------------------+
|
||||
| RTEMS 4.0.0 PC386 BSP HOWTO - 1998/04/21 |
|
||||
+-----------------------------------------------------------------------------+
|
||||
| (C) Copyright 1998 - |
|
||||
| - 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. |
|
||||
+-----------------------------------------------------------------------------+
|
||||
|
||||
This has some information which is specific to 3.6.0. Other parts of the
|
||||
document should be merged with the main RTEMS READMEs. Procedures for
|
||||
building a boot floppy, from a network server, and other information
|
||||
specific to this BSP should remain in this file.
|
||||
|
||||
-----------
|
||||
|
||||
RTEMS PC386 BSP HOWTO:
|
||||
|
||||
1. Introduction
|
||||
---------------
|
||||
|
||||
This howto tries to explain how to setup the RTEMS host
|
||||
environment on a Linux based PC so that RTEMS applications can be
|
||||
built for and run in a bare PC 386+.
|
||||
This tries to explain how to setup the RTEMS host environment so
|
||||
that RTEMS applications can be built for and run in a bare PC 386 or
|
||||
above.
|
||||
|
||||
It covers essentially the aspects of loading images, since
|
||||
information concerning other issues such as building the development
|
||||
tools and the RTEMS distribution can be found in the 'RTEMS 4.0.0
|
||||
On-Line Library' under 'Getting Started with RTEMS for C/C++ Users'.
|
||||
|
||||
Please note that everything in the following text using the
|
||||
notation '<...>' is just an alias to something and should always be
|
||||
substituted by the real thing!
|
||||
|
||||
2. Unarchiving
|
||||
|
||||
2. Building the GNU C/C++ Cross Compiler Toolset
|
||||
------------------------------------------------
|
||||
|
||||
Obtaining, building and installing the tools for building the
|
||||
PC386 BSP of RTEMS is covered in detail in the 'RTEMS 4.0.0 On-Line
|
||||
Library' -> 'Getting Started with RTEMS for C/C++ Users' -> 'Building
|
||||
the GNU C/C++ Cross Compiler Toolset'.
|
||||
|
||||
When running the 'bit' script you should use the 'i386-elf'
|
||||
configuration.
|
||||
|
||||
|
||||
4. Building RTEMS
|
||||
-----------------
|
||||
Obtaining, building and installing the tools for building the
|
||||
PC386 BSP is covered in detail in the 'RTEMS 4.0.0 On-Line Library' ->
|
||||
'Getting Started with RTEMS for C/C++ Users' -> 'Building RTEMS'.
|
||||
|
||||
When running configure, use the following values for the listed
|
||||
options:
|
||||
|
||||
--target=i386-rtems
|
||||
|
||||
--enable-rtemsbsp=pc386
|
||||
|
||||
--prefix=i386-rtems
|
||||
|
||||
|
||||
5. RTEMS Tests
|
||||
--------------
|
||||
|
||||
Files which have been "tarred, zipped" (i.e. .tar.gz or .tgz
|
||||
If you've completed the last step successfully, you'll find the
|
||||
RTEMS sample and test files that can be loaded with GRUB in the
|
||||
'<build_point>/pc386/tests' directory, RTEMS sample and test files in
|
||||
a format suitable for use with NetBoot in the
|
||||
'<build_point>/pc386/BootImgs' directory.
|
||||
|
||||
|
||||
6. Loading RTEMS PC386 applications
|
||||
-----------------------------------
|
||||
|
||||
6.1. Unarchiving
|
||||
----------------
|
||||
|
||||
Files which have been "tarred, gzipped" (i.e. .tar.gz or .tgz
|
||||
extension) may be unarchived with a command similar to one of the
|
||||
following:
|
||||
|
||||
gzcat <file>.tgz | tar xvof -
|
||||
zcat <file>.tgz | tar xvof -
|
||||
|
||||
OR
|
||||
|
||||
@@ -39,455 +89,215 @@ following:
|
||||
|
||||
OR
|
||||
|
||||
gtar xzvf <file>.tgz
|
||||
tar xzvf <file>.tgz
|
||||
|
||||
NOTE: gunzip -c is equivalent to gzcat, while gtar is GNU tar.
|
||||
NOTE: gunzip -c is equivalent to zcat. On commercial (non-Linux)
|
||||
Unices, since the GNU utilities are not the standard 'tar' will be
|
||||
gtar (GNU tar) and 'zcat' will be 'gzcat'.
|
||||
|
||||
Given that the necessary utility programs are installed, any of
|
||||
the above commands will extract the contents of <file>.tar.gz into the
|
||||
current directory. All of the RTEMS components will be extracted into
|
||||
the subdirectory rtems-3.2.0. To view the contents of a component
|
||||
without restoring any files, use a command similar to the following:
|
||||
|
||||
gzcat <file>.tgz | tar tvf -
|
||||
current directory. To view the contents of an archive without
|
||||
restoring any files, use a command similar to the following:
|
||||
|
||||
3. The building tools (gcc, binutils, et al.)
|
||||
---------------------------------------------
|
||||
zcat <file>.tgz | tar tvf -
|
||||
|
||||
The PC386 BSP was developed so that the Linux native building
|
||||
tools can be used to build the RTEMS binaries.
|
||||
|
||||
With this in mind all you have to do is check if you have gcc +
|
||||
binutils (as, ld, ar, objcopy) installed in your system (which most
|
||||
probably you'll have) and check their versions. You can do so with:
|
||||
|
||||
- 'gcc -v' (for gcc); --> version 2.7.2.1
|
||||
- 'ld -v' (for binutils). --> version 2.8.1 (with BFD linux-2.8.1.0.1)
|
||||
|
||||
The above mentioned versions of gcc and binutils are almost
|
||||
certainly guaranteed to work (their the ones we've been using). More
|
||||
recent versions should also be ok, and older versions may be ok too.
|
||||
6.2 Using GRUB to load RTEMS PC386 applications
|
||||
-----------------------------------------------
|
||||
|
||||
The only known problem is with older versions of binutils which
|
||||
still don't have a 'binary' target in 'objcopy'. We need objcopy's
|
||||
binary target to produce our final binaries (this will probably be
|
||||
enhanced in the future, so we get them directly from the 'elf32-i386'
|
||||
object, but for now this is how we do it). There's a possible
|
||||
workaround this, using older versions of 'objdump' with the flags used
|
||||
to produce the Linux kernel binary. You can investigate this in the
|
||||
Linux source makefiles. This hasn't been tested.
|
||||
Using GRUB (GRand Unified Bootloader) is the simplest way to load
|
||||
and run your PC386 BSP samples, tests and programs.
|
||||
|
||||
It should be ok to build a cross-compilation environment (gcc +
|
||||
binutils) that supports the 'elf32-i386' target, so that you can use a
|
||||
host system other than Linux. This hasn't been tested.
|
||||
You can get the latest release of GRUB from its homepage:
|
||||
|
||||
You can get 'gcc' and 'binutils', both pre-compiled binaries for
|
||||
Linux and sources from:
|
||||
- http://www.uruk.org/grub/
|
||||
|
||||
ftp://sunsite.unc.edu/pub/Linux/GCC/
|
||||
or alternatively by ftp from:
|
||||
|
||||
binutils-2.8.1.0.1.bin.tar.gz
|
||||
binutils-2.8.1.0.1.tar.gz
|
||||
gcc-2.7.2.1.bin.tar.gz
|
||||
- ftp://ftp.uruk.org/public/grub/
|
||||
|
||||
as well as from several other mirrors and sites.
|
||||
Once you obtain the .tar.gz archive 'grub-0.4.tar.gz', change to a
|
||||
temporary directory (you won't need the grub files after this and can
|
||||
just go ahead and delete the whole directory structure that was
|
||||
generated) and unarchive 'grub-0.4.tar.gz' following the instructions
|
||||
given above in [2. Unarchiving].
|
||||
|
||||
4. Creating aliases for gcc and the binutils
|
||||
--------------------------------------------
|
||||
After this is done change the directory to:
|
||||
|
||||
The NEWLIB expects to be compiled by a cross-compiler. The easiest
|
||||
(as far as we could find out) way to do this, short of changing the
|
||||
configuration files is to make symbolic links from cross-compiler
|
||||
style names (the usual names with a 'i386-elf32-rtems-' prefix) to the
|
||||
real name.
|
||||
grub-0.4/bin_std
|
||||
|
||||
You can use the following shell script to create these links
|
||||
quickly. It assumes that the native Linux 'gcc' and 'binutils' reside
|
||||
in their usual place (i.e. '/usr/bin/'). It also assumes that you're
|
||||
running it in the directory where the aliases will reside (which we
|
||||
will refer to as <elf32-tools>). You should then add <elf32-tools> to
|
||||
you path. This is necessary for building the NEWLIB package.
|
||||
and there you'll find the two files you'll need from this archive:
|
||||
'stage1' and 'stage2'.
|
||||
|
||||
--- CUT HERE --- CUT HERE --- CUT HERE --- CUT HERE --- CUT HERE ---
|
||||
You should have two (2) formatted diskettes available. One of
|
||||
these will only be used temporarily to create the other one, and we'll
|
||||
refer to it as 'RAW GRUB' diskette (you can label it accordingly if
|
||||
you wish). The other diskette, which we will refer to as 'GRUB FS'
|
||||
should be high-level formatted with one of GRUB's supported file
|
||||
systems, which are: DOS FAT, BSD FFS, and Linux ext2fs.
|
||||
|
||||
#!sh
|
||||
ln -sf /usr/bin/ar i386-elf32-rtems-ar
|
||||
ln -sf /usr/bin/as i386-elf32-rtems-as
|
||||
ln -sf /usr/bin/cpp i386-elf32-rtems-cpp
|
||||
ln -sf /usr/bin/gasp i386-elf32-rtems-gasp
|
||||
ln -sf /usr/bin/gcc i386-elf32-rtems-gcc
|
||||
ln -sf /usr/bin/ld i386-elf32-rtems-ld
|
||||
ln -sf /usr/bin/objcopy i386-elf32-rtems-objcopy
|
||||
ln -sf /usr/bin/objdump i386-elf32-rtems-objdump
|
||||
ln -sf /usr/bin/ranlib i386-elf32-rtems-ranlib
|
||||
A DOS FAT diskette can, obviously, be created under DOS with the
|
||||
'FORMAT' command. Under Linux, the following commands are available to
|
||||
add file systems to low-level formatted diskettes:
|
||||
|
||||
--- CUT HERE --- CUT HERE --- CUT HERE --- CUT HERE --- CUT HERE ---
|
||||
|
||||
5. Building Newlib
|
||||
------------------
|
||||
1. To add a DOS FAT file system to a low-level formatted diskette:
|
||||
|
||||
The next step is to build and install the NEWLIB package. The
|
||||
version we've been using and have tested is:
|
||||
a) If you have mtools installed:
|
||||
|
||||
newlib-1.7.0-posix-rtems-3.6.0.tgz
|
||||
'mformat a:'.
|
||||
|
||||
You can get it from:
|
||||
b) Assuming that you are formatting the diskette in the first
|
||||
floppy disk drive ('/dev/fd0' under Linux):
|
||||
|
||||
ftp://lancelot.gcs.redstone.army.mil/pub/rtems/releases/current/c/
|
||||
'mkdosfs /dev/fd0' or
|
||||
|
||||
After unarchiving the NEWLIB distribution (discussed earlier), the
|
||||
NEWLIB package must be configured for the desired host and target.
|
||||
'mkfs.msdos /dev/fd0'.
|
||||
|
||||
This is accomplished by changing the current directory to the top
|
||||
level of the NEWLIB source tree and executing the configure script
|
||||
with the appropriate arguments. This step configures the NEWLIB source
|
||||
for the 'i386-elf32-rtems' target configuration. The libraries and
|
||||
include files will be installed at <install_point>. The --verbose
|
||||
option to the ./configure script is recommended so you can check how
|
||||
the configuration process is progressing. Meanwhile we must do a
|
||||
little patching: 'install.sh' and 'config.sub' are missing from the
|
||||
'libgloss' sub-directory. A command sequence similar to the following
|
||||
should be used:
|
||||
2. To add a Linux ext2fs file system to a low-level formatted
|
||||
diskette, assuming that you are formatting the diskette in the
|
||||
first floppy disk drive ('/dev/fd0' under Linux):
|
||||
|
||||
cd newlib-<NEWLIB_Version>
|
||||
'mke2fs /dev/fd0' or
|
||||
|
||||
cp configure.sub libgloss
|
||||
cp install.sh libgloss
|
||||
'mkfs.ext2 /dev/fd0'.
|
||||
|
||||
CC=gcc CFLAGS="-O4 -g" ./configure --verbose \
|
||||
--target=i386-elf32-rtems \
|
||||
--prefix=<install_point>
|
||||
Next we will install using 'rawrite' or 'dd' to the 'GRUB RAW'
|
||||
diskette.
|
||||
|
||||
If the configure script successfully completes, then NEWLIB may be
|
||||
built. This step builds the NEWLIB package in the local directory and
|
||||
does NOT install any files. The example commands specifies that gcc
|
||||
should be used as the C compiler and the arguments to be used by gcc.
|
||||
NOTE: This will destroy any data currently on the diskette.
|
||||
|
||||
A command similar to the following should be used:
|
||||
Execute your OS's equivalent of (this should work for recent
|
||||
FreeBSD versions and Linux just fine):
|
||||
|
||||
make CC="gcc" CFLAGS="-O4 -g"
|
||||
dd if=stage1 of=/dev/fd0 bs=512 count=1
|
||||
dd if=stage2 of=/dev/fd0 bs=512 seek=1
|
||||
|
||||
If the build process successfully completes, then the NEWLIB
|
||||
package is ready to install. A command similar to the following should
|
||||
be used:
|
||||
Under DOS/Windows/NT, courtesy of Eric Hanchrow (erich@microsoft.com):
|
||||
|
||||
make CC="gcc" CFLAGS="-O4 -g" install
|
||||
* Use the copy /b command to binary concatenate the stage1 and
|
||||
stage2 files together via:
|
||||
|
||||
If this successfully completes, then the NEWLIB package has been
|
||||
installed at <install_point>.
|
||||
copy /b stage1 stage2 grub.raw
|
||||
|
||||
The documentation for the NEWLIB package is formatted using
|
||||
TeX. If TeX and some supporting tools are installed on the development
|
||||
system, then the following command may be used to produce the
|
||||
documentation in the "DVI" format:
|
||||
* Use rawrite.exe (which is available in many places on the net and
|
||||
in some Linux distributions) to write grub.raw to a diskette.
|
||||
|
||||
gmake CC="gcc" CFLAGS="-O4 -g" dvi
|
||||
Next stage: copy the 'stage1' and 'stage2' files to the 'GRUB FS'
|
||||
diskette (if you are using Linux you can mount the diskette in an
|
||||
appropriate mount point and then 'cp' the files to it, if it is either
|
||||
a DOS FAT or an EXT2FS diskette, or in the case of a DOS FAT diskette
|
||||
you can use 'mcopy' from 'mtools'.)
|
||||
|
||||
If while the documentation is being formatted, the message "Cross reference values unknown; you must run TeX again." is printed, then the "DVI" files generated by this command (e.g. *.dvi in every subdirectory with documentation) must be removed and the command reexecuted.
|
||||
After this is done boot a PC using the 'GRUB RAW' diskette. After
|
||||
this is done, you will get GRUB's command line interface. Exchange
|
||||
'GRUB RAW' with the 'GRUB FS' diskette in the drive and issue the
|
||||
following command from GRUB's prompt:
|
||||
|
||||
6. Modules
|
||||
----------
|
||||
install=(fd0)/stage1 (fd0) (fd0)/stage2 0x8000 (fd0)/grubmenu
|
||||
|
||||
Modules eases the process of manipulating the environment
|
||||
variables required to build RTEMS. If, for whatever reason, you do not
|
||||
wish to use Modules, then it will be necessary to manually modify
|
||||
shell initialization files and set the required RTEMS shell variables
|
||||
"manually." In this case, the Modules files are still the best place
|
||||
to look for information on what variables to set and example values.
|
||||
This command will make the 'GRUB FS' diskette bootable. After this
|
||||
is done, you won't require the 'GRUB RAW' diskette anymore and you can
|
||||
delete the 'stage1' file from the 'GRUB FS' diskette.
|
||||
|
||||
The Modules package was utilized by the RTEMS developers to make
|
||||
the initialization process shell independent. The Modules files used
|
||||
by the RTEMS developers to configure their user environment while
|
||||
working on a particular target board are included in the
|
||||
distribution. These require only simple modifications to be
|
||||
"localized" for the RTEMS developer. The modifications to these ASCII
|
||||
files can be made with an editor such as vi or emacs.
|
||||
Next copy all the files you wish to load to the diskette. The GRUB
|
||||
loadable test and sample files in the RTEMS distribution have '.exe'
|
||||
extension and can be found under the build point in the 'pc386/tests'
|
||||
directory. You can compress this files with gzip to save space if you
|
||||
wish. GRUB loads 'gzipped' files transparently.
|
||||
|
||||
The Modules Homepage is:
|
||||
Finally you have to create a GRUB menu configuration file. We will
|
||||
call this file 'grubmenu'. You can call it anything as long as you use
|
||||
the correct name in the 'install' command where we used 'grubmenu'.
|
||||
|
||||
http://www.modules.org/
|
||||
The 'grubmenu' file, as far as we are interested has the following
|
||||
syntax:
|
||||
|
||||
You can get the Modules distribution (the latest version, which
|
||||
we've been using, is '3.0pre') via the homepage or directly from:
|
||||
title= Hello World Test
|
||||
kernel= (fd0)/hello.exe.gz
|
||||
|
||||
ftp://ftp.modules.org/pub/distrib/Modules-3.0pre.tar.gz
|
||||
You can add as many of this entries as you want to the 'grubmenu'
|
||||
file. There should be one for each program you wish to load. The
|
||||
'title=' line provides a description for the program that will appear
|
||||
after boot in the GRUB menu for the user to choose and the 'kernel='
|
||||
line describes where the file can be found by GRUB (you should leave
|
||||
the '(fd0)/' part and just substitute the rest if you've copied the
|
||||
files to the root directory of the diskette.
|
||||
|
||||
Just boot the PC with the 'GRUB FS' diskette and you will be able
|
||||
to choose which program you want to load from GRUB's menu.
|
||||
|
||||
6.1. New Modules users
|
||||
----------------------
|
||||
The GRUB documentation is available in HTML format in the 'docs'
|
||||
directory of the GRUB tree starting with the 'index.html' file.
|
||||
|
||||
Install Modules on the development system following the
|
||||
instructions in the file README in the main Modules directory. When
|
||||
Modules has been installed and a user account setup to use Modules,
|
||||
then proceed to the section Current Modules Users.
|
||||
|
||||
6.2. Current Modules users
|
||||
--------------------------
|
||||
6.3 Using NetBoot to load RTEMS PC386 applications
|
||||
---------------------------------------------------
|
||||
|
||||
If the host computer already utilizes the Modules package, then
|
||||
the assistance of the system administrator responsible for the Modules
|
||||
package will be required to perform the modifications described below.
|
||||
|
||||
The system administrator must integrate the RTEMS modules into the
|
||||
existing Modules configuration. A first alternative is to copy all of
|
||||
the module files provided with RTEMS into an existing modulefiles
|
||||
directory. This requires that future updates of RTEMS modules will
|
||||
also have to be integrated into the existing modulefiles
|
||||
directory. This alternative is not recommended.
|
||||
|
||||
The more preferable alternative is to add the RTEMS modulefiles
|
||||
directory to the MODULEPATH. This can be accomplished on an individual
|
||||
user or system wide basis. For individual users, the RTEMS modules
|
||||
directory can be added to the MODULEPATH of those users requiring
|
||||
access to RTEMS. The default MODULEPATH is established by the Modules
|
||||
initialization routine. Thus, the RTEMS modules directory must be
|
||||
added to the MODULEPATH in the user's shell initialization file
|
||||
(~/.profile or ~/.cshrc for example) following the Modules
|
||||
initialization statement. The proper way to accomplish this is to use
|
||||
the Modules use statement. For example, the following line should be
|
||||
added to the user's shell initialization file:
|
||||
|
||||
module use <rtems_path>/modules/modulefiles
|
||||
|
||||
For system wide access, the RTEMS modulefiles directory can be
|
||||
added to each of the shell initialization scripts in the existing
|
||||
Modules package. This will require modifying the initialization of
|
||||
MODULEPATH in each shell initialization file.
|
||||
|
||||
After integrating RTEMS modules with the existing modules, one may
|
||||
proceed to the Configuring An RTEMS User section.
|
||||
|
||||
7. RTEMS
|
||||
--------
|
||||
|
||||
You can get the latest free release of the C distribuition of
|
||||
RTEMS (version 3.6.0), from:
|
||||
|
||||
ftp://lancelot.gcs.redstone.army.mil/pub/rtems/releases/current/c/
|
||||
|
||||
Where you'll find:
|
||||
|
||||
rtems-3.6.0.tgz or rtems-c_src.tgz - RTEMS sources;
|
||||
|
||||
rtems-3.5.1-c_doc.tgz or rtems-c_doc.tgz - RTEMS documentation;
|
||||
|
||||
individual_manuals/ - Sub-directory where you can get the
|
||||
manuals individually.
|
||||
|
||||
Please note that the RTEMS documentation is slightly outdated
|
||||
(most noticeably some RTEMS primitives have different protoypes) since
|
||||
it refers to the previous release (3.5.1.) of RTEMS.
|
||||
|
||||
After unarchiving the RTEMS distribution (discussed earlier), it
|
||||
is necessary to add the PC386 BSP to the source tree. This is done in
|
||||
two steps.
|
||||
|
||||
The first step consists in unarchiving the
|
||||
'rtems-3.6.0-PC386-BSP.tgz' archive over the standard rtems-3.6.0
|
||||
distribution. It should be done in the same directory where
|
||||
'rtems-3.6.0.tgz' was unarchived.
|
||||
|
||||
Next you'll need to apply the patch in
|
||||
'rtems-3.6.0-PC386-BSP.diff.gz' to the RTEMS source tree. The
|
||||
following command should be used:
|
||||
|
||||
gzip -d -c rtems-3.6.0-PC386-BSP.diff.gz | patch
|
||||
|
||||
also from the same directory where 'rtems-3.6.0.tgz' was unarchived.
|
||||
|
||||
At this stage we have RTEMS + PC386 BSP, the user environment must
|
||||
be setup to build and install RTEMS.
|
||||
|
||||
Using this process, you'll know which files are patched and which
|
||||
files are new.
|
||||
|
||||
7.1. Board Support Package
|
||||
--------------------------
|
||||
|
||||
A Board Support Package (BSP) is a collection of device drivers,
|
||||
initialization code, and linker scripts necessary to execute RTEMS on
|
||||
a particular target board. The minimum set of device drivers for a
|
||||
single processor target includes a Clock, Console I/O, and Benchmark
|
||||
Timer device drivers.
|
||||
|
||||
The source code for the PC386 BSP can be found in the directory 'c/src/lib/libbsp/i386/pc386.
|
||||
|
||||
7.2. Makefile Configuration Files
|
||||
---------------------------------
|
||||
|
||||
There are two target specific configuration files used by the
|
||||
Makefile system. These configuration files specify detailed
|
||||
information about the toolset, the compilation process, as well as
|
||||
some general configuration information regarding the target and the
|
||||
development environment. The following is a list of these
|
||||
configuration files:
|
||||
|
||||
c/make/compilers/gcc-pc386.cfg
|
||||
|
||||
c/make/custom/pc386.cfg
|
||||
|
||||
If you're compiling to a i386+ with FPU in a standard Linux
|
||||
environment, you shouldn't require any changes to these files in order
|
||||
to build RTEMS (though you'll probably want to fine tune them later
|
||||
on).
|
||||
|
||||
7.3 Creating a Customized Modules File
|
||||
--------------------------------------
|
||||
|
||||
Files which the Modules packages may use to customize a user's
|
||||
environment for building, installing, and modifying RTEMS are found in
|
||||
the c/Modules/rtems directory. Each of the files in this directory
|
||||
corresponds to the configuration used by the RTEMS developers for
|
||||
building and installing RTEMS for a particular target board. These
|
||||
files contain the Modules commands necessary to set the following
|
||||
environment variables:
|
||||
|
||||
Variable Description
|
||||
|
||||
RTEMS_BSP The name of the target BSP (e.g.
|
||||
mvme136 or cvme961).
|
||||
|
||||
RTEMS_ROOT The full path of root directory of the
|
||||
RTEMS source code.
|
||||
|
||||
RTEMS_GNUTOOLS The full path of the root directory for
|
||||
the cross-development toolset to be
|
||||
used.
|
||||
|
||||
RTEMS_HOST The name of the operating system for
|
||||
the development system.
|
||||
|
||||
RTEMS_LIBC_DIR The full path of the root directory for
|
||||
the Standard C Library to be used.
|
||||
|
||||
|
||||
The Modules file for the PC386 BSP is: 'c/Modules/rtems/nav-pc386'.
|
||||
|
||||
You MUST edit this file and set the following variables to the
|
||||
correct values in your system:
|
||||
|
||||
- RTEMS_ROOT;
|
||||
- RTEMS_GNUTOOLS (this is the directory where the links in 4.
|
||||
were created);
|
||||
- RTEMS_LIBC_DIR (this is the directory where the Newlib target
|
||||
specific root is installed, and with reference
|
||||
to 5. should be '<install_point>/i386-elf32-rtems').
|
||||
|
||||
7.4 Configuring an RTEMS User Using Modules
|
||||
-------------------------------------------
|
||||
|
||||
Each user building and installing RTEMS must have their
|
||||
environment configured. The user environment must have a set of
|
||||
variables set in it which indicate the target BSP, host operating
|
||||
system, and numerous paths.
|
||||
|
||||
If you'll just be using the PC386 BSP then a line of the following
|
||||
type may be added to the initialization file for your shell after the
|
||||
Modules initialization statement.
|
||||
|
||||
module load nav-pc386
|
||||
|
||||
Note that you must logout and login before any changes to the shell
|
||||
initialization files will take effect.
|
||||
|
||||
If you don't wish the RTEMS environment configuration to be added
|
||||
to your shell initialization file, then the "module load" statement
|
||||
may be entered at the command line.
|
||||
|
||||
You may switch from one RTEMS configuration to another with either
|
||||
of the following command sequences:
|
||||
|
||||
module unload <old_rtems_modulefile>
|
||||
module load <new_rtems_modulefile>
|
||||
|
||||
OR
|
||||
|
||||
module switch <old_rtems_modulefile> <new_rtems_modulefile>
|
||||
|
||||
The command "module avail" may be used to obtain a list of the
|
||||
Module files which are available to be loaded using the "module load"
|
||||
command.
|
||||
|
||||
The command "module list" provides a list of the currently loaded
|
||||
Modules.
|
||||
|
||||
7.5. Building RTEMS
|
||||
-------------------
|
||||
|
||||
See the file README.configure in the top level directory for
|
||||
more information.
|
||||
|
||||
|
||||
8. RTEMS Tests
|
||||
--------------
|
||||
|
||||
If you've completed the last step successfully, you'll find the
|
||||
RTEMS sample and test files in the 'c/pc386_i386/tests' directory.
|
||||
|
||||
The 'sp*.bt' are the single processor tests and should all work
|
||||
correctly. The same applies to the 'tm*.bt' which are the timing
|
||||
tests.
|
||||
|
||||
The other sample ('*.bt') files should also work with the
|
||||
exception of 'spfatal.bt' and 'stackchk.bt' (see 9.).
|
||||
|
||||
8.1 Using Diskboot or NetBoot
|
||||
------------------------------
|
||||
To load the '*.bt' files you can either run the 'diskboot.exe'
|
||||
(which can be found in 'c/pc386_i386/build-tools') under DOS with a
|
||||
command line like (this is just a quick and dirty loader - you'll have
|
||||
to press return twice after entering it):
|
||||
|
||||
diskboot sp01.bt
|
||||
To load the '*.bt' files you can
|
||||
|
||||
Alternatively, if you have a PC connected to a network with a
|
||||
BOOTP server and a TFTP server (this can very well be you're Linux
|
||||
RTEMS host system), you can use Gero Kuhlmann's netboot loader, to
|
||||
RTEMS host system), you can use Gero Kuhlmann's NetBoot loader, to
|
||||
load RTEMS to a diskless PC across a network. You can get it from:
|
||||
|
||||
ftp://sunsite.unc.edu/pub/Linux/system/boot/netboot-0.7.2.tar.gz
|
||||
ftp://sunsite.unc.edu/pub/Linux/system/boot/netboot-0.7.3.tar.gz
|
||||
|
||||
Follow the instructions contained in the package to setup the
|
||||
or in any of Sunsite's mirrors. It is also available from NetBoot's
|
||||
homepage:
|
||||
|
||||
http://www.han.de/~gero/netboot
|
||||
|
||||
After unarchiving 'netboot-0.7.3.tar.gz' you should change to the
|
||||
base directory of this and run:
|
||||
|
||||
./configure --disable-mknbi-dos --disable-mknbi-linux --disable-mknbi-mgl
|
||||
|
||||
Afterwards, you should follow the instructions contained in the
|
||||
'INSTALL' file also contained in the base directory, on how to setup the
|
||||
server(s) and to build a boot ROM for the client PC network card, or a
|
||||
boot diskette, and the client should be able to load the '*.bt' files
|
||||
boot diskette, and the PC client should be able to load the '*.bt' files
|
||||
from the server.
|
||||
|
||||
For the network loader every relocation address from 0x10200 to
|
||||
0x80200 are known to work correctly. For the DOS loader, relocation
|
||||
addresses 0x20200, 0x40200 and 0x80200 are known to work under DOS
|
||||
5.00, DOS 6.xx and DOS 7.00. You can set the relocation address in
|
||||
'c/make/compilers/gcc-pc386.cfg' by setting the value of the
|
||||
'RELOCADDR' variable.
|
||||
The important sections to check in the 'INSTALL FILE' are the last two:
|
||||
|
||||
8.2 Using GRUB
|
||||
---------------
|
||||
- Setup of the server (only the BOOTP and TFTP parts - ignore NFS).
|
||||
===================
|
||||
|
||||
GRUB is another boot loader which may be used with pc386. It is
|
||||
available from:
|
||||
- Setup of the client including building the bootrom
|
||||
==================================================
|
||||
|
||||
ftp://ftp.uruk.org/public/grub/
|
||||
http://www.uruk.org/grub/
|
||||
all the rest can be safely ignored if you don't care to examine it.
|
||||
|
||||
|
||||
9. Important Notes
|
||||
------------------
|
||||
7. Technical Information
|
||||
------------------------
|
||||
|
||||
The optional stack checker extension ('stackchk') doesn't seem to
|
||||
be working properly. It reports blown task stacks even if everything
|
||||
seems to work properly when 'stackchk' isn't activated... This should
|
||||
be properly investigated: the problem can reside with the 'PC386 BSP',
|
||||
or in the interface between 'stackchk' and the BSP (maybe something
|
||||
isn't being correctly initialized...). Since this doesn't seem to be a
|
||||
serious BSP problem, it hasn't been dealt with, due to more prioritary
|
||||
problems.
|
||||
NOTE: All the following paths are relative to the base directory
|
||||
of the RTEMS distribution.
|
||||
|
||||
The tests which exercise the fatal error mecanisms don't work
|
||||
correctly either. I've been told by Joe that 'spfatal' is outdated, and
|
||||
so this really isn't surprising.
|
||||
As of the writing of this HOWTO, PC386 images can be loaded either
|
||||
in low memory 0x10000 (64KB) until 0x97C00 (607K) using NetBoot or in
|
||||
high memory from 0x100000 (1024KB) until the top of the available
|
||||
memory using either NetBoot or GRUB.
|
||||
|
||||
This issues may be important and should be investigated as soon as
|
||||
possible.
|
||||
If you want to change the default loading address from 1024KB to
|
||||
something else, just change the value of the variable RELOCADDR in the
|
||||
'make/custom/pc386.cfg' file to the new value you want (make sure you
|
||||
follow the instructions indicated before the definition of RELOCADDR).
|
||||
|
||||
Remember that GRUB restricts the loading addresses to values above
|
||||
0x100000 (1024KB), only NetBoot can load images in low memory.
|
||||
|
||||
After you make any changes to RELOCADDR and if you are using
|
||||
NetLoader, you'll have to recompile the
|
||||
'c/src/lib/libbsp/i386/pc386/start/start16.s' file. The easiest way to
|
||||
achieve this is just to 'make clean' and the 'make all' again. The
|
||||
quickest way is to change to
|
||||
'<build_point>/c/src/lib/libbsp/i386/pc386/start' and 'make
|
||||
RTEMS_BSP=pc386 clean all'.
|
||||
|
||||
When programming interrupt handlers take into account that the PIC
|
||||
is reprogrammed and so you should use the interface functions provided
|
||||
to garantee that everything works ok.
|
||||
in '<build_point>/pc386/lib/include/irq.h> to guarantee that everything
|
||||
works ok.
|
||||
|
||||
@@ -19,5 +19,5 @@
|
||||
%{qrtems_debug: start_g.o%s}}
|
||||
|
||||
*link:
|
||||
%{!qrtems: %(old_link)} %{qrtems: -dc -dp -N -e start}
|
||||
%{!qrtems: %(old_link)} %{qrtems: -dc -dp -N -e start --oformat=elf32-i386}
|
||||
|
||||
|
||||
@@ -232,6 +232,10 @@ _IBMPC_keyboard_isr(rtems_vector_number vector)
|
||||
rtems_boolean
|
||||
_IBMPC_chrdy(char *c)
|
||||
{
|
||||
/* FIX ME!!! It doesn't work without something like the following line.
|
||||
Find out why! */
|
||||
printk("");
|
||||
|
||||
/* Check buffer our ISR builds */
|
||||
if (kbd_first != kbd_last)
|
||||
{
|
||||
|
||||
@@ -52,18 +52,6 @@ extern "C" {
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Memory related constants.
|
||||
+--------------------------------------------------------------------------*/
|
||||
#ifdef RTEMS_SMALL_MEMORY /* We only have low (640K) memory. */
|
||||
|
||||
#define RAM_START 0x00000
|
||||
#define RAM_END 0xA0000
|
||||
|
||||
#else /* We have at least 2048K of memory. */
|
||||
|
||||
#define RAM_START 0x100000
|
||||
#define RAM_END 0x200000
|
||||
|
||||
#endif /* RTEMS_SMALL_MEMORY */
|
||||
|
||||
#define HEAP_SIZE 64 /* Size of libc Heap (used for malloc et al) in KBytes. */
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
|
||||
@@ -8,7 +8,7 @@ VPATH = @srcdir@
|
||||
RTEMS_ROOT = @top_srcdir@
|
||||
PROJECT_ROOT = @PROJECT_ROOT@
|
||||
|
||||
PGMS=${ARCH}/start.o
|
||||
PGMS=${ARCH}/start.o ${ARCH}/start16.bin
|
||||
|
||||
# C source names, if any, go here -- minus the .c
|
||||
C_PIECES=
|
||||
@@ -18,7 +18,7 @@ C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
|
||||
H_FILES=
|
||||
|
||||
# Assembly source names, if any, go here -- minus the .s
|
||||
S_PIECES=start
|
||||
S_PIECES=start16 start
|
||||
S_FILES=$(S_PIECES:%=%.s)
|
||||
S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o)
|
||||
|
||||
@@ -50,8 +50,21 @@ LDFLAGS +=
|
||||
CLEAN_ADDITIONS +=
|
||||
CLOBBER_ADDITIONS +=
|
||||
|
||||
all: ${ARCH} $(SRCS) $(OBJS) $(PGM)
|
||||
all: ${ARCH} $(SRCS) $(OBJS) $(PGMS)
|
||||
$(INSTALL_VARIANT) -m 555 ${PGMS} ${PROJECT_RELEASE}/lib
|
||||
|
||||
# Install the program(s), appending _g or _p as appropriate.
|
||||
# for include files, just use $(INSTALL)
|
||||
|
||||
LINKCMDS=$(srcdir)/../startup/linkcmds
|
||||
|
||||
${ARCH}/start16.o: start16.s
|
||||
sed -e 's/\/\/.*$$//' < $< | $(CPP) $(ASMFLAGS) -I. -I$(srcdir) \
|
||||
-DASM -DSTART32ADDR=$(RELOCADDR) - > $*.i
|
||||
$(AS) $(ASFLAGS) -o $@ $*.i
|
||||
|
||||
${ARCH}/start16.bin: ${ARCH}/start16.o
|
||||
$(LD) -N -T $(LINKCMDS) -Ttext $(START16ADDR) -e start16 -nostdlib \
|
||||
--oformat=elf32-i386 -o $(basename $@).obj $(basename $@).o
|
||||
$(OBJCOPY) -O binary $(basename $@).obj $@
|
||||
|
||||
|
||||
@@ -30,26 +30,12 @@
|
||||
| * http://www.OARcorp.com/rtems/license.html.
|
||||
| **************************************************************************
|
||||
|
|
||||
| Also based on (from the Linux source tree):
|
||||
| video.S - Copyright (C) 1995, 1996 Martin Mares <mj@k332.feld.cvut.cz>
|
||||
|
|
||||
| $Id$
|
||||
+--------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "asm.h"
|
||||
|
||||
/*----------------------------------------------------------------------------+
|
||||
| Constants
|
||||
+----------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef pc386
|
||||
|
||||
.set PROT_CODE_SEG, 0x08 # offset of code segment descriptor into GDT
|
||||
.set CR0_PE, 1 # protected mode flag on CR0 register
|
||||
|
||||
#endif /* pc386 */
|
||||
|
||||
/*----------------------------------------------------------------------------+
|
||||
| A Descriptor table register has the following format:
|
||||
+----------------------------------------------------------------------------*/
|
||||
@@ -58,6 +44,13 @@
|
||||
.set DTR_BASE, 2 # offset of four byte base address
|
||||
.set DTR_SIZE, 6 # size of DTR register
|
||||
|
||||
/*----------------------------------------------------------------------------+
|
||||
| Size of heap and stack:
|
||||
+----------------------------------------------------------------------------*/
|
||||
|
||||
.set HEAP_SIZE, 0x2000
|
||||
.set STACK_SIZE, 0x1000
|
||||
|
||||
/*----------------------------------------------------------------------------+
|
||||
| CODE section
|
||||
+----------------------------------------------------------------------------*/
|
||||
@@ -72,65 +65,9 @@ BEGIN_CODE
|
||||
|
||||
SYM (start):
|
||||
|
||||
/*----------------------------------------------------------------------------+
|
||||
| Switch VGA video to 80 lines x 50 columns mode. Has to be done before turning
|
||||
| protected mode on since it uses BIOS int 10h (video) services.
|
||||
+----------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(pc386) && defined(RTEMS_VIDEO_80x50)
|
||||
|
||||
.code16
|
||||
|
||||
movw $0x0003, ax # forced set
|
||||
int $0x10
|
||||
movw $0x1112, ax # use 8x8 font
|
||||
xorb %bl, %bl
|
||||
int $0x10
|
||||
movw $0x1201, ax # turn off cursor emulation
|
||||
movb $0x34, %bl
|
||||
int $0x10
|
||||
movb $0x01, ah # define cursor (scan lines 0 to 7)
|
||||
movw $0x0007, cx
|
||||
int $0x10
|
||||
|
||||
.code32
|
||||
|
||||
#endif /* pc386 && RTEMS_VIDEO_80x50 */
|
||||
|
||||
nop
|
||||
cli # DISABLE INTERRUPTS!!!
|
||||
|
||||
/*----------------------------------------------------------------------------+
|
||||
| Bare PC machines boot in real mode! We have to turn protected mode on.
|
||||
+----------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef pc386
|
||||
|
||||
data16
|
||||
movl $ SYM(gdtptr), eax
|
||||
data16
|
||||
andl $0x0000ffff, eax # get offset into segment
|
||||
addr16
|
||||
lgdt cs:(eax) # load Global Descriptor Table
|
||||
data16
|
||||
movl $ SYM(idtptr), eax
|
||||
data16
|
||||
andl $0x0000ffff, eax # get offset into segment
|
||||
addr16
|
||||
lidt cs:(eax) # load Interrupt Descriptor Table
|
||||
|
||||
movl %cr0, eax
|
||||
data16
|
||||
orl $CR0_PE, eax
|
||||
movl eax, %cr0 # turn on protected mode
|
||||
|
||||
data16
|
||||
ljmp $PROT_CODE_SEG, $ SYM(next) # flush prefetch queue
|
||||
|
||||
SYM(next):
|
||||
|
||||
#endif /* pc386 */
|
||||
|
||||
/*----------------------------------------------------------------------------+
|
||||
| Load the segment registers (this is done by the board's BSP) and perform any
|
||||
| other board specific initialization procedures.
|
||||
@@ -149,9 +86,9 @@ SYM(next):
|
||||
SYM (_establish_stack):
|
||||
|
||||
movl $_end, eax # eax = end of bss/start of heap
|
||||
addl $heap_size, eax # eax = end of heap
|
||||
addl $HEAP_SIZE, eax # eax = end of heap
|
||||
movl eax, stack_start # Save for brk() routine
|
||||
addl $stack_size, eax # make room for stack
|
||||
addl $STACK_SIZE, eax # make room for stack
|
||||
andl $0xffffffc0, eax # align it on 16 byte boundary
|
||||
movl eax, esp # set stack pointer
|
||||
movl eax, ebp # set base pointer
|
||||
@@ -262,6 +199,7 @@ SYM (no_gdt_load):
|
||||
cmpb $0, SYM (_Do_Load_IDT) # Should the new IDT be loaded?
|
||||
je SYM (no_idt_load) # NO, then branch
|
||||
lidt SYM (_New_IDTR) # load the new IDT
|
||||
|
||||
SYM (no_idt_load):
|
||||
|
||||
/*---------------------------------------------------------------------+
|
||||
@@ -315,41 +253,6 @@ END_CODE
|
||||
|
||||
BEGIN_DATA
|
||||
|
||||
#ifdef pc386
|
||||
|
||||
/**************************
|
||||
* GLOBAL DESCRIPTOR TABLE *
|
||||
**************************/
|
||||
|
||||
.align 4
|
||||
SYM(gdtptr):
|
||||
/* we use the NULL descriptor to store the GDT pointer - a trick quite
|
||||
nifty due to: Robert Collins (rcollins@x86.org) */
|
||||
.word gdtlen - 1
|
||||
.long gdtptr
|
||||
.word 0x0000
|
||||
|
||||
/* code segment */
|
||||
.word 0xffff, 0
|
||||
.byte 0, 0x9f, 0xcf, 0
|
||||
|
||||
/* data segment */
|
||||
.word 0xffff, 0
|
||||
.byte 0, 0x93, 0xcf, 0
|
||||
|
||||
.set gdtlen, . - gdtptr # length of GDT
|
||||
|
||||
/*************************************
|
||||
* INTERRUPT DESCRIPTOR TABLE POINTER *
|
||||
*************************************/
|
||||
|
||||
.align 4
|
||||
SYM(idtptr):
|
||||
.word 0x07ff # limit at maximum (allows all 256 interrupts)
|
||||
.word 0, 0 # base at 0
|
||||
|
||||
#endif /* pc386 */
|
||||
|
||||
EXTERN (Do_Load_IDT) # defined in the BSP
|
||||
EXTERN (Do_Load_GDT) # defined in the BSP
|
||||
|
||||
@@ -370,11 +273,13 @@ END_DATA
|
||||
|
||||
BEGIN_BSS
|
||||
|
||||
PUBLIC (heap_size)
|
||||
.set heap_size, 0x2000
|
||||
PUBLIC (_heap_size)
|
||||
SYM (_heap_size):
|
||||
.long HEAP_SIZE
|
||||
|
||||
PUBLIC (stack_size)
|
||||
.set stack_size, 0x1000
|
||||
PUBLIC (_stack_size)
|
||||
SYM (_stack_size):
|
||||
.long STACK_SIZE
|
||||
|
||||
PUBLIC (Interrupt_descriptor_table)
|
||||
SYM (Interrupt_descriptor_table):
|
||||
@@ -390,14 +295,8 @@ SYM (_New_IDTR):
|
||||
|
||||
PUBLIC (_Global_descriptor_table)
|
||||
SYM (_Global_descriptor_table):
|
||||
#ifdef pc386
|
||||
|
||||
.space (3 * 8) # the PC386 bsp only needs 3 segment descriptors:
|
||||
#else # NULL, CODE and DATA
|
||||
.space (8192 * 8)
|
||||
|
||||
#endif /* pc386 */
|
||||
|
||||
# NULL, CODE and DATA
|
||||
PUBLIC (_Original_GDTR)
|
||||
SYM (_Original_GDTR):
|
||||
.space DTR_SIZE
|
||||
|
||||
@@ -41,16 +41,13 @@
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Global Variables
|
||||
+--------------------------------------------------------------------------*/
|
||||
#ifdef RTEMS_SMALL_MEMORY
|
||||
extern rtems_unsigned32 _end; /* End of BSS. Defined in 'linkcmds'. */
|
||||
extern rtems_unsigned32 _heap_size; /* Size of stack. Defined in 'start.s'. */
|
||||
extern rtems_unsigned32 _stack_size; /* Size of heap. Defined in 'start.s'. */
|
||||
|
||||
rtems_unsigned32 rtemsFreeMemStart = (rtems_unsigned32)&_end;
|
||||
rtems_unsigned32 rtemsFreeMemStart;
|
||||
/* Address of start of free memory - should be updated
|
||||
after creating new partitions or regions. */
|
||||
#else
|
||||
rtems_unsigned32 rtemsFreeMemStart = RAM_START;
|
||||
/* RAM_START defined in 'bsp.h'. */
|
||||
#endif /* RTEMS_SMALL_MEMORY */
|
||||
|
||||
/* The original BSP configuration table from the application and our copy of it
|
||||
with some changes. */
|
||||
@@ -105,6 +102,9 @@ void bsp_pretasking_hook(void)
|
||||
+--------------------------------------------------------------------------*/
|
||||
void bsp_start( void )
|
||||
{
|
||||
rtemsFreeMemStart = (rtems_unsigned32)&_end + _heap_size + _stack_size;
|
||||
/* set the value of start of free memory. */
|
||||
|
||||
/* If we don't have command line arguments set default program name. */
|
||||
|
||||
Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
|
||||
@@ -118,8 +118,11 @@ void bsp_start( void )
|
||||
Cpu_table.interrupt_stack_size = 4096;
|
||||
Cpu_table.extra_mpci_receive_server_stack = 0;
|
||||
|
||||
/* Place RTEMS workspace at top of physical RAM (RAM_END defined in 'bsp.h' */
|
||||
/* Place RTEMS workspace at beginning of free memory. */
|
||||
|
||||
BSP_Configuration.work_space_start =
|
||||
(void *)(RAM_END - BSP_Configuration.work_space_size);
|
||||
if (rtemsFreeMemStart & (CPU_ALIGNMENT - 1)) /* not aligned => align it */
|
||||
rtemsFreeMemStart = (rtemsFreeMemStart+CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1);
|
||||
|
||||
BSP_Configuration.work_space_start = (void *)rtemsFreeMemStart;
|
||||
rtemsFreeMemStart += BSP_Configuration.work_space_size;
|
||||
} /* bsp_start */
|
||||
|
||||
@@ -68,27 +68,6 @@ BEGIN_CODE
|
||||
|
||||
EXTERN (establish_stack)
|
||||
|
||||
/*----------------------------------------------------------------------------+
|
||||
| empty_8042
|
||||
+------------------------------------------------------------------------------
|
||||
| This routine checks that the keyboard command queue is empty (after emptying
|
||||
| the output buffers).
|
||||
| No timeout is used - if this hangs there is something wrong with the machine,
|
||||
| and we probably couldn't proceed anyway.
|
||||
+----------------------------------------------------------------------------*/
|
||||
SYM(empty_8042):
|
||||
call delay
|
||||
inb $0x64, al # 8042 status port
|
||||
testb $0x01, al # output buffer?
|
||||
jz SYM(no_output)
|
||||
call SYM(delay)
|
||||
in $0x60, al # read it
|
||||
jmp SYM(empty_8042)
|
||||
SYM(no_output):
|
||||
test $0x02, al # is input buffer full?
|
||||
jnz SYM(empty_8042) # yes - loop
|
||||
ret
|
||||
|
||||
/*----------------------------------------------------------------------------+
|
||||
| delay
|
||||
+------------------------------------------------------------------------------
|
||||
@@ -100,8 +79,8 @@ SYM(delay):
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Function: _load_segments
|
||||
| Description: Load board segment registers with apropriate values + enable
|
||||
A20 line + reprogram PIC.
|
||||
| Description: Load board segment registers with apropriate values +
|
||||
| reprogram PIC.
|
||||
| Global Variables: None.
|
||||
| Arguments: None.
|
||||
| Returns: Nothing.
|
||||
@@ -115,18 +94,6 @@ SYM (_load_segments):
|
||||
LOAD_SEGMENTS(RESET_FS, fs)
|
||||
LOAD_SEGMENTS(RESET_GS, gs)
|
||||
|
||||
/*---------------------------------------------------------------------+
|
||||
| we have to enable A20 in order to access memory above 1MByte
|
||||
+---------------------------------------------------------------------*/
|
||||
|
||||
call SYM(empty_8042)
|
||||
movb $0xD1, al # command write
|
||||
outb al, $0x64
|
||||
call SYM(empty_8042)
|
||||
movb $0xDF, al # A20 on
|
||||
outb al, $0x60
|
||||
call SYM(empty_8042)
|
||||
|
||||
/*---------------------------------------------------------------------+
|
||||
| Now we have to reprogram the interrupts :-(. We put them right after
|
||||
| the intel-reserved hardware interrupts, at int 0x20-0x2F. There they
|
||||
|
||||
@@ -22,11 +22,14 @@ VPATH=@srcdir@
|
||||
USE_HOST_COMPILER=yes
|
||||
|
||||
# C source names, if any, go here -- minus the .c
|
||||
C_PIECES=bin2boot
|
||||
C_PIECES=
|
||||
CC_PIECES=bin2boot Header Image
|
||||
C_FILES=$(C_PIECES:%=%.c)
|
||||
CC_FILES=$(CC_PIECES:%=%.cc)
|
||||
C_O_FILES=$(C_PIECES:%=$(ARCH)/%.o)
|
||||
CC_O_FILES=$(CC_PIECES:%=$(ARCH)/%.o)
|
||||
|
||||
H_FILES=
|
||||
H_FILES=bytetype.h Header.h Image.h
|
||||
|
||||
SRCS=$(C_FILES) $(CC_FILES) $(H_FILES)
|
||||
OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
|
||||
@@ -43,10 +46,11 @@ include $(RTEMS_ROOT)/make/leaf.cfg
|
||||
DEFINES +=
|
||||
CPPFLAGS +=
|
||||
CFLAGS +=
|
||||
CXXFLAGS += -g -Wall
|
||||
|
||||
LD_PATHS +=
|
||||
LD_LIBS +=
|
||||
LDFLAGS +=
|
||||
LD_LIBS += -lstdc++
|
||||
LDFLAGS += -g
|
||||
|
||||
#
|
||||
# Add your list of files to delete here. The config files
|
||||
@@ -60,5 +64,10 @@ CLOBBER_ADDITIONS +=
|
||||
|
||||
all: $(ARCH) $(SRCS) $(PGMS)
|
||||
$(INSTALL) -m 555 $(PGMS) ${PROJECT_RELEASE}/build-tools
|
||||
uudecode < $(srcdir)/diskboot.uue \
|
||||
> $(PROJECT_RELEASE)/build-tools/diskboot.exe
|
||||
|
||||
$(ARCH)/bin2boot: $(OBJS)
|
||||
$(CC) $(LDFLAGS) $^ -o $@ $(LD_LIBS)
|
||||
$(ARCH)/bin2boot.o : bin2boot.cc Header.h Image.h bytetype.h
|
||||
$(ARCH)/Header.o: Header.cc Header.h bytetype.h
|
||||
$(ARCH)/Image.o: Image.cc Image.h bytetype.h
|
||||
|
||||
|
||||
@@ -1,241 +0,0 @@
|
||||
/*-------------------------------------------------------------------------+
|
||||
| bin2boot.c v1.1 - PC386 BSP - 1997/08/18
|
||||
+--------------------------------------------------------------------------+
|
||||
| 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.
|
||||
|
|
||||
| $Id$
|
||||
+--------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "bytetype.h"
|
||||
#include "bootimg.h"
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Constants
|
||||
+--------------------------------------------------------------------------*/
|
||||
#define SEG_MASK 0xffff0000
|
||||
/* Mask for segment part of seg:off address. */
|
||||
#define OFF_MASK 0x0000ffff
|
||||
/* Mask for offset part of seg:off address. */
|
||||
#define DEFAULT_START_ADDR 0x10200 /* Default start address for binary. */
|
||||
#define BOOTIMG_HDR_SIZE 0x0200 /* Size of output file header. */
|
||||
#define BUFFER_BLOCK_SIZE 0x1000 /* Size of transfer buffer size. */
|
||||
#define LAST_BLOCK_SIZE 0x0200
|
||||
/* The output file must have a size multiple of this value. */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Macros
|
||||
+--------------------------------------------------------------------------*/
|
||||
#define getSeg(x) (Word)((x) >> 16)
|
||||
/* Return seg part (Word) of a seg:off address (DWord). */
|
||||
|
||||
#define getOff(x) (Word)((x) & OFF_MASK)
|
||||
/* Return off part (Word) of a seg:off address (DWord). */
|
||||
|
||||
#define getSegOff(x) ((((x) & SEG_MASK) << 12) + ((x) & OFF_MASK))
|
||||
/* Converts a flat address to a seg:off address. */
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Global Variables
|
||||
+--------------------------------------------------------------------------*/
|
||||
const char UsageMsg[] = "\
|
||||
Usage: bin2boot [<infile> [<outfile>]] [-s <start_address>] [-v]\n\
|
||||
\n\
|
||||
<infile> : input file name\n\
|
||||
<outfile> : output file name\n\
|
||||
-s <outfile> : start address of binary image\n\
|
||||
-m <size> : actual size (for compressed images)\n\
|
||||
-v : verbose output\n"; /* Usage message. */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| 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 */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Main
|
||||
+--------------------------------------------------------------------------*/
|
||||
void main(int argc, char *argv[])
|
||||
{
|
||||
FileHeader bootimgFileHdr; /* Output file header. */
|
||||
LoadingInfo imageInfo; /* Section header. */
|
||||
Byte auxBuf[BUFFER_BLOCK_SIZE]; /* */
|
||||
DWord nRead; /* Number of bytes read. */
|
||||
Word padSize; /* Size of padding at end of file. */
|
||||
|
||||
char *progName = argv[0]; /* Program name for errors. */
|
||||
FILE *fpIn = stdin;
|
||||
FILE *fpOut = stdout;
|
||||
DWord binStart = DEFAULT_START_ADDR; /* Start address of image. */
|
||||
DWord memLen = 0; /* Real length for compressed images. */
|
||||
|
||||
char currArg;
|
||||
int argCount;
|
||||
int flag; /* general purpose flag */
|
||||
int verbose = 0; /* flag for verbose output */
|
||||
|
||||
while ((currArg = getopt(argc, argv, "hm:s:v")) >= 0) /* parse command line */
|
||||
switch (currArg)
|
||||
{
|
||||
case 'h' :
|
||||
fprintf(stderr, UsageMsg);
|
||||
exit(0);
|
||||
break;
|
||||
case 'm' :
|
||||
memLen = getNumArg(optarg);
|
||||
break;
|
||||
case 's' :
|
||||
binStart = getNumArg(optarg);
|
||||
break;
|
||||
case 'v' :
|
||||
verbose = 1;
|
||||
break;
|
||||
default :
|
||||
fprintf(stderr, UsageMsg);
|
||||
exit(1);
|
||||
break;
|
||||
} /* switch */
|
||||
|
||||
flag = 0;
|
||||
|
||||
for (argCount = 1; argCount < argc; argCount++)
|
||||
if (argv[argCount][0] == '-')
|
||||
{
|
||||
if (argv[argCount][1] == 's')
|
||||
argCount++;
|
||||
}
|
||||
else if (flag) /* we already have the input file => output file */
|
||||
{
|
||||
if ((fpOut = fopen(argv[argCount], "w")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: can't open %s\n", progName, argv[argCount]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else /* input file */
|
||||
{
|
||||
if ((fpIn = fopen(argv[argCount], "r")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: can't open %s\n", progName, argv[argCount]);
|
||||
exit(1);
|
||||
}
|
||||
flag = 1;
|
||||
}
|
||||
|
||||
/*** begin: Conversion to Bootimg */
|
||||
|
||||
/*** File Header */
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "\nBoot Image File Header:\n\n");
|
||||
|
||||
bootimgFileHdr.magicNum = BOOT_IMAGE_MAGIC; /* 4 bytes - magic number */
|
||||
bootimgFileHdr.flagsLen = NON_VENDOR_LEN; /* 4 bytes - flags and length */
|
||||
bootimgFileHdr.locAddr = getSegOff(binStart - BOOTIMG_HDR_SIZE);
|
||||
/* 4 bytes - location address in ds:bx format */
|
||||
bootimgFileHdr.execAddr = getSegOff(binStart);
|
||||
/* 4 bytes - execute address in cs:ip format */
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
fprintf(stderr, ">> location address in ds:bx format: %04x:%04x\n",
|
||||
getSeg(bootimgFileHdr.locAddr), getOff(bootimgFileHdr.locAddr));
|
||||
fprintf(stderr, ">> execute address in cs:ip format: %04x:%04x\n",
|
||||
getSeg(bootimgFileHdr.execAddr), getOff(bootimgFileHdr.execAddr));
|
||||
}
|
||||
|
||||
/*** Write File Header to output file */
|
||||
|
||||
fwrite((void *)(& bootimgFileHdr), sizeof(FileHeader), 1, fpOut);
|
||||
|
||||
/*** Sections */
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "\nCode Section:\n\n");
|
||||
|
||||
imageInfo.flagsTagsLens = 0x04000004;
|
||||
/* flags, vendor's tags, vendor and non-vendor lengths */
|
||||
imageInfo.loadAddr = binStart; /* load address */
|
||||
|
||||
rewind(fpIn);
|
||||
fseek(fpIn, 0, SEEK_END);
|
||||
nRead = ftell(fpIn);
|
||||
rewind(fpIn);
|
||||
padSize = LAST_BLOCK_SIZE - (nRead % LAST_BLOCK_SIZE);
|
||||
imageInfo.imageLength = nRead + padSize; /* image length */
|
||||
imageInfo.memoryLength = (memLen != 0) ? memLen : imageInfo.imageLength;
|
||||
/* memory length */
|
||||
|
||||
fwrite((void *)(&imageInfo), sizeof(LoadingInfo), 1, fpOut);
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
fprintf(stderr, ">> load address: 0x%08lx\n", imageInfo.loadAddr);
|
||||
fprintf(stderr, ">> image length: 0x%08lx\n", imageInfo.imageLength);
|
||||
fprintf(stderr, ">> memory length: 0x%08lx\n\n", imageInfo.memoryLength);
|
||||
}
|
||||
|
||||
nRead = BOOTIMG_HDR_SIZE - sizeof(FileHeader) - sizeof(LoadingInfo);
|
||||
memset((void *)auxBuf, 0x00, nRead);
|
||||
fwrite((void *)auxBuf, 1, nRead, fpOut);
|
||||
|
||||
nRead = fread((void *)auxBuf, 1, BUFFER_BLOCK_SIZE, fpIn);
|
||||
|
||||
while (!feof(fpIn))
|
||||
{
|
||||
fwrite((void *)auxBuf, BUFFER_BLOCK_SIZE, 1, fpOut);
|
||||
nRead = fread((void *)auxBuf, 1, BUFFER_BLOCK_SIZE, fpIn);
|
||||
}
|
||||
|
||||
fwrite((void *)auxBuf, 1, nRead, fpOut);
|
||||
|
||||
memset((void *)auxBuf, 0x00, padSize);
|
||||
fwrite((void *)auxBuf, 1, padSize, fpOut);
|
||||
|
||||
fclose(fpOut);
|
||||
fclose(fpIn);
|
||||
|
||||
/*** end: Conversion to Bootimg */
|
||||
|
||||
exit(0);
|
||||
|
||||
} /* main */
|
||||
@@ -46,4 +46,6 @@ $(LIB): ${OBJS}
|
||||
|
||||
all: ${ARCH} $(SRCS) $(LIB)
|
||||
$(INSTALL_VARIANT) -m 644 $(LIB) ${PROJECT_RELEASE}/lib
|
||||
|
||||
# we create here a directory specific to the PC386 BSP to store the BootImage
|
||||
# files so they can be easily found
|
||||
mkdir -p ${PROJECT_RELEASE}/BootImgs
|
||||
|
||||
@@ -42,7 +42,7 @@ HAS_KA9Q=no
|
||||
|
||||
define make-target-options
|
||||
@echo "/* #define NDEBUG 1 */ " >>$@
|
||||
@echo "#define RTEMS_TEST_NO_PAUSE 1" >>$@
|
||||
@echo "/* #define RTEMS_TEST_NO_PAUSE 1 */" >>$@
|
||||
@echo "/* #define RTEMS_DEBUG 1 */" >>$@
|
||||
endef
|
||||
|
||||
@@ -51,13 +51,19 @@ endef
|
||||
# Usage ref: src/tests/sptest/sp1/Makefile
|
||||
|
||||
#+--------------------------------------------------------------------------+
|
||||
#| Relocation address. Set this to the linear address where you want your code
|
||||
#| to start. It should abide to the following constraints:
|
||||
#| RELOCADDR >= 0x10200
|
||||
#| RELOCADDR + 'image file size' < 0xA0000
|
||||
#| RELOCADDR % 4 = 0 (i.e. aligned on a 4 byte boundary)
|
||||
#| 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 >=
|
||||
#| 0x100000 (1024K). If you are using NetBoot to load the images it can be
|
||||
#| >= 0x10000 (64K) AND <= 0x97C00 (607K) OR >= 0x100000 (1024K). The memory
|
||||
#| top is of course another limit. Make sure there is enough space before the
|
||||
#| upper memory limits for the image and the memory allocated by it to fit.
|
||||
#| Make sure the value you choose is aligned to 4 bytes.
|
||||
#+--------------------------------------------------------------------------+
|
||||
RELOCADDR=0x00020200
|
||||
RELOCADDR=0x00100000
|
||||
|
||||
START16FILE=$(PROJECT_RELEASE)/lib/start16.bin
|
||||
START16ADDR=0x00097C00
|
||||
HEADERADDR=0x00097E00
|
||||
|
||||
# The following are definitions of make-exe which will work using ld as
|
||||
# is currently required. It is expected that as of gcc 2.8, the end user
|
||||
@@ -66,20 +72,28 @@ RELOCADDR=0x00020200
|
||||
ifeq ($(RTEMS_USE_GCC272),yes)
|
||||
define make-exe
|
||||
$(LD) -N -T $(LINKCMDS) -Ttext $(RELOCADDR) -e start -nostdlib \
|
||||
-o $(basename $@).elf \
|
||||
-o $(basename $@).obj \
|
||||
$(START_FILE) $(LINK_OBJS) --start-group $(LINK_LIBS) --end-group
|
||||
$(OBJCOPY) -O binary --set-start $(RELOCADDR) $(basename $@).elf $@
|
||||
$(PROJECT_TOOLS)/bin2boot -v $@ $(basename $@).bin -s $(RELOCADDR)
|
||||
$(NM) -g -n $(basename $@).elf > $(basename $@).num
|
||||
$(SIZE) $(basename $@).elf
|
||||
$(OBJCOPY) -O a.out-i386 --remove-section=.rodata --strip-unneeded \
|
||||
$(basename $@).obj $@
|
||||
$(OBJCOPY) -O binary $(basename $@).obj $(basename $@).bin
|
||||
$(PROJECT_TOOLS)/bin2boot -v $(basename $@).bin $(HEADERADDR)\
|
||||
$(START16FILE) $(START16ADDR) 0 $(basename $@).bin $(RELOCADDR) 0
|
||||
$(NM) -g -n $(basename $@).obj > $(basename $@).num
|
||||
$(SIZE) $(basename $@).obj
|
||||
$(INSTALL_VARIANT) -m 555 $(basename $@).bt ${PROJECT_RELEASE}/BootImgs
|
||||
endef
|
||||
else
|
||||
define make-exe
|
||||
$(CC) $(CFLAGS) $(CFLAGS_LD) -o $(basename $@).elf $(LINK_OBJS)
|
||||
$(OBJCOPY) -O binary --set-start $(RELOCADDR) $(basename $@).elf $@
|
||||
$(PROJECT_TOOLS)/bin2boot -v $@ $(basename $@).bin -s $(RELOCADDR)
|
||||
$(NM) -g -n $(basename $@).elf > $(basename $@).num
|
||||
$(SIZE) $(basename $@).elf
|
||||
$(CC) $(CFLAGS) $(CFLAGS_LD) -Ttext $(RELOCADDR) -o $(basename $@).obj $(LINK_OBJS)
|
||||
$(OBJCOPY) -O a.out-i386 --remove-section=.rodata --strip-unneeded \
|
||||
$(basename $@).obj $@
|
||||
$(OBJCOPY) -O binary $(basename $@).obj $(basename $@).bin
|
||||
$(PROJECT_TOOLS)/bin2boot -v $(basename $@).bt $(HEADERADDR)\
|
||||
$(START16FILE) $(START16ADDR) 0 $(basename $@).bin $(RELOCADDR) 0
|
||||
$(NM) -g -n $(basename $@).obj > $(basename $@).num
|
||||
$(SIZE) $(basename $@).obj
|
||||
$(INSTALL_VARIANT) -m 555 $(basename $@).bt ${PROJECT_RELEASE}/BootImgs
|
||||
endef
|
||||
endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user