mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-03 14:34:27 -05:00 
			
		
		
		
	ramips: RT-N56U support fixes and factory image creation
Signed-off-by: Mikko Hissa <mikko.hissa@werzek.com> SVN-Revision: 41224
This commit is contained in:
		
							parent
							
								
									28277caccb
								
							
						
					
					
						commit
						dc5fe5f73f
					
				@ -5,7 +5,7 @@
 | 
			
		||||
# this, so we make sure to zero checksum and size to be checksummed before
 | 
			
		||||
# that happens, so this needs to run very early during boot.
 | 
			
		||||
 | 
			
		||||
do_wnce2001_checksumming_disable() {
 | 
			
		||||
do_checksumming_disable() {
 | 
			
		||||
	. /lib/ramips.sh
 | 
			
		||||
 | 
			
		||||
	local board=$(ramips_board_name)
 | 
			
		||||
@ -35,9 +35,22 @@ do_wnce2001_checksumming_disable() {
 | 
			
		||||
			echo "Checksum is already zero, nothing to do."
 | 
			
		||||
		fi
 | 
			
		||||
	;;
 | 
			
		||||
	rt-n56u)
 | 
			
		||||
		echo "Board is ASUS RT-N56U, replacing uImage header..."
 | 
			
		||||
		local firmware_mtd=$(find_mtd_part firmware)
 | 
			
		||||
		local rootfs_mtd=$(find_mtd_part rootfs)
 | 
			
		||||
		local rootfs_data_mtd=$(find_mtd_part rootfs_data)
 | 
			
		||||
		local rootfs_len=$(grep \"rootfs\" /proc/mtd | awk -F' ' '{print "0x"$2}')
 | 
			
		||||
		local rootfs_data_len=$(grep \"rootfs_data\" /proc/mtd | awk -F' ' '{print "0x"$2}')
 | 
			
		||||
		local offset=$(echo "$rootfs_len $rootfs_data_len 0x40" | awk -F' ' '{printf "%i",$1-$2-$3}')
 | 
			
		||||
		local signature=$(dd if=$rootfs_mtd skip=$offset bs=1 count=4 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"')
 | 
			
		||||
		if [ "$signature" == "27051956" ]; then
 | 
			
		||||
			dd conv=notrunc if=$rootfs_mtd skip=$offset of=$firmware_mtd bs=1 count=64 2>/dev/null
 | 
			
		||||
		fi
 | 
			
		||||
	;;
 | 
			
		||||
	esac
 | 
			
		||||
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
boot_hook_add preinit_main do_wnce2001_checksumming_disable
 | 
			
		||||
boot_hook_add preinit_main do_checksumming_disable
 | 
			
		||||
@ -43,12 +43,20 @@
 | 
			
		||||
		host-bridge {
 | 
			
		||||
			pci-bridge@1 {
 | 
			
		||||
				status = "okay";
 | 
			
		||||
				wmac@0,0 {
 | 
			
		||||
                                        compatible = "ralink,rt2880-pci", "pciclass060400", "pciclass0604";
 | 
			
		||||
                                        reg = < 0x10000 0 0 0 0 >;
 | 
			
		||||
                                        ralink,eeprom = "rt2x00pci_1_0.eeprom";
 | 
			
		||||
                                };
 | 
			
		||||
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	wmac@10180000 {
 | 
			
		||||
		status = "okay";
 | 
			
		||||
		ralink,2ghz = <0>;
 | 
			
		||||
		ralink,eeprom = "soc_wmac.eeprom";
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	ehci@101c0000 {
 | 
			
		||||
 | 
			
		||||
@ -665,7 +665,13 @@ Image/Build/Profile/DIR645=$(call BuildFirmware/Seama/$(1),$(1),dir-645,DIR-645,
 | 
			
		||||
omniembhpm_mtd_size=16449536
 | 
			
		||||
Image/Build/Profile/OMNIEMBHPM=$(call BuildFirmware/CustomFlash/$(1),$(1),omni-emb-hpm,OMNI-EMB-HPM,$(omniembhpm_mtd_size))
 | 
			
		||||
 | 
			
		||||
Image/Build/Profile/RTN56U=$(call BuildFirmware/Default8M/$(1),$(1),rt-n56u,RTN56U)
 | 
			
		||||
define BuildFirmware/RTN56U/squashfs
 | 
			
		||||
	$(call BuildFirmware/Default8M/$(1),$(1),rt-n56u,RTN56U)
 | 
			
		||||
	-mkrtn56uimg -s $(call sysupname,$(1),rt-n56u)
 | 
			
		||||
	-cp $(call sysupname,$(1),rt-n56u) $(call imgname,$(1),rt-n56u)-factory.bin
 | 
			
		||||
	-mkrtn56uimg -f $(call imgname,$(1),rt-n56u)-factory.bin
 | 
			
		||||
endef
 | 
			
		||||
Image/Build/Profile/RTN56U=$(call BuildFirmware/RTN56U/$(1),$(1),rt-n56u,RTN56U)
 | 
			
		||||
 | 
			
		||||
Image/Build/Profile/TEW691GR=$(call BuildFirmware/UMedia/$(1),$(1),tew-691gr,TEW-691GR,0x026910)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,28 @@
 | 
			
		||||
--- a/drivers/mtd/mtdpart.c	2014-04-27 10:09:21.566294160 +0300
 | 
			
		||||
+++ b/drivers/mtd/mtdpart.c	2014-06-09 11:27:48.952211672 +0300
 | 
			
		||||
@@ -793,8 +793,11 @@
 | 
			
		||||
 {
 | 
			
		||||
 	struct {
 | 
			
		||||
 		__be32 magic;
 | 
			
		||||
-		__be32 pad[2];
 | 
			
		||||
+		__be32 pad0[2];
 | 
			
		||||
 		__be32 size;
 | 
			
		||||
+		__be32 pad1[4];
 | 
			
		||||
+		__be32 name[7];
 | 
			
		||||
+		__be32 kern_size;
 | 
			
		||||
 	} hdr;
 | 
			
		||||
 	size_t len;
 | 
			
		||||
 
 | 
			
		||||
@@ -804,7 +807,11 @@
 | 
			
		||||
 	if (len != sizeof(hdr) || hdr.magic != cpu_to_be32(UBOOT_MAGIC))
 | 
			
		||||
 		return;
 | 
			
		||||
 
 | 
			
		||||
-	len = be32_to_cpu(hdr.size) + 0x40;
 | 
			
		||||
+	if (hdr.kern_size != 0 && hdr.name[0] == 0)
 | 
			
		||||
+		len = be32_to_cpu(hdr.kern_size);
 | 
			
		||||
+	else
 | 
			
		||||
+		len = be32_to_cpu(hdr.size) + 0x40;
 | 
			
		||||
+
 | 
			
		||||
 	__mtd_add_partition(master, "rootfs", part->offset + len,
 | 
			
		||||
 			    part->mtd.size - len, false);
 | 
			
		||||
 }
 | 
			
		||||
@ -67,6 +67,7 @@ define Host/Compile
 | 
			
		||||
	#$(call cc,mkhilinkfw, -lcrypto)
 | 
			
		||||
	$(call cc,mkdcs932, -Wall)
 | 
			
		||||
	$(call cc,mkheader_gemtek,-lz)
 | 
			
		||||
	$(call cc,mkrtn56uimg, -lz)
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Host/Install
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										294
									
								
								tools/firmware-utils/src/mkrtn56uimg.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										294
									
								
								tools/firmware-utils/src/mkrtn56uimg.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,294 @@
 | 
			
		||||
/*
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2014 OpenWrt.org
 | 
			
		||||
 *  Copyright (C) 2014 Mikko Hissa <mikko.hissa@werzek.com>
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 *  under the terms of the GNU General Public License version 2 as published
 | 
			
		||||
 *  by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <sys/mman.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <zlib.h>
 | 
			
		||||
 | 
			
		||||
#define IH_MAGIC	0x27051956
 | 
			
		||||
#define IH_NMLEN	32
 | 
			
		||||
#define IH_PRODLEN	23
 | 
			
		||||
 | 
			
		||||
#define IH_TYPE_INVALID		0
 | 
			
		||||
#define IH_TYPE_STANDALONE	1
 | 
			
		||||
#define IH_TYPE_KERNEL		2
 | 
			
		||||
#define IH_TYPE_RAMDISK		3
 | 
			
		||||
#define IH_TYPE_MULTI		4
 | 
			
		||||
#define IH_TYPE_FIRMWARE	5
 | 
			
		||||
#define IH_TYPE_SCRIPT		6
 | 
			
		||||
#define IH_TYPE_FILESYSTEM	7
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Compression Types
 | 
			
		||||
 */
 | 
			
		||||
#define IH_COMP_NONE		0
 | 
			
		||||
#define IH_COMP_GZIP		1
 | 
			
		||||
#define IH_COMP_BZIP2		2
 | 
			
		||||
#define IH_COMP_LZMA		3
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
	uint8_t major;
 | 
			
		||||
	uint8_t minor;
 | 
			
		||||
} version_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
	version_t	kernel;
 | 
			
		||||
	version_t	fs;
 | 
			
		||||
	uint8_t		productid[IH_PRODLEN];
 | 
			
		||||
	uint8_t  	sub_fs;
 | 
			
		||||
	uint32_t	ih_ksz;
 | 
			
		||||
} asus_t;
 | 
			
		||||
 | 
			
		||||
typedef struct image_header {
 | 
			
		||||
	uint32_t	ih_magic;
 | 
			
		||||
	uint32_t	ih_hcrc;
 | 
			
		||||
	uint32_t	ih_time;
 | 
			
		||||
	uint32_t	ih_size;
 | 
			
		||||
	uint32_t	ih_load;
 | 
			
		||||
	uint32_t	ih_ep;
 | 
			
		||||
	uint32_t	ih_dcrc;
 | 
			
		||||
	uint8_t		ih_os;
 | 
			
		||||
	uint8_t		ih_arch;
 | 
			
		||||
	uint8_t		ih_type;
 | 
			
		||||
	uint8_t		ih_comp;
 | 
			
		||||
	union {
 | 
			
		||||
		uint8_t	ih_name[IH_NMLEN];
 | 
			
		||||
		asus_t	asus;
 | 
			
		||||
	} tail;
 | 
			
		||||
} image_header_t;
 | 
			
		||||
 | 
			
		||||
typedef struct squashfs_sb {
 | 
			
		||||
	uint32_t	s_magic;
 | 
			
		||||
	uint32_t	pad0[9];
 | 
			
		||||
	uint64_t	bytes_used;
 | 
			
		||||
} squashfs_sb_t;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	NONE, FACTORY, SYSUPGRADE,
 | 
			
		||||
} op_mode_t;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
calc_crc(image_header_t *hdr, void *data, uint32_t len)
 | 
			
		||||
{
 | 
			
		||||
	/*
 | 
			
		||||
	 * Calculate payload checksum
 | 
			
		||||
	 */
 | 
			
		||||
	hdr->ih_dcrc = htonl(crc32(0, data, len));
 | 
			
		||||
	hdr->ih_size = htonl(len);
 | 
			
		||||
	/*
 | 
			
		||||
	 * Calculate header checksum
 | 
			
		||||
	 */
 | 
			
		||||
	hdr->ih_hcrc = 0;
 | 
			
		||||
	hdr->ih_hcrc = htonl(crc32(0, hdr, sizeof(image_header_t)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
usage(const char *progname, int status)
 | 
			
		||||
{
 | 
			
		||||
	FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
 | 
			
		||||
	fprintf(stream, "\n"
 | 
			
		||||
			"Options:\n"
 | 
			
		||||
			"  -f <file>		generate a factory flash image <file>\n"
 | 
			
		||||
			"  -s <file>		generate a sysupgrade flash image <file>\n"
 | 
			
		||||
			"  -h			show this screen\n");
 | 
			
		||||
	exit(status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
process_image(char *progname, char *filename, op_mode_t opmode)
 | 
			
		||||
{
 | 
			
		||||
	int 		fd, len;
 | 
			
		||||
	void 		*data, *ptr;
 | 
			
		||||
	char		namebuf[IH_NMLEN];
 | 
			
		||||
	struct 		stat sbuf;
 | 
			
		||||
	uint32_t	checksum, offset_kernel, offset_sqfs, offset_end,
 | 
			
		||||
				offset_sec_header, offset_eb, offset_image_end;
 | 
			
		||||
	squashfs_sb_t *sqs;
 | 
			
		||||
	image_header_t *hdr;
 | 
			
		||||
 | 
			
		||||
	if ((fd = open(filename, O_RDWR, 0666)) < 0) {
 | 
			
		||||
		fprintf (stderr, "%s: Can't open %s: %s\n",
 | 
			
		||||
			progname, filename, strerror(errno));
 | 
			
		||||
		return (EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (fstat(fd, &sbuf) < 0) {
 | 
			
		||||
		fprintf (stderr, "%s: Can't stat %s: %s\n",
 | 
			
		||||
			progname, filename, strerror(errno));
 | 
			
		||||
		return (EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((unsigned)sbuf.st_size < sizeof(image_header_t)) {
 | 
			
		||||
		fprintf (stderr,
 | 
			
		||||
			"%s: Bad size: \"%s\" is no valid image\n",
 | 
			
		||||
			progname, filename);
 | 
			
		||||
		return (EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ptr = (void *)mmap(0, sbuf.st_size,
 | 
			
		||||
				PROT_READ | PROT_WRITE,
 | 
			
		||||
				MAP_SHARED,
 | 
			
		||||
				fd, 0);
 | 
			
		||||
 | 
			
		||||
	if ((caddr_t)ptr == (caddr_t)-1) {
 | 
			
		||||
		fprintf (stderr, "%s: Can't read %s: %s\n",
 | 
			
		||||
			progname, filename, strerror(errno));
 | 
			
		||||
		return (EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	hdr = ptr;
 | 
			
		||||
 | 
			
		||||
	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
 | 
			
		||||
		fprintf (stderr,
 | 
			
		||||
			"%s: Bad Magic Number: \"%s\" is no valid image\n",
 | 
			
		||||
			progname, filename);
 | 
			
		||||
		return (EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (opmode == FACTORY) {
 | 
			
		||||
		strncpy(&namebuf, (char *)&hdr->tail.ih_name, IH_NMLEN);
 | 
			
		||||
		hdr->tail.asus.kernel.major = 0;
 | 
			
		||||
		hdr->tail.asus.kernel.minor = 0;
 | 
			
		||||
		hdr->tail.asus.fs.major = 0;
 | 
			
		||||
		hdr->tail.asus.fs.minor = 0;
 | 
			
		||||
		strncpy((char *)&hdr->tail.asus.productid, "RT-N56U", IH_PRODLEN);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (hdr->tail.asus.ih_ksz == 0)
 | 
			
		||||
		hdr->tail.asus.ih_ksz = htonl(ntohl(hdr->ih_size) + sizeof(image_header_t));
 | 
			
		||||
 | 
			
		||||
	offset_kernel = sizeof(image_header_t);
 | 
			
		||||
	offset_sqfs = ntohl(hdr->tail.asus.ih_ksz);
 | 
			
		||||
	sqs = ptr + offset_sqfs;
 | 
			
		||||
	offset_sec_header = offset_sqfs + sqs->bytes_used;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Reserve space for the second header.
 | 
			
		||||
	 */
 | 
			
		||||
	offset_end = offset_sec_header + sizeof(image_header_t);
 | 
			
		||||
	offset_eb = ((offset_end>>16)+1)<<16;
 | 
			
		||||
 | 
			
		||||
	if (opmode == FACTORY)
 | 
			
		||||
		offset_image_end = offset_eb + 4;
 | 
			
		||||
	else
 | 
			
		||||
		offset_image_end = sbuf.st_size;
 | 
			
		||||
	/*
 | 
			
		||||
	 * Move the second header at the end of the image.
 | 
			
		||||
	 */
 | 
			
		||||
	offset_end = offset_sec_header;
 | 
			
		||||
	offset_sec_header = offset_eb - sizeof(image_header_t);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Remove jffs2 markers between squashfs and eb boundary.
 | 
			
		||||
	 */
 | 
			
		||||
	if (opmode == FACTORY)
 | 
			
		||||
		memset(ptr+offset_end, 0xff ,offset_eb - offset_end);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Grow the image if needed.
 | 
			
		||||
	 */
 | 
			
		||||
	if (offset_image_end > sbuf.st_size) {
 | 
			
		||||
		(void) munmap((void *)ptr, sbuf.st_size);
 | 
			
		||||
		ftruncate(fd, offset_image_end);
 | 
			
		||||
		ptr = (void *)mmap(0, offset_image_end,
 | 
			
		||||
						PROT_READ | PROT_WRITE,
 | 
			
		||||
						MAP_SHARED,
 | 
			
		||||
						fd, 0);
 | 
			
		||||
		/*
 | 
			
		||||
		 * jffs2 marker
 | 
			
		||||
		 */
 | 
			
		||||
		if (opmode == FACTORY) {
 | 
			
		||||
			*(uint8_t *)(ptr+offset_image_end-4) = 0xde;
 | 
			
		||||
			*(uint8_t *)(ptr+offset_image_end-3) = 0xad;
 | 
			
		||||
			*(uint8_t *)(ptr+offset_image_end-2) = 0xc0;
 | 
			
		||||
			*(uint8_t *)(ptr+offset_image_end-1) = 0xde;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Calculate checksums for the second header to be used after flashing.
 | 
			
		||||
	 */
 | 
			
		||||
	if (opmode == FACTORY) {
 | 
			
		||||
		hdr = ptr+offset_sec_header;
 | 
			
		||||
		memcpy(hdr, ptr, sizeof(image_header_t));
 | 
			
		||||
		strncpy((char *)&hdr->tail.ih_name, &namebuf, IH_NMLEN);
 | 
			
		||||
		calc_crc(hdr, ptr+offset_kernel, offset_sqfs - offset_kernel);
 | 
			
		||||
		calc_crc((image_header_t *)ptr, ptr+offset_kernel, offset_image_end - offset_kernel);
 | 
			
		||||
	} else {
 | 
			
		||||
		calc_crc((image_header_t *)ptr, ptr+offset_kernel, offset_sqfs - offset_kernel);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (sbuf.st_size > offset_image_end)
 | 
			
		||||
		(void) munmap((void *)ptr, sbuf.st_size);
 | 
			
		||||
	else
 | 
			
		||||
		(void) munmap((void *)ptr, offset_image_end);
 | 
			
		||||
 | 
			
		||||
	ftruncate(fd, offset_image_end);
 | 
			
		||||
	(void) close (fd);
 | 
			
		||||
 | 
			
		||||
	return EXIT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
	int 		opt;
 | 
			
		||||
	char 		*filename, *progname;
 | 
			
		||||
	op_mode_t	opmode = NONE;
 | 
			
		||||
 | 
			
		||||
	progname = argv[0];
 | 
			
		||||
 | 
			
		||||
	while ((opt = getopt(argc, argv,":s:f:h?")) != -1) {
 | 
			
		||||
		switch (opt) {
 | 
			
		||||
		case 's':
 | 
			
		||||
			opmode = SYSUPGRADE;
 | 
			
		||||
			filename = optarg;
 | 
			
		||||
			break;
 | 
			
		||||
		case 'f':
 | 
			
		||||
			opmode = FACTORY;
 | 
			
		||||
			filename = optarg;
 | 
			
		||||
			break;
 | 
			
		||||
		case 'h':
 | 
			
		||||
			opmode = NONE;
 | 
			
		||||
		default:
 | 
			
		||||
			usage(progname, EXIT_FAILURE);
 | 
			
		||||
			opmode = NONE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(filename == NULL)
 | 
			
		||||
		opmode = NONE;
 | 
			
		||||
 | 
			
		||||
	switch (opmode) {
 | 
			
		||||
	case NONE:
 | 
			
		||||
		usage(progname, EXIT_FAILURE);
 | 
			
		||||
		break;
 | 
			
		||||
	case FACTORY:
 | 
			
		||||
	case SYSUPGRADE:
 | 
			
		||||
		return process_image(progname, filename, opmode);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return EXIT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user