#elf-file #tock #elf #binary-format #compile #binary-file #file-format

bin+lib elf2tab

从 ELF 编译到 TAB(使用 Tock 二进制格式的 Tock 应用程序包)

12 个版本 (重大更新)

0.12.0 2023 年 10 月 5 日
0.11.0 2023 年 7 月 21 日
0.10.2 2022 年 9 月 9 日
0.9.0 2022 年 4 月 13 日
0.3.0 2018 年 5 月 24 日

#280解析器实现

Download history 275/week @ 2024-03-13 344/week @ 2024-03-20 371/week @ 2024-03-27 391/week @ 2024-04-03 352/week @ 2024-04-10 338/week @ 2024-04-17 327/week @ 2024-04-24 393/week @ 2024-05-01 515/week @ 2024-05-08 269/week @ 2024-05-15 319/week @ 2024-05-22 237/week @ 2024-05-29 286/week @ 2024-06-05 307/week @ 2024-06-12 306/week @ 2024-06-19 179/week @ 2024-06-26

1,135 每月下载量

MIT 许可证

105KB
2K SLoC

elf2tab

elf2tab 是一个工具,可以将 Tock 用户空间应用程序从 .elf 文件转换为 Tock 应用程序包(TAB 或 .tab 文件)。TAB 是为 Tock 运行的各种架构编译的 Tock 应用程序。

使用方法

Usage: elf2tab [OPTIONS] <elf[,architecture]>...

Arguments:
  <elf[,architecture]>...  application file(s) to package

Options:
  -v, --verbose                                        Be verbose
      --deterministic                                  Produce a deterministic TAB file
      --disable                                        Mark the app as disabled in the TBF flags
      --app-version <APP_VERSION>                      Set the version number [default: 0]
      --minimum-ram-size <min-ram-size>                in bytes
  -o, --output-file <filename>                         output file name [default: TockApp.tab]
  -n, --package-name <pkg-name>                        package name
      --stack <stack-size>                             in bytes
      --app-heap <heap-size>                           in bytes [default: 1024]
      --kernel-heap <kernel-heap-size>                 in bytes [default: 1024]
      --protected-region-size <protected-region-size>  Size of the protected region (including headers)
      --permissions <permissions>...                   A list of driver numbers and allowed commands
      --write_id <write_id>                            A storage ID used for writing data
      --read_ids <read_ids>...                         Storage IDs that this app is allowed to read
      --access_ids <access_ids>...                     Storage IDs that this app is allowed to write
      --kernel-major <kernel-major-version>            The kernel version that the app requires
      --kernel-minor <kernel-minor-version>            The minimum kernel minor version that the app requires
      --supported-boards <supported-boards>            comma separated list of boards this app is compatible with
      --minimum-footer-size <min-footer-size>          Minimum number of bytes to reserve space for in the footer [default: 0]
      --sha256                                         Add a SHA256 hash credential to each TBF
      --sha384                                         Add a SHA384 hash credential to each TBF
      --sha512                                         Add a SHA512 hash credential to each TBF
      --rsa4096-private <rsa4096-private-key>          Add an 4096-bit RSA signature credential using this private key
  -h, --help                                           Print help
  -V, --version                                        Print version

例如,使用此工具将 "blink" 应用程序从编译的 .elf 文件(用于 Cortex-M4 设备)转换,如下所示

$ elf2tab -o blink.tab -n blink --stack 1024 --app-heap 1024 --kernel-heap 1024 cortex-m4.elf

它还支持(并鼓励!)将多个架构的 .elf 文件组合成一个 tab

$ elf2tab -o blink.tab -n blink --stack 1024 --app-heap 1024 --kernel-heap 1024 cortex-m0.elf cortex-m3.elf cortex-m4.elf

编译 elf2tab

安装了 rustup 后,只需运行

cargo build

添加 TBF 凭据

elf2tab 支持向生成的 TBF 文件的 TBF 尾部添加凭据。要添加哈希,请使用以下标志之一:--sha256--sha384--sha512

elf2tab 还可以使用公钥/私钥 RSA 密钥对签署 TBF。要生成兼容的密钥

$ openssl genrsa -aes256 -out tockkey.private.pem 4096
$ openssl pkcs8 -topk8 -nocrypt -outform der -in tockkey.private.pem -out tockkey.private.pk8
$ openssl rsa -in tockkey.private.pem -outform der -pubout -out tockkey.public.der

