diff options
Diffstat (limited to 'common/partitions')
-rw-r--r-- | common/partitions/Kconfig | 13 | ||||
-rw-r--r-- | common/partitions/Makefile | 1 | ||||
-rw-r--r-- | common/partitions/dos.c | 88 | ||||
-rw-r--r-- | common/partitions/parser.h | 35 |
4 files changed, 137 insertions, 0 deletions
diff --git a/common/partitions/Kconfig b/common/partitions/Kconfig new file mode 100644 index 0000000000..3f81c2f922 --- /dev/null +++ b/common/partitions/Kconfig @@ -0,0 +1,13 @@ +config PARTITION_DISK + depends on PARTITION + bool "DISK partition support" + help + Add support for handling common partition tables on all kind of disk + like devices (harddisks, CF cards, SD cards and so on) + +config PARTITION_DISK_DOS + depends on PARTITION_DISK + default y + bool "DOS partition support" + help + Add support to handle partitions in DOS style. diff --git a/common/partitions/Makefile b/common/partitions/Makefile new file mode 100644 index 0000000000..0a5c70d16a --- /dev/null +++ b/common/partitions/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_PARTITION_DISK_DOS) += dos.o diff --git a/common/partitions/dos.c b/common/partitions/dos.c new file mode 100644 index 0000000000..4f147f72da --- /dev/null +++ b/common/partitions/dos.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2009...2011 Juergen Beisert, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <common.h> +#include <disks.h> +#include <init.h> +#include <asm/unaligned.h> + +#include "parser.h" + +/** + * Guess the size of the disk, based on the partition table entries + * @param dev device to create partitions for + * @param table partition table + * @return sector count + */ +static int disk_guess_size(struct device_d *dev, struct partition_entry *table) +{ + uint64_t size = 0; + int i; + + for (i = 0; i < 4; i++) { + if (table[i].partition_start != 0) { + size += get_unaligned_le32(&table[i].partition_start) - size; + size += get_unaligned_le32(&table[i].partition_size); + } + } + + return (int)size; +} + +/** + * Check if a DOS like partition describes this block device + * @param blk Block device to register to + * @param pd Where to store the partition information + * + * It seems at least on ARM this routine canot use temp. stack space for the + * sector. So, keep the malloc/free. + */ +static void dos_partition(void *buf, struct block_device *blk, + struct partition_desc *pd) +{ + struct partition_entry *table; + struct partition pentry; + uint8_t *buffer = buf; + int i; + + table = (struct partition_entry *)&buffer[446]; + + /* valid for x86 BIOS based disks only */ + if (IS_ENABLED(CONFIG_DISK_BIOS) && blk->num_blocks == 0) + blk->num_blocks = disk_guess_size(blk->dev, table); + + for (i = 0; i < 4; i++) { + pentry.first_sec = get_unaligned_le32(&table[i].partition_start); + pentry.size = get_unaligned_le32(&table[i].partition_size); + + if (pentry.first_sec != 0) { + pd->parts[pd->used_entries].first_sec = pentry.first_sec; + pd->parts[pd->used_entries].size = pentry.size; + pd->used_entries++; + } else { + dev_dbg(blk->dev, "Skipping empty partition %d\n", i); + } + } +} + +struct partition_parser dos = { + .parse = dos_partition, + .type = filetype_mbr, +}; + +static int dos_partition_init(void) +{ + return partition_parser_register(&dos); +} +postconsole_initcall(dos_partition_init); diff --git a/common/partitions/parser.h b/common/partitions/parser.h new file mode 100644 index 0000000000..13506c00a0 --- /dev/null +++ b/common/partitions/parser.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 only + */ + +#ifndef __PARTITIONS_PARSER_H__ +#define __PARTITIONS_PARSER_H__ + +#include <block.h> +#include <filetype.h> +#include <linux/list.h> + +#define MAX_PARTITION 8 + +struct partition { + uint64_t first_sec; + uint64_t size; +}; + +struct partition_desc { + int used_entries; + struct partition parts[MAX_PARTITION]; +}; + +struct partition_parser { + void (*parse)(void *buf, struct block_device *blk, struct partition_desc *pd); + enum filetype type; + + struct list_head list; +}; + +int partition_parser_register(struct partition_parser *p); + +#endif /* __PARTITIONS_PARSER_H__ */ |