diff options
Diffstat (limited to 'target/linux/rb532-2.6/patches/130-custom_partitions.patch')
-rw-r--r-- | target/linux/rb532-2.6/patches/130-custom_partitions.patch | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/target/linux/rb532-2.6/patches/130-custom_partitions.patch b/target/linux/rb532-2.6/patches/130-custom_partitions.patch new file mode 100644 index 0000000..e4b3327 --- /dev/null +++ b/target/linux/rb532-2.6/patches/130-custom_partitions.patch @@ -0,0 +1,311 @@ +diff -urN linux.old/fs/partitions/check.c linux.dev/fs/partitions/check.c +--- linux.old/fs/partitions/check.c 2006-05-31 02:31:44.000000000 +0200 ++++ linux.dev/fs/partitions/check.c 2006-06-15 01:27:17.000000000 +0200 +@@ -29,6 +29,7 @@ + #include "ldm.h" + #include "mac.h" + #include "msdos.h" ++#include "openwrt.h" + #include "osf.h" + #include "sgi.h" + #include "sun.h" +@@ -48,6 +49,9 @@ + * Probe partition formats with tables at disk address 0 + * that also have an ADFS boot block at 0xdc0. + */ ++#ifdef CONFIG_OPENWRT_PARTITION ++ openwrt_partition, ++#endif + #ifdef CONFIG_ACORN_PARTITION_ICS + adfspart_check_ICS, + #endif +diff -urN linux.old/fs/partitions/Kconfig linux.dev/fs/partitions/Kconfig +--- linux.old/fs/partitions/Kconfig 2006-05-31 02:31:44.000000000 +0200 ++++ linux.dev/fs/partitions/Kconfig 2006-06-15 01:27:17.000000000 +0200 +@@ -14,6 +14,12 @@ + + If unsure, say N. + ++config OPENWRT_PARTITION ++ bool "OpenWrt partition support" if PARTITION_ADVANCED ++ default y ++ help ++ Support the custom OpenWrt partition map ++ + config ACORN_PARTITION + bool "Acorn partition support" if PARTITION_ADVANCED + default y if ARCH_ACORN +diff -urN linux.old/fs/partitions/Makefile linux.dev/fs/partitions/Makefile +--- linux.old/fs/partitions/Makefile 2006-05-31 02:31:44.000000000 +0200 ++++ linux.dev/fs/partitions/Makefile 2006-06-15 01:27:17.000000000 +0200 +@@ -11,6 +11,7 @@ + obj-$(CONFIG_MAC_PARTITION) += mac.o + obj-$(CONFIG_LDM_PARTITION) += ldm.o + obj-$(CONFIG_MSDOS_PARTITION) += msdos.o ++obj-$(CONFIG_OPENWRT_PARTITION) += openwrt.o + obj-$(CONFIG_OSF_PARTITION) += osf.o + obj-$(CONFIG_SGI_PARTITION) += sgi.o + obj-$(CONFIG_SUN_PARTITION) += sun.o +diff -urN linux.old/fs/partitions/openwrt.c linux.dev/fs/partitions/openwrt.c +--- linux.old/fs/partitions/openwrt.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/fs/partitions/openwrt.c 2006-06-15 01:27:17.000000000 +0200 +@@ -0,0 +1,249 @@ ++/* ++ * fs/partitions/openwrt.c ++ * ++ * Code extracted from drivers/block/genhd.c ++ * and fs/partitions/msdos.c ++ * ++ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> ++ * Copyright (C) 1991-1998 Linus Torvalds ++ * ++ * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug ++ * in the early extended-partition checks and added DM partitions ++ * ++ * Support for DiskManager v6.0x added by Mark Lord, ++ * with information provided by OnTrack. This now works for linux fdisk ++ * and LILO, as well as loadlin and bootln. Note that disks other than ++ * /dev/hda *must* have a "DOS" type 0x51 partition in the first slot (hda1). ++ * ++ * More flexible handling of extended partitions - aeb, 950831 ++ * ++ * Check partition table on IDE disks for common CHS translations ++ * ++ * Re-organised Feb 1998 Russell King ++ */ ++ ++#include <linux/config.h> ++ ++#include "check.h" ++#include "openwrt.h" ++ ++/* ++ * Many architectures don't like unaligned accesses, while ++ * the nr_sects and start_sect partition table entries are ++ * at a 2 (mod 4) address. ++ */ ++#include <asm/unaligned.h> ++ ++#define SYS_IND(p) (get_unaligned(&p->sys_ind)) ++#define NR_SECTS(p) ({ __typeof__(p->nr_sects) __a = \ ++ get_unaligned(&p->nr_sects); \ ++ le32_to_cpu(__a); \ ++ }) ++ ++#define START_SECT(p) ({ __typeof__(p->start_sect) __a = \ ++ get_unaligned(&p->start_sect); \ ++ le32_to_cpu(__a); \ ++ }) ++ ++static inline int is_extended_partition(struct partition *p) ++{ ++ return (SYS_IND(p) == DOS_EXTENDED_PARTITION || ++ SYS_IND(p) == WIN98_EXTENDED_PARTITION || ++ SYS_IND(p) == LINUX_EXTENDED_PARTITION); ++} ++ ++#define MSDOS_LABEL_MAGIC1 0x55 ++#define MSDOS_LABEL_MAGIC2 0xAA ++ ++static inline int ++msdos_magic_present(unsigned char *p) ++{ ++ return (p[0] == MSDOS_LABEL_MAGIC1 && p[1] == MSDOS_LABEL_MAGIC2); ++} ++ ++static inline int ++openwrt_magic_present(unsigned char *p) ++{ ++ return (p[0] == 'O' && ++ p[1] == 'W' && ++ p[2] == 'R' && ++ p[3] == 'T'); ++} ++ ++/* ++ * Create devices for each logical partition in an extended partition. ++ * The logical partitions form a linked list, with each entry being ++ * a partition table with two entries. The first entry ++ * is the real data partition (with a start relative to the partition ++ * table start). The second is a pointer to the next logical partition ++ * (with a start relative to the entire extended partition). ++ * We do not create a Linux partition for the partition tables, but ++ * only for the actual data partitions. ++ */ ++ ++static void ++parse_extended(struct parsed_partitions *state, struct block_device *bdev, ++ u32 first_sector, u32 first_size) ++{ ++ struct partition *p; ++ Sector sect; ++ unsigned char *data; ++ u32 this_sector, this_size; ++ int sector_size = bdev_hardsect_size(bdev) / 512; ++ int loopct = 0; /* number of links followed ++ without finding a data partition */ ++ int i; ++ ++ this_sector = first_sector; ++ this_size = first_size; ++ ++ while (1) { ++ if (++loopct > 100) ++ return; ++ if (state->next == state->limit) ++ return; ++ data = read_dev_sector(bdev, this_sector, §); ++ if (!data) ++ return; ++ ++ if (!msdos_magic_present(data + 510)) ++ goto done; ++ ++ p = (struct partition *) (data + 0x1be); ++ ++ /* ++ * Usually, the first entry is the real data partition, ++ * the 2nd entry is the next extended partition, or empty, ++ * and the 3rd and 4th entries are unused. ++ * However, DRDOS sometimes has the extended partition as ++ * the first entry (when the data partition is empty), ++ * and OS/2 seems to use all four entries. ++ */ ++ ++ /* ++ * First process the data partition(s) ++ */ ++ for (i=0; i<4; i++, p++) { ++ u32 offs, size, next; ++ if (!NR_SECTS(p) || is_extended_partition(p)) ++ continue; ++ ++ /* Check the 3rd and 4th entries - ++ these sometimes contain random garbage */ ++ offs = START_SECT(p)*sector_size; ++ size = NR_SECTS(p)*sector_size; ++ next = this_sector + offs; ++ if (i >= 2) { ++ if (offs + size > this_size) ++ continue; ++ if (next < first_sector) ++ continue; ++ if (next + size > first_sector + first_size) ++ continue; ++ } ++ ++ put_partition(state, state->next, next, size); ++ if (SYS_IND(p) == LINUX_RAID_PARTITION) ++ state->parts[state->next].flags = 1; ++ loopct = 0; ++ if (++state->next == state->limit) ++ goto done; ++ } ++ /* ++ * Next, process the (first) extended partition, if present. ++ * (So far, there seems to be no reason to make ++ * parse_extended() recursive and allow a tree ++ * of extended partitions.) ++ * It should be a link to the next logical partition. ++ */ ++ p -= 4; ++ for (i=0; i<4; i++, p++) ++ if (NR_SECTS(p) && is_extended_partition(p)) ++ break; ++ if (i == 4) ++ goto done; /* nothing left to do */ ++ ++ this_sector = first_sector + START_SECT(p) * sector_size; ++ this_size = NR_SECTS(p) * sector_size; ++ put_dev_sector(sect); ++ } ++done: ++ put_dev_sector(sect); ++} ++ ++ ++int openwrt_partition(struct parsed_partitions *state, struct block_device *bdev) ++{ ++ int sector_size = bdev_hardsect_size(bdev) / 512; ++ Sector sect; ++ unsigned char *data; ++ struct partition *p; ++ int slot; ++ u32 last_block = 0; ++ u32 size = 0; ++ int firstfree = 5; ++ ++ data = read_dev_sector(bdev, 0, §); ++ if (!data) ++ return -1; ++ if (!openwrt_magic_present(data)) { ++ printk("No OpenWrt partition table detected\n"); ++ put_dev_sector(sect); ++ return 0; ++ } ++ ++ /* ++ * Now that the 55aa signature is present, this is probably ++ * either the boot sector of a FAT filesystem or a DOS-type ++ * partition table. Reject this in case the boot indicator ++ * is not 0 or 0x80. ++ */ ++ p = (struct partition *) (data + 0x1be); ++ for (slot = 1; slot <= 4; slot++, p++) { ++ if (p->boot_ind != 0 && p->boot_ind != 0x80) { ++ put_dev_sector(sect); ++ return 0; ++ } ++ } ++ ++ p = (struct partition *) (data + 0x1be); ++ ++ /* ++ * Look for partitions in two passes: ++ * First find the primary and DOS-type extended partitions. ++ */ ++ ++ state->next = 6; ++ for (slot = 1 ; slot <= 4 ; slot++, p++) { ++ u32 start = START_SECT(p)*sector_size; ++ size = NR_SECTS(p)*sector_size; ++ if (!size) { ++ if (firstfree > slot) ++ firstfree = slot; ++ ++ continue; ++ } ++ if (is_extended_partition(p)) { ++ /* prevent someone doing mkfs or mkswap on an ++ extended partition, but leave room for LILO */ ++ last_block = start + size; ++ put_partition(state, slot, start, size == 1 ? 1 : 2); ++ printk(" <"); ++ parse_extended(state, bdev, start, size); ++ printk(" >"); ++ continue; ++ } ++ if ((start + size) > get_capacity(bdev->bd_disk)) ++ size = get_capacity(bdev->bd_disk) - start; ++ last_block = start + size; ++ put_partition(state, slot, start, size); ++ } ++ if (last_block + 1024 < (size = get_capacity(bdev->bd_disk))) ++ put_partition(state, firstfree, last_block, size - last_block); ++ ++ printk("\n"); ++ ++ put_dev_sector(sect); ++ return 1; ++} ++ +diff -urN linux.old/fs/partitions/openwrt.h linux.dev/fs/partitions/openwrt.h +--- linux.old/fs/partitions/openwrt.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/fs/partitions/openwrt.h 2006-06-15 01:27:17.000000000 +0200 +@@ -0,0 +1,6 @@ ++/* ++ * fs/partitions/openwrt.h ++ */ ++ ++int openwrt_partition(struct parsed_partitions *state, struct block_device *bdev); ++ |