diff --git a/fs/partition/Kconfig b/fs/partition/Kconfig index 8221ba40a6..1eaf914ea2 100644 --- a/fs/partition/Kconfig +++ b/fs/partition/Kconfig @@ -19,6 +19,18 @@ config GPT_PARTITION bool "GPT support" default n +config TXTABLE_PARTITION + bool "TXTABLE support" + default n + +if TXTABLE_PARTITION + +config TXTABLE_PARTITION_MAX_NUM + int "Max num of TXTABLE partition" + default 16 + +endif + endmenu endif diff --git a/fs/partition/Make.defs b/fs/partition/Make.defs index 738cf2d00e..7bd0a98184 100644 --- a/fs/partition/Make.defs +++ b/fs/partition/Make.defs @@ -36,6 +36,10 @@ ifeq ($(CONFIG_GPT_PARTITION),y) CSRCS += fs_gpt.c endif +ifeq ($(CONFIG_TXTABLE_PARTITION),y) +CSRCS += fs_txtable.c +endif + # Include partition build support DEPPATH += --dep-path partition diff --git a/fs/partition/fs_partition.c b/fs/partition/fs_partition.c index 4707584058..a183ffda92 100644 --- a/fs/partition/fs_partition.c +++ b/fs/partition/fs_partition.c @@ -74,6 +74,10 @@ static const partition_parser_t g_parser[] = parse_mbr_partition, #endif +#ifdef CONFIG_TXTABLE_PARTITION + parse_txtable_partition, +#endif + NULL }; diff --git a/fs/partition/fs_txtable.c b/fs/partition/fs_txtable.c new file mode 100644 index 0000000000..026d4c8a4f --- /dev/null +++ b/fs/partition/fs_txtable.c @@ -0,0 +1,171 @@ +/**************************************************************************** + * fs/partition/fs_txtable.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 +#include +#include + +#include + +#include "partition.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define TXTABLE_MAGIC "TXTABLE0" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: parse_txtable_partition + * + * Description: + * parse the TXTABLE partition txtable. + * + * Input Parameters: + * state - The partition txtable state + * handler - The function to be called for each found partition + * arg - A caller provided value to return with the handler + * + * Returned Value: + * A negated errno value is returned on a failure; Otherwise success + * + ****************************************************************************/ + +int parse_txtable_partition(FAR struct partition_state_s *state, + partition_handler_t handler, + FAR void *arg) +{ + FAR char *save_ptr; + FAR char *token; + FAR struct partition_s *part; + size_t blkpererase; + size_t lasteraseblk; + int ret = OK; + int i; + int j; + + /* Allocate memory for table of parsed and raw */ + + part = kmm_malloc(CONFIG_TXTABLE_PARTITION_MAX_NUM * + sizeof(struct partition_s) + + state->erasesize); + if (part == NULL) + { + return -ENOMEM; + } + + memset(part, 0, CONFIG_TXTABLE_PARTITION_MAX_NUM * + sizeof(struct partition_s)); + + token = (FAR char *)(part + CONFIG_TXTABLE_PARTITION_MAX_NUM); + + /* TXTABLE locate in the last erase block */ + + blkpererase = state->erasesize / state->blocksize; + lasteraseblk = state->nblocks - blkpererase; + + ret = read_partition_block(state, token, lasteraseblk, blkpererase); + if (ret < 0) + { + goto out; + } + + /* Parsing data of partition table */ + + token = strtok_r(token, "\n", &save_ptr); + if (strncmp(token, TXTABLE_MAGIC, strlen(TXTABLE_MAGIC)) != 0) + { + ret = -EFTYPE; + goto out; + } + + for (i = 0; i < CONFIG_TXTABLE_PARTITION_MAX_NUM; i++) + { + token = strtok_r(NULL, "\n", &save_ptr); + if (token == NULL || !isalnum(token[0])) + { + break; + } + + ret = sscanf(token, "%s %zx %zx", + part[i].name, + &part[i].nblocks, + &part[i].firstblock); + if (ret < 0) + { + goto out; + } + + part[i].index = i; + part[i].firstblock /= state->blocksize; + part[i].nblocks /= state->blocksize; + part[i].blocksize = state->blocksize; + } + + for (j = 0; j < i; j++) + { + if (!part[j].firstblock && j > 0) + { + part[j].firstblock = part[j - 1].firstblock + + part[j - 1].nblocks; + } + + if (!part[j].nblocks) + { + if (j + 1 < i) + { + if (part[j + 1].firstblock) + { + part[j].nblocks = part[j + 1].firstblock - + part[j].firstblock; + } + } + else + { + part[j].nblocks = state->nblocks - part[j].firstblock - + blkpererase; + } + } + + /* Reserved for txtable */ + + if (j + 1 == i && + part[j].firstblock + part[j].nblocks > lasteraseblk) + { + part[j].nblocks = lasteraseblk - part[j].firstblock; + } + + /* Notify the caller */ + + handler(&part[j], arg); + } + +out: + kmm_free(part); + return ret; +} diff --git a/fs/partition/partition.h b/fs/partition/partition.h index 8c79b2cfb4..4958501078 100644 --- a/fs/partition/partition.h +++ b/fs/partition/partition.h @@ -70,6 +70,12 @@ int parse_mbr_partition(FAR struct partition_state_s *state, FAR void *arg); #endif +#ifdef CONFIG_TXTABLE_PARTITION +int parse_txtable_partition(FAR struct partition_state_s *state, + partition_handler_t handler, + FAR void *arg); +#endif + #endif /* CONFIG_DISABLE_MOUNTPOINT */ #endif /* __FS_PARTITION_PARTITION_H */