bindesc: Add initial support for binary descriptor definition

Binary descriptors are data objects stored at a known location
of a binary image. They can be read by an external tool or image,
and are used mostly for build information: version, build time,
host information, etc.
This commit adds initial support for defining such descriptors.

Signed-off-by: Yonatan Schachter <yonatan.schachter@gmail.com>
This commit is contained in:
Yonatan Schachter 2023-03-23 17:54:31 +02:00 committed by Anas Nashif
parent a7df77cd99
commit 5508b17fb4
14 changed files with 883 additions and 0 deletions

398
include/zephyr/bindesc.h Normal file
View file

@ -0,0 +1,398 @@
/*
* Copyright (c) 2023 Yonatan Schachter
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_ZEPHYR_BINDESC_H_
#define ZEPHYR_INCLUDE_ZEPHYR_BINDESC_H_
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*
* Corresponds to the definitions in scripts/west_commands/bindesc.py.
* Do not change without syncing the definitions in both files!
*/
#define BINDESC_MAGIC 0xb9863e5a7ea46046
#define BINDESC_ALIGNMENT 4
#define BINDESC_TYPE_UINT 0x0
#define BINDESC_TYPE_STR 0x1
#define BINDESC_TYPE_BYTES 0x2
#define BINDESC_TYPE_DESCRIPTORS_END 0xf
/**
* @brief Binary Descriptor Definition
* @defgroup bindesc_define Bindesc Define
* @{
*/
/*
* Corresponds to the definitions in scripts/west_commands/bindesc.py.
* Do not change without syncing the definitions in both files!
*/
/** The app version string such as "1.2.3" */
#define BINDESC_ID_APP_VERSION_STRING 0x800
/** The app version major such as 1 */
#define BINDESC_ID_APP_VERSION_MAJOR 0x801
/** The app version minor such as 2 */
#define BINDESC_ID_APP_VERSION_MINOR 0x802
/** The app version patchlevel such as 3 */
#define BINDESC_ID_APP_VERSION_PATCHLEVEL 0x803
/** The app version number such as 0x10203 */
#define BINDESC_ID_APP_VERSION_NUMBER 0x804
/** The kernel version string such as "3.4.0" */
#define BINDESC_ID_KERNEL_VERSION_STRING 0x900
/** The kernel version major such as 3 */
#define BINDESC_ID_KERNEL_VERSION_MAJOR 0x901
/** The kernel version minor such as 4 */
#define BINDESC_ID_KERNEL_VERSION_MINOR 0x902
/** The kernel version patchlevel such as 0 */
#define BINDESC_ID_KERNEL_VERSION_PATCHLEVEL 0x903
/** The kernel version number such as 0x30400 */
#define BINDESC_ID_KERNEL_VERSION_NUMBER 0x904
/** The year the image was compiled in */
#define BINDESC_ID_BUILD_TIME_YEAR 0xa00
/** The month of the year the image was compiled in */
#define BINDESC_ID_BUILD_TIME_MONTH 0xa01
/** The day of the month the image was compiled in */
#define BINDESC_ID_BUILD_TIME_DAY 0xa02
/** The hour of the day the image was compiled in */
#define BINDESC_ID_BUILD_TIME_HOUR 0xa03
/** The minute the image was compiled in */
#define BINDESC_ID_BUILD_TIME_MINUTE 0xa04
/** The second the image was compiled in */
#define BINDESC_ID_BUILD_TIME_SECOND 0xa05
/** The UNIX time (seconds since midnight of 1970/01/01) the image was compiled in */
#define BINDESC_ID_BUILD_TIME_UNIX 0xa06
/** The date and time of compilation such as "2023/02/05 00:07:04" */
#define BINDESC_ID_BUILD_DATE_TIME_STRING 0xa07
/** The date of compilation such as "2023/02/05" */
#define BINDESC_ID_BUILD_DATE_STRING 0xa08
/** The time of compilation such as "00:07:04" */
#define BINDESC_ID_BUILD_TIME_STRING 0xa09
/** The name of the host that compiled the image */
#define BINDESC_ID_HOST_NAME 0xb00
/** The C compiler name */
#define BINDESC_ID_C_COMPILER_NAME 0xb01
/** The C compiler version */
#define BINDESC_ID_C_COMPILER_VERSION 0xb02
/** The C++ compiler name */
#define BINDESC_ID_CXX_COMPILER_NAME 0xb03
/** The C++ compiler version */
#define BINDESC_ID_CXX_COMPILER_VERSION 0xb04
#define BINDESC_TAG_DESCRIPTORS_END BINDESC_TAG(DESCRIPTORS_END, 0x0fff)
/**
* @cond INTERNAL_HIDDEN
*/
/*
* Utility macro to generate a tag from a type and an ID
*
* type - Type of the descriptor, UINT, STR or BYTES
* id - Unique ID for the descriptor, must fit in 12 bits
*/
#define BINDESC_TAG(type, id) ((BINDESC_TYPE_##type & 0xf) << 12 | (id & 0x0fff))
/**
* @endcond
*/
#if !IS_ENABLED(_LINKER)
#include <zephyr/sys/byteorder.h>
/**
* @cond INTERNAL_HIDDEN
*/
/*
* Utility macro to get the name of a bindesc entry
*/
#define BINDESC_NAME(name) bindesc_entry_##name
/* Convenience helper for declaring a binary descriptor entry. */
#define __BINDESC_ENTRY_DEFINE(name) \
__aligned(BINDESC_ALIGNMENT) const struct bindesc_entry BINDESC_NAME(name) \
__in_section(_bindesc_entry, static, name) __used __noasan
/**
* @endcond
*/
/**
* @brief Define a binary descriptor of type string.
*
* @details
* Define a string that is registered in the binary descriptor header.
* The defined string can be accessed using @ref BINDESC_GET_STR
*
* @note The defined string is not static, so its name must not collide with
* any other symbol in the executable.
*
* @param name Name of the descriptor
* @param id Unique ID of the descriptor
* @param value A string value for the descriptor
*/
#define BINDESC_STR_DEFINE(name, id, value) \
__BINDESC_ENTRY_DEFINE(name) = { \
.tag = BINDESC_TAG(STR, id), \
.len = (uint16_t)sizeof(value), \
.data = value, \
}
/**
* @brief Define a binary descriptor of type uint.
*
* @details
* Define an integer that is registered in the binary descriptor header.
* The defined integer can be accessed using @ref BINDESC_GET_UINT
*
* @note The defined integer is not static, so its name must not collide with
* any other symbol in the executable.
*
* @param name Name of the descriptor
* @param id Unique ID of the descriptor
* @param value An integer value for the descriptor
*/
#define BINDESC_UINT_DEFINE(name, id, value) \
__BINDESC_ENTRY_DEFINE(name) = { \
.tag = BINDESC_TAG(UINT, id), \
.len = (uint16_t)sizeof(uint32_t), \
.data = sys_uint32_to_array(value), \
}
/**
* @brief Define a binary descriptor of type bytes.
*
* @details
* Define a uint8_t array that is registered in the binary descriptor header.
* The defined array can be accessed using @ref BINDESC_GET_BYTES.
* The value should be given as an array literal, wrapped in parentheses, for
* example:
*
* BINDESC_BYTES_DEFINE(name, id, ({1, 2, 3, 4}));
*
* @note The defined array is not static, so its name must not collide with
* any other symbol in the executable.
*
* @param name Name of the descriptor
* @param id Unique ID of the descriptor
* @param value A uint8_t array as data for the descriptor
*/
#define BINDESC_BYTES_DEFINE(name, id, value) \
__BINDESC_ENTRY_DEFINE(name) = { \
.tag = BINDESC_TAG(BYTES, id), \
.len = (uint16_t)sizeof((uint8_t [])__DEBRACKET value), \
.data = __DEBRACKET value, \
}
/**
* @brief Get the value of a string binary descriptor
*
* @details
* Get the value of a string binary descriptor, previously defined by
* BINDESC_STR_DEFINE.
*
* @param name Name of the descriptor
*/
#define BINDESC_GET_STR(name) BINDESC_NAME(name).data
/**
* @brief Get the value of a uint binary descriptor
*
* @details
* Get the value of a uint binary descriptor, previously defined by
* BINDESC_UINT_DEFINE.
*
* @param name Name of the descriptor
*/
#define BINDESC_GET_UINT(name) *(uint32_t *)&(BINDESC_NAME(name).data)
/**
* @brief Get the value of a bytes binary descriptor
*
* @details
* Get the value of a string binary descriptor, previously defined by
* BINDESC_BYTES_DEFINE. The returned value can be accessed as an array:
*
* for (size_t i = 0; i < BINDESC_GET_SIZE(name); i++)
* BINDESC_GET_BYTES(name)[i];
*
* @param name Name of the descriptor
*/
#define BINDESC_GET_BYTES(name) BINDESC_NAME(name).data
/**
* @brief Get the size of a binary descriptor
*
* @details
* Get the size of a binary descriptor. This is particularly useful for
* bytes binary descriptors where there's no null terminator.
*
* @param name Name of the descriptor
*/
#define BINDESC_GET_SIZE(name) BINDESC_NAME(name).len
/**
* @}
*/
/*
* An entry of the binary descriptor header. Each descriptor is
* described by one of these entries.
*/
struct bindesc_entry {
/** Tag of the entry */
uint16_t tag;
/** Length of the descriptor data */
uint16_t len;
/** Value of the entry. This is either an integer or a string */
uint8_t data[];
} __packed;
/*
* We're assuming that `struct bindesc_entry` has a specific layout in
* memory, so it's worth making sure that the layout is really what we
* think it is. If these assertions fail for your toolchain/platform,
* please open a bug report.
*/
BUILD_ASSERT(offsetof(struct bindesc_entry, tag) == 0, "Incorrect memory layout");
BUILD_ASSERT(offsetof(struct bindesc_entry, len) == 2, "Incorrect memory layout");
BUILD_ASSERT(offsetof(struct bindesc_entry, data) == 4, "Incorrect memory layout");
#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_STRING)
extern const struct bindesc_entry BINDESC_NAME(kernel_version_string);
#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_STRING) */
#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MAJOR)
extern const struct bindesc_entry BINDESC_NAME(kernel_version_major);
#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MAJOR) */
#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MINOR)
extern const struct bindesc_entry BINDESC_NAME(kernel_version_minor);
#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MINOR) */
#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL)
extern const struct bindesc_entry BINDESC_NAME(kernel_version_patchlevel);
#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL) */
#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_NUMBER)
extern const struct bindesc_entry BINDESC_NAME(kernel_version_number);
#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_NUMBER) */
#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_STRING)
extern const struct bindesc_entry BINDESC_NAME(app_version_string);
#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_STRING) */
#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MAJOR)
extern const struct bindesc_entry BINDESC_NAME(app_version_major);
#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MAJOR) */
#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MINOR)
extern const struct bindesc_entry BINDESC_NAME(app_version_minor);
#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MINOR) */
#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL)
extern const struct bindesc_entry BINDESC_NAME(app_version_patchlevel);
#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL) */
#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_NUMBER)
extern const struct bindesc_entry BINDESC_NAME(app_version_number);
#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_NUMBER) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_YEAR)
extern const struct bindesc_entry BINDESC_NAME(build_time_year);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_YEAR) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MONTH)
extern const struct bindesc_entry BINDESC_NAME(build_time_month);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MONTH) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_DAY)
extern const struct bindesc_entry BINDESC_NAME(build_time_day);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_DAY) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_HOUR)
extern const struct bindesc_entry BINDESC_NAME(build_time_hour);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_HOUR) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MINUTE)
extern const struct bindesc_entry BINDESC_NAME(build_time_minute);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MINUTE) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_SECOND)
extern const struct bindesc_entry BINDESC_NAME(build_time_second);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_SECOND) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_UNIX)
extern const struct bindesc_entry BINDESC_NAME(build_time_unix);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_UNIX) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_TIME_STRING)
extern const struct bindesc_entry BINDESC_NAME(build_date_time_string);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_TIME_STRING) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_STRING)
extern const struct bindesc_entry BINDESC_NAME(build_date_string);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_STRING) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_STRING)
extern const struct bindesc_entry BINDESC_NAME(build_time_string);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_STRING) */
#if IS_ENABLED(CONFIG_BINDESC_HOST_NAME)
extern const struct bindesc_entry BINDESC_NAME(host_name);
#endif /* IS_ENABLED(CONFIG_BINDESC_HOST_NAME) */
#if IS_ENABLED(CONFIG_BINDESC_C_COMPILER_NAME)
extern const struct bindesc_entry BINDESC_NAME(c_compiler_name);
#endif /* IS_ENABLED(CONFIG_BINDESC_C_COMPILER_NAME) */
#if IS_ENABLED(CONFIG_BINDESC_C_COMPILER_VERSION)
extern const struct bindesc_entry BINDESC_NAME(c_compiler_version);
#endif /* IS_ENABLED(CONFIG_BINDESC_C_COMPILER_VERSION) */
#if IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_NAME)
extern const struct bindesc_entry BINDESC_NAME(cxx_compiler_name);
#endif /* IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_NAME) */
#if IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_VERSION)
extern const struct bindesc_entry BINDESC_NAME(cxx_compiler_version);
#endif /* IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_VERSION) */
#endif /* !IS_ENABLED(_LINKER) */
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_ZEPHYR_BINDESC_H_ */

