[U-Boot-Users] [PATCH] add OpenGear CM4008 board support

Hi All,
Attached is a patch that adds support to u-boot for the OpenGear CM4008 8 port console manager board. It is built around the KS8695P CPU, with 8 serial ports, 16MB RAM, and 8MB NOR flash.
This patch was originally generated against u-boot 1.1.1.
Regards Greg
diff -Naur --exclude=CVS u-boot-1.1.1/board/cm4008/cm4008.c u-boot/board/cm4008/cm4008.c --- u-boot-1.1.1/board/cm4008/cm4008.c 1970-01-01 10:00:00.000000000 +1000 +++ u-boot/board/cm4008/cm4008.c 2005-05-04 22:47:00.021931928 +1000 @@ -0,0 +1,101 @@ +/* + * (C) Copyright 2005 + * Greg Ungerer, OpenGear Inc, greg.ungerer@opengear.com + * + * (C) Copyright 2002 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger mgroeger@sysgo.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/arch/platform.h> + +/* ------------------------------------------------------------------------- */ + +#define ks8695_read(a) *((volatile unsigned int *) (KS8695_IO_BASE+(a))) +#define ks8695_write(a,b) *((volatile unsigned int *) (KS8695_IO_BASE+(a))) = (b) + +/* ------------------------------------------------------------------------- */ + + +/* + * Miscelaneous platform dependent initialisations + */ +int env_flash_cmdline (void) +{ + unsigned char *sp = (unsigned char *) 0x0201c020; + unsigned char *ep; + int len; + + /* Check if "erase" push button is depressed */ + if ((ks8695_read(KS8695_GPIO_DATA) & 0x8) == 0) { + printf("### Entering network recovery mode...\n"); + setenv("bootargs", "console=ttyAM0,115200 mem=16M initrd=0x400000,6M root=/dev/ram0"); + setenv("bootcmd", "bootp 0x400000; gofsk 0x400000"); + setenv("bootdelay", "2"); + return 0; + } + + /* Check for flash based kernel boot args to use as default */ + for (ep = sp, len = 0; ((len < 1024) && (*ep != 0)); ep++, len++) + ; + + if ((len > 0) && (len <1024)) + setenv("bootargs", sp); + + return 0; +} + +int board_late_init (void) +{ + return 0; +} + + +int board_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + /* arch number of CM4008 */ + gd->bd->bi_arch_number = 624; + + /* adress of boot parameters */ + gd->bd->bi_boot_params = 0x00000100; + + /* power down all but port 0 on the switch */ + ks8695_write(KS8695_SWITCH_LPPM12, 0x00000005); + ks8695_write(KS8695_SWITCH_LPPM34, 0x00050005); + + return 0; +} + +int dram_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + + return (0); +} diff -Naur --exclude=CVS u-boot-1.1.1/board/cm4008/config.mk u-boot/board/cm4008/config.mk --- u-boot-1.1.1/board/cm4008/config.mk 1970-01-01 10:00:00.000000000 +1000 +++ u-boot/board/cm4008/config.mk 2005-01-11 00:56:42.000000000 +1000 @@ -0,0 +1 @@ +TEXT_BASE = 0x00f00000 diff -Naur --exclude=CVS u-boot-1.1.1/board/cm4008/flash.c u-boot/board/cm4008/flash.c --- u-boot-1.1.1/board/cm4008/flash.c 1970-01-01 10:00:00.000000000 +1000 +++ u-boot/board/cm4008/flash.c 2005-01-17 00:55:13.000000000 +1000 @@ -0,0 +1,409 @@ +/* + * (C) Copyright 2005 + * Greg Ungerer, OpenGear Inc, greg.ungerer@opengear.com + * + * (C) Copyright 2001 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net + * + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <linux/byteorder/swab.h> + + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +#define mb() __asm__ __volatile__ ("" : : : "memory") + +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size (unsigned char * addr, flash_info_t * info); +static int write_data (flash_info_t * info, ulong dest, unsigned char data); +static void flash_get_offsets (ulong base, flash_info_t * info); +void inline spin_wheel (void); + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + int i; + ulong size = 0; + + for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { + switch (i) { + case 0: + flash_get_size ((unsigned char *) PHYS_FLASH_1, &flash_info[i]); + flash_get_offsets (PHYS_FLASH_1, &flash_info[i]); + break; + case 1: + /* ignore for now */ + flash_info[i].flash_id = FLASH_UNKNOWN; + break; + default: + panic ("configured too many flash banks!\n"); + break; + } + size += flash_info[i].size; + } + + /* Protect monitor and environment sectors + */ + flash_protect (FLAG_PROTECT_SET, + CFG_FLASH_BASE, + CFG_FLASH_BASE + _bss_start - _armboot_start, + &flash_info[0]); + + return size; +} + +/*----------------------------------------------------------------------- + */ +static void flash_get_offsets (ulong base, flash_info_t * info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) + return; + + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { + for (i = 0; i < info->sector_count; i++) { + info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE); + info->protect[i] = 0; + } + } +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t * info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_INTEL: + printf ("INTEL "); + break; + default: + printf ("Unknown Vendor "); + break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_28F128J3A: + printf ("28F128J3A\n"); + break; + default: + printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i = 0; i < info->sector_count; ++i) { + if ((i % 5) == 0) + printf ("\n "); + printf (" %08lX%s", + info->start[i], info->protect[i] ? " (RO)" : " "); + } + printf ("\n"); + return; +} + +/* + * The following code cannot be run from FLASH! + */ +static ulong flash_get_size (unsigned char * addr, flash_info_t * info) +{ + volatile unsigned char value; + + /* Write auto select command: read Manufacturer ID */ + addr[0x5555] = 0xAA; + addr[0x2AAA] = 0x55; + addr[0x5555] = 0x90; + + mb (); + value = addr[0]; + + switch (value) { + + case (unsigned char)INTEL_MANUFACT: + info->flash_id = FLASH_MAN_INTEL; + break; + + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + addr[0] = 0xFF; /* restore read mode */ + return (0); /* no or unknown flash */ + } + + mb (); + value = addr[2]; /* device ID */ + + switch (value) { + + case (unsigned char)INTEL_ID_28F640J3A: + info->flash_id += FLASH_28F640J3A; + info->sector_count = 64; + info->size = 0x00800000; + break; /* => 8 MB */ + + case (unsigned char)INTEL_ID_28F128J3A: + info->flash_id += FLASH_28F128J3A; + info->sector_count = 128; + info->size = 0x01000000; + break; /* => 16 MB */ + + default: + info->flash_id = FLASH_UNKNOWN; + break; + } + + if (info->sector_count > CFG_MAX_FLASH_SECT) { + printf ("** ERROR: sector count %d > max (%d) **\n", + info->sector_count, CFG_MAX_FLASH_SECT); + info->sector_count = CFG_MAX_FLASH_SECT; + } + + addr[0] = 0xFF; /* restore read mode */ + + return (info->size); +} + + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t * info, int s_first, int s_last) +{ + int flag, prot, sect; + ulong type; + int rcode = 0; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + type = (info->flash_id & FLASH_VENDMASK); + if ((type != FLASH_MAN_INTEL)) { + printf ("Can't erase unknown flash type %08lx - aborted\n", + info->flash_id); + return 1; + } + + prot = 0; + for (sect = s_first; sect <= s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) + printf ("- Warning: %d protected sectors will not be erased!\n", prot); + else + printf ("\n"); + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + volatile unsigned char *addr; + unsigned char status; + + printf ("Erasing sector %2d ... ", sect); + + /* arm simple, non interrupt dependent timer */ + reset_timer_masked (); + + addr = (volatile unsigned char *) (info->start[sect]); + *addr = 0x50; /* clear status register */ + *addr = 0x20; /* erase setup */ + *addr = 0xD0; /* erase confirm */ + + while (((status = *addr) & 0x80) != 0x80) { + if (get_timer_masked () > + CFG_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + *addr = 0xB0; /* suspend erase */ + *addr = 0xFF; /* reset to read mode */ + rcode = 1; + break; + } + } + + *addr = 0x50; /* clear status register cmd */ + *addr = 0xFF; /* resest to read mode */ + + printf (" done\n"); + } + } + return rcode; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 4 - Flash not identified + */ + +int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ + ulong cp, wp; + unsigned char data; + int count, i, l, rc, port_width; + + if (info->flash_id == FLASH_UNKNOWN) + return 4; + + wp = addr; + port_width = 1; + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i = 0, cp = wp; i < l; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + for (; i < port_width && cnt > 0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt == 0 && i < port_width; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + if ((rc = write_data (info, wp, data)) != 0) { + return (rc); + } + wp += port_width; + } + + /* + * handle word aligned part + */ + count = 0; + while (cnt >= port_width) { + data = 0; + for (i = 0; i < port_width; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_data (info, wp, data)) != 0) { + return (rc); + } + wp += port_width; + cnt -= port_width; + if (count++ > 0x800) { + spin_wheel (); + count = 0; + } + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i < port_width; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + return (write_data (info, wp, data)); +} + +/*----------------------------------------------------------------------- + * Write a word or halfword to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_data (flash_info_t * info, ulong dest, unsigned char data) +{ + volatile unsigned char *addr = (volatile unsigned char *) dest; + ulong status; + int flag; + + /* Check if Flash is (sufficiently) erased */ + if ((*addr & data) != data) { + printf ("not erased at %08lx (%lx)\n", (ulong) addr, + (ulong) * addr); + return (2); + } + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + *addr = 0x40; /* write setup */ + *addr = data; + + /* arm simple, non interrupt dependent timer */ + reset_timer_masked (); + + /* wait while polling the status register */ + while (((status = *addr) & 0x80) != 0x80) { + if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) { + *addr = 0xFF; /* restore read mode */ + return (1); + } + } + + *addr = 0xFF; /* restore read mode */ + + return (0); +} + +void inline spin_wheel (void) +{ + static int p = 0; + static char w[] = "\/-"; + + printf ("\010%c", w[p]); + (++p == 3) ? (p = 0) : 0; +} diff -Naur --exclude=CVS u-boot-1.1.1/board/cm4008/Makefile u-boot/board/cm4008/Makefile --- u-boot-1.1.1/board/cm4008/Makefile 1970-01-01 10:00:00.000000000 +1000 +++ u-boot/board/cm4008/Makefile 2004-11-02 00:38:51.000000000 +1000 @@ -0,0 +1,46 @@ +# +# (C) Copyright 2000, 2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS := cm4008.o flash.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $^ + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff -Naur --exclude=CVS u-boot-1.1.1/board/cm4008/u-boot.lds u-boot/board/cm4008/u-boot.lds --- u-boot-1.1.1/board/cm4008/u-boot.lds 1970-01-01 10:00:00.000000000 +1000 +++ u-boot/board/cm4008/u-boot.lds 2004-11-05 00:27:11.000000000 +1000 @@ -0,0 +1,55 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + cpu/ks8695/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +} diff -Naur --exclude=CVS u-boot-1.1.1/include/configs/cm4008.h u-boot/include/configs/cm4008.h --- u-boot-1.1.1/include/configs/cm4008.h 1970-01-01 10:00:00.000000000 +1000 +++ u-boot/include/configs/cm4008.h 2005-03-20 22:31:27.000000000 +1000 @@ -0,0 +1,127 @@ +/* + * (C) Copyright 2004 + * Greg Ungerer greg.ungerer@opengear.com. + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * If we are developing, we might want to start armboot from ram + * so we MUST NOT initialize critical regs like mem-timing ... + */ +#define CONFIG_INIT_CRITICAL /* undef for developing */ + +/* + * High Level Configuration Options + * (easy to change) + */ +#define CONFIG_KS8695 1 /* it is a KS8695 CPU */ +#define CONFIG_CM4008 1 /* it is an OpenGear CM4008 boad */ + +#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ + +#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ +#define CONFIG_SETUP_MEMORY_TAGS 1 +#define CONFIG_INITRD_TAG 1 + +/* + * Size of malloc() pool + */ +#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024) +#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ + +/* + * Hardware drivers + */ + +/* + * select serial console configuration + */ +#define CFG_ENV_IS_NOWHERE +#define CONFIG_SERIAL1 +#define CONFIG_CONS_INDEX 1 +#define CONFIG_BAUDRATE 115200 +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include <cmd_confdefs.h> +#undef CONFIG_COMMANDS +#define CONFIG_COMMANDS (CONFIG_CMD_DFL & ~(CFG_CMD_NONSTD | CFG_CMD_ENV)) + +#define CONFIG_BOOTDELAY 0 +#define CONFIG_BOOTARGS "mem=16M console=ttyAM0,115200" +#define CONFIG_BOOTCOMMAND "gofsk 0x02200000" + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "boot > " /* Monitor Command Prompt */ +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_MEMTEST_START 0x00800000 /* memtest works on */ +#define CFG_MEMTEST_END 0x01000000 /* 16 MB in DRAM */ + +#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ + +#define CFG_LOAD_ADDR 0x00008000 /* default load address */ + +#define CFG_HZ (1000) /* 1ms resolution ticks */ + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ +#ifdef CONFIG_USE_IRQ +#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */ +#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ +#endif + +/*----------------------------------------------------------------------- + * Physical Memory Map + */ +#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */ +#define PHYS_SDRAM_1 0x00000000 /* SDRAM Bank #1 */ +#define PHYS_SDRAM_1_SIZE 0x01000000 /* 16 MB */ + +#define PHYS_FLASH_1 0x02000000 /* Flash Bank #1 */ +#define PHYS_FLASH_SECT_SIZE 0x00020000 /* 128 KB sectors (x1) */ +#define CFG_FLASH_BASE PHYS_FLASH_1 + +/*----------------------------------------------------------------------- + * FLASH and environment organization + */ +#define CFG_MAX_FLASH_BANKS 2 /* max number of flash banks */ +#define CFG_MAX_FLASH_SECT (128) /* max number of sectors on one chip */ + +/* timeout values are in ticks */ +#define CFG_FLASH_ERASE_TOUT (20*CFG_HZ) /* Timeout for Flash Erase */ +#define CFG_FLASH_WRITE_TOUT (20*CFG_HZ) /* Timeout for Flash Write */ + +#define CFG_ENV_SIZE 0x20000 /* Total Size of Environment */ + +#endif /* __CONFIG_H */ diff -Naur --exclude=CVS u-boot-1.1.1/Makefile u-boot/Makefile --- u-boot-1.1.1/Makefile 2004-04-25 09:23:30.000000000 +1000 +++ u-boot/Makefile 2005-03-12 23:06:59.000000000 +1000 @@ -1040,6 +1040,11 @@ VCMA9_config : unconfig @./mkconfig $(@:_config=) arm arm920t vcma9 mpl
+cm4008_config : unconfig + @./mkconfig $(@:_config=) arm ks8695 cm4008 + +cm41xx_config : unconfig + @./mkconfig $(@:_config=) arm ks8695 cm41xx
######################################################################### ## S3C44B0 Systems

