Welcome! Log In Create A New Profile

Advanced

Howto: roll your own kernel (mtd1) for GoFlexHome

Posted by majic79 
Howto: roll your own kernel (mtd1) for GoFlexHome
August 09, 2013 06:33PM
This is a follow up to my earlier thread, showing how you go about building u-boot for the GoFlexHome. This deals with building a compatible kernel for mtd1 - I've been using kernels from the longterm release stream (3.2.49 and 3.4.55 & 56) which almost support the goflex home out of the box.

I'm assuming a debian build environment, codesourcery cross-compile toolchain and that you've already prepared and successfully built u-boot with as detailed in this thread

First, grab a copy of the kernel tarball from http://www.kernel.org - now, I've successfully built for the two latest (at the time of writing) longterm releases and I believe it can be applied to the current stable release as well (YMMV)

tar xf linux-3.4.56.tar.xz
cd linux-3.4.56

Now, you'll have to add a file and tweak a couple more:

create a new file in linux-3.4.56/arch/arm/mach-kirkwood: goflexhome-setup.c

/*
 * arch/arm/mach-kirkwood/goflexhome-setup.c
 *
 * Seagate GoFlex Home Setup
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
#include <linux/mtd/partitions.h>
#include <linux/mv643xx_eth.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/kirkwood.h>
#include <plat/mvsdio.h>
#include "common.h"
#include "mpp.h"

static struct mtd_partition goflexhome_nand_parts[] = {
	{
		.name = "u-boot",
		.offset = 0,
		.size = SZ_1M
	}, {
		.name = "uImage",
		.offset = MTDPART_OFS_NXTBLK,
		.size = SZ_2M + SZ_4M
	}, {
		.name = "root",
		.offset = MTDPART_OFS_NXTBLK,
		.size = MTDPART_SIZ_FULL
	},
};

static struct mv643xx_eth_platform_data goflexhome_ge00_data = {
	.phy_addr	= MV643XX_ETH_PHY_ADDR(0),
};

static struct mv_sata_platform_data goflexhome_sata_data = {
	.n_ports	= 1,
};

static struct gpio_led goflexhome_led_pins[] = {
	{
		.name			= "status:green:health",
		.default_trigger	= "default-on",
		.gpio			= 46,
		.active_low		= 1,
	},
	{
		.name			= "status:orange:misc",
		.default_trigger	= "heartbeat", /* default: none */
		.gpio			= 47,
		.active_low		= 1,
	},
	{
		.name			= "status:white:misc",
		.default_trigger	= "default-on", /* default: none */
		.gpio			= 40,
		.active_low		= 0,
	}
};

static struct gpio_led_platform_data goflexhome_led_data = {
	.leds		= goflexhome_led_pins,
	.num_leds	= ARRAY_SIZE(goflexhome_led_pins),
};

static struct platform_device goflexhome_leds = {
	.name	= "leds-gpio",
	.id	= -1,
	.dev	= {
		.platform_data	= &goflexhome_led_data,
	}
};

static unsigned int goflexhome_mpp_config[] __initdata = {
	MPP29_GPIO,	/* USB Power Enable */
	MPP47_GPIO,	/* LED Orange */
	MPP46_GPIO,	/* LED Green */
	MPP40_GPIO,	/* LED White */
	0
};

static void __init goflexhome_init(void)
{
	/*
	 * Basic setup. Needs to be called early.
	 */
	kirkwood_init();

	/* setup gpio pin select */
	kirkwood_mpp_conf(goflexhome_mpp_config);

	kirkwood_uart0_init();
	kirkwood_nand_init(ARRAY_AND_SIZE(goflexhome_nand_parts), 40);

	if (gpio_request(29, "USB Power Enable") != 0 ||
	    gpio_direction_output(29, 1) != 0)
		printk(KERN_ERR "can't set up GPIO 29 (USB Power Enable)\n");
	kirkwood_ehci_init();
	kirkwood_ge00_init(&goflexhome_ge00_data);
	kirkwood_sata_init(&goflexhome_sata_data);

	platform_device_register(&goflexhome_leds);
}

