From: Mike Frysinger <vapier@gentoo.org>
To: newlib@sourceware.org
Subject: [PATCH htdocs 3/7] add libgloss manual from current git
Date: Mon, 14 Feb 2022 21:25:49 -0500 [thread overview]
Message-ID: <20220215022552.11267-3-vapier@gentoo.org> (raw)
In-Reply-To: <20220215022552.11267-1-vapier@gentoo.org>
---
docs.html | 10 +-
libgloss.html | 2352 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 2357 insertions(+), 5 deletions(-)
create mode 100644 libgloss.html
diff --git a/docs.html b/docs.html
index 65ca1fdf398b..3389fa810deb 100644
--- a/docs.html
+++ b/docs.html
@@ -8,11 +8,11 @@ The following web pages were generated from the texinfo documentation included i
</p>
<p>
-<a href="libc.html">Red Hat newlib C Library Documentation</a>
-</p>
-
-<p>
-<a href="libm.html">Red Hat newlib C Math Library Documentation</a>
+<ul>
+<li><a href="libc.html">Red Hat newlib C Library Documentation</a></li>
+<li><a href="libm.html">Red Hat newlib C Math Library Documentation</a></li>
+<li><a href="libgloss.html">libgloss Library Documentation</a></li>
+</ul>
</p>
<p>
diff --git a/libgloss.html b/libgloss.html
new file mode 100644
index 000000000000..b8b63df8df0f
--- /dev/null
+++ b/libgloss.html
@@ -0,0 +1,2352 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<!-- Created by GNU Texinfo 6.8, https://www.gnu.org/software/texinfo/ -->
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>Embed with GNU</title>
+
+<meta name="description" content="Embed with GNU">
+<meta name="keywords" content="Embed with GNU">
+<meta name="resource-type" content="document">
+<meta name="distribution" content="global">
+<meta name="Generator" content="makeinfo">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+
+<link href="#Top" rel="start" title="Top">
+<link href="#SEC_Contents" rel="contents" title="Table of Contents">
+<link href="#Libgloss" rel="next" title="Libgloss">
+<style type="text/css">
+<!--
+a.copiable-anchor {visibility: hidden; text-decoration: none; line-height: 0em}
+a.summary-letter {text-decoration: none}
+blockquote.indentedblock {margin-right: 0em}
+div.display {margin-left: 3.2em}
+div.example {margin-left: 3.2em}
+kbd {font-style: oblique}
+pre.display {font-family: inherit}
+pre.format {font-family: inherit}
+pre.menu-comment {font-family: serif}
+pre.menu-preformatted {font-family: serif}
+span.nolinebreak {white-space: nowrap}
+span.roman {font-family: initial; font-weight: normal}
+span.sansserif {font-family: sans-serif; font-weight: normal}
+span:hover a.copiable-anchor {visibility: visible}
+ul.no-bullet {list-style: none}
+-->
+</style>
+
+
+</head>
+
+<body lang="en">
+<h1 class="settitle" align="center">Embed with GNU</h1>
+
+
+
+
+<p>Copyright (c) 1993, 1994, 1995 Cygnus Support
+</p>
+<p>Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+</p>
+<p>Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+</p>
+<p>Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+</p>
+<div class="top" id="Top">
+<div class="header">
+<p>
+Next: <a href="#Libgloss" accesskey="n" rel="next">Libgloss</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Embed-with-GNU"></span><h1 class="top">Embed with GNU</h1>
+
+<p><strong>Rough Draft</strong>
+</p>
+<p>The goal of this document is to gather all the information needed to
+port the GNU tools to a new embedded target in one place. This will
+duplicate some info found in the other manual for the GNU tools, but
+this should be all you’ll need.
+</p>
+
+<div class="Contents_element" id="SEC_Contents">
+<h2 class="contents-heading">Table of Contents</h2>
+
+<div class="contents">
+
+<ul class="no-bullet">
+ <li><a id="toc-Libgloss-1" href="#Libgloss">1 Libgloss</a>
+ <ul class="no-bullet">
+ <li><a id="toc-Supported-Targets" href="#Supported-targets">1.1 Supported Targets</a>
+ <ul class="no-bullet">
+ <li><a id="toc-Sparclite-Targets-Supported" href="#Sparclite">1.1.1 Sparclite Targets Supported</a></li>
+ <li><a id="toc-Motorola-CPU32-Targets-supported" href="#CPU32">1.1.2 Motorola CPU32 Targets supported</a></li>
+ <li><a id="toc-Mips-core-Targets-Supported" href="#Mips">1.1.3 Mips core Targets Supported</a></li>
+ <li><a id="toc-PA_002dRISC-Targets-Supported" href="#PA_002dRISC">1.1.4 PA-RISC Targets Supported</a></li>
+ </ul></li>
+ <li><a id="toc-Configuring-and-building-libgloss_002e" href="#Building-libgloss">1.2 Configuring and building libgloss.</a></li>
+ <li><a id="toc-Adding-Support-for-a-New-Board" href="#Board-support">1.3 Adding Support for a New Board</a></li>
+ </ul></li>
+ <li><a id="toc-Porting-GCC" href="#GCC">2 Porting GCC</a>
+ <ul class="no-bullet">
+ <li><a id="toc-Compilation-passes" href="#Overview">2.1 Compilation passes</a></li>
+ </ul></li>
+ <li><a id="toc-Porting-newlib" href="#Libraries">3 Porting newlib</a>
+ <ul class="no-bullet">
+ <li><a id="toc-Crt0_002c-the-main-startup-file" href="#Crt0">3.1 Crt0, the main startup file</a></li>
+ <li><a id="toc-Linker-scripts-for-memory-management" href="#Linker-Scripts">3.2 Linker scripts for memory management</a></li>
+ <li><a id="toc-What-to-do-when-you-have-a-binary-image" href="#What-to-do-now">3.3 What to do when you have a binary image</a></li>
+ <li><a id="toc-Libraries-1" href="#Libc">3.4 Libraries</a>
+ <ul class="no-bullet">
+ <li><a id="toc-Making-I_002fO-work" href="#I_002fO-Support">3.4.1 Making I/O work</a></li>
+ <li><a id="toc-Routines-for-dynamic-memory-allocation" href="#Memory-Support">3.4.2 Routines for dynamic memory allocation</a></li>
+ <li><a id="toc-Misc-support-routines" href="#Misc-Support">3.4.3 Misc support routines</a></li>
+ <li><a id="toc-Useful-debugging-functions" href="#Debugging">3.4.4 Useful debugging functions</a></li>
+ </ul></li>
+ </ul></li>
+ <li><a id="toc-Writing-a-new-GDB-backend" href="#GDB">4 Writing a new GDB backend</a>
+ <ul class="no-bullet">
+ <li><a id="toc-The-standard-remote-protocol" href="#GNU-remote-protocol">4.1 The standard remote protocol</a></li>
+ <li><a id="toc-A-linked-in-exception-handler" href="#Exception-handler">4.2 A linked in exception handler</a></li>
+ <li><a id="toc-Using-a-ROM-monitor-as-a-backend" href="#ROM-monitors">4.3 Using a ROM monitor as a backend</a></li>
+ <li><a id="toc-Adding-support-for-new-protocols" href="#Other-remote-protocols">4.4 Adding support for new protocols</a></li>
+ </ul></li>
+ <li><a id="toc-Code-Listings-1" href="#Code-Listings">Appendix A Code Listings</a>
+ <ul class="no-bullet">
+ <li><a id="toc-Linker-script-for-the-IDP-board" href="#idp_002eld">A.1 Linker script for the IDP board</a></li>
+ <li><a id="toc-crt0_002eS-_002d-The-startup-file" href="#crt0_002eS">A.2 crt0.S - The startup file</a></li>
+ <li><a id="toc-C-based-_0022glue_0022-code_002e" href="#glue_002ec">A.3 C based "glue" code.</a></li>
+ <li><a id="toc-I_002fO-assembler-code-sample" href="#mvme_002eS">A.4 I/O assembler code sample</a></li>
+ <li><a id="toc-I_002fO-code-sample" href="#io_002ec">A.5 I/O code sample</a></li>
+ <li><a id="toc-Led-control-sample" href="#leds_002ec">A.6 Led control sample</a></li>
+ </ul></li>
+</ul>
+</div>
+</div>
+<hr>
+<div class="chapter" id="Libgloss">
+<div class="header">
+<p>
+Next: <a href="#GCC" accesskey="n" rel="next">Porting GCC</a>, Previous: <a href="#Top" accesskey="p" rel="prev">Embed with GNU</a>, Up: <a href="#Top" accesskey="u" rel="up">Embed with GNU</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Libgloss-1"></span><h2 class="chapter">1 Libgloss</h2>
+<p>Libgloss is a library for all the details that usually get glossed over.
+This library refers to things like startup code, and usually I/O support
+for <code>gcc</code> and <code>C library</code>. The C library used through out
+this manual is <code>newlib</code>. Newlib is a ANSI conforming C library
+developed by Cygnus Support. Libgloss could easily be made to
+support other C libraries, and it can be used standalone as well. The
+standalone configuration is typically used when bringing up new
+hardware, or on small systems.
+</p>
+<p>For a long time, these details were part of newlib. This approach worked
+well when a complete tool chain only had to support one system. A tool
+chain refers to the series of compiler passes required to produce a
+binary file that will run on an embedded system. For C, the passes are
+cpp, gcc, gas, ld. Cpp is the preprocessor, which process all the header
+files and macros. Gcc is the compiler, which produces assembler from the
+processed C files. Gas assembles the code into object files, and then ld
+combines the object files and binds the code to addresses and produces
+the final executable image.
+</p>
+<p>Most of the time a tool chain does only have to support one target
+execution environment. An example of this would be a tool chain for the
+AMD 29k processor family. All of the execution environments for this
+processor have the same interface, the same memory map, and the same
+I/O code. In this case all of the support code is under newlib/libc/sys.
+Libgloss’s creation was forced initially because of the <code>cpu32</code>
+processor family. There are many different execution environments for
+this line, and they vary wildly. newlib itself has only a few
+dependencies that it needs for each target. These are explained later in
+this doc. The hardware dependent part of newlib was reorganized into a
+separate directory structure within newlib called the stub dirs. It was
+initially called this because most of the routines newlib needs for a
+target were simple stubs that do nothing, but return a value to the
+application. They only exist so the linker can produce a final
+executable image. This work was done during the early part of 1993.
+</p>
+<p>After a while it became apparent that this approach of isolating the
+hardware and systems files together made sense. Around this same time
+the stub dirs were made to run standalone, mostly so it could also be
+used to support GDB’s remote debugging needs. At this time it was
+decided to move the stub dirs out of newlib and into it’s own separate
+library so it could be used standalone, and be included in various other
+GNU tools without having to bring in all of newlib, which is large. The
+new library is called Libgloss, for Gnu Low-level OS support.
+</p>
+
+<ul class="section-toc">
+<li><a href="#Supported-targets" accesskey="1">Supported Targets</a></li>
+<li><a href="#Building-libgloss" accesskey="2">Configuring and building libgloss.</a></li>
+<li><a href="#Board-support" accesskey="3">Adding Support for a New Board</a></li>
+</ul>
+<hr>
+<div class="section" id="Supported-targets">
+<div class="header">
+<p>
+Next: <a href="#Building-libgloss" accesskey="n" rel="next">Configuring and building libgloss.</a>, Previous: <a href="#Libgloss" accesskey="p" rel="prev">Libgloss</a>, Up: <a href="#Libgloss" accesskey="u" rel="up">Libgloss</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Supported-Targets"></span><h3 class="section">1.1 Supported Targets</h3>
+<p>Currently libgloss is being used for the following targets:
+</p>
+
+<ul class="section-toc">
+<li><a href="#Sparclite" accesskey="1">Sparclite Targets Supported</a></li>
+<li><a href="#CPU32" accesskey="2">Motorola CPU32 Targets supported</a></li>
+<li><a href="#Mips" accesskey="3">Mips core Targets Supported</a></li>
+<li><a href="#PA_002dRISC" accesskey="4">PA-RISC Targets Supported</a></li>
+</ul>
+<hr>
+<div class="subsection" id="Sparclite">
+<div class="header">
+<p>
+Next: <a href="#CPU32" accesskey="n" rel="next">Motorola CPU32 Targets supported</a>, Up: <a href="#Supported-targets" accesskey="u" rel="up">Supported Targets</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Sparclite-Targets-Supported"></span><h4 class="subsection">1.1.1 Sparclite Targets Supported</h4>
+<p>This is for the Fujitsu Sparclite family of processors. Currently this
+covers the ex930, ex931, ex932, ex933, and the ex934. In addition to the
+I/O code a startup file, this has a GDB debug-stub that gets linked into
+your application. This is an exception handler style debug stub. For
+more info, see the section on Porting GDB. <a href="#GDB">Porting GDB</a>.
+</p>
+<p>The Fujitsu eval boards use a host based terminal program to load and
+execute programs on the target. This program, <code>pciuh</code> is relatively
+new (in 1994) and it replaced the previous ROM monitor which had the
+shell in the ROM. GDB uses the the GDB remote protocol, the relevant
+source files from the gdb sources are remote-sparcl.c. The debug stub is
+part of libgloss and is called sparcl-stub.c.
+</p>
+<hr>
+</div>
+<div class="subsection" id="CPU32">
+<div class="header">
+<p>
+Next: <a href="#Mips" accesskey="n" rel="next">Mips core Targets Supported</a>, Previous: <a href="#Sparclite" accesskey="p" rel="prev">Sparclite Targets Supported</a>, Up: <a href="#Supported-targets" accesskey="u" rel="up">Supported Targets</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Motorola-CPU32-Targets-supported"></span><h4 class="subsection">1.1.2 Motorola CPU32 Targets supported</h4>
+<p>This refers to Motorola’s m68k based CPU32 processor family. The crt0.S
+startup file should be usable with any target environment, and it’s
+mostly just the I/O code and linker scripts that vary. Currently there
+is support for the Motorola MVME line of 6U VME boards and IDP
+line of eval boards. All of the
+Motorola VME boards run <code>Bug</code>, a ROM based debug monitor.
+This monitor has the feature of using user level traps to do I/O, so
+this code should be portable to other MVME boards with little if any
+change. The startup file also can remain unchanged. About the only thing
+that varies is the address for where the text section begins. This can
+be accomplished either in the linker script, or on the command line
+using the ‘<samp>-Ttext [address]</samp>’.
+</p>
+<p>There is also support for the <code>rom68k</code> monitor as shipped on
+Motorola’s IDP eval board line. This code should be portable across the
+range of CPU’s the board supports. There is also GDB support for this
+target environment in the GDB source tree. The relevant files are
+gdb/monitor.c, monitor.h, and rom58k-rom.c. The usage of these files is
+discussed in the GDB section.
+</p>
+<hr>
+</div>
+<div class="subsection" id="Mips">
+<div class="header">
+<p>
+Next: <a href="#PA_002dRISC" accesskey="n" rel="next">PA-RISC Targets Supported</a>, Previous: <a href="#CPU32" accesskey="p" rel="prev">Motorola CPU32 Targets supported</a>, Up: <a href="#Supported-targets" accesskey="u" rel="up">Supported Targets</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Mips-core-Targets-Supported"></span><h4 class="subsection">1.1.3 Mips core Targets Supported</h4>
+<p>The Crt0 startup file should run on any mips target that doesn’t require
+additional hardware initialization. The I/O code so far only supports a
+custom LSI33k based RAID disk controller board. It should easy to
+change to support the IDT line of eval boards. Currently the two
+debugging protocols supported by GDB for mips targets is IDT’s mips
+debug protocol, and a customized hybrid of the standard GDB remote
+protocol and GDB’s standard ROM monitor support. Included here is the
+debug stub for the hybrid monitor. This supports the LSI33k processor,
+and only has support for the GDB protocol commands <code>g</code>, <code>G</code>,
+<code>m</code>, <code>M</code>, which basically only supports the register and
+memory reading and writing commands. This is part of libgloss and is
+called lsi33k-stub.c.
+</p>
+<p>The crt0.S should also work on the IDT line of eval boards, but has only
+been run on the LSI33k for now. There is no I/O support for the IDT eval
+board at this time. The current I/O code is for a customized version of
+LSI’s <code>pmon</code> ROM monitor. This uses entry points into the monitor,
+and should easily port to other versions of the pmon monitor. Pmon is
+distributed in source by LSI.
+</p>
+<hr>
+</div>
+<div class="subsection" id="PA_002dRISC">
+<div class="header">
+<p>
+Previous: <a href="#Mips" accesskey="p" rel="prev">Mips core Targets Supported</a>, Up: <a href="#Supported-targets" accesskey="u" rel="up">Supported Targets</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="PA_002dRISC-Targets-Supported"></span><h4 class="subsection">1.1.4 PA-RISC Targets Supported</h4>
+<p>This supports the various boards manufactured by the HP-PRO consortium.
+This is a group of companies all making variations on the PA-RISC
+processor. Currently supported are ports to the WinBond ‘<samp>Cougar</samp>’
+board based around their w89k version of the PA. Also supported is the
+Oki op50n processor.
+</p>
+<p>There is also included, but never built an unfinished port to the HP 743
+board. This board is the main CPU board for the HP700 line of industrial
+computers. This target isn’t exactly an embedded system, in fact it’s
+really only designed to load and run HP-UX. Still, the crt0.S and I/O
+code are fully working. It is included mostly because their is a barely
+functioning exception handler GDB debug stub, and I hope somebody could
+use it. The other PRO targets all use GDB’s ability to talk to ROM
+monitors directly, so it doesn’t need a debug stub. There is also a
+utility that will produce a bootable file by HP’s ROM monitor. This is
+all included in the hopes somebody else will finish it. :-)
+</p>
+<p>Both the WinBond board and the Oki board download srecords. The WinBond
+board also has support for loading the SOM files as produced by the
+native compiler on HP-UX. WinBond supplies a set of DOS programs that
+will allow the loading of files via a bidirectional parallel port. This
+has never been tested with the output of GNU SOM, as this manual is
+mostly for Unix based systems.
+</p>
+<hr>
+</div>
+</div>
+<div class="section" id="Building-libgloss">
+<div class="header">
+<p>
+Next: <a href="#Board-support" accesskey="n" rel="next">Adding Support for a New Board</a>, Previous: <a href="#Supported-targets" accesskey="p" rel="prev">Supported Targets</a>, Up: <a href="#Libgloss" accesskey="u" rel="up">Libgloss</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Configuring-and-building-libgloss_002e"></span><h3 class="section">1.2 Configuring and building libgloss.</h3>
+
+<p>Libgloss uses an autoconf based script to configure. Autoconf scripts
+are portable shell scripts that are generated from a configure.in file.
+Configure input scripts are based themselves on m4. Most configure
+scripts run a series of tests to determine features the various
+supported features of the target. For features that can’t be determined
+by a feature test, a makefile fragment is merged in. The configure
+process leaves creates a Makefile in the build directory. For libgloss,
+there are only a few configure options of importance. These are –target
+and –srcdir.
+</p>
+<p>Typically libgloss is built in a separate tree just for objects. In this
+manner, it’s possible to have a single source tree, and multiple object
+trees. If you only need to configure for a single target environment,
+then you can configure in the source tree. The argument for –target is
+a config string. It’s usually safest to use the full canonical opposed
+to the target alias. So, to configure for a CPU32 (m68k) with a separate
+source tree, use:
+</p>
+<div class="example">
+<pre class="example">../src/libgloss/configure --verbose --target m68k-coff
+</pre></div>
+
+<p>The configure script is in the source tree. When configure is invoked
+it will determine it’s own source tree, so the –srcdir is would be
+redundant here.
+</p>
+<p>Once libgloss is configured, <code>make</code> is sufficient to build it. The
+default values for <code>Makefiles</code> are typically correct for all
+supported systems. The test cases in the testsuite will also built
+automatically as opposed to a <code>make check</code>, where test binaries
+aren’t built till test time. This is mostly cause the libgloss
+testsuites are the last thing built when building the entire GNU source
+tree, so it’s a good test of all the other compilation passes.
+</p>
+<p>The default values for the Makefiles are set in the Makefile fragment
+merged in during configuration. This fragment typically has rules like
+</p>
+<div class="example">
+<pre class="example">CC_FOR_TARGET = `if [ -f $${OBJROOT}/gcc/xgcc ] ; \
+ then echo ${OBJROOT}/gcc/xgcc -B${OBJROOT}/gcc/ ; \
+ else t='${program_transform_name}'; echo gcc | sed -e '' $$t ; fi`
+</pre></div>
+
+<p>Basically this is a runtime test to determine whether there are freshly
+built executables for the other main passes of the GNU tools. If there
+isn’t an executable built in the same object tree, then
+<em>transformed</em>the generic tool name (like gcc) is transformed to the
+name typically used in GNU cross compilers. The names are
+typically based on the target’s canonical name, so if you’ve configured
+for <code>m68k-coff</code> the transformed name is <code>m68k-coff-gcc</code> in
+this case. If you install with aliases or rename the tools, this won’t
+work, and it will always look for tools in the path. You can force the a
+different name to work by reconfiguring with the
+<code>--program-transform-name</code> option to configure. This option takes a
+sed script like this <code>-e s,^,m68k-coff-,</code> which produces tools
+using the standard names (at least here at Cygnus).
+</p>
+<p>The search for the other GNU development tools is exactly the same idea.
+This technique gets messier when build options like <code>-msoft-float</code>
+support are used. The Makefile fragments set the <code>MUTILIB</code>
+variable, and if it is set, the search path is modified. If the linking
+is done with an installed cross compiler, then none of this needs to be
+used. This is done so libgloss will build automatically with a fresh,
+and uninstalled object tree. It also makes it easier to debug the other
+tools using libgloss’s test suites.
+</p>
+<hr>
+</div>
+<div class="section" id="Board-support">
+<div class="header">
+<p>
+Previous: <a href="#Building-libgloss" accesskey="p" rel="prev">Configuring and building libgloss.</a>, Up: <a href="#Libgloss" accesskey="u" rel="up">Libgloss</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Adding-Support-for-a-New-Board"></span><h3 class="section">1.3 Adding Support for a New Board</h3>
+
+<p>This section explains how to add support for a new board to libgloss.
+In order to add support for a board, you must already have developed a
+toolchain for the target architecture.
+</p>
+<p>All of the changes you will make will be in the subdirectory named
+after the architecture used by your board. For example, if you are
+developing support for a new ColdFire board, you will modify files in
+the <samp>m68k</samp> subdirectory, as that subdirectory contains support
+for all 68K devices, including architecture variants like ColdFire.
+</p>
+<p>In general, you will be adding three components: a <samp>crt0.S</samp> file
+(see <a href="#Crt0">Crt0, the main startup file</a>), a linker script (see <a href="#Linker-Scripts">Linker scripts for memory management</a>), and a
+hardware support library. Each should be prefixed with the name of
+your board. For example, if you ard adding support for a new Surf
+board, then you will be adding the assembly <samp>surf-crt0.S</samp> (which
+will be assembled into <samp>surf-crt0.o</samp>), the linker script
+<samp>surf.ld</samp>, and other C and assembly files which will be combined
+into the hardware support library <samp>libsurf.a</samp>.
+</p>
+<p>You should modify <samp>Makefile.in</samp> to define new variables
+corresponding to your board. Although there is some variation between
+architectures, the general convention is to use the following format:
+</p>
+<div class="example">
+<pre class="example"># The name of the crt0.o file.
+SURF_CRT0 = surf-crt0.o
+# The name of the linker script.
+SURF_SCRIPTS = surf.ld
+# The name of the hardware support library.
+SURF_BSP = libsurf.a
+# The object files that make up the hardware support library.
+SURF_OBJS = surf-file1.o surf-file2.o
+# The name of the Makefile target to use for installation.
+SURF_INSTALL = install-surf
+</pre></div>
+
+<p>Then, you should create the <code>${SURF_BSP}</code> and
+<code>${SURF_INSTALL}</code> make targets. Add <code>${SURF_CRT0}</code> to
+the dependencies for the <code>all</code> target and add
+<code>${SURF_INSTALL}</code> to the dependencies for the <code>install</code>
+target. Now, when libgloss is built and installed, support for your
+BSP will be installed as well.
+</p>
+<hr>
+</div>
+</div>
+<div class="chapter" id="GCC">
+<div class="header">
+<p>
+Next: <a href="#Libraries" accesskey="n" rel="next">Porting newlib</a>, Previous: <a href="#Libgloss" accesskey="p" rel="prev">Libgloss</a>, Up: <a href="#Top" accesskey="u" rel="up">Embed with GNU</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Porting-GCC"></span><h2 class="chapter">2 Porting GCC</h2>
+
+<p>Porting GCC requires two things, neither of which has anything to do
+with GCC. If GCC already supports a processor type, then all the work in
+porting GCC is really a linker issue. All GCC has to do is produce
+assembler output in the proper syntax. Most of the work is done by the
+linker, which is described elsewhere.
+</p>
+<p>Mostly all GCC does is format the command line for the linker pass. The
+command line for GCC is set in the various config subdirectories of gcc.
+The options of interest to us are <code>CPP_SPEC</code> and
+<code>STARTFILE_SPEC</code>. CPP_SPEC sets the builtin defines for your
+environment. If you support multiple environments with the same
+processor, then OS specific defines will need to be elsewhere.
+</p>
+<p><code>STARTFILE_SPEC</code>
+</p>
+<p>Once you have linker support, GCC will be able to produce a fully linked
+executable image. The only <em>part</em> of GCC that the linker wants is a
+crt0.o, and a memory map. If you plan on running any programs that do
+I/O of any kind, you’ll need to write support for the C library, which
+is described elsewhere.
+</p>
+
+<ul class="section-toc">
+<li><a href="#Overview" accesskey="1">Compilation passes</a></li>
+</ul>
+<hr>
+<div class="section" id="Overview">
+<div class="header">
+<p>
+Next: <a href="#Options" accesskey="n" rel="next">Options</a>, Up: <a href="#GCC" accesskey="u" rel="up">Porting GCC</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Compilation-passes"></span><h3 class="section">2.1 Compilation passes</h3>
+
+<p>GCC by itself only compiles the C or C++ code into assembler. Typically
+GCC invokes all the passes required for you. These passes are cpp, cc1,
+gas, ld. <code>cpp</code> is the C preprocessor. This will merge in the
+include files, expand all macros definitions, and process all the
+<code>#ifdef</code> sections. To see the output of ccp, invoke gcc with the
+<code>-E</code> option, and the preprocessed file will be printed on the
+stdout. cc1 is the actual compiler pass that produces the assembler for
+the processed file. GCC is actually only a driver program for all the
+compiler passes. It will format command line options for the other passes.
+The usual command line GCC uses for the final link phase will have LD
+link in the startup code and additional libraries by default.
+</p>
+<p>GNU AS started it’s life to only function as a compiler pass, but
+these days it can also be used as a source level assembler. When used as
+a source level assembler, it has a companion assembler preprocessor
+called <code>gasp</code>. This has a syntax similar to most other assembler
+macros packages. GAS emits a relocatable object file from the assembler
+source. The object file contains the executable part of the application,
+and debug symbols.
+</p>
+<p>LD is responsible for resolving the addresses and symbols to something
+that will be fully self-contained. Some RTOS’s use relocatable object
+file formats like <code>a.out</code>, but more commonly the final image will
+only use absolute addresses for symbols. This enables code to be burned
+into PROMS as well. Although LD can produce an executable image, there
+is usually a hidden object file called <code>crt0.o</code> that is required as
+startup code. With this startup code and a memory map, the executable
+image will actually run on the target environment. <a href="#Crt0">Startup
+Files</a>.
+</p>
+<p>The startup code usually defines a special symbol like <code>_start</code>
+that is the default base address for the application, and the first
+symbol in the executable image. If you plan to use any routines from the
+standard C library, you’ll also need to implement the functions that
+this library is dependent on. <a href="#Libraries">Porting Newlib</a>.
+</p>
+<hr>
+<span id="Options"></span><div class="header">
+<p>
+Previous: <a href="#Overview" accesskey="p" rel="prev">Compilation passes</a>, Up: <a href="#GCC" accesskey="u" rel="up">Porting GCC</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<h4 class="node-heading">Options</h4>
+
+<p>Options for the various development tools are covered in more detail
+elsewhere. Still, the amount of options can be an overwhelming amount of
+stuff, so the options most suited to embedded systems are summarized
+here. If you use GCC as the main driver for all the passes, most of the
+linker options can be passed directly to the compiler. There are also
+GCC options that control how the GCC driver formats the command line
+arguments for the linker.
+</p>
+
+<hr>
+<span id="GCC-Options"></span><div class="header">
+<p>
+Next: <a href="#GAS-Options" accesskey="n" rel="next">GAS Options</a>, Up: <a href="#Options" accesskey="u" rel="up">Options</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<h4 class="node-heading">GCC Options</h4>
+<p>Most of the GCC options that we’re interested control how the GCC driver
+formats the options for the linker pass.
+</p>
+<dl compact="compact">
+<dt><span><code>-nostartfiles</code></span></dt>
+<dt><span><code>-nostdlib</code></span></dt>
+<dt><span><code>-Xlinker</code></span></dt>
+<dd><p>Pass the next option directly to the linker.
+</p>
+</dd>
+<dt><span><code>-v</code></span></dt>
+<dt><span><code>-fpic</code></span></dt>
+</dl>
+
+<hr>
+<span id="GAS-Options"></span><div class="header">
+<p>
+Next: <a href="#LD-Options" accesskey="n" rel="next">LD Options</a>, Previous: <a href="#GCC-Options" accesskey="p" rel="prev">GCC Options</a>, Up: <a href="#Options" accesskey="u" rel="up">Options</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<h4 class="node-heading">GAS Options</h4>
+
+<hr>
+<span id="LD-Options"></span><div class="header">
+<p>
+Previous: <a href="#GAS-Options" accesskey="p" rel="prev">GAS Options</a>, Up: <a href="#Options" accesskey="u" rel="up">Options</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<h4 class="node-heading">LD Options</h4>
+
+
+<hr>
+</div>
+</div>
+<div class="chapter" id="Libraries">
+<div class="header">
+<p>
+Next: <a href="#GDB" accesskey="n" rel="next">Writing a new GDB backend</a>, Previous: <a href="#GCC" accesskey="p" rel="prev">Porting GCC</a>, Up: <a href="#Top" accesskey="u" rel="up">Embed with GNU</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Porting-newlib"></span><h2 class="chapter">3 Porting newlib</h2>
+
+
+<ul class="section-toc">
+<li><a href="#Crt0" accesskey="1">Crt0, the main startup file</a></li>
+<li><a href="#Linker-Scripts" accesskey="2">Linker scripts for memory management</a></li>
+<li><a href="#What-to-do-now" accesskey="3">What to do when you have a binary image</a></li>
+<li><a href="#Libc" accesskey="4">Libraries</a></li>
+</ul>
+<hr>
+<div class="section" id="Crt0">
+<div class="header">
+<p>
+Next: <a href="#Linker-Scripts" accesskey="n" rel="next">Linker scripts for memory management</a>, Up: <a href="#Libraries" accesskey="u" rel="up">Porting newlib</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Crt0_002c-the-main-startup-file"></span><h3 class="section">3.1 Crt0, the main startup file</h3>
+
+<p>To make a program that has been compiled with GCC to run, you
+need to write some startup code. The initial piece of startup code is
+called a crt0. (C RunTime 0) This is usually written in assembler, and
+it’s object gets linked in first, and bootstraps the rest of the
+application when executed. This file needs to do the following things.
+</p>
+<ol>
+<li> Initialize anything that needs it. This init section varies. If you are
+developing an application that gets download to a ROM monitor, then
+there is usually no need for any special initialization. The ROM monitor
+handles it for you.
+
+<p>If you plan to burn your code in a ROM, then the crt0 typically has to
+do all the hardware initialization that is required to run an
+application. This can include things like initializing serial ports or
+run a memory check. It all depends on the hardware.
+</p>
+</li><li> Zero the BSS section. This is for uninitialized data. All the addresses in
+this section need to be initialized to zero so that programs that forget
+to check new variables default value will get unpredictable results.
+
+</li><li> Call main()
+This is what basically starts things running. If your ROM monitor
+supports it, then first setup argc and argv for command line arguments
+and an environment pointer. Then branch to main(). For G++ the the main
+routine gets a branch to __main inserted by the code generator at the
+very top. __main() is used by G++ to initialize it’s internal tables.
+__main() then returns back to your original main() and your code gets
+executed.
+
+</li><li> Call exit()
+After main() has returned, you need to cleanup things and return control
+of the hardware from the application. On some hardware, there is nothing
+to return to, especially if your program is in ROM. Sometimes the best
+thing to do in this case is do a hardware reset, or branch back to the
+start address all over again.
+
+<p>When there is a ROM monitor present, usually a user trap can be called
+and then the ROM takes over. Pick a safe vector with no side
+effects. Some ROMs have a builtin trap handler just for this case.
+</p></li></ol>
+<p>portable between all the m68k based boards we have here.
+<a href="#crt0_002eS">Example Crt0.S</a>.
+</p>
+
+<div class="example">
+<pre class="example">/* ANSI concatenation macros. */
+
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+</pre></div>
+<p>These we’ll use later.
+</p>
+<div class="example">
+<pre class="example">/* These are predefined by new versions of GNU cpp. */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+/* Use the right prefix for global labels. */
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+</pre></div>
+
+<p>These macros are to make this code portable between both <em>COFF</em> and
+<em>a.out</em>. <em>COFF</em> always has an <var>_ (underline)</var> prepended on
+the front of all global symbol names. <em>a.out</em> has none.
+</p>
+<div class="example">
+<pre class="example">#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+/* Use the right prefix for registers. */
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+#define d0 REG (d0)
+#define d1 REG (d1)
+#define d2 REG (d2)
+#define d3 REG (d3)
+#define d4 REG (d4)
+#define d5 REG (d5)
+#define d6 REG (d6)
+#define d7 REG (d7)
+#define a0 REG (a0)
+#define a1 REG (a1)
+#define a2 REG (a2)
+#define a3 REG (a3)
+#define a4 REG (a4)
+#define a5 REG (a5)
+#define a6 REG (a6)
+#define fp REG (fp)
+#define sp REG (sp)
+</pre></div>
+
+<p>This is for portability between assemblers. Some register names have a
+<var>%</var> or <var>$</var> prepended to the register name.
+</p>
+<div class="example">
+<pre class="example">/*
+ * Set up some room for a stack. We just grab a chunk of memory.
+ */
+ .set stack_size, 0x2000
+ .comm SYM (stack), stack_size
+</pre></div>
+
+<p>Set up space for the stack. This can also be done in the linker script,
+but it typically gets done here.
+</p>
+<div class="example">
+<pre class="example">/*
+ * Define an empty environment.
+ */
+ .data
+ .align 2
+SYM (environ):
+ .long 0
+</pre></div>
+
+<p>Set up an empty space for the environment. This is bogus on any most ROM
+monitor, but we setup a valid address for it, and pass it to main. At
+least that way if an application checks for it, it won’t crash.
+</p>
+<div class="example">
+<pre class="example"> .align 2
+ .text
+ .global SYM (stack)
+
+ .global SYM (main)
+ .global SYM (exit)
+/*
+ * This really should be __bss_start, not SYM (__bss_start).
+ */
+ .global __bss_start
+</pre></div>
+
+<p>Setup a few global symbols that get used elsewhere. <var>__bss_start</var>
+needs to be unchanged, as it’s setup by the linker script.
+</p>
+<div class="example">
+<pre class="example">/*
+ * start -- set things up so the application will run.
+ */
+SYM (start):
+ link a6, #-8
+ moveal #SYM (stack) + stack_size, sp
+
+/*
+ * zerobss -- zero out the bss section
+ */
+ moveal #__bss_start, a0
+ moveal #SYM (end), a1
+1:
+ movel #0, (a0)
+ leal 4(a0), a0
+ cmpal a0, a1
+ bne 1b
+</pre></div>
+
+<p>The global symbol <code>start</code> is used by the linker as the default
+address to use for the <code>.text</code> section. then it zeros the
+<code>.bss</code> section so the uninitialized data will all be cleared. Some
+programs have wild side effects from having the .bss section let
+uncleared. Particularly it causes problems with some implementations of
+<code>malloc</code>.
+</p>
+<div class="example">
+<pre class="example">/*
+ * Call the main routine from the application to get it going.
+ * main (argc, argv, environ)
+ * We pass argv as a pointer to NULL.
+ */
+ pea 0
+ pea SYM (environ)
+ pea sp@(4)
+ pea 0
+ jsr SYM (main)
+ movel d0, sp@-
+</pre></div>
+
+<p>Setup the environment pointer and jump to <code>main()</code>. When
+<code>main()</code> returns, it drops down to the <code>exit</code> routine below.
+</p>
+<div class="example">
+<pre class="example">/*
+ * _exit -- Exit from the application. Normally we cause a user trap
+ * to return to the ROM monitor for another run.
+ */
+SYM (exit):
+ trap #0
+</pre></div>
+
+<p>Implementing <code>exit</code> here is easy. Both the <code>rom68k</code> and <code>bug</code>
+can handle a user caused exception of <code>zero</code> with no side effects.
+Although the <code>bug</code> monitor has a user caused trap that will return
+control to the ROM monitor, this solution has been more portable.
+</p>
+<hr>
+</div>
+<div class="section" id="Linker-Scripts">
+<div class="header">
+<p>
+Next: <a href="#What-to-do-now" accesskey="n" rel="next">What to do when you have a binary image</a>, Previous: <a href="#Crt0" accesskey="p" rel="prev">Crt0, the main startup file</a>, Up: <a href="#Libraries" accesskey="u" rel="up">Porting newlib</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Linker-scripts-for-memory-management"></span><h3 class="section">3.2 Linker scripts for memory management</h3>
+
+<p>The linker script sets up the memory map of an application. It also
+sets up default values for variables used elsewhere by sbrk() and the
+crt0. These default variables are typically called <code>_bss_start</code> and
+<code>_end</code>.
+</p>
+<p>For G++, the constructor and destructor tables must also be setup here.
+The actual section names vary depending on the object file format. For
+<code>a.out</code> and <code>coff</code>, the three main sections are <code>.text</code>,
+<code>.data</code>, and <code>.bss</code>.
+</p>
+<p>Now that you have an image, you can test to make sure it got the
+memory map right. You can do this by having the linker create a memory
+map (by using the <code>-Map</code> option), or afterwards by using <code>nm</code> to
+check a few critical addresses like <code>start</code>, <code>bss_end</code>, and
+<code>_etext</code>.
+</p>
+<p>Here’s a breakdown of a linker script for a m68k based target board.
+See the file <code>libgloss/m68k/idp.ld</code>, or go to the appendixes in
+the end of the manual. <a href="#idp_002eld">Example Linker Script</a>.
+</p>
+<div class="example">
+<pre class="example">STARTUP(crt0.o)
+OUTPUT_ARCH(m68k)
+INPUT(idp.o)
+SEARCH_DIR(.)
+__DYNAMIC = 0;
+</pre></div>
+
+<p>The <code>STARTUP</code> command loads the file specified so that it’s
+first. In this case it also doubles to load the file as well, because
+the m68k-coff configuration defaults to not linking in the crt0.o by
+default. It assumes that the developer probably has their own crt0.o.
+This behavior is controlled in the config file for each architecture.
+It’s a macro called <code>STARTFILE_SPEC</code>, and if it’s set to
+<code>null</code>, then when <code>gcc</code> formats it’s command line, it doesn’t
+add <code>crto.o</code>. Any file name can be specified here, but the default
+is always <code>crt0.o</code>.
+</p>
+<p>Course if you only use <code>ld</code> to link, then the control of whether or
+not to link in <code>crt0.o</code> is done on the command line. If you have
+multiple crto files, then you can leave this out all together, and link
+in the <code>crt0.o</code> in the makefile, or by having different linker
+scripts. Sometimes this is done for initializing floating point
+optionally, or to add device support.
+</p>
+<p>The <code>OUTPUT_ARCH</code> sets architecture the output file is for.
+</p>
+<p><code>INPUT</code> loads in the file specified. In this case, it’s a relocated
+library that contains the definitions for the low-level functions need
+by libc.a. This could have also been specified on the command line, but
+as it’s always needed, it might as well be here as a default.
+<code>SEARCH_DIR</code> specifies the path to look for files, and
+<code>_DYNAMIC</code> means in this case there are no shared libraries.
+</p>
+<div class="example">
+<pre class="example">/*
+ * Setup the memory map of the MC68ec0x0 Board (IDP)
+ * stack grows up towards high memory. This works for
+ * both the rom68k and the mon68k monitors.
+ */
+MEMORY
+{
+ ram : ORIGIN = 0x10000, LENGTH = 2M
+}
+</pre></div>
+
+<p>This specifies a name for a section that can be referred to later in the
+script. In this case, it’s only a pointer to the beginning of free RAM
+space, with an upper limit at 2M. If the output file exceeds the upper
+limit, it will produce an error message.
+</p>
+<div class="example">
+<pre class="example">/*
+ * stick everything in ram (of course)
+ */
+SECTIONS
+{
+ .text :
+ {
+ CREATE_OBJECT_SYMBOLS
+ *(.text)
+ etext = .;
+ __CTOR_LIST__ = .;
+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
+ *(.ctors)
+ LONG(0)
+ __CTOR_END__ = .;
+ __DTOR_LIST__ = .;
+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
+ *(.dtors)
+ LONG(0)
+ __DTOR_END__ = .;
+ *(.lit)
+ *(.shdata)
+ } > ram
+ .shbss SIZEOF(.text) + ADDR(.text) : {
+ *(.shbss)
+ }
+</pre></div>
+
+<p>Set up the <code>.text</code> section. In a <code>COFF</code> file, .text is where
+all the actual instructions are. This also sets up the <em>CONTRUCTOR</em>
+and the <em>DESTRUCTOR</em> tables for <code>G++</code>. Notice that the section
+description redirects itself to the <em>ram</em> variable setup earlier.
+</p>
+<div class="example">
+<pre class="example"> .talias : { } > ram
+ .data : {
+ *(.data)
+ CONSTRUCTORS
+ _edata = .;
+ } > ram
+</pre></div>
+
+<p>Setup the <code>.data</code> section. In a <code>coff</code> file, this is where all
+he initialized data goes. <code>CONSTRUCTORS</code> is a special command used
+by <code>ld</code>.
+</p>
+<div class="example">
+<pre class="example"> .bss SIZEOF(.data) + ADDR(.data) :
+ {
+ __bss_start = ALIGN(0x8);
+ *(.bss)
+ *(COMMON)
+ end = ALIGN(0x8);
+ _end = ALIGN(0x8);
+ __end = ALIGN(0x8);
+ }
+ .mstack : { } > ram
+ .rstack : { } > ram
+ .stab . (NOLOAD) :
+ {
+ [ .stab ]
+ }
+ .stabstr . (NOLOAD) :
+ {
+ [ .stabstr ]
+ }
+}
+</pre></div>
+
+<p>Setup the <code>.bss</code> section. In a <code>COFF</code> file, this is where
+unitialized data goes. The symbols <code>_bss_start</code> and <code>_end</code>
+are setup here for use by the <code>crt0.o</code> when it zero’s the
+<code>.bss</code> section.
+</p>
+
+<hr>
+</div>
+<div class="section" id="What-to-do-now">
+<div class="header">
+<p>
+Next: <a href="#Libc" accesskey="n" rel="next">Libraries</a>, Previous: <a href="#Linker-Scripts" accesskey="p" rel="prev">Linker scripts for memory management</a>, Up: <a href="#Libraries" accesskey="u" rel="up">Porting newlib</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="What-to-do-when-you-have-a-binary-image"></span><h3 class="section">3.3 What to do when you have a binary image</h3>
+
+<p>A few ROM monitors load binary images, typically <code>a.out</code>, but most all
+will load an <code>srecord</code>. An srecord is an ASCII representation of a binary
+image. At it’s simplest, an srecord is an address, followed by a byte
+count, followed by the bytes, and a 2’s compliment checksum. A whole
+srecord file has an optional <em>start</em> record, and a required <em>end</em>
+record. To make an srecord from a binary image, the GNU <code>objcopy</code> program
+is used. This will read the image and make an srecord from it. To do
+this, invoke objcopy like this: <code>objcopy -O srec infile outfile</code>. Most
+PROM burners also read srecords or a similar format. Use <code>objdump -i</code> to
+get a list of support object files types for your architecture.
+</p>
+<hr>
+</div>
+<div class="section" id="Libc">
+<div class="header">
+<p>
+Previous: <a href="#What-to-do-now" accesskey="p" rel="prev">What to do when you have a binary image</a>, Up: <a href="#Libraries" accesskey="u" rel="up">Porting newlib</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Libraries-1"></span><h3 class="section">3.4 Libraries</h3>
+
+<p>This describes <code>newlib</code>, a freely available libc replacement. Most
+applications use calls in the standard C library. When initially linking
+in libc.a, several I/O functions are undefined. If you don’t plan on
+doing any I/O, then you’re OK, otherwise they need to be created. These
+routines are read, write, open, close. sbrk, and kill. Open & close
+don’t need to be fully supported unless you have a filesystems, so
+typically they are stubbed out. Kill is also a stub, since you can’t do
+process control on an embedded system.
+</p>
+<p>Sbrk() is only needed by applications that do dynamic memory
+allocation. It’s uses the symbol <code>_end</code> that is setup in the linker
+script. It also requires a compile time option to set the upper size
+limit on the heap space. This leaves us with read and write, which are
+required for serial I/O. Usually these two routines are written in C,
+and call a lower level function for the actual I/O operation. These two
+lowest level I/O primitives are inbyte() and outbyte(), and are also
+used by GDB back ends if you’ve written an exception handler. Some
+systems also implement a havebyte() for input as well.
+</p>
+<p>Other commonly included functions are routines for manipulating
+LED’s on the target (if they exist) or low level debug help. Typically a
+putnum() for printing words and bytes as a hex number is helpful, as
+well as a low-level print() to output simple strings.
+</p>
+<p>As libg++ uses the I/O routines in libc.a, if read and write work,
+then libg++ will also work with no additional changes.
+</p>
+
+<ul class="section-toc">
+<li><a href="#I_002fO-Support" accesskey="1">Making I/O work</a></li>
+<li><a href="#Memory-Support" accesskey="2">Routines for dynamic memory allocation</a></li>
+<li><a href="#Misc-Support" accesskey="3">Misc support routines</a></li>
+<li><a href="#Debugging" accesskey="4">Useful debugging functions</a></li>
+</ul>
+<hr>
+<div class="subsection" id="I_002fO-Support">
+<div class="header">
+<p>
+Next: <a href="#Memory-Support" accesskey="n" rel="next">Routines for dynamic memory allocation</a>, Up: <a href="#Libc" accesskey="u" rel="up">Libraries</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Making-I_002fO-work"></span><h4 class="subsection">3.4.1 Making I/O work</h4>
+
+<hr>
+</div>
+<div class="subsection" id="Memory-Support">
+<div class="header">
+<p>
+Next: <a href="#Misc-Support" accesskey="n" rel="next">Misc support routines</a>, Previous: <a href="#I_002fO-Support" accesskey="p" rel="prev">Making I/O work</a>, Up: <a href="#Libc" accesskey="u" rel="up">Libraries</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Routines-for-dynamic-memory-allocation"></span><h4 class="subsection">3.4.2 Routines for dynamic memory allocation</h4>
+<p>To support using any of the memory functions, you need to implement
+sbrk(). <code>malloc()</code>, <code>calloc()</code>, and <code>realloc()</code> all call
+<code>sbrk()</code> at there lowest level. <code>caddr_t</code> is defined elsewhere
+as <code>char *</code>. <code>RAMSIZE</code> is presently a compile time option. All
+this does is move a pointer to heap memory and check for the upper
+limit. <a href="#glue_002ec">Example libc support code</a>. <code>sbrk()</code> returns a
+pointer to the previous value before more memory was allocated.
+</p>
+<div class="example">
+<pre class="example">/* _end is set in the linker command file *
+extern caddr_t _end;/
+
+/* just in case, most boards have at least some memory */
+#ifndef RAMSIZE
+# define RAMSIZE (caddr_t)0x100000
+#endif
+
+/*
+ * sbrk -- changes heap size size. Get nbytes more
+ * RAM. We just increment a pointer in what's
+ * left of memory on the board.
+ */
+caddr_t
+sbrk(nbytes)
+ int nbytes;
+{
+ static caddr_t heap_ptr = NULL;
+ caddr_t base;
+
+ if (heap_ptr == NULL) {
+ heap_ptr = (caddr_t)&_end;
+ }
+
+ if ((RAMSIZE - heap_ptr) >= 0) {
+ base = heap_ptr;
+ heap_ptr += nbytes;
+ return (base);
+ } else {
+ errno = ENOMEM;
+ return ((caddr_t)-1);
+ }
+}
+</pre></div>
+
+<hr>
+</div>
+<div class="subsection" id="Misc-Support">
+<div class="header">
+<p>
+Next: <a href="#Debugging" accesskey="n" rel="next">Useful debugging functions</a>, Previous: <a href="#Memory-Support" accesskey="p" rel="prev">Routines for dynamic memory allocation</a>, Up: <a href="#Libc" accesskey="u" rel="up">Libraries</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Misc-support-routines"></span><h4 class="subsection">3.4.3 Misc support routines</h4>
+
+<p>These are called by <code>newlib</code> but don’t apply to the embedded
+environment. <code>isatty()</code> is self explanatory. <code>kill()</code> doesn’t
+apply either in an environment withno process control, so it justs
+exits, which is a similar enough behavior. <code>getpid()</code> can safely
+return any value greater than 1. The value doesn’t effect anything in
+<code>newlib</code> because once again there is no process control.
+</p>
+<div class="example">
+<pre class="example">/*
+ * isatty -- returns 1 if connected to a terminal device,
+ * returns 0 if not. Since we're hooked up to a
+ * serial port, we'll say yes and return a 1.
+ */
+int
+isatty(fd)
+ int fd;
+{
+ return (1);
+}
+
+/*
+ * getpid -- only one process, so just return 1.
+ */
+#define __MYPID 1
+int
+getpid()
+{
+ return __MYPID;
+}
+
+/*
+ * kill -- go out via exit...
+ */
+int
+kill(pid, sig)
+ int pid;
+ int sig;
+{
+ if(pid == __MYPID)
+ _exit(sig);
+ return 0;
+}
+</pre></div>
+
+<hr>
+</div>
+<div class="subsection" id="Debugging">
+<div class="header">
+<p>
+Previous: <a href="#Misc-Support" accesskey="p" rel="prev">Misc support routines</a>, Up: <a href="#Libc" accesskey="u" rel="up">Libraries</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Useful-debugging-functions"></span><h4 class="subsection">3.4.4 Useful debugging functions</h4>
+
+<p>There are always a few useful functions for debugging your project in
+progress. I typically implement a simple <code>print()</code> routine that
+runs standalone in liblgoss, with no <code>newlib</code> support. The I/O
+function <code>outbyte()</code> can also be used for low level debugging. Many
+times print will work when there are problems that cause <code>printf()</code> to
+cause an exception. <code>putnum()</code> is just to print out values in hex
+so they are easier to read.
+</p>
+<div class="example">
+<pre class="example">/*
+ * print -- do a raw print of a string
+ */
+int
+print(ptr)
+char *ptr;
+{
+ while (*ptr) {
+ outbyte (*ptr++);
+ }
+}
+
+/*
+ * putnum -- print a 32 bit number in hex
+ */
+int
+putnum (num)
+unsigned int num;
+{
+ char buffer[9];
+ int count;
+ char *bufptr = buffer;
+ int digit;
+
+ for (count = 7 ; count >= 0 ; count--) {
+ digit = (num >> (count * 4)) & 0xf;
+
+ if (digit <= 9)
+ *bufptr++ = (char) ('0' + digit);
+ else
+ *bufptr++ = (char) ('a' - 10 + digit);
+ }
+
+ *bufptr = (char) 0;
+ print (buffer);
+ return;
+}
+</pre></div>
+
+<p>If there are LEDs on the board, they can also be put to use for
+debugging when the serial I/O code is being written. I usually implement
+a <code>zylons()</code> function, which strobes the LEDS (if there is more
+than one) in sequence, creating a rotating effect. This is convenient
+between I/O to see if the target is still alive. Another useful LED
+function is <code>led_putnum()</code>, which takes a digit and displays it as
+a bit pattern or number. These usually have to be written in assembler
+for each target board. Here are a number of C based routines that may be
+useful.
+</p>
+<p><code>led_putnum()</code> puts a number on a single digit segmented
+LED display. This LED is set by setting a bit mask to an address, where
+1 turns the segment off, and 0 turns it on. There is also a little
+decimal point on the LED display, so it gets the leftmost bit. The other
+bits specify the segment location. The bits look like:
+</p>
+<div class="example">
+<pre class="example"> [d.p | g | f | e | d | c | b | a ] is the byte.
+</pre></div>
+
+<p>The locations are set up as:
+</p>
+<div class="example">
+<pre class="example"> a
+ -----
+ f | | b
+ | g |
+ -----
+ | |
+ e | | c
+ -----
+ d
+</pre></div>
+
+<p>This takes a number that’s already been converted to a string, and
+prints it.
+</p>
+<div class="example">
+<pre class="example">#define LED_ADDR 0xd00003
+
+void
+led_putnum ( num )
+char num;
+{
+ static unsigned char *leds = (unsigned char *)LED_ADDR;
+ static unsigned char num_bits [18] = {
+ 0xff, /* clear all */
+ 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x98, /* numbers 0-9 */
+ 0x98, 0x20, 0x3, 0x27, 0x21, 0x4, 0xe /* letters a-f */
+ };
+
+ if (num >= '0' && num <= '9')
+ num = (num - '0') + 1;
+
+ if (num >= 'a' && num <= 'f')
+ num = (num - 'a') + 12;
+
+ if (num == ' ')
+ num = 0;
+
+ *leds = num_bits[num];
+}
+
+/*
+ * zylons -- draw a rotating pattern. NOTE: this function never returns.
+ */
+void
+zylons()
+{
+ unsigned char *leds = (unsigned char *)LED_ADDR;
+ unsigned char curled = 0xfe;
+
+ while (1)
+ {
+ *leds = curled;
+ curled = (curled >> 1) | (curled << 7);
+ delay ( 200 );
+ }
+}
+</pre></div>
+
+
+<hr>
+</div>
+</div>
+</div>
+<div class="chapter" id="GDB">
+<div class="header">
+<p>
+Next: <a href="#Binutils" accesskey="n" rel="next">Binutils</a>, Previous: <a href="#Libraries" accesskey="p" rel="prev">Porting newlib</a>, Up: <a href="#Top" accesskey="u" rel="up">Embed with GNU</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Writing-a-new-GDB-backend"></span><h2 class="chapter">4 Writing a new GDB backend</h2>
+
+<p>Typically, either the low-level I/O routines are used for debugging, or
+LEDs, if present. It is much easier to use GDb for debugging an
+application. There are several different techniques used to have GDB work
+remotely. Commonly more than one kind of GDB interface is used to cober
+a wide variety of development needs.
+</p>
+<p>The most common style of GDB backend is an exception handler for
+breakpoints. This is also called a <em>gdb stub</em>, and is requires the
+two additional lines of init code in your <code>main()</code> routine. The GDB
+stubs all use the GDB <em>remote protocol</em>. When the application gets a
+breakpoint exception, it communicates to GDB on the host.
+</p>
+<p>Another common style of interfacing GDB to a target is by using an
+existing ROM monitor. These break down into two main kinds, a similar
+protocol to the GDB remote protocol, and an interface that uses the ROM
+monitor directly. This kind has GDB simulating a human operator, and all
+GDB does is work as a command formatter and parser.
+</p>
+
+<ul class="section-toc">
+<li><a href="#GNU-remote-protocol" accesskey="1">The standard remote protocol</a></li>
+<li><a href="#Exception-handler" accesskey="2">A linked in exception handler</a></li>
+<li><a href="#ROM-monitors" accesskey="3">Using a ROM monitor as a backend</a></li>
+<li><a href="#Other-remote-protocols" accesskey="4">Adding support for new protocols</a></li>
+</ul>
+<hr>
+<div class="section" id="GNU-remote-protocol">
+<div class="header">
+<p>
+Next: <a href="#Exception-handler" accesskey="n" rel="next">A linked in exception handler</a>, Up: <a href="#GDB" accesskey="u" rel="up">Writing a new GDB backend</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="The-standard-remote-protocol"></span><h3 class="section">4.1 The standard remote protocol</h3>
+
+<p>The standard remote protocol is a simple, packet based scheme. A debug
+packet whose contents are <em><data></em> is encapsulated for transmission
+in the form:
+</p>
+<div class="example">
+<pre class="example"> $ <data> # CSUM1 CSUM2
+</pre></div>
+
+<p><em><data></em> must be ASCII alphanumeric and cannot include characters
+<code>$</code> or <code>#</code>. If <em><data></em> starts with two characters
+followed by <code>:</code>, then the existing stubs interpret this as a
+sequence number. For example, the command <code>g</code> is used to read the
+values of the registers. So, a packet to do this would look like
+</p>
+<div class="example">
+<pre class="example"> $g#67
+</pre></div>
+
+<p><em>CSUM1</em> and <em>CSUM2</em> are an ascii representation in hex of an
+8-bit checksum of <em><data></em>, the most significant nibble is sent first.
+the hex digits 0-9,a-f are used.
+</p>
+<p>A simple protocol is used when communicating with the target. This is
+mainly to give a degree of error handling over the serial cable. For
+each packet transmitted successfully, the target responds with a
+<code>+</code> (<code>ACK</code>). If there was a transmission error, then the target
+responds with a <code>-</code> (<code>NAK</code>). An error is determined when the
+checksum doesn’t match the calculated checksum for that data record.
+Upon reciept of the <code>ACK</code>, <code>GDB</code> can then transmit the next
+packet.
+</p>
+<p>Here is a list of the main functions that need to be supported. Each data
+packet is a command with a set number of bytes in the command packet.
+Most commands either return data, or respond with a <code>NAK</code>. Commands
+that don’t return data respond with an <code>ACK</code>. All data values are
+ascii hex digits. Every byte needs two hex digits to represent t. This
+means that a byte with the value ‘<samp>7</samp>’ becomes ‘<samp>07</samp>’. On a 32 bit
+machine this works out to 8 characters per word. All of the bytes in a
+word are stored in the target byte order. When writing the host side of
+the GDB protocol, be careful of byte order, and make sure that the code
+will run on both big and little endian hosts and produce the same answers.
+</p>
+<p>These functions are the minimum required to make a GDB backend work. All
+other commands are optional, and not supported by all GDB backends.
+</p>
+<dl compact="compact">
+<dt><span>‘<samp>read registers <code>g</code></samp>’</span></dt>
+<dd>
+<p>returns <code>XXXXXXXX...</code>
+</p>
+<p>Registers are in the internal order for GDB, and the bytes in a register
+are in the same order the machine uses. All values are in sequence
+starting with register 0. All registers are listed in the same packet. A
+sample packet would look like <code>$g#</code>.
+</p>
+</dd>
+<dt><span>‘<samp>write registers <code>GXXXXXXXX...</code></samp>’</span></dt>
+<dd><p><code>XXXXXXXX</code> is the value to set the register to. Registers are in
+the internal order for GDB, and the bytes in a register are in the same
+order the machine uses. All values are in sequence starting with
+register 0. All registers values are listed in the same packet. A sample
+packet would look like <code>$G000000001111111122222222...#</code>
+</p>
+<p>returns <code>ACK</code> or <code>NAK</code>
+</p>
+</dd>
+<dt><span>‘<samp>read memory <code>mAAAAAAAA,LLLL</code></samp>’</span></dt>
+<dd><p><code>AAAAAAAA</code> is address, <code>LLLL</code> is length. A sample packet would
+look like <code>$m00005556,0024#</code>. This would request 24 bytes starting
+at address <em>00005556</em>
+</p>
+<p>returns <code>XXXXXXXX...</code>
+<code>XXXXXXXX</code> is the memory contents. Fewer bytes than requested will
+be returned if only part of the data can be read. This can be determined
+by counting the values till the end of packet <code>#</code> is seen and
+comparing that with the total count of bytes that was requested.
+</p>
+</dd>
+<dt><span>‘<samp>write memory <code>MAAAAAAAA,LLLL:XXXXXXXX</code></samp>’</span></dt>
+<dd><p><code>AAAAAAAA</code> is the starting address, <code>LLLL</code> is the number of
+bytes to be written, and <code>XXXXXXXX</code> is value to be written. A
+sample packet would look like
+<code>$M00005556,0024:101010101111111100000000...#</code>
+</p>
+<p>returns <code>ACK</code> or <code>NAK</code> for an error. <code>NAK</code> is also
+returned when only part of the data is written.
+</p>
+</dd>
+<dt><span>‘<samp>continue <code>cAAAAAAAAA</code></samp>’</span></dt>
+<dd><p><code>AAAAAAAA</code> is address to resume execution at. If <code>AAAAAAAA</code> is
+omitted, resume at the curent address of the <code>pc</code> register.
+</p>
+<p>returns the same replay as <code>last signal</code>. There is no immediate
+replay to <code>cont</code> until the next breakpoint is reached, and the
+program stops executing.
+</p>
+</dd>
+<dt><span>‘<samp>step sAA..AA</samp>’</span></dt>
+<dd><p><code>AA..AA</code> is address to resume
+If <code>AA..AA</code> is omitted, resume at same address.
+</p>
+<p>returns the same replay as <code>last signal</code>. There is no immediate
+replay to <code>step</code> until the next breakpoint is reached, and the
+program stops executing.
+</p>
+</dd>
+<dt><span>‘<samp>last signal <code>?</code></samp>’</span></dt>
+<dd>
+<p>This returns one of the following:
+</p>
+<ul>
+<li> <code>SAA</code>
+Where <code>AA</code> is the number of the last signal.
+Exceptions on the target are converted to the most similar Unix style
+signal number, like <code>SIGSEGV</code>. A sample response of this type would
+look like <code>$S05#</code>.
+
+</li><li> TAAnn:XXXXXXXX;nn:XXXXXXXX;nn:XXXXXXXX;
+<code>AA</code> is the signal number.
+<code>nn</code> is the register number.
+<code>XXXXXXXX</code> is the register value.
+
+</li><li> WAA
+The process exited, and <code>AA</code> is the exit status. This is only
+applicable for certains sorts of targets.
+
+</li></ul>
+
+<p>These are used in some GDB backends, but not all.
+</p>
+</dd>
+<dt><span>‘<samp>write reg <code>Pnn=XXXXXXXX</code></samp>’</span></dt>
+<dd><p>Write register <code>nn</code> with value <code>XXXXXXXX</code>.
+</p>
+<p>returns <code>ACK</code> or <code>NAK</code>
+</p>
+</dd>
+<dt><span>‘<samp>kill request k</samp>’</span></dt>
+<dt><span>‘<samp>toggle debug d</samp>’</span></dt>
+<dd><p>toggle debug flag (see 386 & 68k stubs)
+</p>
+</dd>
+<dt><span>‘<samp>reset r</samp>’</span></dt>
+<dd><p>reset – see sparc stub.
+</p>
+</dd>
+<dt><span>‘<samp>reserved <code>other</code></samp>’</span></dt>
+<dd><p>On other requests, the stub should ignore the request and send an empty
+response <code>$#<checksum></code>. This way we can extend the protocol and GDB
+can tell whether the stub it is talking to uses the old or the new.
+</p>
+</dd>
+<dt><span>‘<samp>search <code>tAA:PP,MM</code></samp>’</span></dt>
+<dd><p>Search backwards starting at address <code>AA</code> for a match with pattern
+PP and mask <code>MM</code>. <code>PP</code> and <code>MM</code> are 4 bytes.
+</p>
+</dd>
+<dt><span>‘<samp>general query <code>qXXXX</code></samp>’</span></dt>
+<dd><p>Request info about XXXX.
+</p>
+</dd>
+<dt><span>‘<samp>general set <code>QXXXX=yyyy</code></samp>’</span></dt>
+<dd><p>Set value of <code>XXXX</code> to <code>yyyy</code>.
+</p>
+</dd>
+<dt><span>‘<samp>query sect offs <code>qOffsets</code></samp>’</span></dt>
+<dd><p>Get section offsets. Reply is <code>Text=xxx;Data=yyy;Bss=zzz</code>
+</p>
+</dd>
+<dt><span>‘<samp>console output Otext</samp>’</span></dt>
+<dd><p>Send text to stdout. The text gets display from the target side of the
+serial connection.
+</p>
+</dd>
+</dl>
+
+<p>Responses can be run-length encoded to save space. A <code>*</code>means that
+the next character is an ASCII encoding giving a repeat count which
+stands for that many repetitions of the character preceding the <code>*</code>.
+The encoding is n+29, yielding a printable character where n >=3
+(which is where run length encoding starts to win). You can’t use a
+value of where n >126 because it’s only a two byte value. An example
+would be a <code>0*03</code> means the same thing as <code>0000</code>.
+</p>
+<hr>
+</div>
+<div class="section" id="Exception-handler">
+<div class="header">
+<p>
+Next: <a href="#ROM-monitors" accesskey="n" rel="next">Using a ROM monitor as a backend</a>, Previous: <a href="#GNU-remote-protocol" accesskey="p" rel="prev">The standard remote protocol</a>, Up: <a href="#GDB" accesskey="u" rel="up">Writing a new GDB backend</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="A-linked-in-exception-handler"></span><h3 class="section">4.2 A linked in exception handler</h3>
+
+<p>A <em>GDB stub</em> consists of two parts, support for the exception
+handler, and the exception handler itself. The exception handler needs
+to communicate to GDB on the host whenever there is a breakpoint
+exception. When GDB starts a program running on the target, it’s polling
+the serial port during execution looking for any debug packets. So when
+a breakpoint occurs, the exception handler needs to save state, and send
+a GDB remote protocol packet to GDB on the host. GDB takes any output
+that isn’t a debug command packet and displays it in the command window.
+</p>
+<p>Support for the exception handler varies between processors, but the
+minimum supported functions are those needed by GDB. These are functions
+to support the reading and writing of registers, the reading and writing
+of memory, start execution at an address, single step, and last signal.
+Sometimes other functions for adjusting the baud rate, or resetting the
+hardware are implemented.
+</p>
+<p>Once GDB gets the command packet from the breakpoint, it will read a few
+registers and memory locations an then wait for the user. When the user
+types <code>run</code> or <code>continue</code> a <code>continue</code> command is issued
+to the backend, and control returns from the breakpoint routine to the
+application.
+</p>
+<hr>
+</div>
+<div class="section" id="ROM-monitors">
+<div class="header">
+<p>
+Next: <a href="#Other-remote-protocols" accesskey="n" rel="next">Adding support for new protocols</a>, Previous: <a href="#Exception-handler" accesskey="p" rel="prev">A linked in exception handler</a>, Up: <a href="#GDB" accesskey="u" rel="up">Writing a new GDB backend</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Using-a-ROM-monitor-as-a-backend"></span><h3 class="section">4.3 Using a ROM monitor as a backend</h3>
+<p>GDB also can mimic a human user and use a ROM monitors normal debug
+commands as a backend. This consists mostly of sending and parsing
+<code>ASCII</code> strings. All the ROM monitor interfaces share a common set
+of routines in <code>gdb/monitor.c</code>. This supports adding new ROM
+monitor interfaces by filling in a structure with the common commands
+GDB needs. GDb already supports several command ROM monitors, including
+Motorola’s <code>Bug</code> monitor for their VME boards, and the Rom68k
+monitor by Integrated Systems, Inc. for various m68k based boards. GDB
+also supports the custom ROM monitors on the WinBond and Oki PA based
+targets. There is builtin support for loading files to ROM monitors
+specifically. GDB can convert a binary into an srecord and then load it
+as an ascii file, or using <code>xmodem</code>.
+</p>
+
+<hr>
+</div>
+<div class="section" id="Other-remote-protocols">
+<div class="header">
+<p>
+Previous: <a href="#ROM-monitors" accesskey="p" rel="prev">Using a ROM monitor as a backend</a>, Up: <a href="#GDB" accesskey="u" rel="up">Writing a new GDB backend</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Adding-support-for-new-protocols"></span><h3 class="section">4.4 Adding support for new protocols</h3>
+
+<hr>
+<span id="Binutils"></span><div class="header">
+<p>
+Next: <a href="#Code-Listings" accesskey="n" rel="next">Code Listings</a>, Previous: <a href="#GDB" accesskey="p" rel="prev">Writing a new GDB backend</a>, Up: <a href="#Top" accesskey="u" rel="up">Embed with GNU</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<h4 class="node-heading">Binutils</h4>
+
+<hr>
+</div>
+</div>
+<div class="appendix" id="Code-Listings">
+<div class="header">
+<p>
+Next: <a href="#idp_002eld" accesskey="n" rel="next">Linker script for the IDP board</a>, Previous: <a href="#Binutils" accesskey="p" rel="prev">Binutils</a>, Up: <a href="#Top" accesskey="u" rel="up">Embed with GNU</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Code-Listings-1"></span><h2 class="appendix">Appendix A Code Listings</h2>
+
+
+<ul class="section-toc">
+<li><a href="#idp_002eld" accesskey="1">Linker script for the IDP board</a></li>
+<li><a href="#crt0_002eS" accesskey="2">crt0.S - The startup file</a></li>
+<li><a href="#glue_002ec" accesskey="3">C based "glue" code.</a></li>
+<li><a href="#mvme_002eS" accesskey="4">I/O assembler code sample</a></li>
+<li><a href="#io_002ec" accesskey="5">I/O code sample</a></li>
+<li><a href="#leds_002ec" accesskey="6">Led control sample</a></li>
+</ul>
+<hr>
+<div class="section" id="idp_002eld">
+<div class="header">
+<p>
+Next: <a href="#crt0_002eS" accesskey="n" rel="next">crt0.S - The startup file</a>, Previous: <a href="#Code-Listings" accesskey="p" rel="prev">Code Listings</a>, Up: <a href="#Code-Listings" accesskey="u" rel="up">Code Listings</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Linker-script-for-the-IDP-board"></span><h3 class="section">A.1 Linker script for the IDP board</h3>
+
+<p>This is the linker script script that is used on the Motorola IDP board.
+</p>
+<div class="example">
+<pre class="example">STARTUP(crt0.o)
+OUTPUT_ARCH(m68k)
+INPUT(idp.o)
+SEARCH_DIR(.)
+__DYNAMIC = 0;
+/*
+ * Setup the memory map of the MC68ec0x0 Board (IDP)
+ * stack grows up towards high memory. This works for
+ * both the rom68k and the mon68k monitors.
+ */
+MEMORY
+{
+ ram : ORIGIN = 0x10000, LENGTH = 2M
+}
+/*
+ * stick everything in ram (of course)
+ */
+SECTIONS
+{
+ .text :
+ {
+ CREATE_OBJECT_SYMBOLS
+ *(.text)
+ etext = .;
+ __CTOR_LIST__ = .;
+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
+ *(.ctors)
+ LONG(0)
+ __CTOR_END__ = .;
+ __DTOR_LIST__ = .;
+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
+ *(.dtors)
+ LONG(0)
+ __DTOR_END__ = .;
+ *(.lit)
+ *(.shdata)
+ } > ram
+ .shbss SIZEOF(.text) + ADDR(.text) : {
+ *(.shbss)
+ }
+ .talias : { } > ram
+ .data : {
+ *(.data)
+ CONSTRUCTORS
+ _edata = .;
+ } > ram
+
+ .bss SIZEOF(.data) + ADDR(.data) :
+ {
+ __bss_start = ALIGN(0x8);
+ *(.bss)
+ *(COMMON)
+ end = ALIGN(0x8);
+ _end = ALIGN(0x8);
+ __end = ALIGN(0x8);
+ }
+ .mstack : { } > ram
+ .rstack : { } > ram
+ .stab . (NOLOAD) :
+ {
+ [ .stab ]
+ }
+ .stabstr . (NOLOAD) :
+ {
+ [ .stabstr ]
+ }
+}
+</pre></div>
+
+<hr>
+</div>
+<div class="section" id="crt0_002eS">
+<div class="header">
+<p>
+Next: <a href="#glue_002ec" accesskey="n" rel="next">C based "glue" code.</a>, Previous: <a href="#idp_002eld" accesskey="p" rel="prev">Linker script for the IDP board</a>, Up: <a href="#Code-Listings" accesskey="u" rel="up">Code Listings</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="crt0_002eS-_002d-The-startup-file"></span><h3 class="section">A.2 crt0.S - The startup file</h3>
+
+<div class="example">
+<pre class="example">/*
+ * crt0.S -- startup file for m68k-coff
+ *
+ */
+
+ .title "crt0.S for m68k-coff"
+
+/* These are predefined by new versions of GNU cpp. */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+/* ANSI concatenation macros. */
+
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+
+/* Use the right prefix for global labels. */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers. */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+#define d0 REG (d0)
+#define d1 REG (d1)
+#define d2 REG (d2)
+#define d3 REG (d3)
+#define d4 REG (d4)
+#define d5 REG (d5)
+#define d6 REG (d6)
+#define d7 REG (d7)
+#define a0 REG (a0)
+#define a1 REG (a1)
+#define a2 REG (a2)
+#define a3 REG (a3)
+#define a4 REG (a4)
+#define a5 REG (a5)
+#define a6 REG (a6)
+#define fp REG (fp)
+#define sp REG (sp)
+
+/*
+ * Set up some room for a stack. We just grab a chunk of memory.
+ */
+ .set stack_size, 0x2000
+ .comm SYM (stack), stack_size
+
+/*
+ * Define an empty environment.
+ */
+ .data
+ .align 2
+SYM (environ):
+ .long 0
+
+ .align 2
+ .text
+ .global SYM (stack)
+
+ .global SYM (main)
+ .global SYM (exit)
+/*
+ * This really should be __bss_start, not SYM (__bss_start).
+ */
+ .global __bss_start
+
+/*
+ * start -- set things up so the application will run.
+ */
+SYM (start):
+ link a6, #-8
+ moveal #SYM (stack) + stack_size, sp
+
+/*
+ * zerobss -- zero out the bss section
+ */
+ moveal #__bss_start, a0
+ moveal #SYM (end), a1
+1:
+ movel #0, (a0)
+ leal 4(a0), a0
+ cmpal a0, a1
+ bne 1b
+
+/*
+ * Call the main routine from the application to get it going.
+ * main (argc, argv, environ)
+ * We pass argv as a pointer to NULL.
+ */
+ pea 0
+ pea SYM (environ)
+ pea sp@(4)
+ pea 0
+ jsr SYM (main)
+ movel d0, sp@-
+
+/*
+ * _exit -- Exit from the application. Normally we cause a user trap
+ * to return to the ROM monitor for another run.
+ */
+SYM (exit):
+ trap #0
+</pre></div>
+
+<hr>
+</div>
+<div class="section" id="glue_002ec">
+<div class="header">
+<p>
+Next: <a href="#mvme_002eS" accesskey="n" rel="next">I/O assembler code sample</a>, Previous: <a href="#crt0_002eS" accesskey="p" rel="prev">crt0.S - The startup file</a>, Up: <a href="#Code-Listings" accesskey="u" rel="up">Code Listings</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="C-based-_0022glue_0022-code_002e"></span><h3 class="section">A.3 C based "glue" code.</h3>
+
+<div class="example">
+<pre class="example">
+
+/*
+ * glue.c -- all the code to make GCC and the libraries run on
+ * a bare target board. These should work with any
+ * target if inbyte() and outbyte() exist.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* FIXME: this is a hack till libc builds */
+__main()
+{
+ return;
+}
+
+#undef errno
+int errno;
+
+extern caddr_t _end; /* _end is set in the linker command file */
+extern int outbyte();
+extern unsigned char inbyte();
+extern int havebyte();
+
+/* just in case, most boards have at least some memory */
+#ifndef RAMSIZE
+# define RAMSIZE (caddr_t)0x100000
+#endif
+
+/*
+ * read -- read bytes from the serial port. Ignore fd, since
+ * we only have stdin.
+ */
+int
+read(fd, buf, nbytes)
+ int fd;
+ char *buf;
+ int nbytes;
+{
+ int i = 0;
+
+ for (i = 0; i < nbytes; i++) {
+ *(buf + i) = inbyte();
+ if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) {
+ (*(buf + i)) = 0;
+ break;
+ }
+ }
+ return (i);
+}
+
+/*
+ * write -- write bytes to the serial port. Ignore fd, since
+ * stdout and stderr are the same. Since we have no filesystem,
+ * open will only return an error.
+ */
+int
+write(fd, buf, nbytes)
+ int fd;
+ char *buf;
+ int nbytes;
+{
+ int i;
+
+ for (i = 0; i < nbytes; i++) {
+ if (*(buf + i) == '\n') {
+ outbyte ('\r');
+ }
+ outbyte (*(buf + i));
+ }
+ return (nbytes);
+}
+
+/*
+ * open -- open a file descriptor. We don't have a filesystem, so
+ * we return an error.
+ */
+int
+open(buf, flags, mode)
+ char *buf;
+ int flags;
+ int mode;
+{
+ errno = EIO;
+ return (-1);
+}
+
+/*
+ * close -- close a file descriptor. We don't need
+ * to do anything, but pretend we did.
+ */
+int
+close(fd)
+ int fd;
+{
+ return (0);
+}
+
+/*
+ * sbrk -- changes heap size size. Get nbytes more
+ * RAM. We just increment a pointer in what's
+ * left of memory on the board.
+ */
+caddr_t
+sbrk(nbytes)
+ int nbytes;
+{
+ static caddr_t heap_ptr = NULL;
+ caddr_t base;
+
+ if (heap_ptr == NULL) {
+ heap_ptr = (caddr_t)&_end;
+ }
+
+ if ((RAMSIZE - heap_ptr) >= 0) {
+ base = heap_ptr;
+ heap_ptr += nbytes;
+ return (base);
+ } else {
+ errno = ENOMEM;
+ return ((caddr_t)-1);
+ }
+}
+
+/*
+ * isatty -- returns 1 if connected to a terminal device,
+ * returns 0 if not. Since we're hooked up to a
+ * serial port, we'll say yes and return a 1.
+ */
+int
+isatty(fd)
+ int fd;
+{
+ return (1);
+}
+
+/*
+ * lseek -- move read/write pointer. Since a serial port
+ * is non-seekable, we return an error.
+ */
+off_t
+lseek(fd, offset, whence)
+ int fd;
+ off_t offset;
+ int whence;
+{
+ errno = ESPIPE;
+ return ((off_t)-1);
+}
+
+/*
+ * fstat -- get status of a file. Since we have no file
+ * system, we just return an error.
+ */
+int
+fstat(fd, buf)
+ int fd;
+ struct stat *buf;
+{
+ errno = EIO;
+ return (-1);
+}
+
+/*
+ * getpid -- only one process, so just return 1.
+ */
+#define __MYPID 1
+int
+getpid()
+{
+ return __MYPID;
+}
+
+/*
+ * kill -- go out via exit...
+ */
+int
+kill(pid, sig)
+ int pid;
+ int sig;
+{
+ if(pid == __MYPID)
+ _exit(sig);
+ return 0;
+}
+
+/*
+ * print -- do a raw print of a string
+ */
+int
+print(ptr)
+char *ptr;
+{
+ while (*ptr) {
+ outbyte (*ptr++);
+ }
+}
+
+/*
+ * putnum -- print a 32 bit number in hex
+ */
+int
+putnum (num)
+unsigned int num;
+{
+ char buffer[9];
+ int count;
+ char *bufptr = buffer;
+ int digit;
+
+ for (count = 7 ; count >= 0 ; count--) {
+ digit = (num >> (count * 4)) & 0xf;
+
+ if (digit <= 9)
+ *bufptr++ = (char) ('0' + digit);
+ else
+ *bufptr++ = (char) ('a' - 10 + digit);
+ }
+
+ *bufptr = (char) 0;
+ print (buffer);
+ return;
+}
+</pre></div>
+
+<hr>
+</div>
+<div class="section" id="mvme_002eS">
+<div class="header">
+<p>
+Next: <a href="#io_002ec" accesskey="n" rel="next">I/O code sample</a>, Previous: <a href="#glue_002ec" accesskey="p" rel="prev">C based "glue" code.</a>, Up: <a href="#Code-Listings" accesskey="u" rel="up">Code Listings</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="I_002fO-assembler-code-sample"></span><h3 class="section">A.4 I/O assembler code sample</h3>
+
+<div class="example">
+<pre class="example">/*
+ * mvme.S -- board support for m68k
+ */
+
+ .title "mvme.S for m68k-coff"
+
+/* These are predefined by new versions of GNU cpp. */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+/* ANSI concatenation macros. */
+
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+
+/* Use the right prefix for global labels. */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers. */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+#define d0 REG (d0)
+#define d1 REG (d1)
+#define d2 REG (d2)
+#define d3 REG (d3)
+#define d4 REG (d4)
+#define d5 REG (d5)
+#define d6 REG (d6)
+#define d7 REG (d7)
+#define a0 REG (a0)
+#define a1 REG (a1)
+#define a2 REG (a2)
+#define a3 REG (a3)
+#define a4 REG (a4)
+#define a5 REG (a5)
+#define a6 REG (a6)
+#define fp REG (fp)
+#define sp REG (sp)
+#define vbr REG (vbr)
+
+ .align 2
+ .text
+ .global SYM (_exit)
+ .global SYM (outln)
+ .global SYM (outbyte)
+ .global SYM (putDebugChar)
+ .global SYM (inbyte)
+ .global SYM (getDebugChar)
+ .global SYM (havebyte)
+ .global SYM (exceptionHandler)
+
+ .set vbr_size, 0x400
+ .comm SYM (vbr_table), vbr_size
+
+/*
+ * inbyte -- get a byte from the serial port
+ * d0 - contains the byte read in
+ */
+ .align 2
+SYM (getDebugChar): /* symbol name used by m68k-stub */
+SYM (inbyte):
+ link a6, #-8
+ trap #15
+ .word inchr
+ moveb sp@, d0
+ extbl d0
+ unlk a6
+ rts
+
+/*
+ * outbyte -- sends a byte out the serial port
+ * d0 - contains the byte to be sent
+ */
+ .align 2
+SYM (putDebugChar): /* symbol name used by m68k-stub */
+SYM (outbyte):
+ link fp, #-4
+ moveb fp@(11), sp@
+ trap #15
+ .word outchr
+ unlk fp
+ rts
+
+/*
+ * outln -- sends a string of bytes out the serial port with a CR/LF
+ * a0 - contains the address of the string's first byte
+ * a1 - contains the address of the string's last byte
+ */
+ .align 2
+SYM (outln):
+ link a6, #-8
+ moveml a0/a1, sp@
+ trap #15
+ .word outln
+ unlk a6
+ rts
+
+/*
+ * outstr -- sends a string of bytes out the serial port without a CR/LF
+ * a0 - contains the address of the string's first byte
+ * a1 - contains the address of the string's last byte
+ */
+ .align 2
+SYM (outstr):
+ link a6, #-8
+ moveml a0/a1, sp@
+ trap #15
+ .word outstr
+ unlk a6
+ rts
+
+/*
+ * havebyte -- checks to see if there is a byte in the serial port,
+ * returns 1 if there is a byte, 0 otherwise.
+ */
+SYM (havebyte):
+ trap #15
+ .word instat
+ beqs empty
+ movel #1, d0
+ rts
+empty:
+ movel #0, d0
+ rts
+
+/*
+ * These constants are for the MVME-135 board's boot monitor. They
+ * are used with a TRAP #15 call to access the monitor's I/O routines.
+ * they must be in the word following the trap call.
+ */
+ .set inchr, 0x0
+ .set instat, 0x1
+ .set inln, 0x2
+ .set readstr, 0x3
+ .set readln, 0x4
+ .set chkbrk, 0x5
+
+ .set outchr, 0x20
+ .set outstr, 0x21
+ .set outln, 0x22
+ .set write, 0x23
+ .set writeln, 0x24
+ .set writdln, 0x25
+ .set pcrlf, 0x26
+ .set eraseln, 0x27
+ .set writd, 0x28
+ .set sndbrk, 0x29
+
+ .set tm_ini, 0x40
+ .set dt_ini, 0x42
+ .set tm_disp, 0x43
+ .set tm_rd, 0x44
+
+ .set redir, 0x60
+ .set redir_i, 0x61
+ .set redir_o, 0x62
+ .set return, 0x63
+ .set bindec, 0x64
+
+ .set changev, 0x67
+ .set strcmp, 0x68
+ .set mulu32, 0x69
+ .set divu32, 0x6A
+ .set chk_sum, 0x6B
+
+</pre></div>
+
+<hr>
+</div>
+<div class="section" id="io_002ec">
+<div class="header">
+<p>
+Next: <a href="#leds_002ec" accesskey="n" rel="next">Led control sample</a>, Previous: <a href="#mvme_002eS" accesskey="p" rel="prev">I/O assembler code sample</a>, Up: <a href="#Code-Listings" accesskey="u" rel="up">Code Listings</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="I_002fO-code-sample"></span><h3 class="section">A.5 I/O code sample</h3>
+
+<div class="example">
+<pre class="example">#include "w89k.h"
+
+/*
+ * outbyte -- shove a byte out the serial port. We wait till the byte
+ */
+int
+outbyte(byte)
+ unsigned char byte;
+{
+ while ((inp(RS232REG) & TRANSMIT) == 0x0) { } ;
+ return (outp(RS232PORT, byte));
+}
+
+/*
+ * inbyte -- get a byte from the serial port
+ */
+unsigned char
+inbyte()
+{
+ while ((inp(RS232REG) & RECEIVE) == 0x0) { };
+ return (inp(RS232PORT));
+}
+</pre></div>
+
+<hr>
+</div>
+<div class="section" id="leds_002ec">
+<div class="header">
+<p>
+Previous: <a href="#io_002ec" accesskey="p" rel="prev">I/O code sample</a>, Up: <a href="#Code-Listings" accesskey="u" rel="up">Code Listings</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<span id="Led-control-sample"></span><h3 class="section">A.6 Led control sample</h3>
+
+<div class="example">
+<pre class="example">/*
+ * leds.h -- control the led's on a Motorola mc68ec0x0 board.
+ */
+
+#ifndef __LEDS_H__
+#define __LEDS_H__
+
+#define LED_ADDR 0xd00003
+#define LED_0 ~0x1
+#define LED_1 ~0x2
+#define LED_2 ~0x4
+#define LED_3 ~0x8
+#define LED_4 ~0x10
+#define LED_5 ~0x20
+#define LED_6 ~0x40
+#define LED_7 ~0x80
+#define LEDS_OFF 0xff
+#define LEDS_ON 0x0
+
+#define FUDGE(x) ((x >= 0xa && x <= 0xf) ? (x + 'a') & 0x7f : (x + '0') & 0x7f)
+
+extern void led_putnum( char );
+
+#endif /* __LEDS_H__ */
+
+/*
+ * leds.c -- control the led's on a Motorola mc68ec0x0 (IDP)board.
+ */
+#include "leds.h"
+
+void zylons();
+void led_putnum();
+
+/*
+ * led_putnum -- print a hex number on the LED. the value of num must be a char with
+ * the ascii value. ie... number 0 is '0', a is 'a', ' ' (null) clears
+ * the led display.
+ * Setting the bit to 0 turns it on, 1 turns it off.
+ * the LED's are controlled by setting the right bit mask in the base
+ * address.
+ * The bits are:
+ * [d.p | g | f | e | d | c | b | a ] is the byte.
+ *
+ * The locations are:
+ *
+ * a
+ * -----
+ * f | | b
+ * | g |
+ * -----
+ * | |
+ * e | | c
+ * -----
+ * d . d.p (decimal point)
+ */
+void
+led_putnum ( num )
+char num;
+{
+ static unsigned char *leds = (unsigned char *)LED_ADDR;
+ static unsigned char num_bits [18] = {
+ 0xff, /* clear all */
+ 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x98, /* numbers 0-9 */
+ 0x98, 0x20, 0x3, 0x27, 0x21, 0x4, 0xe /* letters a-f */
+ };
+
+ if (num >= '0' && num <= '9')
+ num = (num - '0') + 1;
+
+ if (num >= 'a' && num <= 'f')
+ num = (num - 'a') + 12;
+
+ if (num == ' ')
+ num = 0;
+
+ *leds = num_bits[num];
+}
+
+/*
+ * zylons -- draw a rotating pattern. NOTE: this function never returns.
+ */
+void
+zylons()
+{
+ unsigned char *leds = (unsigned char *)LED_ADDR;
+ unsigned char curled = 0xfe;
+
+ while (1)
+ {
+ *leds = curled;
+ curled = (curled >> 1) | (curled << 7);
+ delay ( 200 );
+ }
+}
+</pre></div>
+
+</div>
+</div>
+</div>
+
+
+
+</body>
+</html>
--
2.34.1
next prev parent reply other threads:[~2022-02-15 2:25 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-15 2:25 [PATCH htdocs 0/7] various website updates Mike Frysinger
2022-02-15 2:25 ` [PATCH htdocs 2/7] switch to https:// for many sites Mike Frysinger
2022-02-15 2:25 ` Mike Frysinger [this message]
2022-02-15 2:25 ` [PATCH htdocs 5/7] simplify mailing list news links Mike Frysinger
2022-02-15 2:25 ` [PATCH htdocs 6/7] update news entries for last few years Mike Frysinger
2022-02-15 2:25 ` [PATCH htdocs 7/7] update autotools faq entry to match current tree Mike Frysinger
2022-02-15 2:27 ` [PATCH htdocs 1/7] crush images Mike Frysinger
2022-02-17 6:27 ` Brian Inglis
2022-02-17 15:56 ` Brian Inglis
2022-02-15 2:28 ` [PATCH htdocs 4/7] refressh libc & libm manual from current git Mike Frysinger
2022-02-16 10:56 ` [PATCH htdocs 0/7] various website updates Corinna Vinschen
2022-02-17 1:39 ` Mike Frysinger
2022-02-17 12:07 ` Corinna Vinschen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220215022552.11267-3-vapier@gentoo.org \
--to=vapier@gentoo.org \
--cc=newlib@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).