In message 4289F766.5040208@moreton.com.au you wrote:
Attached is a patch that adds support to u-boot for the OpenGear CM4008 8 port console manager board. It is built around the KS8695P CPU, with 8 serial ports, 16MB RAM, and 8MB NOR flash.
This patch was originally generated against u-boot 1.1.1.
Sorry, but 1.1.1 is just too old as reference for any new work. Please update your source base and resubmit. Please pay special attention to the fact that CONFIG_INIT_CRITICAL has been depracted!
Also, it seems that this board support references a CPU directory which is missing and has not been submitted yet.
Finally, please include the required entries to the CHANGELOG, CREDITS and MAINTAINERS files.
Best regards,
Wolfgang Denk

Hi All,
Revised patch against CVS source, adds support for the OpenGear CM4008 board (based on support for the ks8695 CPU).
Regards Greg
diff -Naur --exclude=CVS u-boot.cvs/board/cm4008/cm4008.c u-boot/board/cm4008/cm4008.c --- u-boot.cvs/board/cm4008/cm4008.c 1970-01-01 10:00:00.000000000 +1000 +++ u-boot/board/cm4008/cm4008.c 2005-05-19 20:59:04.000000000 +1000 @@ -0,0 +1,101 @@ +/* + * (C) Copyright 2005 + * Greg Ungerer, OpenGear Inc, greg.ungerer@opengear.com + * + * (C) Copyright 2002 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger mgroeger@sysgo.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/arch/platform.h> + +/* ------------------------------------------------------------------------- */ + +#define ks8695_read(a) *((volatile unsigned int *) (KS8695_IO_BASE+(a))) +#define ks8695_write(a,b) *((volatile unsigned int *) (KS8695_IO_BASE+(a))) = (b) + +/* ------------------------------------------------------------------------- */ + + +/* + * Miscelaneous platform dependent initialisations + */ +int env_flash_cmdline (void) +{ + unsigned char *sp = (unsigned char *) 0x0201c020; + unsigned char *ep; + int len; + + /* Check if "erase" push button is depressed */ + if ((ks8695_read(KS8695_GPIO_DATA) & 0x8) == 0) { + printf("### Entering network recovery mode...\n"); + setenv("bootargs", "console=ttyAM0,115200 mem=16M initrd=0x400000,6M root=/dev/ram0"); + setenv("bootcmd", "bootp 0x400000; gofsk 0x400000"); + setenv("bootdelay", "2"); + return 0; + } + + /* Check for flash based kernel boot args to use as default */ + for (ep = sp, len = 0; ((len < 1024) && (*ep != 0)); ep++, len++) + ; + + if ((len > 0) && (len <1024)) + setenv("bootargs", sp); + + return 0; +} + +int board_late_init (void) +{ + return 0; +} + + +int board_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + /* arch number of CM4008 */ + gd->bd->bi_arch_number = 624; + + /* adress of boot parameters */ + gd->bd->bi_boot_params = 0x00000100; + + /* power down all but port 0 on the switch */ + ks8695_write(KS8695_SWITCH_LPPM12, 0x00000005); + ks8695_write(KS8695_SWITCH_LPPM34, 0x00050005); + + return 0; +} + +int dram_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + + return (0); +} diff -Naur --exclude=CVS u-boot.cvs/board/cm4008/config.mk u-boot/board/cm4008/config.mk --- u-boot.cvs/board/cm4008/config.mk 1970-01-01 10:00:00.000000000 +1000 +++ u-boot/board/cm4008/config.mk 2005-05-19 20:59:04.000000000 +1000 @@ -0,0 +1 @@ +TEXT_BASE = 0x00f00000 diff -Naur --exclude=CVS u-boot.cvs/board/cm4008/flash.c u-boot/board/cm4008/flash.c --- u-boot.cvs/board/cm4008/flash.c 1970-01-01 10:00:00.000000000 +1000 +++ u-boot/board/cm4008/flash.c 2005-05-19 20:59:05.000000000 +1000 @@ -0,0 +1,409 @@ +/* + * (C) Copyright 2005 + * Greg Ungerer, OpenGear Inc, greg.ungerer@opengear.com + * + * (C) Copyright 2001 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net + * + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <linux/byteorder/swab.h> + + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +#define mb() __asm__ __volatile__ ("" : : : "memory") + +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size (unsigned char * addr, flash_info_t * info); +static int write_data (flash_info_t * info, ulong dest, unsigned char data); +static void flash_get_offsets (ulong base, flash_info_t * info); +void inline spin_wheel (void); + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + int i; + ulong size = 0; + + for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { + switch (i) { + case 0: + flash_get_size ((unsigned char *) PHYS_FLASH_1, &flash_info[i]); + flash_get_offsets (PHYS_FLASH_1, &flash_info[i]); + break; + case 1: + /* ignore for now */ + flash_info[i].flash_id = FLASH_UNKNOWN; + break; + default: + panic ("configured too many flash banks!\n"); + break; + } + size += flash_info[i].size; + } + + /* Protect monitor and environment sectors + */ + flash_protect (FLAG_PROTECT_SET, + CFG_FLASH_BASE, + CFG_FLASH_BASE + _bss_start - _armboot_start, + &flash_info[0]); + + return size; +} + +/*----------------------------------------------------------------------- + */ +static void flash_get_offsets (ulong base, flash_info_t * info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) + return; + + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { + for (i = 0; i < info->sector_count; i++) { + info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE); + info->protect[i] = 0; + } + } +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t * info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_INTEL: + printf ("INTEL "); + break; + default: + printf ("Unknown Vendor "); + break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_28F128J3A: + printf ("28F128J3A\n"); + break; + default: + printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i = 0; i < info->sector_count; ++i) { + if ((i % 5) == 0) + printf ("\n "); + printf (" %08lX%s", + info->start[i], info->protect[i] ? " (RO)" : " "); + } + printf ("\n"); + return; +} + +/* + * The following code cannot be run from FLASH! + */ +static ulong flash_get_size (unsigned char * addr, flash_info_t * info) +{ + volatile unsigned char value; + + /* Write auto select command: read Manufacturer ID */ + addr[0x5555] = 0xAA; + addr[0x2AAA] = 0x55; + addr[0x5555] = 0x90; + + mb (); + value = addr[0]; + + switch (value) { + + case (unsigned char)INTEL_MANUFACT: + info->flash_id = FLASH_MAN_INTEL; + break; + + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + addr[0] = 0xFF; /* restore read mode */ + return (0); /* no or unknown flash */ + } + + mb (); + value = addr[2]; /* device ID */ + + switch (value) { + + case (unsigned char)INTEL_ID_28F640J3A: + info->flash_id += FLASH_28F640J3A; + info->sector_count = 64; + info->size = 0x00800000; + break; /* => 8 MB */ + + case (unsigned char)INTEL_ID_28F128J3A: + info->flash_id += FLASH_28F128J3A; + info->sector_count = 128; + info->size = 0x01000000; + break; /* => 16 MB */ + + default: + info->flash_id = FLASH_UNKNOWN; + break; + } + + if (info->sector_count > CFG_MAX_FLASH_SECT) { + printf ("** ERROR: sector count %d > max (%d) **\n", + info->sector_count, CFG_MAX_FLASH_SECT); + info->sector_count = CFG_MAX_FLASH_SECT; + } + + addr[0] = 0xFF; /* restore read mode */ + + return (info->size); +} + + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t * info, int s_first, int s_last) +{ + int flag, prot, sect; + ulong type; + int rcode = 0; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + type = (info->flash_id & FLASH_VENDMASK); + if ((type != FLASH_MAN_INTEL)) { + printf ("Can't erase unknown flash type %08lx - aborted\n", + info->flash_id); + return 1; + } + + prot = 0; + for (sect = s_first; sect <= s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) + printf ("- Warning: %d protected sectors will not be erased!\n", prot); + else + printf ("\n"); + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + volatile unsigned char *addr; + unsigned char status; + + printf ("Erasing sector %2d ... ", sect); + + /* arm simple, non interrupt dependent timer */ + reset_timer_masked (); + + addr = (volatile unsigned char *) (info->start[sect]); + *addr = 0x50; /* clear status register */ + *addr = 0x20; /* erase setup */ + *addr = 0xD0; /* erase confirm */ + + while (((status = *addr) & 0x80) != 0x80) { + if (get_timer_masked () > + CFG_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + *addr = 0xB0; /* suspend erase */ + *addr = 0xFF; /* reset to read mode */ + rcode = 1; + break; + } + } + + *addr = 0x50; /* clear status register cmd */ + *addr = 0xFF; /* resest to read mode */ + + printf (" done\n"); + } + } + return rcode; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 4 - Flash not identified + */ + +int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ + ulong cp, wp; + unsigned char data; + int count, i, l, rc, port_width; + + if (info->flash_id == FLASH_UNKNOWN) + return 4; + + wp = addr; + port_width = 1; + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i = 0, cp = wp; i < l; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + for (; i < port_width && cnt > 0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt == 0 && i < port_width; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + if ((rc = write_data (info, wp, data)) != 0) { + return (rc); + } + wp += port_width; + } + + /* + * handle word aligned part + */ + count = 0; + while (cnt >= port_width) { + data = 0; + for (i = 0; i < port_width; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_data (info, wp, data)) != 0) { + return (rc); + } + wp += port_width; + cnt -= port_width; + if (count++ > 0x800) { + spin_wheel (); + count = 0; + } + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i < port_width; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + return (write_data (info, wp, data)); +} + +/*----------------------------------------------------------------------- + * Write a word or halfword to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_data (flash_info_t * info, ulong dest, unsigned char data) +{ + volatile unsigned char *addr = (volatile unsigned char *) dest; + ulong status; + int flag; + + /* Check if Flash is (sufficiently) erased */ + if ((*addr & data) != data) { + printf ("not erased at %08lx (%lx)\n", (ulong) addr, + (ulong) * addr); + return (2); + } + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + *addr = 0x40; /* write setup */ + *addr = data; + + /* arm simple, non interrupt dependent timer */ + reset_timer_masked (); + + /* wait while polling the status register */ + while (((status = *addr) & 0x80) != 0x80) { + if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) { + *addr = 0xFF; /* restore read mode */ + return (1); + } + } + + *addr = 0xFF; /* restore read mode */ + + return (0); +} + +void inline spin_wheel (void) +{ + static int p = 0; + static char w[] = "\/-"; + + printf ("\010%c", w[p]); + (++p == 3) ? (p = 0) : 0; +} diff -Naur --exclude=CVS u-boot.cvs/board/cm4008/Makefile u-boot/board/cm4008/Makefile --- u-boot.cvs/board/cm4008/Makefile 1970-01-01 10:00:00.000000000 +1000 +++ u-boot/board/cm4008/Makefile 2005-05-19 20:59:05.000000000 +1000 @@ -0,0 +1,46 @@ +# +# (C) Copyright 2000, 2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS := cm4008.o flash.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $^ + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff -Naur --exclude=CVS u-boot.cvs/board/cm4008/u-boot.lds u-boot/board/cm4008/u-boot.lds --- u-boot.cvs/board/cm4008/u-boot.lds 1970-01-01 10:00:00.000000000 +1000 +++ u-boot/board/cm4008/u-boot.lds 2005-05-19 22:41:31.000000000 +1000 @@ -0,0 +1,55 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + cpu/arm920t/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +} diff -Naur --exclude=CVS u-boot.cvs/include/configs/cm4008.h u-boot/include/configs/cm4008.h --- u-boot.cvs/include/configs/cm4008.h 1970-01-01 10:00:00.000000000 +1000 +++ u-boot/include/configs/cm4008.h 2005-05-19 21:04:14.000000000 +1000 @@ -0,0 +1,121 @@ +/* + * (C) Copyright 2004 + * Greg Ungerer greg.ungerer@opengear.com. + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + * (easy to change) + */ +#define CONFIG_KS8695 1 /* it is a KS8695 CPU */ +#define CONFIG_CM4008 1 /* it is an OpenGear CM4008 boad */ + +#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ + +#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ +#define CONFIG_SETUP_MEMORY_TAGS 1 +#define CONFIG_INITRD_TAG 1 + +/* + * Size of malloc() pool + */ +#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024) +#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ + +/* + * Hardware drivers + */ + +/* + * select serial console configuration + */ +#define CFG_ENV_IS_NOWHERE +#define CONFIG_SERIAL1 +#define CONFIG_CONS_INDEX 1 +#define CONFIG_BAUDRATE 115200 +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include <cmd_confdefs.h> +#undef CONFIG_COMMANDS +#define CONFIG_COMMANDS (CONFIG_CMD_DFL & ~(CFG_CMD_NONSTD | CFG_CMD_ENV)) + +#define CONFIG_BOOTDELAY 0 +#define CONFIG_BOOTARGS "mem=16M console=ttyAM0,115200" +#define CONFIG_BOOTCOMMAND "gofsk 0x02200000" + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "boot > " /* Monitor Command Prompt */ +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_MEMTEST_START 0x00800000 /* memtest works on */ +#define CFG_MEMTEST_END 0x01000000 /* 16 MB in DRAM */ + +#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ + +#define CFG_LOAD_ADDR 0x00008000 /* default load address */ + +#define CFG_HZ (1000) /* 1ms resolution ticks */ + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ +#ifdef CONFIG_USE_IRQ +#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */ +#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ +#endif + +/*----------------------------------------------------------------------- + * Physical Memory Map + */ +#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */ +#define PHYS_SDRAM_1 0x00000000 /* SDRAM Bank #1 */ +#define PHYS_SDRAM_1_SIZE 0x01000000 /* 16 MB */ + +#define PHYS_FLASH_1 0x02000000 /* Flash Bank #1 */ +#define PHYS_FLASH_SECT_SIZE 0x00020000 /* 128 KB sectors (x1) */ +#define CFG_FLASH_BASE PHYS_FLASH_1 + +/*----------------------------------------------------------------------- + * FLASH and environment organization + */ +#define CFG_MAX_FLASH_BANKS 2 /* max number of flash banks */ +#define CFG_MAX_FLASH_SECT (128) /* max number of sectors on one chip */ + +/* timeout values are in ticks */ +#define CFG_FLASH_ERASE_TOUT (20*CFG_HZ) /* Timeout for Flash Erase */ +#define CFG_FLASH_WRITE_TOUT (20*CFG_HZ) /* Timeout for Flash Write */ + +#define CFG_ENV_SIZE 0x20000 /* Total Size of Environment */ + +#endif /* __CONFIG_H */ diff -Naur --exclude=CVS u-boot.cvs/Makefile u-boot/Makefile --- u-boot.cvs/Makefile 2005-05-19 20:57:30.000000000 +1000 +++ u-boot/Makefile 2005-05-19 22:33:46.000000000 +1000 @@ -1407,6 +1407,12 @@ fi @./mkconfig -a voiceblue arm arm925t voiceblue
+cm4008_config : unconfig + @./mkconfig $(@:_config=) arm arm920t cm4008 NULL ks8695 + +cm41xx_config : unconfig + @./mkconfig $(@:_config=) arm arm920t cm41xx NULL ks8695 + ######################################################################### ## S3C44B0 Systems #########################################################################

