This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 58e0781  arch/arm: Implement TLS support
58e0781 is described below

commit 58e0781e2eb6b84ac7b032928aac4116bc489774
Author: Huang Qi <[email protected]>
AuthorDate: Fri Dec 3 21:35:39 2021 +0800

    arch/arm: Implement TLS support
    
    Signed-off-by: Huang Qi <[email protected]>
---
 arch/Kconfig                                       |  5 ++
 arch/arm/src/common/arm_internal.h                 |  8 ++
 arch/arm/src/common/arm_tls.c                      | 90 ++++++++++++++++++++++
 arch/arm/src/stm32/Make.defs                       |  4 +
 boards/arm/stm32/axoloti/scripts/ld.script         | 12 +++
 boards/arm/stm32/b-g431b-esc1/scripts/ld.script    | 12 +++
 boards/arm/stm32/b-g474e-dpow1/scripts/ld.script   | 12 +++
 .../arm/stm32/b-g474e-dpow1/scripts/ld.script.dfu  | 12 +++
 boards/arm/stm32/clicker2-stm32/scripts/flash.ld   | 12 +++
 boards/arm/stm32/cloudctrl/scripts/cloudctrl.ld    | 12 +++
 boards/arm/stm32/emw3162/scripts/ld.script         | 12 +++
 boards/arm/stm32/et-stm32-stamp/scripts/ld.script  | 12 +++
 .../stm32/fire-stm32v2/scripts/fire-stm32v2-dfu.ld | 12 +++
 .../arm/stm32/fire-stm32v2/scripts/fire-stm32v2.ld | 12 +++
 boards/arm/stm32/hymini-stm32v/scripts/ld.script   | 12 +++
 boards/arm/stm32/maple/scripts/ld.script           | 12 +++
 boards/arm/stm32/mikroe-stm32f4/scripts/ld.script  | 12 +++
 boards/arm/stm32/nucleo-f103rb/scripts/ld.script   | 12 +++
 boards/arm/stm32/nucleo-f207zg/scripts/ld.script   | 12 +++
 boards/arm/stm32/nucleo-f302r8/scripts/ld.script   | 12 +++
 boards/arm/stm32/nucleo-f303re/scripts/ld.script   | 12 +++
 boards/arm/stm32/nucleo-f303ze/scripts/ld.script   | 12 +++
 boards/arm/stm32/nucleo-f334r8/scripts/ld.script   | 12 +++
 boards/arm/stm32/nucleo-f410rb/scripts/f410rb.ld   | 12 +++
 boards/arm/stm32/nucleo-f412zg/scripts/f412zg.ld   | 12 +++
 boards/arm/stm32/nucleo-f429zi/scripts/ld.script   | 12 +++
 boards/arm/stm32/nucleo-f446re/scripts/f446re.ld   | 12 +++
 boards/arm/stm32/nucleo-f4x1re/scripts/f411re.ld   | 12 +++
 boards/arm/stm32/nucleo-g431kb/scripts/ld.script   | 12 +++
 boards/arm/stm32/nucleo-g431rb/scripts/ld.script   | 12 +++
 boards/arm/stm32/nucleo-l152re/scripts/ld.script   | 12 +++
 .../arm/stm32/olimex-stm32-e407/scripts/f407ze.ld  | 12 +++
 .../arm/stm32/olimex-stm32-e407/scripts/f407zg.ld  | 12 +++
 .../arm/stm32/olimex-stm32-h405/scripts/ld.script  | 12 +++
 .../arm/stm32/olimex-stm32-h407/scripts/ld.script  | 12 +++
 .../arm/stm32/olimex-stm32-p107/scripts/ld.script  | 12 +++
 .../arm/stm32/olimex-stm32-p207/scripts/ld.script  | 12 +++
 .../arm/stm32/olimex-stm32-p407/scripts/flash.ld   | 12 +++
 boards/arm/stm32/olimexino-stm32/scripts/ld.script | 12 +++
 .../stm32/olimexino-stm32/scripts/ld.script.dfu    | 12 +++
 boards/arm/stm32/omnibusf4/scripts/ld.script       | 12 +++
 boards/arm/stm32/photon/scripts/photon_dfu.ld      | 12 +++
 boards/arm/stm32/photon/scripts/photon_jtag.ld     | 12 +++
 boards/arm/stm32/shenzhou/scripts/ld.script        | 12 +++
 boards/arm/stm32/shenzhou/scripts/ld.script.dfu    | 12 +++
 boards/arm/stm32/stm3210e-eval/scripts/ld.script   | 12 +++
 .../arm/stm32/stm3210e-eval/scripts/ld.script.dfu  | 12 +++
 boards/arm/stm32/stm3220g-eval/scripts/ld.script   | 12 +++
 boards/arm/stm32/stm3240g-eval/scripts/ld.script   | 12 +++
 boards/arm/stm32/stm32_tiny/scripts/ld.script      | 12 +++
 boards/arm/stm32/stm32butterfly2/scripts/dfu.ld    | 12 +++
 boards/arm/stm32/stm32butterfly2/scripts/flash.ld  | 12 +++
 .../arm/stm32/stm32f103-minimum/scripts/ld.script  | 12 +++
 .../stm32/stm32f103-minimum/scripts/ld.script.dfu  | 12 +++
 boards/arm/stm32/stm32f334-disco/scripts/ld.script | 12 +++
 .../arm/stm32/stm32f3discovery/scripts/ld.script   | 12 +++
 .../stm32/stm32f411-minimum/scripts/stm32f411ce.ld | 12 +++
 .../arm/stm32/stm32f411e-disco/scripts/f411ve.ld   | 12 +++
 .../arm/stm32/stm32f429i-disco/scripts/ld.script   | 12 +++
 .../arm/stm32/stm32f4discovery/scripts/ld.script   | 12 +++
 .../stm32/stm32ldiscovery/scripts/stm32l152rb.ld   | 12 +++
 .../stm32/stm32ldiscovery/scripts/stm32l152rc.ld   | 12 +++
 .../stm32vldiscovery/scripts/stm32vldiscovery.ld   | 12 +++
 boards/arm/stm32/viewtool-stm32f107/scripts/dfu.ld | 12 +++
 .../arm/stm32/viewtool-stm32f107/scripts/flash.ld  | 12 +++
 include/nuttx/arch.h                               | 35 +++++++++
 include/nuttx/tls.h                                |  3 +
 sched/Kconfig                                      |  8 ++
 sched/init/nx_start.c                              |  4 +-
 sched/pthread/pthread_create.c                     |  6 +-
 sched/task/task_init.c                             |  6 +-
 sched/task/task_vfork.c                            |  4 +-
 72 files changed, 899 insertions(+), 6 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index ff19a25..127ca68 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -16,6 +16,7 @@ config ARCH_ARM
        select ARCH_HAVE_STDARG_H
        select ARCH_HAVE_SYSCALL_HOOKS
        select ARCH_HAVE_RDWR_MEM_CPU_RUN
