本文说明如何在Zephyr下使用gcc-arm-none-eabi支持TLS.
在Zephyr TLS线程本地存储的实现一文中说明了如何在Zephyr上使用TLS,在这种默认的情况下Zephyr的编译是使用的是Zephyr SDK提供的工具链。
而在一些特殊情况下我们希望使用重新配置编译第三方工具链来编译Zephyr,这就需要配置让第三方工具链支持TLS,并修改Zephyr的Kconifg加入第三方工具链支持TLS.
工具链编译
到https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads下载要用的source code,例如我选择的是gcc-arm-none-eabi-9-2020-q2-update-src.tar.bz2
解压缩后有一个How-to-build-toolchain.pdf文档说明如何编译
安装依赖
我的环境是ubuntu 18.04,安装依赖1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45sudo su
apt-get install software-properties-common
add-apt-repository universe
cat >/etc/apt/sources.list.d/xenial.list <<EOF
deb http://archive.ubuntu.com/ubuntu xenial main universe
deb-src http://archive.ubuntu.com/ubuntu xenial main universe
deb http://security.ubuntu.com/ubuntu xenial-security main
EOF
dpkg --add-architecture i386
apt-get update
apt-get install -y -t xenial \
gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686
apt-get -f install -y \
build-essential \
autoconf \
autogen \
bison \
dejagnu \
flex \
flip \
gawk \
git \
gperf \
gzip \
nsis \
openssh-client \
p7zip-full \
perl \
python-dev \
libisl-dev \
scons \
tcl \
texinfo \
tofrodos \
wget \
zip \
texlive \
texlive-extra-utils \
libncurses5-dev
exit
修改编译配置项
不需要mingw32,配置为跳过加速编译
1
2skip_mingw32=yes
skip_mingw32_gdb_with_python=yes将
--disable-tls
修改为--enable-tls
gcc-arm-none-eabi默认是关闭tls的,gcc编译代码后访问TLS时使用的是emulated tls,和Zephyr的实现不一致,需要改为--enable-tls
编译
执行下面命令进行编译1
2
3./install-sources.sh
./build-prerequisites.sh
./build-toolchain.sh
编译完成后的结果会被打包放在pkg/下, 例如我这里生成的就是gcc-arm-none-eabi-9-2021-q2-x86_64-linux.tar.bz2
在编译gdb的时候可能会提示python有问题,需要进行python版本切换gcc-arm-none-eabi-9-2020-q2使用python 2.7, 切换方法见Python2和3切换
第三方工具链配置TLS
使用第三方工具链
将gcc-arm-none-eabi-9-2021-q2-update-x86_64-linux.tar.bz2解压缩,根据解压缩的路径修改~/.zephyrrc如下,Zephyr就会使用第三方工具链进行编译1
2export ZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb
export GNUARMEMB_TOOLCHAIN_PATH=/mnt/d/code/gcc-arm-none-eabi-9-2021-q2-update
修改Zephyr配置
当使用第三方工具链后即使配置了CONFIG_THREAD_LOCAL_STORAGE=y
在编译的时候也会提示由于TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE
为n
而无法TLS, 但由于TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE
是Zephyr的隐藏配置项因此无法在prj.conf中配置。
修改方式是在zephyr/kernel/Kconfig中为gnuarmemb添加默认支持TLS1
2
3config TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE
bool
default y if ("$(ZEPHYR_TOOLCHAIN_VARIANT)" = "zephyr" || "$(ZEPHYR_TOOLCHAIN_VARIANT)" = "gnuarmemb")
通过以上修改,用第三方工具链gnuarmemb编译就可以支持Zephyr的TLS。
参考
https://docs.zephyrproject.org/latest/getting_started/toolchain_3rd_party_x_compilers.html