diff --git a/meta-digi-arm/recipes-bsp/ubootenv/ubootenv.bb b/meta-digi-arm/recipes-bsp/ubootenv/ubootenv.bb new file mode 100644 index 000000000..961386819 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/ubootenv/ubootenv.bb @@ -0,0 +1,32 @@ +SUMMARY = "Digi's ubootenv tool" +SECTION = "base" +LICENSE = "GPL-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" + +PR = "r0" + +DEPENDS = "libdigi nvram" + +SRC_URI = " \ + file://env_funcs.c \ + file://env_funcs.h \ + file://environment.h \ + file://main_env.c \ + " + +S = "${WORKDIR}" + +GIT_SHA1 = "$(cd ${THISDIR} && git rev-parse --short HEAD)" + +CFLAGS += "-Wall -DLINUX -DGIT_SHA1=\"${GIT_SHA1}\" -I${STAGING_INCDIR}/libdigi" + +do_compile() { + ${CC} ${CFLAGS} -o ubootenv main_env.c env_funcs.c -lnvram -ldigi +} + +do_install() { + mkdir -p ${D}${base_sbindir} + install -m 0755 ubootenv ${D}${base_sbindir}/ +} + +PACKAGE_ARCH = "${MACHINE_ARCH}" diff --git a/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/env_funcs.c b/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/env_funcs.c new file mode 100644 index 000000000..588c9b6c6 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/env_funcs.c @@ -0,0 +1,183 @@ +/* + * env_funcs.c + * + * Copyright (C) 2006-2013 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: Function prototypes for all the flavors of the NVRAM tool + * + */ + +#include +#include + +#include "env_funcs.h" + +/* + * Function: get_var_value + * Return: NULL on failure/ pointer where var value starts on succes + * Description: Checks if the variable name is contained on the string and + * returns a pointer where the variable value starts. + */ +char *get_var_value(const char *from, const char *var_name, char sep) +{ + char *separator; + char *start; + + if (((separator = strchr(from, sep)) != NULL) && + ((start = strstr(from, var_name)) != NULL)) { + if (start < separator) + return (++separator); + } + + return NULL; +} + +/* + * Function: get_var_name + * Return: 1 on success, 0 otherwise + * Description: Retrieves the var name from a var string + */ +int get_var_name(const char *from, char *var_name, char sep) +{ + char *separator; + + if ((separator = strchr(from, sep)) != NULL) { + while (from < separator) + *var_name++ = *from++; + *var_name = 0; + return 1; + } + return 0; +} + +/* + * Function: get_next_env_string + * Return: the string to the next environment variable in UBOOT or + * NULL on failure + * Description: returns the addr of the next string in a data structure + * \0\0\0 + * It does an offset calculation to check for overflow. + */ +char *get_next_env_string(char *from, char *till) +{ + if (*from == 0) + return NULL; + + while (from < till && *from) + from++; + + if (from == till && *from) + return NULL; // Indicate string to long + + return (++from); +} + +/* + * Function: get_var_addr + * Return: the pointer to the address string or NULL if not found. + * Description: Returns the addr of the variable in a data structure + * \0\0\0 + * It does an offset calculation to check for overflow. + */ +char *get_var_addr(char *from, char *till, char *var_name) +{ + char *data = from; + char *var_addr; + char var_name_temp[ENV_MAX_VAR_NAME_LEN + 1]; + + sprintf(var_name_temp, "%s%s", var_name, "="); + + do { + if (*data && data < till) { + if ((var_addr = strstr(data, var_name_temp)) != NULL + && (var_addr == data)) + return var_addr < till ? var_addr : NULL; + } + } while ((data = get_next_env_string(data, till)) != NULL); + + return NULL; +} + +/* + * Function: get_end_mark + * Description: + */ +char *get_end_mark(char *from, char *till) +{ + while (from < till) { + while (*from) + from++; + if (from >= till) + return NULL; + if (*(++from) == 0) + return from; + } + return NULL; +} + +/* + * Function: remove_var + * Return: 1 on success, 0 otherwise + * Description: Remove environment variables + */ +int remove_var(char *from, char *till, char *var_name) +{ + char *var_addr; + char *env_end; + char *var_end; + + /* Check if variable already exists */ + if ((var_addr = get_var_addr(from, till, var_name)) != NULL) { + if ((env_end = get_end_mark(var_addr, till)) != NULL) { + if ((var_end = get_next_env_string(var_addr, till)) != NULL) { + while (var_end <= env_end) + *var_addr++ = *var_end++; + while (var_addr <= env_end) + *var_addr++ = 0; /* Just to have a clean environment :-) */ + return 1; + } + } + } + + return 0; +} + +/* + * Function: add_var + * Return: 1 on success, 0 otherwise + * Description: Add a new environment variable + */ +int add_var(char *from, char *till, char *var_str) +{ + char *var_addr; + char var_name[ENV_MAX_VAR_NAME_LEN]; + + if (get_var_name(var_str, var_name, '=')) { + /* Check if variable already exists */ + if ((var_addr = get_var_addr(from, till, var_name)) != NULL) { + /* @TODO: remove more?? could be that it were there more than once?? */ + if (!remove_var(var_addr, till, var_name)) + return 0; + } + /* Append the variable to the end */ + if ((var_addr = get_end_mark(from, till)) != NULL) { + /* Check if environment is empty. If yes, start from the beginning */ + if (var_addr == (from + 1)) + var_addr--; + while (var_addr < till && *var_str) + *var_addr++ = *var_str++; + *var_addr++ = 0; + *var_addr = 0; + return 1; + } else { + fprintf(stderr, "Unable to find environment end\n"); + } + } + + return 0; +} diff --git a/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/env_funcs.h b/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/env_funcs.h new file mode 100644 index 000000000..051ca0662 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/env_funcs.h @@ -0,0 +1,29 @@ +/* + * env_funcs.h + * + * Copyright (C) 2006-2013 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: Data types and prototypes for parsing the NVRAM environment + * + */ + +#ifndef ENV_FUNCS_H +#define ENV_FUNCS_H + +#define ENV_MAX_VAR_NAME_LEN 50 +#define ENV_MAX_VAR_VAL_LEN 256 + +char *get_var_value(const char *from, const char *var_name, char sep); +char *get_next_env_string(char *from, char *till); +char *get_var_addr(char *from, char *till, char *var_name); +char *get_end_mark(char *from, char *till); +int get_var_name(const char *from, char *var_name, char sep); +int add_var(char *from, char *till, char *var_str); +int remove_var(char *from, char *till, char *var_name); + +#endif diff --git a/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/environment.h b/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/environment.h new file mode 100644 index 000000000..ea60bd84a --- /dev/null +++ b/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/environment.h @@ -0,0 +1,26 @@ +/* + * environment.h + * + * Copyright (C) 2006-2013 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: Data types and definitions for environment in NVRAM + * + */ + +#ifndef __ENV_TOOL_H_ +#define __ENV_TOOL_H_ + +#define VAR_SEP '\0' +#define VAR_ASIGN '=' + +typedef struct { + unsigned long crc; + char data[]; +} env_t; + +#endif diff --git a/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/main_env.c b/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/main_env.c new file mode 100644 index 000000000..1e5a7257f --- /dev/null +++ b/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/main_env.c @@ -0,0 +1,561 @@ +/* + * main_env.c + * + * Copyright (C) 2006-2013 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: main() and user code to manage u-boot and linux environment + * + */ + +#define VERSION "1.8" "-g"GIT_SHA1 + +#include +#include +#include +#include /* MEMERASE */ +#include +#include +#include +#include /* ioctl */ +#include + +#include + +#include /* Nv* */ + +#include "env_funcs.h" +#include "environment.h" + +#define APP_UBOOTENV "ubootenv" +#define APP_PRODINFOENV "prodinfoenv" + +static char *fileadd = NULL; +static char *printlist = NULL; +static char *setstring = NULL; +static char *eraselist = NULL; +static char *cmdname = NULL; +static int dump = 0, clean = 0; +static nv_os_type_e envType; + +static const char *envTypes[] = { + [NVOS_NONE] = "None", + [NVOS_UBOOT] = "U-Boot", + [NVOS_PROD_INFO] = "Product Info", +}; + +static const size_t envDefaultSizes[] = { + [NVOS_NONE] = 0, + [NVOS_UBOOT] = 8192, /* Default value is CONFIG_ENV_SIZE, normally set by U-Boot */ + [NVOS_PROD_INFO] = PROD_INFO_DATA_SIZE, /* Defined in nvram.h but shouldn't be except uboot needs it */ +}; + +static const char* excludeVars[][2] = { + {"ethaddr", "ethaddr1" }, + {"wlanaddr", "ethaddr2" }, + {"eth1addr", "ethaddr3" }, + {"ipaddr", "ip1" }, + {"ipaddr_wlan", "ip2" }, + {"ipaddr1", "ip3" }, + {"netmask", "netmask1" }, + {"netmask_wlan","netmask2" }, + {"netmask1", "netmask3" }, + {"serverip", "server" }, + {"gatewayip", "gateway" }, + {"dnsip", "dns1" }, + {"dnsip2", "dns2" }, + {"dhcp", "dhcp1" }, + {"dhcp_wlan", "dhcp2" }, + {"dhcp1", "dhcp3" }, +}; + +static const char *env_os_type_to_string(void) +{ + return envTypes[envType]; +} + +static int env_onetime_writable(void) +{ + if (NVOS_PROD_INFO == envType) + return 1; + + return 0; +} + +static int env_is_empty(env_t * env, unsigned int envlen) +{ + char *from = (char *)&env->data; + char *till = (char *)&env->data + envlen; + char *end; + + end = get_end_mark(from, till); + /* Check if environment is empty. If yes, start from the beginning */ + if (end == (from + 1)) + return 1; + + return 0; +} + +static int env_have_to_use_nvram(const char *varname) +{ + int j; + + if (envType == NVOS_UBOOT) { + for (j = 0; j < ARRAY_SIZE(excludeVars); j++) { + if (strcmp(varname, excludeVars[j][0]) == 0) + return j; + } + } + return -1; +} + +static void show_usage(void) +{ + fprintf(stdout, "Usage: %s [options]\n" + "%s %s Copyright Digi International Inc.\n\n" + "Prints or updates the %s environment\n" + "\n" + " -d, --dump Prints the values of all the environment\n" + " -p, --print 'var_name_list' Prints the value of the list of variables\n" + " The list has to be simple quoted ('')\n" + " -s, --set 'var_name=var_value' Sets var_value in the variable var_name\n" + " The string has to be simple quoted ('') to allow\n" + " spaces\n" + " -e --erase 'var_name_list' Removes the list of variables (simple quoted)\n" + " -c --clean Removes all variables\n" + " -a --fileadd file_name Adds variables from file_name. To init the full\n" + " environment from file use -c -a simultaneously\n" + " -h --help Displays usage information\n\n", + cmdname, cmdname, VERSION, env_os_type_to_string()); + + if (env_onetime_writable()) { + fprintf(stdout, " WARNING: Variables can only be set the first time\n" + " and become read-only afterwards.\n"); + } +} + +static void show_usage_and_exit(int exit_code) +{ + show_usage(); + exit(exit_code); +} + +static void process_options(int argc, char *argv[]) +{ + int opt_index, opt, optcount = 0; + static const char *short_options = "?hdcp:s:e:a:"; + static const struct option long_options[] = { + {"dump", no_argument, NULL, 'd'}, + {"help", no_argument, NULL, 'h'}, + {"erase", required_argument, NULL, 'e'}, + {"clean", no_argument, NULL, 'c'}, + {"fileadd", required_argument, NULL, 'a'}, + {"print", required_argument, NULL, 'p'}, + {"set", required_argument, NULL, 's'}, + {0, 0, 0, 0}, + }; + + for (opt_index = 0;;) { + + opt = getopt_long(argc, argv, short_options, long_options, &opt_index); + if (opt == EOF) + break; + + switch (opt) { + case 'd': + dump = 1; + break; + case 'p': + printlist = optarg; + break; + case 's': + setstring = optarg; + break; + case 'a': + fileadd = optarg; + break; + case 'e': + eraselist = optarg; + break; + case 'c': + clean = 1; + break; + case 'h': + case '?': + show_usage_and_exit(EXIT_SUCCESS); + break; + } + optcount++; + } + + if (optcount == 0) + show_usage_and_exit(EXIT_FAILURE); + + /* Check options */ + if (dump && (printlist != NULL)) { + fprintf(stderr, "--dump and --print can't be used simultaneously\n"); + show_usage_and_exit(EXIT_FAILURE); + } + if (clean && (eraselist != NULL)) { + fprintf(stderr, "--clean and --erase can't be used simultaneously\n"); + show_usage_and_exit(EXIT_FAILURE); + } +} + +static int env_add_var(const char *varstring, env_t * env, unsigned int envlen) +{ + char *nvramCmd[3] = { "set", "network", NULL }; + char tmpstr[50]; + + char *varval; + int j; + + if (varstring == NULL) + return -EINVAL; + + if (!get_var_name(varstring, tmpstr, VAR_ASIGN)) + return -EINVAL; + + /* Check if is a special variable */ + if ((j = env_have_to_use_nvram(tmpstr)) != -1) { + if ((varval = get_var_value(varstring, excludeVars[j][0], VAR_ASIGN)) != NULL) { + /* Define command to be used by nvram */ + sprintf(tmpstr, "%s=%s", excludeVars[j][1], varval); + nvramCmd[2] = tmpstr; + if (!NvCmdLine(3, (const char **)nvramCmd)) { + return -EINVAL; + } + } + } else { + if (!add_var(env->data, env->data + envlen, (char *)varstring)) { + return -EINVAL; + } + } + + return 0; +} + +static int env_add_vars_from_file(char *filename, env_t * env, unsigned int envlen) +{ + FILE *fp; + char line[ENV_MAX_VAR_NAME_LEN + ENV_MAX_VAR_VAL_LEN + 3]; + int ret = EXIT_SUCCESS; + + if ((fp = fopen(filename, "r")) == NULL) + return -errno; + + while (!feof(fp)) { + if (fgets(line, sizeof(line), fp)) { + /* TODO should we remove comments starting with # ?? */ + /* Remove '\n' */ + if (line[strlen(line) - 1] == '\n') + line[strlen(line) - 1] = 0; + if (env_add_var((const char *)line, env, envlen)) { + fprintf(stderr, "Unable to add environment variable %s\n", + line); + ret = -EINVAL; + goto out; + } + } + } + + out: + if (fp) + fclose(fp); + return ret; +} + +static void env_remove_varlist(const char *varlist, env_t * env, unsigned int envlen) +{ + char *var; + + var = strtok((char *)varlist, " "); + + while (var != NULL) { + if (!remove_var(env->data, env->data + envlen, var)) + fprintf(stderr, "Unable to remove environment variable %s\n", var); + var = strtok(NULL, " "); + } +} + +static int env_validate(env_t * env, int datalen, int verbose) +{ + unsigned long new_crc; + + /* Check stored crc with data */ + new_crc = crc32(0, (const unsigned char *)env->data, datalen); + + if ((unsigned int)env->crc != new_crc) { + if ( verbose ) { + fprintf(stderr, "CRC failure: got 0x%08x expected 0x%08x\n", + (unsigned int)env->crc, (unsigned int)new_crc); + } + return 1; + } + return 0; +} + +static void env_printenv_nvram_vars(char *varname) +{ + struct nv_critical *crit; + nv_param_ip_t *ip_params; + int index; + int oneloop = 0; + + if (NvCriticalGet(&crit)) { + + ip_params = &crit->s.p.xIP; + for (index = 3; index < ARRAY_SIZE(excludeVars); index++) { + if (varname != NULL) { + if ((index = env_have_to_use_nvram(varname)) == -1) + break; + oneloop = 1; + } + + switch (index) { + case 3: + fprintf(stdout, "ipaddr=%s\n", + NvToStringIP(ip_params->axDevice[0].uiIP)); + break; + case 4: + fprintf(stdout, "ipaddr_wlan=%s\n", + NvToStringIP(ip_params->axDevice[1].uiIP)); + break; + case 5: + fprintf(stdout, "ipaddr1=%s\n", + NvToStringIP(crit->s.p.eth1dev.uiIP)); + break; + case 6: + fprintf(stdout, "netmask=%s\n", + NvToStringIP(ip_params->axDevice[0].uiNetMask)); + break; + case 7: + fprintf(stdout, "netmask_wlan=%s\n", + NvToStringIP(ip_params->axDevice[1].uiNetMask)); + break; + case 8: + fprintf(stdout, "netmask1=%s\n", + NvToStringIP(crit->s.p.eth1dev.uiNetMask)); + break; + case 9: + fprintf(stdout, "serverip=%s\n", + NvToStringIP(ip_params->uiIPServer)); + break; + case 10: + fprintf(stdout, "gatewayip=%s\n", + NvToStringIP(ip_params->uiIPGateway)); + break; + case 11: + fprintf(stdout, "dnsip=%s\n", + NvToStringIP(ip_params->auiIPDNS[0])); + break; + case 12: + fprintf(stdout, "dnsip2=%s\n", + NvToStringIP(ip_params->auiIPDNS[1])); + break; + case 13: + fprintf(stdout, "dhcp=%s\n", + (ip_params->axDevice[0].flags.bDHCP ? "on" : "off")); + break; + case 14: + fprintf(stdout, "dhcp_wlan=%s\n", + (ip_params->axDevice[1].flags.bDHCP ? "on" : "off")); + break; + case 15: + fprintf(stdout, "dhcp1=%s\n", + (crit->s.p.eth1dev.flags.bDHCP ? "on" : "off")); + break; + } + if (oneloop) + break; + } + } +} + +static void env_printenv(int dump, char *varlist, env_t * env, unsigned int envlen) +{ + char *var; + char *data = env->data; + char *varinenv; + + if (dump) { + /* print the full environment */ + while (data != NULL && *data) { + fprintf(stdout, "%s\n", data); + data = get_next_env_string(data, env->data + envlen); + } + if (envType == NVOS_UBOOT) + env_printenv_nvram_vars(NULL); + return; + } else { + var = strtok((char *)varlist, " "); + + while (var != NULL) { + + if (envType == NVOS_UBOOT) + env_printenv_nvram_vars(var); + if ((varinenv = + get_var_addr(env->data, env->data + envlen, var)) != NULL) { + fprintf(stdout, "%s\n", varinenv); + } + var = strtok(NULL, " "); + } + } +} + +int main(int argc, char *argv[]) +{ + unsigned int envlen = 0; + env_t *env = NULL; + nv_param_os_cfg_t xCfg; + size_t iSize; + int save_env = 0; + int ret = EXIT_SUCCESS; + int found; + char *cmdstart; + + cmdname = argv[0]; + + cmdname = *argv; + + if ((cmdstart = strrchr(cmdname, '/')) != NULL) { + cmdname = cmdstart + 1; + } + + if (strcmp(cmdname, APP_UBOOTENV) == 0) + envType = NVOS_UBOOT; + else if (strcmp(cmdname, APP_PRODINFOENV) == 0) + envType = NVOS_PROD_INFO; + else { + fprintf(stderr, "This application can be invoked as:\n" + "%s\n%s\n\n", APP_UBOOTENV, APP_PRODINFOENV); + return EXIT_FAILURE; + } + + /* read and process command line */ + process_options(argc, argv); + + if (!NvInit(NVR_AUTO)) { + fprintf(stderr, "Unable to initialize nvram\n"); + return EXIT_FAILURE; + } + + found = NvOSCfgFind(&xCfg, envType); + + if (!found && clean) { + /* Add missing section to nvram if --clean specified */ + + if (envDefaultSizes[envType] != 0 ) { + if (!NvOSCfgAdd(envType, envDefaultSizes[envType])) { + fprintf(stderr, "Unable to add missing %s environment to flash\n", + env_os_type_to_string()); + return EXIT_FAILURE; + } + + /* Try again to find our section */ + found = NvOSCfgFind(&xCfg, envType); + } + } + + if (!found) { + fprintf(stderr, "Unable to detect %s environment in flash\n", + env_os_type_to_string()); + return EXIT_FAILURE; + } + + env = malloc(xCfg.uiSize); + if (NULL == env) { + perror("malloc"); + return EXIT_FAILURE; + } + + memset(env, 0, xCfg.uiSize); + /* Adjust envlen for just for data, crc32 value not included */ + envlen = xCfg.uiSize - sizeof(unsigned long); + + if (!NvOSCfgGet(envType, (void *)env, xCfg.uiSize, &iSize)) { + /* This can't fail; we either found it, created it, or exited. */ + /* But just to be safe... */ + fprintf(stderr, "Unable to get %s environment from flash\n", + env_os_type_to_string()); + ret = EXIT_FAILURE; + goto free_and_ret; + } + + /* Check if env is one-time writable, is valid, and was already written */ + if (env_onetime_writable() && !env_validate(env, envlen, 0) && + !env_is_empty(env, envlen)) { + if ( clean || fileadd || eraselist || setstring ) { + fprintf(stderr, "Environment is one-time writable only\n"); + ret = EXIT_FAILURE; + goto free_and_ret; + } + } + + if (clean) { + memset(env, 0, xCfg.uiSize); + save_env = 1; + } else { + if (env_validate(env, envlen, 1)) { + fprintf(stderr, "Invalid %s environment found\n", + env_os_type_to_string()); + ret = EXIT_FAILURE; + goto free_and_ret; + } + } + + if (fileadd != NULL) { + if (env_add_vars_from_file(fileadd, env, envlen) < 0) { + fprintf(stderr, "Unable to add %s environment from file %s\n", + env_os_type_to_string(), fileadd); + ret = EXIT_FAILURE; + goto free_and_ret; + } + save_env = 1; + } + + if (eraselist != NULL) { + env_remove_varlist(eraselist, env, envlen); + save_env = 1; + } + + if (setstring != NULL) { + if (env_add_var(setstring, env, envlen)) { + fprintf(stderr, "Unable to add environment variable %s\n", setstring); + ret = EXIT_FAILURE; + goto free_and_ret; + } + save_env = 1; + } + + if (dump) { + env_printenv(1, NULL, env, envlen); + } else if (printlist != NULL) { + env_printenv(0, printlist, env, envlen); + } + + if (save_env) { + /* Compute new crc32 value just in case we are going to update the value in flash */ + env->crc = crc32(0, (const unsigned char *)env->data, envlen); + + if (!NvOSCfgSet(envType, env, xCfg.uiSize)) { + fprintf(stderr, "Unable to set %s environment to store in flash\n", + env_os_type_to_string()); + ret = EXIT_FAILURE; + } + if (!NvSave()) { + fprintf(stderr, "Unable to save %s environment in flash\n", + env_os_type_to_string()); + ret = EXIT_FAILURE; + } + } + + free_and_ret: + free(env); + return ret; +} + diff --git a/meta-digi-dbl/recipes-core/packagegroups/packagegroup-dbl-core.bb b/meta-digi-dbl/recipes-core/packagegroups/packagegroup-dbl-core.bb index ecd232126..535ce134c 100644 --- a/meta-digi-dbl/recipes-core/packagegroups/packagegroup-dbl-core.bb +++ b/meta-digi-dbl/recipes-core/packagegroups/packagegroup-dbl-core.bb @@ -39,6 +39,7 @@ RDEPENDS_${PN} = "\ ${VIRTUAL-RUNTIME_login_manager} \ ${VIRTUAL-RUNTIME_init_manager} \ ${VIRTUAL-RUNTIME_update-alternatives} \ + ubootenv \ update-flash \ usbutils \ ${MACHINE_ESSENTIAL_EXTRA_RDEPENDS}" diff --git a/meta-digi-del/recipes-core/packagegroups/packagegroup-del-core.bb b/meta-digi-del/recipes-core/packagegroups/packagegroup-del-core.bb index 02f59c3f3..3fd63a518 100644 --- a/meta-digi-del/recipes-core/packagegroups/packagegroup-del-core.bb +++ b/meta-digi-del/recipes-core/packagegroups/packagegroup-del-core.bb @@ -39,6 +39,7 @@ RDEPENDS_${PN} = "\ ${VIRTUAL-RUNTIME_login_manager} \ ${VIRTUAL-RUNTIME_init_manager} \ ${VIRTUAL-RUNTIME_update-alternatives} \ + ubootenv \ update-flash \ usbutils \ ${MACHINE_ESSENTIAL_EXTRA_RDEPENDS}"