MACHINE_START(GOFLEXHOME, "Seagate GoFlex Home")
	/* Maintainer: Peter Carmichael <peterjncarm@ovi.com> */
	.atag_offset	= 0x100,
	.init_machine	= goflexhome_init,
	.map_io		= kirkwood_map_io,
	.init_early	= kirkwood_init_early,
	.init_irq	= kirkwood_init_irq,
	.timer		= &kirkwood_timer,
	.restart	= kirkwood_restart,
MACHINE_END

Now (in the same folder) open "Makefile" and insert the following line (probably under a similar line for the DockStar)
obj-$(CONFIG_MACH_GOFLEXHOME)		+= goflexhome-setup.o

Also modify "Kconfig" and add the following lines:
config MACH_GOFLEXHOME
	bool "Seagate GoFlex Home"
	help
	  Say 'Y' here if you want your kernel to support the
	  Seagate GoFlex Home.

now to build it all

codesourcery-arm-2011.03.sh
make clean
make kirkwood_defconfig
make gconfig

When the config menu opens up, set the following options up:
  • System Type->Marvell Kirkwood Implementations->Seagate GoFlex Home (Y)
  • General setup->Initial RAM filesystem and RAM disk (initramfs/initrd) support (Y)
  • Device drivers->Memory Technology Device (MTD) support->Enable UBI (Y)
  • Device drivers->Wireless LAN (N)
  • Device drivers->Legacy (BSD) PTY support (N)
  • Networking support->Wireless (N)
  • Networking support->Networking options->TCP/IP Networking->The IPv6 Protocol (M)
  • File systems->The Extended 4 (ext4) filesystem (Y)
  • File systems->Miscellaneous filesystems->UBIFS file system support (Y)


Save the config and close the menu configurator down

export CONCURRENCY_LEVEL=2
make uImage
Now go and make a cuppa - this takes a little while - my quad core with CONCURRENCY_LEVEL=5 takes around 4 minutes

Finally - pad out the image, it should be around 3MB:

dd if=arch/arm/boot/uImage of=uImage.mtd1.kwb bs=512K conv=sync
5+1 records in
6+0 records out
3145728 bytes (3.1 MB) copied, 0.00670699 s, 469 MB/s

You can tweak the uboot environment at this point, modify the following:
"bootcmd_ubifs=run setdevice_ubi; ubi part root 2048; ubifsmount ubi0:rootfs; run device_bootargs; setenv bootargs ubi.mtd=2,2048 ${bootargs}; nand read 0x800000 0x100000 0x600000; bootm 0x800000\0"
and match the bolded number to the size of the uImage area. You can also use this as the size for writing the chunk to memory when you've transferred it to the device (if going through u-boot environment)

NAS>> setenv ipaddr 192.168.0.254
NAS>> setenv serverip 192.168.0.100
NAS>> tftp 0x800000 uboot.mtd0.kwb
NAS>> nand erase 0x0 0x80000
NAS>> nand write 0x800000 0x0 0x80000
NAS>> tftp 0x1100000 uImage.mtd1.kwb
NAS>> nand erase 0x100000 0x300000
NAS>> nand write 0x800000 0x100000 0x300000

At some point, you may want to use this on a memory stick or other device, to make a package:

time DEB_HOST_ARCH=armel make-kpkg --rootcmd=fakeroot --arch=$ARCH --cross-compile=$CROSS_COMPILE \
--append-to-version=-kirkwood --revision=0.1 --initrd kernel_image modules_image
...
real	3m6.509s
user	7m45.965s
sys	0m26.189s
This will create .deb file in the level above that can be installed to your device (you may need to manually create the uImage/uInitrd afterwards)



Edited 4 time(s). Last edit at 08/15/2013 05:52AM by majic79.
Author:

Your Email:


Subject:


Spam prevention:
Please, enter the code that you see below in the input field. This is for blocking bots that try to post this form automatically. If the code is hard to read, then just try to guess it right. If you enter the wrong code, a new image is created and you get another chance to enter it right.
Message: