diff options
| -rw-r--r-- | target/linux/rb532-2.6/config | 1 | ||||
| -rw-r--r-- | target/linux/rb532-2.6/image/Makefile | 16 | ||||
| -rwxr-xr-x | target/linux/rb532-2.6/image/gen_image.sh | 17 | ||||
| -rw-r--r-- | target/linux/rb532-2.6/patches/130-custom_partitions.patch | 311 | ||||
| -rw-r--r-- | tools/firmware-utils/Makefile | 1 | ||||
| -rw-r--r-- | tools/firmware-utils/src/ptgen.c | 219 | 
6 files changed, 238 insertions, 327 deletions
diff --git a/target/linux/rb532-2.6/config b/target/linux/rb532-2.6/config index 2d2138261..98474ad71 100644 --- a/target/linux/rb532-2.6/config +++ b/target/linux/rb532-2.6/config @@ -1180,7 +1180,6 @@ CONFIG_CIFS=m  # Partition Types  #  CONFIG_PARTITION_ADVANCED=y -CONFIG_OPENWRT_PARTITION=y  # CONFIG_ACORN_PARTITION is not set  # CONFIG_OSF_PARTITION is not set  # CONFIG_AMIGA_PARTITION is not set diff --git a/target/linux/rb532-2.6/image/Makefile b/target/linux/rb532-2.6/image/Makefile index 490721446..1f3a88ba4 100644 --- a/target/linux/rb532-2.6/image/Makefile +++ b/target/linux/rb532-2.6/image/Makefile @@ -39,9 +39,6 @@ define Image/BuildKernel  	$(CP) $(KDIR)/loader.elf $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-vmlinux  endef -PARTITION1=\x80\x01\x01\x00\x27\x01\x20\x7b\x20\x00\x00\x00\xe0\x1e\x00\x00# 4 MB  (kernel part) -PARTITION2=\x00\x00\x01\x7c\x83\x01\xa0\x64\x00\x1f\x00\x00\x40\x7a\x00\x00# 16 MB (rootfs part) -  define Image/cmdline/jffs2-64k  block2mtd.block2mtd=/dev/cfa2,65536 root=/dev/mtdblock0 rootfstype=jffs2  endef @@ -56,18 +53,7 @@ endef  define Image/Build  	$(STAGING_DIR)/bin/patch-cmdline $(LINUX_DIR)/vmlinux '$(strip $(call Image/cmdline/$(1))) ' -	( \ -		echo -ne OWRT | dd bs=$$$$((0x1be)) conv=sync; \ -		( \ -			echo -ne '$(strip $(PARTITION1))'; \ -			echo -ne '$(strip $(PARTITION2))'; \ -		) | dd bs=$$$$((0x40)) conv=sync; \ -		echo -ne '\x55\xaa'; \ -		dd if=/dev/zero bs=$$$$((0x3e00)) conv=sync count=1; \ -		dd if=$(LINUX_DIR)/vmlinux bs=$$$$((0x3dc000)) conv=sync; \ -		cat $(KDIR)/root.$(1); \ -		echo -ne '\xde\xad\xc0\xde'; \ -	) > $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(1).bin +	./gen_image.sh $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(1).bin 4 $(LINUX_DIR)/vmlinux 16 $(KDIR)/root.$(1)  endef  $(eval $(call BuildImage)) diff --git a/target/linux/rb532-2.6/image/gen_image.sh b/target/linux/rb532-2.6/image/gen_image.sh new file mode 100755 index 000000000..e81285979 --- /dev/null +++ b/target/linux/rb532-2.6/image/gen_image.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +OUTPUT="$1" +KERNELSIZE="$2" +KERNELIMAGE="$3" +ROOTFSSIZE="$4" +ROOTFSIMAGE="$5" + +rm -f "$OUTPUT" + +# create partition table +set `ptgen -o "$OUTPUT" -h 16 -s 32 -t 0x27 -p ${KERNELSIZE}m -t 0x83 -p ${ROOTFSSIZE}m` + +KERNELOFFSET="$(($1 / 512))" +ROOTFSOFFSET="$(($2 / 512))" + +dd if="$KERNELIMAGE" of="$OUTPUT" bs=512 conv=notrunc seek="$KERNELOFFSET" +dd if="$ROOTFSIMAGE" of="$OUTPUT" bs=512 conv=notrunc seek="$ROOTFSOFFSET" diff --git a/target/linux/rb532-2.6/patches/130-custom_partitions.patch b/target/linux/rb532-2.6/patches/130-custom_partitions.patch deleted file mode 100644 index e4b332703..000000000 --- a/target/linux/rb532-2.6/patches/130-custom_partitions.patch +++ /dev/null @@ -1,311 +0,0 @@ -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); -+ diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile index 7b612aeac..e600e9059 100644 --- a/tools/firmware-utils/Makefile +++ b/tools/firmware-utils/Makefile @@ -23,6 +23,7 @@ define Build/Compile  	$(call cc,motorola-bin)  	$(call cc,dgfirmware)  	$(call cc,trx2usr) +	$(call cc,ptgen)  endef  define Build/Install diff --git a/tools/firmware-utils/src/ptgen.c b/tools/firmware-utils/src/ptgen.c new file mode 100644 index 000000000..2d78eae53 --- /dev/null +++ b/tools/firmware-utils/src/ptgen.c @@ -0,0 +1,219 @@ +/*  + * ptgen - partition table generator + * Copyright (C) 2006 by Felix Fietkau <nbd@openwrt.org> + * + * uses parts of afdisk + * Copyright (C) 2002 by David Roetzel <david@roetzel.de> + * + * 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. + *  + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <fcntl.h> + +#if __BYTE_ORDER == __BIG_ENDIAN +#define cpu_to_le16(x) bswap_16(x) +#elif __BYTE_ORDER == __LITTLE_ENDIAN +#define cpu_to_le16(x) (x) +#else +#error unknown endianness! +#endif + +/* Partition table entry */ +struct pte {  +	unsigned char active; +	unsigned char chs_start[3]; +	unsigned char type; +	unsigned char chs_end[3]; +	unsigned int start; +	unsigned int length; +}; + +struct partinfo { +	unsigned long size; +	int type; +}; + +int verbose = 0; +int active = 1; +int heads = -1; +int sectors = -1; +struct partinfo parts[4]; +char *filename = NULL; + + +/*  + * parse the size argument, which is either + * a simple number (K assumed) or + * K, M or G + * + * returns the size in KByte + */ +static long to_kbytes(const char *string) { +	int exp = 0; +	long result; +	char *end; + +	result = strtoul(string, &end, 0); +	switch (tolower(*end)) { +			case 'k' : +			case '\0' : exp = 0; break; +			case 'm' : exp = 1; break; +			case 'g' : exp = 2; break; +			default: return 0; +	} + +	if (*end) +		end++; + +	if (*end) { +		fprintf(stderr, "garbage after end of number\n"); +		return 0; +	} + +	/* result: number + 1024^(exp) */ +	return result * ((2 << ((10 * exp) - 1)) ?: 1); +} + +/* convert the sector number into a CHS value for the partition table */ +static void to_chs(long sect, unsigned char chs[3]) { +	int c,h,s; +	 +	s = (sect % sectors) + 1; +	sect = sect / sectors; +	h = sect % heads; +	sect = sect / heads; +	c = sect; + +	chs[0] = h; +	chs[1] = s | ((c >> 2) & 0xC0); +	chs[2] = c & 0xFF; + +	return; +} + +/* round the sector number up to the next cylinder */ +static inline unsigned long round_to_cyl(long sect) { +	int cyl_size = heads * sectors; + +	return sect + cyl_size - ((sect % cyl_size) ?: cyl_size);  +} + +/* check the partition sizes and write the partition table */ +static int gen_ptable(int nr) +{ +	struct pte pte[4]; +	unsigned long sect = 0;  +	int i, fd, ret = -1, start, len; + +	memset(pte, 0, sizeof(struct pte) * 4); +	for (i = 0; i < nr; i++) { +		if (!parts[i].size) { +			fprintf(stderr, "Invalid size in partition %d!\n", i); +			return -1; +		} +		pte[i].active = ((i + 1) == active) ? 0x80 : 0; +		pte[i].type = parts[i].type; +		pte[i].start = cpu_to_le16(start = sect + sectors); +		sect = round_to_cyl(start + parts[i].size * 2); +		pte[i].length = cpu_to_le16(len = sect - start); +		to_chs(start, pte[i].chs_start); +		to_chs(start + len - 1, pte[i].chs_end); +		if (verbose) +			fprintf(stderr, "Partition %d: start=%ld, end=%ld, size=%ld\n", i, (long) start * 512, ((long) start + (long) len) * 512, (long) len * 512); +		printf("%ld\n", ((long) start * 512)); +	} + +	if ((fd = open(filename, O_WRONLY|O_CREAT, 0644)) < 0) { +		fprintf(stderr, "Can't open output file '%s'\n",filename); +		return -1; +	} + +	lseek(fd, 446, SEEK_SET); +	if (write(fd, pte, sizeof(struct pte) * 4) != sizeof(struct pte) * 4) { +		fprintf(stderr, "write failed.\n"); +		goto fail; +	} +	lseek(fd, 510, SEEK_SET); +	if (write(fd, "\x55\xaa", 2) != 2) { +		fprintf(stderr, "write failed.\n"); +		goto fail; +	} +	 +	ret = 0; +fail: +	close(fd); +	return ret; +} + +static void usage(char *prog) +{ +	fprintf(stderr,	"Usage: %s [-v] -h <heads> -s <sectors> -o <outputfile> [-a 0..4] [[-t <type>] -p <size>...] \n", prog); +	exit(1); +} + +int main (int argc, char **argv) +{ +	char type = 0x83; +	int ch; +	int part = 0; + +	while ((ch = getopt(argc, argv, "h:s:p:a:t:o:v")) != -1) { +		switch (ch) { +		case 'o': +			filename = optarg; +			break; +		case 'v': +			verbose++; +			break; +		case 'h': +			heads = (int) strtoul(optarg, NULL, 0); +			break; +		case 's': +			sectors = (int) strtoul(optarg, NULL, 0); +			break; +		case 'p': +			if (part > 3) { +				fprintf(stderr, "Too many partitions\n"); +				exit(1); +			} +			parts[part].size = to_kbytes(optarg); +			parts[part++].type = type; +			break; +		case 't': +			type = (char) strtoul(optarg, NULL, 16); +			break; +		case 'a': +			active = (int) strtoul(optarg, NULL, 0); +			if ((active < 0) || (active > 4)) +				active = 0; +			break; +		case '?': +		default: +			usage(argv[0]); +		} +	} +	argc -= optind; +	if (argc || (heads <= 0) || (sectors <= 0) || !filename)  +		usage(argv[0]); +	 +	return gen_ptable(part); +}  | 
