This article was originally posted on 23 October 2012 on blogs.arm.com
ARM DS-5TM is becoming a standard tool in the development of complex embedded software for ARM applications processors. The DS-5 debugger integrated in the Eclipse environment provides a reliable and flexible solution for different target types.
ARM application processors include many complex features, for example, a Memory Management Unit, Caches and an FPU/NEON unit. Debugging software that runs on application processors can be a tough task.
DS-5 has incorporated scripting capabilities that allows users to extend the current set of debugger features provided to match user requirements. The DS-5/Jython API offers a simple interface and versatile solution to solve many different problems.
This article provides a simple overview of the Jython capabilities and shows an example on how to decode the Translation Table entries used by the Memory Management Unit (MMU) using this scripting language.
Jython is a Java implementation of the popular Python scripting language, which it is used in a wide range of applications due to its flexibility and expressive syntax. The Jython interface [1] available in the DS-5 debugger provides support to perform read and write operations by directly accessing variables, memory, and CPU registers or indirectly by executing DS-5 commands. Some examples of this API are shown below:
Reading registers:
data = ec.getRegisterService().getValue('PC')
Reading variables:
data = ec.getVariableService().readValue('variable')
Reading memory:
data = ec.getMemoryService().readMemory32('0x80004000')
With these basic functions and some elementary knowledge of Python, it is very easy for any software developer to write a script to interact with the hardware.
There are many different documents that provide a detailed description of the Memory Management Unit (MMU). This article gives a brief overview of the basic concepts required to understand the TTD script. Please refer to the documentation [2] and [3] for more information.
The MMU allows us to manage tasks as independent programs running in their own private virtual memory space. These virtual memory addresses are translated to different main memory physical addresses using the MMU hardware and entries in a page table. These entries describe the address translation, access permissions and memory attributes necessary for that page. The page table entries are indexed by virtual address as shown in the following figure.
The page tables can be allocated anywhere in main memory. However, the address of the first level page table must be specified in the TTBR{n} registers, so the MMU hardware can perform the translation lookups automatically.
An operating system may decide to split user threads and kernel page tables in which case both the TTBR0 and TTBR1 registers will be used. Simpler implementations may use TTBR0 and leave TTBR1 unused (this split is configured in the TTBCR register).
The TTD script reads the TTBR{n} registers and dumps the page tables for the current context of execution (Bare-metal or Linux OS). Some bits of the page table entries are checked to determine whether a entry is a Fault access, Section (1 MB), Super-section (16 MB), Small page (4 KB) or Large page (64 KB). All this information can be dumped in the DS-5 console, or saved in a text file for further analysis.
The script is currently only intended for processors configuring the Memory Management unit for "short descriptor" page table format. Significant changes to the script will be required to support the new "long descriptor" page-table format as supported by the Cortex-A15.
The script is shipped with the ARM Development Studio 5 (DS-5). After installing the tool, the script can be found under the DS-5 examples path, file Bare-metal_examples.zip, project jython_ttd.
To install the script you can either import the jython_ttd project into DS-5 or copy the ttd.py file to any user folder. The script can be executed in DS-5 by writing the command 'source' and specifying the path to the script. Both absolute and relative paths are supported in both Linux and Windows. Example:
source “/home/user/ttd/ttd.py”
This script has been tested on different scenarios: Bare-metal and Linux environments running on the following development boards: BeagleBoard (Cortex-A8) , PandaBoard (Cortex-A9) and Versatile Express (Cortex-A15).
The following commands show how the script works with the Cortex-A8 Fireworks Bare-metal example, available under the DS-5 installation path.
Displaying the TTD script’s help:
source ./ttd/ttd.py -hTranslation Table Decoder V0.35 Copyright © ARM Limited, 2012.Usage: ttd [options]Options:-d dump translation table given by TTBR0/TTBR1 registers-a address dump translation table given by a (virtual) address-s variable dump translation table given by a variable name (symbols should be loaded in DS-5)-f file dump data to a text file-h print this help
Dumping the Page table entry for a specific address:
source ./ttd/ttd.py -a 0x70001000TTBR1 disabledTTBR0page table (address: 0x100000L / size: 16 KB - 4096 Entries) + Page Table Entry (1792) = SP:0x70000de2L * (Section page: 1 MB) Virtual Addr: 0x70000000 --> Physical Addr: 0x70000000LDone!
Dumping the Page table entry for a given global variable (please note symbols should be loaded)
source ./ttd/ttd.py -s sineTable*** Symbol: sineTable - Virtual Add: 0x2446cL ***TTBR1 disabledTTBR0 page table (address: 0x100000L / size: 16 KB - 4096 Entries) + Page Table Entry (0) = SP:0xdeeL * (Section page: 1 MB) Virtual Addr: 0x0L --> Physical Addr: 0x0LDone!
Dumping all the Page table entries and saving it to a file
source ./ttd/ttd.py -d -f dump.txtTTBR1 disabledTTBR0 page table (address: 0x100000L / size: 16 KB - 4096 Entries)Data will be exported to file: dump.txtDone!
The content of the dump.txt file is shown as follows:
TTBR0 page table (address: 0x100000L / size: 16 KB - 4096 Entries) + Page Table Entry (0) = SP:0xdeeL * (Section page: 1 MB) Virtual Addr: 0x0L --> Physical Addr: 0x0L + Page Table Entry (1) = SP:0x100de2L * (Section page: 1 MB) Virtual Addr: 0x100000L --> Physical Addr: 0x100000L + Page Table Entry (2) = SP:0x200de2L * (Section page: 1 MB) Virtual Addr: 0x200000L --> Physical Addr: 0x200000L......... + Page Table Entry (4094) = SP:0xffe00de2L * (Section page: 1 MB) Virtual Addr: 0xffe00000L --> Physical Addr: 0xffe...L + Page Table Entry (4095) = SP:0xfff00de2L * (Section page: 1 MB) Virtual Addr: 0xfff00000L --> Physical Addr: 0xfff...L
The Jython language has been designed to be flexible and easy to use. The integration of Jython with DS-5 helps the user to automate tasks and customize the behaviour of the tool.
The TTD script presented here shows how we successfully implemented a feature needed for debugging a complex system using address translation provided by the MMU. You can use the same approach to solve many similar debug challenges which are specific to your software and hardware environment.
This script is copyright protected by ARM. However, you can download and modify it according to your needs.
[1] Jython script concepts and interfaces
[2] ARM Architecture Reference Manual v7-A
[3] Cortex-A Series Programmers Guide