Overview
A memory layout diagram describes how the address space of a system is divided into regions, and the .mld file format is the text description from which such a diagram is drawn. Diagrams of this kind are common in hardware and operating system documentation, where a fixed memory map is explained by a column of labelled blocks with the lowest address at the bottom.
The description is kept as a small text file, so it can be held in source control and the picture redrawn whenever the layout changes. The mld command, from the Memory Layout Diagram tool, draws it as an SVG image. It checks the description as it reads it, and reports anything it does not understand; this is described in Errors and warnings, below. The tool is installed with pip install memory-layout, and can also be run as python -m memory_layout. In the RISC OS Build Environment it is available as riscos-mld.
A .mld file has no RISC OS filetype. It is recognised by its .mld extension.
Concepts
Regions and the layout
A memory region is a block of continuous address space, drawn as a rectangle. The ordered collection of regions is the layout, and it is always drawn with the lowest address at the bottom and the highest at the top.
A gap between the end of one region and the start of the next is a discontinuity. Discontinuities are usually memory that is not allocated, or that is grown into as the system is used. They may be described explicitly, or filled in automatically.
Sizes and units
A region's drawn height is its size in bytes divided by the unit_size, multiplied by the unit_height, then limited to between min_height and max_height. The limits stop a very large region from making the diagram excessively tall, and a very small one from being too short to hold its text. A region with no size is one unit_size long. Every region, and the text columns beside the regions, has the same width, region_width.
Distances are in inches. A distance may instead be given in points (1/72 of an inch) by following the number with pt, for example 2pt.
Labels
Each region may have any number of labels. A label is placed relative to the region, inside it, outside it to the left or right, or on the junction at its top or bottom. A label position is two parts separated by a comma, the horizontal position and then the vertical position, such as il,it for inside the region at the top left.
| Horizontal | Meaning |
|---|---|
| il | Inside the region, left aligned. |
| ic | Inside the region, centred. |
| ir | Inside the region, right aligned. |
| el | To the left of the region, right aligned against its edge. |
| elm | To the left of the region, centred. |
| elf | To the left of the region, left aligned away from the edge. |
| er | To the right of the region, left aligned against its edge. |
| erm | To the right of the region, centred. |
| erf | To the right of the region, right aligned away from the edge. |
| Vertical | Meaning |
|---|---|
| it | Inside the region, aligned to the top. |
| ic | Inside the region, centred. |
| ib | Inside the region, aligned to the bottom. |
| jt | Centred on the junction at the top of the region. |
| jb | Centred on the junction at the bottom of the region. |
The commonest positions have shorter names, which can be used in place of the two-part form.
| Shortcut | Full form | Meaning |
|---|---|---|
| c | ic,ic | Centred in both directions. |
| t | ic,it | Top centre. |
| b | ic,ib | Bottom centre. |
| l | il,ic | Left side, vertically centred. |
| r | ir,ic | Right side, vertically centred. |
| tl | il,it | Top left. |
| tr | ir,it | Top right. |
| bl | il,ib | Bottom left. |
| br | ir,ib | Bottom right. |
The text of a label may contain \n to start a new line.
Colours
A colour is a CSS colour name, or a hexadecimal colour in the form #RGB or #RRGGBB. A colour in either hexadecimal form must be quoted in the file, because # otherwise starts a comment: fill: #FFF gives the field no value at all. The tool reports a colour field which has no value, and any colour that it does not recognise.
File structure
The description language
A .mld file is a text file in a restricted form of YAML. It holds a mapping with up to three keys, defaults, layout (which is required) and automatic. A key that is not described in this chapter is reported as a warning, with the name of the key it is most like, so a misspelt key is noticed.
The restricted form of YAML supports mappings, lists, comments, plain and quoted single-line strings, integers (decimal, hexadecimal, binary and octal), floating point numbers, true and false, and an optional %YAML 1.1 line and --- document marker at the start. It does not support flow style (inline { } and [ ]), block strings, anchors and aliases, type tags, or more than one document. Use indented block mappings and lists throughout. The words yes and no are not booleans; write true or false. A line which uses syntax that is not supported, a quoted string which is not closed, or a key which is given twice in a mapping, is an error, and the tool reports the number of the line.
%YAML 1.1
---
# Comments start with a hash.
defaults:
unit_size: 0x1000
layout:
0x0000: Low memory
automatic:
discontinuities: true
The defaults block
The defaults block sets the size and appearance of the diagram, and the defaults for the regions in it. Every field is optional.
| Field | Meaning |
|---|---|
| unit_size | The number of bytes drawn as one unit of height, and the size of a region that gives none. |
| unit_height | The drawn height of one unit_size, as a distance. |
| min_height | The smallest height of a region, as a distance. |
| max_height | The largest height of a region, as a distance. |
| discontinuity_height | The largest height of a discontinuity, as a distance. |
| region_width | The width of the regions, and of the text columns beside them, as a distance. |
| background | The background colour of the diagram. |
| fill | The default fill colour of regions. |
| outline | The default colour of region outlines. |
| outline_width | The default width of region outlines, as a distance. |
| colour | The default colour of label text. |
| colour_size | The colour of the automatic size labels. |
| fontname | The font used for labels. |
| fontname_address | The font used for the automatic address labels. |
| position | The default position of a label which gives none. The default is c. |
| address_format | The name of the format used for automatic addresses, from the list below. |
| size_format | The name of the format used for automatic sizes, from the list below. |
An address or size format is one of the following names. The examples show how the value &540000 (5.25 MiB) is written.
| Name | Example | Style |
|---|---|---|
| acorn | &540000 | An ampersand and hexadecimal digits, as used by RISC OS. |
| commodore | $540000 | A dollar sign and hexadecimal digits. |
| c | 0x540000 | C style hexadecimal. |
| c8 | 0x0054 0000 | C style hexadecimal, as two groups of four digits. |
| si | 5376.0 KiB | A size in binary units, shown exactly. |
| si2 | 5.25 MiB | A size in binary units, to the nearest quarter of a unit. |
| human | 5 MB | A size in whole units such as KB, MB or GB. |
The layout block
The required layout block is a mapping with one entry for each region. The key is the address at which the region starts, written in decimal or as C style hexadecimal starting 0x. The regions are sorted by address, so they may be written in any order. An address that is neither is an error.
The value is either a string, which is the label of a region of the default size, or a mapping with these keys:
| Key | Meaning |
|---|---|
| size | The size of the region in bytes. If omitted, the region is one unit_size long. |
| label | A single label, placed at the default position. |
| labels | Several labels, given as a mapping keyed by position. Each value is the text of the label, or a mapping with label (the text), position (overriding the key) and colour (the colour of the text). |
| discontinuity | Set to true if the region is a discontinuity. |
| fill | The fill colour of the region. |
| outline | The colour of the outline of the region. |
| outline_width | The width of the outline of the region, as a distance. |
| junction_low | The style of the boundary at the low address of the region. |
| junction_high | The style of the boundary at the high address of the region. |
A boundary between two regions, which is called a junction, is drawn as a solid line unless a junction style says otherwise. The styles are solid, dotted, dashed, double for a double solid line, and ticks for marks at the edges only, which do not continue across the region. A style set on a region replaces the style of the adjoining junction of the neighbouring region.
A discontinuity region has a different outline from an ordinary region. Its style is chosen with the style field in the automatic block, below, and is one of zig-zag (the default), cut-out for a wavy line like the break in a graph axis, dotted or dashed.
The automatic block
The automatic block asks for parts of the diagram to be generated rather than written by hand. It has two optional keys, discontinuities and addresses. The name of the second is plural.
The value of discontinuities is true to fill in every gap between regions, or a mapping:
| Key | Meaning |
|---|---|
| enable | Set to false to turn the filling off. |
| fill | The fill colour of the discontinuities. |
| outline | The colour of the outline of the discontinuities. |
| style | The discontinuity style, from the list above. |
The value of addresses is true to label the start address of every region, or a mapping:
| Key | Meaning |
|---|---|
| enable | Set to false to turn the labels off. |
| start | Set to true (the default) to label the start address of each region. |
| end | Set to true to label the end address of each region. The default is false. |
| size | Set to true to label the size of each region. The default is false. |
| side | left or right (the default), the side of the regions on which the labels are placed. |
| end_exclusive | Set to true (the default) to give the end address as the address of the next byte after the region, or false to give the address of its last byte. |
| final_end | Set to true to label the end of the last region even when end is off. |
| omit | An address, or a list of addresses, for which no label is drawn. This is for addresses which are not fixed or not defined. |
| colour | The colour of the address labels. |
Errors and warnings
The tool checks the description as it reads it, and writes what it finds to the error stream, one problem on each line. Each message gives the name of the tool, whether it is an error or a warning, the name of the file, and the problem. There are two kinds of problem.
An error means that no diagram can be drawn. The tool exits with status 1 and writes no output. The errors are:
- a file which cannot be read;
- syntax which the description language does not support, such as an inline list [a, b] or mapping {a: b}, a block string, an anchor, an alias or a tag. The message gives the line number. A value that really does start with one of these characters must be quoted;
- a quoted string which is not closed, or which has text after the closing quote;
- a key which is given twice in the same mapping;
- a document which is not a mapping, or which has no layout, or whose layout has no regions;
- a layout address which is not a number.
A warning means that the tool has understood enough to draw the diagram, but something in it was not as it should be, and it has used the default instead. The tool still writes the diagram and exits with status 0. The warnings are:
- a key which is not known where it is found. The message suggests the known key which is most like it, so that address in the automatic block is reported with a suggestion of addresses;
- a value which is not valid for its field: a colour, a distance, a label position, a junction style, a discontinuity style, an address side, a format name, a yes/no value which is not true or false, or a size or unit which is not a whole number greater than zero;
- a field which has no value, such as a colour which has not been quoted;
- a section or value of the wrong type, such as a defaults block which is not a mapping;
- two layout addresses which are the same address, written differently, such as 16 and 0x10.
The warnings name the field in which the problem was found, such as automatic.addresses.side or layout '0x1000' fill. They do not give a line number, because only the syntax errors are found while the lines are being read.
The --strict option makes every warning an error. The problems are reported as errors, no diagram is written, and the exit status is 1. Use it when a description is checked automatically, so that a mistake is not drawn silently.
$ mld readme.mld
mld: warning: readme.mld: Unknown key 'address' in 'automatic' (did you mean 'addresses'?)
$ mld --strict readme.mld
mld: error: readme.mld: Unknown key 'address' in 'automatic' (did you mean 'addresses'?)
Worked example
This description shows a small application space. The regions are given explicit sizes, one has a label on the left and one has a dotted boundary, the gaps are filled automatically, and the addresses are written in the RISC OS style.
defaults:
unit_size: 0x1000
address_format: acorn
fill: "#C7E3EC"
outline: "#336DA5"
layout:
0x8000:
size: 0x4000
label: Program code
labels:
"el,ic": Read only
0xC000:
size: 0x2000
label: Static data
junction_high: dotted
0x10000: Heap
automatic:
discontinuities: true
addresses:
side: right
start: true
Drawing it with mld produces an SVG image, with the program code at the bottom and the heap above it.
mld appslot.mld --output appslot.svg
Output and limits
The SVG renderer is the supported output. A second renderer writes a Graphviz description, but it cannot place regions close together and its output is much less faithful, so the SVG output is the one to use.
The checks find mistakes in the structure and the values of the description. They cannot know whether the picture is what was intended: a region with the wrong label, or a size which is valid but not the one meant, is still drawn. Look at the picture after changing a description.
Command line
<input> | - | The .mld description to draw. |
--format <format> | - | The output format: svg (the default) or dot, a Graphviz description which is provided for completeness and is much less faithful than the SVG. |
--output <output> | - | The file to write. Without it, the image is written beside the input, with the .mld suffix replaced by the extension of the format. |
--output-prefix <prefix> | - | A name to which the extension of the format is added, instead of naming the whole output. |
--strict | - | Treat unrecognised keys and invalid values as errors, rather than warnings. No output is written if there is any problem. |
mld reads a memory layout description and draws it as a self-contained SVG image: the regions of a memory map in a column, with the lowest address at the bottom, each labelled, with addresses and gaps drawn as the description asks. It is intended for documenting fixed memory maps, such as where an application slot, a module area or a ROM sits in the address space. The description language is described in this document.
The exit status is 0 if the diagram was written, including when warnings were given, and 1 if there was an error, or if there were warnings and --strict was given. Nothing is written when the status is 1.