View file

@ -32,6 +32,7 @@ add_subdirectory(testsuite)
add_subdirectory(tracing)
add_subdirectory(usb)
add_subdirectory_ifdef(CONFIG_BINDESC bindesc)
add_subdirectory_ifdef(CONFIG_BT bluetooth)
add_subdirectory_ifdef(CONFIG_CONSOLE_SUBSYS console)
add_subdirectory_ifdef(CONFIG_DEMAND_PAGING demand_paging)

View file

@ -6,6 +6,7 @@
menu "Subsystems and OS Services"
source "subsys/bindesc/Kconfig"
source "subsys/bluetooth/Kconfig"
source "subsys/canbus/Kconfig"
source "subsys/console/Kconfig"

View file

@ -0,0 +1,78 @@
# SPDX-License-Identifier: Apache-2.0
zephyr_library()
if(CONFIG_X86)
zephyr_linker_sources(ROM_START SORT_KEY 0x1bindesc bindesc_no_vt.ld)
zephyr_library_sources(x86/bindesc_skip.S)
else()
zephyr_linker_sources(ROM_START SORT_KEY 0x1bindesc bindesc.ld)
endif()
macro(gen_build_time_int_definition def_name format)
if(CONFIG_BINDESC_${def_name})
string(TIMESTAMP ${def_name} ${format})
# remove leading zeros so that the output will not be interpreted as octal
math(EXPR ${def_name} ${${def_name}})
zephyr_library_compile_definitions(${def_name}=${${def_name}})
endif()
endmacro()
macro(gen_build_time_str_definition def_name format)
if(CONFIG_BINDESC_${def_name})
string(TIMESTAMP ${def_name} ${${format}})
zephyr_library_compile_definitions(${def_name}="${${def_name}}")
endif()
endmacro()
macro(gen_str_definition def_name value)
if(CONFIG_BINDESC_${def_name})
zephyr_library_compile_definitions(${def_name}="${value}")
endif()
endmacro()
if(CONFIG_BINDESC_DEFINE_BUILD_TIME)
zephyr_library_sources(bindesc_build_time.c)
gen_build_time_int_definition(BUILD_TIME_YEAR "%Y")
gen_build_time_int_definition(BUILD_TIME_MONTH "%m")
gen_build_time_int_definition(BUILD_TIME_DAY "%d")
gen_build_time_int_definition(BUILD_TIME_HOUR "%H")
gen_build_time_int_definition(BUILD_TIME_MINUTE "%M")
gen_build_time_int_definition(BUILD_TIME_SECOND "%S")
gen_build_time_int_definition(BUILD_TIME_UNIX "%s")
gen_build_time_str_definition(BUILD_DATE_TIME_STRING
CONFIG_BINDESC_BUILD_DATE_TIME_STRING_FORMAT)
gen_build_time_str_definition(BUILD_DATE_STRING
CONFIG_BINDESC_BUILD_DATE_STRING_FORMAT)
gen_build_time_str_definition(BUILD_TIME_STRING
CONFIG_BINDESC_BUILD_TIME_STRING_FORMAT)
if(CONFIG_BINDESC_BUILD_TIME_ALWAYS_REBUILD)
# By adding a custom target that invokes cmake,
# CMake is forced to rebuild this target on every build. This is
# done to ensure that the timestamp is always up to date.
add_custom_target(
bindesc_time_force_rebuild
COMMAND ${CMAKE_COMMAND} ${CMAKE_BINARY_DIR}
)
add_dependencies(${ZEPHYR_CURRENT_LIBRARY} bindesc_time_force_rebuild)
endif()
endif()
if(CONFIG_BINDESC_DEFINE_VERSION)
zephyr_library_sources(bindesc_version.c)
if(EXISTS ${APPLICATION_SOURCE_DIR}/VERSION)
zephyr_library_compile_definitions(HAS_APP_VERSION=1)
endif()
endif()
if(CONFIG_BINDESC_DEFINE_HOST_INFO)
cmake_host_system_information(RESULT hostname QUERY HOSTNAME)
zephyr_library_sources(bindesc_host_info.c)
gen_str_definition(HOST_NAME ${hostname})
gen_str_definition(C_COMPILER_NAME ${CMAKE_C_COMPILER_ID})
gen_str_definition(C_COMPILER_VERSION ${CMAKE_C_COMPILER_VERSION})
gen_str_definition(CXX_COMPILER_NAME ${CMAKE_CXX_COMPILER_ID})
gen_str_definition(CXX_COMPILER_VERSION ${CMAKE_CXX_COMPILER_VERSION})
endif()

