Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  bcm63xxpart.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * BCM63XX CFE image tag parser
 *
 * Copyright © 2006-2008  Florian Fainelli <florian@openwrt.org>
 *   Mike Albon <malbon@openwrt.org>
 * Copyright © 2009-2010  Daniel Dickinson <openwrt@cshore.neomailbox.net>
 * Copyright © 2011-2013  Jonas Gorski <jonas.gorski@gmail.com>
 */


#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/bcm963xx_nvram.h>
#include <linux/bcm963xx_tag.h>
#include <linux/crc32.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/of.h>

#ifdef CONFIG_MIPS
#include <asm/bootinfo.h>
#include <asm/fw/cfe/cfe_api.h>
#endif /* CONFIG_MIPS */

#define BCM963XX_CFE_BLOCK_SIZE  SZ_64K /* always at least 64KiB */

#define BCM963XX_CFE_MAGIC_OFFSET 0x4e0
#define BCM963XX_CFE_VERSION_OFFSET 0x570
#define BCM963XX_NVRAM_OFFSET  0x580

/* Ensure strings read from flash structs are null terminated */
#define STR_NULL_TERMINATE(x) \
 do { char *_str = (x); _str[sizeof(x) - 1] = 0; } while (0)

static inline int bcm63xx_detect_cfe(void)
{
 int ret = 0;

#ifdef CONFIG_MIPS
 ret = (fw_arg3 == CFE_EPTSEAL);
#endif /* CONFIG_MIPS */

 return ret;
}

static int bcm63xx_read_nvram(struct mtd_info *master,
 struct bcm963xx_nvram *nvram)
{
 u32 actual_crc, expected_crc;
 size_t retlen;
 int ret;

 /* extract nvram data */
 ret = mtd_read(master, BCM963XX_NVRAM_OFFSET, BCM963XX_NVRAM_V5_SIZE,
   &retlen, (void *)nvram);
 if (ret)
  return ret;

 ret = bcm963xx_nvram_checksum(nvram, &expected_crc, &actual_crc);
 if (ret)
  pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n",
   expected_crc, actual_crc);

 if (!nvram->psi_size)
  nvram->psi_size = BCM963XX_DEFAULT_PSI_SIZE;

 return 0;
}

static const char * const bcm63xx_cfe_part_types[] = {
 "bcm963xx-imagetag",
 NULL,
};

static int bcm63xx_parse_cfe_nor_partitions(struct mtd_info *master,
 const struct mtd_partition **pparts, struct bcm963xx_nvram *nvram)
{
 struct mtd_partition *parts;
 int nrparts = 3, curpart = 0;
 unsigned int cfelen, nvramlen;
 unsigned int cfe_erasesize;
 int i;

 cfe_erasesize = max_t(uint32_t, master->erasesize,
         BCM963XX_CFE_BLOCK_SIZE);

 cfelen = cfe_erasesize;
 nvramlen = nvram->psi_size * SZ_1K;
 nvramlen = roundup(nvramlen, cfe_erasesize);

 parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);
 if (!parts)
  return -ENOMEM;

 /* Start building partition list */
 parts[curpart].name = "CFE";
 parts[curpart].offset = 0;
 parts[curpart].size = cfelen;
 curpart++;

 parts[curpart].name = "nvram";
 parts[curpart].offset = master->size - nvramlen;
 parts[curpart].size = nvramlen;
 curpart++;

 /* Global partition "linux" to make easy firmware upgrade */
 parts[curpart].name = "linux";
 parts[curpart].offset = cfelen;
 parts[curpart].size = master->size - cfelen - nvramlen;
 parts[curpart].types = bcm63xx_cfe_part_types;

 for (i = 0; i < nrparts; i++)
  pr_info("Partition %d is %s offset %llx and length %llx\n", i,
   parts[i].name, parts[i].offset, parts[i].size);

 *pparts = parts;

 return nrparts;
}

static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
     const struct mtd_partition **pparts,
     struct mtd_part_parser_data *data)
{
 struct bcm963xx_nvram *nvram = NULL;
 int ret;

 if (!bcm63xx_detect_cfe())
  return -EINVAL;

 nvram = vzalloc(sizeof(*nvram));
 if (!nvram)
  return -ENOMEM;

 ret = bcm63xx_read_nvram(master, nvram);
 if (ret)
  goto out;

 if (!mtd_type_is_nand(master))
  ret = bcm63xx_parse_cfe_nor_partitions(master, pparts, nvram);
 else
  ret = -EINVAL;

out:
 vfree(nvram);
 return ret;
};

static const struct of_device_id parse_bcm63xx_cfe_match_table[] = {
 { .compatible = "brcm,bcm963xx-cfe-nor-partitions" },
 {},
};
MODULE_DEVICE_TABLE(of, parse_bcm63xx_cfe_match_table);

static struct mtd_part_parser bcm63xx_cfe_parser = {
 .parse_fn = bcm63xx_parse_cfe_partitions,
 .name = "bcm63xxpart",
 .of_match_table = parse_bcm63xx_cfe_match_table,
};
module_mtd_part_parser(bcm63xx_cfe_parser);

MODULE_AUTHOR("Daniel Dickinson ");
MODULE_AUTHOR("Florian Fainelli ");
MODULE_AUTHOR("Mike Albon ");
MODULE_AUTHOR("Jonas Gorski );
MODULE_DESCRIPTION("MTD partitioning for BCM63XX CFE bootloaders");

Messung V0.5
C=95 H=83 G=88

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge