.. index:: linker

Linker
======

The linker is used to combine the output of the assembler and the RPN
compiler into a module file.

.. running:: linker lnnut
.. literalinclude:: gen/LinkerSignOn.text
   :language: none

You need to specify the object files, a module description file and a
linker rules file as input.

From each object file comes named relocatable section fragments that
are to be placed at a final position in some memory. The link process
is defined by a set of rules that govern where section fragments can
be placed.


.. index:: memory

Memory
------

A *memory* is a named entity that gives a continuous range of storage
locations. On the HP-41, a 4K page is normally treated as a memory. A
description of a memory contains the following attributes:

.. index:: memory;name

name
   The name of the memory. The memory name is the identifier used for
   a particular memory area

.. index:: memory;address range

address range
   The start and end address (inclusive) specify the address range of
   the memory.

position
   Tells whether the memory is fixed or position independent. For a
   page relocatable module  you want to specify this as ``(position
   independent)``. The alternative is ``(position fixed)`` if you are
   writing code for a fixed address.

section
   Here you put the section names you want to bind to the current memory.

.. index:: memory;address range, checksum

checksum
  An optional address where a checksum will be stored. For the HP-41
  it should be the highest address of a 4K page (last address in
  memory). You should also specify the checksum algorithm to be used.
  The normal value to use here is ``(checksum #xFFF hp41)``.

.. index:: fill word, memory;fill

fill word
  Value used to fill unused locations in the memory. Defaults to zero,
  but can specified as ``(fill 0)``.


.. index:: rules for linking, linker rules

Linker rules file
-----------------

The rules file (extension ``.scm``) describes how the section
fragments are to be laid out in memory. This file serves three
purposes, *a*) it defines the actual memories; *b*) it defines which
sections to expect; and *c*) it describes where the sections can
be placed in memory.


.. index:: memory;rule linking
.. index:: section;placement

Memory rule
^^^^^^^^^^^

A memory rule defines a memory. It also defines which sections (by
name) that will go into that memory. There can be multiple memory
rules in a rule file and you will need one for each memory block.

A simple rule file for a relocatable 4K module where you have used a
single section ``CODE`` may look as:

.. literalinclude:: Plugin4K.scm
   :language: scheme

While the use of spacing for indentation here is unimportant to the
linker tool, it makes the file easier to read. However, the use of
characters like the single quote, period and parentheses are important
to make the linker tool able to parse the file correctly.

A slightly more advanced example with a 8K relocatable module with
some sections:

.. literalinclude:: Plugin8K.scm
   :language: scheme


.. index:: section; placement

Section placement
^^^^^^^^^^^^^^^^^

There are several ways to control how sections are placed. Here we
walk through some typical cases, consider this linker rules file:

.. literalinclude:: sectionVariants.scm
   :language: scheme

Free placement
..............

The ``Code1`` and ``Code2`` sections appear alone (no surrounding
parentheses). Sections with these names can be placed anywhere in the
defined memory.

Restricted placement
....................

The ``CodeQ0`` section has an address range, which should be a
sub-range of the memory range. It can be placed anywhere within the
sub-range.

Fixed placement
...............

The ``Tail`` section will be placed starting at address ``FF4``.

Fixed section group placement
.............................

A FAT (function address table) consists of three parts. First an
identifier, then a table of functions and finally an end marker. The
section group ``ID``, ``FAT`` and ``FATEND`` are placed together
starting at address 0.
The order in which section fragments are placed are important when
setting up a FAT, as this also gives the XROM number allocation.

In this example section fragments are placed so that all ``ID``
fragments comes first, followed by all ``FAT`` fragments and finally
the ``FATEND`` fragments.

In a real setup, ``ID`` and ``FATEND`` probably consist of single
section fragments. However, the ``FAT`` section is likely to consist
of multiple section fragments.

The order in which ``FAT`` section fragments are placed here, is the
same as the order in which the object files appear on the command line
to the linker. If there are multiple ``FAT`` sections within the same
object file, the order among them are decided by the order in which
they were encountered when compiling the source file.

.. note::
   You will most likely want to ensure consistent ordering in the FAT,
   as the actual XROM number allocated for each function depends on
   it.


.. index:: banking

Banking
^^^^^^^

To make a module with banked pages, [#banked]_ you place more than one
memory at the same address, but with different bank numbers using the
``bank`` attribute.

The following rule file shows how to use the ``bank`` attribute for
banked memory:

.. literalinclude:: Plugin4KBanked.scm
   :language: scheme

These bank numbers are only used for detecting problems when resolving
external references at the link stage.

The actual bank and page layout of the module is described in the
module description file (``.moddesc``). The memories in the linker
control file are paired with pages in the module description file
based on their names. The meta data of the module description file is
combined with the memory images to form the final module image.


.. index:: list files;linker
.. index:: memory; size, allocated memory, used memory
           .. index:: section; fragments
.. index:: FAT, function address table

Linker list files
-----------------

The linker list file that can be optionally generated shows how the
section fragments are distributed in the memories and the total size
of memory allocated.

.. literalinclude:: example/games/games.lst
   :language: none

The `Memories summary` section summarizes the different
memories (pages) used in the module.
Here you will see the size of the memory, how much memory is
in use and the largest unallocated continuous memory block.
The checksum column lists the calculated checksum, which
is also saved in the memory image.

The `Sections summary` gives an idea of where the sections are
located and how many section fragments there are for each one.

The `XROM allocation summary` lists the FAT and gives the entry point
for each routine (using some fictive page address if the page is
relocatable).

Finally the `Memory sizes` summarizes the total amount of memory in
use. Note that the amount of memory is given in decimal (addresses and
sizes above are in hexadecimal).


Module files
------------

Output from the linker is in a binary format called *module
file*.  This is a special binary format defined for the HP-41 which is
inspired by how actual modules looks. A one single file is used to
describe a plug-in module. Multiple 4K pages can reside in a module
and they can either be loaded to a fixed addresses, being relocatable
and even have multiple pages that are to be relocated together. It can
also describe banked 4K pages and tell whether the module contains
special hardware.

To create a module file, a module description file is needed. This
contains the meta data of the module file.

The easiest way to create a ``.moddesc`` file is to use the module
tool ``modtool`` to extract one from an existing ``.mod`` file that
have similarities with the module you are going to create (see
:ref:`sec-extract-moddesc`).


More on linker rules
--------------------

The linker rules file is actually a source file for the Scheme
programming language, which is the reason for the choice of the
``.scm`` file extension.

You do not need to be familiar with Scheme to specify linker rules,
simply follow the examples to set things up.

The shown examples are just a Scheme "program" that consists of a
single variable named ``memories`` which is bound to a data
structure. The linker runs a Scheme interpreter to read the file and
then look for the resulting ``memories`` variable and peek into its
contents. This has two implications, *a*) the syntax of the file is
dictated by Scheme, which is based on `s-expressions
<https://www.wikipedia.org/wiki/S-expression>`_; and *b*) it is
possible to use a more elaborate program with Scheme macros to
generate the memory rules.


.. rubric:: Footnotes
.. [#banked]
   This means that more than one page are at the same address, though
   only one will be visible to the microprocessor at a given time.