In message 428CA2EE.2090405@moreton.com.au you wrote:
Revised patch against CVS source, adds support for the OpenGear CM4008 board (based on support for the ks8695 CPU).
Added, thanks.
Please don't add trailing white space (board/cm4008/cm4008.c).
Note that your code references a non-existing U-Boot command "gofsk"!
Note that there are compiler warnings generated from your code:
ks8695eth.c: In function `eth_send': ks8695eth.c:217: warning: passing arg 2 of `memcpy' discards qualifiers from pointer target type ks8695eth.c:220: warning: passing arg 1 of `memset' makes pointer from integer without a cast
Please submit a (new, incremental) patch for this one!
Best regards,
Wolfgang Denk

Hi Wolfgang,
Wolfgang Denk wrote:
Note that there are compiler warnings generated from your code:
ks8695eth.c: In function `eth_send': ks8695eth.c:217: warning: passing arg 2 of `memcpy' discards qualifiers from pointer target type ks8695eth.c:220: warning: passing arg 1 of `memset' makes pointer from integer without a cast
Please submit a (new, incremental) patch for this one!
Ok, attached.
Thanks Greg
------------------------------------------------------------------------ Greg Ungerer -- Chief Software Dude EMAIL: gerg@snapgear.com SnapGear -- a CyberGuard Company PHONE: +61 7 3435 2888 825 Stanley St, FAX: +61 7 3891 3630 Woolloongabba, QLD, 4102, Australia WEB: http://www.SnapGear.com
diff -Naur --exclude=CVS u-boot.cvs/drivers/ks8695eth.c u-boot/drivers/ks8695eth.c --- u-boot.cvs/drivers/ks8695eth.c 2005-05-20 08:39:43.000000000 +1000 +++ u-boot/drivers/ks8695eth.c 2005-05-21 00:03:02.000000000 +1000 @@ -214,10 +214,10 @@ packet, len);
dp = &ks8695_tx[next]; - memcpy((void *) dp->addr, packet, len); + memcpy((void *) dp->addr, (void *) packet, len);
if (len < 64) { - memset(dp->addr+len, 0, 64-len); + memset((void *) (dp->addr + len), 0, 64-len); len = 64; }