25
subsys/bindesc/Kconfig Normal file
View file

@ -0,0 +1,25 @@
# Copyright (c) 2023 Yonatan Schachter
# SPDX-License-Identifier: Apache-2.0
menuconfig BINDESC
bool "Binary Descriptors"
depends on ARCH_SUPPORTS_ROM_START || BOARD_NATIVE_POSIX
help
Binary Descriptors - constant data accessible outside of the executable image
if BINDESC
config BINDESC_DEFINE
bool "Binary Descriptors Define"
help
Enable the app to define its own binary descriptors
if BINDESC_DEFINE
source "subsys/bindesc/Kconfig.version"
source "subsys/bindesc/Kconfig.build_time"
source "subsys/bindesc/Kconfig.host_info"
endif # BINDESC_DEFINE
endif # BINDESC

View file

@ -0,0 +1,106 @@
# Copyright (c) 2023 Yonatan Schachter
# SPDX-License-Identifier: Apache-2.0
menuconfig BINDESC_DEFINE_BUILD_TIME
bool "Build Time binary descriptors"
help
Add the build time binary descriptors
if BINDESC_DEFINE_BUILD_TIME
config BINDESC_BUILD_TIME_ALWAYS_REBUILD
bool "Always rebuild"
default y
help
If enabled, the file containing the build time definitions will
always be rebuilt. This results in the timestamp always being
accurate, but also in slightly longer build times.
config BINDESC_BUILD_TIME_YEAR
bool "Year of build"
help
The year the image was compiled, such as 2023
config BINDESC_BUILD_TIME_MONTH
bool "Month of build"
help
The month the image was compiled, such as 5 (May)
config BINDESC_BUILD_TIME_DAY
bool "Day of build"
help
The day of the month the image was compiled, such as 9
config BINDESC_BUILD_TIME_HOUR
bool "Hour of build"
help
The hour of the day the image was compiled, such as 13 in 13:34:52
config BINDESC_BUILD_TIME_MINUTE
bool "Minute of build"
help
The minute the image was compiled, such as 34 in 13:34:52
config BINDESC_BUILD_TIME_SECOND
bool "Second of build"
help
The second the image was compiled, such as 52 in 13:34:52
config BINDESC_BUILD_TIME_UNIX
bool "Build time as UNIX time"
help
The UNIX time at which the image was compiled. This is an integer
counting the seconds since midnight of January 1st 1970
config BINDESC_BUILD_DATE_TIME_STRING
bool "Build date and time as string"
help
The date and time of compilation as a string, such as "2023/02/05 00:07:04"
config BINDESC_BUILD_DATE_STRING
bool "Build date as string"
help
The date of compilation as a string, such as "2023/02/05"
config BINDESC_BUILD_TIME_STRING
bool "Build time as string"
help
The time of compilation as a string, such as "00:07:04"
config BINDESC_BUILD_DATE_TIME_STRING_FORMAT
depends on BINDESC_BUILD_DATE_TIME_STRING
string "Date-Time format"
default "%Y/%m/%d %H:%M:%S"
help
Format of the build time string. This value is passed to cmake's string(TIMESTAMP ...)
function, so refer to string's documentation for more info on the different formats.
This can also be used to set a specific time, when trying to reproduce an image. For
example, setting the format to "2023/02/05 00:07:04" will set it as the build time,
regardless of the actual build time.
Example of the default format: 2023/02/05 00:07:04
config BINDESC_BUILD_DATE_STRING_FORMAT
depends on BINDESC_BUILD_DATE_STRING
string "Date format"
default "%Y/%m/%d"
help
Format of the build date string. This value is passed to cmake's string(TIMESTAMP ...)
function, so refer to string's documentation for more info on the different formats.
This can also be used to set a specific time, when trying to reproduce an image. For
example, setting the format to "2023/02/05" will set it as the build time,
regardless of the actual build time.
Example of the default format: 2023/02/05
config BINDESC_BUILD_TIME_STRING_FORMAT
depends on BINDESC_BUILD_TIME_STRING
string "Time format"
default "%H:%M:%S"
help
Format of the build time string. This value is passed to cmake's string(TIMESTAMP ...)
function, so refer to string's documentation for more info on the different formats.
This can also be used to set a specific time, when trying to reproduce an image. For
example, setting the format to "00:07:04" will set it as the build time,
regardless of the actual build time.
Example of the default format: 00:07:04
endif # BINDESC_DEFINE_BUILD_TIME