+       select ARCH_HAVE_THREAD_LOCAL
        ---help---
                The ARM architectures
 
@@ -352,6 +353,10 @@ config ARCH_HAVE_TESTSET
        bool
        default n
 
+config ARCH_HAVE_THREAD_LOCAL
+       bool
+       default n
+
 config ARCH_HAVE_FETCHADD
        bool
        default n
diff --git a/arch/arm/src/common/arm_internal.h 
b/arch/arm/src/common/arm_internal.h
index 068ca0b..0dd2d94 100644
--- a/arch/arm/src/common/arm_internal.h
+++ b/arch/arm/src/common/arm_internal.h
@@ -153,6 +153,10 @@
 #  define _DATA_INIT   &_eronly
 #  define _START_DATA  &_sdata
 #  define _END_DATA    &_edata
+#  define _START_TDATA &_stdata
+#  define _END_TDATA   &_etdata
+#  define _START_TBSS  &_stbss
+#  define _END_TBSS    &_etbss
 #endif
 
 /* This is the value used to mark the stack for subsequent stack monitoring
@@ -240,6 +244,10 @@ EXTERN uint32_t _sdata;           /* Start of .data */
 EXTERN uint32_t _edata;           /* End+1 of .data */
 EXTERN uint32_t _sbss;            /* Start of .bss */
 EXTERN uint32_t _ebss;            /* End+1 of .bss */
+EXTERN uint32_t _stdata;          /* Start of .tdata */
+EXTERN uint32_t _etdata;          /* End+1 of .tdata */
+EXTERN uint32_t _stbss;           /* Start of .tbss */
+EXTERN uint32_t _etbss;           /* End+1 of .tbss */
 
 /* Sometimes, functions must be executed from RAM.  In this case, the
  * following macro may be used (with GCC!) to specify a function that will
diff --git a/arch/arm/src/common/arm_tls.c b/arch/arm/src/common/arm_tls.c
new file mode 100644
index 0000000..2a627b6
--- /dev/null
+++ b/arch/arm/src/common/arm_tls.c
@@ -0,0 +1,90 @@
+/****************************************************************************
+ * arch/arm/src/common/arm_tls.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+#include <nuttx/tls.h>
+
+#include "arm_internal.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_tls_size
+ *
+ * Description:
+ *   Get TLS (sizeof(struct tls_info_s) + tdata + tbss) section size.
+ *
+ * Returned Value:
+ *   Size of (sizeof(struct tls_info_s) + tdata + tbss).
+ *
+ ****************************************************************************/
+
+int up_tls_size(void)
+{
+  /* Extra 8 bytes (2 pointer) according to GCC */
+
+  return sizeof(struct tls_info_s) +
+         sizeof(void *) * 2 +
+         sizeof(uint32_t) * (_END_TBSS - _START_TDATA);
+}
+
+/****************************************************************************
+ * Name: up_tls_initialize
+ *
+ * Description:
+ *   Initialize thread local region.
+ *
+ * Input Parameters:
+ *   info - The TLS structure to initialize.
+ *
+ ****************************************************************************/
+
+void up_tls_initialize(FAR struct tls_info_s *info)
+{
+  FAR uint8_t *tls_data = info->tl_data;
+
+  uint32_t tdata_len = sizeof(uint32_t) * (_END_TDATA - _START_TDATA);
+  uint32_t tbss_len = sizeof(uint32_t) * (_END_TBSS - _START_TBSS);
+
+  tls_data += sizeof(void *) * 2;
+
+  memcpy(tls_data, _START_TDATA, tdata_len);
+  memset(tls_data + tdata_len, 0, tbss_len);
+}
+
+/****************************************************************************
+ * Name: __aeabi_read_tp
+ *
+ * Description:
+ *   Read thread local storage region pointer.
+ *
+ ****************************************************************************/
+
+void *__aeabi_read_tp(void)
+{
+  return tls_get_info()->tl_data;
+}
diff --git a/arch/arm/src/stm32/Make.defs b/arch/arm/src/stm32/Make.defs
index ee7a9a0..4de2988 100644
--- a/arch/arm/src/stm32/Make.defs
+++ b/arch/arm/src/stm32/Make.defs
@@ -76,6 +76,10 @@ ifeq ($(CONFIG_ARMV7M_ITMSYSLOG),y)
 CMN_CSRCS += arm_itm_syslog.c
 endif
 
+ifeq ($(CONFIG_SCHED_THREAD_LOCAL),y)
+CMN_CSRCS += arm_tls.c
+endif
+
 CHIP_CSRCS  = stm32_allocateheap.c stm32_start.c stm32_rcc.c stm32_lse.c
 CHIP_CSRCS += stm32_lsi.c stm32_gpio.c stm32_exti_gpio.c stm32_flash.c
 CHIP_CSRCS += stm32_irq.c stm32_lowputc.c
