From patchwork Fri Feb 13 19:07:55 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Davey Hutchison X-Patchwork-Id: 439615 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from arrakis.dune.hu (arrakis.dune.hu [78.24.191.176]) (using TLSv1.1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id B8F901401AF for ; Sat, 14 Feb 2015 06:08:19 +1100 (AEDT) Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id EDDAF289B85; Fri, 13 Feb 2015 20:05:32 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on arrakis.dune.hu X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=BAYES_00 autolearn=unavailable version=3.3.2 Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 605EA289B85 for ; Fri, 13 Feb 2015 20:05:22 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 CL_IP_EQ_HELO_IP=-2 (check from: .bluemesh. - helo: .mail-wi0-f173.google. - helo-domain: .google.) FROM/MX_MATCHES_HELO(DOMAIN)=-2; rate: -8.5 Received: from mail-wi0-f173.google.com (mail-wi0-f173.google.com [209.85.212.173]) by arrakis.dune.hu (Postfix) with ESMTPS for ; Fri, 13 Feb 2015 20:05:15 +0100 (CET) Received: by mail-wi0-f173.google.com with SMTP id bs8so14221599wib.0 for ; Fri, 13 Feb 2015 11:07:55 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:date:message-id:subject:from:to :content-type; bh=SKB39YPMiVeISaWkg85OMLaNShc6itxxZB3wD7AwheQ=; b=kC60SsH7hdqpAeDcghN8eY/+eLlHs7kLuI9ZqL00b+V8otH2aoiSylIqogH4HesaAr a00n/bxsLnhohnEDIIc8Z9T3UvnREZYcIk5yctC7TA70FspYrW0ndRycCNBJ86Ao4Bll 0FFKA+jzQ8c68h0ThjrWSbkyEQkZeKTdt1oWwP5g6BaJ8gsHUdxy2hc531LMTzMvL3l9 Lr75dyfMDaAVAl8MupYEF7aWYSkUH4KL+wIZNHpWDk4g/xv7GnPZe1uGaR2SiYnD3BVr rVCxbuo9+6oIzcDw7bAdg7HEQuTc1Zm72eUjvYZ+yQE/W3gijv88cCQNvu5aAoqMY6Jp ZR2Q== X-Gm-Message-State: ALoCoQldSGbO2pOugv00BrZb2yJ3xfxGup/PMdQn6hFUrF7YvDUy9Yt6UaTG3ArNNutrc+et7S7l MIME-Version: 1.0 X-Received: by 10.181.27.168 with SMTP id jh8mr19232224wid.56.1423854475392; Fri, 13 Feb 2015 11:07:55 -0800 (PST) Received: by 10.27.170.73 with HTTP; Fri, 13 Feb 2015 11:07:55 -0800 (PST) X-Originating-IP: [64.128.89.82] Date: Fri, 13 Feb 2015 12:07:55 -0700 Message-ID: From: David Hutchison To: OpenWrt Development List Subject: [OpenWrt-Devel] Initial support for Mikrotik mAP2n and Mikrotik cAP2n X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openwrt-devel-bounces@lists.openwrt.org Sender: "openwrt-devel" I just got the mAP2n and cAP2n to boot from the flash chip into OpenWRT :-) I need some assistance generating an official patch. You have to make some changes to yaffs and I don't know if this is an acceptable approach. This is however the only way I could get RouterBOOT to find the kernel. RouterBOOT seems to require the kernel partition near the bottom of the flash chip ( or it will get stuck while trying to search for the kernel ). When using binwalk and looking at RouterOS, Mikrotik has the bootloader first, rootfs, and the kernel is directly after the squashfs filesystem. Is there a way to dynamically set a partition to start where the previous partition ended? I took the approach of allocating ~6mb at the bottom of the flash for the kernel and the rootfs is between the bootloader and the kernel. This works, however the boot process is kind of slow ( Probably because it has to search the entire 16mb flash chip for the kernel ). If I could raise the position of the kernel, that may speed things up. The goal would be: start of spi flash ==> bootloader, rootfs ( squashfs ), kernel, rootfs_data ( jffs2 ) ==> end of spi flash. I don't know if this would make it boot faster or not, i figured it would be worth a try. Everything in the mAP2n seems to work. The cAP2n is missing the LEDs First you have to patch yaffs, so it can support a NOR flash chip. Here are changes I made: Modifications to yaffs_vfs_glue.c You will also need to update the machtypes header $(kernel)/arch/mips/ath79/machtypes.h + ATH79_MACH_RB_MAP, /* MikroTik RouterBOARD mAP2n */ + ATH79_MACH_RB_CAP, /* Mikrotik cAP */ You will need to update Kconfig $(kernel)/arch/mips/ath79/Kconfig +config ATH79_MACH_RBMAP + bool "Mikrotik RouterBOARD mAP2n support" + select SOC_AR933X + select ATH79_DEV_AP9X_PCI if PCI + select ATH79_DEV_ETH + select ATH79_DEV_GPIO_BUTTONS + select ATH79_DEV_LEDS_GPIO + select ATH79_DEV_M25P80 + select ATH79_DEV_USB + select ATH79_DEV_WMAC + select ATH79_ROUTERBOOT + select RLE_DECOMPRESS Update your Makefile by adding an entry for mach-rbmap.c $(kernel)/arch/mips/ath79/Makefile +obj-$(CONFIG_ATH79_MACH_RBMAP) += mach-rbmap.o ============= After the above patches are applied compile both an initramfs and a nand image. Boot the initramfs, it should expose a kernel and rootfs partition. First erase both kernel and rootfs: mtd erase kernel mtd erase rootfs Then mount the kernel as yaffs2 mkdir -p /mnt/kernel mount -t yaffs2 /dev/mtdblock1 /mnt/kernel Put openwrt-ar71xx-nand-vmlinux.elf inside /mnt/kernel and rename it to kernel mv /tmp/openwrt-ar71xx-nand-vmlinux.elf /mnt/kernel/kernel # This is important that openwrt-ar71xx-nand-vmlinux.elf is named kernel, or the bootloader will not find it. Now it's time to put the rootfs on, you will need the openwrt-ar71xx-nand-rootfs.squashfs file. You *could* make the rootfs yaffs as well, but we really need the extra space... mtd write openwrt-ar71xx-nand-rootfs.squashfs rootfs sync Then reboot. The mAP2n or cAP2n should now boot into OpenWRT from the flash chip. :) Hope this helps! It worked for me :) dmesg [ 0.000000] MyLoader: sysp=11632981, boardp=1960086e, parts=02355bc0 [ 0.000000] bootconsole [early0] enabled [ 0.000000] CPU revision is: 00019374 (MIPS 24Kc) [ 0.000000] SoC: Atheros AR9330 rev 1 [ 0.000000] Clocks: CPU:400.000MHz, DDR:400.000MHz, AHB:200.000MHz, Ref:40.000MHz [ 0.000000] Determined physical RAM map: [ 0.000000] memory: 04000000 @ 00000000 (usable) [ 0.000000] User-defined physical RAM map: [ 0.000000] memory: 04000000 @ 00000000 (usable) [ 0.000000] Initrd not found or empty - disabling initrd [ 0.000000] Zone ranges: [ 0.000000] Normal [mem 0x00000000-0x03ffffff] [ 0.000000] Movable zone start for each node [ 0.000000] Early memory node ranges [ 0.000000] node 0: [mem 0x00000000-0x03ffffff] [ 0.000000] On node 0 totalpages: 16384 [ 0.000000] free_area_init_node: node 0, pgdat 80345cf0, node_mem_map 81000000 [ 0.000000] Normal zone: 128 pages used for memmap [ 0.000000] Normal zone: 0 pages reserved [ 0.000000] Normal zone: 16256 pages, LIFO batch:3 [ 0.000000] Primary instruction cache 64kB, VIPT, 4-way, linesize 32 bytes. [ 0.000000] Primary data cache 32kB, 4-way, VIPT, cache aliases, linesize 32 bytes [ 0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768 [ 0.000000] pcpu-alloc: [0] 0 [ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256 [ 0.000000] Kernel command line: bootimage=1 no-uart no-nand parts=1 boot_part_size=16777216 gpio=956196807 HZ=200000000 mem=64M kmac=4C:5E:0C:CA:26:FF board=mAP ver=3.17 boot=1 mlc=6 rootfstype=squashfs,yaffs,jffs2 noinitrd nohalt [ 0.000000] PID hash table entries: 256 (order: -2, 1024 bytes) [ 0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes) [ 0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes) [ 0.000000] __ex_table already sorted, skipping sort [ 0.000000] Writing ErrCtl register=00000000 [ 0.000000] Readback ErrCtl register=00000000 [ 0.000000] Memory: 61180k/65536k available (2321k kernel code, 4356k reserved, 647k data, 228k init, 0k highmem) [ 0.000000] SLUB: Genslabs=9, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1 [ 0.000000] NR_IRQS:51 [ 0.080000] Calibrating delay loop... 265.42 BogoMIPS (lpj=1327104) [ 0.080000] pid_max: default: 32768 minimum: 301 [ 0.080000] Mount-cache hash table entries: 512 [ 0.090000] NET: Registered protocol family 16 [ 0.100000] MIPS: machine is Mikrotik mAP2n [ 0.550000] bio: create slab at 0 [ 0.560000] Switching to clocksource MIPS [ 0.570000] NET: Registered protocol family 2 [ 0.570000] TCP established hash table entries: 2048 (order: 2, 16384 bytes) [ 0.570000] TCP bind hash table entries: 2048 (order: 1, 8192 bytes) [ 0.580000] TCP: Hash tables configured (established 2048 bind 2048) [ 0.580000] TCP: reno registered [ 0.580000] UDP hash table entries: 256 (order: 0, 4096 bytes) [ 0.590000] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes) [ 0.600000] NET: Registered protocol family 1 [ 0.600000] PCI: CLS 0 bytes, default 32 [ 0.620000] squashfs: version 4.0 (2009/01/31) Phillip Lougher [ 0.620000] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc. [ 0.640000] yaffs built Feb 12 2015 23:52:32 Installing. [ 0.640000] [ 0.640000] [ 0.640000] [ 0.640000] [ 0.640000] YAFFS-WARNING CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED selected. [ 0.640000] [ 0.640000] [ 0.640000] [ 0.640000] msgmni has been set to 119 [ 0.640000] io scheduler noop registered [ 0.640000] io scheduler deadline registered (default) [ 0.650000] Serial: 8250/16550 driver, 1 ports, IRQ sharing disabled [ 0.650000] ar933x-uart: ttyATH0 at MMIO 0x18020000 (irq = 11) is a AR933X UART [ 0.660000] console [ttyATH0] enabled, bootconsole disabled [ 0.670000] ath79-spi ath79-spi: master is unqueued, this is deprecated [ 0.680000] m25p80 spi0.0: found w25q128, expected m25p80 [ 0.690000] m25p80 spi0.0: w25q128 (16384 Kbytes) [ 0.690000] Creating 3 MTD partitions on "spi0.0": [ 0.700000] 0x000000000000-0x000000020000 : "RouterBoot" [ 0.700000] 0x000000a00000-0x000001000000 : "kernel" [ 0.710000] 0x000000020000-0x000000a00000 : "rootfs" [ 0.710000] mtd: partition "rootfs" set to be root filesystem [ 0.720000] mtd: partition "rootfs_data" created automatically, ofs=570000, len=490000 [ 0.730000] 0x000000570000-0x000000a00000 : "rootfs_data" [ 0.750000] libphy: ag71xx_mdio: probed [ 1.300000] ag71xx ag71xx.0: connected to PHY at ag71xx-mdio.1:04 [uid=004dd041, driver=Generic PHY] [ 1.310000] eth0: Atheros AG71xx at 0xb9000000, irq 4, mode:MII [ 1.870000] ag71xx-mdio.1: Found an AR7240/AR9330 built-in switch [ 2.900000] eth1: Atheros AG71xx at 0xba000000, irq 5, mode:GMII [ 2.900000] TCP: cubic registered [ 2.900000] NET: Registered protocol family 17 [ 2.910000] 8021q: 802.1Q VLAN Support v1.8 [ 2.920000] VFS: Mounted root (squashfs filesystem) readonly on device 31:2. [ 2.930000] Freeing unused kernel memory: 228k freed [ 11.260000] jffs2: notice: (460) jffs2_build_xattr_subsystem: complete building xattr subsystem, 3 of xdatum (1 unchecked, 2 orphan) and 10 of xref (0 dead, 7 orphan) found. [ 13.100000] Loading modules backported from Linux version master-2014-11-04-0-gf3660a2 [ 13.100000] Backport generated by backports.git backports-20141023-2-g4ff890b [ 13.380000] cfg80211: Calling CRDA to update world regulatory domain [ 13.380000] cfg80211: World regulatory domain updated: [ 13.390000] cfg80211: DFS Master region: unset [ 13.390000] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time) [ 13.400000] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A) [ 13.410000] cfg80211: (2457000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A) [ 13.420000] cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (N/A, 2000 mBm), (N/A) [ 13.420000] cfg80211: (5170000 KHz - 5250000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A) [ 13.430000] cfg80211: (5250000 KHz - 5330000 KHz @ 80000 KHz, 160000 KHz AUTO), (N/A, 2000 mBm), (0 s) [ 13.440000] cfg80211: (5490000 KHz - 5730000 KHz @ 160000 KHz), (N/A, 2000 mBm), (0 s) [ 13.450000] cfg80211: (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A) [ 13.460000] cfg80211: (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 0 mBm), (N/A) [ 14.160000] nls_base: exports duplicate symbol load_nls (owned by kernel) [ 14.510000] SCSI subsystem initialized [ 14.810000] usbcore: registered new interface driver usbfs [ 14.810000] usbcore: registered new interface driver hub [ 14.890000] usbcore: registered new device driver usb [ 15.920000] ath: EEPROM regdomain: 0x0 [ 15.920000] ath: EEPROM indicates default country code should be used [ 15.920000] ath: doing EEPROM country->regdmn map search [ 15.920000] ath: country maps to regdmn code: 0x3a [ 15.920000] ath: Country alpha2 being used: US [ 15.920000] ath: Regpair used: 0x3a [ 15.940000] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht' [ 15.940000] Registered led device: ath9k-phy0 [ 15.940000] ieee80211 phy0: Atheros AR9330 Rev:1 mem=0xb8100000, irq=2 [ 16.160000] cfg80211: Calling CRDA for country: US [ 16.160000] cfg80211: Regulatory domain changed to country: US [ 16.170000] cfg80211: DFS Master region: FCC [ 16.170000] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time) [ 16.180000] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A, 3000 mBm), (N/A) [ 16.190000] cfg80211: (5170000 KHz - 5250000 KHz @ 80000 KHz, 160000 KHz AUTO), (N/A, 1700 mBm), (N/A) [ 16.200000] cfg80211: (5250000 KHz - 5330000 KHz @ 80000 KHz, 160000 KHz AUTO), (N/A, 2300 mBm), (0 s) [ 16.210000] cfg80211: (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 3000 mBm), (N/A) [ 16.220000] cfg80211: (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 4000 mBm), (N/A) [ 16.830000] PPP generic driver version 2.4.2 [ 17.050000] tun: Universal TUN/TAP device driver, 1.6 [ 17.060000] tun: (C) 1999-2004 Max Krasnyansky [ 17.220000] ip_tables: (C) 2000-2006 Netfilter Core Team [ 18.020000] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver [ 18.030000] ehci-platform ehci-platform: Generic Platform EHCI Controller [ 18.040000] ehci-platform ehci-platform: new USB bus registered, assigned bus number 1 [ 18.080000] ehci-platform ehci-platform: irq 3, io mem 0x1b000000 [ 18.110000] ehci-platform ehci-platform: USB 2.0 started, EHCI 1.00 [ 18.110000] hub 1-0:1.0: USB hub found [ 18.120000] hub 1-0:1.0: 1 port detected [ 18.320000] nf_conntrack version 0.5.0 (959 buckets, 3836 max) [ 20.200000] xt_time: kernel timezone is -0000 [ 20.990000] Hooked IMQ after mangle on PREROUTING [ 20.990000] Hooked IMQ after nat on POSTROUTING [ 21.000000] IMQ driver loaded successfully. (numdevs = 2, numqueues = 1) [ 21.550000] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver [ 21.890000] Registered led device: rb:user [ 21.890000] Registered led device: rb:led:eth1 [ 21.890000] Registered led device: rb:led:eth2 [ 21.890000] Registered led device: rb:led:poe [ 21.890000] Registered led device: rb:led:wlan [ 21.890000] Registered led device: rb:led5 [ 22.220000] usbcore: registered new interface driver cdc_acm [ 22.230000] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters [ 22.510000] usbcore: registered new interface driver usbserial [ 22.520000] usbcore: registered new interface driver usbserial_generic [ 22.530000] usbserial: USB Serial support registered for generic [ 22.760000] Initializing USB Mass Storage driver... [ 22.770000] usbcore: registered new interface driver usb-storage [ 22.770000] USB Mass Storage support registered. [ 22.930000] usbcore: registered new interface driver cdc_wdm [ 22.990000] usbcore: registered new interface driver cdc_ether [ 23.160000] hso: drivers/net/usb/hso.c: Option Wireless [ 23.160000] usbcore: registered new interface driver hso [ 23.310000] usbcore: registered new interface driver qmi_wwan [ 23.760000] usbcore: registered new interface driver rndis_host [ 23.920000] usbcore: registered new interface driver sierra_net [ 24.070000] usbcore: registered new interface driver option [ 24.070000] usbserial: USB Serial support registered for GSM modem (1-port) [ 24.260000] usbcore: registered new interface driver sierra [ 24.260000] usbserial: USB Serial support registered for Sierra USB modem [ 24.800000] u32 classifier [ 24.800000] Performance counters on [ 24.800000] input device check on [ 24.810000] Actions configured [ 24.970000] Mirror/redirect action on [ 32.730000] eth1: link up (1000Mbps/Full duplex) /proc/mtd cat /proc/mtd dev: size erasesize name mtd0: 00020000 00010000 "RouterBoot" mtd1: 00600000 00010000 "kernel" mtd2: 009e0000 00010000 "rootfs" mtd3: 00490000 00010000 "rootfs_data" /proc/cpuinfo cat /proc/cpuinfo system type : Atheros AR9330 rev 1 machine : Mikrotik mAP2n processor : 0 cpu model : MIPS 24Kc V7.4 BogoMIPS : 265.42 wait instruction : yes microsecond timers : yes tlb_entries : 16 extra interrupt vector : yes hardware watchpoint : yes, count: 4, address/irw mask: [0x0000, 0x0008, 0x01a0, 0x0088] ASEs implemented : mips16 shadow register sets : 1 kscratch registers : 0 core : 0 VCED exceptions : not available VCEI exceptions : not available Note: The LEDs are not done for the cAP2n but have confirmed that it does boot. --- $(kernel)/fs/yaffs2/yaffs_vfs_glue.c +++ $(kernel)/fs/yaffs2/yaffs_vfs_glue.c @@ -171,6 +171,7 @@ #include "yaffs_mtdif.h" #include "yaffs_mtdif1.h" #include "yaffs_mtdif2.h" +#include "yaffs_mtdif2_nor.h" unsigned int yaffs_trace_mask = YAFFS_TRACE_BAD_BLOCKS | YAFFS_TRACE_ALWAYS; unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS; @@ -2913,7 +2914,8 @@ return NULL; } /* Check it's NAND */ - if (mtd->type != MTD_NANDFLASH) { + if (mtd->type != MTD_NANDFLASH && mtd->type != MTD_NORFLASH) { T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs: MTD device is not NAND it's type %d\n"), mtd->type)); @@ -2954,6 +2956,11 @@ yaffs_version = 2; } + if (mtd->type == MTD_NORFLASH) { + yaffs_version = 2; + } + /* Added NCB 26/5/2006 for completeness */ if (yaffs_version == 2 && !options.inband_tags && WRITE_SIZE(mtd) == 512) { T(YAFFS_TRACE_ALWAYS, @@ -2963,7 +2970,18 @@ #endif - if (yaffs_version == 2) { + if (yaffs_version == 2 && mtd->type == MTD_NORFLASH) { + /* Check for version 2 style functions */ + if (!mtd->_erase || + !mtd->_read || + !mtd->_write) { + T(YAFFS_TRACE_ALWAYS, + ("yaffs: MTD device does not support required " + "functions\n"));; + return NULL; + } + } else if (yaffs_version == 2) { /* Check for version 2 style functions */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) if (!mtd->_erase || @@ -3137,7 +3155,26 @@ param->empty_lost_n_found = options.empty_lost_and_found; /* ... and the functions. */ - if (yaffs_version == 2) { + if (yaffs_version == 2 && mtd->type == MTD_NORFLASH) { + param->write_chunk_tags_fn = + normtd2_WriteChunkWithTagsToNAND; + param->read_chunk_tags_fn = + normtd2_ReadChunkWithTagsFromNAND; + param->bad_block_fn = normtd2_MarkNANDBlockBad; + param->query_block_fn = normtd2_QueryNANDBlock; + param->erase_fn = normtd_EraseBlockInNAND; + param->initialise_flash_fn = normtd_InitialiseNAND; + + param->is_yaffs2 = 1; + param->total_bytes_per_chunk = 1024; + param->chunks_per_block = mtd->erasesize / (param->total_bytes_per_chunk + 16); + nBlocks = (uint32_t) mtd->size / mtd->erasesize; + yaffs_dev_to_lc(dev)->spareBuffer = YMALLOC(16); + + param->start_block = 0; + param->end_block = nBlocks - 1; + } else if (yaffs_version == 2) { param->write_chunk_tags_fn = nandmtd2_WriteChunkWithTagsToNAND; param->read_chunk_tags_fn = @@ -3173,8 +3210,11 @@ param->is_yaffs2 = 0; } /* ... and common functions */ - param->erase_fn = nandmtd_EraseBlockInNAND; - param->initialise_flash_fn = nandmtd_InitialiseNAND; + if(mtd->type != MTD_NORFLASH) { + param->erase_fn = nandmtd_EraseBlockInNAND; + param->initialise_flash_fn = nandmtd_InitialiseNAND; + } yaffs_dev_to_lc(dev)->putSuperFunc = yaffs_MTDPutSuper; added file yaffs_mtdif2_nor.c --- /dev/null +++ $(kernel)/fs/yaffs2/yaffs_mtdif2_nor.c @@ -0,0 +1,172 @@ +#include "yportenv.h" +#include "yaffs_trace.h" + + +#include "yaffs_mtdif2_nor.h" + +#include "linux/mtd/mtd.h" +#include "linux/types.h" +#include "linux/time.h" + +#include "yaffs_packedtags2.h" +#include "yaffs_linux.h" + +#define NOR_OOB_SIZE 16 +#define NOR_PAGE_SIZE(x) (x + NOR_OOB_SIZE) + +static inline loff_t chunkToAddr(yaffs_dev_t *dev, struct mtd_info *mtd, + int chunkInNAND) +{ + return mtd->erasesize * (chunkInNAND / dev->param.chunks_per_block) + + NOR_PAGE_SIZE(dev->param.total_bytes_per_chunk) + * (chunkInNAND % dev->param.chunks_per_block); +} + +int normtd2_WriteChunkWithTagsToNAND(yaffs_dev_t *dev, int chunkInNAND, + const __u8 * data, + const yaffs_ext_tags *tags) +{ + struct mtd_info *mtd = yaffs_dev_to_mtd(dev); + size_t dummy; + int retval = 0; + + loff_t addr = chunkToAddr(dev, mtd, chunkInNAND); + + yaffs_PackedTags2 pt; + + T(YAFFS_TRACE_MTD, + (TSTR + ("normtd2_WriteChunkWithTagsToNAND chunk %d addr 0x%08llx data %p tags %p" + TENDSTR), chunkInNAND, addr, data, tags)); + + if (data && tags) { + // Calculates ECC, but doesn't write it, return NOR_OOB_SIZE + yaffs_PackTags2(&pt, tags, NOR_OOB_SIZE); + + retval = mtd->_write(mtd, addr, dev->param.total_bytes_per_chunk, + &dummy, data); + if (retval == 0) { + retval = mtd->_write(mtd, addr + dev->param.total_bytes_per_chunk, + NOR_OOB_SIZE, &dummy, (__u8 *) &pt); + } + } else + BUG(); /* both tags and data should always be present */ + + if (retval == 0) + return YAFFS_OK; + else + return YAFFS_FAIL; +} + +int normtd2_ReadChunkWithTagsFromNAND(yaffs_dev_t *dev, int chunkInNAND, + __u8 * data, yaffs_ext_tags *tags) +{ + struct mtd_info *mtd = yaffs_dev_to_mtd(dev); + size_t dummy; + int retval = 0; + + loff_t addr = chunkToAddr(dev, mtd, chunkInNAND); + + yaffs_PackedTags2 pt; + + T(YAFFS_TRACE_MTD, + (TSTR + ("normtd2_ReadChunkWithTagsFromNAND chunk %d addr 0x%08llx data %p tags %p" + TENDSTR), chunkInNAND, addr, data, tags)); + + if (data) { + retval = mtd->_read(mtd, addr, dev->param.total_bytes_per_chunk, &dummy, data); + } + if (tags && retval == 0) { + retval = mtd->_read(mtd, addr + dev->param.total_bytes_per_chunk, + NOR_OOB_SIZE, &dummy, yaffs_dev_to_lc(dev)->spareBuffer); + memcpy(&pt, yaffs_dev_to_lc(dev)->spareBuffer, sizeof(pt)); + } + + if (tags) + yaffs_unpack_tags2(tags, &pt, 1); // Ignore ecc + + if (retval == -EUCLEAN) { + if (tags) tags->ecc_result = YAFFS_ECC_RESULT_FIXED; + retval = 0; + } + + if (tags && retval == -EBADMSG && tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR) + tags->ecc_result = YAFFS_ECC_RESULT_UNFIXED; + + if (retval == 0) + return YAFFS_OK; + else + return YAFFS_FAIL; +} + +int normtd2_MarkNANDBlockBad(struct yaffs_dev_s *dev, int blockNo) +{ + return YAFFS_OK; +} + +int normtd2_QueryNANDBlock(struct yaffs_dev_s *dev, int blockNo, + yaffs_block_state_t *state, int *sequenceNumber) +{ + int retval = 0; + yaffs_ext_tags t; + + T(YAFFS_TRACE_MTD, + (TSTR("normtd2_QueryNANDBlock %d" TENDSTR), blockNo)); + + retval = normtd2_ReadChunkWithTagsFromNAND(dev, + blockNo * + dev->param.total_bytes_per_chunk, NULL, + &t); + + if (t.chunk_used) { + *sequenceNumber = t.seq_number; + *state = YAFFS_BLOCK_STATE_NEEDS_SCANNING; + } else { + *sequenceNumber = 0; + *state = YAFFS_BLOCK_STATE_EMPTY; + } + + T(YAFFS_TRACE_MTD, + (TSTR("block is bad seq %d state %d" TENDSTR), *sequenceNumber, + *state)); + + if (retval == 0) + return YAFFS_OK; + else + return YAFFS_FAIL; +} + +int normtd_EraseBlockInNAND(yaffs_dev_t *dev, int blockNumber) +{ + struct mtd_info *mtd = yaffs_dev_to_mtd(dev); + __u32 addr = ((loff_t) blockNumber) * mtd->erasesize; + struct erase_info ei; + int retval = 0; + + ei.mtd = mtd; + ei.addr = addr; + ei.len = mtd->erasesize; + ei.time = 1000; + ei.retries = 2; + ei.callback = NULL; + ei.priv = (u_long) dev; + + /* Todo finish off the ei if required */ + + T(YAFFS_TRACE_MTD, + (TSTR("normtd_EraseBlockInNAND block %d, addr 0x%08x, len %lld" + TENDSTR), blockNumber, addr, ei.len)); + + retval = mtd->_erase(mtd, &ei); + + if (retval == 0) + return YAFFS_OK; + else + return YAFFS_FAIL; +} + +int normtd_InitialiseNAND(yaffs_dev_t *dev) +{ + return YAFFS_OK; +} Modified yaffs Makefile --- $(kernel)/fs/yaffs2/Makefile +++ Makefile @@ -7,7 +7,7 @@ yaffs-y := yaffs_ecc.o yaffs_vfs_glue.o yaffs_guts.o yaffs_checkptrw.o yaffs-y += yaffs_packedtags1.o yaffs_packedtags2.o yaffs_nand.o yaffs-y += yaffs_tagscompat.o yaffs_tagsvalidity.o -yaffs-y += yaffs_mtdif.o yaffs_mtdif1.o yaffs_mtdif2.o +yaffs-y += yaffs_mtdif.o yaffs_mtdif1.o yaffs_mtdif2.o yaffs_mtdif2_nor.o yaffs-y += yaffs_nameval.o yaffs-y += yaffs_allocator.o yaffs-y += yaffs_yaffs1.o This will now give you the ability to mount the SPI NOR Flash chip ( w25q128 ) as yaffs2. Now you will need the architecture code --- /dev/null +++ $(kernel)/arch/mips/ath79/mach-rbmap.c @@ -0,0 +1,154 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "common.h" +#include "dev-ap9x-pci.h" +#include "dev-eth.h" +#include "dev-spi.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "dev-wmac.h" +#include "machtypes.h" +#include "routerboot.h" + +#define RB_ROUTERBOOT_OFFSET 0x0000 +#define RB_ROUTERBOOT_SIZE 0xe000 +#define RB_HARD_CFG_OFFSET 0xe000 +#define RB_HARD_CFG_SIZE 0x1000 + +#define RB_ART_SIZE 0x10000 + +static struct gpio_led rb_map_leds_gpio[] __initdata = { + { + .name = "rb:user", + .gpio = 21, + .active_low = 1, + }, { + .name = "rb:led:eth1", + .gpio = 18, + .active_low = 1, + }, { + .name = "rb:led:eth2", + .gpio = 20, + .active_low = 1, + }, { + .name = "rb:led:poe", + .gpio = 19, + .active_low = 1, + .default_state = LEDS_GPIO_DEFSTATE_ON + }, { + .name = "rb:led:wlan", + .gpio = 22, + .active_low = 1, + }, { + .name = "rb:led5", + .gpio = 23, + .active_low = 1, + } +}; + +static struct mtd_partition rbmap_spi_partitions[] = { + { + .name = "RouterBoot", + .offset = 0, + .size = 128 * 1024, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "kernel", + .offset = 0xa00000, + .size = MTDPART_SIZ_FULL + }, + { + .name = "rootfs", + .offset = 128 * 1024, + .size = 0x9e0000 + } +}; + +static struct flash_platform_data rbmap_spi_flash_data = { + .parts = rbmap_spi_partitions, + .nr_parts = ARRAY_SIZE(rbmap_spi_partitions), +}; + +static void __init rbmap_wlan_init(void) +{ + u8 *hard_cfg = (u8 *) KSEG1ADDR(0x1f000000 + RB_HARD_CFG_OFFSET); + u16 tag_len; + u8 *tag; + char *art_buf; + u8 wlan_mac[ETH_ALEN]; + int err; + + err = routerboot_find_tag(hard_cfg, RB_HARD_CFG_SIZE, RB_ID_WLAN_DATA, + &tag, &tag_len); + if (err) { + pr_err("no calibration data found\n"); + return; + } + + art_buf = kmalloc(RB_ART_SIZE, GFP_KERNEL); + if (art_buf == NULL) { + pr_err("no memory for calibration data\n"); + return; + } + + err = rle_decode((char *) tag, tag_len, art_buf, RB_ART_SIZE, + NULL, NULL); + if (err) { + pr_err("unable to decode calibration data\n"); + goto free; + } + + ath79_init_mac(wlan_mac, ath79_mac_base, 11); + ath79_register_wmac(art_buf + 0x1000, wlan_mac); + +free: + kfree(art_buf); +} + +static void __init rbmap_setup(void) +{ + ath79_register_leds_gpio(-1, ARRAY_SIZE(rb_map_leds_gpio), + rb_map_leds_gpio); + + ath79_register_m25p80(&rbmap_spi_flash_data); + ath79_register_mdio(0, 0x0); + + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); + ath79_register_eth(0); + + ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); + ath79_register_eth(1); + + ath79_register_usb(); + + rbmap_wlan_init(); + + gpio_request_one(26, + GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_CHANGEABLE, + "rb:poe"); +} + +MIPS_MACHINE(ATH79_MACH_RB_MAP, "mAP", "Mikrotik mAP2n", + rbmap_setup); + +MIPS_MACHINE(ATH79_MACH_RB_CAP, "cm2n", "Mikrotik cAP2n", + rbmap_setup);