View file

@ -0,0 +1,36 @@
# Copyright (c) 2023 Yonatan Schachter
# SPDX-License-Identifier: Apache-2.0
menuconfig BINDESC_DEFINE_HOST_INFO
bool "Host info binary descriptors"
help
Add the host info binary descriptors
if BINDESC_DEFINE_HOST_INFO
config BINDESC_HOST_NAME
bool "Host name"
help
The name of the host that the image was compiled on
config BINDESC_C_COMPILER_NAME
bool "C compiler name"
help
The C compiler name, such as "GNU"
config BINDESC_C_COMPILER_VERSION
bool "C compiler version"
help
The C compiler version, such as "12.3.0"
config BINDESC_CXX_COMPILER_NAME
bool "C++ compiler name"
help
The C++ compiler name, such as "GNU"
config BINDESC_CXX_COMPILER_VERSION
bool "C++ compiler version"
help
The C++ compiler version, such as "12.3.0"
endif # BINDESC_DEFINE_HOST_INFO

View file

@ -0,0 +1,65 @@
# Copyright (c) 2023 Yonatan Schachter
# SPDX-License-Identifier: Apache-2.0
menuconfig BINDESC_DEFINE_VERSION
bool "Version binary descriptors"
help
Add the version binary descriptors
if BINDESC_DEFINE_VERSION
config BINDESC_KERNEL_VERSION_STRING
bool "Kernel version string"
help
The kernel version string, such as "3.4.0"
config BINDESC_KERNEL_VERSION_MAJOR
bool "Kernel version major"
help
The major version number, such as 3 in 3.4.0
config BINDESC_KERNEL_VERSION_MINOR
bool "Kernel version minor"
help
The minor version number, such as 4 in 3.4.0
config BINDESC_KERNEL_VERSION_PATCHLEVEL
bool "Kernel version patchlevel"
help
The patchlevel version number, such as 0 in 3.4.0
config BINDESC_KERNEL_VERSION_NUMBER
bool "Kernel version number"
help
The kernel version as binary coded decimal, computed as
(major << 16 | minor << 8 | patchlevel). For example,
3.4.0 would be represented as 0x30400
config BINDESC_APP_VERSION_STRING
bool "App version string"
help
The app version string, such as "1.0.0"
config BINDESC_APP_VERSION_MAJOR
bool "App version major"
help
The app major version number, such as 1 in 1.0.0
config BINDESC_APP_VERSION_MINOR
bool "App version minor"
help
The app minor version number, such as 0 in 1.0.0
config BINDESC_APP_VERSION_PATCHLEVEL
bool "App version patchlevel"
help
The app patchlevel version number, such as 0 in 1.0.0
config BINDESC_APP_VERSION_NUMBER
bool "App version number"
help
The app version as binary coded decimal, computed as
(major << 16 | minor << 8 | patchlevel). For example,
1.0.0 would be represented as 0x10000
endif # BINDESC_DEFINE_VERSION

