sysinit: Add RTEMS_SYSINIT_ZERO_MEMORY

Use a dedicate system initialization step to zero the memory used for
the workspace and C program heap.

This avoids dead code in case CONFIGURE_ZERO_WORKSPACE_AUTOMATICALLY is
not configured.
This commit is contained in:
Sebastian Huber
2020-02-04 13:56:41 +01:00
parent 1d43a976a8
commit 8ecbc3826e
10 changed files with 111 additions and 22 deletions

View File

@@ -854,6 +854,8 @@ librtemscpu_a_SOURCES += score/src/heapgreedy.c
librtemscpu_a_SOURCES += score/src/heapnoextend.c
librtemscpu_a_SOURCES += score/src/memoryallocate.c
librtemscpu_a_SOURCES += score/src/memoryfill.c
librtemscpu_a_SOURCES += score/src/memoryzerobeforeuse.c
librtemscpu_a_SOURCES += score/src/memoryzerofreeareas.c
librtemscpu_a_SOURCES += score/src/objectallocate.c
librtemscpu_a_SOURCES += score/src/objectclose.c
librtemscpu_a_SOURCES += score/src/objectextendinformation.c

View File

@@ -2778,11 +2778,6 @@ struct _reent *__getreent(void)
CONFIGURE_TASK_STACK_ALLOCATOR_INIT, /* stack allocator init */
CONFIGURE_TASK_STACK_ALLOCATOR, /* stack allocator */
CONFIGURE_TASK_STACK_DEALLOCATOR, /* stack deallocator */
#ifdef CONFIGURE_ZERO_WORKSPACE_AUTOMATICALLY /* true to clear memory */
true,
#else
false,
#endif
#ifdef CONFIGURE_UNIFIED_WORK_AREAS /* true for unified work areas */
true,
#else
@@ -2807,6 +2802,16 @@ struct _reent *__getreent(void)
#endif
};
#ifdef CONFIGURE_ZERO_WORKSPACE_AUTOMATICALLY
const bool _Memory_Zero_before_use = true;
RTEMS_SYSINIT_ITEM(
_Memory_Zero_free_areas,
RTEMS_SYSINIT_ZERO_MEMORY,
RTEMS_SYSINIT_ORDER_MIDDLE
);
#endif
#if CONFIGURE_RECORD_PER_PROCESSOR_ITEMS > 0
#if (CONFIGURE_RECORD_PER_PROCESSOR_ITEMS & (CONFIGURE_RECORD_PER_PROCESSOR_ITEMS - 1)) != 0
#error "CONFIGURE_RECORD_PER_PROCESSOR_ITEMS must be a power of two"

View File