diff --git a/boards/arm/stm32/axoloti/scripts/ld.script 
b/boards/arm/stm32/axoloti/scripts/ld.script
index 4fc296c..ffd242e 100644
--- a/boards/arm/stm32/axoloti/scripts/ld.script
+++ b/boards/arm/stm32/axoloti/scripts/ld.script
@@ -75,6 +75,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The RAM vector table (if present) should lie at the beginning of SRAM */
diff --git a/boards/arm/stm32/b-g431b-esc1/scripts/ld.script 
b/boards/arm/stm32/b-g431b-esc1/scripts/ld.script
index e565025..e989b04 100644
--- a/boards/arm/stm32/b-g431b-esc1/scripts/ld.script
+++ b/boards/arm/stm32/b-g431b-esc1/scripts/ld.script
@@ -87,6 +87,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/b-g474e-dpow1/scripts/ld.script 
b/boards/arm/stm32/b-g474e-dpow1/scripts/ld.script
index d2be3e9..75fe310 100644
--- a/boards/arm/stm32/b-g474e-dpow1/scripts/ld.script
+++ b/boards/arm/stm32/b-g474e-dpow1/scripts/ld.script
@@ -87,6 +87,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/b-g474e-dpow1/scripts/ld.script.dfu 
b/boards/arm/stm32/b-g474e-dpow1/scripts/ld.script.dfu
index 2e526aa..1925fdd 100644
--- a/boards/arm/stm32/b-g474e-dpow1/scripts/ld.script.dfu
+++ b/boards/arm/stm32/b-g474e-dpow1/scripts/ld.script.dfu
@@ -90,6 +90,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/clicker2-stm32/scripts/flash.ld 
b/boards/arm/stm32/clicker2-stm32/scripts/flash.ld
index 254c2db..cf07ccb 100644
--- a/boards/arm/stm32/clicker2-stm32/scripts/flash.ld
+++ b/boards/arm/stm32/clicker2-stm32/scripts/flash.ld
@@ -77,6 +77,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data :
diff --git a/boards/arm/stm32/cloudctrl/scripts/cloudctrl.ld 
b/boards/arm/stm32/cloudctrl/scripts/cloudctrl.ld
index c446a51..09e6b31 100644
--- a/boards/arm/stm32/cloudctrl/scripts/cloudctrl.ld
+++ b/boards/arm/stm32/cloudctrl/scripts/cloudctrl.ld
@@ -65,6 +65,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The STM32F107VC has 64Kb of SRAM beginning at the following address */
diff --git a/boards/arm/stm32/emw3162/scripts/ld.script 
b/boards/arm/stm32/emw3162/scripts/ld.script
index 493d32f..f8595b9 100644
--- a/boards/arm/stm32/emw3162/scripts/ld.script
+++ b/boards/arm/stm32/emw3162/scripts/ld.script
@@ -79,6 +79,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : {
diff --git a/boards/arm/stm32/et-stm32-stamp/scripts/ld.script 
b/boards/arm/stm32/et-stm32-stamp/scripts/ld.script
index b0b307a..1846d58 100644
--- a/boards/arm/stm32/et-stm32-stamp/scripts/ld.script
+++ b/boards/arm/stm32/et-stm32-stamp/scripts/ld.script
@@ -69,6 +69,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The STM32F103RET6 has 64Kb of SRAM beginning at the following address */
diff --git a/boards/arm/stm32/fire-stm32v2/scripts/fire-stm32v2-dfu.ld 
b/boards/arm/stm32/fire-stm32v2/scripts/fire-stm32v2-dfu.ld
index 6a04294..a477b00 100644
--- a/boards/arm/stm32/fire-stm32v2/scripts/fire-stm32v2-dfu.ld
+++ b/boards/arm/stm32/fire-stm32v2/scripts/fire-stm32v2-dfu.ld
@@ -67,6 +67,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The STM32F103Z has 64Kb of SRAM beginning at the following address */
diff --git a/boards/arm/stm32/fire-stm32v2/scripts/fire-stm32v2.ld 
b/boards/arm/stm32/fire-stm32v2/scripts/fire-stm32v2.ld
index 8e38cb6..e964e62 100644
--- a/boards/arm/stm32/fire-stm32v2/scripts/fire-stm32v2.ld
+++ b/boards/arm/stm32/fire-stm32v2/scripts/fire-stm32v2.ld
@@ -68,6 +68,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The STM32F103Z has 64Kb of SRAM beginning at the following address */
diff --git a/boards/arm/stm32/hymini-stm32v/scripts/ld.script 
b/boards/arm/stm32/hymini-stm32v/scripts/ld.script
index 55e5d12..99eea44 100644
--- a/boards/arm/stm32/hymini-stm32v/scripts/ld.script
+++ b/boards/arm/stm32/hymini-stm32v/scripts/ld.script
@@ -68,6 +68,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The STM32F103VCT6 has 48Kb of SRAM beginning at the following address */
diff --git a/boards/arm/stm32/maple/scripts/ld.script 
b/boards/arm/stm32/maple/scripts/ld.script
index e2346d3..c134643 100644
--- a/boards/arm/stm32/maple/scripts/ld.script
+++ b/boards/arm/stm32/maple/scripts/ld.script
@@ -68,6 +68,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The STM32F103VCT6 has 48Kb of SRAM beginning at the following address */
diff --git a/boards/arm/stm32/mikroe-stm32f4/scripts/ld.script 
b/boards/arm/stm32/mikroe-stm32f4/scripts/ld.script
index e9f98ef..f5ac21c 100644
--- a/boards/arm/stm32/mikroe-stm32f4/scripts/ld.script
+++ b/boards/arm/stm32/mikroe-stm32f4/scripts/ld.script
@@ -74,6 +74,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/nucleo-f103rb/scripts/ld.script 
b/boards/arm/stm32/nucleo-f103rb/scripts/ld.script
index bd9ca76..e0d905f 100644
--- a/boards/arm/stm32/nucleo-f103rb/scripts/ld.script
+++ b/boards/arm/stm32/nucleo-f103rb/scripts/ld.script
@@ -69,6 +69,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The RAM vector table (if present) should lie at the beginning of SRAM */
diff --git a/boards/arm/stm32/nucleo-f207zg/scripts/ld.script 
b/boards/arm/stm32/nucleo-f207zg/scripts/ld.script
index ad83994..5d5740d 100644
--- a/boards/arm/stm32/nucleo-f207zg/scripts/ld.script
+++ b/boards/arm/stm32/nucleo-f207zg/scripts/ld.script
@@ -72,6 +72,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/nucleo-f302r8/scripts/ld.script 
b/boards/arm/stm32/nucleo-f302r8/scripts/ld.script
index 2cde41c..de8a7f1 100644
--- a/boards/arm/stm32/nucleo-f302r8/scripts/ld.script
+++ b/boards/arm/stm32/nucleo-f302r8/scripts/ld.script
@@ -69,6 +69,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The RAM vector table (if present) should lie at the beginning of SRAM */
diff --git a/boards/arm/stm32/nucleo-f303re/scripts/ld.script 
b/boards/arm/stm32/nucleo-f303re/scripts/ld.script
index 8148801..5138140 100644
--- a/boards/arm/stm32/nucleo-f303re/scripts/ld.script
+++ b/boards/arm/stm32/nucleo-f303re/scripts/ld.script
@@ -69,6 +69,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/nucleo-f303ze/scripts/ld.script 
b/boards/arm/stm32/nucleo-f303ze/scripts/ld.script
index 44a627c..896699b 100644
--- a/boards/arm/stm32/nucleo-f303ze/scripts/ld.script
+++ b/boards/arm/stm32/nucleo-f303ze/scripts/ld.script
@@ -69,6 +69,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/nucleo-f334r8/scripts/ld.script 
b/boards/arm/stm32/nucleo-f334r8/scripts/ld.script
index 0be20c9..584d8a9 100644
--- a/boards/arm/stm32/nucleo-f334r8/scripts/ld.script
+++ b/boards/arm/stm32/nucleo-f334r8/scripts/ld.script
@@ -69,6 +69,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The RAM vector table (if present) should lie at the beginning of SRAM */
diff --git a/boards/arm/stm32/nucleo-f410rb/scripts/f410rb.ld 
b/boards/arm/stm32/nucleo-f410rb/scripts/f410rb.ld
index 0693e74..a5f3b8a 100644
--- a/boards/arm/stm32/nucleo-f410rb/scripts/f410rb.ld
+++ b/boards/arm/stm32/nucleo-f410rb/scripts/f410rb.ld
@@ -68,6 +68,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The STM32F410RBT6 has 32Kb of SRAM beginning at the following address */
diff --git a/boards/arm/stm32/nucleo-f412zg/scripts/f412zg.ld 
b/boards/arm/stm32/nucleo-f412zg/scripts/f412zg.ld
index 70015aa..c582ce3 100644
--- a/boards/arm/stm32/nucleo-f412zg/scripts/f412zg.ld
+++ b/boards/arm/stm32/nucleo-f412zg/scripts/f412zg.ld
@@ -68,6 +68,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : {
diff --git a/boards/arm/stm32/nucleo-f429zi/scripts/ld.script 
b/boards/arm/stm32/nucleo-f429zi/scripts/ld.script
index d3f80b7..e9b5785 100644
--- a/boards/arm/stm32/nucleo-f429zi/scripts/ld.script
+++ b/boards/arm/stm32/nucleo-f429zi/scripts/ld.script
@@ -75,6 +75,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The RAM vector table (if present) should lie at the beginning of SRAM */
diff --git a/boards/arm/stm32/nucleo-f446re/scripts/f446re.ld 
b/boards/arm/stm32/nucleo-f446re/scripts/f446re.ld
index 19fd6c1..25bbd4f 100644
--- a/boards/arm/stm32/nucleo-f446re/scripts/f446re.ld
+++ b/boards/arm/stm32/nucleo-f446re/scripts/f446re.ld
@@ -68,6 +68,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The STM32F103VCT6 has 48Kb of SRAM beginning at the following address */
diff --git a/boards/arm/stm32/nucleo-f4x1re/scripts/f411re.ld 
b/boards/arm/stm32/nucleo-f4x1re/scripts/f411re.ld
index 7d234c5..00a2217 100644
--- a/boards/arm/stm32/nucleo-f4x1re/scripts/f411re.ld
+++ b/boards/arm/stm32/nucleo-f4x1re/scripts/f411re.ld
@@ -58,6 +58,18 @@ SECTIONS
         _einit = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     .ARM.extab : {
         *(.ARM.extab*)
     } > flash
diff --git a/boards/arm/stm32/nucleo-g431kb/scripts/ld.script 
b/boards/arm/stm32/nucleo-g431kb/scripts/ld.script
index df8fda8..df22aaa 100755
--- a/boards/arm/stm32/nucleo-g431kb/scripts/ld.script
+++ b/boards/arm/stm32/nucleo-g431kb/scripts/ld.script
@@ -87,6 +87,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/nucleo-g431rb/scripts/ld.script 
b/boards/arm/stm32/nucleo-g431rb/scripts/ld.script
index 35db223..cc15b7d 100644
--- a/boards/arm/stm32/nucleo-g431rb/scripts/ld.script
+++ b/boards/arm/stm32/nucleo-g431rb/scripts/ld.script
@@ -87,6 +87,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/nucleo-l152re/scripts/ld.script 
b/boards/arm/stm32/nucleo-l152re/scripts/ld.script
index 4a8af66..9bd4a3f 100644
--- a/boards/arm/stm32/nucleo-l152re/scripts/ld.script
+++ b/boards/arm/stm32/nucleo-l152re/scripts/ld.script
@@ -69,6 +69,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The RAM vector table (if present) should lie at the beginning of SRAM */
diff --git a/boards/arm/stm32/olimex-stm32-e407/scripts/f407ze.ld 
b/boards/arm/stm32/olimex-stm32-e407/scripts/f407ze.ld
index e8956bd..3d20926 100644
--- a/boards/arm/stm32/olimex-stm32-e407/scripts/f407ze.ld
+++ b/boards/arm/stm32/olimex-stm32-e407/scripts/f407ze.ld
@@ -74,6 +74,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/olimex-stm32-e407/scripts/f407zg.ld 
b/boards/arm/stm32/olimex-stm32-e407/scripts/f407zg.ld
index 973c3ba..08ace87 100644
--- a/boards/arm/stm32/olimex-stm32-e407/scripts/f407zg.ld
+++ b/boards/arm/stm32/olimex-stm32-e407/scripts/f407zg.ld
@@ -74,6 +74,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/olimex-stm32-h405/scripts/ld.script 
b/boards/arm/stm32/olimex-stm32-h405/scripts/ld.script
index 25dbed7..28f8a8e 100644
--- a/boards/arm/stm32/olimex-stm32-h405/scripts/ld.script
+++ b/boards/arm/stm32/olimex-stm32-h405/scripts/ld.script
@@ -74,6 +74,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/olimex-stm32-h407/scripts/ld.script 
b/boards/arm/stm32/olimex-stm32-h407/scripts/ld.script
index 2370a58..4485a65 100644
--- a/boards/arm/stm32/olimex-stm32-h407/scripts/ld.script
+++ b/boards/arm/stm32/olimex-stm32-h407/scripts/ld.script
@@ -73,6 +73,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/olimex-stm32-p107/scripts/ld.script 
b/boards/arm/stm32/olimex-stm32-p107/scripts/ld.script
index 76e62eb..e68c944 100644
--- a/boards/arm/stm32/olimex-stm32-p107/scripts/ld.script
+++ b/boards/arm/stm32/olimex-stm32-p107/scripts/ld.script
@@ -61,6 +61,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The STM32F107VC has 64Kb of SRAM beginning at the following address */
diff --git a/boards/arm/stm32/olimex-stm32-p207/scripts/ld.script 
b/boards/arm/stm32/olimex-stm32-p207/scripts/ld.script
index 2c5672e..f359f2a 100644
--- a/boards/arm/stm32/olimex-stm32-p207/scripts/ld.script
+++ b/boards/arm/stm32/olimex-stm32-p207/scripts/ld.script
@@ -73,6 +73,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/olimex-stm32-p407/scripts/flash.ld 
b/boards/arm/stm32/olimex-stm32-p407/scripts/flash.ld
index 8d6e77c..d6f8917 100644
--- a/boards/arm/stm32/olimex-stm32-p407/scripts/flash.ld
+++ b/boards/arm/stm32/olimex-stm32-p407/scripts/flash.ld
@@ -73,6 +73,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : {
diff --git a/boards/arm/stm32/olimexino-stm32/scripts/ld.script 
b/boards/arm/stm32/olimexino-stm32/scripts/ld.script
index 1da42ab..ac5d159 100644
--- a/boards/arm/stm32/olimexino-stm32/scripts/ld.script
+++ b/boards/arm/stm32/olimexino-stm32/scripts/ld.script
@@ -68,6 +68,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/olimexino-stm32/scripts/ld.script.dfu 
b/boards/arm/stm32/olimexino-stm32/scripts/ld.script.dfu
index 354562a..c13d11a 100644
--- a/boards/arm/stm32/olimexino-stm32/scripts/ld.script.dfu
+++ b/boards/arm/stm32/olimexino-stm32/scripts/ld.script.dfu
@@ -62,6 +62,18 @@ SECTIONS
                 __exidx_end = ABSOLUTE(.);
         } > flash
 
+        .tdata : {
+                _stdata = ABSOLUTE(.);
+                *(.tdata .tdata.* .gnu.linkonce.td.*);
+                _etdata = ABSOLUTE(.);
+        } > flash
+        
+        .tbss : {
+                _stbss = ABSOLUTE(.);
+                *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+                _etbss = ABSOLUTE(.);
+        } > flash
+
         _eronly = ABSOLUTE(.);
 
         /* The STM32F103Z has 64Kb of SRAM beginning at the following address 
*/
diff --git a/boards/arm/stm32/omnibusf4/scripts/ld.script 
b/boards/arm/stm32/omnibusf4/scripts/ld.script
index c012388..3345884 100644
--- a/boards/arm/stm32/omnibusf4/scripts/ld.script
+++ b/boards/arm/stm32/omnibusf4/scripts/ld.script
@@ -74,6 +74,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/photon/scripts/photon_dfu.ld 
b/boards/arm/stm32/photon/scripts/photon_dfu.ld
index 7e55c02..70b2132 100644
--- a/boards/arm/stm32/photon/scripts/photon_dfu.ld
+++ b/boards/arm/stm32/photon/scripts/photon_dfu.ld
@@ -82,6 +82,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : {
diff --git a/boards/arm/stm32/photon/scripts/photon_jtag.ld 
b/boards/arm/stm32/photon/scripts/photon_jtag.ld
index 51c2349..cf427c8 100644
--- a/boards/arm/stm32/photon/scripts/photon_jtag.ld
+++ b/boards/arm/stm32/photon/scripts/photon_jtag.ld
@@ -70,6 +70,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : {
diff --git a/boards/arm/stm32/shenzhou/scripts/ld.script 
b/boards/arm/stm32/shenzhou/scripts/ld.script
index ed89ab2..ba03dc7 100644
--- a/boards/arm/stm32/shenzhou/scripts/ld.script
+++ b/boards/arm/stm32/shenzhou/scripts/ld.script
@@ -65,6 +65,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The STM32F107VC has 64Kb of SRAM beginning at the following address */
diff --git a/boards/arm/stm32/shenzhou/scripts/ld.script.dfu 
b/boards/arm/stm32/shenzhou/scripts/ld.script.dfu
index 1924956..61c9ae6 100644
--- a/boards/arm/stm32/shenzhou/scripts/ld.script.dfu
+++ b/boards/arm/stm32/shenzhou/scripts/ld.script.dfu
@@ -67,6 +67,18 @@ SECTIONS
                 __exidx_end = ABSOLUTE(.);
         } > flash
 
+        .tdata : {
+                _stdata = ABSOLUTE(.);
+                *(.tdata .tdata.* .gnu.linkonce.td.*);
+                _etdata = ABSOLUTE(.);
+        } > flash
+        
+        .tbss : {
+                _stbss = ABSOLUTE(.);
+                *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+                _etbss = ABSOLUTE(.);
+        } > flash
+
         _eronly = ABSOLUTE(.);
 
         /* The STM32F107VC has 64Kb of SRAM beginning at the following address 
*/
diff --git a/boards/arm/stm32/stm3210e-eval/scripts/ld.script 
b/boards/arm/stm32/stm3210e-eval/scripts/ld.script
index ea76cdd..8efe9ca 100644
--- a/boards/arm/stm32/stm3210e-eval/scripts/ld.script
+++ b/boards/arm/stm32/stm3210e-eval/scripts/ld.script
@@ -68,6 +68,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The STM32F103Z has 64Kb of SRAM beginning at the following address */
diff --git a/boards/arm/stm32/stm3210e-eval/scripts/ld.script.dfu 
b/boards/arm/stm32/stm3210e-eval/scripts/ld.script.dfu
index 7f7abb8..62da453 100644
--- a/boards/arm/stm32/stm3210e-eval/scripts/ld.script.dfu
+++ b/boards/arm/stm32/stm3210e-eval/scripts/ld.script.dfu
@@ -67,6 +67,18 @@ SECTIONS
                 __exidx_end = ABSOLUTE(.);
         } > flash
 
+        .tdata : {
+                _stdata = ABSOLUTE(.);
+                *(.tdata .tdata.* .gnu.linkonce.td.*);
+                _etdata = ABSOLUTE(.);
+        } > flash
+        
+        .tbss : {
+                _stbss = ABSOLUTE(.);
+                *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+                _etbss = ABSOLUTE(.);
+        } > flash
+
         _eronly = ABSOLUTE(.);
 
         /* The STM32F103Z has 64Kb of SRAM beginning at the following address 
*/
diff --git a/boards/arm/stm32/stm3220g-eval/scripts/ld.script 
b/boards/arm/stm32/stm3220g-eval/scripts/ld.script
index 7c4c7dc..d701dd5 100644
--- a/boards/arm/stm32/stm3220g-eval/scripts/ld.script
+++ b/boards/arm/stm32/stm3220g-eval/scripts/ld.script
@@ -73,6 +73,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/stm3240g-eval/scripts/ld.script 
b/boards/arm/stm32/stm3240g-eval/scripts/ld.script
index f15c84e..aa11c9a 100644
--- a/boards/arm/stm32/stm3240g-eval/scripts/ld.script
+++ b/boards/arm/stm32/stm3240g-eval/scripts/ld.script
@@ -74,6 +74,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/stm32_tiny/scripts/ld.script 
b/boards/arm/stm32/stm32_tiny/scripts/ld.script
index 72e3d3b..5146656 100644
--- a/boards/arm/stm32/stm32_tiny/scripts/ld.script
+++ b/boards/arm/stm32/stm32_tiny/scripts/ld.script
@@ -68,6 +68,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The STM32F103C8T6 has 20Kb of SRAM beginning at the following address */
diff --git a/boards/arm/stm32/stm32butterfly2/scripts/dfu.ld 
b/boards/arm/stm32/stm32butterfly2/scripts/dfu.ld
index 02eedb2..91eaafd 100644
--- a/boards/arm/stm32/stm32butterfly2/scripts/dfu.ld
+++ b/boards/arm/stm32/stm32butterfly2/scripts/dfu.ld
@@ -61,6 +61,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The RAM vector table (if present) should lie at the beginning of SRAM */
diff --git a/boards/arm/stm32/stm32butterfly2/scripts/flash.ld 
b/boards/arm/stm32/stm32butterfly2/scripts/flash.ld
index f631b18..b08a10d 100644
--- a/boards/arm/stm32/stm32butterfly2/scripts/flash.ld
+++ b/boards/arm/stm32/stm32butterfly2/scripts/flash.ld
@@ -61,6 +61,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The RAM vector table (if present) should lie at the beginning of SRAM */
diff --git a/boards/arm/stm32/stm32f103-minimum/scripts/ld.script 
b/boards/arm/stm32/stm32f103-minimum/scripts/ld.script
index db23e11..5aea492 100644
--- a/boards/arm/stm32/stm32f103-minimum/scripts/ld.script
+++ b/boards/arm/stm32/stm32f103-minimum/scripts/ld.script
@@ -73,6 +73,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The STM32F103C8T6 has 20Kb of SRAM beginning at the following address */
diff --git a/boards/arm/stm32/stm32f103-minimum/scripts/ld.script.dfu 
b/boards/arm/stm32/stm32f103-minimum/scripts/ld.script.dfu
index 34d7a8e..5c72c8f 100644
--- a/boards/arm/stm32/stm32f103-minimum/scripts/ld.script.dfu
+++ b/boards/arm/stm32/stm32f103-minimum/scripts/ld.script.dfu
@@ -67,6 +67,18 @@ SECTIONS
                 __exidx_end = ABSOLUTE(.);
         } > flash
 
+        .tdata : {
+                _stdata = ABSOLUTE(.);
+                *(.tdata .tdata.* .gnu.linkonce.td.*);
+                _etdata = ABSOLUTE(.);
+        } > flash
+        
+        .tbss : {
+                _stbss = ABSOLUTE(.);
+                *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+                _etbss = ABSOLUTE(.);
+        } > flash
+
         _eronly = ABSOLUTE(.);
 
         /* The STM32F103C8T6 has 20Kb of SRAM beginning at the following 
address */
diff --git a/boards/arm/stm32/stm32f334-disco/scripts/ld.script 
b/boards/arm/stm32/stm32f334-disco/scripts/ld.script
index aaed872..3bfbffe 100644
--- a/boards/arm/stm32/stm32f334-disco/scripts/ld.script
+++ b/boards/arm/stm32/stm32f334-disco/scripts/ld.script
@@ -69,6 +69,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The RAM vector table (if present) should lie at the beginning of SRAM */
diff --git a/boards/arm/stm32/stm32f3discovery/scripts/ld.script 
b/boards/arm/stm32/stm32f3discovery/scripts/ld.script
index 4b203ee..cab35da 100644
--- a/boards/arm/stm32/stm32f3discovery/scripts/ld.script
+++ b/boards/arm/stm32/stm32f3discovery/scripts/ld.script
@@ -69,6 +69,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/stm32f411-minimum/scripts/stm32f411ce.ld 
b/boards/arm/stm32/stm32f411-minimum/scripts/stm32f411ce.ld
index f98239c..b401858 100644
--- a/boards/arm/stm32/stm32f411-minimum/scripts/stm32f411ce.ld
+++ b/boards/arm/stm32/stm32f411-minimum/scripts/stm32f411ce.ld
@@ -68,6 +68,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The STM32F103VCT6 has 48Kb of SRAM beginning at the following address */
diff --git a/boards/arm/stm32/stm32f411e-disco/scripts/f411ve.ld 
b/boards/arm/stm32/stm32f411e-disco/scripts/f411ve.ld
index cf6b9e8..a4f525d 100644
--- a/boards/arm/stm32/stm32f411e-disco/scripts/f411ve.ld
+++ b/boards/arm/stm32/stm32f411e-disco/scripts/f411ve.ld
@@ -68,6 +68,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The STM32F103VCT6 has 48Kb of SRAM beginning at the following address */
diff --git a/boards/arm/stm32/stm32f429i-disco/scripts/ld.script 
b/boards/arm/stm32/stm32f429i-disco/scripts/ld.script
index 0b53d3b..f25c765 100644
--- a/boards/arm/stm32/stm32f429i-disco/scripts/ld.script
+++ b/boards/arm/stm32/stm32f429i-disco/scripts/ld.script
@@ -75,6 +75,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The RAM vector table (if present) should lie at the beginning of SRAM */
diff --git a/boards/arm/stm32/stm32f4discovery/scripts/ld.script 
b/boards/arm/stm32/stm32f4discovery/scripts/ld.script
index a402fe6..cfa3337 100644
--- a/boards/arm/stm32/stm32f4discovery/scripts/ld.script
+++ b/boards/arm/stm32/stm32f4discovery/scripts/ld.script
@@ -74,6 +74,18 @@ SECTIONS
         __exidx_end = ABSOLUTE(.);
     } > flash
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : ALIGN(4) {
diff --git a/boards/arm/stm32/stm32ldiscovery/scripts/stm32l152rb.ld 
b/boards/arm/stm32/stm32ldiscovery/scripts/stm32l152rb.ld
index e663e39..31a9a78 100644
--- a/boards/arm/stm32/stm32ldiscovery/scripts/stm32l152rb.ld
+++ b/boards/arm/stm32/stm32ldiscovery/scripts/stm32l152rb.ld
@@ -73,6 +73,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data :
diff --git a/boards/arm/stm32/stm32ldiscovery/scripts/stm32l152rc.ld 
b/boards/arm/stm32/stm32ldiscovery/scripts/stm32l152rc.ld
index b323f6f..f44a5cd 100644
--- a/boards/arm/stm32/stm32ldiscovery/scripts/stm32l152rc.ld
+++ b/boards/arm/stm32/stm32ldiscovery/scripts/stm32l152rc.ld
@@ -73,6 +73,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data :
diff --git a/boards/arm/stm32/stm32vldiscovery/scripts/stm32vldiscovery.ld 
b/boards/arm/stm32/stm32vldiscovery/scripts/stm32vldiscovery.ld
index 49d2623..f47006d 100644
--- a/boards/arm/stm32/stm32vldiscovery/scripts/stm32vldiscovery.ld
+++ b/boards/arm/stm32/stm32vldiscovery/scripts/stm32vldiscovery.ld
@@ -68,6 +68,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     .data : {
diff --git a/boards/arm/stm32/viewtool-stm32f107/scripts/dfu.ld 
b/boards/arm/stm32/viewtool-stm32f107/scripts/dfu.ld
index b4d5ce0..617c8f9 100644
--- a/boards/arm/stm32/viewtool-stm32f107/scripts/dfu.ld
+++ b/boards/arm/stm32/viewtool-stm32f107/scripts/dfu.ld
@@ -61,6 +61,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The RAM vector table (if present) should lie at the beginning of SRAM */
diff --git a/boards/arm/stm32/viewtool-stm32f107/scripts/flash.ld 
b/boards/arm/stm32/viewtool-stm32f107/scripts/flash.ld
index 1e2a158..ae0cb90 100644
--- a/boards/arm/stm32/viewtool-stm32f107/scripts/flash.ld
+++ b/boards/arm/stm32/viewtool-stm32f107/scripts/flash.ld
@@ -61,6 +61,18 @@ SECTIONS
     } > flash
     __exidx_end = ABSOLUTE(.);
 
+    .tdata : {
+        _stdata = ABSOLUTE(.);
+        *(.tdata .tdata.* .gnu.linkonce.td.*);
+        _etdata = ABSOLUTE(.);
+    } > flash
+
+    .tbss : {
+        _stbss = ABSOLUTE(.);
+        *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+        _etbss = ABSOLUTE(.);
+    } > flash
+
     _eronly = ABSOLUTE(.);
 
     /* The RAM vector table (if present) should lie at the beginning of SRAM */
diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h
index 12779c6..e7e2f36 100644
--- a/include/nuttx/arch.h
+++ b/include/nuttx/arch.h
@@ -85,6 +85,7 @@
 #include <nuttx/compiler.h>
 #include <nuttx/cache.h>
 #include <nuttx/sched.h>
+#include <nuttx/tls.h>
 
 /****************************************************************************
  * Pre-processor definitions
@@ -1804,6 +1805,40 @@ int up_timer_start(FAR const struct timespec *ts);
 #endif
 
 /****************************************************************************
+ * Name: up_tls_size
+ *
+ * Description:
+ *   Get TLS (sizeof(struct tls_info_s) + tdata + tbss) section size.
+ *
+ * Returned Value:
+ *   Size of (sizeof(struct tls_info_s) + tdata + tbss).
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SCHED_THREAD_LOCAL
+int up_tls_size(void);
+#else
+#define up_tls_size() sizeof(struct tls_info_s) 
+#endif
+
+/****************************************************************************
+ * Name: up_tls_initialize
+ *
+ * Description:
+ *   Initialize thread local region
+ *
+ * Input Parameters:
+ *   tls_data - The memory region to initialize
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SCHED_THREAD_LOCAL
+void up_tls_initialize(FAR struct tls_info_s *info);
+#else
+#define up_tls_initialize(x)
+#endif
+
+/****************************************************************************
  * Multiple CPU support
  ****************************************************************************/
 
diff --git a/include/nuttx/tls.h b/include/nuttx/tls.h
index 0ba9549..4a26964 100644
--- a/include/nuttx/tls.h
+++ b/include/nuttx/tls.h
@@ -167,6 +167,9 @@ struct tls_info_s
 #endif
 
   int tl_errno;                        /* Per-thread error number */
+#ifdef CONFIG_SCHED_THREAD_LOCAL
+  uint8_t tl_data[0];
+#endif
 };
 
 /****************************************************************************
diff --git a/sched/Kconfig b/sched/Kconfig
index e01fa4c..05b1311 100644
--- a/sched/Kconfig
+++ b/sched/Kconfig
@@ -600,6 +600,14 @@ config SCHED_USER_IDENTITY
                Those can then be managed using the interfaces.  Child tasks 
will
                inherit the UID and GID of its parent.
 
+config SCHED_THREAD_LOCAL
+       bool "Support __thread/thread_local keyword"
+       default n
+       depends on ARCH_HAVE_THREAD_LOCAL
+       ---help---
+               This option enables architecture-sepecific TLS supports 
(__thread/thread_local keyword)
+               Note: Toolchain must be compiled with '--enable-tls' enabled
+
 endmenu # Tasks and Scheduling
 
 menu "Pthread Options"
diff --git a/sched/init/nx_start.c b/sched/init/nx_start.c
index 5a9ee3e..521e6c1 100644
--- a/sched/init/nx_start.c
+++ b/sched/init/nx_start.c
@@ -580,7 +580,9 @@ void nx_start(void)
 
       up_initial_state(&g_idletcb[i].cmn);
 
-      /* Initialize the thread local storage */
+      /* Initialize the thread local storage
+       * Note: Don't copy tdata and tss for idle task to improve footprint
+       */
 
       info = up_stack_frame(&g_idletcb[i].cmn, sizeof(struct tls_info_s));
       DEBUGASSERT(info == g_idletcb[i].cmn.stack_alloc_ptr);
diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c
index aa88c8a..e58c91f 100644
--- a/sched/pthread/pthread_create.c
+++ b/sched/pthread/pthread_create.c
@@ -315,7 +315,7 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR 
pthread_t *thread,
       /* Allocate the stack for the TCB */
 
       ret = up_create_stack((FAR struct tcb_s *)ptcb,
-                            sizeof(struct tls_info_s) + attr->stacksize,
+                            up_tls_size() + attr->stacksize,
                             TCB_FLAG_TTYPE_PTHREAD);
     }
 
@@ -327,7 +327,7 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR 
pthread_t *thread,
 
   /* Initialize thread local storage */
 
-  info = up_stack_frame(&ptcb->cmn, sizeof(struct tls_info_s));
+  info = up_stack_frame(&ptcb->cmn, up_tls_size());
   if (info == NULL)
     {
       errcode = ENOMEM;
@@ -336,6 +336,8 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR 
pthread_t *thread,
 
   DEBUGASSERT(info == ptcb->cmn.stack_alloc_ptr);
 
+  up_tls_initialize(info);
+
   /* Attach per-task info in group to TLS */
 
   info->tl_task = ptcb->cmn.group->tg_info;
diff --git a/sched/task/task_init.c b/sched/task/task_init.c
index 7a757fe..a777c44 100644
--- a/sched/task/task_init.c
+++ b/sched/task/task_init.c
@@ -122,7 +122,7 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char 
*name, int priority,
       /* Allocate the stack for the TCB */
 
       ret = up_create_stack(&tcb->cmn,
-                            sizeof(struct tls_info_s) + stack_size,
+                            up_tls_size() + stack_size,
                             ttype);
     }
 