In message 428DEF7E.9080703@moreton.com.au you wrote:
ks8695eth.c:217: warning: passing arg 2 of `memcpy' discards qualifiers from pointer target type ks8695eth.c:220: warning: passing arg 1 of `memset' makes pointer from integer without a cast
Please submit a (new, incremental) patch for this one!
Ok, attached.
Applied. But please provide a CHANGELO entry next time!
Best regards,
Wolfgang Denk

Hi Wolfgang,
Wolfgang Denk wrote:
Note that your code references a non-existing U-Boot command "gofsk"!
Indeed it does :-)
I have a couple of more patches, things a little more contentious than simple cpu or board add.
The gofsk command is something I added to support loading snapgear/uClinux-dist style raw filesystem+kernel images.
The image itself is a simple concatenation of a root filesystem and a kernel. Typically it is used with a CRAMfs root filesystem. The primary motivator for not having any header on this image is that it can be dumped directly into an MTD flash partition, and it can be directly mounted as the root filesystem. For known filesystem types (like CRAMfs and ROMfs) the loader simply looks over the filesystem to get to the kernel for boot time starting.
Patch attached is my current implementation of this.
Is this something that you would allow into the main tree?
Regards Greg
------------------------------------------------------------------------ Greg Ungerer -- Chief Software Dude EMAIL: gerg@snapgear.com SnapGear -- a CyberGuard Company PHONE: +61 7 3435 2888 825 Stanley St, FAX: +61 7 3891 3630 Woolloongabba, QLD, 4102, Australia WEB: http://www.SnapGear.com
diff -Naur --exclude=CVS u-boot.cvs/common/cmd_bootr.c u-boot/common/cmd_bootr.c --- u-boot.cvs/common/cmd_bootr.c 1970-01-01 10:00:00.000000000 +1000 +++ u-boot/common/cmd_bootr.c 2005-05-19 23:29:06.000000000 +1000 @@ -0,0 +1,117 @@ +/* + * (C) Copyright 2005 + * Greg Ungerer, OpenGear Inc, greg.ungerer@opengear.com + * + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Misc boot support + */ +#include <common.h> +#include <command.h> +#include <net.h> + + +/* -------------------------------------------------------------------- */ + +int do_gofsk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +#if defined(CONFIG_I386) + DECLARE_GLOBAL_DATA_PTR; +#endif + ulong fsaddr, fslen, kaddr, klen, rc; + uchar *s; + int rcode = 0; + + kaddr = CFG_LOAD_ADDR; + klen = 0x100000; + + if (argc < 2) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + fsaddr = simple_strtoul(argv[1], NULL, 16); + if (argc > 2) + kaddr = simple_strtoul(argv[2], NULL, 16); + if (argc > 3) + klen = simple_strtoul(argv[3], NULL, 16); + + printf ("## Checking Filesystem at 0x%08lX ...\n", fsaddr); + + s = (uchar *) fsaddr; + fslen = 0; + + if (memcmp(fsaddr, "-rom1fs-", 8) == 0) { + /* ROMfs */ + fslen = (s[8] << 24) | (s[9] << 16) | (s[10] << 8) | s[11]; + fslen = (fslen + 1023) & ~1023; + printf ("## Found ROMfs filesystem at 0x%08lX size 0x%08lX\n", + fsaddr, fslen); + } else if ((s[0] == 0x45) && (s[1] == 0x3d) && (s[2] == 0xcd) && (s[3]== 0x28)) { + /* CRAMfs */ + fslen = (s[7] << 24) | (s[6] << 16) | (s[5] << 8) | s[4]; + printf ("## Found CRAMfs filesystem at 0x%08lX size 0x%08lX\n", + fsaddr, fslen); + } else { + printf("## Unknown filesystem type, cannot skip\n"); + return 1; + } + + fsaddr += fslen; + + printf ("## Copying Linux Kernel from 0x%08lX to 0x%08lX...\n", + fsaddr, kaddr); + + memcpy(kaddr, fsaddr, klen); + + printf ("## Starting Linux Kernel at 0x%08lX ...\n", kaddr); + +#if defined(CONFIG_ARM) + make_tags(); +#endif + cleanup_before_linux(); +#if !defined(CONFIG_NIOS) + rc = ((ulong (*)(void))kaddr) (); +#else + /* + * Nios function pointers are address >> 1 + */ + rc = ((ulong (*)(int, char *[]))(kaddr>>1)) (); +#endif + if (rc != 0) rcode = 1; + + printf ("## Application terminated, rc = 0x%lX\n", rc); + return rcode; +} + +/* -------------------------------------------------------------------- */ + +U_BOOT_CMD( + gofsk, CFG_MAXARGS, 3, do_gofsk, + "gofsk - copy and start kernel after fileystem\n", + "fsaddr [kaddr [klen]]\n" + " - copy kernel after fileystem at address 'fsaddr'\n" + " to 'kaddr' (of length 'klen') and then jump to it\n" +); + diff -Naur --exclude=CVS u-boot.cvs/common/Makefile u-boot/common/Makefile --- u-boot.cvs/common/Makefile 2005-05-19 20:57:31.000000000 +1000 +++ u-boot/common/Makefile 2005-05-19 23:29:06.000000000 +1000 @@ -29,7 +29,7 @@
COBJS = main.o ACEX1K.o altera.o bedbug.o circbuf.o \ cmd_ace.o cmd_autoscript.o \ - cmd_bdinfo.o cmd_bedbug.o cmd_bmp.o cmd_boot.o cmd_bootm.o \ + cmd_bdinfo.o cmd_bedbug.o cmd_bmp.o cmd_boot.o cmd_bootm.o cmd_bootr.o \ cmd_cache.o cmd_console.o \ cmd_date.o cmd_dcr.o cmd_diag.o cmd_doc.o cmd_dtt.o \ cmd_eeprom.o cmd_elf.o cmd_ext2.o \ diff -Naur --exclude=CVS u-boot.cvs/lib_arm/armlinux.c u-boot/lib_arm/armlinux.c --- u-boot.cvs/lib_arm/armlinux.c 2005-05-19 20:57:45.000000000 +1000 +++ u-boot/lib_arm/armlinux.c 2005-05-19 23:43:51.000000000 +1000 @@ -278,6 +278,41 @@ defined (CONFIG_REVISION_TAG) || \ defined (CONFIG_LCD) || \ defined (CONFIG_VFD) +void make_tags (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + bd_t *bd = gd->bd; + +#ifdef CONFIG_CMDLINE_TAG + char *commandline = getenv ("bootargs"); +#endif + + setup_start_tag (bd); +#ifdef CONFIG_SERIAL_TAG + setup_serial_tag (¶ms); +#endif +#ifdef CONFIG_REVISION_TAG + setup_revision_tag (¶ms); +#endif +#ifdef CONFIG_SETUP_MEMORY_TAGS + setup_memory_tags (bd); +#endif +#ifdef CONFIG_CMDLINE_TAG + setup_commandline_tag (bd, commandline); +#endif +#if defined (CONFIG_VFD) + setup_videolfb_tag ((gd_t *) gd); +#endif + setup_end_tag (bd); +} + static void setup_start_tag (bd_t *bd) { params = (struct tag *) bd->bi_boot_params;

Dear Greg,
in message 428DF0F8.5090404@moreton.com.au you wrote:
The gofsk command is something I added to support loading snapgear/uClinux-dist style raw filesystem+kernel images.
I don't understand why a separate command is needed for that; you need to store the start address of the image anyway, so you can also store it's size and use this to compute any other offset; or store the kernel address, too.
The image itself is a simple concatenation of a root filesystem and a kernel. Typically it is used with a CRAMfs root filesystem. The primary motivator for not having any header on this image is that it can be dumped directly into an MTD flash partition, and it can be directly mounted as the root filesystem. For known
This is normal. We don't have headers for standard filesystem images like cramfs, ext2 or jffs2 for exactly this reason.
filesystem types (like CRAMfs and ROMfs) the loader simply looks over the filesystem to get to the kernel for boot time starting.
Why do you need a separate command for this?
Patch attached is my current implementation of this.
Is this something that you would allow into the main tree?
No, I don't think so. I don't see what it gives you what you cannot get with the existing commands and clever usage of a few environment variables. Also, in general I find it is not a good idea to combine filesystem and OS kernel into ane image. Usually you buy more restrictions than advantages this way. If you feel you must do it, you could extend the capabilities of mutli-file images to match your needs.
But the main question is: what can you do with this setup that cannot be done with the existing code, too?
Best regards,
Wolfgang Denk

Hi Wolfgang,
Wolfgang Denk wrote:
Dear Greg,
in message 428DF0F8.5090404@moreton.com.au you wrote:
The gofsk command is something I added to support loading snapgear/uClinux-dist style raw filesystem+kernel images.
I don't understand why a separate command is needed for that; you need to store the start address of the image anyway, so you can also store it's size and use this to compute any other offset; or store the kernel address, too.
Not quite. The start address is fixed (as in fixed position in flash normally). Size is completely dependant on the image - so you need to compute that at run time. You don't want to store the length independantly.
The image itself is a simple concatenation of a root filesystem and a kernel. Typically it is used with a CRAMfs root filesystem. The primary motivator for not having any header on this image is that it can be dumped directly into an MTD flash partition, and it can be directly mounted as the root filesystem. For known
This is normal. We don't have headers for standard filesystem images like cramfs, ext2 or jffs2 for exactly this reason.
Yes, but that is not the point here. The is a complete system image with no heads (system being kernel and root filesystem).
filesystem types (like CRAMfs and ROMfs) the loader simply looks over the filesystem to get to the kernel for boot time starting.
Why do you need a separate command for this?
The other possibility seemed to be for a complicated sequence of commands to extract the size - though I didn't try to actually do this.
But I still wanted to construct the armtags for boot. I couldn't see that this was currently possible if not used a strictly tagged ARM u-boot image.
Patch attached is my current implementation of this.
Is this something that you would allow into the main tree?
No, I don't think so. I don't see what it gives you what you cannot get with the existing commands and clever usage of a few environment variables. Also, in general I find it is not a good idea to combine filesystem and OS kernel into ane image.
As a general rule I have always found the exact opposite. Although conveient for debugging I find sepearate kernel and filesystems a limitation in real field setups. A single flash partition with no additional layout restrictions is a much more flexible arrangment. Doesn't limit one or the others size or location.
Usually you buy more restrictions than advantages this way. If you feel you must do it, you could extend the capabilities of mutli-file images to match your needs.
But the main question is: what can you do with this setup that cannot be done with the existing code, too?
I couldn't see how to load a raw image (no header) and still get the ARM tags setup for booting. ofcousre this was with 1.1.1 when I originally did this. Is it possible now?
Regards Greg

In message 42913295.6080308@moreton.com.au you wrote:
I don't understand why a separate command is needed for that; you need to store the start address of the image anyway, so you can also store it's size and use this to compute any other offset; or store the kernel address, too.
Not quite. The start address is fixed (as in fixed position in flash normally). Size is completely dependant on the image - so you need to compute that at run time. You don't want to store the length independantly.
You can "compute" the image size at download time - actually it comes for free in $filesize.
Yes, but that is not the point here. The is a complete system image with no heads (system being kernel and root filesystem).
I think it is not a good idea to use header-less kernel images - most projects I've seen were happy enough to be able to find outr which image is installed in flash and if it's corrupted or not. YMMV.
filesystem types (like CRAMfs and ROMfs) the loader simply looks over the filesystem to get to the kernel for boot time starting.
Why do you need a separate command for this?
The other possibility seemed to be for a complicated sequence of commands to extract the size - though I didn't try to actually do this.
"tftp ..." followed by using $filesize seems not too complicated to me.
But I still wanted to construct the armtags for boot. I couldn't see that this was currently possible if not used a strictly tagged ARM u-boot image.
One more reason to use headers for the kernel image.
But the main question is: what can you do with this setup that cannot be done with the existing code, too?
I couldn't see how to load a raw image (no header) and still get the ARM tags setup for booting. ofcousre this was with 1.1.1 when I originally did this. Is it possible now?
You cannot. And I will not tolerate duplication of the standard Linux boot command code into other "private" commands. Let's keep the code clean and implemented only once.
But this was NOT your requirement. You wanted to store a kernel image in flash immediately following a cramfs (or other file system) image.
The file system image is usually header-less (only exception: ramdisk images); the kernel image should have proper U-Boot headers so it can be nooted by the standard bootm command.
If I wanted to do this, I would probly change the order: put the kernel image first, followed by the filesystem image. Then we ar every close to using a standard multi-file image. The only thing still needed is to manually pad the kernel image so that the file system will start on a sector boundary.
If this is too cumbersome, you could easily patch the mkimage tool to take a new option ("-b blocksize" or so) to do the padding automatically for you.
That would be even more flexible as it does not restrict you to just two images.
Best regards,
Wolfgang Denk

Hi Wolfgang,
Wolfgang Denk wrote:
In message 42913295.6080308@moreton.com.au you wrote:
I don't understand why a separate command is needed for that; you need to store the start address of the image anyway, so you can also store it's size and use this to compute any other offset; or store the kernel address, too.
Not quite. The start address is fixed (as in fixed position in flash normally). Size is completely dependant on the image - so you need to compute that at run time. You don't want to store the length independantly.
You can "compute" the image size at download time - actually it comes for free in $filesize.
It is not the filesize that you want. You want the size of the filesystem that is the first part of the combined image. You need to know that so you can find the the start of the kernel image (the zImage part) that is after the filesystem.
To get the filesystem size you have to look at the first few words when you get it in memory. Once you figure out the filesystem type (since there is only a couple of interresting types that can work here you only need to check for the magic number header) you know how to determine its size.
So single file image is:
+----------------------------------------+---------------------+ | filesystem | kernel | +----------------------------------------+---------------------+ ^ |
You don't know where the kernel starts until you have a look in the header of the filesystem. If it is CRAMfs or ROMfs (or that type of fixed filesystem) then the size is stored in the the header.
The start offset of the kernel in this file will change whenever you change the filesystem (normally it is a readonly type, so the only change is at compile time when you generate it).
Because there is no boot loader header this image is directly mountable if I copy it into an mtd flash partition.
Yes, but that is not the point here. The is a complete system image with no heads (system being kernel and root filesystem).
I think it is not a good idea to use header-less kernel images - most projects I've seen were happy enough to be able to find outr which image is installed in flash and if it's corrupted or not. YMMV.
Some people want that, some don't. There is a pretty big installed base of configurations that don't use headers.
filesystem types (like CRAMfs and ROMfs) the loader simply looks over the filesystem to get to the kernel for boot time starting.
Why do you need a separate command for this?
The other possibility seemed to be for a complicated sequence of commands to extract the size - though I didn't try to actually do this.
"tftp ..." followed by using $filesize seems not too complicated to me.
As I pointed out that does not work, it is not filesize you want.
But I still wanted to construct the armtags for boot. I couldn't see that this was currently possible if not used a strictly tagged ARM u-boot image.
One more reason to use headers for the kernel image.
Well, thats not quite the way I looked at it. I saw it as a limitation of u-boot, something that it could not do.
This method is in common use. The snapgear guys have been doing it for years. They would have a pretty large installed base (though that is not relevant to this discussion).
But the main question is: what can you do with this setup that cannot be done with the existing code, too?
I couldn't see how to load a raw image (no header) and still get the ARM tags setup for booting. ofcousre this was with 1.1.1 when I originally did this. Is it possible now?
You cannot. And I will not tolerate duplication of the standard Linux boot command code into other "private" commands. Let's keep the code clean and implemented only once.
It is not a question of tolerating anything, it is about finding a solution that is acceptable to you for something that u-boot cannot currently do.
But this was NOT your requirement. You wanted to store a kernel image in flash immediately following a cramfs (or other file system) image.
Yes, the requirement is to be able to store the image in flash and have it directly bootable and mountable, and for it to be network loadable and to run just the same that way. Ofcourse it has to support the ARM boot tags, this is booting an ARM linux kernel.
So there is a couple of problems that fall out of this:
1. the image cannot have a header - otherwise it would not be directly mountable as a filesystem on an mtd device 2. you need to determine the kernel start address so you can run it (irrespective of whether it is in flash or network loaded into RAM 3. you don't want to copy the filesystem part needlessly (so if it is in flash then don't bother copying it to RAM, and don require any additional copy of filesystem if network loaded into RAM
You want this setup to support boot tags - since that is the ARM defined mechanism for parsing boot information to the kernel.
The fundamental idea is to have a single image that is a single file that is capable of all of this. (in other words it can be directly dumped into an mtd flash partition - usually within Linux, and it is capable of being network loaded and run.
I can load a one of these combined images into RAM (or from flash) using standard command, I can manually determine the size by dumping memory and looking at, I can start that image. I can do all of this without any extra command support (though I am not sure about automating the size calculation here). But with no ARM tags in memory it is not a correct boot.
From what you have said so far it seems I was right, you cannot do this currently with u-boot?
Is a command tool that allows constructing ARM tags a better solution for you?
The file system image is usually header-less (only exception: ramdisk images); the kernel image should have proper U-Boot headers so it can be nooted by the standard bootm command.
If I wanted to do this, I would probly change the order: put the kernel image first, followed by the filesystem image. Then we ar every close to using a standard multi-file image. The only thing still needed is to manually pad the kernel image so that the file system will start on a sector boundary.
But I cannot copy this "as is" into an mtd flash partition and mount it as a filesystem.
Even if you try to pad out to mtd partition boundaries that is at best a kludge. You will either waste too much flash space, or you will eventually have a kernel that is too large. It will happen.
If this is too cumbersome, you could easily patch the mkimage tool to take a new option ("-b blocksize" or so) to do the padding automatically for you.
That would be even more flexible as it does not restrict you to just two images.
I don't understand, two images? Virtually all the platfoms I deal with do not have the flash space for two images (or even just two kernels). If they did then the hardware guys have spec'ed to much flash on the board :-)
Regards Greg

Dear Greg,
in message 4292CCC5.2050104@moreton.com.au you wrote:
You can "compute" the image size at download time - actually it comes for free in $filesize.
It is not the filesize that you want. You want the size of the
Yes, it is what *I* want :-)
filesystem that is the first part of the combined image. You
This is the catch: I wouldn't use combined images.
To get the filesystem size you have to look at the first few words when you get it in memory. Once you figure out the filesystem type (since there is only a couple of interresting types that can work here you only need to check for the magic number header) you know how to determine its size.
Did you read my proposal of using a multifile image?
You don't know where the kernel starts until you have a look in the header of the filesystem. If it is CRAMfs or ROMfs (or that type of
I understand this problem., It results from an unadept choice of your image layout - put the kernel first, and the problems just go away :-)
Because there is no boot loader header this image is directly mountable if I copy it into an mtd flash partition.
You can do the same with a standard multifile image.
I think it is not a good idea to use header-less kernel images - most projects I've seen were happy enough to be able to find outr which image is installed in flash and if it's corrupted or not. YMMV.
Some people want that, some don't. There is a pretty big installed base of configurations that don't use headers.
Well, the only disadvantage you get from having a header is an additional 64 bytes (or 68 + 4 * number of images in case of a multi-image file). More memory is saved by NOT adding special boot code for headerless images.
"tftp ..." followed by using $filesize seems not too complicated to me.
As I pointed out that does not work, it is not filesize you want.
It does work. I use it all the time. You just have to use tftp twice - once for the filesystem and a second time for the kernel :-)
This method is in common use. The snapgear guys have been doing it for years. They would have a pretty large installed base (though that is not relevant to this discussion).
Well, I cannot prevent anybody from not reading the documentation or from doing non-standard things. I don't consider it my problem if Snapgear comes up with a solution that ignores the existing standard methods and creates their own proprietary solutions or problems.
Quote:
"UNIX was not designed to stop you from doing stupid things, because that would also stop you from doing clever things." - Doug Gwyn
But I will try to enforce some design principles on the official U-Boot tree, and one of these is to avoid duplication of code.
Don't use "a pretty large installed base" as an argument - it doesn't count. You could have discussed your design here on the mailing list BEFORE implementing your own proprietary stuff.
It is not a question of tolerating anything, it is about finding a solution that is acceptable to you for something that u-boot cannot currently do.
Did you *read* me previous message? Why do you continue to ignore my proposal of using a multifile image instead? I really don't see where exactly your problem is.
Yes, the requirement is to be able to store the image in flash and have it directly bootable and mountable, and for it to be network loadable and to run just the same that way. Ofcourse it has to support the ARM boot tags, this is booting an ARM linux kernel.
Yes, I understood this. And ALL of this is available with either two separate images or with a combined multifile image.
- the image cannot have a header - otherwise it would not be directly mountable as a filesystem on an mtd device
Wrong. As I explained before, you can use a multifile image with the header "belonging" to the kernel, which should be the first file in the image then.
- you need to determine the kernel start address so you can run it (irrespective of whether it is in flash or network loaded into RAM
You created this problem yourself. It results from your unadept design.
If you use a multifile image with a proper header the kernel start address is encoded in the header.
- you don't want to copy the filesystem part needlessly (so if it is in flash then don't bother copying it to RAM, and don require any additional copy of filesystem if network loaded into RAM
Agreed. But I don't see what this has to do with the current discussion. It's a completely separate issue, relevant only to ramdisk images and then more of a Linux kernel question (i. e. if it can read a [compressed] ramdisk image directly from flash or not).
You want this setup to support boot tags - since that is the ARM defined mechanism for parsing boot information to the kernel.
This is part of the standard boot command. Just use it.
The fundamental idea is to have a single image that is a single file that is capable of all of this. (in other words it can be directly dumped into an mtd flash partition - usually within Linux, and it is capable of being network loaded and run.
You repeat this again and again. I understood your intentions.
But there is amy ways to implement this, and I repeat that your method is probably not the best one.
I can load a one of these combined images into RAM (or from flash) using standard command, I can manually determine the size by dumping memory and looking at, I can start that image. I can do all of this without any extra command support (though I am not sure about
Right. YOu can also save all this effort and just use a multifile image.
automating the size calculation here). But with no ARM tags in memory it is not a correct boot.
Right. Which is one of the reasons why this approach does not make sense.
From what you have said so far it seems I was right, you cannot do this currently with u-boot?
Wrong. I really ask myself if you are READING my postings????
I try to explain to you that it CAN be done, with existing commands only.
Is a command tool that allows constructing ARM tags a better solution for you?
What for? WE ALREADY HAVE A WORKING IMPLEMENTATION FOR THIS!
If I wanted to do this, I would probly change the order: put the kernel image first, followed by the filesystem image. Then we ar every close to using a standard multi-file image. The only thing still needed is to manually pad the kernel image so that the file system will start on a sector boundary.
But I cannot copy this "as is" into an mtd flash partition and mount it as a filesystem.
Please explain why not?
Even if you try to pad out to mtd partition boundaries that is at best a kludge. You will either waste too much flash space, or you will eventually have a kernel that is too large. It will happen.
Ummm... I cannot parse this. Can you please explain how this should be any problem? I mean, any more of a problem like in your solution? I understand that your kernel uses a static partition map, right? So the kernel knows about the current partitioning?
If this is too cumbersome, you could easily patch the mkimage tool to take a new option ("-b blocksize" or so) to do the padding automatically for you.
That would be even more flexible as it does not restrict you to just two images.
I don't understand, two images?
A multifile image contains one ore more (usually more, that's where the "multi" is coming from) "files" or "images". You talk allt he time about two items: the linux kernel and a file system. So we have two "files" or "images" to deal with, right?
With the multifile setup you could - for example - have 3 "files" or "images" in one combined image - say (1) the Linux kernel, (2) a read-only root file system like a cramfs image, and (3) a writable JFFS2 image for configuration data etc.
Virtually all the platfoms I deal with do not have the flash space for two images (or even just two kernels). If they did then the hardware
But you are using two images: kernel plus root filesystem - right?
Best regards,
Wolfgang Denk

Hi Wolfgang,
I guess we have a mismatch here somewhere, lets try and straiten this out.
Wolfgang Denk wrote:
To get the filesystem size you have to look at the first few words when you get it in memory. Once you figure out the filesystem type (since there is only a couple of interresting types that can work here you only need to check for the magic number header) you know how to determine its size.
Did you read my proposal of using a multifile image?
Yes, I read it. I don't currently see how it solves the problem.
You don't know where the kernel starts until you have a look in the header of the filesystem. If it is CRAMfs or ROMfs (or that type of
I understand this problem., It results from an unadept choice of your image layout - put the kernel first, and the problems just go away :-)
I geuss I disagree. We see a different problem. I see u-boot doesn't support an established image format. You see that it does (well I think that is what you are saying?).
I don't want to neccessarily turn this into a discussion about the merits of the format. I want this to be a discussion about how to go about best supporting it.
I think it is not a good idea to use header-less kernel images - most projects I've seen were happy enough to be able to find outr which image is installed in flash and if it's corrupted or not. YMMV.
Some people want that, some don't. There is a pretty big installed base of configurations that don't use headers.
Well, the only disadvantage you get from having a header is an additional 64 bytes (or 68 + 4 * number of images in case of a multi-image file). More memory is saved by NOT adding special boot code for headerless images.
The size of the header is not important.
"tftp ..." followed by using $filesize seems not too complicated to me.
As I pointed out that does not work, it is not filesize you want.
It does work. I use it all the time. You just have to use tftp twice
- once for the filesystem and a second time for the kernel :-)
Hmm, ok, you didn't say that earlier. Seems like an awful kludge to have to load it twice - don't you think?
This method is in common use. The snapgear guys have been doing it for years. They would have a pretty large installed base (though that is not relevant to this discussion).
Well, I cannot prevent anybody from not reading the documentation or from doing non-standard things. I don't consider it my problem if Snapgear comes up with a solution that ignores the existing standard methods and creates their own proprietary solutions or problems.
This isn't about reading documentation. And I suspect this method predates u-boot anyway. When you say standard you really mean u-boots own methods don't you? Does any other boot loader support the same format headers? (I actually don't know the answer to this, thus I am genuinely asking the question).
Quote:
"UNIX was not designed to stop you from doing stupid things, because that would also stop you from doing clever things." - Doug Gwyn
Yes, illustrates my point really... For one, u-boot has no mechanism for generating arm boot tags for anything other than its own defined kernel format.
But I will try to enforce some design principles on the official U-Boot tree, and one of these is to avoid duplication of code.
Certainly. I have no issue with that. Never have.
Don't use "a pretty large installed base" as an argument - it doesn't count. You could have discussed your design here on the mailing list BEFORE implementing your own proprietary stuff.
That makes no sense, I want to use u-boot with an existing format. No point asking years later what would be a good load format.
It is not a question of tolerating anything, it is about finding a solution that is acceptable to you for something that u-boot cannot currently do.
Did you *read* me previous message? Why do you continue to ignore my proposal of using a multifile image instead? I really don't see where exactly your problem is.
Ok, this is where I guess I don't understand your argument.
How can I take a multi-part image, and in Linux do
erase /dev/mtd1 cat imagefile > /dev/mtd1 mount /dev/mtdblock1 /mnt
If there is any header then that is not directly mountable as a filesystem.
You would need additional tool support to do this, and this either goes in Linux or u-boot.
[snip a lot of stuff that all goes back to the above question]
- you need to determine the kernel start address so you can run it (irrespective of whether it is in flash or network loaded into RAM
You created this problem yourself. It results from your unadept design.
Sorry, just don't agree. Unadept design. It works very well for its intended purpose. Just not with u-boot as it is.
Regards Greg

Dear Greg,
in message 429300A9.9050202@moreton.com.au you wrote:
I understand this problem., It results from an unadept choice of your image layout - put the kernel first, and the problems just go away :-)
I geuss I disagree. We see a different problem. I see u-boot doesn't support an established image format. You see that it does (well I think that is what you are saying?).
Please don't call your proprietary solution an "established image format". It is not, and never has been, at least not in the U-Boot context. U-Boot uses multifile images for such a purpose. Please don't blame me if you ignored the existing solutions and came up with somthing different which causes problems (no working boot support).
I don't want to neccessarily turn this into a discussion about the merits of the format. I want this to be a discussion about how to go about best supporting it.
Me too.
The size of the header is not important.
OK. Then what exactly prevents you from using a multifile image with header?
It does work. I use it all the time. You just have to use tftp twice
- once for the filesystem and a second time for the kernel :-)
Hmm, ok, you didn't say that earlier. Seems like an awful kludge to have to load it twice - don't you think?
I don't load anything twice - I load two separate images: one with the kernel, and one with the file system. I always found this to be much more flexible as you can change one component while leaving the other in place - this is MUCH easier to debug as you change one part of the system only, while keeping all the rest of the system (which is probably known to be working) unchanged.
I understand that you don't want to have separate images. OK, this is your decision. In this case U-Boot uses multifile images.
This isn't about reading documentation. And I suspect this method predates u-boot anyway. When you say standard you really mean u-boots own methods don't you? Does any other boot loader support
U-Boot, ARMBoot, PPCBoot, Linux in general. Just emember how Linux wraps a kernel image and an initial ramdisk image into one loadable file.
the same format headers? (I actually don't know the answer to this, thus I am genuinely asking the question).
Not with exactly the same header format. But the idea was not completely new when I implemented it.
For one, u-boot has no mechanism for generating arm boot tags for anything other than its own defined kernel format.
Right. This is intentional.
My intention my be wrong, or too limited, in which case I will be happy to discuss beter solutions. But for your application I don't see the need to change anything.
Don't use "a pretty large installed base" as an argument - it doesn't count. You could have discussed your design here on the mailing list BEFORE implementing your own proprietary stuff.
That makes no sense, I want to use u-boot with an existing format.
What exactly is your problem with using a different format which is supported by U-Boot?
How can I take a multi-part image, and in Linux do
erase /dev/mtd1 cat imagefile > /dev/mtd1 mount /dev/mtdblock1 /mnt
If there is any header then that is not directly mountable as a filesystem.
Create _THREE_ partitions in flash: one representing the area used for the Linux kernel (plus image headers), a second one for the root file system, and a third one which covers both areas.
For example:
Partition Offset Size Usage /dev/mtd0 0 256 kB U-Boot /dev/mtd1 256 kB 768 kB Linux Kernel (with header(s)) /dev/mtd2 1024 kB 3072 kB Root Filesystem /dev/mtd3 256 kB 3840 kB Combined Image
Then run:
erase /dev/mtd3 cat imagefile >/dev/mtd3 mount /dev/mtd2 /mnt
You would need additional tool support to do this, and this either goes in Linux or u-boot.
No. I don't need any new tools.
Sorry, just don't agree. Unadept design. It works very well for its intended purpose. Just not with u-boot as it is.
It does not work with U-Boot because it does not adhere to the U-Boot's design principles. One needs to be changed. I would be unwise to try to support the plethora of proprietary image formats in U-Boot. Instead, we try to provide interfaces that allow to get (at least) the same functionality. You can use these features, or ignore them.
Best regards,
Wolfgang Denk

Hi Wolfgang,
Wolfgang Denk wrote:
in message 429300A9.9050202@moreton.com.au you wrote:
I understand this problem., It results from an unadept choice of your image layout - put the kernel first, and the problems just go away :-)
I geuss I disagree. We see a different problem. I see u-boot doesn't support an established image format. You see that it does (well I think that is what you are saying?).
Please don't call your proprietary solution an "established image format".
When I say established I mean that it is in current use, this isn't a new format just created recently. And it is hardly proprietary, it is freely available to use - it is just a concatentation of 2 files how can you possibly make that proprietary.
And it is not my solution, I am just trying to work with it.
It is not, and never has been, at least not in the U-Boot context.
Well, yes, otherwise we wouldn't be having this discussion.
U-Boot uses multifile images for such a purpose. Please don't blame me if you ignored the existing solutions and came up with somthing different which causes problems (no working boot support).
This makes no sense, nobody ignored an exitsing u-boot solution, it did not exist yet!
It does work. I use it all the time. You just have to use tftp twice
- once for the filesystem and a second time for the kernel :-)
Hmm, ok, you didn't say that earlier. Seems like an awful kludge to have to load it twice - don't you think?
I don't load anything twice - I load two separate images: one with the kernel, and one with the file system. I always found this to be much more flexible as you can change one component while leaving the other in place - this is MUCH easier to debug as you change one part of the system only, while keeping all the rest of the system (which is probably known to be working) unchanged.
It can be somewhat useful for debug. But the majority of use for real products in my experience it is not.
This isn't about reading documentation. And I suspect this method predates u-boot anyway. When you say standard you really mean u-boots own methods don't you? Does any other boot loader support
U-Boot, ARMBoot, PPCBoot, Linux in general. Just emember how Linux wraps a kernel image and an initial ramdisk image into one loadable file.
I don't understand this. This has nothing to do with init ramdisk on Linux. The Linux ramdisk setup doesn't at all care how the ramdisk data got in memory (or flash). That is why there is TAGs and command line options - so the kernel can tell where it is without being tied to any boot loader machanism.
The header (or no header) is completely specific to u-boot/armboot/ ppcboot.
the same format headers? (I actually don't know the answer to this, thus I am genuinely asking the question).
Not with exactly the same header format. But the idea was not completely new when I implemented it.
For one, u-boot has no mechanism for generating arm boot tags for anything other than its own defined kernel format.
Right. This is intentional.
My intention my be wrong, or too limited, in which case I will be happy to discuss beter solutions.
Isn't that what we are doing?
But for your application I don't see the need to change anything.
I still don't see a solution to using this existing format. You have argued it is a bad format, you have argued if you re-organize it it could be made to work. That doesn't make u-boot work with this simple existing format as it is.
Changing the format opens lots of options for layout, but that is not what this discussion is about. Lets start another thread if anyone wants to talk about that.
Don't use "a pretty large installed base" as an argument - it doesn't count. You could have discussed your design here on the mailing list BEFORE implementing your own proprietary stuff.
That makes no sense, I want to use u-boot with an existing format.
What exactly is your problem with using a different format which is supported by U-Boot?
U-boot is not the only loader that is used, will be used, or has been used on this hardware in the past. Existing devices that rely on the old format (for their tftp loading of images) won't have their boot loaders changed. So changing to a different format is not really an option here.
How can I take a multi-part image, and in Linux do
erase /dev/mtd1 cat imagefile > /dev/mtd1 mount /dev/mtdblock1 /mnt
If there is any header then that is not directly mountable as a filesystem.
Create _THREE_ partitions in flash: one representing the area used for the Linux kernel (plus image headers), a second one for the root file system, and a third one which covers both areas.
For example:
Partition Offset Size Usage /dev/mtd0 0 256 kB U-Boot /dev/mtd1 256 kB 768 kB Linux Kernel (with header(s)) /dev/mtd2 1024 kB 3072 kB Root Filesystem /dev/mtd3 256 kB 3840 kB Combined Image
You have changed the format now, so that is not a solution to the problem.
(The reason I would hesitate to use this is that you have now set an arbitrary limit on the kernel size, and you are potentially wasting up to 256k of flash in this example. Ofcourse you could come up with a clever mtd map that let you have any size kernel, but you are still wasting some flash).
Sorry, just don't agree. Unadept design. It works very well for its intended purpose. Just not with u-boot as it is.
It does not work with U-Boot because it does not adhere to the U-Boot's design principles. One needs to be changed. I would be unwise to try to support the plethora of proprietary image formats in U-Boot. Instead, we try to provide interfaces that allow to get (at least) the same functionality. You can use these features, or ignore them.
None of this discussion has been about changing the way u-boot works, or what are the ways it has defined as being good image file formats. It is merely about some mechanism to support an additional format - that is all.
It doesn't at all bother me if you don't want this in the main u-boot source - it never has. I can and will quite happily carry it along in the versions of u-boot that are built for the hardware that I put it on that needs it. That is the great thing about the GPL.
I am simply make these changes available to the community, and if they are useful to others, then great. Otherwise it just doesn't matter.
Regards Greg
------------------------------------------------------------------------ Greg Ungerer -- Chief Software Dude EMAIL: gerg@snapgear.com SnapGear -- a CyberGuard Company PHONE: +61 7 3435 2888 825 Stanley St, FAX: +61 7 3891 3630 Woolloongabba, QLD, 4102, Australia WEB: http://www.SnapGear.com

In message 42932848.7010704@moreton.com.au you wrote:
U-Boot uses multifile images for such a purpose. Please don't blame me if you ignored the existing solutions and came up with somthing different which causes problems (no working boot support).
This makes no sense, nobody ignored an exitsing u-boot solution, it did not exist yet!
Multifile images were added (to PPCBoot) in October 2000.
I don't load anything twice - I load two separate images: one with the kernel, and one with the file system. I always found this to be much more flexible as you can change one component while leaving the
...
It can be somewhat useful for debug. But the majority of use for real products in my experience it is not.
You're just working in a different area of the market.
I don't understand this. This has nothing to do with init ramdisk on Linux. The Linux ramdisk setup doesn't at all care how the ramdisk
Did you check what happens when you run "make zImage.initrd" in a PowerPC Linux tree? Yes, this has a lot to do with these things.
The header (or no header) is completely specific to u-boot/armboot/ ppcboot.
As mentioned before the U-Boot header is just one way. If you prefer to have sections in an ELF file please look around - there are several examples that use such a technology.
Please try to get a bit a wider view on this topic than just from the point of view of your product and just ARM systems.
But for your application I don't see the need to change anything.
I still don't see a solution to using this existing format. You have
So let's get this straight:
I will NOT add support for your private "existing format" because with the same right support for a zilion of other private formats would have to be added, too.
I will not discuss this decision unless (1) you prove that the existing code (i.e. multifile images) cannot be used for the same purpose and (2) it turns out that adapting the multifile support code creates a bigger mess than adding support for your private image format.
argued it is a bad format, you have argued if you re-organize it it could be made to work. That doesn't make u-boot work with this simple existing format as it is.
No. But it solves your problem.
Changing the format opens lots of options for layout, but that is not what this discussion is about. Lets start another thread if anyone wants to talk about that.
OK. Feel free to start such a new thread (or actually to continue this one).
The other part of the discussion is complete. I will reject code to support your private image format, even if you submit it as board-specific code.
Sorry for not being clear about this, but this is what I wanted to tell you right from the beginning.
U-boot is not the only loader that is used, will be used, or has been used on this hardware in the past. Existing devices that rely on the old format (for their tftp loading of images) won't have their boot loaders changed. So changing to a different format is not really an option here.
Then provide two images depending on which boot loade ris used. I understand that your bootloader is capable of checking if an image is valid for this hardware or not?
You have changed the format now, so that is not a solution to the problem.
OK. OK. OK.
You don't want to change your image, I don't want to change U-Boot.
I offered you a compromise (and actually a more powerful solution than what you have now), you don't accept it. It's your decision.
(The reason I would hesitate to use this is that you have now set an arbitrary limit on the kernel size, and you are potentially wasting up to 256k of flash in this example. Ofcourse you could
Ther eis no such limit. This was an EXAMPLE only. Feel free to adjust sizes as needed - and oviously limited by sector boundaries of your flash memory. SInce the kernel has the partition map embedded the map can be adjusted with each new kernel version transparently.
come up with a clever mtd map that let you have any size kernel, but you are still wasting some flash).
Yes, of course we're wasting flash - we have to round up to the next sector boundary - but this is exactly the same amount of flash you lose in your configuratio - in your case it's just "free" (= unused) space after the combined image. There is not a single byte difference (assuming uniform flash sectors).
It is merely about some mechanism to support an additional format - that is all.
And I tell you again that I will not add support for any arbitrary defined new image format.
I am simply make these changes available to the community, and if they are useful to others, then great. Otherwise it just doesn't matter.
Then we've reached a point. You don't want to change anything. I cannot allow arbitray code bloat. Anybody looking for a solution for the problem itself will be able to implement this in the existing U-Boot framework, without need for special code or new commands or boot image formats.
End of this discussion.
Best regards,
Wolfgang Denk

Hi Wolfgang,
Wolfgang Denk wrote:
In message 42932848.7010704@moreton.com.au you wrote:
U-Boot uses multifile images for such a purpose. Please don't blame me if you ignored the existing solutions and came up with somthing different which causes problems (no working boot support).
This makes no sense, nobody ignored an exitsing u-boot solution, it did not exist yet!
Multifile images were added (to PPCBoot) in October 2000.
As far as I know the concat format was first used in 1999.
I don't understand this. This has nothing to do with init ramdisk on Linux. The Linux ramdisk setup doesn't at all care how the ramdisk
Did you check what happens when you run "make zImage.initrd" in a PowerPC Linux tree? Yes, this has a lot to do with these things.
The header (or no header) is completely specific to u-boot/armboot/ ppcboot.
As mentioned before the U-Boot header is just one way. If you prefer to have sections in an ELF file please look around - there are several examples that use such a technology.
Please try to get a bit a wider view on this topic than just from the point of view of your product and just ARM systems.
So powerpc does it. I have used on plenty of other architectures (x86, ARM, SuperH, Sparc, ColdFire, etc) I have never come across "make zImage.initrd".
I have used ELF sections before, suffers from the similar problems (and them some extra ones too).
But for your application I don't see the need to change anything.
I still don't see a solution to using this existing format. You have
So let's get this straight:
I will NOT add support for your private "existing format" because with the same right support for a zilion of other private formats would have to be added, too.
Please. I have already stated - not my format, and not private. I could argue that the u-boot multi-file format is provate to u-boot.
I will not discuss this decision unless (1) you prove that the existing code (i.e. multifile images) cannot be used for the same purpose and (2) it turns out that adapting the multifile support code creates a bigger mess than adding support for your private image format.
argued it is a bad format, you have argued if you re-organize it it could be made to work. That doesn't make u-boot work with this simple existing format as it is.
No. But it solves your problem.
No it doesn't. Sorry, the whole world is not u-boot.
come up with a clever mtd map that let you have any size kernel, but you are still wasting some flash).
Yes, of course we're wasting flash - we have to round up to the next sector boundary - but this is exactly the same amount of flash you lose in your configuratio - in your case it's just "free" (= unused) space after the combined image. There is not a single byte difference (assuming uniform flash sectors).
Wrong, there is a difference. You have some wasted space between the kernel and filesystem. The concat image doesn't. This will make a difference if you are cramped for flash space.
Example scenario, your layout:
FLASH SIZE 2MB (64k uniform flash segments)
u-boot size 85k --> 128k rounded --> 2 flash segments kernel zImage 722k --> 768k rounded --> 12 flash segments cramfs size 1180k --> 1216k rounded --> 19 flasg semgmets
This does not fit in the 32 flash segments available.
With concat (size = 722k + 1180k = 1902k):
u-boot size 85k --> 128k rounded --> 2 flash segments concat size 1902k --> 1920k rounded --> 30 flash segments
Fits in 32 flash segments.
Size is NOT the same. These sizes are real u-boot binary, kernel zImage and CRAMfs filesystem
Then we've reached a point. You don't want to change anything.
I am willing to change how this is done in u-boot, but I am not willing to change the file format. And I sure don't want to be tied to one header format supported by one boot loader.
I cannot allow arbitray code bloat. Anybody looking for a solution for the problem itself will be able to implement this in the existing U-Boot framework, without need for special code or new commands or boot image formats.
End of this discussion.
Yes.
Regards Greg
------------------------------------------------------------------------ Greg Ungerer -- Chief Software Dude EMAIL: gerg@snapgear.com SnapGear -- a CyberGuard Company PHONE: +61 7 3435 2888 825 Stanley St, FAX: +61 7 3891 3630 Woolloongabba, QLD, 4102, Australia WEB: http://www.SnapGear.com
participants (2)
-
Greg Ungerer
-
Wolfgang Denk