13
subsys/bindesc/bindesc.ld Normal file
View file

@ -0,0 +1,13 @@
/*
* Copyright (c) 2023 Yonatan Schachter
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/linker/iterable_sections.h>
#include <zephyr/bindesc.h>
SQUAD(BINDESC_MAGIC);
Z_LINK_ITERABLE(bindesc_entry);
. = ALIGN(BINDESC_ALIGNMENT);
LONG(BINDESC_TAG_DESCRIPTORS_END)

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2023 Yonatan Schachter
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/bindesc.h>
#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_YEAR)
BINDESC_UINT_DEFINE(build_time_year, BINDESC_ID_BUILD_TIME_YEAR, BUILD_TIME_YEAR);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_YEAR) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MONTH)
BINDESC_UINT_DEFINE(build_time_month, BINDESC_ID_BUILD_TIME_MONTH, BUILD_TIME_MONTH);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MONTH) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_DAY)
BINDESC_UINT_DEFINE(build_time_day, BINDESC_ID_BUILD_TIME_DAY, BUILD_TIME_DAY);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_DAY) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_HOUR)
BINDESC_UINT_DEFINE(build_time_hour, BINDESC_ID_BUILD_TIME_HOUR, BUILD_TIME_HOUR);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_HOUR) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MINUTE)
BINDESC_UINT_DEFINE(build_time_minute, BINDESC_ID_BUILD_TIME_MINUTE, BUILD_TIME_MINUTE);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MINUTE) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_SECOND)
BINDESC_UINT_DEFINE(build_time_second, BINDESC_ID_BUILD_TIME_SECOND, BUILD_TIME_SECOND);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_SECOND) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_UNIX)
BINDESC_UINT_DEFINE(build_time_unix, BINDESC_ID_BUILD_TIME_UNIX, BUILD_TIME_UNIX);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_UNIX) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_TIME_STRING)
BINDESC_STR_DEFINE(build_date_time_string, BINDESC_ID_BUILD_DATE_TIME_STRING,
BUILD_DATE_TIME_STRING);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_TIME_STRING) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_STRING)
BINDESC_STR_DEFINE(build_date_string, BINDESC_ID_BUILD_DATE_STRING, BUILD_DATE_STRING);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_STRING) */
#if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_STRING)
BINDESC_STR_DEFINE(build_time_string, BINDESC_ID_BUILD_TIME_STRING, BUILD_TIME_STRING);
#endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_STRING) */

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2023 Yonatan Schachter
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/bindesc.h>
#if IS_ENABLED(CONFIG_BINDESC_HOST_NAME)
BINDESC_STR_DEFINE(host_name, BINDESC_ID_HOST_NAME, HOST_NAME);
#endif /* IS_ENABLED(CONFIG_BINDESC_HOST_NAME) */
#if IS_ENABLED(CONFIG_BINDESC_C_COMPILER_NAME)
BINDESC_STR_DEFINE(c_compiler_name, BINDESC_ID_C_COMPILER_NAME, C_COMPILER_NAME);
#endif /* IS_ENABLED(CONFIG_BINDESC_C_COMPILER_NAME) */
#if IS_ENABLED(CONFIG_BINDESC_C_COMPILER_VERSION)
BINDESC_STR_DEFINE(c_compiler_version, BINDESC_ID_C_COMPILER_VERSION, C_COMPILER_VERSION);
#endif /* IS_ENABLED(CONFIG_BINDESC_C_COMPILER_VERSION) */
#if IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_NAME)
BINDESC_STR_DEFINE(cxx_compiler_name, BINDESC_ID_CXX_COMPILER_NAME, CXX_COMPILER_NAME);
#endif /* IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_NAME) */
#if IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_VERSION)
BINDESC_STR_DEFINE(cxx_compiler_version, BINDESC_ID_CXX_COMPILER_VERSION,
CXX_COMPILER_VERSION);
#endif /* IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_VERSION) */