@@ -133,7 +133,7 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char 
*name, int priority,
 
   /* Initialize thread local storage */
 
-  info = up_stack_frame(&tcb->cmn, sizeof(struct tls_info_s));
+  info = up_stack_frame(&tcb->cmn, up_tls_size());
   if (info == NULL)
     {
       ret = -ENOMEM;
@@ -144,6 +144,8 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char 
*name, int priority,
 
   info->tl_task = tcb->cmn.group->tg_info;
 
+  up_tls_initialize(info);
+
   /* Initialize the task control block */
 
   ret = nxtask_setup_scheduler(tcb, priority, nxtask_start,
diff --git a/sched/task/task_vfork.c b/sched/task/task_vfork.c
index 942f837..1f63386 100644
--- a/sched/task/task_vfork.c
+++ b/sched/task/task_vfork.c
@@ -173,7 +173,7 @@ FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr)
 
   /* Setup thread local storage */
 
-  info = up_stack_frame(&child->cmn, sizeof(struct tls_info_s));
+  info = up_stack_frame(&child->cmn, up_tls_size());
   if (info == NULL)
     {
       ret = -ENOMEM;
@@ -184,6 +184,8 @@ FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr)
   memcpy(info, parent->cmn.stack_alloc_ptr, sizeof(struct tls_info_s));
   info->tl_task = child->cmn.group->tg_info;
 
+  up_tls_initialize(info);
+
   /* Get the priority of the parent task */
 
 #ifdef CONFIG_PRIORITY_INHERITANCE

Reply via email to