然后将密钥传递给 elf2tab

$ elf2tab --rsa4096-private tockkey.private.pk8 ...

包括多个凭据的示例

$ elf2tab --sha256 --sha384 --sha512 --rsa4096-private tockkey.private.pk8 ...

elf2tab 详细信息

elf2tab 尝试尽可能通用地创建可以闪存到 Tock 板上的应用程序。它做三件事

  1. 从每个 .elf 文件中提取各种部分,并为每个 .elf 创建一个二进制文件。
  2. 为每个二进制文件添加一个 Tock 二进制格式 标头。
  3. 通过创建包含每个 Tock 二进制的 tar 文件来创建 TAB 文件。

从 .elf 文件创建二进制文件

elf2tab 尝试尽可能通用地处理 .elf 文件。要创建二进制文件,elf2tab 会按偏移顺序遍历 .elf 文件中的可写、可执行或分配的节,长度不为零,且类型为 PROGBITS 的节。这些节的二进制数据将连接到输出文件中。

接下来,elf2tab 将所有包含字符串 .rel 的可写或已分配段添加到二进制文件中。因为这些段是链接器为PIC代码创建的,所以这些段需要特殊处理,不能归入第一步。

创建TBF头

所有Tock应用程序都必须以Tock二进制格式头开始,这样内核才能知道应用程序的大小、所需内存以及其他重要属性。elf2tab会自动处理创建此头,主要只需要设置--stack--app-heap--kernel-heap标志,以知道内存需求。

然而,TBF头还包含有关“可写闪存区域”的信息,即应用程序地址空间中应用程序打算用来存储持久数据的部分。将这些信息添加到头文件中,以便内核和其他工具知道需要保持完整的数据持久性。要指定elf2tab,链接器段是这些可写闪存区域之一,则该段的名称应包含字符串.wfr。任何包含.wfr的段的相对地址偏移都会通过TbfHeaderWriteableFlashRegions TLV包含在TBF头中。

如果elf2tab发现.elf文件是为RAM或闪存中的固定地址编译的,而不是位置无关的,它还会自动添加TBF“固定地址”TLV头。为了检测固定的闪存地址,elf2tab会查看闪存段是否位于PIC应用程序的虚拟闪存地址。为了检测固定的RAM地址,elf2tab会查找_sram_origin符号,如果存在,会检查地址是否与PIC应用程序的虚拟RAM地址匹配。

elf2tab必须在TBF头和实际应用程序二进制文件开始之间选择一个保护区域的长度。通常,这默认为0。可以使用命令行参数--protected-region-size(该参数接受整个大小作为参数,包括TBF头)来为所有TBF固定。但是,一个TAB可以包含PIC应用程序和非PIC应用程序,对所有TBF设置大小并不总是理想。因此,elf2tab还支持通过输入ELF文件中的tbf_protected_region_size符号来提供保护区域大小。如果未传递此符号或--protected-region-size,对于已编译为固定地址的应用程序(如上所述),elf2tab将估算一个保护区域大小,以确保TBF头和应用程序二进制文件的开始放置在有用的地址中。当应用程序二进制文件位于正确的固定地址时,elf2tab会尝试增加保护区域的大小,使TBF头的开始地址与256字节对齐。

系统调用权限

elf2tab允许显式指定应用程序允许调用的系统调用。这是通过--permissions标志完成的。允许驱动器编号1命令0和命令1的示例如下

$ elf2tab --permissions 1,0 1,1 ...

然后由Tock内核和板卡应用过滤器。

存储ID

elf2tab 允许指定存储ID。这些ID用于从用户空间访问非易失性数据。您可以指定一个用于存储新数据的单写ID,以及多个用于在现有数据上强制执行读写权限的读ID和访问ID。

示例如下

$ elf2tab  --write_id 12345678 --read_ids 1 2 --access_ids 2 3 ...

创建TAB文件

在生成命令行中指定的每个.elf文件的程序二进制和TBF头文件后,elf2tab将存储这些文件与.elf文件(使用.tbf扩展名)一起,并创建一个包含每个.tbf文件的TAB文件。这些.tab文件由Tockloader等工具用于在板上加载Tock应用程序。

检查TAB文件

Tockloader可以显示一些.tab文件的详细信息。只需

$ tockloader inspect-tab <tab file name>

依赖关系

约10-22MB
约407K SLoC