Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve linker scripts a little #1275

Merged
merged 13 commits into from
Dec 25, 2023
182 changes: 108 additions & 74 deletions man/rgblink.5
Original file line number Diff line number Diff line change
@@ -1,53 +1,37 @@
.\" SPDX-License-Identifier: MIT
.\"
.Dd March 28, 2021
.Dd December 22, 2023
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
.Dt RGBLINK 5
.Os
.Sh NAME
.Nm rgblink
.Nd linker script file format
.Sh DESCRIPTION
The linker script is an external file that allows the user to specify the order of sections at link time and in a centralized manner.
The linker script is a self-contained file that allows specifying attributes for sections at link time, and in a centralized manner.
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
There can only be one linker script per invocation of
.Nm ,
but it can be split into several files
.Pq using the Ic INCLUDE No directive .
.Ss Basic syntax
A linker script follows a very line-oriented format: each line can contain up to one directive or section name, and up to one comment.
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
Whitespace (space and tab characters) is used to separate elements, but is otherwise ignored.
.Pp
A linker script consists of a series of bank declarations, each optionally followed by a list of section names (in double quotes) or directives.
All reserved keywords (bank types and directive names) are case-insensitive; all section names are case-sensitive.
.Pp
Any line can contain a comment starting with
Comments begin with a semicolon
.Ql \&;
that ends at the end of the line.
.Bd -literal -offset indent
; This line is a comment
ROMX $F ; start a bank
"Some functions" ; a section name
ALIGN 8 ; a directive
"Some array"

WRAMX 2 ; start another bank
org $d123 ; another directive
"Some variables"
.Ed
.Pp
Numbers can be in decimal or hexadecimal format
.Pq the prefix is Ql $ .
It is an error if any section name or directive is found before setting a bank.
character, until the end of the line; they are simply ignored.
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
.Pp
Files can be included by using the
.Ic INCLUDE
keyword, followed by a string with the path of the file that has to be included.
Keywords are composed of letters and digits (but they can't start with a digit); they are all case-insensitive.
.Pp
The possible bank types are:
.Cm ROM0 , ROMX , VRAM , SRAM , WRAM0 , WRAMX , OAM
and
.Cm HRAM .
Unless there is a single bank, which can occur with types
.Cm ROMX , VRAM , SRAM
and
.Cm WRAMX ,
it is mandatory to specify a bank number after the type.
Numbers can be written in the usual decimal format, or in binary using the
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
.Ql %
prefix, or in hexadecimal using the
.Ql $
prefix (both uppercase and lowercase letters are accepted).
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
.Pp
Section names in double quotes support the same character escape sequences as strings in
.Xr rgbasm 5 ,
specifically
Strings begin with a double quote, and end at the next (non-escaped) double quote.
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
Most of the same character escapes as
.Xr rgbasm 5
are supported, specifically
.Ql \e\e ,
.Ql \e" ,
.Ql \en ,
Expand All @@ -56,55 +40,105 @@ and
.Ql \et .
Other backslash escape sequences in
.Xr rgbasm 5
are only relevant to assembly code and do not apply in section names.
are only relevant to assembly code and do not apply in linker scripts.
.Ss Directives
.Bl -tag -width Ds
.It Including other files
.Ql Ic INCLUDE Ar path
acts as if the contents of the file at
.Ar path
were copy-pasted in place of the
.Ic INCLUDE
directive.
.Ar path
must be a string.
.It Bank specification
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
.Tg region
The active bank can be set by specifying its type (memory region) and number.
The possible types are:
.Ic ROM0 , ROMX , VRAM , SRAM , WRAM0 , WRAMX , OAM ,
and
.Ic HRAM .
However, if the type only contains a single bank
.Pq Ic ROM0, Ic ROMX No if Fl t No is passed to Xr rgblink 1 , Ic VRAM No if Fl d No is passed to Xr rgblink 1 , Ic WRAM0 , Ic WRAMX No if Fl w No is passed to Xr rgblink 1 , Ic OAM , Ic HRAM ,
then the number can be omitted.
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
.Pp
When a new bank statement is found, sections found after it will be placed right from the beginning of that bank.
If the linker script switches to a different bank and then comes back to a previous one, it will continue from the last address that was used.
After a bank specification, the
.Dq current address
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
is set to the last value it had for that bank.
If the bank has never been active thus far, the
.Dq current address
defaults to the beginning of the bank
.Pq e.g. Ad $4000 No for Ic ROMX No sections .
.It Changing the Dq current address
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
A bank must be active for any of these directives to be used.
.Pp
The only three directives are
.Ic ORG ,
.Ic ALIGN ,
and
.Ic DS :
.Bl -bullet
.It
.Ic ORG Ar addr
sets the address in which new sections will be placed to
.Ql Ic ORG Ar addr
sets the
.Dq current address
to
.Ar addr .
It can not be lower than the current address.
.It
.Ic ALIGN Ar addr
or
.Ic ALIGN Ar addr , Ar offset
will increase the address until it is aligned to the specified boundary
.Po it tries to set to
The new address cannot be less than the old one.
ISSOtm marked this conversation as resolved.
Show resolved Hide resolved
.Pp
.Ql Ic FLOATING :
All sections between
.Ic FLOATING
and the next
.Ic ORG
or bank specification, will be placed at addresses automatically determined by
.Nm .
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
.Pp
.Ql Ic ALIGN Ar addr , Ar offset
increases the
.Dq current address
until it is aligned to the specified boundary (i.e. the
.Ar align
lowest bits of the address are equal to
.Ar offset ) .
If
.Ar offset
the number of bits specified by
.Ar align :
for example,
is omitted, it is implied to be 0.
For example, if the
.Dq current address
is $007,
ISSOtm marked this conversation as resolved.
Show resolved Hide resolved
.Ql ALIGN 8
will align to $100 ,
and
would set it to $100, and
.Ql ALIGN 8 , 10
will align to $10A
.Pc .
.It
.Ic DS
will increase the address by the specified non-negative amount.
would set it to $00A.
.Pp
.Ql Ic DS Ar size
increases the
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
.Dq current address
by
.Ar size .
.El
.Ss Section placement
A section can be placed simply by naming it (with a string).
Its bank is set to the active bank, and its address to the
.Dq current address .
Any properties the section already possesses must be consistent with what the linker script specifies: the section's type must match, (if set) the section's bank number must match the active bank's, etc.
.Pp
.Sy Note :
The bank, alignment, address and type of sections can be specified both in the source code and in the linker script.
For a section to be able to be placed with the linker script, the bank, address and alignment must be left unassigned in the source code or be compatible with what is specified in the linker script.
For example,
.Ql ALIGN[8]
in the source code is compatible with
.Ql ORG $F00
in the linker script.
Afterwards, the
.Dq current address
is increased by the section's size.
This must not make it go past the end of the active memory region.
Rangi42 marked this conversation as resolved.
Show resolved Hide resolved
.Sh EXAMPLES
.Bd -literal -offset indent
; This line contains only a comment
ROMX $F ; start a bank
"Some functions" ; a section name
ALIGN 8 ; a directive
"Some \e"array\e""

WRAMX 2 ; start another bank
org $d123 ; another directive
"Some variables"
.Ed
.Sh SEE ALSO
.Xr rgbasm 1 ,
.Xr rgblink 1 ,
.Xr rgbfix 1 ,
.Xr rgbasm 5 ,
.Xr rgbds 5 ,
.Xr rgbds 7
.Sh HISTORY
Expand Down
Loading