meta-digi-dey: bootcount: add new binary application to manage the bootcount
Add a user space application to manage the bootcount from the running system. This application allows to read, reset and set the bootcount: Usage: bootcount [options] -r --read Read the current bootcount value (Default action) -s <value> --set=<value> Set current bootcount to a specific value. -x --reset Reset bootcount value to zero. The binary checks the running platform underneath to perform the correct system access. While on it, add a service to automatically execute the binary on boot to reset the bootcount value. https://onedigi.atlassian.net/browse/DEL-8506 Signed-off-by: David Escalona <david.escalona@digi.com>
This commit is contained in:
parent
88f74279b1
commit
7174a42e87
|
|
@ -0,0 +1,44 @@
|
|||
# Copyright (C) 2023 Digi International
|
||||
|
||||
SUMMARY = "Application to manage the bootcount value"
|
||||
LICENSE = "MPL-2.0"
|
||||
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
|
||||
|
||||
DEPENDS = "libubootenv"
|
||||
|
||||
PV = "1.0"
|
||||
|
||||
SRC_URI = " \
|
||||
file://bootcount-bin \
|
||||
file://bootcount-init/bootcount-init \
|
||||
file://bootcount-init/bootcount-init.service \
|
||||
"
|
||||
|
||||
S = "${WORKDIR}/bootcount-bin"
|
||||
|
||||
inherit pkgconfig systemd update-rc.d
|
||||
|
||||
do_install() {
|
||||
oe_runmake DESTDIR=${D} install
|
||||
|
||||
# INITSCRIPT
|
||||
install -d ${D}${sysconfdir}/init.d/
|
||||
install -m 0755 ${WORKDIR}/bootcount-init/bootcount-init ${D}${sysconfdir}/bootcount-init
|
||||
ln -sf /etc/bootcount-init ${D}${sysconfdir}/init.d/bootcount-init
|
||||
|
||||
# SYSTEMD
|
||||
install -d ${D}${systemd_unitdir}/system/
|
||||
install -m 0644 ${WORKDIR}/bootcount-init/bootcount-init.service ${D}${systemd_unitdir}/system/
|
||||
}
|
||||
|
||||
FILES:${PN} += " \
|
||||
${sysconfdir}/bootcount-init \
|
||||
${sysconfdir}/init.d/bootcount-init \
|
||||
${systemd_unitdir}/system/bootcount-init.service \
|
||||
"
|
||||
|
||||
INITSCRIPT_PACKAGES += "${PN}"
|
||||
INITSCRIPT_NAME:${PN} = "bootcount-init"
|
||||
INITSCRIPT_PARAMS:${PN = "start 19 2 3 4 5 . stop 21 0 1 6 ."
|
||||
|
||||
SYSTEMD_SERVICE:${PN} = "bootcount-init.service"
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
bootcount
|
||||
*.o
|
||||
.cproject
|
||||
.project
|
||||
.settings/
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#
|
||||
# Copyright (c) 2023, Digi International Inc.
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, you can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
PROGRAM := bootcount
|
||||
|
||||
GIT_REVISION := $(shell git rev-parse --verify --short=7 HEAD 2>/dev/null)
|
||||
|
||||
CFLAGS += -Wall -DGIT_REVISION=\"$(if $(GIT_REVISION),-g$(GIT_REVISION))\"
|
||||
CFLAGS += -Iinclude
|
||||
CFLAGS += $(shell pkg-config --cflags libubootenv)
|
||||
LDLIBS += $(shell pkg-config --libs libubootenv)
|
||||
|
||||
SRCS = $(wildcard *.c)
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
.PHONY: all
|
||||
all: $(PROGRAM)
|
||||
|
||||
$(PROGRAM): $(OBJS)
|
||||
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
.PHONY: install
|
||||
install: $(PROGRAM)
|
||||
install -d $(DESTDIR)/usr/bin
|
||||
install -m 0755 $(PROGRAM) $(DESTDIR)/usr/bin/
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
-rm -f *.o $(PROGRAM)
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bootcount_env.h"
|
||||
#include "bootcount_nvmem.h"
|
||||
#include "platform_utils.h"
|
||||
|
||||
#define VERSION "1.0" GIT_REVISION
|
||||
|
||||
#define USAGE \
|
||||
"Bootcount utility.\n" \
|
||||
"Copyright(c) Digi International Inc.\n" \
|
||||
"\n" \
|
||||
"Version: %s\n" \
|
||||
"\n" \
|
||||
"Usage: bootcount [options] \n\n" \
|
||||
" -p --print Print the current bootcount value (Default action)\n" \
|
||||
" -s <value> --set=<value> Set current bootcount to a specific value.\n" \
|
||||
" -r --reset Reset bootcount value to zero.\n" \
|
||||
" -h --help Print help and exit\n" \
|
||||
"\n"
|
||||
|
||||
/*
|
||||
* Struct used to store the pointers to the methods to read/write
|
||||
* the bootcount value for each platform.
|
||||
*/
|
||||
struct platform_functions {
|
||||
int (*read_bootcount) (void);
|
||||
int (*write_bootcount) (unsigned int);
|
||||
};
|
||||
|
||||
/*
|
||||
* Static list of the platforms with their corresponding methods to
|
||||
* access the bootcount.
|
||||
*/
|
||||
struct platform_functions platforms_functions[] = {
|
||||
[PLATFORM_CC6QP] = {read_bootcount_env, write_bootcount_env},
|
||||
[PLATFORM_CC6SBC] = {read_bootcount_env, write_bootcount_env},
|
||||
[PLATFORM_CC6UL] = {read_bootcount_nvmem, write_bootcount_nvmem},
|
||||
[PLATFORM_CC8MM] = {read_bootcount_nvmem, write_bootcount_nvmem},
|
||||
[PLATFORM_CC8MN] = {read_bootcount_nvmem, write_bootcount_nvmem},
|
||||
[PLATFORM_CC8X] = {read_bootcount_nvmem, write_bootcount_nvmem},
|
||||
[PLATFORM_CC93] = {read_bootcount_nvmem, write_bootcount_nvmem},
|
||||
[PLATFORM_CCMP13] = {read_bootcount_nvmem, write_bootcount_nvmem},
|
||||
[PLATFORM_CCMP15] = {read_bootcount_nvmem, write_bootcount_nvmem},
|
||||
[PLATFORM_UNKNOWN] = {NULL, NULL}
|
||||
};
|
||||
|
||||
/* Global variables. */
|
||||
platform_t platform;
|
||||
|
||||
/* Command line variables */
|
||||
static bool read, write, reset = false;
|
||||
static uint write_value;
|
||||
|
||||
/**
|
||||
* @brief Print usage information and exit the program with the specified exit value.
|
||||
*
|
||||
* @param exitval The exit status code for the program.
|
||||
*/
|
||||
static void usage_and_exit(int exitval) {
|
||||
fprintf(stdout, USAGE, VERSION);
|
||||
|
||||
exit(exitval);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parses command-line options.
|
||||
*
|
||||
* This function parses the command-line options passed to the bootcount utility.
|
||||
*
|
||||
* If no options are provided (`argc == 1`), the default action is assumed to be read,
|
||||
* and the 'read' flag is set to true.
|
||||
*
|
||||
* If invalid options or incorrect bootcount values are provided, the function prints
|
||||
* error messages and exits with failure status.
|
||||
*
|
||||
* @param argc The number of command-line arguments.
|
||||
* @param argv An array of strings containing the command-line arguments.
|
||||
*/
|
||||
static void parse_options(int argc, char *argv[]) {
|
||||
static int opt_index, opt;
|
||||
static const char *short_options = "ps:rh";
|
||||
static const struct option long_options[] = {
|
||||
{"print", no_argument, NULL, 'p'},
|
||||
{"set", required_argument, NULL, 's'},
|
||||
{"reset", no_argument, NULL, 'r'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
char *endptr;
|
||||
|
||||
if (argc == 1) {
|
||||
/* Consider default action is print. */
|
||||
read = true;
|
||||
return;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
opt = getopt_long(argc, argv, short_options, long_options, &opt_index);
|
||||
if (opt == -1)
|
||||
break;
|
||||
|
||||
switch (opt) {
|
||||
case 'p':
|
||||
read = true;
|
||||
break;
|
||||
case 's':
|
||||
write = true;
|
||||
write_value = (int)strtoul(optarg, &endptr, 10);
|
||||
if (*endptr) {
|
||||
printf("Error: incorrect bootcount value\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
reset = true;
|
||||
break;
|
||||
case 'h':
|
||||
usage_and_exit(EXIT_SUCCESS);
|
||||
break;
|
||||
default:
|
||||
usage_and_exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main program function and entry point.
|
||||
*
|
||||
* @param argc The number of command-line arguments.
|
||||
* @param argv An array of strings containing the command-line arguments.
|
||||
*
|
||||
* @return 0 if the process finishes successfully, any other value otherwise..
|
||||
*/
|
||||
int main(int argc, char *argv[]) {
|
||||
int ret = 0;
|
||||
struct platform_functions *pfuncs;
|
||||
|
||||
/* Read and parse command line */
|
||||
parse_options(argc, argv);
|
||||
|
||||
/* Determine platform. */
|
||||
platform = get_platform();
|
||||
pfuncs = &platforms_functions[platform];
|
||||
|
||||
/* Execute the requested action. */
|
||||
if (read) {
|
||||
ret = pfuncs->read_bootcount();
|
||||
if (ret >= 0) {
|
||||
printf("%d\n", ret);
|
||||
ret = 0;
|
||||
}
|
||||
} else if (write) {
|
||||
ret = pfuncs->write_bootcount(write_value);
|
||||
} else if (reset) {
|
||||
ret = pfuncs->write_bootcount(0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bootcount_env.h"
|
||||
#include "libuboot.h"
|
||||
|
||||
/* Environment variables. */
|
||||
#define ENV_VAR_UPGRADE_AVAILABLE "upgrade_available"
|
||||
#define ENV_VAR_BOOTCOUNT "bootcount"
|
||||
|
||||
int read_bootcount_env() {
|
||||
int ret;
|
||||
char* endptr;
|
||||
const char *var;
|
||||
|
||||
/* Obtain 'bootcount' value from environment. */
|
||||
ret = uboot_getenv(ENV_VAR_BOOTCOUNT, &var);
|
||||
if (!ret) {
|
||||
/* Convert read value to integer. */
|
||||
ret = (int)strtoul(var, &endptr, 10);
|
||||
if (*endptr) {
|
||||
printf("Error: incorrect bootcount value in environment\n");
|
||||
ret = -1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Error: could not read '%s' variable from U-Boot environment'\n", ENV_VAR_BOOTCOUNT);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
free((char*)var);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int write_bootcount_env(uint count) {
|
||||
int ret;
|
||||
char value_str[5];
|
||||
|
||||
/* Convert value to string. */
|
||||
snprintf(value_str, sizeof(value_str), "%u", count);
|
||||
/* Write value to environment. */
|
||||
ret = uboot_setenv(ENV_VAR_BOOTCOUNT, value_str);
|
||||
if (ret) {
|
||||
fprintf(stderr, "Error: could not write '%s' variable to U-Boot environment\n", ENV_VAR_BOOTCOUNT);
|
||||
ret = -1;
|
||||
} else if (count == 0) {
|
||||
/* Clear 'upgrade_available' variable. */
|
||||
ret = uboot_setenv(ENV_VAR_UPGRADE_AVAILABLE, NULL);
|
||||
if (ret) {
|
||||
fprintf(stderr, "Error: could not unset '%s' variable in U-Boot environment\n", ENV_VAR_UPGRADE_AVAILABLE);
|
||||
ret = -1;
|
||||
}
|
||||
} else {
|
||||
/* Set 'upgrade_available' variable to '1'. */
|
||||
snprintf(value_str, sizeof(value_str), "%u", 1);
|
||||
ret = uboot_setenv(ENV_VAR_UPGRADE_AVAILABLE, value_str);
|
||||
if (ret) {
|
||||
fprintf(stderr, "Error: could not set '%s' variable in U-Boot environment\n", ENV_VAR_UPGRADE_AVAILABLE);
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "file_utils.h"
|
||||
#include "bootcount_nvmem.h"
|
||||
#include "platform_utils.h"
|
||||
|
||||
/* Platform struct for the bootcount nvmem access */
|
||||
struct platform_nvmem {
|
||||
const char *nvmem_path;
|
||||
long bootcount_offset;
|
||||
int bootcount_size;
|
||||
};
|
||||
|
||||
/* List of platform structs for the bootcount nvmem access */
|
||||
struct platform_nvmem platforms_nvmem[] = {
|
||||
[PLATFORM_CC6QP] = {NULL, 0, 1},
|
||||
[PLATFORM_CC6SBC] = {NULL, 0, 1},
|
||||
[PLATFORM_CC6UL] = {"/sys/bus/i2c/devices/0-007e/nvram", 0, 1},
|
||||
[PLATFORM_CC8MM] = {"/sys/bus/i2c/devices/0-0063/nvram", 0, 1},
|
||||
[PLATFORM_CC8MN] = {"/sys/bus/i2c/devices/0-0063/nvram", 0, 1},
|
||||
[PLATFORM_CC8X] = {"/sys/bus/i2c/devices/0-0063/nvram", 0, 1},
|
||||
[PLATFORM_CC93] = {"/sys/bus/i2c/devices/2-0052/rv3028_nvram0/nvmem", 0, 1},
|
||||
[PLATFORM_CCMP13] = {"/sys/bus/i2c/devices/2-0052/rv3028_nvram0/nvmem", 0, 1},
|
||||
[PLATFORM_CCMP15] = {"/sys/bus/i2c/devices/6-0052/rv3028_nvram0/nvmem", 0, 1},
|
||||
[PLATFORM_UNKNOWN] = {NULL, 0, 0},
|
||||
};
|
||||
|
||||
/* Variables. */
|
||||
extern platform_t platform;
|
||||
|
||||
int read_bootcount_nvmem() {
|
||||
char value;
|
||||
int ret;
|
||||
struct platform_nvmem *platform_data = &platforms_nvmem[platform];
|
||||
|
||||
ret = read_file(platform_data->nvmem_path, &value, platform_data->bootcount_offset, platform_data->bootcount_size);
|
||||
if (!ret) {
|
||||
return value;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int write_bootcount_nvmem(uint count) {
|
||||
char value = (char)(count & 0xFF);
|
||||
struct platform_nvmem *platform_data = &platforms_nvmem[platform];
|
||||
|
||||
return write_file(platform_data->nvmem_path, &value, platform_data->bootcount_offset, platform_data->bootcount_size);
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "file_utils.h"
|
||||
|
||||
int read_file(const char* path, char* buffer, long offset, int num_bytes) {
|
||||
FILE* file;
|
||||
int ret = -1;
|
||||
|
||||
/* Sanity check. */
|
||||
if (path == NULL) {
|
||||
fprintf(stderr, "Error opening file: path is NULL");
|
||||
return ret;
|
||||
}
|
||||
|
||||
file = fopen(path, "rb");
|
||||
if (!file) {
|
||||
fprintf(stderr, "Error opening file");
|
||||
return ret;
|
||||
}
|
||||
|
||||
fseek(file, offset, SEEK_SET);
|
||||
ret = fread(buffer, sizeof(char), num_bytes, file);
|
||||
if (ret != num_bytes) {
|
||||
printf("Error reading from file '%s'\n", path);
|
||||
ret = -1;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int write_file(const char* path, const char* data, long offset, int num_bytes) {
|
||||
FILE* file;
|
||||
int ret = -1;
|
||||
|
||||
/* Sanity check. */
|
||||
if (path == NULL) {
|
||||
fprintf(stderr, "Error opening file: path is NULL");
|
||||
return ret;
|
||||
}
|
||||
|
||||
file = fopen(path, "r+b");
|
||||
if (!file) {
|
||||
fprintf(stderr, "Error opening file");
|
||||
return ret;
|
||||
}
|
||||
|
||||
fseek(file, offset, SEEK_SET);
|
||||
ret = fwrite(data, sizeof(char), num_bytes, file);
|
||||
if (ret != num_bytes) {
|
||||
printf("Error writing to file '%s'\n", path);
|
||||
ret = -1;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef BOOTCOUNT_ENV_H
|
||||
#define BOOTCOUNT_ENV_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* @brief Read the 'bootcount' variable from the U-Boot environment.
|
||||
*
|
||||
* This function retrieves the 'bootcount' value from the U-Boot environment and
|
||||
* converts it to an integer.
|
||||
*
|
||||
* @return The 'bootcount' value as an integer on success, -1 on error.
|
||||
*/
|
||||
int read_bootcount_env();
|
||||
|
||||
/**
|
||||
* @brief Set the 'bootcount' variable in the U-Boot environment.
|
||||
*
|
||||
* This function sets the 'bootcount' value to the given one in the U-Boot environment.
|
||||
*
|
||||
* @param count The new bootcount value to set.
|
||||
*
|
||||
* @return 0 on success, -1 on error.
|
||||
*/
|
||||
int write_bootcount_env(uint count);
|
||||
|
||||
#endif /* BOOTCOUNT_ENV_H */
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef BOOTCOUNT_NVMEM_H
|
||||
#define BOOTCOUNT_NVMEM_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* @brief Read the 'bootcount' value from the NVMEM registers.
|
||||
*
|
||||
* The method performs an internal check to use the correct NVMEM path depending
|
||||
* on the running platform.
|
||||
*
|
||||
* @return The 'bootcount' value as an integer on success, -1 on error.
|
||||
*/
|
||||
int read_bootcount_nvmem();
|
||||
|
||||
/**
|
||||
* @brief Write the 'bootcount' value to the NVMEM registers.
|
||||
*
|
||||
* The method performs an internal check to use the correct NVMEM path depending
|
||||
* on the running platform.
|
||||
*
|
||||
* @param count The new bootcount value to set.
|
||||
*
|
||||
* @return 0 on success, -1 on error.
|
||||
*/
|
||||
int write_bootcount_nvmem(uint count);
|
||||
|
||||
#endif /* BOOTCOUNT_NVMEM_H */
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef FILE_UTILS_H
|
||||
#define FILE_UTILS_H
|
||||
|
||||
/**
|
||||
* @brief Reads data from a binary file into the provided buffer.
|
||||
*
|
||||
* This function opens the specified binary file in read mode and reads up to
|
||||
* 'num_bytes' of data starting at 'offset' into the provided 'buffer'.
|
||||
*
|
||||
* @param path The path to the binary file to read.
|
||||
* @param buffer The buffer to store the read data.
|
||||
* @param offset The offset from where to start reading in the file.
|
||||
* @param num_bytes The number of bytes to read.
|
||||
*
|
||||
* @return 0 on success, -1 on error.
|
||||
*/
|
||||
int read_file(const char* path, char* buffer, long offset, int num_bytes);
|
||||
|
||||
/**
|
||||
* @brief Writes data to a binary file at the specified offset.
|
||||
*
|
||||
* This function opens the specified binary file in read/write mode and writes up to
|
||||
* 'num_bytes' of data from the provided 'data' buffer starting at 'offset' in the file.
|
||||
*
|
||||
* @param path The path to the binary file to write to.
|
||||
* @param data The buffer containing the data to write to the file.
|
||||
* @param offset The offset in the file where to start writing.
|
||||
* @param num_bytes The number of bytes to write.
|
||||
*
|
||||
* @return 0 on success, -1 on error.
|
||||
*/
|
||||
int write_file(const char* path, const char* data, long offset, int num_bytes);
|
||||
|
||||
#endif /* FILE_UTILS_H */
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_UTILS_H
|
||||
#define PLATFORM_UTILS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/* List of all available platforms. */
|
||||
typedef enum {
|
||||
PLATFORM_CC6QP,
|
||||
PLATFORM_CC6SBC,
|
||||
PLATFORM_CC6UL,
|
||||
PLATFORM_CC8MM,
|
||||
PLATFORM_CC8MN,
|
||||
PLATFORM_CC8X,
|
||||
PLATFORM_CC93,
|
||||
PLATFORM_CCMP13,
|
||||
PLATFORM_CCMP15,
|
||||
PLATFORM_UNKNOWN
|
||||
} platform_t;
|
||||
|
||||
/* List of all platform names. */
|
||||
extern char* platform_names[];
|
||||
|
||||
/**
|
||||
* @brief Retrieve the running platform.
|
||||
*
|
||||
* The running platform is determined by reading the corresponding entry from
|
||||
* the device tree.
|
||||
*
|
||||
* @return The running platform, 'PLATFORM_UNKNOWN' if the platform cannot be determined.
|
||||
*/
|
||||
platform_t get_platform();
|
||||
|
||||
#endif /* PLATFORM_UTILS_H */
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "file_utils.h"
|
||||
#include "platform_utils.h"
|
||||
|
||||
#define DT_COMPATIBLE_NODE "/proc/device-tree/compatible"
|
||||
|
||||
char* platform_names[] = {
|
||||
[PLATFORM_CC6QP] = "ccimx6qp",
|
||||
[PLATFORM_CC6SBC] = "ccimx6sbc",
|
||||
[PLATFORM_CC6UL] = "ccimx6ul",
|
||||
[PLATFORM_CC8MM] = "ccimx8mm",
|
||||
[PLATFORM_CC8MN] = "ccimx8mn",
|
||||
[PLATFORM_CC8X] = "ccimx8x",
|
||||
[PLATFORM_CC93] = "ccimx93",
|
||||
[PLATFORM_CCMP13] = "ccmp13",
|
||||
[PLATFORM_CCMP15] = "ccmp15",
|
||||
[PLATFORM_UNKNOWN] = "unknown"
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Checks if the running platform matches the given platform name.
|
||||
*
|
||||
* The running platform is determined by reading the corresponding entry from
|
||||
* the device tree.
|
||||
*
|
||||
* @param platform_name The name of the platform to check.
|
||||
*
|
||||
* @return true if the given platform name matches the running one, false otherwise.
|
||||
*/
|
||||
platform_t get_platform() {
|
||||
FILE *fd;
|
||||
char buffer[100];
|
||||
int bytes_read = 0;
|
||||
platform_t platform = PLATFORM_UNKNOWN;
|
||||
|
||||
fd = fopen(DT_COMPATIBLE_NODE, "r");
|
||||
if (fd == NULL) {
|
||||
fprintf(stderr, "No DT node " DT_COMPATIBLE_NODE "\n");
|
||||
return platform;
|
||||
}
|
||||
|
||||
/* The 'compatible' node specifies multiple strings null-deliniated. The fread() will read
|
||||
* the full file, however, strstr() will consider data up to the first null byte. The strings
|
||||
* comparison must continue until bytes_read number is reached.
|
||||
*/
|
||||
while (feof(fd) == 0 && ferror(fd) == 0 && platform == PLATFORM_UNKNOWN) {
|
||||
if ((bytes_read = fread(buffer, 1, sizeof(buffer)-1, fd)) > 0 ) {
|
||||
buffer[bytes_read] = 0; // null-terminate the full string
|
||||
char *ptr = buffer;
|
||||
while (ptr < buffer + bytes_read) {
|
||||
platform = 0;
|
||||
while (platform < PLATFORM_UNKNOWN) {
|
||||
if (strstr(ptr, platform_names[platform]) != NULL) {
|
||||
goto end;
|
||||
}
|
||||
platform += 1;
|
||||
}
|
||||
ptr += strlen(ptr) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
fclose(fd);
|
||||
return platform;
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#!/bin/sh
|
||||
#===============================================================================
|
||||
#
|
||||
# Copyright (C) 2023 by Digi International Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 as published by
|
||||
# the Free Software Foundation.
|
||||
#
|
||||
#
|
||||
# !Description: Clear bootcount value
|
||||
#
|
||||
#===============================================================================
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Resetting bootcount value... "
|
||||
bootcount -r
|
||||
echo "done."
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
[Unit]
|
||||
Description=Reset bootcount value
|
||||
After=default.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
RemainAfterExit=no
|
||||
ExecStart=/etc/bootcount-init start
|
||||
TimeoutStartSec=0
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
Loading…
Reference in New Issue