15.4. The ROMS Directive

The ROMS directive specifies the physical memory configuration of your system as a list of address-range parameters.

Each address range produces one set of files containing the hex conversion utility output data that corresponds to that address range. Each file can be used to program one single ROM device.

The ROMS directive is similar to the MEMORY directive of the Arm linker: both define the memory map of the target address space. Each line entry in the ROMS directive defines a specific address range. The general syntax is:

ROMS
{
    romname : [origin=value,] [length=value,] [romwidth=value,]
              [memwidth=value,] [fill=value]
              [files={ filename, filename, ... }]

    romname : [origin=value,] [length=value,] [romwidth=value,]
              [memwidth=value,] [fill=value]
              [files={ filename, filename, ... }]

    ...
}
  • ROMS begins the directive definition.

  • romname identifies a memory range. The name of the memory range can be one to eight characters in length. The name has no significance to the program; it simply identifies the range, except when the output is for a load image in which case it denotes the section name. (Duplicate memory range names are allowed.)

  • origin | specifies the starting address of a memory range. It can be entered as origin, org, or o. The associated value must be a decimal, octal, or hexadecimal constant. If you omit the origin value, the origin defaults to 0. The following table summarizes the notation you can use to specify a decimal, octal, or hexadecimal constant:

Constant

Notation

Example

Hexadecimal

0x prefix or h suffix

0x77 or 077h

Octal

0 prefix

077

Decimal

No prefix or suffix

77

  • length | specifies the length of a memory range as the physical length of the ROM device. It can be entered as length, len, or l. The value must be a decimal, octal, or hexadecimal constant. If you omit the length, it defaults to the length of the entire address space.

  • romwidth | specifies the physical ROM width of the range in bits (see Partitioning Data Into Output Files). Any value you specify here overrides the --romwidth option. The value must be a decimal, octal, or hexadecimal constant that is a power of 2 greater than or equal to 8.

  • memwidth specifies the memory width of the range in bits (see Specifying the Memory Width). Any value you specify here overrides the --memwidth option. The value must be a decimal, octal, or hexadecimal constant that is a power of 2 greater than or equal to 8. When using the memwidth parameter, you must also specify the paddr parameter for each section in the SECTIONS directive. (See The SECTIONS Directive.)

  • fill specifies a fill value to use for the range. In image mode, the hex conversion utility uses this value to fill any holes between sections in a range. A hole is an area between the input sections that comprises an output section that contains no actual code or data. The fill value must be a decimal, octal, or hexadecimal constant with a width equal to the target width. Any value you specify here overrides the --fill option. When using fill, you must also use the --image command line option. (See Specifying a Fill Value.)

  • files identifies the names of the output files that correspond to this range. Enclose the list of names in curly braces and order them from least significant to most significant output file, where the bits of the memory word are numbered from right to left. The number of file names must equal the number of output files that the range generates. To calculate the number of output files, see Partitioning Data Into Output Files. The utility warns you if you list too many or too few filenames.

Unless you are using the --image option, all of the parameters that define a range are optional; the commas and equal signs are also optional. A range with no origin or length defines the entire address space. In image mode, an origin and length are required for all ranges.

Ranges must not overlap and must be listed in order of ascending address.

15.4.1. When to Use the ROMS Directive

If you do not use a ROMS directive, the utility defines a single default range that includes the entire address space. This is equivalent to a ROMS directive with a single range without origin or length.

Use the ROMS directive when you want to:

  • Program large amounts of data into fixed-size ROMs. When you specify memory ranges corresponding to the length of your ROMs, the utility automatically breaks the output into blocks that fit into the ROMs.

  • Restrict output to certain segments. You can also use the ROMS directive to restrict the conversion to a certain segment or segments of the target address space. The utility does not convert the data that falls outside of the ranges defined by the ROMS directive. Sections can span range boundaries; the utility splits them at the boundary into multiple ranges. If a section falls completely outside any of the ranges you define, the utility does not convert that section and issues no messages or warnings. Thus, you can exclude sections without listing them by name with the SECTIONS directive. However, if a section falls partially in a range and partially in unconfigured memory, the utility issues a warning and converts only the part within the range.

  • Use image mode. When you use the --image option, you must use a ROMS directive. Each range is filled completely so that each output file in a range contains data for the whole range. Holes before, between, or after sections are filled with the fill value from the ROMS directive, with the value specified with the --fill option, or with the default value of 0.

15.4.2. An Example of the ROMS Directive

The ROMS directive in the following example shows how 16K bytes of 16-bit memory could be partitioned for two 8K-byte 8-bit EPROMs. The figure that follows the code illustrates the input and output files.

Example: A ROMS Directive Example

infile.out
--image
--memwidth 16

ROMS
{
    EPROM1: org = 0x00004000, len = 0x2000, romwidth = 8
            files = { rom4000.b0, rom4000.b1}
    EPROM2: org = 0x00006000, len = 0x2000, romwidth = 8,
            fill = 0xFF00FF00,
            files = { rom6000.b0, rom6000.b1}
}

Figure: The infile.out File Partitioned Into Four Output Files

../../_images/partition_pru186.png

The map file (specified with the --map option) is advantageous when you use the ROMS directive with multiple ranges. The map file shows each range, its parameters, names of associated output files, and a list of contents (section names and fill values) broken down by address. The following example is a segment of the map file resulting from the previous ROMS directive.

Example: Map File Output Showing Memory Ranges From ROMS Example

-----------------------------------------------------
00004000..00005fff Page=0 Width=8 "EPROM1"
-----------------------------------------------------
   OUTPUT FILES:   rom4000.b0   [b0..b7]
                   rom4000.b1   [b8..b15]
   CONTENTS: 00004000..0000487f .text
             00004880..00005b7f FILL = 00000000
             00005b80..00005fff .data
-----------------------------------------------------
00006000..00007fff Page=0 Width=8 "EPROM2"
-----------------------------------------------------
   OUTPUT FILES:   rom6000.b0   [b0..b7]
                   rom6000.b1   [b8..b15]
   CONTENTS: 00006000..0000633f .data
             00006340..000066ff FILL = ff00ff00
             00006700..00007c7f .table
             00007c80..00007fff FILL = ff00ff00

EPROM1 defines the address range from 0x00004000 through 0x00005FFF with the following sections:

This section …

Has this range …

.text

0x00004000 through 0x0000487F

.data

0x00005B80 through 0x00005FFF

The rest of the range is filled with 0h (the default fill value), converted into two output files:

  • rom4000.b0 contains bits 0 through 7

  • rom4000.b1 contains bits 8 through 15

EPROM2 defines the address range from 0x00006000 through 0x00007FFF with the following sections:

This section …

Has this range …

.data

0x00006000 through 0x0000633F

.table

0x00006700 through 0x00007C7F

The rest of the range is filled with 0xFF00FF00 (from the specified fill value). The data from this range is converted into two output files:

  • rom6000.b0 contains bits 0 through 7

  • rom6000.b1 contains bits 8 through 15