@@ -29,6 +29,7 @@
#include <rtems/score/object.h>
#include <rtems/score/isr.h>
#include <rtems/score/memory.h>
#include <rtems/score/userextdata.h>
#include <rtems/score/watchdogticks.h>
#include <rtems/rtems/config.h>
@@ -148,14 +149,6 @@ typedef struct {
*/
rtems_stack_free_hook stack_free_hook;
/**
* If this element is TRUE, then RTEMS will zero the Executive Workspace.
* When this element is FALSE, it is assumed that the BSP or invoking
* environment has ensured that memory was cleared before RTEMS was
* invoked.
*/
bool do_zero_of_workspace;
/**
* @brief Specifies if a unified work area is used or not.
*
@@ -241,7 +234,7 @@ uint32_t rtems_configuration_get_maximum_extensions( void );
* RTEMS is responsible for zeroing the Executive Workspace.
*/
#define rtems_configuration_get_do_zero_of_workspace() \
(Configuration.do_zero_of_workspace)
_Memory_Zero_before_use
#define rtems_configuration_get_number_of_initial_extensions() \
((uint32_t) _User_extensions_Initial_count)

View File

@@ -331,6 +331,19 @@ void *_Memory_Allocate(
*/
void _Memory_Fill( const Memory_Information *information, int c );
/**
* @brief Indicates if the memory is zeroed during system initialization.
*
* This value is provided via <rtems/confdefs.h> in case
* CONFIGURE_ZERO_WORKSPACE_AUTOMATICALLY is defined.
*/
extern const bool _Memory_Zero_before_use;
/**
* @brief Zeros all free memory areas of the system.
*/
void _Memory_Zero_free_areas( void );
/** @} */
#ifdef __cplusplus

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018 embedded brains GmbH. All rights reserved.
* Copyright (c) 2015, 2020 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
@@ -30,6 +30,7 @@ extern "C" {
#define RTEMS_SYSINIT_BSP_EARLY 000140
#define RTEMS_SYSINIT_MEMORY 000180
#define RTEMS_SYSINIT_DIRTY_MEMORY 0001c0
#define RTEMS_SYSINIT_ZERO_MEMORY 0001e0
#define RTEMS_SYSINIT_ISR_STACK 000200
#define RTEMS_SYSINIT_PER_CPU_DATA 000220
#define RTEMS_SYSINIT_SBRK 000240

View File

@@ -48,6 +48,7 @@ RTEMS_LINKER_RWSET_ITEM_DECLARE(
SYSINIT_VERBOSE( BSP_EARLY );
SYSINIT_VERBOSE( MEMORY );
SYSINIT_VERBOSE( DIRTY_MEMORY );
SYSINIT_VERBOSE( ZERO_MEMORY );
SYSINIT_VERBOSE( ISR_STACK );
SYSINIT_VERBOSE( PER_CPU_DATA );
SYSINIT_VERBOSE( SBRK );
@@ -192,9 +193,16 @@ static void _Sysinit_Verbose_DIRTY_MEMORY( void )
}
}
static void _Sysinit_Verbose_ZERO_MEMORY( void )
{
if ( !SYSINIT_IS_ADJACENT( DIRTY_MEMORY, ZERO_MEMORY ) ) {
printk( "sysinit: ZERO_MEMORY: done\n" );
}
}
static void _Sysinit_Verbose_ISR_STACK( void )
{
if ( !SYSINIT_IS_ADJACENT( DIRTY_MEMORY, ISR_STACK ) ) {
if ( !SYSINIT_IS_ADJACENT( ZERO_MEMORY, ISR_STACK ) ) {
printk( "sysinit: ISR_STACK: done\n" );
}
}

View File

@@ -0,0 +1,34 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2020 embedded brains GmbH
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/memory.h>
const bool _Memory_Zero_before_use;

View File

@@ -0,0 +1,37 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2020 embedded brains GmbH
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/memory.h>
void _Memory_Zero_free_areas( void )
{
_Memory_Fill( _Memory_Get(), 0 );
}

View File

@@ -90,7 +90,6 @@ void _Workspace_Handler_initialization(
{
Heap_Initialization_or_extend_handler init_or_extend;
uintptr_t remaining;
bool do_zero;
bool unified;
uintptr_t page_size;
uintptr_t overhead;
@@ -101,7 +100,6 @@ void _Workspace_Handler_initialization(
remaining += _Workspace_Space_for_TLS( page_size );
init_or_extend = _Heap_Initialize;
do_zero = rtems_configuration_get_do_zero_of_workspace();
unified = rtems_configuration_get_unified_work_area();
overhead = _Heap_Area_overhead( page_size );
@@ -112,10 +110,6 @@ void _Workspace_Handler_initialization(
area = _Memory_Get_area( mem, i );
free_size = _Memory_Get_free_size( area );
if ( do_zero ) {
memset( _Memory_Get_free_begin( area ), 0, free_size );
}
if ( free_size > overhead ) {
uintptr_t space_available;
uintptr_t size;

View File

@@ -50,6 +50,8 @@ static void *Init( uintptr_t ignored )
);
fatal_directive_status( status, RTEMS_INVALID_NAME, "rtems_task_ident" );
rtems_test_assert( rtems_configuration_get_do_zero_of_workspace() );
TEST_END();
rtems_test_exit(0);
}