View file

@ -0,0 +1,9 @@
/*
* Copyright (c) 2023 Yonatan Schachter
*
* SPDX-License-Identifier: Apache-2.0
*/
KEEP(*(.bindesc_skip));
. = ALIGN(4);
#include "bindesc.ld"

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2023 Yonatan Schachter
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/bindesc.h>
#include <version.h>
#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_STRING)
BINDESC_STR_DEFINE(kernel_version_string, BINDESC_ID_KERNEL_VERSION_STRING,
KERNEL_VERSION_STRING);
#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_STRING) */
#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MAJOR)
BINDESC_UINT_DEFINE(kernel_version_major, BINDESC_ID_KERNEL_VERSION_MAJOR,
KERNEL_VERSION_MAJOR);
#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MAJOR) */
#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MINOR)
BINDESC_UINT_DEFINE(kernel_version_minor, BINDESC_ID_KERNEL_VERSION_MINOR,
KERNEL_VERSION_MINOR);
#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MINOR) */
#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL)
BINDESC_UINT_DEFINE(kernel_version_patchlevel, BINDESC_ID_KERNEL_VERSION_PATCHLEVEL,
KERNEL_PATCHLEVEL);
#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL) */
#if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_NUMBER)
BINDESC_UINT_DEFINE(kernel_version_number, BINDESC_ID_KERNEL_VERSION_NUMBER,
KERNEL_VERSION_NUMBER);
#endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_NUMBER) */
#if IS_ENABLED(HAS_APP_VERSION)
#include <app_version.h>
#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_STRING)
BINDESC_STR_DEFINE(app_version_string, BINDESC_ID_APP_VERSION_STRING,
APP_VERSION_STRING);
#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_STRING) */
#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MAJOR)
BINDESC_UINT_DEFINE(app_version_major, BINDESC_ID_APP_VERSION_MAJOR,
APP_VERSION_MAJOR);
#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MAJOR) */
#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MINOR)
BINDESC_UINT_DEFINE(app_version_minor, BINDESC_ID_APP_VERSION_MINOR,
APP_VERSION_MINOR);
#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MINOR) */
#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL)
BINDESC_UINT_DEFINE(app_version_patchlevel, BINDESC_ID_APP_VERSION_PATCHLEVEL,
APP_PATCHLEVEL);
#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL) */
#if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_NUMBER)
BINDESC_UINT_DEFINE(app_version_number, BINDESC_ID_APP_VERSION_NUMBER,
APP_VERSION_NUMBER);
#endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_NUMBER) */
#endif /* IS_ENABLED(HAS_APP_VERSION) */

View file

@ -0,0 +1,9 @@
/*
* Copyright (c) 2023 Yonatan Schachter
*
* SPDX-License-Identifier: Apache-2.0
*/
.section .bindesc_skip
_bindesc_skip:
jmp __start