elf2tab
is a tool that converts Tock userland
apps from .elf
files to Tock Application Bundles (TABs or .tab
files). TABs
are Tock apps that have been compiled for the various architectures that Tock
runs on.
```
Usage: elf2tab [OPTIONS] Arguments:
Options:
-v, --verbose Be verbose
--deterministic Produce a deterministic TAB file
--disable Mark the app as disabled in the TBF flags
--app-version For example, converting a "blink" app from a compiled .elf file (for a Cortex-M4
device) with this tool would look like: It also supports (and encourages!) combining .elf files for multiple architectures
into a single tab: With rustup installed, simply run: elf2tab supports adding credentials to the TBF footer of the generated TBF
files. To add a hash, use one or more of these flags: elf2tab can also sign the TBF with a public/private RSA key pair. To generate
compatible keys: Then pass the keys to elf2tab: Example including multiple credentials: elf2tab tries to be as generic as possible for creating apps that can be
flashed onto a Tock board. It does three main things: elf2tab tries to process .elf files in as generic of a way as possible. To
create the binary file, elf2tab iterates through the sections in the .elf file
in their offset order that are writeable, executable, or allocated, have nonzero
length, and are of type PROGBITS. The binary data for each of these sections
are concatenated into the output file. Next, elf2tab appends to the binary all writeable or allocated sections that
contain the string All Tock apps must start with a Tock Binary Format header so that the kernel
knows how big the app is, how much memory it requires, and other important
properties. elf2tab handles creating this header automatically, and mostly
just requires the However, the TBF header also contains information about "writeable flash
regions", or portions of the application's address space in flash that the app
intends to use to store persistent data. This information is added to the header
so that the kernel and other tools know that there is persistent that should be
maintained intact. To specify to elf2tab that a linker section is one of these
writeable flash regions, the name of the section should include the string
elf2tab will also automatically add a TBF "fixed addresses" TLV header if it
finds that the .elf file was compiled for a fixed address in RAM or flash
instead of being position independent. To detect a fixed flash address, elf2tab
looks to see if the flash segment is at the dummy flash address for PIC apps or
not. To detect a fixed RAM address, elf2tab looks for a elf2tab has to choose a length for the protected region after the TBF header and
before the start of the actual application binary. Normally, this defaults to 0.
It can be fixed for all TBFs in the TAB using the command line argument
elf2tab allows explicitly specifying the syscalls that an app is allowed to
call. This is done with the It is then up to the Tock kernel and board to apply the filters. elf2tab also allows specifying the storage IDs. These are used to access
nonvolatile data from userspace. You can specify a single writeid used
to store new data and multiple readids and access_ids used to enforce
read/write permissions on existing data. An example looks like this: After generating the program binary and TBF header for each .elf file specified
in the command line, elf2tab will store those files along side the .elf files
(using the Tockloader can show some details of a .tab file. Simply:$ elf2tab -o blink.tab -n blink --stack 1024 --app-heap 1024 --kernel-heap 1024 cortex-m4.elf
$ elf2tab -o blink.tab -n blink --stack 1024 --app-heap 1024 --kernel-heap 1024 cortex-m0.elf cortex-m3.elf cortex-m4.elf
Compiling elf2tab
cargo build
Adding TBF Credentials
--sha256
, --sha384
,
--sha512
.$ openssl genrsa -aes256 -out tockkey.private.pem 4096
$ openssl rsa -in tockkey.private.pem -outform der -out tockkey.private.der
$ openssl rsa -in tockkey.private.pem -outform der -pubout -out tockkey.public.der
$ elf2tab --rsa4096-private tockkey.private.der --rsa4096-public tockkey.public.der ...
$ elf2tab --sha256 --sha384 --sha512 --rsa4096-private tockkey.private.der --rsa4096-public tockkey.public.der ...
elf2tab Details
Creating binary files from .elf files
.rel
in their name. Because of how these sections are
created for PIC code by the linker, it seems these sections have to be special
cased and not grouped into the first step.Creating the TBF Header
--stack
, --app-heap
, and --kernel-heap
flags so it
knows the memory requirements..wfr
. Any sections in the .elf that include .wfr
in their name will have
their relative address offset included in the TBF header via the
TbfHeaderWriteableFlashRegions
TLV._sram_origin
symbol,
and if it exists checks if the address matches the dummy RAM address for PIC
apps or not.--protected-region-size
(which takes as an argument entire size before the
application binary, including the TBF header). However, a TAB can include both
PIC apps and non-PIC apps, and setting the size for all TBFs isn't always
desirable. Therefore, elf2tab further supports supplying the protected region
size through a tbf_protected_region_size
symbol in the input ELF files. If
neither this symbol nor --protected-region-size
are passed, for apps compiled
for fixed addresses (as determined above) elf2tab will estimate a protected
region size that tries to ensure the start of the TBF headers and the
application binary are placed at useful addresses in flash. elf2tab will try to
increase the size of the protected region to make the start of the TBF header at
an address aligned to 256 bytes when the application binary is at its correct
fixed address.Syscall Permissions
--permissions
flag.
An example of allowing driver number 1
command 0
and command 1
looks like
this:$ elf2tab --permissions 1,0 1,1 ...
Storage IDs
$ elf2tab --write_id 12345678 --read_ids 1 2 --access_ids 2 3 ...
Creating the TAB file
.tbf
extension), and create a TAB
file
containing each .tbf file. These .tab files are used by tools like Tockloader to
load Tock apps on to boards.Inspecting TABs
$ tockloader inspect-tab <tab file name>