1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter.git synced 2025-03-09 15:40:20 +00:00

Kernel 5.4 RUTX support

This commit is contained in:
Ycarus (Yannick Chabanois) 2023-08-14 17:47:02 +02:00
parent 839fcf1cab
commit cfce9f52b2
7376 changed files with 3902 additions and 546 deletions

View file

@ -0,0 +1,19 @@
/bmp_logo
/envcrc
/gen_eth_addr
/img2srec
/dumpimage
/mkenvimage
/mkimage
/mpc86x_clk
/mxsboot
/ncb
/ncp
/ubsha1
/xway-swap-bytes
/*.exe
/easylogo/easylogo
/env/crc32.c
/env/fw_printenv
/gdb/gdbcont
/gdb/gdbsend

View file

@ -0,0 +1,303 @@
#
# (C) Copyright 2000-2006
# 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
#
TOOLSUBDIRS =
#
# Include this after HOSTOS HOSTARCH check
# so that we can act intelligently.
#
include $(TOPDIR)/config.mk
#
# toolchains targeting win32 generate .exe files
#
ifneq (,$(findstring WIN32 ,$(shell $(HOSTCC) -E -dM -xc /dev/null)))
SFX = .exe
else
SFX =
endif
# Enable all the config-independent tools
ifneq ($(HOST_TOOLS_ALL),)
CONFIG_LCD_LOGO = y
CONFIG_CMD_LOADS = y
CONFIG_CMD_NET = y
CONFIG_XWAY_SWAP_BYTES = y
CONFIG_NETCONSOLE = y
CONFIG_SHA1_CHECK_UB_IMG = y
endif
# Merge all the different vars for envcrc into one
ENVCRC-$(CONFIG_ENV_IS_EMBEDDED) = y
ENVCRC-$(CONFIG_ENV_IS_IN_DATAFLASH) = y
ENVCRC-$(CONFIG_ENV_IS_IN_EEPROM) = y
ENVCRC-$(CONFIG_ENV_IS_IN_FLASH) = y
ENVCRC-$(CONFIG_ENV_IS_IN_ONENAND) = y
ENVCRC-$(CONFIG_ENV_IS_IN_NAND) = y
ENVCRC-$(CONFIG_ENV_IS_IN_NVRAM) = y
ENVCRC-$(CONFIG_ENV_IS_IN_SPI_FLASH) = y
CONFIG_BUILD_ENVCRC ?= $(ENVCRC-y)
# Generated executable files
BIN_FILES-$(CONFIG_LCD_LOGO) += bmp_logo$(SFX)
BIN_FILES-$(CONFIG_VIDEO_LOGO) += bmp_logo$(SFX)
BIN_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc$(SFX)
BIN_FILES-$(CONFIG_CMD_NET) += gen_eth_addr$(SFX)
BIN_FILES-$(CONFIG_CMD_LOADS) += img2srec$(SFX)
BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX)
BIN_FILES-y += dumpimage$(SFX)
BIN_FILES-y += mkenvimage$(SFX)
BIN_FILES-y += mkimage$(SFX)
BIN_FILES-$(CONFIG_SMDK5250) += mksmdk5250spl$(SFX)
BIN_FILES-$(CONFIG_MX28) += mxsboot$(SFX)
BIN_FILES-$(CONFIG_NETCONSOLE) += ncb$(SFX)
BIN_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1$(SFX)
BIN_FILES-$(CONFIG_KIRKWOOD) += kwboot$(SFX)
# Source files which exist outside the tools directory
EXT_OBJ_FILES-$(CONFIG_BUILD_ENVCRC) += common/env_embedded.o
EXT_OBJ_FILES-y += common/image.o
EXT_OBJ_FILES-y += lib/crc32.o
EXT_OBJ_FILES-y += lib/md5.o
EXT_OBJ_FILES-y += lib/sha1.o
# Source files located in the tools directory
OBJ_FILES-$(CONFIG_LCD_LOGO) += bmp_logo.o
OBJ_FILES-$(CONFIG_VIDEO_LOGO) += bmp_logo.o
NOPED_OBJ_FILES-y += default_image.o
OBJ_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc.o
NOPED_OBJ_FILES-y += dumpimage.o
NOPED_OBJ_FILES-y += fit_image.o
OBJ_FILES-$(CONFIG_CMD_NET) += gen_eth_addr.o
OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o
OBJ_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes.o
NOPED_OBJ_FILES-y += aisimage.o
NOPED_OBJ_FILES-y += kwbimage.o
NOPED_OBJ_FILES-y += imagetool.o
NOPED_OBJ_FILES-y += imximage.o
NOPED_OBJ_FILES-y += omapimage.o
NOPED_OBJ_FILES-y += mkenvimage.o
NOPED_OBJ_FILES-y += mkimage.o
OBJ_FILES-$(CONFIG_SMDK5250) += mkexynosspl.o
OBJ_FILES-$(CONFIG_MX28) += mxsboot.o
OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o
NOPED_OBJ_FILES-y += os_support.o
OBJ_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1.o
NOPED_OBJ_FILES-y += ublimage.o
OBJ_FILES-$(CONFIG_KIRKWOOD) += kwboot.o
# Don't build by default
#ifeq ($(ARCH),ppc)
#BIN_FILES-y += mpc86x_clk$(SFX)
#OBJ_FILES-y += mpc86x_clk.o
#endif
# Flattened device tree objects
LIBFDT_OBJ_FILES-y += fdt.o
LIBFDT_OBJ_FILES-y += fdt_ro.o
LIBFDT_OBJ_FILES-y += fdt_rw.o
LIBFDT_OBJ_FILES-y += fdt_strerror.o
LIBFDT_OBJ_FILES-y += fdt_wip.o
# Generated LCD/video logo
LOGO_H = $(OBJTREE)/include/bmp_logo.h
LOGO_DATA_H = $(OBJTREE)/include/bmp_logo_data.h
LOGO-$(CONFIG_LCD_LOGO) += $(LOGO_H)
LOGO-$(CONFIG_LCD_LOGO) += $(LOGO_DATA_H)
LOGO-$(CONFIG_VIDEO_LOGO) += $(LOGO_H)
LOGO-$(CONFIG_VIDEO_LOGO) += $(LOGO_DATA_H)
ifeq ($(LOGO_BMP),)
LOGO_BMP= logos/denx.bmp
endif
ifeq ($(VENDOR),atmel)
LOGO_BMP= logos/atmel.bmp
endif
ifeq ($(VENDOR),esd)
LOGO_BMP= logos/esd.bmp
endif
ifeq ($(VENDOR),freescale)
LOGO_BMP= logos/freescale.bmp
endif
ifeq ($(VENDOR),ronetix)
LOGO_BMP= logos/ronetix.bmp
endif
ifeq ($(VENDOR),syteco)
LOGO_BMP= logos/syteco.bmp
endif
ifeq ($(VENDOR),intercontrol)
LOGO_BMP= logos/intercontrol.bmp
endif
# now $(obj) is defined
HOSTSRCS += $(addprefix $(SRCTREE)/,$(EXT_OBJ_FILES-y:.o=.c))
HOSTSRCS += $(addprefix $(SRCTREE)/tools/,$(OBJ_FILES-y:.o=.c))
HOSTSRCS += $(addprefix $(SRCTREE)/lib/libfdt/,$(LIBFDT_OBJ_FILES-y:.o=.c))
BINS := $(addprefix $(obj),$(sort $(BIN_FILES-y)))
LIBFDT_OBJS := $(addprefix $(obj),$(LIBFDT_OBJ_FILES-y))
HOSTOBJS := $(addprefix $(obj),$(OBJ_FILES-y))
NOPEDOBJS := $(addprefix $(obj),$(NOPED_OBJ_FILES-y))
#
# Use native tools and options
# Define __KERNEL_STRICT_NAMES to prevent typedef overlaps
#
HOSTCPPFLAGS = -idirafter $(SRCTREE)/include \
-idirafter $(OBJTREE)/include2 \
-idirafter $(OBJTREE)/include \
-I $(SRCTREE)/lib/libfdt \
-I $(SRCTREE)/tools \
-DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE) \
-DUSE_HOSTCC \
-D__KERNEL_STRICT_NAMES
all: $(obj).depend $(BINS) $(LOGO-y) subdirs
$(obj)bin2header$(SFX): $(obj)bin2header.o
@$(call compile,$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^)
@$(call compile,$(HOSTSTRIP) $@)
$(obj)bmp_logo$(SFX): $(obj)bmp_logo.o
@$(call compile,$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^)
@$(call compile,$(HOSTSTRIP) $@)
$(obj)envcrc$(SFX): $(obj)crc32.o $(obj)env_embedded.o $(obj)envcrc.o $(obj)sha1.o
@$(call compile,$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^)
$(obj)gen_eth_addr$(SFX): $(obj)gen_eth_addr.o
@$(call compile,$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^)
@$(call compile,$(HOSTSTRIP) $@)
$(obj)img2srec$(SFX): $(obj)img2srec.o
@$(call compile,$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^)
@$(call compile,$(HOSTSTRIP) $@)
$(obj)xway-swap-bytes$(SFX): $(obj)xway-swap-bytes.o
@$(call compile,$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^)
@$(call compile,$(HOSTSTRIP) $@)
$(obj)dumpimage$(SFX): $(obj)aisimage.o \
$(FIT_SIG_OBJS) \
$(obj)crc32.o \
$(obj)default_image.o \
$(obj)fit_image.o \
$(obj)image.o \
$(obj)imagetool.o \
$(obj)imximage.o \
$(obj)kwbimage.o \
$(obj)dumpimage.o \
$(obj)md5.o \
$(obj)omapimage.o \
$(obj)os_support.o \
$(obj)sha1.o \
$(obj)ublimage.o \
$(LIBFDT_OBJS) \
$(RSA_OBJS)
@$(call compile,$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) $(QSDK_CFLAGS) $(QSDK_LDFLAGS) -o $@ $^ $(HOSTLIBS))
@$(call compile,$(HOSTSTRIP) $@)
$(obj)mkenvimage$(SFX): $(obj)crc32.o $(obj)mkenvimage.o \
$(obj)os_support.o
@$(call compile,$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^)
@$(call compile,$(HOSTSTRIP) $@)
$(obj)mkimage$(SFX): $(obj)aisimage.o \
$(obj)crc32.o \
$(obj)default_image.o \
$(obj)fit_image.o \
$(obj)image.o \
$(obj)imagetool.o \
$(obj)imximage.o \
$(obj)kwbimage.o \
$(obj)md5.o \
$(obj)mkimage.o \
$(obj)os_support.o \
$(obj)omapimage.o \
$(obj)sha1.o \
$(obj)ublimage.o \
$(LIBFDT_OBJS)
@$(call compile,$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) $(QSDK_CFLAGS) $(QSDK_LDFLAGS) -o $@ $^)
@$(call compile,$(HOSTSTRIP) $@)
$(obj)mk$(BOARD)spl$(SFX): $(obj)mkexynosspl.o
@$(call compile,$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^)
@$(call compile,$(HOSTSTRIP) $@)
$(obj)mpc86x_clk$(SFX): $(obj)mpc86x_clk.o
@$(call compile,$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^)
@$(call compile,$(HOSTSTRIP) $@)
$(obj)mxsboot$(SFX): $(obj)mxsboot.o
@$(call compile,$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^)
@$(call compile,$(HOSTSTRIP) $@)
$(obj)ncb$(SFX): $(obj)ncb.o
@$(call compile,$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^)
@$(call compile,$(HOSTSTRIP) $@)
$(obj)ubsha1$(SFX): $(obj)os_support.o $(obj)sha1.o $(obj)ubsha1.o
@$(call compile,$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^)
$(obj)kwboot$(SFX): $(obj)kwboot.o
@$(call compile,$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^)
@$(call compile,$(HOSTSTRIP) $@)
# Some of the tool objects need to be accessed from outside the tools directory
$(obj)%.o: $(SRCTREE)/common/%.c
@$(call compile,$(HOSTCC) -g $(HOSTCFLAGS_NOPED) -c -o $@ $<)
$(obj)%.o: $(SRCTREE)/lib/%.c
@$(call compile,$(HOSTCC) -g $(HOSTCFLAGS) -c -o $@ $<)
$(obj)%.o: $(SRCTREE)/lib/libfdt/%.c
@$(call compile,$(HOSTCC) -g $(HOSTCFLAGS_NOPED) -c -o $@ $<)
subdirs:
ifeq ($(TOOLSUBDIRS),)
@:
else
@for dir in $(TOOLSUBDIRS) ; do \
$(MAKE) \
HOSTOS=$(HOSTOS) \
HOSTARCH=$(HOSTARCH) \
-C $$dir || exit 1 ; \
done
endif
$(LOGO_H): $(obj)bmp_logo $(LOGO_BMP)
$(obj)./bmp_logo --gen-info $(LOGO_BMP) > $@
$(LOGO_DATA_H): $(obj)bmp_logo $(LOGO_BMP)
$(obj)./bmp_logo --gen-data $(LOGO_BMP) > $@
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################

View file

@ -0,0 +1,451 @@
/*
* (C) Copyright 2011
* Stefano Babic, DENX Software Engineering, sbabic@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
*/
/* Required to obtain the getline prototype from stdio.h */
#define _GNU_SOURCE
#include "imagetool.h"
#include "aisimage.h"
#include <image.h>
#define IS_FNC_EXEC(c) (cmd_table[c].AIS_cmd == AIS_CMD_FNLOAD)
#define WORD_ALIGN0 4
#define WORD_ALIGN(len) (((len)+WORD_ALIGN0-1) & ~(WORD_ALIGN0-1))
#define MAX_CMD_BUFFER 4096
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
static uint32_t ais_img_size;
/*
* Supported commands for configuration file
*/
static table_entry_t aisimage_cmds[] = {
{CMD_DATA, "DATA", "Reg Write Data"},
{CMD_FILL, "FILL", "Fill range with pattern"},
{CMD_CRCON, "CRCON", "CRC Enable"},
{CMD_CRCOFF, "CRCOFF", "CRC Disable"},
{CMD_CRCCHECK, "CRCCHECK", "CRC Validate"},
{CMD_JMPCLOSE, "JMPCLOSE", "Jump & Close"},
{CMD_JMP, "JMP", "Jump"},
{CMD_SEQREAD, "SEQREAD", "Sequential read"},
{CMD_PLL0, "PLL0", "PLL0"},
{CMD_PLL1, "PLL1", "PLL1"},
{CMD_CLK, "CLK", "Clock configuration"},
{CMD_DDR2, "DDR2", "DDR2 Configuration"},
{CMD_EMIFA, "EMIFA", "EMIFA"},
{CMD_EMIFA_ASYNC, "EMIFA_ASYNC", "EMIFA Async"},
{CMD_PLL, "PLL", "PLL & Clock configuration"},
{CMD_PSC, "PSC", "PSC setup"},
{CMD_PINMUX, "PINMUX", "Pinmux setup"},
{CMD_BOOTTABLE, "BOOT_TABLE", "Boot table command"},
{-1, "", ""},
};
static struct ais_func_exec {
uint32_t index;
uint32_t argcnt;
} ais_func_table[] = {
[CMD_PLL0] = {0, 2},
[CMD_PLL1] = {1, 2},
[CMD_CLK] = {2, 1},
[CMD_DDR2] = {3, 8},
[CMD_EMIFA] = {4, 5},
[CMD_EMIFA_ASYNC] = {5, 5},
[CMD_PLL] = {6, 3},
[CMD_PSC] = {7, 1},
[CMD_PINMUX] = {8, 3}
};
static struct cmd_table_t {
uint32_t nargs;
uint32_t AIS_cmd;
} cmd_table[] = {
[CMD_FILL] = { 4, AIS_CMD_FILL},
[CMD_CRCON] = { 0, AIS_CMD_ENCRC},
[CMD_CRCOFF] = { 0, AIS_CMD_DISCRC},
[CMD_CRCCHECK] = { 2, AIS_CMD_ENCRC},
[CMD_JMPCLOSE] = { 1, AIS_CMD_JMPCLOSE},
[CMD_JMP] = { 1, AIS_CMD_JMP},
[CMD_SEQREAD] = { 0, AIS_CMD_SEQREAD},
[CMD_PLL0] = { 2, AIS_CMD_FNLOAD},
[CMD_PLL1] = { 2, AIS_CMD_FNLOAD},
[CMD_CLK] = { 1, AIS_CMD_FNLOAD},
[CMD_DDR2] = { 8, AIS_CMD_FNLOAD},
[CMD_EMIFA] = { 5, AIS_CMD_FNLOAD},
[CMD_EMIFA_ASYNC] = { 5, AIS_CMD_FNLOAD},
[CMD_PLL] = { 3, AIS_CMD_FNLOAD},
[CMD_PSC] = { 1, AIS_CMD_FNLOAD},
[CMD_PINMUX] = { 3, AIS_CMD_FNLOAD},
[CMD_BOOTTABLE] = { 4, AIS_CMD_BOOTTBL},
};
static uint32_t get_cfg_value(char *token, char *name, int linenr)
{
char *endptr;
uint32_t value;
errno = 0;
value = strtoul(token, &endptr, 16);
if (errno || (token == endptr)) {
fprintf(stderr, "Error: %s[%d] - Invalid hex data(%s)\n",
name, linenr, token);
exit(EXIT_FAILURE);
}
return value;
}
static int get_ais_table_id(uint32_t *ptr)
{
int i;
int func_no;
for (i = 0; i < ARRAY_SIZE(cmd_table); i++) {
if (*ptr == cmd_table[i].AIS_cmd) {
if (cmd_table[i].AIS_cmd != AIS_CMD_FNLOAD)
return i;
func_no = ((struct ais_cmd_func *)ptr)->func_args
& 0xFFFF;
if (func_no == ais_func_table[i].index)
return i;
}
}
return -1;
}
static void aisimage_print_header(const void *hdr)
{
struct ais_header *ais_hdr = (struct ais_header *)hdr;
uint32_t *ptr;
struct ais_cmd_load *ais_load;
int id;
if (ais_hdr->magic != AIS_MAGIC_WORD) {
fprintf(stderr, "Error: - AIS Magic Number not found\n");
return;
}
fprintf(stdout, "Image Type: TI Davinci AIS Boot Image\n");
fprintf(stdout, "AIS magic : %08x\n", ais_hdr->magic);
ptr = (uint32_t *)&ais_hdr->magic;
ptr++;
while (*ptr != AIS_CMD_JMPCLOSE) {
/* Check if we find the image */
if (*ptr == AIS_CMD_LOAD) {
ais_load = (struct ais_cmd_load *)ptr;
fprintf(stdout, "Image at : 0x%08x size 0x%08x\n",
ais_load->addr,
ais_load->size);
ptr = ais_load->data + ais_load->size / sizeof(*ptr);
continue;
}
id = get_ais_table_id(ptr);
if (id < 0) {
fprintf(stderr, "Error: - AIS Image corrupted\n");
return;
}
fprintf(stdout, "AIS cmd : %s\n",
get_table_entry_name(aisimage_cmds, NULL, id));
ptr += cmd_table[id].nargs + IS_FNC_EXEC(id) + 1;
if (((void *)ptr - hdr) > ais_img_size) {
fprintf(stderr,
"AIS Image not terminated by JMPCLOSE\n");
return;
}
}
}
static uint32_t *ais_insert_cmd_header(uint32_t cmd, uint32_t nargs,
uint32_t *parms, struct image_type_params *tparams,
uint32_t *ptr)
{
int i;
*ptr++ = cmd_table[cmd].AIS_cmd;
if (IS_FNC_EXEC(cmd))
*ptr++ = ((nargs & 0xFFFF) << 16) + ais_func_table[cmd].index;
/* Copy parameters */
for (i = 0; i < nargs; i++)
*ptr++ = cpu_to_le32(parms[i]);
return ptr;
}
static uint32_t *ais_alloc_buffer(struct image_tool_params *params)
{
int dfd;
struct stat sbuf;
char *datafile = params->datafile;
uint32_t *ptr;
dfd = open(datafile, O_RDONLY|O_BINARY);
if (dfd < 0) {
fprintf(stderr, "%s: Can't open %s: %s\n",
params->cmdname, datafile, strerror(errno));
exit(EXIT_FAILURE);
}
if (fstat(dfd, &sbuf) < 0) {
fprintf(stderr, "%s: Can't stat %s: %s\n",
params->cmdname, datafile, strerror(errno));
exit(EXIT_FAILURE);
}
/*
* Place for header is allocated. The size is taken from
* the size of the datafile, that the ais_image_generate()
* will copy into the header. Copying the datafile
* is not left to the main program, because after the datafile
* the header must be terminated with the Jump & Close command.
*/
ais_img_size = WORD_ALIGN(sbuf.st_size) + MAX_CMD_BUFFER;
ptr = (uint32_t *)malloc(WORD_ALIGN(sbuf.st_size) + MAX_CMD_BUFFER);
if (!ptr) {
fprintf(stderr, "%s: malloc return failure: %s\n",
params->cmdname, strerror(errno));
exit(EXIT_FAILURE);
}
close(dfd);
return ptr;
}
static uint32_t *ais_copy_image(struct image_tool_params *params,
uint32_t *aisptr)
{
int dfd;
struct stat sbuf;
char *datafile = params->datafile;
void *ptr;
dfd = open(datafile, O_RDONLY|O_BINARY);
if (dfd < 0) {
fprintf(stderr, "%s: Can't open %s: %s\n",
params->cmdname, datafile, strerror(errno));
exit(EXIT_FAILURE);
}
if (fstat(dfd, &sbuf) < 0) {
fprintf(stderr, "%s: Can't stat %s: %s\n",
params->cmdname, datafile, strerror(errno));
exit(EXIT_FAILURE);
}
ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, dfd, 0);
*aisptr++ = AIS_CMD_LOAD;
*aisptr++ = params->ep;
*aisptr++ = sbuf.st_size;
memcpy((void *)aisptr, ptr, sbuf.st_size);
aisptr += WORD_ALIGN(sbuf.st_size) / sizeof(uint32_t);
(void) munmap((void *)ptr, sbuf.st_size);
(void) close(dfd);
return aisptr;
}
static int aisimage_generate(struct image_tool_params *params,
struct image_type_params *tparams)
{
FILE *fd = NULL;
char *line = NULL;
char *token, *saveptr1, *saveptr2;
int lineno = 0;
int fld;
size_t len;
int32_t cmd;
uint32_t nargs, cmd_parms[10];
uint32_t value, size;
char *name = params->imagename;
uint32_t *aishdr;
fd = fopen(name, "r");
if (fd == 0) {
fprintf(stderr,
"Error: %s - Can't open AIS configuration\n", name);
exit(EXIT_FAILURE);
}
/*
* the size of the header is variable and is computed
* scanning the configuration file.
*/
tparams->header_size = 0;
/*
* Start allocating a buffer suitable for most command
* The buffer is then reallocated if it is too small
*/
aishdr = ais_alloc_buffer(params);
tparams->hdr = aishdr;
*aishdr++ = AIS_MAGIC_WORD;
/* Very simple parsing, line starting with # are comments
* and are dropped
*/
while ((getline(&line, &len, fd)) > 0) {
lineno++;
token = strtok_r(line, "\r\n", &saveptr1);
if (token == NULL)
continue;
/* Check inside the single line */
line = token;
fld = CFG_COMMAND;
cmd = CMD_INVALID;
nargs = 0;
while (token != NULL) {
token = strtok_r(line, " \t", &saveptr2);
if (token == NULL)
break;
/* Drop all text starting with '#' as comments */
if (token[0] == '#')
break;
switch (fld) {
case CFG_COMMAND:
cmd = get_table_entry_id(aisimage_cmds,
"aisimage commands", token);
if (cmd < 0) {
fprintf(stderr,
"Error: %s[%d] - Invalid command"
"(%s)\n", name, lineno, token);
exit(EXIT_FAILURE);
}
break;
case CFG_VALUE:
value = get_cfg_value(token, name, lineno);
cmd_parms[nargs++] = value;
if (nargs > cmd_table[cmd].nargs) {
fprintf(stderr,
"Error: %s[%d] - too much arguments:"
"(%s) for command %s\n", name,
lineno, token,
aisimage_cmds[cmd].sname);
exit(EXIT_FAILURE);
}
break;
}
line = NULL;
fld = CFG_VALUE;
}
if (cmd != CMD_INVALID) {
/* Now insert the command into the header */
aishdr = ais_insert_cmd_header(cmd, nargs, cmd_parms,
tparams, aishdr);
}
}
fclose(fd);
aishdr = ais_copy_image(params, aishdr);
/* Add Jmp & Close */
*aishdr++ = AIS_CMD_JMPCLOSE;
*aishdr++ = params->ep;
size = (aishdr - (uint32_t *)tparams->hdr) * sizeof(uint32_t);
tparams->header_size = size;
return 0;
}
static int aisimage_check_image_types(uint8_t type)
{
if (type == IH_TYPE_AISIMAGE)
return EXIT_SUCCESS;
else
return EXIT_FAILURE;
}
static int aisimage_verify_header(unsigned char *ptr, int image_size,
struct image_tool_params *params)
{
struct ais_header *ais_hdr = (struct ais_header *)ptr;
if (ais_hdr->magic != AIS_MAGIC_WORD)
return -FDT_ERR_BADSTRUCTURE;
/* Store the total size to remember in print_hdr */
ais_img_size = image_size;
return 0;
}
static void aisimage_set_header(void *ptr, struct stat *sbuf, int ifd,
struct image_tool_params *params)
{
}
int aisimage_check_params(struct image_tool_params *params)
{
if (!params)
return CFG_INVALID;
if (!strlen(params->imagename)) {
fprintf(stderr, "Error: %s - Configuration file not specified, "
"it is needed for aisimage generation\n",
params->cmdname);
return CFG_INVALID;
}
/*
* Check parameters:
* XIP is not allowed and verify that incompatible
* parameters are not sent at the same time
* For example, if list is required a data image must not be provided
*/
return (params->dflag && (params->fflag || params->lflag)) ||
(params->fflag && (params->dflag || params->lflag)) ||
(params->lflag && (params->dflag || params->fflag)) ||
(params->xflag) || !(strlen(params->imagename));
}
/*
* aisimage parameters
*/
static struct image_type_params aisimage_params = {
.name = "TI Davinci AIS Boot Image support",
.header_size = 0,
.hdr = NULL,
.check_image_type = aisimage_check_image_types,
.verify_header = aisimage_verify_header,
.print_header = aisimage_print_header,
.set_header = aisimage_set_header,
.check_params = aisimage_check_params,
.vrec_header = aisimage_generate,
};
void init_ais_image_type(void)
{
register_image_type(&aisimage_params);
}

View file

@ -0,0 +1,97 @@
/*
* (C) Copyright 2011
* Stefano Babic, DENX Software Engineering, sbabic@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 _AISIMAGE_H_
#define _AISIMAGE_H_
/* all values are for little endian systems */
#define AIS_MAGIC_WORD 0x41504954
#define AIS_FCN_MAX 8
enum {
AIS_CMD_LOAD = 0x58535901,
AIS_CMD_VALCRC = 0x58535902,
AIS_CMD_ENCRC = 0x58535903,
AIS_CMD_DISCRC = 0x58535904,
AIS_CMD_JMP = 0x58535905,
AIS_CMD_JMPCLOSE = 0x58535906,
AIS_CMD_BOOTTBL = 0x58535907,
AIS_CMD_FILL = 0x5853590A,
AIS_CMD_FNLOAD = 0x5853590D,
AIS_CMD_SEQREAD = 0x58535963,
};
struct ais_cmd_load {
uint32_t cmd;
uint32_t addr;
uint32_t size;
uint32_t data[1];
};
struct ais_cmd_func {
uint32_t cmd;
uint32_t func_args;
uint32_t parms[AIS_FCN_MAX];
};
struct ais_cmd_jmpclose {
uint32_t cmd;
uint32_t addr;
};
#define CMD_DATA_STR "DATA"
enum ais_file_cmd {
CMD_INVALID,
CMD_FILL,
CMD_CRCON,
CMD_CRCOFF,
CMD_CRCCHECK,
CMD_JMPCLOSE,
CMD_JMP,
CMD_SEQREAD,
CMD_DATA,
CMD_PLL0,
CMD_PLL1,
CMD_CLK,
CMD_DDR2,
CMD_EMIFA,
CMD_EMIFA_ASYNC,
CMD_PLL,
CMD_PSC,
CMD_PINMUX,
CMD_BOOTTABLE
};
enum aisimage_fld_types {
CFG_INVALID = -1,
CFG_COMMAND,
CFG_VALUE,
};
struct ais_header {
uint32_t magic;
char data[1];
};
#endif /* _AISIMAGE_H_ */

View file

@ -0,0 +1,116 @@
Hymod Board Database
(C) Copyright 2001
Murray Jensen <Murray.Jensen@csiro.au>
CSIRO Manufacturing Science and Technology, Preston Lab
25-Jun-01
This stuff is a set of PHP/MySQL scripts to implement a custom board
database. It will need *extensive* hacking to modify it to keep the
information about your custom boards that you want, however it is a good
starting point.
How it is used:
1. a board has gone through all the hardware testing etc and is
ready to have the flash programmed for the first time - first you
go to a web page and fill in information about the board in a form
to register it in a database
2. the web stuff allocates a (unique) serial number and (optionally)
a (locally administered) ethernet address and stores the information
in a database using the serial number as the key (can do whole
batches of boards in one go and/or use a previously registered board
as defaults for the new board(s))
3. it then creates a file in the tftp area of a server somewhere
containing the board information in a simple text format (one
per serial number)
4. all hymod boards have an i2c eeprom, and when U-Boot sees that
the eeprom is unitialised, it prompts for a serial number and
ethernet address (if not set), then transfers the file created
in step 3 from the server and initialises the eeprom from its
contents
What this means is you can't boot the board until you have allocated a serial
number, but you don't have to type it all twice - you do it once on the web
and the board then finds the info it needs to initialise its eeprom. The
other side of the coin is the reading of the eeprom and how it gets passed
to Linux (or another O/S).
To see how this is all done for the hymod boards look at the code in the
"board/hymod" directory and in the file "include/asm/hymod.h". Hymod boards
can have a mezzanine card which also have an eeprom that needs allocating,
the same process is used for these as well - just a different i2c address.
Other forms provide the following functions:
- browsing the board database
- editing board information (one at a time)
- maintaining/browsing a (simple) per board event log
You will need: MySQL (I use version 3.23.7-alpha), PHP4 (with MySQL
support enabled) and a web server (I use Apache 1.3.x).
I originally started by using phpMyBuilder (http://kyber.dk/phpMyBuilder)
but it soon got far more complicated than that could handle (but I left
the copyright messages in there anyway). Most of the code resides in the
common defs.php file, which shouldn't need much alteration - all the work
will be in shaping the front-end php files to your liking.
Here's a quick summary of what needs doing to use it for your boards:
1. get phpMyAdmin (http://phpwizard.net/projects/phpMyAdmin/) - it's an
invaluable tool for this sort of stuff (this step is optional of course)
2. edit "bddb.css" to your taste, if you could be bothered - I have no
idea what is in there or what it does - I copied it from somewhere else
("user.css" from the phpMyEdit (http://phpmyedit.sourcerforge.net) package,
I think) - I figure one day I'll see what sort of things I can change
in there.
3. create a mysql database - call it whatever you like
4. edit "create_tables.sql" and modify the "boards" table schema to
reflect the information you want to keep about your boards. It may or
may not be easier to do this and the next step in phpMyAdmin. Check out
the MySQL documentation at http://www.mysql.com/doc/ in particular the
column types at http://www.mysql.com/doc/C/o/Column_types.html - Note
there is only support for a few data types:
int - presented as an html text input
char/text - presented as an html text input
date - presented as an html text input
enum - presented as an html radio input
I also have what I call "enum_multi" which is a set of enums with the
same name, but suffixed with a number e.g. fred0, fred1, fred2. These
are presented as a number of html select's with a single label "fred"
this is useful for board characteristics that have multiple items of
the same type e.g. multiple banks of sdram.
5. use the "create_tables.sql" file to create the "boards" table in the
database e.g. mysql dbname < create_tables.sql
6. create a user and password for the web server to log into the MySQL
database with; give this user select, insert and update privileges
to the database created in 3 (and delete, if you want the "delete"
functions in the edit forms to work- I have this turned off). phpMyAdmin
helps in this step.
7. edit "config.php" and set the variables: $mysql_user, $mysql_pw, $mysql_db,
$bddb_cfgdir and $bddb_label - keep the contents of this file secret - it
contains the web servers username and password (the three $mysql_* vars
are set from the previous step)
8. edit "defs.php" and a. adjust the various enum value arrays and b. edit
the function "pg_foot()" to remove my email address :-)
9. do major hacking on the following files: browse.php, doedit.php, donew.php,
edit.php and new.php to reflect your database schema - fortunately the
hacking is fairly straight-forward, but it is boring and time-consuming.
These notes were written rather hastily - if you find any obvious problems
please let me know.

View file

@ -0,0 +1,23 @@
<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?>
<?php
// (C) Copyright 2001
// Murray Jensen <Murray.Jensen@csiro.au>
// CSIRO Manufacturing Science and Technology, Preston Lab
require("defs.php");
pg_head("$bddb_label - Unknown Submit Type");
?>
<center>
<font size="+4">
<b>
The <?php echo "$bddb_label"; ?> form was submitted with an
unknown SUBMIT type <?php echo "(value was '$submit')" ?>.
<br></br>
Perhaps you typed the URL in directly? Click here to go to the
home page of the <a href="index.php"><?php echo "$bddb_label"; ?></a>.
</b>
</font>
</center>
<?php
pg_foot();
?>

View file

@ -0,0 +1,207 @@
BODY {
background: #e0ffff;
color: #000000;
font-family: Arial, Verdana, Helvetica;
}
H1 {
font-family: "Copperplate Gothic Bold";
background: transparent;
color: #993300;
text-align: center;
}
H2, H3, H4, H5 {
background: transparent;
color: #993300;
margin-top: 4%;
text-align: center;
}
Body.Plain Div.Abstract, Body.Plain P.Abstract {
background: #cccc99;
color: #333300;
border: white;
padding: 3%;
font-family: Times, Verdana;
}
TH.Nav {
background: #0000cc;
color: #ff9900;
}
TH.Menu {
background: #3366cc;
color: #ff9900;
}
A:hover {
color: #ff6600;
}
A.Menu:hover {
color: #ff6600;
}
A.HoMe:hover {
color: #ff6600;
}
A.Menu {
background: transparent;
color: #ffcc33;
font-family: Verdana, Helvetica, Arial;
font-size: smaller;
text-decoration: none;
}
A.Menu:visited {
background: transparent;
color: #ffcc99;
}
A.HoMe {
background: transparent;
color: #ffcc33;
font-family: Verdana, Helvetica, Arial;
text-decoration:none;
}
A.HoMe:visited {
background: transparent;
color: #ffcc99;
}
TH.Xmp {
background: #eeeeee;
color: #330066;
font-family: courier;
font-weight: normal;
}
TH.LuT {
background: #cccccc;
color: #000000;
}
TD.LuT {
background: #ffffcc;
color: #000000;
font-size: 85%;
}
TH.Info, TD.Info {
background: #ffffcc;
color: #660000;
font-family: "Comic Sans MS", Cursive, Verdana;
font-size: smaller;
}
Div.Info, P.Info {
background: #ffff99;
color: #990033;
text-align: left;
padding: 2%;
font-family: "Comic Sans MS", Cursive, Verdana;
font-size: 85%;
}
Div.Info A {
background: transparent;
color: #ff6600;
}
.HL {
background: #ffff99;
color: #000000;
}
TD.HL {
background: #ccffff;
color: #000000;
}
Div.Margins {
width: 512px;
text-align: center;
}
TD.Plain {
background: #ffffcc;
color: #000033;
}
.Type {
background: #cccccc;
color: #660000;
}
.Name {
background: #eeeeee;
color: #660000;
vertical-align: top;
text-align: right;
}
.Value {
background: #ffffee;
color: #000066;
}
.Drop {
background: #333366;
color: #ffcc33;
font-family: "Copperplate Gothic Light", Helvetica, Verdana, Arial;
}
A.Button:hover {
color: #ff6600;
}
A.Button {
text-decoration:none;
color: #003366;
background: #ffcc66;
}
.Button {
font-size: 9pt;
text-align: center;
text-decoration:none;
color: #003366;
background: #ffcc66;
margin-bottom: 2pt;
border-top: 2px solid #ffff99;
border-left: 2px solid #ffff99;
border-right: 2px solid #cc9933;
border-bottom: 2px solid #cc9933;
font-family: Verdana, Arial, "Comic Sans MS";
}
.Banner {
width: 468;
font-size: 12pt;
text-align: center;
text-decoration:none;
color: #003366;
background: #ffcc66;
border-top: 4px solid #ffff99;
border-left: 4px solid #ffff99;
border-right: 4px solid #cc9933;
border-bottom: 4px solid #cc9933;
font-family: Verdana, Arial, "Comic Sans MS";
}
TD.Nova, Body.Nova {
background: #000000;
font-family: "Times New Roman";
font-weight: light;
color: #ffcc00;
}
Body.Nova A.Button {
background: gold;
color: #003366;
}
Body.Nova A.Banner {
background: transparent;
color: #003366;
}
Body.Nova A {
background: transparent;
text-decoration:none;
color: #ffd766;
}
Body.Nova H1, Body.Nova H2, Body.Nova H3, Body.Nova H4 {
background: transparent;
color: white;
margin-top: 4%;
text-align: center;
filter: Blur(Add=1, Direction=0, Strength=8);
}
Body.Nova Div.Abstract {
background: #000000;
color: #ffffff;
font-family: Times, Verdana;
}
Body.Nova A.Abstract {
background: transparent;
color: #ffeedd;
}
Body.Nova TH.LuT {
background: black;
color: #ffff99;
}
Body.Nova TD.LuT {
background: navy;
color: #ffff99;
}

View file

@ -0,0 +1,109 @@
<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?>
<?php
// (C) Copyright 2001
// Murray Jensen <Murray.Jensen@csiro.au>
// CSIRO Manufacturing Science and Technology, Preston Lab
// list page (hymod_bddb / boards)
require("defs.php");
pg_head("$bddb_label - Browse Board Log");
$serno=intval($serno);
if ($serno == 0)
die("serial number not specified or invalid!");
function print_cell($str) {
if ($str == '')
$str = '&nbsp;';
echo "\t<td>$str</td>\n";
}
?>
<table align=center border=1 cellpadding=10>
<tr>
<th>serno / edit</th>
<th>ethaddr</th>
<th>date</th>
<th>batch</th>
<th>type</th>
<th>rev</th>
<th>location</th>
</tr>
<?php
$r=mysql_query("select * from boards where serno=$serno");
while($row=mysql_fetch_array($r)){
foreach ($columns as $key) {
if (!key_in_array($key, $row))
$row[$key] = '';
}
echo "<tr>\n";
print_cell("<a href=\"edit.php?serno=$row[serno]\">$row[serno]</a>");
print_cell($row['ethaddr']);
print_cell($row['date']);
print_cell($row['batch']);
print_cell($row['type']);
print_cell($row['rev']);
print_cell($row['location']);
echo "</tr>\n";
}
mysql_free_result($r);
?>
</table>
<hr></hr>
<p></p>
<?php
$limit=abs(isset($_REQUEST['limit'])?$_REQUEST['limit']:20);
$offset=abs(isset($_REQUEST['offset'])?$_REQUEST['offset']:0);
$lr=mysql_query("select count(*) as n from log where serno=$serno");
$lrow=mysql_fetch_array($lr);
if($lrow['n']>$limit){
$preoffset=max(0,$offset-$limit);
$postoffset=$offset+$limit;
echo "<table width=\"100%\">\n<tr align=center>\n";
printf("<td><%sa href=\"%s?submit=Log&serno=$serno&offset=%d\"><img border=0 alt=\"&lt;\" src=\"/icons/left.gif\"></a></td>\n", $offset>0?"":"no", $PHP_SELF, $preoffset);
printf("<td><%sa href=\"%s?submit=Log&serno=$serno&offset=%d\"><img border=0 alt=\"&gt;\" src=\"/icons/right.gif\"></a></td>\n", $postoffset<$lrow['n']?"":"no", $PHP_SELF, $postoffset);
echo "</tr>\n</table>\n";
}
mysql_free_result($lr);
?>
<table width="100%" border=1 cellpadding=10>
<tr valign=top>
<th>logno / edit</th>
<th>date</th>
<th>who</th>
<th width="70%">details</th>
</tr>
<?php
$r=mysql_query("select * from log where serno=$serno order by logno limit $offset,$limit");
while($row=mysql_fetch_array($r)){
echo "<tr>\n";
print_cell("<a href=\"edlog.php?serno=$row[serno]&logno=$row[logno]\">$row[logno]</a>");
print_cell($row['date']);
print_cell($row['who']);
print_cell("<pre>" . urldecode($row['details']) . "</pre>");
echo "</tr>\n";
}
mysql_free_result($r);
?>
</table>
<hr></hr>
<p></p>
<table width="100%">
<tr>
<td align=center>
<a href="newlog.php?serno=<?php echo "$serno"; ?>">Add to Log</a>
</td>
<td align=center>
<a href="index.php">Back to Start</a>
</td>
</tr>
</table>
<?php
pg_foot();
?>

View file

@ -0,0 +1,147 @@
<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?>
<?php
// (C) Copyright 2001
// Murray Jensen <Murray.Jensen@csiro.au>
// CSIRO Manufacturing Science and Technology, Preston Lab
// list page (hymod_bddb / boards)
require("defs.php");
$serno=isset($_REQUEST['serno'])?$_REQUEST['serno']:'';
$verbose=isset($_REQUEST['verbose'])?intval($_REQUEST['verbose']):0;
pg_head("$bddb_label - Browse database" . ($verbose?" (verbose)":""));
?>
<p></p>
<?php
$limit=isset($_REQUEST['limit'])?abs(intval($_REQUEST['limit'])):20;
$offset=isset($_REQUEST['offset'])?abs(intval($_REQUEST['offset'])):0;
if ($serno == '') {
$lr=mysql_query("select count(*) as n from boards");
$lrow=mysql_fetch_array($lr);
if($lrow['n']>$limit){
$preoffset=max(0,$offset-$limit);
$postoffset=$offset+$limit;
echo "<table width=\"100%\">\n<tr>\n";
printf("<td align=left><%sa href=\"%s?submit=Browse&offset=%d&verbose=%d\"><img border=0 alt=\"&lt;\" src=\"/icons/left.gif\"></a></td>\n", $offset>0?"":"no", $PHP_SELF, $preoffset, $verbose);
printf("<td align=right><%sa href=\"%s?submit=Browse&offset=%d&verbose=%d\"><img border=0 alt=\"&gt;\" src=\"/icons/right.gif\"></a></td>\n", $postoffset<$lrow['n']?"":"no", $PHP_SELF, $postoffset, $offset);
echo "</tr>\n</table>\n";
}
mysql_free_result($lr);
}
?>
<table align=center border=1 cellpadding=10>
<tr>
<th></th>
<th>serno / edit</th>
<th>ethaddr</th>
<th>date</th>
<th>batch</th>
<th>type</th>
<th>rev</th>
<th>location</th>
<?php
if ($verbose) {
echo "<th>comments</th>\n";
echo "<th>sdram</th>\n";
echo "<th>flash</th>\n";
echo "<th>zbt</th>\n";
echo "<th>xlxtyp</th>\n";
echo "<th>xlxspd</th>\n";
echo "<th>xlxtmp</th>\n";
echo "<th>xlxgrd</th>\n";
echo "<th>cputyp</th>\n";
echo "<th>cpuspd</th>\n";
echo "<th>cpmspd</th>\n";
echo "<th>busspd</th>\n";
echo "<th>hstype</th>\n";
echo "<th>hschin</th>\n";
echo "<th>hschout</th>\n";
}
?>
</tr>
<?php
$query = "select * from boards";
if ($serno != '') {
$pre = " where ";
foreach (preg_split("/[\s,]+/", $serno) as $s) {
if (preg_match('/^[0-9]+$/',$s))
$query .= $pre . "serno=" . $s;
else if (preg_match('/^([0-9]+)-([0-9]+)$/',$s,$m)) {
$m1 = intval($m[1]); $m2 = intval($m[2]);
if ($m2 <= $m1)
die("bad serial number range ($s)");
$query .= $pre . "(serno>=$m[1] and serno<=$m[2])";
}
else
die("illegal serial number ($s)");
$pre = " or ";
}
}
$query .= " order by serno";
if ($serno == '')
$query .= " limit $offset,$limit";
$r = mysql_query($query);
function print_cell($str) {
if ($str == '')
$str = '&nbsp;';
echo "\t<td>$str</td>\n";
}
while($row=mysql_fetch_array($r)){
foreach ($columns as $key) {
if (!key_in_array($key, $row))
$row[$key] = '';
}
echo "<tr>\n";
print_cell("<a href=\"brlog.php?serno=$row[serno]\">Log</a>");
print_cell("<a href=\"edit.php?serno=$row[serno]\">$row[serno]</a>");
print_cell($row['ethaddr']);
print_cell($row['date']);
print_cell($row['batch']);
print_cell($row['type']);
print_cell($row['rev']);
print_cell($row['location']);
if ($verbose) {
print_cell("<pre>\n" . urldecode($row['comments']) .
"\n\t</pre>");
print_cell(gather_enum_multi_print("sdram", 4, $row));
print_cell(gather_enum_multi_print("flash", 4, $row));
print_cell(gather_enum_multi_print("zbt", 16, $row));
print_cell(gather_enum_multi_print("xlxtyp", 4, $row));
print_cell(gather_enum_multi_print("xlxspd", 4, $row));
print_cell(gather_enum_multi_print("xlxtmp", 4, $row));
print_cell(gather_enum_multi_print("xlxgrd", 4, $row));
print_cell($row['cputyp']);
print_cell($row['cpuspd']);
print_cell($row['cpmspd']);
print_cell($row['busspd']);
print_cell($row['hstype']);
print_cell($row['hschin']);
print_cell($row['hschout']);
}
echo "</tr>\n";
}
?>
</table>
<p></p>
<table width="100%">
<tr>
<td align=center><?php
printf("<a href=\"%s?submit=Browse&offset=%d&verbose=%d%s\">%s Listing</a>\n", $PHP_SELF, $offset, $verbose?0:1, $serno!=''?"&serno=$serno":'', $verbose?"Terse":"Verbose");
?></td>
<td align=center><a href="index.php">Back to Start</a></td>
</tr>
</table>
<?php
pg_foot();
?>

View file

@ -0,0 +1,16 @@
<?php
// (C) Copyright 2001
// Murray Jensen <Murray.Jensen@csiro.au>
// CSIRO Manufacturing Science and Technology, Preston Lab
// mysql database access info
$mysql_user="fred";
$mysql_pw="apassword";
$mysql_db="mydbname";
// where to put the eeprom config files
$bddb_cfgdir = '/tftpboot/bddb';
// what this database is called
$bddb_label = 'Hymod Board Database';
?>

View file

@ -0,0 +1,90 @@
# phpMyAdmin MySQL-Dump
# http://phpwizard.net/phpMyAdmin/
#
# Host: localhost Database : hymod_bddb
# (C) Copyright 2001
# Murray Jensen <Murray.Jensen@csiro.au>
# CSIRO Manufacturing and Infrastructure Technology, Preston Lab
# --------------------------------------------------------
#
# Table structure for table 'boards'
#
DROP TABLE IF EXISTS boards;
CREATE TABLE boards (
serno int(10) unsigned zerofill NOT NULL auto_increment,
ethaddr char(17),
date date NOT NULL,
batch char(32),
type enum('IO','CLP','DSP','INPUT','ALT-INPUT','DISPLAY') NOT NULL,
rev tinyint(3) unsigned zerofill NOT NULL,
location char(64),
comments text,
sdram0 enum('32M','64M','128M','256M','512M','1G','2G','4G'),
sdram1 enum('32M','64M','128M','256M','512M','1G','2G','4G'),
sdram2 enum('32M','64M','128M','256M','512M','1G','2G','4G'),
sdram3 enum('32M','64M','128M','256M','512M','1G','2G','4G'),
flash0 enum('4M','8M','16M','32M','64M','128M','256M','512M','1G'),
flash1 enum('4M','8M','16M','32M','64M','128M','256M','512M','1G'),
flash2 enum('4M','8M','16M','32M','64M','128M','256M','512M','1G'),
flash3 enum('4M','8M','16M','32M','64M','128M','256M','512M','1G'),
zbt0 enum('512K','1M','2M','4M','8M','16M'),
zbt1 enum('512K','1M','2M','4M','8M','16M'),
zbt2 enum('512K','1M','2M','4M','8M','16M'),
zbt3 enum('512K','1M','2M','4M','8M','16M'),
zbt4 enum('512K','1M','2M','4M','8M','16M'),
zbt5 enum('512K','1M','2M','4M','8M','16M'),
zbt6 enum('512K','1M','2M','4M','8M','16M'),
zbt7 enum('512K','1M','2M','4M','8M','16M'),
zbt8 enum('512K','1M','2M','4M','8M','16M'),
zbt9 enum('512K','1M','2M','4M','8M','16M'),
zbta enum('512K','1M','2M','4M','8M','16M'),
zbtb enum('512K','1M','2M','4M','8M','16M'),
zbtc enum('512K','1M','2M','4M','8M','16M'),
zbtd enum('512K','1M','2M','4M','8M','16M'),
zbte enum('512K','1M','2M','4M','8M','16M'),
zbtf enum('512K','1M','2M','4M','8M','16M'),
xlxtyp0 enum('XCV300E','XCV400E','XCV600E','XC2V2000','XC2V3000','XC2V4000','XC2V6000','XC2VP2','XC2VP4','XC2VP7','XC2VP20','XC2VP30','XC2VP50','XC4VFX20','XC4VFX40','XC4VFX60','XC4VFX100','XC4VFX140'),
xlxtyp1 enum('XCV300E','XCV400E','XCV600E','XC2V2000','XC2V3000','XC2V4000','XC2V6000','XC2VP2','XC2VP4','XC2VP7','XC2VP20','XC2VP30','XC2VP50','XC4VFX20','XC4VFX40','XC4VFX60','XC4VFX100','XC4VFX140'),
xlxtyp2 enum('XCV300E','XCV400E','XCV600E','XC2V2000','XC2V3000','XC2V4000','XC2V6000','XC2VP2','XC2VP4','XC2VP7','XC2VP20','XC2VP30','XC2VP50','XC4VFX20','XC4VFX40','XC4VFX60','XC4VFX100','XC4VFX140'),
xlxtyp3 enum('XCV300E','XCV400E','XCV600E','XC2V2000','XC2V3000','XC2V4000','XC2V6000','XC2VP2','XC2VP4','XC2VP7','XC2VP20','XC2VP30','XC2VP50','XC4VFX20','XC4VFX40','XC4VFX60','XC4VFX100','XC4VFX140'),
xlxspd0 enum('6','7','8','4','5','9','10','11','12'),
xlxspd1 enum('6','7','8','4','5','9','10','11','12'),
xlxspd2 enum('6','7','8','4','5','9','10','11','12'),
xlxspd3 enum('6','7','8','4','5','9','10','11','12'),
xlxtmp0 enum('COM','IND'),
xlxtmp1 enum('COM','IND'),
xlxtmp2 enum('COM','IND'),
xlxtmp3 enum('COM','IND'),
xlxgrd0 enum('NORMAL','ENGSAMP'),
xlxgrd1 enum('NORMAL','ENGSAMP'),
xlxgrd2 enum('NORMAL','ENGSAMP'),
xlxgrd3 enum('NORMAL','ENGSAMP'),
cputyp enum('MPC8260(HIP3)','MPC8260A(HIP4)','MPC8280(HIP7)','MPC8560'),
cpuspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ','233MHZ','266MHZ','300MHZ','333MHZ','366MHZ','400MHZ','433MHZ','466MHZ','500MHZ','533MHZ','566MHZ','600MHZ','633MHZ','666MHZ','700MHZ','733MHZ','766MHZ','800MHZ','833MHZ','866MHZ','900MHZ','933MHZ','966MHZ','1000MHZ','1033MHZ','1066MHZ','1100MHZ','1133MHZ','1166MHZ','1200MHZ','1233MHZ','1266MHZ','1300MHZ','1333MHZ'),
cpmspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ','233MHZ','266MHZ','300MHZ','333MHZ','366MHZ','400MHZ','433MHZ','466MHZ','500MHZ','533MHZ','566MHZ','600MHZ','633MHZ','666MHZ','700MHZ','733MHZ','766MHZ','800MHZ','833MHZ','866MHZ','900MHZ','933MHZ','966MHZ','1000MHZ','1033MHZ','1066MHZ','1100MHZ','1133MHZ','1166MHZ','1200MHZ','1233MHZ','1266MHZ','1300MHZ','1333MHZ'),
busspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ','233MHZ','266MHZ','300MHZ','333MHZ','366MHZ','400MHZ','433MHZ','466MHZ','500MHZ','533MHZ','566MHZ','600MHZ','633MHZ','666MHZ','700MHZ','733MHZ','766MHZ','800MHZ','833MHZ','866MHZ','900MHZ','933MHZ','966MHZ','1000MHZ','1033MHZ','1066MHZ','1100MHZ','1133MHZ','1166MHZ','1200MHZ','1233MHZ','1266MHZ','1300MHZ','1333MHZ'),
hstype enum('AMCC-S2064A','Xilinx-Rockets'),
hschin enum('0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16'),
hschout enum('0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16'),
PRIMARY KEY (serno),
KEY serno (serno),
UNIQUE serno_2 (serno)
);
#
# Table structure for table 'log'
#
DROP TABLE IF EXISTS log;
CREATE TABLE log (
logno int(10) unsigned zerofill NOT NULL auto_increment,
serno int(10) unsigned zerofill NOT NULL,
date date NOT NULL,
details text NOT NULL,
PRIMARY KEY (logno),
KEY logno (logno, serno, date),
UNIQUE logno_2 (logno)
);

View file

@ -0,0 +1,710 @@
<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?>
<?php
// (C) Copyright 2001
// Murray Jensen <Murray.Jensen@csiro.au>
// CSIRO Manufacturing Science and Technology, Preston Lab
// contains mysql user id and password - keep secret
require("config.php");
if (isset($_REQUEST['logout'])) {
Header("status: 401 Unauthorized");
Header("HTTP/1.0 401 Unauthorized");
Header("WWW-authenticate: basic realm=\"$bddb_label\"");
echo "<html><head><title>" .
"Access to '$bddb_label' Denied" .
"</title></head>\n";
echo "<body bgcolor=#ffffff><br></br><br></br><center><h1>" .
"You must be an Authorised User " .
"to access the '$bddb_label'" .
"</h1>\n</center></body></html>\n";
exit;
}
// contents of the various enumerated types - if first item is
// empty ('') then the enum is allowed to be null (ie "not null"
// is not set on the column)
// all column names in the database table
$columns = array(
'serno','ethaddr','date','batch',
'type','rev','location','comments',
'sdram0','sdram1','sdram2','sdram3',
'flash0','flash1','flash2','flash3',
'zbt0','zbt1','zbt2','zbt3','zbt4','zbt5','zbt6','zbt7',
'zbt8','zbt9','zbta','zbtb','zbtc','zbtd','zbte','zbtf',
'xlxtyp0','xlxtyp1','xlxtyp2','xlxtyp3',
'xlxspd0','xlxspd1','xlxspd2','xlxspd3',
'xlxtmp0','xlxtmp1','xlxtmp2','xlxtmp3',
'xlxgrd0','xlxgrd1','xlxgrd2','xlxgrd3',
'cputyp','cpuspd','cpmspd','busspd',
'hstype','hschin','hschout'
);
// board type
$type_vals = array('IO','CLP','DSP','INPUT','ALT-INPUT','DISPLAY');
// Xilinx fpga types
$xlxtyp_vals = array('','XCV300E','XCV400E','XCV600E','XC2V2000','XC2V3000','XC2V4000','XC2V6000','XC2VP2','XC2VP4','XC2VP7','XC2VP20','XC2VP30','XC2VP50','XC4VFX20','XC4VFX40','XC4VFX60','XC4VFX100','XC4VFX140');
// Xilinx fpga speeds
$xlxspd_vals = array('','6','7','8','4','5','9','10','11','12');
// Xilinx fpga temperatures (commercial or industrial)
$xlxtmp_vals = array('','COM','IND');
// Xilinx fpga grades (normal or engineering sample)
$xlxgrd_vals = array('','NORMAL','ENGSAMP');
// CPU types
$cputyp_vals = array('','MPC8260(HIP3)','MPC8260A(HIP4)','MPC8280(HIP7)','MPC8560');
// CPU/BUS/CPM clock speeds
$clk_vals = array('','33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ','233MHZ','266MHZ','300MHZ','333MHZ','366MHZ','400MHZ','433MHZ','466MHZ','500MHZ','533MHZ','566MHZ','600MHZ','633MHZ','666MHZ','700MHZ','733MHZ','766MHZ','800MHZ','833MHZ','866MHZ','900MHZ','933MHZ','966MHZ','1000MHZ','1033MHZ','1066MHZ','1100MHZ','1133MHZ','1166MHZ','1200MHZ','1233MHZ','1266MHZ','1300MHZ','1333MHZ');
// sdram sizes (nbits array is for eeprom config file)
$sdram_vals = array('','32M','64M','128M','256M','512M','1G','2G','4G');
$sdram_nbits = array(0,25,26,27,28,29,30,31,32);
// flash sizes (nbits array is for eeprom config file)
$flash_vals = array('','4M','8M','16M','32M','64M','128M','256M','512M','1G');
$flash_nbits = array(0,22,23,24,25,26,27,28,29,30);
// zbt ram sizes (nbits array is for write into eeprom config file)
$zbt_vals = array('','512K','1M','2M','4M','8M','16M');
$zbt_nbits = array(0,19,20,21,22,23,24);
// high-speed serial attributes
$hstype_vals = array('','AMCC-S2064A','Xilinx-Rockets');
$hschin_vals = array('0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16');
$hschout_vals = array('0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16');
// value filters - used when outputting html
function rev_filter($num) {
if ($num == 0)
return "001";
else
return sprintf("%03d", $num);
}
function text_filter($str) {
return urldecode($str);
}
mt_srand(time() | getmypid());
// set up MySQL connection
mysql_connect("", $mysql_user, $mysql_pw) || die("cannot connect");
mysql_select_db($mysql_db) || die("cannot select db");
// page header
function pg_head($title)
{
echo "<html>\n<head>\n";
echo "<link rel=stylesheet href=\"bddb.css\" type=\"text/css\" title=\"style sheet\"></link>\n";
echo "<title>$title</title>\n";
echo "</head>\n";
echo "<body>\n";
echo "<center><h1>$title</h1></center>\n";
echo "<hr></hr>\n";
}
// page footer
function pg_foot()
{
echo "<hr></hr>\n";
echo "<table width=\"100%\"><tr><td align=left>\n<address>" .
"If you have any problems, email " .
"<a href=\"mailto:Murray.Jensen@csiro.au\">" .
"Murray Jensen" .
"</a></address>\n" .
"</td><td align=right>\n" .
"<a href=\"index.php?logout=true\">logout</a>\n" .
"</td></tr></table>\n";
echo "<p><small><i>Made with " .
"<a href=\"http://kyber.dk/phpMyBuilder/\">" .
"Kyber phpMyBuilder</a></i></small></p>\n";
echo "</body>\n";
echo "</html>\n";
}
// some support functions
if (!function_exists('array_search')) {
function array_search($needle, $haystack, $strict = false) {
if (is_array($haystack) && count($haystack)) {
$ntype = gettype($needle);
foreach ($haystack as $key => $value) {
if ($value == $needle && (!$strict ||
gettype($value) == $ntype))
return $key;
}
}
return false;
}
}
if (!function_exists('in_array')) {
function in_array($needle, $haystack, $strict = false) {
if (is_array($haystack) && count($haystack)) {
$ntype = gettype($needle);
foreach ($haystack as $key => $value) {
if ($value == $needle && (!$strict ||
gettype($value) == $ntype))
return true;
}
}
return false;
}
}
function key_in_array($key, $array) {
return in_array($key, array_keys($array), true);
}
function enum_to_index($name, $vals) {
$index = array_search($GLOBALS[$name], $vals);
if ($vals[0] != '')
$index++;
return $index;
}
// fetch a value from an array - return empty string is not present
function get_key_value($key, $array) {
if (key_in_array($key, $array))
return $array[$key];
else
return '';
}
function fprintf() {
$n = func_num_args();
if ($n < 2)
return FALSE;
$a = func_get_args();
$fp = array_shift($a);
$x = "\$s = sprintf";
$sep = '(';
foreach ($a as $z) {
$x .= "$sep'$z'";
$sep = ',';
}
$x .= ');';
eval($x);
$l = strlen($s);
$r = fwrite($fp, $s, $l);
if ($r != $l)
return FALSE;
else
return TRUE;
}
// functions to display (print) a database table and its columns
function begin_table($ncols) {
global $table_ncols;
$table_ncols = $ncols;
echo "<table align=center width=\"100%\""
. " border=1 cellpadding=4 cols=$table_ncols>\n";
}
function begin_field($name, $span = 0) {
global $table_ncols;
echo "<tr valign=top>\n";
echo "\t<th align=center>$name</th>\n";
if ($span <= 0)
$span = $table_ncols - 1;
if ($span > 1)
echo "\t<td colspan=$span>\n";
else
echo "\t<td>\n";
}
function cont_field($span = 1) {
echo "\t</td>\n";
if ($span > 1)
echo "\t<td colspan=$span>\n";
else
echo "\t<td>\n";
}
function end_field() {
echo "\t</td>\n";
echo "</tr>\n";
}
function end_table() {
echo "</table>\n";
}
function print_field($name, $array, $size = 0, $filt='') {
begin_field($name);
if (key_in_array($name, $array))
$value = $array[$name];
else
$value = '';
if ($filt != '')
$value = $filt($value);
echo "\t\t<input name=$name value=\"$value\"";
if ($size > 0)
echo " size=$size maxlength=$size";
echo "></input>\n";
end_field();
}
function print_field_multiline($name, $array, $cols, $rows, $filt='') {
begin_field($name);
if (key_in_array($name, $array))
$value = $array[$name];
else
$value = '';
if ($filt != '')
$value = $filt($value);
echo "\t\t<textarea name=$name " .
"cols=$cols rows=$rows wrap=off>\n";
echo "$value";
echo "</textarea>\n";
end_field();
}
// print a mysql ENUM as an html RADIO INPUT
function print_enum($name, $array, $vals, $def = -1) {
begin_field($name);
if (key_in_array($name, $array))
$chk = array_search($array[$name], $vals, FALSE);
else
$chk = $def;
$nval = count($vals);
for ($i = 0; $i < $nval; $i++) {
$val = $vals[$i];
if ($val == '')
$pval = "none";
else
$pval = "$val";
printf("\t\t<input type=radio name=$name"
. " value=\"$val\"%s>$pval</input>\n",
$i == $chk ? " checked" : "");
}
end_field();
}
// print a mysql ENUM as an html SELECT INPUT
function print_enum_select($name, $array, $vals, $def = -1) {
begin_field($name);
echo "\t\t<select name=$name>\n";
if (key_in_array($name, $array))
$chk = array_search($array[$name], $vals, FALSE);
else
$chk = $def;
$nval = count($vals);
for ($i = 0; $i < $nval; $i++) {
$val = $vals[$i];
if ($val == '')
$pval = "none";
else
$pval = "$val";
printf("\t\t\t<option " .
"value=\"%s\"%s>%s</option>\n",
$val, $i == $chk ? " selected" : "", $pval);
}
echo "\t\t</select>\n";
end_field();
}
// print a group of mysql ENUMs (e.g. name0,name1,...) as an html SELECT
function print_enum_multi($base, $array, $vals, $cnt, $defs, $grp = 0) {
global $table_ncols;
if ($grp <= 0)
$grp = $cnt;
$ncell = $cnt / $grp;
$span = ($table_ncols - 1) / $ncell;
begin_field($base, $span);
$nval = count($vals);
for ($i = 0; $i < $cnt; $i++) {
if ($i > 0 && ($i % $grp) == 0)
cont_field($span);
$name = sprintf("%s%x", $base, $i);
echo "\t\t<select name=$name>\n";
if (key_in_array($name, $array))
$ai = array_search($array[$name], $vals, FALSE);
else {
if (key_in_array($i, $defs))
$ai = $defs[$i];
else
$ai = 0;
}
for ($j = 0; $j < $nval; $j++) {
$val = $vals[$j];
if ($val == '')
$pval = "&nbsp;";
else
$pval = "$val";
printf("\t\t\t<option " .
"value=\"%s\"%s>%s</option>\n",
$val,
$j == $ai ? " selected" : "",
$pval);
}
echo "\t\t</select>\n";
}
end_field();
}
// functions to handle the form input
// fetch all the parts of an "enum_multi" into a string suitable
// for a MySQL query
function gather_enum_multi_query($base, $cnt) {
$retval = '';
for ($i = 0; $i < $cnt; $i++) {
$name = sprintf("%s%x", $base, $i);
if (isset($_REQUEST[$name])) {
$retval .= sprintf(", %s='%s'",
$name, $_REQUEST[$name]);
}
}
return $retval;
}
// fetch all the parts of an "enum_multi" into a string suitable
// for a display e.g. in an html table cell
function gather_enum_multi_print($base, $cnt, $array) {
$retval = '';
for ($i = 0; $i < $cnt; $i++) {
$name = sprintf("%s%x", $base, $i);
if ($array[$name] != '') {
if ($retval != '')
$retval .= ',';
$retval .= $array[$name];
}
}
return $retval;
}
// fetch all the parts of an "enum_multi" into a string suitable
// for writing to the eeprom data file
function gather_enum_multi_write($base, $cnt, $vals, $xfrm = array()) {
$retval = '';
for ($i = 0; $i < $cnt; $i++) {
$name = sprintf("%s%x", $base, $i);
if ($GLOBALS[$name] != '') {
if ($retval != '')
$retval .= ',';
$index = enum_to_index($name, $vals);
if ($xfrm != array())
$retval .= $xfrm[$index];
else
$retval .= $index;
}
}
return $retval;
}
// count how many parts of an "enum_multi" are actually set
function count_enum_multi($base, $cnt) {
$retval = 0;
for ($i = 0; $i < $cnt; $i++) {
$name = sprintf("%s%x", $base, $i);
if (isset($_REQUEST[$name]))
$retval++;
}
return $retval;
}
// ethernet address functions
// generate a (possibly not unique) random vendor ethernet address
// (setting bit 6 in the ethernet address - motorola wise i.e. bit 0
// is the most significant bit - means it is not an assigned ethernet
// address - it is a "locally administered" address). Also, make sure
// it is NOT a multicast ethernet address (by setting bit 7 to 0).
// e.g. the first byte of all ethernet addresses generated here will
// have 2 in the bottom two bits (incidentally, these are the first
// two bits transmitted on the wire, since the octets in ethernet
// addresses are transmitted LSB first).
function gen_eth_addr($serno) {
$ethaddr_hgh = (mt_rand(0, 65535) & 0xfeff) | 0x0200;
$ethaddr_mid = mt_rand(0, 65535);
$ethaddr_low = mt_rand(0, 65535);
return sprintf("%02lx:%02lx:%02lx:%02lx:%02lx:%02lx",
$ethaddr_hgh >> 8, $ethaddr_hgh & 0xff,
$ethaddr_mid >> 8, $ethaddr_mid & 0xff,
$ethaddr_low >> 8, $ethaddr_low & 0xff);
}
// check that an ethernet address is valid
function eth_addr_is_valid($ethaddr) {
$ethbytes = split(':', $ethaddr);
if (count($ethbytes) != 6)
return FALSE;
for ($i = 0; $i < 6; $i++) {
$ethbyte = $ethbytes[$i];
if (!ereg('^[0-9a-f][0-9a-f]$', $ethbyte))
return FALSE;
}
return TRUE;
}
// write a simple eeprom configuration file
function write_eeprom_cfg_file() {
global $sernos, $nsernos, $bddb_cfgdir, $numerrs, $cfgerrs;
global $date, $batch, $type_vals, $rev;
global $sdram_vals, $sdram_nbits;
global $flash_vals, $flash_nbits;
global $zbt_vals, $zbt_nbits;
global $xlxtyp_vals, $xlxspd_vals, $xlxtmp_vals, $xlxgrd_vals;
global $cputyp, $cputyp_vals, $clk_vals;
global $hstype, $hstype_vals, $hschin, $hschout;
$numerrs = 0;
$cfgerrs = array();
for ($i = 0; $i < $nsernos; $i++) {
$serno = sprintf("%010d", $sernos[$i]);
$wfp = @fopen($bddb_cfgdir . "/$serno.cfg", "w");
if (!$wfp) {
$cfgerrs[$i] = 'file create fail';
$numerrs++;
continue;
}
set_file_buffer($wfp, 0);
if (!fprintf($wfp, "serno=%d\n", $sernos[$i])) {
$cfgerrs[$i] = 'cfg wr fail (serno)';
fclose($wfp);
$numerrs++;
continue;
}
if (!fprintf($wfp, "date=%s\n", $date)) {
$cfgerrs[$i] = 'cfg wr fail (date)';
fclose($wfp);
$numerrs++;
continue;
}
if ($batch != '') {
if (!fprintf($wfp, "batch=%s\n", $batch)) {
$cfgerrs[$i] = 'cfg wr fail (batch)';
fclose($wfp);
$numerrs++;
continue;
}
}
$typei = enum_to_index("type", $type_vals);
if (!fprintf($wfp, "type=%d\n", $typei)) {
$cfgerrs[$i] = 'cfg wr fail (type)';
fclose($wfp);
$numerrs++;
continue;
}
if (!fprintf($wfp, "rev=%d\n", $rev)) {
$cfgerrs[$i] = 'cfg wr fail (rev)';
fclose($wfp);
$numerrs++;
continue;
}
$s = gather_enum_multi_write("sdram", 4,
$sdram_vals, $sdram_nbits);
if ($s != '') {
$b = fprintf($wfp, "sdram=%s\n", $s);
if (!$b) {
$cfgerrs[$i] = 'cfg wr fail (sdram)';
fclose($wfp);
$numerrs++;
continue;
}
}
$s = gather_enum_multi_write("flash", 4,
$flash_vals, $flash_nbits);
if ($s != '') {
$b = fprintf($wfp, "flash=%s\n", $s);
if (!$b) {
$cfgerrs[$i] = 'cfg wr fail (flash)';
fclose($wfp);
$numerrs++;
continue;
}
}
$s = gather_enum_multi_write("zbt", 16,
$zbt_vals, $zbt_nbits);
if ($s != '') {
$b = fprintf($wfp, "zbt=%s\n", $s);
if (!$b) {
$cfgerrs[$i] = 'cfg wr fail (zbt)';
fclose($wfp);
$numerrs++;
continue;
}
}
$s = gather_enum_multi_write("xlxtyp", 4, $xlxtyp_vals);
if ($s != '') {
$b = fprintf($wfp, "xlxtyp=%s\n", $s);
if (!$b) {
$cfgerrs[$i] = 'cfg wr fail (xlxtyp)';
fclose($wfp);
$numerrs++;
continue;
}
}
$s = gather_enum_multi_write("xlxspd", 4, $xlxspd_vals);
if ($s != '') {
$b = fprintf($wfp, "xlxspd=%s\n", $s);
if (!$b) {
$cfgerrs[$i] = 'cfg wr fail (xlxspd)';
fclose($wfp);
$numerrs++;
continue;
}
}
$s = gather_enum_multi_write("xlxtmp", 4, $xlxtmp_vals);
if ($s != '') {
$b = fprintf($wfp, "xlxtmp=%s\n", $s);
if (!$b) {
$cfgerrs[$i] = 'cfg wr fail (xlxtmp)';
fclose($wfp);
$numerrs++;
continue;
}
}
$s = gather_enum_multi_write("xlxgrd", 4, $xlxgrd_vals);
if ($s != '') {
$b = fprintf($wfp, "xlxgrd=%s\n", $s);
if (!$b) {
$cfgerrs[$i] = 'cfg wr fail (xlxgrd)';
fclose($wfp);
$numerrs++;
continue;
}
}
if ($cputyp != '') {
$cputypi = enum_to_index("cputyp",$cputyp_vals);
$cpuspdi = enum_to_index("cpuspd", $clk_vals);
$busspdi = enum_to_index("busspd", $clk_vals);
$cpmspdi = enum_to_index("cpmspd", $clk_vals);
$b = fprintf($wfp, "cputyp=%d\ncpuspd=%d\n" .
"busspd=%d\ncpmspd=%d\n",
$cputypi, $cpuspdi, $busspdi, $cpmspdi);
if (!$b) {
$cfgerrs[$i] = 'cfg wr fail (cputyp)';
fclose($wfp);
$numerrs++;
continue;
}
}
if ($hstype != '') {
$hstypei = enum_to_index("hstype",$hstype_vals);
$b = fprintf($wfp, "hstype=%d\n" .
"hschin=%s\nhschout=%s\n",
$hstypei, $hschin, $hschout);
if (!$b) {
$cfgerrs[$i] = 'cfg wr fail (hstype)';
fclose($wfp);
$numerrs++;
continue;
}
}
if (!fclose($wfp)) {
$cfgerrs[$i] = 'file cls fail';
$numerrs++;
}
}
return $numerrs;
}
?>

View file

@ -0,0 +1,65 @@
<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?>
<?php
// (C) Copyright 2001
// Murray Jensen <Murray.Jensen@csiro.au>
// CSIRO Manufacturing Science and Technology, Preston Lab
// dodelete page (hymod_bddb / boards)
require("defs.php");
pg_head("$bddb_label - Delete Board Results");
if (!isset($_REQUEST['serno']))
die("the board serial number was not specified");
$serno=intval($_REQUEST['serno']);
mysql_query("delete from boards where serno=$serno");
if(mysql_errno()) {
$errstr = mysql_error();
echo "\t<font size=+4>\n";
echo "\t\t<p>\n";
echo "\t\t\tThe following error was encountered:\n";
echo "\t\t</p>\n";
echo "\t\t<center>\n";
printf("\t\t\t<b>%s</b>\n", $errstr);
echo "\t\t</center>\n";
echo "\t</font>\n";
}
else {
echo "\t<font size=+2>\n";
echo "\t\t<p>\n";
echo "\t\t\tThe board with serial number <b>$serno</b> was"
. " successfully deleted\n";
mysql_query("delete from log where serno=$serno");
if (mysql_errno()) {
$errstr = mysql_error();
echo "\t\t\t<font size=+4>\n";
echo "\t\t\t\t<p>\n";
echo "\t\t\t\t\tBut the following error occurred " .
"when deleting the log entries:\n";
echo "\t\t\t\t</p>\n";
echo "\t\t\t\t<center>\n";
printf("\t\t\t\t\t<b>%s</b>\n", $errstr);
echo "\t\t\t\t</center>\n";
echo "\t\t\t</font>\n";
}
echo "\t\t</p>\n";
echo "\t</font>\n";
}
?>
<p>
<table width="100%">
<tr>
<td align=center>
<a href="browse.php">Back to Browse</a>
</td>
<td align=center>
<a href="index.php">Back to Start</a>
</td>
</tr>
</table>
<?php
pg_foot();
?>

View file

@ -0,0 +1,57 @@
<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?>
<?php
// (C) Copyright 2001
// Murray Jensen <Murray.Jensen@csiro.au>
// CSIRO Manufacturing Science and Technology, Preston Lab
// dodelete page (hymod_bddb / boards)
require("defs.php");
pg_head("$bddb_label - Delete Log Entry Results");
if (!isset($_REQUEST['serno']))
die("the board serial number was not specified");
$serno=intval($_REQUEST['serno']);
if (!isset($_REQUEST['logno']) || $_REQUEST['logno'] == 0)
die("the log entry number not specified!");
$logno=$_REQUEST['logno'];
mysql_query("delete from log where serno=$serno and logno=$logno");
if(mysql_errno()) {
$errstr = mysql_error();
echo "\t<font size=+4>\n";
echo "\t\t<p>\n";
echo "\t\t\tThe following error was encountered:\n";
echo "\t\t</p>\n";
echo "\t\t<center>\n";
printf("\t\t\t<b>%s</b>\n", $errstr);
echo "\t\t</center>\n";
echo "\t</font>\n";
}
else {
echo "\t<font size=+2>\n";
echo "\t\t<p>\n";
echo "\t\t\tThe log entry with log number <b>$logno</b>\n";
echo "\t\t\tand serial number <b>$serno</b> ";
echo "was successfully deleted\n";
echo "\t\t</p>\n";
echo "\t</font>\n";
}
?>
<p>
<table width="100%">
<tr>
<td align=center>
<a href="brlog.php?serno=<?php echo "$serno"; ?>">Back to Log</a>
</td>
<td align=center>
<a href="index.php">Back to Start</a>
</td>
</tr>
</table>
<?php
pg_foot();
?>

View file

@ -0,0 +1,186 @@
<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?>
<?php
// (C) Copyright 2001
// Murray Jensen <Murray.Jensen@csiro.au>
// CSIRO Manufacturing Science and Technology, Preston Lab
// doedit page (hymod_bddb / boards)
require("defs.php");
pg_head("$bddb_label - Edit Board Results");
if (!isset($_REQUEST['serno']) || $_REQUEST['serno'] == '')
die("the board serial number was not specified");
$serno=intval($_REQUEST['serno']);
$query="update boards set";
if (isset($_REQUEST['ethaddr'])) {
$ethaddr=$_REQUEST['ethaddr'];
if (!eth_addr_is_valid($ethaddr))
die("ethaddr is invalid ('$ethaddr')");
$query.=" ethaddr='$ethaddr',";
}
if (isset($_REQUEST['date'])) {
$date=$_REQUEST['date'];
list($y, $m, $d) = split("-", $date);
if (!checkdate($m, $d, $y) || $y < 1999)
die("date is invalid (input '$date', " .
"yyyy-mm-dd '$y-$m-$d')");
$query.=" date='$date'";
}
if (isset($_REQUEST['batch'])) {
$batch=$_REQUEST['batch'];
if (strlen($batch) > 32)
die("batch field too long (>32)");
$query.=", batch='$batch'";
}
if (isset($_REQUEST['type'])) {
$type=$_REQUEST['type'];
if (!in_array($type, $type_vals))
die("Invalid type ($type) specified");
$query.=", type='$type'";
}
if (isset($_REQUEST['rev'])) {
$rev=$_REQUEST['rev'];
if (($rev = intval($rev)) <= 0 || $rev > 255)
die("Revision number is invalid ($rev)");
$query.=sprintf(", rev=%d", $rev);
}
if (isset($_REQUEST['location'])) {
$location=$_REQUEST['location'];
if (strlen($location) > 64)
die("location field too long (>64)");
$query.=", location='$location'";
}
if (isset($_REQUEST['comments']))
$comments=$_REQUEST['comments'];
$query.=", comments='" . rawurlencode($comments) . "'";
$query.=gather_enum_multi_query("sdram", 4);
$query.=gather_enum_multi_query("flash", 4);
$query.=gather_enum_multi_query("zbt", 16);
$query.=gather_enum_multi_query("xlxtyp", 4);
$nxlx = count_enum_multi("xlxtyp", 4);
$query.=gather_enum_multi_query("xlxspd", 4);
if (count_enum_multi("xlxspd", 4) != $nxlx)
die("number of xilinx speeds not same as number of types");
$query.=gather_enum_multi_query("xlxtmp", 4);
if (count_enum_multi("xlxtmp", 4) != $nxlx)
die("number of xilinx temps. not same as number of types");
$query.=gather_enum_multi_query("xlxgrd", 4);
if (count_enum_multi("xlxgrd", 4) != $nxlx)
die("number of xilinx grades not same as number of types");
if (isset($_REQUEST['cputyp'])) {
$cputyp=$_REQUEST['cputyp'];
$query.=", cputyp='$cputyp'";
if (!isset($_REQUEST['cpuspd']) || $_REQUEST['cpuspd'] == '')
die("must specify cpu speed if cpu type is defined");
$cpuspd=$_REQUEST['cpuspd'];
$query.=", cpuspd='$cpuspd'";
if (!isset($_REQUEST['cpmspd']) || $_REQUEST['cpmspd'] == '')
die("must specify cpm speed if cpu type is defined");
$cpmspd=$_REQUEST['cpmspd'];
$query.=", cpmspd='$cpmspd'";
if (!isset($_REQUEST['busspd']) || $_REQUEST['busspd'] == '')
die("must specify bus speed if cpu type is defined");
$busspd=$_REQUEST['busspd'];
$query.=", busspd='$busspd'";
}
else {
if (isset($_REQUEST['cpuspd']))
die("can't specify cpu speed if there is no cpu");
if (isset($_REQUEST['cpmspd']))
die("can't specify cpm speed if there is no cpu");
if (isset($_REQUEST['busspd']))
die("can't specify bus speed if there is no cpu");
}
if (isset($_REQUEST['hschin'])) {
$hschin=$_REQUEST['hschin'];
if (($hschin = intval($hschin)) < 0 || $hschin > 4)
die("Invalid number of hs input chans ($hschin)");
}
else
$hschin = 0;
if (isset($_REQUEST['hschout'])) {
$hschout=$_REQUEST['hschout'];
if (($hschout = intval($hschout)) < 0 || $hschout > 4)
die("Invalid number of hs output chans ($hschout)");
}
else
$hschout = 0;
if (isset($_REQUEST['hstype'])) {
$hstype=$_REQUEST['hstype'];
$query.=", hstype='$hstype'";
}
else {
if ($_REQUEST['hschin'] != 0)
die("number of high-speed input channels must be zero"
. " if high-speed chip is not present");
if ($_REQUEST['hschout'] != 0)
die("number of high-speed output channels must be zero"
. " if high-speed chip is not present");
}
$query.=", hschin='$hschin'";
$query.=", hschout='$hschout'";
$query.=" where serno=$serno";
mysql_query($query);
if(mysql_errno()) {
$errstr = mysql_error();
echo "\t<font size=+4>\n";
echo "\t\t<p>\n";
echo "\t\t\tThe following error was encountered:\n";
echo "\t\t</p>\n";
echo "\t\t<center>\n";
printf("\t\t\t<b>%s</b>\n", $errstr);
echo "\t\t</center>\n";
echo "\t</font>\n";
}
else {
$sernos = array($serno);
$nsernos = 1;
write_eeprom_cfg_file();
echo "\t<font size=+2>\n";
echo "\t\t<p>\n";
echo "\t\t\tThe board with serial number <b>$serno</b> was"
. " successfully updated";
if ($numerrs > 0) {
$errstr = $cfgerrs[0];
echo "<br>\n\t\t\t";
echo "(but the cfg file update failed: $errstr)";
}
echo "\n";
echo "\t\t</p>\n";
echo "\t</font>\n";
}
?>
<p>
<table align=center width="100%">
<tr>
<td align=center><a href="browse.php">Back to Browse</a></td>
<td align=center><a href="index.php">Back to Start</a></td>
</tr>
</table>
<?php
pg_foot();
?>

View file

@ -0,0 +1,76 @@
<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?>
<?php
// (C) Copyright 2001
// Murray Jensen <Murray.Jensen@csiro.au>
// CSIRO Manufacturing Science and Technology, Preston Lab
// doedit page (hymod_bddb / boards)
require("defs.php");
pg_head("$bddb_label - Edit Log Entry Results");
if (!isset($_REQUEST['serno']) || $_REQUEST['serno'] == '')
die("the board serial number was not specified");
$serno=intval($_REQUEST['serno']);
if (!isset($_REQUEST['logno']) || $_REQUEST['logno'] == '')
die("log number not specified!");
$logno=intval($_REQUEST['logno']);
$query="update log set";
if (isset($_REQUEST['date'])) {
$date=$_REQUEST['date'];
list($y, $m, $d) = split("-", $date);
if (!checkdate($m, $d, $y) || $y < 1999)
die("date is invalid (input '$date', " .
"yyyy-mm-dd '$y-$m-$d')");
$query.=" date='$date'";
}
if (isset($_REQUEST['who'])) {
$who=$_REQUEST['who'];
$query.=", who='" . $who . "'";
}
if (isset($_REQUEST['details'])) {
$details=$_REQUEST['details'];
$query.=", details='" . rawurlencode($details) . "'";
}
$query.=" where serno=$serno and logno=$logno";
mysql_query($query);
if(mysql_errno()) {
$errstr = mysql_error();
echo "\t<font size=+4>\n";
echo "\t\t<p>\n";
echo "\t\t\tThe following error was encountered:\n";
echo "\t\t</p>\n";
echo "\t\t<center>\n";
printf("\t\t\t<b>%s</b>\n", $errstr);
echo "\t\t</center>\n";
echo "\t</font>\n";
}
else {
echo "\t<font size=+2>\n";
echo "\t\t<p>\n";
echo "\t\t\tThe log entry with log number <b>$logno</b> and\n";
echo "\t\t\tserial number <b>$serno</b> ";
echo "was successfully updated\n";
echo "\t\t</p>\n";
echo "\t</font>\n";
}
?>
<p>
<table align=center width="100%">
<tr>
<td align=center><a href="brlog.php?serno=<?php echo "$serno"; ?>">Back to Log</a></td>
<td align=center><a href="index.php">Back to Start</a></td>
</tr>
</table>
<?php
pg_foot();
?>

View file

@ -0,0 +1,230 @@
<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?>
<?php
// (C) Copyright 2001
// Murray Jensen <Murray.Jensen@csiro.au>
// CSIRO Manufacturing Science and Technology, Preston Lab
// doedit page (hymod_bddb / boards)
require("defs.php");
pg_head("$bddb_label - Board Registration Results");
if (isset($_REQUEST['serno'])) {
$serno=$_REQUEST['serno'];
die("serial number must not be set ($serno) when Creating!");
}
$query="update boards set";
list($y, $m, $d) = split("-", $date);
if (!checkdate($m, $d, $y) || $y < 1999)
die("date is invalid (input '$date', yyyy-mm-dd '$y-$m-$d')");
$query.=" date='$date'";
if ($batch != '') {
if (strlen($batch) > 32)
die("batch field too long (>32)");
$query.=", batch='$batch'";
}
if (!in_array($type, $type_vals))
die("Invalid type ($type) specified");
$query.=", type='$type'";
if (($rev = intval($rev)) <= 0 || $rev > 255)
die("Revision number is invalid ($rev)");
$query.=sprintf(", rev=%d", $rev);
$query.=gather_enum_multi_query("sdram", 4);
$query.=gather_enum_multi_query("flash", 4);
$query.=gather_enum_multi_query("zbt", 16);
$query.=gather_enum_multi_query("xlxtyp", 4);
$nxlx = count_enum_multi("xlxtyp", 4);
$query.=gather_enum_multi_query("xlxspd", 4);
if (count_enum_multi("xlxspd", 4) != $nxlx)
die("number of xilinx speeds not same as number of types");
$query.=gather_enum_multi_query("xlxtmp", 4);
if (count_enum_multi("xlxtmp", 4) != $nxlx)
die("number of xilinx temps. not same as number of types");
$query.=gather_enum_multi_query("xlxgrd", 4);
if (count_enum_multi("xlxgrd", 4) != $nxlx)
die("number of xilinx grades not same as number of types");
if ($cputyp == '') {
if ($cpuspd != '')
die("can't specify cpu speed if there is no cpu");
if ($cpmspd != '')
die("can't specify cpm speed if there is no cpu");
if ($busspd != '')
die("can't specify bus speed if there is no cpu");
}
else {
$query.=", cputyp='$cputyp'";
if ($cpuspd == '')
die("must specify cpu speed if cpu type is defined");
$query.=", cpuspd='$cpuspd'";
if ($cpmspd == '')
die("must specify cpm speed if cpu type is defined");
$query.=", cpmspd='$cpmspd'";
if ($busspd == '')
die("must specify bus speed if cpu type is defined");
$query.=", busspd='$busspd'";
}
if (($hschin = intval($hschin)) < 0 || $hschin > 4)
die("Invalid number of hs input chans ($hschin)");
if (($hschout = intval($hschout)) < 0 || $hschout > 4)
die("Invalid number of hs output chans ($hschout)");
if ($hstype == '') {
if ($hschin != 0)
die("number of high-speed input channels must be zero"
. " if high-speed chip is not present");
if ($hschout != 0)
die("number of high-speed output channels must be zero"
. " if high-speed chip is not present");
}
else
$query.=", hstype='$hstype'";
$query.=", hschin='$hschin'";
$query.=", hschout='$hschout'";
// echo "final query = '$query'<br>\n";
$quant = intval($quant);
if ($quant <= 0) $quant = 1;
$sernos = array();
if ($geneths)
$ethaddrs = array();
$sqlerr = '';
while ($quant-- > 0) {
mysql_query("insert into boards (serno) values (null)");
if (mysql_errno()) {
$sqlerr = mysql_error();
break;
}
$serno = mysql_insert_id();
if (!$serno) {
$sqlerr = "couldn't allocate new serial number";
break;
}
mysql_query($query . " where serno=$serno");
if (mysql_errno()) {
$sqlerr = mysql_error();
break;
}
array_push($sernos, $serno);
if ($geneths) {
$ethaddr = gen_eth_addr($serno);
mysql_query("update boards set ethaddr='$ethaddr'" .
" where serno=$serno");
if (mysql_errno()) {
$sqlerr = mysql_error();
array_push($ethaddrs,
"<font color=#ff0000><b>" .
"db save fail" .
"</b></font>");
break;
}
array_push($ethaddrs, $ethaddr);
}
}
$nsernos = count($sernos);
if ($nsernos > 0) {
write_eeprom_cfg_file();
echo "<font size=+2>\n";
echo "\t<p>\n";
echo "\t\tThe following board serial numbers were"
. " successfully allocated";
if ($numerrs > 0)
echo " (but with $numerrs cfg file error" .
($numerrs > 1 ? "s" : "") . ")";
echo ":\n";
echo "\t</p>\n";
echo "</font>\n";
echo "<table align=center width=\"100%\">\n";
echo "<tr>\n";
echo "\t<th>Serial Number</th>\n";
if ($numerrs > 0)
echo "\t<th>Cfg File Errs</th>\n";
if ($geneths)
echo "\t<th>Ethernet Address</th>\n";
echo "</tr>\n";
for ($i = 0; $i < $nsernos; $i++) {
$serno = sprintf("%010d", $sernos[$i]);
echo "<tr>\n";
echo "\t<td align=center><font size=+2>" .
"<b>$serno</b></font></td>\n";
if ($numerrs > 0) {
if (($errstr = $cfgerrs[$i]) == '')
$errstr = '&nbsp;';
echo "\t<td align=center>" .
"<font size=+2 color=#ff0000><b>" .
$errstr .
"</b></font></td>\n";
}
if ($geneths) {
echo "\t<td align=center>" .
"<font size=+2 color=#00ff00><b>" .
$ethaddrs[$i] .
"</b></font></td>\n";
}
echo "</tr>\n";
}
echo "</table>\n";
}
if ($sqlerr != '') {
echo "\t<font size=+4>\n";
echo "\t\t<p>\n";
echo "\t\t\tThe following SQL error was encountered:\n";
echo "\t\t</p>\n";
echo "\t\t<center>\n";
printf("\t\t\t<b>%s</b>\n", $sqlerr);
echo "\t\t</center>\n";
echo "\t</font>\n";
}
?>
<p>
<table align=center width="100%">
<tr>
<td align=center><a href="browse.php">Go to Browse</a></td>
<td align=center><a href="index.php">Back to Start</a></td>
</tr>
</table>
<?php
pg_foot();
?>

View file

@ -0,0 +1,86 @@
<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?>
<?php
// (C) Copyright 2001
// Murray Jensen <Murray.Jensen@csiro.au>
// CSIRO Manufacturing Science and Technology, Preston Lab
// doedit page (hymod_bddb / boards)
require("defs.php");
pg_head("$bddb_label - Add Log Entry Results");
if (!isset($_REQUEST['serno']) || $_REQUEST['serno'] == '')
die("serial number not specified!");
$serno=intval($_REQUEST['serno']);
if (isset($_REQUEST['logno'])) {
$logno=$_REQUEST['logno'];
die("log number must not be set ($logno) when Creating!");
}
$query="update log set serno=$serno";
list($y, $m, $d) = split("-", $date);
if (!checkdate($m, $d, $y) || $y < 1999)
die("date is invalid (input '$date', yyyy-mm-dd '$y-$m-$d')");
$query.=", date='$date'";
if (isset($_REQUEST['who'])) {
$who=$_REQUEST['who'];
$query.=", who='" . $who . "'";
}
if (isset($_REQUEST['details'])) {
$details=$_REQUEST['details'];
$query.=", details='" . rawurlencode($details) . "'";
}
// echo "final query = '$query'<br>\n";
$sqlerr = '';
mysql_query("insert into log (logno) values (null)");
if (mysql_errno())
$sqlerr = mysql_error();
else {
$logno = mysql_insert_id();
if (!$logno)
$sqlerr = "couldn't allocate new serial number";
else {
mysql_query($query . " where logno=$logno");
if (mysql_errno())
$sqlerr = mysql_error();
}
}
if ($sqlerr == '') {
echo "<font size=+2>\n";
echo "\t<p>\n";
echo "\t\tA log entry with log number '$logno' was " .
"added to the board with serial number '$serno'\n";
echo "\t</p>\n";
echo "</font>\n";
}
else {
echo "\t<font size=+4>\n";
echo "\t\t<p>\n";
echo "\t\t\tThe following SQL error was encountered:\n";
echo "\t\t</p>\n";
echo "\t\t<center>\n";
printf("\t\t\t<b>%s</b>\n", $sqlerr);
echo "\t\t</center>\n";
echo "\t</font>\n";
}
?>
<p></p>
<table width="100%">
<tr>
<td align=center><a href="brlog.php?serno=<?php echo "$serno"; ?>">Go to Browse</a></td>
<td align=center><a href="index.php">Back to Start</a></td>
</tr>
</table>
<?php
pg_foot();
?>

View file

@ -0,0 +1,131 @@
<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?>
<?php
// (C) Copyright 2001
// Murray Jensen <Murray.Jensen@csiro.au>
// CSIRO Manufacturing Science and Technology, Preston Lab
// edit page (hymod_bddb / boards)
require("defs.php");
pg_head("$bddb_label - Edit Board Registration");
if ($serno == 0)
die("serial number not specified or invalid!");
$pserno = sprintf("%010d", $serno);
echo "<center><b><font size=+2>";
echo "Board Serial Number: $pserno";
echo "</font></b></center>\n";
?>
<p>
<form action=doedit.php method=POST>
<?php
echo "<input type=hidden name=serno value=$serno>\n";
$r=mysql_query("select * from boards where serno=$serno");
$row=mysql_fetch_array($r);
if(!$row) die("no record of serial number '$serno' in database");
begin_table(5);
// ethaddr char(17)
print_field("ethaddr", $row, 17);
// date date
print_field("date", $row);
// batch char(32)
print_field("batch", $row, 32);
// type enum('IO','CLP','DSP','INPUT','ALT-INPUT','DISPLAY')
print_enum("type", $row, $type_vals);
// rev tinyint(3) unsigned zerofill
print_field("rev", $row, 3, 'rev_filter');
// location char(64)
print_field("location", $row, 64);
// comments text
print_field_multiline("comments", $row, 60, 10, 'text_filter');
// sdram[0-3] enum('32M','64M','128M','256M')
print_enum_multi("sdram", $row, $sdram_vals, 4, array());
// flash[0-3] enum('4M','8M','16M','32M','64M')
print_enum_multi("flash", $row, $flash_vals, 4, array());
// zbt[0-f] enum('512K','1M','2M','4M')
print_enum_multi("zbt", $row, $zbt_vals, 16, array());
// xlxtyp[0-3] enum('XCV300E','XCV400E','XCV600E')
print_enum_multi("xlxtyp", $row, $xlxtyp_vals, 4, array(), 1);
// xlxspd[0-3] enum('6','7','8')
print_enum_multi("xlxspd", $row, $xlxspd_vals, 4, array(), 1);
// xlxtmp[0-3] enum('COM','IND')
print_enum_multi("xlxtmp", $row, $xlxtmp_vals, 4, array(), 1);
// xlxgrd[0-3] enum('NORMAL','ENGSAMP')
print_enum_multi("xlxgrd", $row, $xlxgrd_vals, 4, array(), 1);
// cputyp enum('MPC8260(HIP3)','MPC8260A(HIP4)','MPC8280(HIP7)')
print_enum("cputyp", $row, $cputyp_vals);
// cpuspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ','233MHZ','266MHZ')
print_enum_select("cpuspd", $row, $clk_vals);
// cpmspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ','233MHZ','266MHZ')
print_enum_select("cpmspd", $row, $clk_vals);
// busspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ','233MHZ','266MHZ')
print_enum_select("busspd", $row, $clk_vals);
// hstype enum('AMCC-S2064A')
print_enum("hstype", $row, $hstype_vals);
// hschin enum('0','1','2','3','4')
print_enum("hschin", $row, $hschin_vals);
// hschout enum('0','1','2','3','4')
print_enum("hschout", $row, $hschout_vals);
end_table();
echo "<p>\n";
echo "<center><b>";
echo "<font color=#ff0000>WARNING: NO UNDO ON DELETE!</font>";
echo "<br></br>\n";
echo "<tt>[ <a href=\"dodelete.php?serno=$serno\">delete</a> ]</tt>";
echo "</b></center>\n";
echo "</p>\n";
?>
<p>
<table align=center width="100%">
<tr>
<td align=center>
<input type=submit value=Edit>
</td>
<td>
&nbsp;
</td>
<td align=center>
<input type=reset value=Reset>
</td>
<td>
&nbsp;
</td>
<td align=center>
<a href="index.php">Back to Start</a>
</td>
</tr>
</table>
</p>
</form>
<?php
pg_foot();
?>

View file

@ -0,0 +1,86 @@
<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?>
<?php
// (C) Copyright 2001
// Murray Jensen <Murray.Jensen@csiro.au>
// CSIRO Manufacturing Science and Technology, Preston Lab
// edit page (hymod_bddb / boards)
require("defs.php");
pg_head("$bddb_label - Edit Board Log Entry");
if (!isset($_REQUEST['serno']) || $_REQUEST['serno'] == '')
die("serial number not specified!");
$serno=intval($_REQUEST['serno']);
if (!isset($_REQUEST['logno']) || $_REQUEST['logno'] == '')
die("log number not specified!");
$logno=intval($_REQUEST['logno']);
$pserno = sprintf("%010d", $serno);
$plogno = sprintf("%010d", $logno);
echo "<center><b><font size=+2>";
echo "Board Serial Number: $pserno, Log Number: $plogno";
echo "</font></b></center>\n";
?>
<p>
<form action=doedlog.php method=POST>
<?php
echo "<input type=hidden name=serno value=$serno>\n";
echo "<input type=hidden name=logno value=$logno>\n";
$r=mysql_query("select * from log where serno=$serno and logno=$logno");
$row=mysql_fetch_array($r);
if(!$row)
die("no record of log entry with serial number '$serno' " .
"and log number '$logno' in database");
begin_table(3);
// date date
print_field("date", $row);
// who char(20)
print_field("who", $row);
// details text
print_field_multiline("details", $row, 60, 10, 'text_filter');
end_table();
echo "<p>\n";
echo "<center><b>";
echo "<font color=#ff0000>WARNING: NO UNDO ON DELETE!</font>";
echo "<br></br>\n";
echo "<tt>[ <a href=\"dodellog.php?serno=$serno&logno=$logno\">delete</a> ]</tt>";
echo "</b></center>\n";
echo "</p>\n";
?>
<p>
<table align=center width="100%">
<tr>
<td align=center>
<input type=submit value=Edit>
</td>
<td>
&nbsp;
</td>
<td align=center>
<input type=reset value=Reset>
</td>
<td>
&nbsp;
</td>
<td align=center>
<a href="index.php">Back to Start</a>
</td>
</tr>
</table>
</p>
</form>
<?php
pg_foot();
?>

View file

@ -0,0 +1,33 @@
<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?>
<?php
// (C) Copyright 2001
// Murray Jensen <Murray.Jensen@csiro.au>
// CSIRO Manufacturing Science and Technology, Preston Lab
$serno=isset($_REQUEST['serno'])?$_REQUEST['serno']:'';
$submit=isset($_REQUEST['submit'])?$_REQUEST['submit']:"[NOT SET]";
switch ($submit) {
case "New":
require("new.php");
break;
case "Edit":
require("edit.php");
break;
case "Browse":
require("browse.php");
break;
case "Log":
require("brlog.php");
break;
default:
require("badsubmit.php");
break;
}
?>

View file

@ -0,0 +1,38 @@
<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?>
<?php
// (C) Copyright 2001
// Murray Jensen <Murray.Jensen@csiro.au>
// CSIRO Manufacturing Science and Technology, Preston Lab
require("defs.php");
pg_head("$bddb_label");
?>
<font size="+4">
<form action=execute.php method=POST>
<table width="100%" cellspacing=10 cellpadding=10>
<tr>
<td align=center>
<input type=submit name=submit value="New"></input>
</td>
<td align=center>
<input type=submit name=submit value="Edit"></input>
</td>
<td align=center>
<input type=submit name=submit value="Browse"></input>
</td>
<td align=center>
<input type=submit name=submit value="Log"></input>
</td>
</tr>
<tr>
<td align=center colspan=4>
<b>Serial Number:</b>
<input type=text name=serno size=10 maxsize=10 value=""></input>
</td>
</tr>
</table>
</form>
</font>
<?php
pg_foot();
?>

View file

@ -0,0 +1,120 @@
<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?>
<?php
// (C) Copyright 2001
// Murray Jensen <Murray.Jensen@csiro.au>
// CSIRO Manufacturing Science and Technology, Preston Lab
// edit page (hymod_bddb / boards)
require("defs.php");
pg_head("$bddb_label - New Board Registration");
?>
<form action=donew.php method=POST>
<p></p>
<?php
$serno=intval($serno);
// if a serial number was supplied, fetch the record
// and use its contents as defaults
if ($serno != 0) {
$r=mysql_query("select * from boards where serno=$serno");
$row=mysql_fetch_array($r);
if(!$row)die("no record of serial number '$serno' in database");
}
else
$row = array();
begin_table(5);
// date date
print_field("date", array('date' => date("Y-m-d")));
// batch char(32)
print_field("batch", $row, 32);
// type enum('IO','CLP','DSP','INPUT','ALT-INPUT','DISPLAY')
print_enum("type", $row, $type_vals, 0);
// rev tinyint(3) unsigned zerofill
print_field("rev", $row, 3, 'rev_filter');
// sdram[0-3] enum('32M','64M','128M','256M')
print_enum_multi("sdram", $row, $sdram_vals, 4, array(2));
// flash[0-3] enum('4M','8M','16M','32M','64M')
print_enum_multi("flash", $row, $flash_vals, 4, array(2));
// zbt[0-f] enum('512K','1M','2M','4M')
print_enum_multi("zbt", $row, $zbt_vals, 16, array(2, 2));
// xlxtyp[0-3] enum('XCV300E','XCV400E','XCV600E')
print_enum_multi("xlxtyp", $row, $xlxtyp_vals, 4, array(1), 1);
// xlxspd[0-3] enum('6','7','8')
print_enum_multi("xlxspd", $row, $xlxspd_vals, 4, array(1), 1);
// xlxtmp[0-3] enum('COM','IND')
print_enum_multi("xlxtmp", $row, $xlxtmp_vals, 4, array(1), 1);
// xlxgrd[0-3] enum('NORMAL','ENGSAMP')
print_enum_multi("xlxgrd", $row, $xlxgrd_vals, 4, array(1), 1);
// cputyp enum('MPC8260(HIP3)','MPC8260A(HIP4)','MPC8280(HIP7)')
print_enum("cputyp", $row, $cputyp_vals, 1);
// cpuspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ','233MHZ','266MHZ')
print_enum_select("cpuspd", $row, $clk_vals, 4);
// cpmspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ','233MHZ','266MHZ')
print_enum_select("cpmspd", $row, $clk_vals, 4);
// busspd enum('33MHZ','66MHZ','100MHZ','133MHZ','166MHZ','200MHZ','233MHZ','266MHZ')
print_enum_select("busspd", $row, $clk_vals, 2);
// hstype enum('AMCC-S2064A')
print_enum("hstype", $row, $hstype_vals, 1);
// hschin enum('0','1','2','3','4')
print_enum("hschin", $row, $hschin_vals, 4);
// hschout enum('0','1','2','3','4')
print_enum("hschout", $row, $hschout_vals, 4);
end_table();
?>
<p></p>
<table width="100%">
<tr>
<td align=center colspan=3>
Allocate
<input type=text name=quant size=2 maxlength=2 value=" 1">
board serial number(s)
</td>
</tr>
<tr>
<td align=center colspan=3>
<input type=checkbox name=geneths checked>
Generate Ethernet Address(es)
</td>
</tr>
<tr>
<td colspan=3>
&nbsp;
</td>
</tr>
<tr>
<td align=center>
<input type=submit value="Register Board">
</td>
<td>
&nbsp;
</td>
<td align=center>
<input type=reset value="Reset Form Contents">
</td>
</tr>
</table>
</form>
<?php
pg_foot();
?>

View file

@ -0,0 +1,54 @@
<?php // php pages made with phpMyBuilder <http://kyber.dk/phpMyBuilder> ?>
<?php
// (C) Copyright 2001
// Murray Jensen <Murray.Jensen@csiro.au>
// CSIRO Manufacturing Science and Technology, Preston Lab
// edit page (hymod_bddb / boards)
require("defs.php");
pg_head("$bddb_label - New Log Entry");
if (!isset($_REQUEST['serno']) || $_REQUEST['serno'] == '')
die("serial number not specified or invalid!");
$serno=intval($_REQUEST['serno']);
if (isset($_REQUEST['logno'])) {
$logno=$_REQUEST['logno'];
die("log number must not be specified when adding! ($logno)");
}
?>
<form action=donewlog.php method=POST>
<p></p>
<?php
echo "<input type=hidden name=serno value=$serno>\n";
begin_table(3);
// date date
print_field("date", array('date' => date("Y-m-d")));
// who char(20)
print_field("who", array());
// details text
print_field_multiline("details", array(), 60, 10, 'text_filter');
end_table();
?>
<p></p>
<table width="100%">
<tr>
<td align=center>
<input type=submit value="Add Log Entry">
</td>
<td align=center>
<input type=reset value="Reset Form Contents">
</td>
</tr>
</table>
</form>
<?php
pg_foot();
?>

View file

@ -0,0 +1,56 @@
/* bin2header.c - program to convert binary file into a C structure
* definition to be included in a header file.
*
* (C) Copyright 2008 by Harald Welte <laforge@openmoko.org>
*
* 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 <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
if (argc < 2) {
fprintf(stderr, "%s needs one argument: the structure name\n",
argv[0]);
exit(1);
}
printf("/* bin2header output - automatically generated */\n");
printf("unsigned char %s[] = {\n", argv[1]);
while (1) {
int i, nread;
unsigned char buf[10];
nread = read(0, buf, sizeof(buf));
if (nread <= 0)
break;
printf("\t");
for (i = 0; i < nread - 1; i++)
printf("0x%02x, ", buf[i]);
printf("0x%02x,\n", buf[nread-1]);
}
printf("};\n");
exit(0);
}

View file

@ -0,0 +1,203 @@
#include "compiler.h"
enum {
MODE_GEN_INFO,
MODE_GEN_DATA
};
typedef struct bitmap_s { /* bitmap description */
uint16_t width;
uint16_t height;
uint8_t palette[256*3];
uint8_t *data;
} bitmap_t;
#define DEFAULT_CMAP_SIZE 16 /* size of default color map */
void usage(const char *prog)
{
fprintf(stderr, "Usage: %s [--gen-info|--gen-data] file\n", prog);
}
/*
* Neutralize little endians.
*/
uint16_t le_short(uint16_t x)
{
uint16_t val;
uint8_t *p = (uint8_t *)(&x);
val = (*p++ & 0xff) << 0;
val |= (*p & 0xff) << 8;
return val;
}
void skip_bytes (FILE *fp, int n)
{
while (n-- > 0)
fgetc (fp);
}
__attribute__ ((__noreturn__))
int error (char * msg, FILE *fp)
{
fprintf (stderr, "ERROR: %s\n", msg);
fclose (fp);
exit (EXIT_FAILURE);
}
void gen_info(bitmap_t *b, uint16_t n_colors)
{
printf("/*\n"
" * Automatically generated by \"tools/bmp_logo\"\n"
" *\n"
" * DO NOT EDIT\n"
" *\n"
" */\n\n\n"
"#ifndef __BMP_LOGO_H__\n"
"#define __BMP_LOGO_H__\n\n"
"#define BMP_LOGO_WIDTH\t\t%d\n"
"#define BMP_LOGO_HEIGHT\t\t%d\n"
"#define BMP_LOGO_COLORS\t\t%d\n"
"#define BMP_LOGO_OFFSET\t\t%d\n\n"
"extern unsigned short bmp_logo_palette[];\n"
"extern unsigned char bmp_logo_bitmap[];\n\n"
"#endif /* __BMP_LOGO_H__ */\n",
b->width, b->height, n_colors,
DEFAULT_CMAP_SIZE);
}
int main (int argc, char *argv[])
{
int mode, i, x;
FILE *fp;
bitmap_t bmp;
bitmap_t *b = &bmp;
uint16_t data_offset, n_colors;
if (argc < 3) {
usage(argv[0]);
exit (EXIT_FAILURE);
}
if (!strcmp(argv[1], "--gen-info"))
mode = MODE_GEN_INFO;
else if (!strcmp(argv[1], "--gen-data"))
mode = MODE_GEN_DATA;
else {
usage(argv[0]);
exit(EXIT_FAILURE);
}
fp = fopen(argv[2], "rb");
if (!fp) {
perror(argv[2]);
exit (EXIT_FAILURE);
}
if (fgetc (fp) != 'B' || fgetc (fp) != 'M')
error ("Input file is not a bitmap", fp);
/*
* read width and height of the image, and the number of colors used;
* ignore the rest
*/
skip_bytes (fp, 8);
if (fread (&data_offset, sizeof (uint16_t), 1, fp) != 1)
error ("Couldn't read bitmap data offset", fp);
skip_bytes (fp, 6);
if (fread (&b->width, sizeof (uint16_t), 1, fp) != 1)
error ("Couldn't read bitmap width", fp);
skip_bytes (fp, 2);
if (fread (&b->height, sizeof (uint16_t), 1, fp) != 1)
error ("Couldn't read bitmap height", fp);
skip_bytes (fp, 22);
if (fread (&n_colors, sizeof (uint16_t), 1, fp) != 1)
error ("Couldn't read bitmap colors", fp);
skip_bytes (fp, 6);
/*
* Repair endianess.
*/
data_offset = le_short(data_offset);
b->width = le_short(b->width);
b->height = le_short(b->height);
n_colors = le_short(n_colors);
/* assume we are working with an 8-bit file */
if ((n_colors == 0) || (n_colors > 256 - DEFAULT_CMAP_SIZE)) {
/* reserve DEFAULT_CMAP_SIZE color map entries for default map */
n_colors = 256 - DEFAULT_CMAP_SIZE;
}
if (mode == MODE_GEN_INFO) {
gen_info(b, n_colors);
goto out;
}
printf("/*\n"
" * Automatically generated by \"tools/bmp_logo\"\n"
" *\n"
" * DO NOT EDIT\n"
" *\n"
" */\n\n\n"
"#ifndef __BMP_LOGO_DATA_H__\n"
"#define __BMP_LOGO_DATA_H__\n\n");
/* allocate memory */
if ((b->data = (uint8_t *)malloc(b->width * b->height)) == NULL)
error ("Error allocating memory for file", fp);
/* read and print the palette information */
printf("unsigned short bmp_logo_palette[] = {\n");
for (i=0; i<n_colors; ++i) {
b->palette[(int)(i*3+2)] = fgetc(fp);
b->palette[(int)(i*3+1)] = fgetc(fp);
b->palette[(int)(i*3+0)] = fgetc(fp);
x=fgetc(fp);
printf ("%s0x0%X%X%X,%s",
((i%8) == 0) ? "\t" : " ",
(b->palette[(int)(i*3+0)] >> 4) & 0x0F,
(b->palette[(int)(i*3+1)] >> 4) & 0x0F,
(b->palette[(int)(i*3+2)] >> 4) & 0x0F,
((i%8) == 7) ? "\n" : ""
);
}
/* seek to offset indicated by file header */
fseek(fp, (long)data_offset, SEEK_SET);
/* read the bitmap; leave room for default color map */
printf ("\n");
printf ("};\n");
printf ("\n");
printf("unsigned char bmp_logo_bitmap[] = {\n");
for (i=(b->height-1)*b->width; i>=0; i-=b->width) {
for (x = 0; x < b->width; x++) {
b->data[(uint16_t) i + x] = (uint8_t) fgetc (fp) \
+ DEFAULT_CMAP_SIZE;
}
}
for (i=0; i<(b->height*b->width); ++i) {
if ((i%8) == 0)
putchar ('\t');
printf ("0x%02X,%c",
b->data[i],
((i%8) == 7) ? '\n' : ' '
);
}
printf ("\n"
"};\n\n"
"#endif /* __BMP_LOGO_DATA_H__ */\n"
);
out:
fclose(fp);
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,171 @@
#!/usr/bin/perl
# Check the stack usage of functions
#
# Copyright Joern Engel <joern@lazybastard.org>
# Inspired by Linus Torvalds
# Original idea maybe from Keith Owens
# s390 port and big speedup by Arnd Bergmann <arnd@bergmann-dalldorf.de>
# Mips port by Juan Quintela <quintela@mandrakesoft.com>
# IA64 port via Andreas Dilger
# Arm port by Holger Schurig
# sh64 port by Paul Mundt
# Random bits by Matt Mackall <mpm@selenic.com>
# M68k port by Geert Uytterhoeven and Andreas Schwab
# AVR32 port by Haavard Skinnemoen (Atmel)
# PARISC port by Kyle McMartin <kyle@parisc-linux.org>
# sparc port by Martin Habets <errandir_news@mph.eclipse.co.uk>
#
# Usage:
# objdump -d vmlinux | scripts/checkstack.pl [arch]
#
# TODO : Port to all architectures (one regex per arch)
use strict;
# check for arch
#
# $re is used for two matches:
# $& (whole re) matches the complete objdump line with the stack growth
# $1 (first bracket) matches the size of the stack growth
#
# $dre is similar, but for dynamic stack redutions:
# $& (whole re) matches the complete objdump line with the stack growth
# $1 (first bracket) matches the dynamic amount of the stack growth
#
# use anything else and feel the pain ;)
my (@stack, $re, $dre, $x, $xs);
{
my $arch = shift;
if ($arch eq "") {
$arch = `uname -m`;
chomp($arch);
}
$x = "[0-9a-f]"; # hex character
$xs = "[0-9a-f ]"; # hex character or space
if ($arch eq 'arm') {
#c0008ffc: e24dd064 sub sp, sp, #100 ; 0x64
$re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o;
} elsif ($arch eq 'avr32') {
#8000008a: 20 1d sub sp,4
#80000ca8: fa cd 05 b0 sub sp,sp,1456
$re = qr/^.*sub.*sp.*,([0-9]{1,8})/o;
} elsif ($arch =~ /^i[3456]86$/) {
#c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp
$re = qr/^.*[as][du][db] \$(0x$x{1,8}),\%esp$/o;
$dre = qr/^.*[as][du][db] (%.*),\%esp$/o;
} elsif ($arch eq 'x86_64') {
# 2f60: 48 81 ec e8 05 00 00 sub $0x5e8,%rsp
$re = qr/^.*[as][du][db] \$(0x$x{1,8}),\%rsp$/o;
$dre = qr/^.*[as][du][db] (\%.*),\%rsp$/o;
} elsif ($arch eq 'ia64') {
#e0000000044011fc: 01 0f fc 8c adds r12=-384,r12
$re = qr/.*adds.*r12=-(([0-9]{2}|[3-9])[0-9]{2}),r12/o;
} elsif ($arch eq 'm68k') {
# 2b6c: 4e56 fb70 linkw %fp,#-1168
# 1df770: defc ffe4 addaw #-28,%sp
$re = qr/.*(?:linkw %fp,|addaw )#-([0-9]{1,4})(?:,%sp)?$/o;
} elsif ($arch eq 'mips64') {
#8800402c: 67bdfff0 daddiu sp,sp,-16
$re = qr/.*daddiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
} elsif ($arch eq 'mips') {
#88003254: 27bdffe0 addiu sp,sp,-32
$re = qr/.*addiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
} elsif ($arch eq 'parisc' || $arch eq 'parisc64') {
$re = qr/.*ldo ($x{1,8})\(sp\),sp/o;
} elsif ($arch eq 'ppc') {
#c00029f4: 94 21 ff 30 stwu r1,-208(r1)
$re = qr/.*stwu.*r1,-($x{1,8})\(r1\)/o;
} elsif ($arch eq 'ppc64') {
#XXX
$re = qr/.*stdu.*r1,-($x{1,8})\(r1\)/o;
} elsif ($arch eq 'powerpc') {
$re = qr/.*st[dw]u.*r1,-($x{1,8})\(r1\)/o;
} elsif ($arch =~ /^s390x?$/) {
# 11160: a7 fb ff 60 aghi %r15,-160
# or
# 100092: e3 f0 ff c8 ff 71 lay %r15,-56(%r15)
$re = qr/.*(?:lay|ag?hi).*\%r15,-(([0-9]{2}|[3-9])[0-9]{2})
(?:\(\%r15\))?$/ox;
} elsif ($arch =~ /^sh64$/) {
#XXX: we only check for the immediate case presently,
# though we will want to check for the movi/sub
# pair for larger users. -- PFM.
#a00048e0: d4fc40f0 addi.l r15,-240,r15
$re = qr/.*addi\.l.*r15,-(([0-9]{2}|[3-9])[0-9]{2}),r15/o;
} elsif ($arch =~ /^blackfin$/) {
# 0: 00 e8 38 01 LINK 0x4e0;
$re = qr/.*[[:space:]]LINK[[:space:]]*(0x$x{1,8})/o;
} elsif ($arch eq 'sparc' || $arch eq 'sparc64') {
# f0019d10: 9d e3 bf 90 save %sp, -112, %sp
$re = qr/.*save.*%sp, -(([0-9]{2}|[3-9])[0-9]{2}), %sp/o;
} else {
print("wrong or unknown architecture \"$arch\"\n");
exit
}
}
#
# main()
#
my $funcre = qr/^$x* <(.*)>:$/;
my ($func, $file, $lastslash);
while (my $line = <STDIN>) {
if ($line =~ m/$funcre/) {
$func = $1;
}
elsif ($line =~ m/(.*):\s*file format/) {
$file = $1;
$file =~ s/\.ko//;
$lastslash = rindex($file, "/");
if ($lastslash != -1) {
$file = substr($file, $lastslash + 1);
}
}
elsif ($line =~ m/$re/) {
my $size = $1;
$size = hex($size) if ($size =~ /^0x/);
if ($size > 0xf0000000) {
$size = - $size;
$size += 0x80000000;
$size += 0x80000000;
}
next if ($size > 0x10000000);
next if $line !~ m/^($xs*)/;
my $addr = $1;
$addr =~ s/ /0/g;
$addr = "0x$addr";
my $intro = "$addr $func [$file]:";
my $padlen = 56 - length($intro);
while ($padlen > 0) {
$intro .= ' ';
$padlen -= 8;
}
next if ($size < 100);
push @stack, "$intro$size\n";
}
elsif (defined $dre && $line =~ m/$dre/) {
my $size = "Dynamic ($1)";
next if $line !~ m/^($xs*)/;
my $addr = $1;
$addr =~ s/ /0/g;
$addr = "0x$addr";
my $intro = "$addr $func [$file]:";
my $padlen = 56 - length($intro);
while ($padlen > 0) {
$intro .= ' ';
$padlen -= 8;
}
push @stack, "$intro$size\n";
}
}
# Sort output by size (last field)
print sort { ($b =~ /:\t*(\d+)$/)[0] <=> ($a =~ /:\t*(\d+)$/)[0] } @stack;

View file

@ -0,0 +1,207 @@
/*
* (C) Copyright 2008 Semihalf
*
* (C) Copyright 2000-2004
* DENX Software Engineering
* Wolfgang Denk, wd@denx.de
*
* Updated-by: Prafulla Wadaskar <prafulla@marvell.com>
* default_image specific code abstracted from mkimage.c
* some functions added to address abstraction
*
* All rights reserved.
*
* 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 "imagetool.h"
#include <image.h>
#include <u-boot/crc.h>
static image_header_t header;
static int image_check_image_types(uint8_t type)
{
if (((type > IH_TYPE_INVALID) && (type < IH_TYPE_FLATDT)) ||
(type == IH_TYPE_KERNEL_NOLOAD))
return EXIT_SUCCESS;
else
return EXIT_FAILURE;
}
static int image_check_params(struct image_tool_params *params)
{
return ((params->dflag && (params->fflag || params->lflag)) ||
(params->fflag && (params->dflag || params->lflag)) ||
(params->lflag && (params->dflag || params->fflag)));
}
static int image_verify_header(unsigned char *ptr, int image_size,
struct image_tool_params *params)
{
uint32_t len;
const unsigned char *data;
uint32_t checksum;
image_header_t header;
image_header_t *hdr = &header;
/*
* create copy of header so that we can blank out the
* checksum field for checking - this can't be done
* on the PROT_READ mapped data.
*/
memcpy(hdr, ptr, sizeof(image_header_t));
if (be32_to_cpu(hdr->ih_magic) != IH_MAGIC) {
fprintf(stderr,
"%s: Bad Magic Number: \"%s\" is no valid image\n",
params->cmdname, params->imagefile);
return -FDT_ERR_BADMAGIC;
}
data = (const unsigned char *)hdr;
len = sizeof(image_header_t);
checksum = be32_to_cpu(hdr->ih_hcrc);
hdr->ih_hcrc = cpu_to_be32(0); /* clear for re-calculation */
if (crc32(0, data, len) != checksum) {
fprintf(stderr,
"%s: ERROR: \"%s\" has bad header checksum!\n",
params->cmdname, params->imagefile);
return -FDT_ERR_BADSTATE;
}
data = (const unsigned char *)ptr + sizeof(image_header_t);
len = image_size - sizeof(image_header_t) ;
checksum = be32_to_cpu(hdr->ih_dcrc);
if (crc32(0, data, len) != checksum) {
fprintf(stderr,
"%s: ERROR: \"%s\" has corrupted data!\n",
params->cmdname, params->imagefile);
return -FDT_ERR_BADSTRUCTURE;
}
return 0;
}
static void image_set_header(void *ptr, struct stat *sbuf, int ifd,
struct image_tool_params *params)
{
uint32_t checksum;
image_header_t * hdr = (image_header_t *)ptr;
checksum = crc32(0,
(const unsigned char *)(ptr +
sizeof(image_header_t)),
sbuf->st_size - sizeof(image_header_t));
/* Build new header */
image_set_magic(hdr, IH_MAGIC);
image_set_time(hdr, sbuf->st_mtime);
image_set_size(hdr, sbuf->st_size - sizeof(image_header_t));
image_set_load(hdr, params->addr);
image_set_ep(hdr, params->ep);
image_set_dcrc(hdr, checksum);
image_set_os(hdr, params->os);
image_set_arch(hdr, params->arch);
image_set_type(hdr, params->type);
image_set_comp(hdr, params->comp);
image_set_name(hdr, params->imagename);
checksum = crc32(0, (const unsigned char *)hdr,
sizeof(image_header_t));
image_set_hcrc(hdr, checksum);
}
static int image_save_datafile(struct image_tool_params *params,
ulong file_data, ulong file_len)
{
int dfd;
const char *datafile = params->outfile;
dfd = open(datafile, O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
S_IRUSR | S_IWUSR);
if (dfd < 0) {
fprintf(stderr, "%s: Can't open \"%s\": %s\n",
params->cmdname, datafile, strerror(errno));
return -1;
}
if (write(dfd, (void *)file_data, file_len) != (ssize_t)file_len) {
fprintf(stderr, "%s: Write error on \"%s\": %s\n",
params->cmdname, datafile, strerror(errno));
close(dfd);
return -1;
}
close(dfd);
return 0;
}
static int image_extract_datafile(void *ptr, struct image_tool_params *params)
{
const image_header_t *hdr = (const image_header_t *)ptr;
ulong file_data;
ulong file_len;
if (image_check_type(hdr, IH_TYPE_MULTI)) {
ulong idx = params->pflag;
ulong count;
/* get the number of data files present in the image */
count = image_multi_count(hdr);
/* retrieve the "data file" at the idx position */
image_multi_getimg(hdr, idx, &file_data, &file_len);
if ((file_len == 0) || (idx >= count)) {
fprintf(stderr, "%s: No such data file %ld in \"%s\"\n",
params->cmdname, idx, params->imagefile);
return -1;
}
} else {
file_data = image_get_data(hdr);
file_len = image_get_size(hdr);
}
/* save the "data file" into the file system */
return image_save_datafile(params, file_data, file_len);
}
/*
* Default image type parameters definition
*/
static struct image_type_params defimage_params = {
.name = "Default Image support",
.header_size = sizeof(image_header_t),
.hdr = (void*)&header,
.check_image_type = image_check_image_types,
.verify_header = image_verify_header,
.print_header = image_print_contents,
.set_header = image_set_header,
.extract_datafile = image_extract_datafile,
.check_params = image_check_params,
};
void init_default_image_type(void)
{
register_image_type(&defimage_params);
}

View file

@ -0,0 +1,306 @@
/*
* Based on mkimage.c.
*
* Written by Guilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include "dumpimage.h"
#include <image.h>
#include <version.h>
static void usage(void);
/* image_type_params linked list to maintain registered image types supports */
static struct image_type_params *dumpimage_tparams;
/* parameters initialized by core will be used by the image type code */
static struct image_tool_params params = {
.type = IH_TYPE_KERNEL,
};
/**
* dumpimage_register() - register respective image generation/list support
*
* the input struct image_type_params is checked and appended to the link
* list, if the input structure is already registered, issue an error
*
* @tparams: Image type parameters
*/
static void dumpimage_register(struct image_type_params *tparams)
{
struct image_type_params **tp;
if (!tparams) {
fprintf(stderr, "%s: %s: Null input\n", params.cmdname,
__func__);
exit(EXIT_FAILURE);
}
/* scan the linked list, check for registry and point the last one */
for (tp = &dumpimage_tparams; *tp != NULL; tp = &(*tp)->next) {
if (!strcmp((*tp)->name, tparams->name)) {
fprintf(stderr, "%s: %s already registered\n",
params.cmdname, tparams->name);
return;
}
}
/* add input struct entry at the end of link list */
*tp = tparams;
/* mark input entry as last entry in the link list */
tparams->next = NULL;
debug("Registered %s\n", tparams->name);
}
/**
* dumpimage_get_type() - find the image type params for a given image type
*
* Scan all registered image types and check the input type_id for each
* supported image type
*
* @return respective image_type_params pointer. If the input type is not
* supported by any of registered image types, returns NULL
*/
static struct image_type_params *dumpimage_get_type(int type)
{
struct image_type_params *curr;
for (curr = dumpimage_tparams; curr != NULL; curr = curr->next) {
if (curr->check_image_type) {
if (!curr->check_image_type(type))
return curr;
}
}
return NULL;
}
/*
* dumpimage_verify_print_header() - verifies the image header
*
* Scan registered image types and verify the image_header for each
* supported image type. If verification is successful, this prints
* the respective header.
*
* @return 0 on success, negative if input image format does not match with
* any of supported image types
*/
static int dumpimage_verify_print_header(void *ptr, struct stat *sbuf)
{
int retval = -1;
struct image_type_params *curr;
for (curr = dumpimage_tparams; curr != NULL; curr = curr->next) {
if (curr->verify_header) {
retval = curr->verify_header((unsigned char *)ptr,
sbuf->st_size, &params);
if (retval != 0)
continue;
/*
* Print the image information if verify is
* successful
*/
if (curr->print_header) {
curr->print_header(ptr);
} else {
fprintf(stderr,
"%s: print_header undefined for %s\n",
params.cmdname, curr->name);
}
break;
}
}
return retval;
}
/*
* dumpimage_extract_datafile -
*
* It scans all registered image types,
* verifies image_header for each supported image type
* if verification is successful, it extracts the desired file,
* indexed by pflag, from the image
*
* returns negative if input image format does not match with any of
* supported image types
*/
static int dumpimage_extract_datafile(void *ptr, struct stat *sbuf)
{
int retval = -1;
struct image_type_params *curr;
for (curr = dumpimage_tparams; curr != NULL; curr = curr->next) {
if (curr->verify_header) {
retval = curr->verify_header((unsigned char *)ptr,
sbuf->st_size, &params);
if (retval != 0)
continue;
/*
* Extract the file from the image
* if verify is successful
*/
if (curr->extract_datafile) {
retval = curr->extract_datafile(ptr, &params);
break;
} else {
fprintf(stderr,
"%s: extract_datafile undefined for %s\n",
params.cmdname, curr->name);
break;
}
}
}
return retval;
}
int main(int argc, char **argv)
{
int opt;
int ifd = -1;
struct stat sbuf;
char *ptr;
int retval = 0;
struct image_type_params *tparams = NULL;
/* Init all image generation/list support */
register_image_tool(dumpimage_register);
params.cmdname = *argv;
while ((opt = getopt(argc, argv, "li:o:p:V")) != -1) {
switch (opt) {
case 'l':
params.lflag = 1;
break;
case 'i':
params.imagefile = optarg;
params.iflag = 1;
break;
case 'o':
params.outfile = optarg;
break;
case 'p':
params.pflag = strtoul(optarg, &ptr, 10);
if (*ptr) {
fprintf(stderr,
"%s: invalid file position %s\n",
params.cmdname, *argv);
exit(EXIT_FAILURE);
}
break;
case 'V':
printf("dumpimage version %s\n", PLAIN_VERSION);
exit(EXIT_SUCCESS);
default:
usage();
}
}
if (optind >= argc)
usage();
/* set tparams as per input type_id */
tparams = dumpimage_get_type(params.type);
if (tparams == NULL) {
fprintf(stderr, "%s: unsupported type %s\n",
params.cmdname, genimg_get_type_name(params.type));
exit(EXIT_FAILURE);
}
/*
* check the passed arguments parameters meets the requirements
* as per image type to be generated/listed
*/
if (tparams->check_params) {
if (tparams->check_params(&params))
usage();
}
if (params.iflag)
params.datafile = argv[optind];
else
params.imagefile = argv[optind];
if (!params.outfile)
params.outfile = params.datafile;
ifd = open(params.imagefile, O_RDONLY|O_BINARY);
if (ifd < 0) {
fprintf(stderr, "%s: Can't open \"%s\": %s\n",
params.cmdname, params.imagefile,
strerror(errno));
exit(EXIT_FAILURE);
}
if (params.lflag || params.iflag) {
if (fstat(ifd, &sbuf) < 0) {
fprintf(stderr, "%s: Can't stat \"%s\": %s\n",
params.cmdname, params.imagefile,
strerror(errno));
exit(EXIT_FAILURE);
}
if ((unsigned)sbuf.st_size < tparams->header_size) {
fprintf(stderr,
"%s: Bad size: \"%s\" is not valid image\n",
params.cmdname, params.imagefile);
exit(EXIT_FAILURE);
}
ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0);
if (ptr == MAP_FAILED) {
fprintf(stderr, "%s: Can't read \"%s\": %s\n",
params.cmdname, params.imagefile,
strerror(errno));
exit(EXIT_FAILURE);
}
/*
* Both calls bellow scan through dumpimage registry for all
* supported image types and verify the input image file
* header for match
*/
if (params.iflag) {
/*
* Extract the data files from within the matched
* image type. Returns the error code if not matched
*/
retval = dumpimage_extract_datafile(ptr, &sbuf);
} else {
/*
* Print the image information for matched image type
* Returns the error code if not matched
*/
retval = dumpimage_verify_print_header(ptr, &sbuf);
}
(void)munmap((void *)ptr, sbuf.st_size);
(void)close(ifd);
return retval;
}
(void)close(ifd);
return EXIT_SUCCESS;
}
static void usage(void)
{
fprintf(stderr, "Usage: %s -l image\n"
" -l ==> list image header information\n",
params.cmdname);
fprintf(stderr,
" %s -i image [-p position] [-o outfile] data_file\n"
" -i ==> extract from the 'image' a specific 'data_file'"
", indexed by 'position' (starting at 0)\n",
params.cmdname);
fprintf(stderr,
" %s -V ==> print version information and exit\n",
params.cmdname);
exit(EXIT_FAILURE);
}

View file

@ -0,0 +1,33 @@
/*
* Based on mkimage.c.
*
* Written by Guilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _DUMPIMAGE_H_
#define _DUMPIMAGE_H_
#include "os_support.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include <u-boot-sha1.h>
#include "fdt_host.h"
#include "imagetool.h"
#undef DUMPIMAGE_DEBUG
#ifdef DUMPIMAGE_DEBUG
#define debug(fmt, args...) printf(fmt, ##args)
#else
#define debug(fmt, args...)
#endif /* DUMPIMAGE_DEBUG */
#endif /* _DUMPIMAGE_H_ */

View file

@ -0,0 +1,11 @@
include $(TOPDIR)/config.mk
all: $(obj)easylogo
$(obj)easylogo: $(SRCTREE)/tools/easylogo/easylogo.c
$(HOSTCC) $(HOSTCFLAGS_NOPED) $(HOSTLDFLAGS) -o $@ $^
clean:
rm -f $(obj)easylogo
.PHONY: all clean

View file

@ -0,0 +1,610 @@
/*
** Easylogo TGA->header converter
** ==============================
** (C) 2000 by Paolo Scaffardi (arsenio@tin.it)
** AIRVENT SAM s.p.a - RIMINI(ITALY)
** (C) 2007-2008 Mike Frysinger <vapier@gentoo.org>
**
** This is still under construction!
*/
#include <errno.h>
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#pragma pack(1)
/*#define ENABLE_ASCII_BANNERS */
typedef struct {
unsigned char id;
unsigned char ColorMapType;
unsigned char ImageTypeCode;
unsigned short ColorMapOrigin;
unsigned short ColorMapLenght;
unsigned char ColorMapEntrySize;
unsigned short ImageXOrigin;
unsigned short ImageYOrigin;
unsigned short ImageWidth;
unsigned short ImageHeight;
unsigned char ImagePixelSize;
unsigned char ImageDescriptorByte;
} tga_header_t;
typedef struct {
unsigned char r, g, b;
} rgb_t;
typedef struct {
unsigned char b, g, r;
} bgr_t;
typedef struct {
unsigned char Cb, y1, Cr, y2;
} yuyv_t;
typedef struct {
void *data, *palette;
int width, height, pixels, bpp, pixel_size, size, palette_size, yuyv;
} image_t;
void *xmalloc (size_t size)
{
void *ret = malloc (size);
if (!ret) {
fprintf (stderr, "\nerror: malloc(%zu) failed: %s",
size, strerror(errno));
exit (1);
}
return ret;
}
void StringUpperCase (char *str)
{
int count = strlen (str);
char c;
while (count--) {
c = *str;
if ((c >= 'a') && (c <= 'z'))
*str = 'A' + (c - 'a');
str++;
}
}
void StringLowerCase (char *str)
{
int count = strlen (str);
char c;
while (count--) {
c = *str;
if ((c >= 'A') && (c <= 'Z'))
*str = 'a' + (c - 'A');
str++;
}
}
void pixel_rgb_to_yuyv (rgb_t * rgb_pixel, yuyv_t * yuyv_pixel)
{
unsigned int pR, pG, pB;
/* Transform (0-255) components to (0-100) */
pR = rgb_pixel->r * 100 / 255;
pG = rgb_pixel->g * 100 / 255;
pB = rgb_pixel->b * 100 / 255;
/* Calculate YUV values (0-255) from RGB beetween 0-100 */
yuyv_pixel->y1 = yuyv_pixel->y2 = 209 * (pR + pG + pB) / 300 + 16;
yuyv_pixel->Cb = pB - (pR / 4) - (pG * 3 / 4) + 128;
yuyv_pixel->Cr = pR - (pG * 3 / 4) - (pB / 4) + 128;
return;
}
void printlogo_rgb (rgb_t * data, int w, int h)
{
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++, data++)
if ((data->r <
30) /*&&(data->g == 0)&&(data->b == 0) */ )
printf (" ");
else
printf ("X");
printf ("\n");
}
}
void printlogo_yuyv (unsigned short *data, int w, int h)
{
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++, data++)
if (*data == 0x1080) /* Because of inverted on i386! */
printf (" ");
else
printf ("X");
printf ("\n");
}
}
static inline unsigned short le16_to_cpu (unsigned short val)
{
union {
unsigned char pval[2];
unsigned short val;
} swapped;
swapped.val = val;
return (swapped.pval[1] << 8) + swapped.pval[0];
}
int image_load_tga (image_t * image, char *filename)
{
FILE *file;
tga_header_t header;
int i;
unsigned char app;
rgb_t *p;
if ((file = fopen (filename, "rb")) == NULL)
return -1;
fread (&header, sizeof (header), 1, file);
/* byte swap: tga is little endian, host is ??? */
header.ColorMapOrigin = le16_to_cpu (header.ColorMapOrigin);
header.ColorMapLenght = le16_to_cpu (header.ColorMapLenght);
header.ImageXOrigin = le16_to_cpu (header.ImageXOrigin);
header.ImageYOrigin = le16_to_cpu (header.ImageYOrigin);
header.ImageWidth = le16_to_cpu (header.ImageWidth);
header.ImageHeight = le16_to_cpu (header.ImageHeight);
image->width = header.ImageWidth;
image->height = header.ImageHeight;
switch (header.ImageTypeCode) {
case 2: /* Uncompressed RGB */
image->yuyv = 0;
image->palette_size = 0;
image->palette = NULL;
break;
default:
printf ("Format not supported!\n");
return -1;
}
image->bpp = header.ImagePixelSize;
image->pixel_size = ((image->bpp - 1) / 8) + 1;
image->pixels = image->width * image->height;
image->size = image->pixels * image->pixel_size;
image->data = xmalloc (image->size);
if (image->bpp != 24) {
printf ("Bpp not supported: %d!\n", image->bpp);
return -1;
}
fread (image->data, image->size, 1, file);
/* Swapping R and B values */
p = image->data;
for (i = 0; i < image->pixels; i++, p++) {
app = p->r;
p->r = p->b;
p->b = app;
}
/* Swapping image */
if (!(header.ImageDescriptorByte & 0x20)) {
unsigned char *temp = xmalloc (image->size);
int linesize = image->pixel_size * image->width;
void *dest = image->data,
*source = temp + image->size - linesize;
printf ("S");
if (temp == NULL) {
printf ("Cannot alloc temp buffer!\n");
return -1;
}
memcpy (temp, image->data, image->size);
for (i = 0; i < image->height;
i++, dest += linesize, source -= linesize)
memcpy (dest, source, linesize);
free (temp);
}
#ifdef ENABLE_ASCII_BANNERS
printlogo_rgb (image->data, image->width, image->height);
#endif
fclose (file);
return 0;
}
void image_free (image_t * image)
{
free (image->data);
free (image->palette);
}
int image_rgb_to_yuyv (image_t * rgb_image, image_t * yuyv_image)
{
rgb_t *rgb_ptr = (rgb_t *) rgb_image->data;
yuyv_t yuyv;
unsigned short *dest;
int count = 0;
yuyv_image->pixel_size = 2;
yuyv_image->bpp = 16;
yuyv_image->yuyv = 1;
yuyv_image->width = rgb_image->width;
yuyv_image->height = rgb_image->height;
yuyv_image->pixels = yuyv_image->width * yuyv_image->height;
yuyv_image->size = yuyv_image->pixels * yuyv_image->pixel_size;
dest = (unsigned short *) (yuyv_image->data =
xmalloc (yuyv_image->size));
yuyv_image->palette = 0;
yuyv_image->palette_size = 0;
while ((count++) < rgb_image->pixels) {
pixel_rgb_to_yuyv (rgb_ptr++, &yuyv);
if ((count & 1) == 0) /* Was == 0 */
memcpy (dest, ((void *) &yuyv) + 2, sizeof (short));
else
memcpy (dest, (void *) &yuyv, sizeof (short));
dest++;
}
#ifdef ENABLE_ASCII_BANNERS
printlogo_yuyv (yuyv_image->data, yuyv_image->width,
yuyv_image->height);
#endif
return 0;
}
int image_rgb888_to_rgb565(image_t *rgb888_image, image_t *rgb565_image)
{
rgb_t *rgb_ptr = (rgb_t *) rgb888_image->data;
unsigned short *dest;
int count = 0;
rgb565_image->pixel_size = 2;
rgb565_image->bpp = 16;
rgb565_image->yuyv = 0;
rgb565_image->width = rgb888_image->width;
rgb565_image->height = rgb888_image->height;
rgb565_image->pixels = rgb565_image->width * rgb565_image->height;
rgb565_image->size = rgb565_image->pixels * rgb565_image->pixel_size;
dest = (unsigned short *) (rgb565_image->data =
xmalloc(rgb565_image->size));
rgb565_image->palette = 0;
rgb565_image->palette_size = 0;
while ((count++) < rgb888_image->pixels) {
*dest++ = ((rgb_ptr->b & 0xF8) << 8) |
((rgb_ptr->g & 0xFC) << 3) |
(rgb_ptr->r >> 3);
rgb_ptr++;
}
return 0;
}
enum comp_t {
COMP_NONE,
COMP_GZIP,
COMP_LZMA,
};
static enum comp_t compression = COMP_NONE;
static bool bss_storage = false;
int image_save_header (image_t * image, char *filename, char *varname)
{
FILE *file = fopen (filename, "w");
char app[256], str[256] = "", def_name[64];
int count = image->size, col = 0;
unsigned char *dataptr = image->data;
if (file == NULL)
return -1;
/* Author information */
fprintf (file,
"/*\n * Generated by EasyLogo, (C) 2000 by Paolo Scaffardi\n *\n");
fprintf (file,
" * To use this, include it and call: easylogo_plot(screen,&%s, width,x,y)\n *\n",
varname);
fprintf (file,
" * Where:\t'screen'\tis the pointer to the frame buffer\n");
fprintf (file, " *\t\t'width'\tis the screen width\n");
fprintf (file, " *\t\t'x'\t\tis the horizontal position\n");
fprintf (file, " *\t\t'y'\t\tis the vertical position\n */\n\n");
/* image compress */
if (compression != COMP_NONE) {
const char *errstr = NULL;
unsigned char *compressed;
const char *comp_name;
struct stat st;
FILE *compfp;
size_t filename_len = strlen(filename);
char *compfilename = xmalloc(filename_len + 20);
char *compcmd = xmalloc(filename_len + 50);
sprintf(compfilename, "%s.bin", filename);
switch (compression) {
case COMP_GZIP:
strcpy(compcmd, "gzip");
comp_name = "GZIP";
break;
case COMP_LZMA:
strcpy(compcmd, "lzma");
comp_name = "LZMA";
break;
default:
errstr = "\nerror: unknown compression method";
goto done;
}
strcat(compcmd, " > ");
strcat(compcmd, compfilename);
compfp = popen(compcmd, "w");
if (!compfp) {
errstr = "\nerror: popen() failed";
goto done;
}
if (fwrite(image->data, image->size, 1, compfp) != 1) {
errstr = "\nerror: writing data to gzip failed";
goto done;
}
if (pclose(compfp)) {
errstr = "\nerror: gzip process failed";
goto done;
}
compfp = fopen(compfilename, "r");
if (!compfp) {
errstr = "\nerror: open() on gzip data failed";
goto done;
}
if (stat(compfilename, &st)) {
errstr = "\nerror: stat() on gzip file failed";
goto done;
}
compressed = xmalloc(st.st_size);
if (fread(compressed, st.st_size, 1, compfp) != 1) {
errstr = "\nerror: reading gzip data failed";
goto done;
}
fclose(compfp);
unlink(compfilename);
dataptr = compressed;
count = st.st_size;
fprintf(file, "#define EASYLOGO_ENABLE_%s %i\n\n", comp_name, count);
if (bss_storage)
fprintf (file, "static unsigned char EASYLOGO_DECOMP_BUFFER[%i];\n\n", image->size);
done:
free(compfilename);
free(compcmd);
if (errstr) {
perror (errstr);
return -1;
}
}
/* Headers */
fprintf (file, "#include <video_easylogo.h>\n\n");
/* Macros */
strcpy (def_name, varname);
StringUpperCase (def_name);
fprintf (file, "#define DEF_%s_WIDTH\t\t%d\n", def_name,
image->width);
fprintf (file, "#define DEF_%s_HEIGHT\t\t%d\n", def_name,
image->height);
fprintf (file, "#define DEF_%s_PIXELS\t\t%d\n", def_name,
image->pixels);
fprintf (file, "#define DEF_%s_BPP\t\t%d\n", def_name, image->bpp);
fprintf (file, "#define DEF_%s_PIXEL_SIZE\t%d\n", def_name,
image->pixel_size);
fprintf (file, "#define DEF_%s_SIZE\t\t%d\n\n", def_name,
image->size);
/* Declaration */
fprintf (file, "unsigned char DEF_%s_DATA[] = {\n",
def_name);
/* Data */
while (count)
switch (col) {
case 0:
sprintf (str, " 0x%02x", *dataptr++);
col++;
count--;
break;
case 16:
fprintf (file, "%s", str);
if (count > 0)
fprintf (file, ",");
fprintf (file, "\n");
col = 0;
break;
default:
strcpy (app, str);
sprintf (str, "%s, 0x%02x", app, *dataptr++);
col++;
count--;
break;
}
if (col)
fprintf (file, "%s\n", str);
/* End of declaration */
fprintf (file, "};\n\n");
/* Variable */
fprintf (file, "fastimage_t %s = {\n", varname);
fprintf (file, " DEF_%s_DATA,\n", def_name);
fprintf (file, " DEF_%s_WIDTH,\n", def_name);
fprintf (file, " DEF_%s_HEIGHT,\n", def_name);
fprintf (file, " DEF_%s_BPP,\n", def_name);
fprintf (file, " DEF_%s_PIXEL_SIZE,\n", def_name);
fprintf (file, " DEF_%s_SIZE\n};\n", def_name);
fclose (file);
return 0;
}
#define DEF_FILELEN 256
static void usage (int exit_status)
{
puts (
"EasyLogo 1.0 (C) 2000 by Paolo Scaffardi\n"
"\n"
"Syntax: easylogo [options] inputfile [outputvar [outputfile]]\n"
"\n"
"Options:\n"
" -r Output RGB888 instead of YUYV\n"
" -s Output RGB565 instead of YUYV\n"
" -g Compress with gzip\n"
" -l Compress with lzma\n"
" -b Preallocate space in bss for decompressing image\n"
" -h Help output\n"
"\n"
"Where: 'inputfile' is the TGA image to load\n"
" 'outputvar' is the variable name to create\n"
" 'outputfile' is the output header file (default is 'inputfile.h')"
);
exit (exit_status);
}
int main (int argc, char *argv[])
{
int c;
bool use_rgb888 = false;
bool use_rgb565 = false;
char inputfile[DEF_FILELEN],
outputfile[DEF_FILELEN], varname[DEF_FILELEN];
image_t rgb888_logo, rgb565_logo, yuyv_logo;
while ((c = getopt(argc, argv, "hrsglb")) > 0) {
switch (c) {
case 'h':
usage (0);
break;
case 'r':
use_rgb888 = true;
puts("Using 24-bit RGB888 Output Fromat");
break;
case 's':
use_rgb565 = true;
puts("Using 16-bit RGB565 Output Fromat");
break;
case 'g':
compression = COMP_GZIP;
puts("Compressing with gzip");
break;
case 'l':
compression = COMP_LZMA;
puts("Compressing with lzma");
break;
case 'b':
bss_storage = true;
puts("Preallocating bss space for decompressing image");
break;
default:
usage (1);
break;
}
}
c = argc - optind;
if (c > 4 || c < 1)
usage (1);
strcpy (inputfile, argv[optind]);
if (c > 1)
strcpy (varname, argv[optind + 1]);
else {
/* transform "input.tga" to just "input" */
char *dot;
strcpy (varname, inputfile);
dot = strchr (varname, '.');
if (dot)
*dot = '\0';
}
if (c > 2)
strcpy (outputfile, argv[optind + 2]);
else {
/* just append ".h" to input file name */
strcpy (outputfile, inputfile);
strcat (outputfile, ".h");
}
/* Make sure the output is sent as soon as we printf() */
setbuf(stdout, NULL);
printf ("Doing '%s' (%s) from '%s'...",
outputfile, varname, inputfile);
/* Import TGA logo */
printf ("L");
if (image_load_tga(&rgb888_logo, inputfile) < 0) {
printf ("input file not found!\n");
exit (1);
}
/* Convert, save, and free the image */
if (!use_rgb888 && !use_rgb565) {
printf ("C");
image_rgb_to_yuyv(&rgb888_logo, &yuyv_logo);
printf("S");
image_save_header(&yuyv_logo, outputfile, varname);
image_free(&yuyv_logo);
} else if (use_rgb565) {
printf("C");
image_rgb888_to_rgb565(&rgb888_logo, &rgb565_logo);
printf("S");
image_save_header(&rgb565_logo, outputfile, varname);
image_free(&rgb565_logo);
} else {
printf("S");
image_save_header(&rgb888_logo, outputfile, varname);
}
/* Free original image and copy */
image_free(&rgb888_logo);
printf ("\n");
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -0,0 +1,4 @@
#!/bin/sh
make
./easylogo linux_logo.tga u_boot_logo video_logo.h
mv video_logo.h ../../include

View file

@ -0,0 +1,55 @@
#
# (C) Copyright 2002-2006
# 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
HOSTSRCS := $(SRCTREE)/lib/crc32.c fw_env.c fw_env_main.c
HEADERS := fw_env.h
# Compile for a hosted environment on the target
HOSTCPPFLAGS = -idirafter $(SRCTREE)/include \
-idirafter $(OBJTREE)/include2 \
-idirafter $(OBJTREE)/include \
-DUSE_HOSTCC
ifeq ($(MTD_VERSION),old)
HOSTCPPFLAGS += -DMTD_OLD
endif
all: $(obj)fw_printenv
# Some files complain if compiled with -pedantic, use HOSTCFLAGS_NOPED
$(obj)fw_printenv: $(HOSTSRCS) $(HEADERS)
$(HOSTCC) $(HOSTCFLAGS_NOPED) $(HOSTLDFLAGS) -o $@ $(HOSTSRCS)
$(HOSTSTRIP) $@
clean:
rm -f $(obj)fw_printenv
#########################################################################
include $(TOPDIR)/rules.mk
sinclude $(obj).depend
#########################################################################

View file

@ -0,0 +1,57 @@
This is a demo implementation of a Linux command line tool to access
the U-Boot's environment variables.
In the current version, there is an issue in cross-compilation.
In order to cross-compile fw_printenv, run
make HOSTCC=<your CC cross-compiler> env
in the root directory of the U-Boot distribution. For example,
make HOSTCC=arm-linux-gcc env
For the run-time utiltity configuration uncomment the line
#define CONFIG_FILE "/etc/fw_env.config"
in fw_env.h.
For building against older versions of the MTD headers (meaning before
v2.6.8-rc1) it is required to pass the argument "MTD_VERSION=old" to
make.
See comments in the fw_env.config file for definitions for the
particular board.
Configuration can also be done via #defines in the fw_env.h file. The
following lines are relevant:
#define HAVE_REDUND /* For systems with 2 env sectors */
#define DEVICE1_NAME "/dev/mtd1"
#define DEVICE2_NAME "/dev/mtd2"
#define DEVICE1_OFFSET 0x0000
#define ENV1_SIZE 0x4000
#define DEVICE1_ESIZE 0x4000
#define DEVICE1_ENVSECTORS 2
#define DEVICE2_OFFSET 0x0000
#define ENV2_SIZE 0x4000
#define DEVICE2_ESIZE 0x4000
#define DEVICE2_ENVSECTORS 2
Un-define HAVE_REDUND, if you want to use the utlities on a system
that does not have support for redundant environment enabled.
If HAVE_REDUND is undefined, DEVICE2_NAME is ignored,
as is ENV2_SIZE and DEVICE2_ESIZE.
The DEVICEx_NAME constants define which MTD character devices are to
be used to access the environment.
The DEVICEx_OFFSET constants define the environment offset within the
MTD character device.
ENVx_SIZE defines the size in bytes taken by the environment, which
may be less then flash sector size, if the environment takes less
then 1 sector.
DEVICEx_ESIZE defines the size of the first sector in the flash
partition where the environment resides.
DEVICEx_ENVSECTORS defines the number of sectors that may be used for
this environment instance. On NAND this is used to limit the range
within which bad blocks are skipped, on NOR it is not used.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,19 @@
# Configuration file for fw_(printenv/saveenv) utility.
# Up to two entries are valid, in this case the redundant
# environment sector is assumed present.
# Notice, that the "Number of sectors" is ignored on NOR and SPI-dataflash.
# Futhermore, if the Flash sector size is ommitted, this value is assumed to
# be the same as the Environment size, which is valid for NOR and SPI-dataflash
# NOR example
# MTD device name Device offset Env. size Flash sector size Number of sectors
/dev/mtd1 0x0000 0x4000 0x4000
/dev/mtd2 0x0000 0x4000 0x4000
# MTD SPI-dataflash example
# MTD device name Device offset Env. size Flash sector size Number of sectors
#/dev/mtd5 0x4200 0x4200
#/dev/mtd6 0x4200 0x4200
# NAND example
#/dev/mtd0 0x4000 0x4000 0x20000 2

View file

@ -0,0 +1,60 @@
/*
* (C) Copyright 2002-2008
* 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
*/
/*
* To build the utility with the static configuration
* comment out the next line.
* See included "fw_env.config" sample file
* for notes on configuration.
*/
#define CONFIG_FILE "/etc/fw_env.config"
#define HAVE_REDUND /* For systems with 2 env sectors */
#define DEVICE1_NAME "/dev/mtd1"
#define DEVICE2_NAME "/dev/mtd2"
#define DEVICE1_OFFSET 0x0000
#define ENV1_SIZE 0x4000
#define DEVICE1_ESIZE 0x4000
#define DEVICE1_ENVSECTORS 2
#define DEVICE2_OFFSET 0x0000
#define ENV2_SIZE 0x4000
#define DEVICE2_ESIZE 0x4000
#define DEVICE2_ENVSECTORS 2
#define CONFIG_BAUDRATE 115200
#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */
#define CONFIG_BOOTCOMMAND \
"bootp; " \
"setenv bootargs root=/dev/nfs nfsroot=${serverip}:${rootpath} " \
"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off; " \
"bootm"
extern int fw_printenv(int argc, char *argv[]);
extern char *fw_getenv (char *name);
extern int fw_setenv (int argc, char *argv[]);
extern int fw_parse_script(char *fname);
extern int fw_env_open(void);
extern int fw_env_write(char *name, char *value);
extern int fw_env_close(void);
extern unsigned long crc32 (unsigned long, const unsigned char *, unsigned);

View file

@ -0,0 +1,141 @@
/*
* (C) Copyright 2000-2008
* 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
*/
/*
* Command line user interface to firmware (=U-Boot) environment.
*
* Implements:
* fw_printenv [[ -n name ] | [ name ... ]]
* - prints the value of a single environment variable
* "name", the ``name=value'' pairs of one or more
* environment variables "name", or the whole
* environment if no names are specified.
* fw_setenv name [ value ... ]
* - If a name without any values is given, the variable
* with this name is deleted from the environment;
* otherwise, all "value" arguments are concatenated,
* separated by single blank characters, and the
* resulting string is assigned to the environment
* variable "name"
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include "fw_env.h"
#define CMD_PRINTENV "fw_printenv"
#define CMD_SETENV "fw_setenv"
static struct option long_options[] = {
{"script", required_argument, NULL, 's'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
void usage(void)
{
fprintf(stderr, "fw_printenv/fw_setenv, "
"a command line interface to U-Boot environment\n\n"
"usage:\tfw_printenv [-n] [variable name]\n"
"\tfw_setenv [variable name] [variable value]\n"
"\tfw_setenv -s [ file ]\n"
"\tfw_setenv -s - < [ file ]\n\n"
"The file passed as argument contains only pairs "
"name / value\n"
"Example:\n"
"# Any line starting with # is treated as comment\n"
"\n"
"\t netdev eth0\n"
"\t kernel_addr 400000\n"
"\t var1\n"
"\t var2 The quick brown fox jumps over the "
"lazy dog\n"
"\n"
"A variable without value will be dropped. It is possible\n"
"to put any number of spaces between the fields, but any\n"
"space inside the value is treated as part of the value "
"itself.\n\n"
);
}
int
main(int argc, char *argv[])
{
char *p;
char *cmdname = *argv;
char *script_file = NULL;
int c;
if ((p = strrchr (cmdname, '/')) != NULL) {
cmdname = p + 1;
}
while ((c = getopt_long (argc, argv, "ns:h",
long_options, NULL)) != EOF) {
switch (c) {
case 'n':
/* handled in fw_printenv */
break;
case 's':
script_file = optarg;
break;
case 'h':
usage();
return EXIT_SUCCESS;
default: /* '?' */
fprintf(stderr, "Try `%s --help' for more information."
"\n", cmdname);
return EXIT_FAILURE;
}
}
if (strcmp(cmdname, CMD_PRINTENV) == 0) {
if (fw_printenv (argc, argv) != 0)
return EXIT_FAILURE;
return EXIT_SUCCESS;
} else if (strcmp(cmdname, CMD_SETENV) == 0) {
if (!script_file) {
if (fw_setenv(argc, argv) != 0)
return EXIT_FAILURE;
} else {
if (fw_parse_script(script_file) != 0)
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
fprintf (stderr,
"Identity crisis - may be called as `" CMD_PRINTENV
"' or as `" CMD_SETENV "' but not as `%s'\n",
cmdname);
return EXIT_FAILURE;
}

View file

@ -0,0 +1,145 @@
/*
* (C) Copyright 2001
* Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
*
* 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 <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifndef __ASSEMBLY__
#define __ASSEMBLY__ /* Dirty trick to get only #defines */
#endif
#define __ASM_STUB_PROCESSOR_H__ /* don't include asm/processor. */
#include <config.h>
#undef __ASSEMBLY__
#if defined(CONFIG_ENV_IS_IN_FLASH)
# ifndef CONFIG_ENV_ADDR
# define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
# endif
# ifndef CONFIG_ENV_OFFSET
# define CONFIG_ENV_OFFSET (CONFIG_ENV_ADDR - CONFIG_SYS_FLASH_BASE)
# endif
# if !defined(CONFIG_ENV_ADDR_REDUND) && defined(CONFIG_ENV_OFFSET_REDUND)
# define CONFIG_ENV_ADDR_REDUND (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET_REDUND)
# endif
# ifndef CONFIG_ENV_SIZE
# define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE
# endif
# if defined(CONFIG_ENV_ADDR_REDUND) && !defined(CONFIG_ENV_SIZE_REDUND)
# define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
# endif
# if (CONFIG_ENV_ADDR >= CONFIG_SYS_MONITOR_BASE) && \
((CONFIG_ENV_ADDR + CONFIG_ENV_SIZE) <= (CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN))
# define ENV_IS_EMBEDDED
# endif
# if defined(CONFIG_ENV_ADDR_REDUND) || defined(CONFIG_ENV_OFFSET_REDUND)
# define CONFIG_SYS_REDUNDAND_ENVIRONMENT
# endif
#endif /* CONFIG_ENV_IS_IN_FLASH */
#if defined(ENV_IS_EMBEDDED) && !defined(CONFIG_BUILD_ENVCRC)
# define CONFIG_BUILD_ENVCRC
#endif
#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
# define ENV_HEADER_SIZE (sizeof(uint32_t) + 1)
#else
# define ENV_HEADER_SIZE (sizeof(uint32_t))
#endif
#define ENV_SIZE (CONFIG_ENV_SIZE - ENV_HEADER_SIZE)
#ifdef CONFIG_BUILD_ENVCRC
# include <environment.h>
extern unsigned int env_size;
extern env_t environment;
#endif /* CONFIG_BUILD_ENVCRC */
extern uint32_t crc32 (uint32_t, const unsigned char *, unsigned int);
int main (int argc, char **argv)
{
#ifdef CONFIG_BUILD_ENVCRC
unsigned char pad = 0x00;
uint32_t crc;
unsigned char *envptr = (unsigned char *)&environment,
*dataptr = envptr + ENV_HEADER_SIZE;
unsigned int datasize = ENV_SIZE;
unsigned int eoe;
if (argv[1] && !strncmp(argv[1], "--binary", 8)) {
int ipad = 0xff;
if (argv[1][8] == '=')
sscanf(argv[1] + 9, "%i", &ipad);
pad = ipad;
}
if (pad) {
/* find the end of env */
for (eoe = 0; eoe < datasize - 1; ++eoe)
if (!dataptr[eoe] && !dataptr[eoe+1]) {
eoe += 2;
break;
}
if (eoe < datasize - 1)
memset(dataptr + eoe, pad, datasize - eoe);
}
crc = crc32 (0, dataptr, datasize);
/* Check if verbose mode is activated passing a parameter to the program */
if (argc > 1) {
if (!strncmp(argv[1], "--binary", 8)) {
int le = (argc > 2 ? !strcmp(argv[2], "le") : 1);
size_t i, start, end, step;
if (le) {
start = 0;
end = ENV_HEADER_SIZE;
step = 1;
} else {
start = ENV_HEADER_SIZE - 1;
end = -1;
step = -1;
}
for (i = start; i != end; i += step)
printf("%c", (crc & (0xFF << (i * 8))) >> (i * 8));
if (fwrite(dataptr, 1, datasize, stdout) != datasize)
fprintf(stderr, "fwrite() failed: %s\n", strerror(errno));
} else {
printf("CRC32 from offset %08X to %08X of environment = %08X\n",
(unsigned int) (dataptr - envptr),
(unsigned int) (dataptr - envptr) + datasize,
crc);
}
} else {
printf ("0x%08X\n", crc);
}
#else
printf ("0\n");
#endif
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,28 @@
/*
* (C) Copyright 2008 Semihalf
*
* 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 __FDT_HOST_H__
#define __FDT_HOST_H__
/* Make sure to include u-boot version of libfdt include files */
#include "../include/fdt.h"
#include "../include/libfdt.h"
#include "../include/fdt_support.h"
#endif /* __FDT_HOST_H__ */

View file

@ -0,0 +1,269 @@
/*
* (C) Copyright 2014 The Linux Foundation. All rights reserved.
* (C) Copyright 2008 Semihalf
*
* (C) Copyright 2000-2004
* DENX Software Engineering
* Wolfgang Denk, wd@denx.de
*
* Updated-by: Prafulla Wadaskar <prafulla@marvell.com>
* FIT image specific code abstracted from mkimage.c
* some functions added to address abstraction
*
* All rights reserved.
*
* 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 "imagetool.h"
#include "mkimage.h"
#include <image.h>
#include <u-boot/crc.h>
static image_header_t header;
static int fit_verify_header (unsigned char *ptr, int image_size,
struct image_tool_params *params)
{
return fdt_check_header ((void *)ptr);
}
static int fit_check_image_types (uint8_t type)
{
if (type == IH_TYPE_FLATDT)
return EXIT_SUCCESS;
else
return EXIT_FAILURE;
}
/**
* fit_handle_file - main FIT file processing function
*
* fit_handle_file() runs dtc to convert .its to .itb, includes
* binary data, updates timestamp property and calculates hashes.
*
* datafile - .its file
* imagefile - .itb file
*
* returns:
* only on success, otherwise calls exit (EXIT_FAILURE);
*/
static int fit_handle_file (struct image_tool_params *params)
{
char tmpfile[MKIMAGE_MAX_TMPFILE_LEN];
char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN];
int tfd;
struct stat sbuf;
unsigned char *ptr;
/* Flattened Image Tree (FIT) format handling */
debug ("FIT format handling\n");
/* call dtc to include binary properties into the tmp file */
if (strlen (params->imagefile) +
strlen (MKIMAGE_TMPFILE_SUFFIX) + 1 > sizeof (tmpfile)) {
fprintf (stderr, "%s: Image file name (%s) too long, "
"can't create tmpfile",
params->imagefile, params->cmdname);
return (EXIT_FAILURE);
}
snprintf (tmpfile, MKIMAGE_MAX_TMPFILE_LEN, "%s%s", params->imagefile,
MKIMAGE_TMPFILE_SUFFIX);
/* dtc -I dts -O -p 200 datafile > tmpfile */
snprintf (cmd, MKIMAGE_MAX_DTC_CMDLINE_LEN, "%s %s %s > %s",
MKIMAGE_DTC, params->dtc, params->datafile, tmpfile);
debug ("Trying to execute \"%s\"\n", cmd);
if (system (cmd) == -1) {
fprintf (stderr, "%s: system(%s) failed: %s\n",
params->cmdname, cmd, strerror(errno));
unlink (tmpfile);
return (EXIT_FAILURE);
}
/* load FIT blob into memory */
tfd = open (tmpfile, O_RDWR|O_BINARY);
if (tfd < 0) {
fprintf (stderr, "%s: Can't open %s: %s\n",
params->cmdname, tmpfile, strerror(errno));
unlink (tmpfile);
return (EXIT_FAILURE);
}
if (fstat (tfd, &sbuf) < 0) {
fprintf (stderr, "%s: Can't stat %s: %s\n",
params->cmdname, tmpfile, strerror(errno));
unlink (tmpfile);
return (EXIT_FAILURE);
}
ptr = mmap (0, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED,
tfd, 0);
if (ptr == MAP_FAILED) {
fprintf (stderr, "%s: Can't read %s: %s\n",
params->cmdname, tmpfile, strerror(errno));
unlink (tmpfile);
return (EXIT_FAILURE);
}
/* check if ptr has a valid blob */
if (fdt_check_header (ptr)) {
fprintf (stderr, "%s: Invalid FIT blob\n", params->cmdname);
unlink (tmpfile);
return (EXIT_FAILURE);
}
/* set hashes for images in the blob */
if (fit_set_hashes (ptr)) {
fprintf (stderr, "%s Can't add hashes to FIT blob",
params->cmdname);
unlink (tmpfile);
return (EXIT_FAILURE);
}
/* add a timestamp at offset 0 i.e., root */
if (fit_set_timestamp (ptr, 0, sbuf.st_mtime)) {
fprintf (stderr, "%s: Can't add image timestamp\n",
params->cmdname);
unlink (tmpfile);
return (EXIT_FAILURE);
}
debug ("Added timestamp successfully\n");
munmap ((void *)ptr, sbuf.st_size);
close (tfd);
if (rename (tmpfile, params->imagefile) == -1) {
fprintf (stderr, "%s: Can't rename %s to %s: %s\n",
params->cmdname, tmpfile, params->imagefile,
strerror (errno));
unlink (tmpfile);
unlink (params->imagefile);
return (EXIT_FAILURE);
}
return (EXIT_SUCCESS);
}
static int fit_save_datafile (struct image_tool_params *params,
const void *file_data, size_t file_size)
{
int dfd;
const char *datafile = params->outfile;
dfd = open(datafile, O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
S_IRUSR | S_IWUSR);
if (dfd < 0) {
fprintf(stderr, "%s: Can't open \"%s\": %s\n",
params->cmdname, datafile, strerror(errno));
return (EXIT_FAILURE);
}
if (write(dfd, (void *)file_data, file_size) != (ssize_t)file_size) {
fprintf(stderr, "%s: Write error on \"%s\": %s\n",
params->cmdname, datafile, strerror(errno));
close(dfd);
return (EXIT_FAILURE);
}
close(dfd);
return (EXIT_SUCCESS);
}
static int fit_extract_datafile (void *ptr, struct image_tool_params *params)
{
const void *fit = (const void *) ptr;
int images_noffset, noffset, ndepth;
const void *file_data = NULL;
size_t file_size;
images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
/* check if ptr has a valid blob */
if (fdt_check_header (fit)) {
fprintf (stderr, "%s: Invalid FIT blob\n", params->cmdname);
unlink (params->imagefile);
return (EXIT_FAILURE);
}
ndepth = 0;
noffset = fdt_next_node(fit, images_noffset, &ndepth);
while (noffset >= 0 && ndepth > 0) {
const char *name = fdt_get_name(fit, noffset, NULL);
if (ndepth != 1)
goto next_node;
if (strcmp(params->datafile, name)) {
/* This is not the image you're looking for... */
goto next_node;
}
if (!fit_image_check_hashes(fit, noffset)) {
fprintf(stderr,
"%s: Invalid hash in image %s, aborting\n",
params->cmdname, params->datafile);
unlink (params->imagefile);
return (EXIT_FAILURE);
}
if (fit_image_get_data(fit, noffset, &file_data, &file_size)) {
fprintf(stderr,
"%s: Can't read data in image %s, aborting\n",
params->cmdname, params->datafile);
unlink(params->imagefile);
return (EXIT_FAILURE);
}
break;
next_node:
noffset = fdt_next_node(fit, noffset, &ndepth);
}
if (!file_data) {
fprintf(stderr, "%s: Can't find image name %s\n",
params->cmdname, params->datafile);
return (EXIT_FAILURE);
}
return fit_save_datafile(params, file_data, file_size);
}
static int fit_check_params (struct image_tool_params *params)
{
return ((params->dflag && (params->fflag || params->lflag)) ||
(params->fflag && (params->dflag || params->lflag)) ||
(params->lflag && (params->dflag || params->fflag)));
}
static struct image_type_params fitimage_params = {
.name = "FIT Image support",
.header_size = sizeof(image_header_t),
.hdr = (void*)&header,
.verify_header = fit_verify_header,
.print_header = fit_print_contents,
.check_image_type = fit_check_image_types,
.fflag_handle = fit_handle_file,
.set_header = NULL, /* FIT images use DTB header */
.extract_datafile = fit_extract_datafile,
.check_params = fit_check_params,
};
void init_fit_image_type (void)
{
register_image_type (&fitimage_params);
}

View file

@ -0,0 +1,32 @@
#!/bin/sh
#
# gcc-version [-p] gcc-command
#
# Prints the gcc version of `gcc-command' in a canonical 4-digit form
# such as `0295' for gcc-2.95, `0303' for gcc-3.3, etc.
#
# With the -p option, prints the patchlevel as well, for example `029503' for
# gcc-2.95.3, `030301' for gcc-3.3.1, etc.
#
if [ "$1" = "-p" ] ; then
with_patchlevel=1;
shift;
fi
compiler="$*"
if [ ${#compiler} -eq 0 ]; then
echo "Error: No compiler specified."
printf "Usage:\n\t$0 <gcc-command>\n"
exit 1
fi
MAJOR=$(echo __GNUC__ | $compiler -E -xc - | tail -n 1)
MINOR=$(echo __GNUC_MINOR__ | $compiler -E -xc - | tail -n 1)
if [ "x$with_patchlevel" != "x" ] ; then
PATCHLEVEL=$(echo __GNUC_PATCHLEVEL__ | $compiler -E -xc - | tail -n 1)
printf "%02d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL
else
printf "%02d%02d\\n" $MAJOR $MINOR
fi

View file

@ -0,0 +1,74 @@
#
# (C) Copyright 2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# (C) Copyright 2000
# Murray Jensen <Murray.Jensen@csiro.au>
#
# 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
BINS = gdbsend gdbcont
COBJS = gdbsend.o gdbcont.o error.o remote.o serial.o
HOSTOBJS := $(addprefix $(obj),$(COBJS))
HOSTSRCS := $(COBJS:.o=.c)
BINS := $(addprefix $(obj),$(BINS))
#
# Use native tools and options
#
HOSTCPPFLAGS = -I$(BFD_ROOT_DIR)/include
HOSTOS := $(shell uname -s | sed -e 's/\([Cc][Yy][Gg][Ww][Ii][Nn]\).*/cygwin/')
ifeq ($(HOSTOS),cygwin)
all:
$(obj).depend:
else # ! CYGWIN
all: $(obj).depend $(BINS)
$(obj)gdbsend: $(obj)gdbsend.o $(obj)error.o $(obj)remote.o $(obj)serial.o
$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
$(obj)gdbcont: $(obj)gdbcont.o $(obj)error.o $(obj)remote.o $(obj)serial.o
$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
clean:
rm -f $(HOSTOBJS)
distclean: clean
rm -f $(BINS) $(obj)core $(obj)*.bak $(obj).depend
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################
endif # cygwin

View file

@ -0,0 +1,81 @@
/*
* (C) Copyright 2000
* Murray Jensen <Murray.Jensen@csiro.au>
*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "error.h"
char *pname;
void
Warning(char *fmt, ...)
{
va_list args;
fprintf(stderr, "%s: WARNING: ", pname);
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "\n");
}
void
Error(char *fmt, ...)
{
va_list args;
fprintf(stderr, "%s: ERROR: ", pname);
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "\n");
exit(1);
}
void
Perror(char *fmt, ...)
{
va_list args;
int e = errno;
char *p;
fprintf(stderr, "%s: ERROR: ", pname);
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
if ((p = strerror(e)) == NULL || *p == '\0')
fprintf(stderr, ": Unknown Error (%d)\n", e);
else
fprintf(stderr, ": %s\n", p);
exit(1);
}

View file

@ -0,0 +1,30 @@
/*
* (C) Copyright 2000
* Murray Jensen <Murray.Jensen@csiro.au>
*
* 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 <stdarg.h>
extern char *pname;
extern void Warning(char *, ...);
extern void Error(char *, ...);
extern void Perror(char *, ...);

View file

@ -0,0 +1,87 @@
/*
* (C) Copyright 2000
* Murray Jensen <Murray.Jensen@csiro.au>
*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "serial.h"
#include "error.h"
#include "remote.h"
char *serialdev = "/dev/term/b";
speed_t speed = B230400;
int verbose = 0;
int
main(int ac, char **av)
{
int c, sfd;
if ((pname = strrchr(av[0], '/')) == NULL)
pname = av[0];
else
pname++;
while ((c = getopt(ac, av, "b:p:v")) != EOF)
switch (c) {
case 'b':
if ((speed = cvtspeed(optarg)) == B0)
Error("can't decode baud rate specified in -b option");
break;
case 'p':
serialdev = optarg;
break;
case 'v':
verbose = 1;
break;
default:
usage:
fprintf(stderr, "Usage: %s [-b bps] [-p dev] [-v]\n", pname);
exit(1);
}
if (optind != ac)
goto usage;
if (verbose)
fprintf(stderr, "Opening serial port and sending continue...\n");
if ((sfd = serialopen(serialdev, speed)) < 0)
Perror("open of serial device '%s' failed", serialdev);
remote_desc = sfd;
remote_reset();
remote_continue();
if (serialclose(sfd) < 0)
Perror("close of serial device '%s' failed", serialdev);
if (verbose)
fprintf(stderr, "Done.\n");
return (0);
}

View file

@ -0,0 +1,137 @@
/*
* (C) Copyright 2000
* Murray Jensen <Murray.Jensen@csiro.au>
*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "serial.h"
#include "error.h"
#include "remote.h"
char *serialdev = "/dev/term/b";
speed_t speed = B230400;
int verbose = 0, docont = 0;
unsigned long addr = 0x10000UL;
int
main(int ac, char **av)
{
int c, sfd, ifd;
char *ifn, *image;
struct stat ist;
if ((pname = strrchr(av[0], '/')) == NULL)
pname = av[0];
else
pname++;
while ((c = getopt(ac, av, "a:b:cp:v")) != EOF)
switch (c) {
case 'a': {
char *ep;
addr = strtol(optarg, &ep, 0);
if (ep == optarg || *ep != '\0')
Error("can't decode address specified in -a option");
break;
}
case 'b':
if ((speed = cvtspeed(optarg)) == B0)
Error("can't decode baud rate specified in -b option");
break;
case 'c':
docont = 1;
break;
case 'p':
serialdev = optarg;
break;
case 'v':
verbose = 1;
break;
default:
usage:
fprintf(stderr,
"Usage: %s [-a addr] [-b bps] [-c] [-p dev] [-v] imagefile\n",
pname);
exit(1);
}
if (optind != ac - 1)
goto usage;
ifn = av[optind++];
if (verbose)
fprintf(stderr, "Opening file and reading image...\n");
if ((ifd = open(ifn, O_RDONLY)) < 0)
Perror("can't open kernel image file '%s'", ifn);
if (fstat(ifd, &ist) < 0)
Perror("fstat '%s' failed", ifn);
if ((image = (char *)malloc(ist.st_size)) == NULL)
Perror("can't allocate %ld bytes for image", ist.st_size);
if ((c = read(ifd, image, ist.st_size)) < 0)
Perror("read of %d bytes from '%s' failed", ist.st_size, ifn);
if (c != ist.st_size)
Error("read of %ld bytes from '%s' failed (%d)", ist.st_size, ifn, c);
if (close(ifd) < 0)
Perror("close of '%s' failed", ifn);
if (verbose)
fprintf(stderr, "Opening serial port and sending image...\n");
if ((sfd = serialopen(serialdev, speed)) < 0)
Perror("open of serial device '%s' failed", serialdev);
remote_desc = sfd;
remote_reset();
remote_write_bytes(addr, image, ist.st_size);
if (docont) {
if (verbose)
fprintf(stderr, "[continue]");
remote_continue();
}
if (serialclose(sfd) < 0)
Perror("close of serial device '%s' failed", serialdev);
if (verbose)
fprintf(stderr, "Done.\n");
return (0);
}

View file

@ -0,0 +1,928 @@
/*
* taken from gdb/remote.c
*
* I am only interested in the write to memory stuff - everything else
* has been ripped out
*
* all the copyright notices etc have been left in
*/
/* enough so that it will compile */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/*nicked from gcc..*/
#ifndef alloca
#ifdef __GNUC__
#define alloca __builtin_alloca
#else /* not GNU C. */
#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
#include <alloca.h>
#else /* not sparc */
#if defined (MSDOS) && !defined (__TURBOC__)
#include <malloc.h>
#else /* not MSDOS, or __TURBOC__ */
#if defined(_AIX)
#include <malloc.h>
#pragma alloca
#else /* not MSDOS, __TURBOC__, or _AIX */
#ifdef __hpux
#endif /* __hpux */
#endif /* not _AIX */
#endif /* not MSDOS, or __TURBOC__ */
#endif /* not sparc. */
#endif /* not GNU C. */
#ifdef __cplusplus
extern "C" {
#endif
void* alloca(size_t);
#ifdef __cplusplus
}
#endif
#endif /* alloca not defined. */
#include "serial.h"
#include "error.h"
#include "remote.h"
#define REGISTER_BYTES 0
#define fprintf_unfiltered fprintf
#define fprintf_filtered fprintf
#define fputs_unfiltered fputs
#define fputs_filtered fputs
#define fputc_unfiltered fputc
#define fputc_filtered fputc
#define printf_unfiltered printf
#define printf_filtered printf
#define puts_unfiltered puts
#define puts_filtered puts
#define putchar_unfiltered putchar
#define putchar_filtered putchar
#define fputstr_unfiltered(a,b,c) fputs((a), (c))
#define gdb_stdlog stderr
#define SERIAL_READCHAR(fd,timo) serialreadchar((fd), (timo))
#define SERIAL_WRITE(fd, addr, len) serialwrite((fd), (addr), (len))
#define error Error
#define perror_with_name Perror
#define gdb_flush fflush
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define target_mourn_inferior() {}
#define ULONGEST unsigned long
#define CORE_ADDR unsigned long
static int putpkt (char *);
static int putpkt_binary(char *, int);
static void getpkt (char *, int);
static int remote_debug = 0, remote_register_buf_size = 0, watchdog = 0;
int remote_desc = -1, remote_timeout = 10;
static void
fputstrn_unfiltered(char *s, int n, int x, FILE *fp)
{
while (n-- > 0)
fputc(*s++, fp);
}
void
remote_reset(void)
{
SERIAL_WRITE(remote_desc, "+", 1);
}
void
remote_continue(void)
{
putpkt("c");
}
/* Remote target communications for serial-line targets in custom GDB protocol
Copyright 1988, 91, 92, 93, 94, 95, 96, 97, 98, 1999
Free Software Foundation, Inc.
This file is part of GDB.
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. */
/* *INDENT-OFF* */
/* Remote communication protocol.
A debug packet whose contents are <data>
is encapsulated for transmission in the form:
$ <data> # CSUM1 CSUM2
<data> must be ASCII alphanumeric and cannot include characters
'$' or '#'. If <data> starts with two characters followed by
':', then the existing stubs interpret this as a sequence number.
CSUM1 and CSUM2 are ascii hex representation of an 8-bit
checksum of <data>, the most significant nibble is sent first.
the hex digits 0-9,a-f are used.
Receiver responds with:
+ - if CSUM is correct and ready for next packet
- - if CSUM is incorrect
<data> is as follows:
Most values are encoded in ascii hex digits. Signal numbers are according
to the numbering in target.h.
Request Packet
set thread Hct... Set thread for subsequent operations.
c = 'c' for thread used in step and
continue; t... can be -1 for all
threads.
c = 'g' for thread used in other
operations. If zero, pick a thread,
any thread.
reply OK for success
ENN for an error.
read registers g
reply XX....X Each byte of register data
is described by two hex digits.
Registers are in the internal order
for GDB, and the bytes in a register
are in the same order the machine uses.
or ENN for an error.
write regs GXX..XX Each byte of register data
is described by two hex digits.
reply OK for success
ENN for an error
write reg Pn...=r... Write register n... with value r...,
which contains two hex digits for each
byte in the register (target byte
order).
reply OK for success
ENN for an error
(not supported by all stubs).
read mem mAA..AA,LLLL AA..AA is address, LLLL is length.
reply XX..XX XX..XX is mem contents
Can be fewer bytes than requested
if able to read only part of the data.
or ENN NN is errno
write mem MAA..AA,LLLL:XX..XX
AA..AA is address,
LLLL is number of bytes,
XX..XX is data
reply OK for success
ENN for an error (this includes the case
where only part of the data was
written).
write mem XAA..AA,LLLL:XX..XX
(binary) AA..AA is address,
LLLL is number of bytes,
XX..XX is binary data
reply OK for success
ENN for an error
continue cAA..AA AA..AA is address to resume
If AA..AA is omitted,
resume at same address.
step sAA..AA AA..AA is address to resume
If AA..AA is omitted,
resume at same address.
continue with Csig;AA..AA Continue with signal sig (hex signal
signal number). If ;AA..AA is omitted,
resume at same address.
step with Ssig;AA..AA Like 'C' but step not continue.
signal
last signal ? Reply the current reason for stopping.
This is the same reply as is generated
for step or cont : SAA where AA is the
signal number.
detach D Reply OK.
There is no immediate reply to step or cont.
The reply comes when the machine stops.
It is SAA AA is the signal number.
or... TAAn...:r...;n...:r...;n...:r...;
AA = signal number
n... = register number (hex)
r... = register contents
n... = `thread'
r... = thread process ID. This is
a hex integer.
n... = other string not starting
with valid hex digit.
gdb should ignore this n,r pair
and go on to the next. This way
we can extend the protocol.
or... WAA The process exited, and AA is
the exit status. This is only
applicable for certains sorts of
targets.
or... XAA The process terminated with signal
AA.
or (obsolete) NAA;tttttttt;dddddddd;bbbbbbbb
AA = signal number
tttttttt = address of symbol "_start"
dddddddd = base of data section
bbbbbbbb = base of bss section.
Note: only used by Cisco Systems
targets. The difference between this
reply and the "qOffsets" query is that
the 'N' packet may arrive spontaneously
whereas the 'qOffsets' is a query
initiated by the host debugger.
or... OXX..XX XX..XX is hex encoding of ASCII data. This
can happen at any time while the
program is running and the debugger
should continue to wait for
'W', 'T', etc.
thread alive TXX Find out if the thread XX is alive.
reply OK thread is still alive
ENN thread is dead
remote restart RXX Restart the remote server
extended ops ! Use the extended remote protocol.
Sticky -- only needs to be set once.
kill request k
toggle debug d toggle debug flag (see 386 & 68k stubs)
reset r reset -- see sparc stub.
reserved <other> On other requests, the stub should
ignore the request and send an empty
response ($#<checksum>). This way
we can extend the protocol and GDB
can tell whether the stub it is
talking to uses the old or the new.
search tAA:PP,MM Search backwards starting at address
AA for a match with pattern PP and
mask MM. PP and MM are 4 bytes.
Not supported by all stubs.
general query qXXXX Request info about XXXX.
general set QXXXX=yyyy Set value of XXXX to yyyy.
query sect offs qOffsets Get section offsets. Reply is
Text=xxx;Data=yyy;Bss=zzz
Responses can be run-length encoded to save space. A '*' means that
the next character is an ASCII encoding giving a repeat count which
stands for that many repititions of the character preceding the '*'.
The encoding is n+29, yielding a printable character where n >=3
(which is where rle starts to win). Don't use an n > 126.
So
"0* " means the same as "0000". */
/* *INDENT-ON* */
/* This variable (available to the user via "set remotebinarydownload")
dictates whether downloads are sent in binary (via the 'X' packet).
We assume that the stub can, and attempt to do it. This will be cleared if
the stub does not understand it. This switch is still needed, though
in cases when the packet is supported in the stub, but the connection
does not allow it (i.e., 7-bit serial connection only). */
static int remote_binary_download = 1;
/* Have we already checked whether binary downloads work? */
static int remote_binary_checked;
/* Maximum number of bytes to read/write at once. The value here
is chosen to fill up a packet (the headers account for the 32). */
#define MAXBUFBYTES(N) (((N)-32)/2)
/* Having this larger than 400 causes us to be incompatible with m68k-stub.c
and i386-stub.c. Normally, no one would notice because it only matters
for writing large chunks of memory (e.g. in downloads). Also, this needs
to be more than 400 if required to hold the registers (see below, where
we round it up based on REGISTER_BYTES). */
/* Round up PBUFSIZ to hold all the registers, at least. */
#define PBUFSIZ ((REGISTER_BYTES > MAXBUFBYTES (400)) \
? (REGISTER_BYTES * 2 + 32) \
: 400)
/* This variable sets the number of bytes to be written to the target
in a single packet. Normally PBUFSIZ is satisfactory, but some
targets need smaller values (perhaps because the receiving end
is slow). */
static int remote_write_size = 0x7fffffff;
/* This variable sets the number of bits in an address that are to be
sent in a memory ("M" or "m") packet. Normally, after stripping
leading zeros, the entire address would be sent. This variable
restricts the address to REMOTE_ADDRESS_SIZE bits. HISTORY: The
initial implementation of remote.c restricted the address sent in
memory packets to ``host::sizeof long'' bytes - (typically 32
bits). Consequently, for 64 bit targets, the upper 32 bits of an
address was never sent. Since fixing this bug may cause a break in
some remote targets this variable is principly provided to
facilitate backward compatibility. */
static int remote_address_size;
/* Convert hex digit A to a number. */
static int
fromhex (int a)
{
if (a >= '0' && a <= '9')
return a - '0';
else if (a >= 'a' && a <= 'f')
return a - 'a' + 10;
else if (a >= 'A' && a <= 'F')
return a - 'A' + 10;
else {
error ("Reply contains invalid hex digit %d", a);
return -1;
}
}
/* Convert number NIB to a hex digit. */
static int
tohex (int nib)
{
if (nib < 10)
return '0' + nib;
else
return 'a' + nib - 10;
}
/* Return the number of hex digits in num. */
static int
hexnumlen (ULONGEST num)
{
int i;
for (i = 0; num != 0; i++)
num >>= 4;
return max (i, 1);
}
/* Set BUF to the hex digits representing NUM. */
static int
hexnumstr (char *buf, ULONGEST num)
{
int i;
int len = hexnumlen (num);
buf[len] = '\0';
for (i = len - 1; i >= 0; i--)
{
buf[i] = "0123456789abcdef"[(num & 0xf)];
num >>= 4;
}
return len;
}
/* Mask all but the least significant REMOTE_ADDRESS_SIZE bits. */
static CORE_ADDR
remote_address_masked (CORE_ADDR addr)
{
if (remote_address_size > 0
&& remote_address_size < (sizeof (ULONGEST) * 8))
{
/* Only create a mask when that mask can safely be constructed
in a ULONGEST variable. */
ULONGEST mask = 1;
mask = (mask << remote_address_size) - 1;
addr &= mask;
}
return addr;
}
/* Determine whether the remote target supports binary downloading.
This is accomplished by sending a no-op memory write of zero length
to the target at the specified address. It does not suffice to send
the whole packet, since many stubs strip the eighth bit and subsequently
compute a wrong checksum, which causes real havoc with remote_write_bytes.
NOTE: This can still lose if the serial line is not eight-bit clean. In
cases like this, the user should clear "remotebinarydownload". */
static void
check_binary_download (CORE_ADDR addr)
{
if (remote_binary_download && !remote_binary_checked)
{
char *buf = alloca (PBUFSIZ);
char *p;
remote_binary_checked = 1;
p = buf;
*p++ = 'X';
p += hexnumstr (p, (ULONGEST) addr);
*p++ = ',';
p += hexnumstr (p, (ULONGEST) 0);
*p++ = ':';
*p = '\0';
putpkt_binary (buf, (int) (p - buf));
getpkt (buf, 0);
if (buf[0] == '\0')
remote_binary_download = 0;
}
if (remote_debug)
{
if (remote_binary_download)
fprintf_unfiltered (gdb_stdlog,
"binary downloading suppported by target\n");
else
fprintf_unfiltered (gdb_stdlog,
"binary downloading NOT suppported by target\n");
}
}
/* Write memory data directly to the remote machine.
This does not inform the data cache; the data cache uses this.
MEMADDR is the address in the remote memory space.
MYADDR is the address of the buffer in our space.
LEN is the number of bytes.
Returns number of bytes transferred, or 0 for error. */
int
remote_write_bytes (memaddr, myaddr, len)
CORE_ADDR memaddr;
char *myaddr;
int len;
{
unsigned char *buf = alloca (PBUFSIZ);
int max_buf_size; /* Max size of packet output buffer */
int origlen;
extern int verbose;
/* Verify that the target can support a binary download */
check_binary_download (memaddr);
/* Chop the transfer down if necessary */
max_buf_size = min (remote_write_size, PBUFSIZ);
if (remote_register_buf_size != 0)
max_buf_size = min (max_buf_size, remote_register_buf_size);
/* Subtract header overhead from max payload size - $M<memaddr>,<len>:#nn */
max_buf_size -= 2 + hexnumlen (memaddr + len - 1) + 1 + hexnumlen (len) + 4;
origlen = len;
while (len > 0)
{
unsigned char *p, *plen;
int todo;
int i;
/* construct "M"<memaddr>","<len>":" */
/* sprintf (buf, "M%lx,%x:", (unsigned long) memaddr, todo); */
memaddr = remote_address_masked (memaddr);
p = buf;
if (remote_binary_download)
{
*p++ = 'X';
todo = min (len, max_buf_size);
}
else
{
*p++ = 'M';
todo = min (len, max_buf_size / 2); /* num bytes that will fit */
}
p += hexnumstr ((char *)p, (ULONGEST) memaddr);
*p++ = ',';
plen = p; /* remember where len field goes */
p += hexnumstr ((char *)p, (ULONGEST) todo);
*p++ = ':';
*p = '\0';
/* We send target system values byte by byte, in increasing byte
addresses, each byte encoded as two hex characters (or one
binary character). */
if (remote_binary_download)
{
int escaped = 0;
for (i = 0;
(i < todo) && (i + escaped) < (max_buf_size - 2);
i++)
{
switch (myaddr[i] & 0xff)
{
case '$':
case '#':
case 0x7d:
/* These must be escaped */
escaped++;
*p++ = 0x7d;
*p++ = (myaddr[i] & 0xff) ^ 0x20;
break;
default:
*p++ = myaddr[i] & 0xff;
break;
}
}
if (i < todo)
{
/* Escape chars have filled up the buffer prematurely,
and we have actually sent fewer bytes than planned.
Fix-up the length field of the packet. */
/* FIXME: will fail if new len is a shorter string than
old len. */
plen += hexnumstr ((char *)plen, (ULONGEST) i);
*plen++ = ':';
}
}
else
{
for (i = 0; i < todo; i++)
{
*p++ = tohex ((myaddr[i] >> 4) & 0xf);
*p++ = tohex (myaddr[i] & 0xf);
}
*p = '\0';
}
putpkt_binary ((char *)buf, (int) (p - buf));
getpkt ((char *)buf, 0);
if (buf[0] == 'E')
{
/* There is no correspondance between what the remote protocol uses
for errors and errno codes. We would like a cleaner way of
representing errors (big enough to include errno codes, bfd_error
codes, and others). But for now just return EIO. */
errno = EIO;
return 0;
}
/* Increment by i, not by todo, in case escape chars
caused us to send fewer bytes than we'd planned. */
myaddr += i;
memaddr += i;
len -= i;
if (verbose)
putc('.', stderr);
}
return origlen;
}
/* Stuff for dealing with the packets which are part of this protocol.
See comment at top of file for details. */
/* Read a single character from the remote end, masking it down to 7 bits. */
static int
readchar (int timeout)
{
int ch;
ch = SERIAL_READCHAR (remote_desc, timeout);
switch (ch)
{
case SERIAL_EOF:
error ("Remote connection closed");
case SERIAL_ERROR:
perror_with_name ("Remote communication error");
case SERIAL_TIMEOUT:
return ch;
default:
return ch & 0x7f;
}
}
static int
putpkt (buf)
char *buf;
{
return putpkt_binary (buf, strlen (buf));
}
/* Send a packet to the remote machine, with error checking. The data
of the packet is in BUF. The string in BUF can be at most PBUFSIZ - 5
to account for the $, # and checksum, and for a possible /0 if we are
debugging (remote_debug) and want to print the sent packet as a string */
static int
putpkt_binary (buf, cnt)
char *buf;
int cnt;
{
int i;
unsigned char csum = 0;
char *buf2 = alloca (PBUFSIZ);
char *junkbuf = alloca (PBUFSIZ);
int ch;
int tcount = 0;
char *p;
/* Copy the packet into buffer BUF2, encapsulating it
and giving it a checksum. */
if (cnt > BUFSIZ - 5) /* Prosanity check */
abort ();
p = buf2;
*p++ = '$';
for (i = 0; i < cnt; i++)
{
csum += buf[i];
*p++ = buf[i];
}
*p++ = '#';
*p++ = tohex ((csum >> 4) & 0xf);
*p++ = tohex (csum & 0xf);
/* Send it over and over until we get a positive ack. */
while (1)
{
int started_error_output = 0;
if (remote_debug)
{
*p = '\0';
fprintf_unfiltered (gdb_stdlog, "Sending packet: ");
fputstrn_unfiltered (buf2, p - buf2, 0, gdb_stdlog);
fprintf_unfiltered (gdb_stdlog, "...");
gdb_flush (gdb_stdlog);
}
if (SERIAL_WRITE (remote_desc, buf2, p - buf2))
perror_with_name ("putpkt: write failed");
/* read until either a timeout occurs (-2) or '+' is read */
while (1)
{
ch = readchar (remote_timeout);
if (remote_debug)
{
switch (ch)
{
case '+':
case SERIAL_TIMEOUT:
case '$':
if (started_error_output)
{
putchar_unfiltered ('\n');
started_error_output = 0;
}
}
}
switch (ch)
{
case '+':
if (remote_debug)
fprintf_unfiltered (gdb_stdlog, "Ack\n");
return 1;
case SERIAL_TIMEOUT:
tcount++;
if (tcount > 3)
return 0;
break; /* Retransmit buffer */
case '$':
{
/* It's probably an old response, and we're out of sync.
Just gobble up the packet and ignore it. */
getpkt (junkbuf, 0);
continue; /* Now, go look for + */
}
default:
if (remote_debug)
{
if (!started_error_output)
{
started_error_output = 1;
fprintf_unfiltered (gdb_stdlog, "putpkt: Junk: ");
}
fputc_unfiltered (ch & 0177, gdb_stdlog);
}
continue;
}
break; /* Here to retransmit */
}
#if 0
/* This is wrong. If doing a long backtrace, the user should be
able to get out next time we call QUIT, without anything as
violent as interrupt_query. If we want to provide a way out of
here without getting to the next QUIT, it should be based on
hitting ^C twice as in remote_wait. */
if (quit_flag)
{
quit_flag = 0;
interrupt_query ();
}
#endif
}
}
/* Come here after finding the start of the frame. Collect the rest
into BUF, verifying the checksum, length, and handling run-length
compression. Returns 0 on any error, 1 on success. */
static int
read_frame (char *buf)
{
unsigned char csum;
char *bp;
int c;
csum = 0;
bp = buf;
while (1)
{
c = readchar (remote_timeout);
switch (c)
{
case SERIAL_TIMEOUT:
if (remote_debug)
fputs_filtered ("Timeout in mid-packet, retrying\n", gdb_stdlog);
return 0;
case '$':
if (remote_debug)
fputs_filtered ("Saw new packet start in middle of old one\n",
gdb_stdlog);
return 0; /* Start a new packet, count retries */
case '#':
{
unsigned char pktcsum;
*bp = '\000';
pktcsum = fromhex (readchar (remote_timeout)) << 4;
pktcsum |= fromhex (readchar (remote_timeout));
if (csum == pktcsum)
{
return 1;
}
if (remote_debug)
{
fprintf_filtered (gdb_stdlog,
"Bad checksum, sentsum=0x%x, csum=0x%x, buf=",
pktcsum, csum);
fputs_filtered (buf, gdb_stdlog);
fputs_filtered ("\n", gdb_stdlog);
}
return 0;
}
case '*': /* Run length encoding */
csum += c;
c = readchar (remote_timeout);
csum += c;
c = c - ' ' + 3; /* Compute repeat count */
if (c > 0 && c < 255 && bp + c - 1 < buf + PBUFSIZ - 1)
{
memset (bp, *(bp - 1), c);
bp += c;
continue;
}
*bp = '\0';
printf_filtered ("Repeat count %d too large for buffer: ", c);
puts_filtered (buf);
puts_filtered ("\n");
return 0;
default:
if (bp < buf + PBUFSIZ - 1)
{
*bp++ = c;
csum += c;
continue;
}
*bp = '\0';
puts_filtered ("Remote packet too long: ");
puts_filtered (buf);
puts_filtered ("\n");
return 0;
}
}
}
/* Read a packet from the remote machine, with error checking, and
store it in BUF. BUF is expected to be of size PBUFSIZ. If
FOREVER, wait forever rather than timing out; this is used while
the target is executing user code. */
static void
getpkt (buf, forever)
char *buf;
int forever;
{
int c;
int tries;
int timeout;
int val;
strcpy (buf, "timeout");
if (forever)
{
timeout = watchdog > 0 ? watchdog : -1;
}
else
timeout = remote_timeout;
#define MAX_TRIES 3
for (tries = 1; tries <= MAX_TRIES; tries++)
{
/* This can loop forever if the remote side sends us characters
continuously, but if it pauses, we'll get a zero from readchar
because of timeout. Then we'll count that as a retry. */
/* Note that we will only wait forever prior to the start of a packet.
After that, we expect characters to arrive at a brisk pace. They
should show up within remote_timeout intervals. */
do
{
c = readchar (timeout);
if (c == SERIAL_TIMEOUT)
{
if (forever) /* Watchdog went off. Kill the target. */
{
target_mourn_inferior ();
error ("Watchdog has expired. Target detached.\n");
}
if (remote_debug)
fputs_filtered ("Timed out.\n", gdb_stdlog);
goto retry;
}
}
while (c != '$');
/* We've found the start of a packet, now collect the data. */
val = read_frame (buf);
if (val == 1)
{
if (remote_debug)
{
fprintf_unfiltered (gdb_stdlog, "Packet received: ");
fputstr_unfiltered (buf, 0, gdb_stdlog);
fprintf_unfiltered (gdb_stdlog, "\n");
}
SERIAL_WRITE (remote_desc, "+", 1);
return;
}
/* Try the whole thing again. */
retry:
SERIAL_WRITE (remote_desc, "-", 1);
}
/* We have tried hard enough, and just can't receive the packet. Give up. */
printf_unfiltered ("Ignoring packet error, continuing...\n");
SERIAL_WRITE (remote_desc, "+", 1);
}

View file

@ -0,0 +1,28 @@
/*
* (C) Copyright 2000
* Murray Jensen <Murray.Jensen@csiro.au>
*
* 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
*/
extern int remote_desc, remote_timeout;
extern void remote_reset(void);
extern void remote_continue(void);
extern int remote_write_bytes(unsigned long, char *, int);

View file

@ -0,0 +1,149 @@
/*
* (C) Copyright 2000
* Murray Jensen <Murray.Jensen@csiro.au>
*
* 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 <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/time.h>
#include "serial.h"
#if defined(__sun__) || \
defined(__OpenBSD__) || \
defined(__FreeBSD__) || \
defined(__NetBSD__) || \
defined(__APPLE__)
static struct termios tios = { BRKINT, 0, B115200|CS8|CREAD, 0, { 0 } };
#else
static struct termios tios = { BRKINT, 0, B115200|CS8|CREAD, 0, 0 };
#endif
static struct speedmap {
char *str;
speed_t val;
} speedmap[] = {
{ "50", B50 }, { "75", B75 }, { "110", B110 },
{ "134", B134 }, { "150", B150 }, { "200", B200 },
{ "300", B300 }, { "600", B600 }, { "1200", B1200 },
{ "1800", B1800 }, { "2400", B2400 }, { "4800", B4800 },
{ "9600", B9600 }, { "19200", B19200 }, { "38400", B38400 },
{ "57600", B57600 },
#ifdef B76800
{ "76800", B76800 },
#endif
{ "115200", B115200 },
#ifdef B153600
{ "153600", B153600 },
#endif
{ "230400", B230400 },
#ifdef B307200
{ "307200", B307200 },
#endif
#ifdef B460800
{ "460800", B460800 }
#endif
};
static int nspeeds = sizeof speedmap / sizeof speedmap[0];
speed_t
cvtspeed(char *str)
{
struct speedmap *smp = speedmap, *esmp = &speedmap[nspeeds];
while (smp < esmp) {
if (strcmp(str, smp->str) == 0)
return (smp->val);
smp++;
}
return B0;
}
int
serialopen(char *device, speed_t speed)
{
int fd;
if (cfsetospeed(&tios, speed) < 0)
return -1;
if ((fd = open(device, O_RDWR)) < 0)
return -1;
if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
(void)close(fd);
return -1;
}
return fd;
}
int
serialreadchar(int fd, int timeout)
{
fd_set fds;
struct timeval tv;
int n;
char ch;
tv.tv_sec = timeout;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(fd, &fds);
/* this is a fucking horrible quick hack - fix this */
if ((n = select(fd + 1, &fds, 0, 0, &tv)) < 0)
return SERIAL_ERROR;
if (n == 0)
return SERIAL_TIMEOUT;
if ((n = read(fd, &ch, 1)) < 0)
return SERIAL_ERROR;
if (n == 0)
return SERIAL_EOF;
return ch;
}
int
serialwrite(int fd, char *buf, int len)
{
int n;
do {
n = write(fd, buf, len);
if (n < 0)
return 1;
len -= n;
buf += n;
} while (len > 0);
return 0;
}
int
serialclose(int fd)
{
return close(fd);
}

View file

@ -0,0 +1,34 @@
/*
* (C) Copyright 2000
* Murray Jensen <Murray.Jensen@csiro.au>
*
* 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 <termios.h>
#define SERIAL_ERROR -1 /* General error, see errno for details */
#define SERIAL_TIMEOUT -2
#define SERIAL_EOF -3
extern speed_t cvtspeed(char *);
extern int serialopen(char *, speed_t);
extern int serialreadchar(int, int);
extern int serialwrite(int, char *, int);
extern int serialclose(int);

View file

@ -0,0 +1,50 @@
/*
* (C) Copyright 2001
* Murray Jensen <Murray.Jensen@cmst.csiro.au>
*
* 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
int
main(int argc, char *argv[])
{
unsigned long ethaddr_low, ethaddr_high;
srand(time(0) | getpid());
/*
* setting the 2nd LSB in the most significant byte of
* the address makes it a locally administered ethernet
* address
*/
ethaddr_high = (rand() & 0xfeff) | 0x0200;
ethaddr_low = rand();
printf("%02lx:%02lx:%02lx:%02lx:%02lx:%02lx\n",
ethaddr_high >> 8, ethaddr_high & 0xff,
ethaddr_low >> 24, (ethaddr_low >> 16) & 0xff,
(ethaddr_low >> 8) & 0xff, ethaddr_low & 0xff);
return (0);
}

View file

@ -0,0 +1,101 @@
/* getline.c -- Replacement for GNU C library function getline
Copyright (C) 1993, 1996, 2001, 2002 Free Software Foundation, Inc.
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. */
/* Written by Jan Brittenson, bson@gnu.ai.mit.edu. */
#include <assert.h>
#include <stdio.h>
/* Always add at least this many bytes when extending the buffer. */
#define MIN_CHUNK 64
/* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR
+ OFFSET (and null-terminate it). *LINEPTR is a pointer returned from
malloc (or NULL), pointing to *N characters of space. It is realloc'd
as necessary. Return the number of characters read (not including the
null terminator), or -1 on error or EOF.
NOTE: There is another getstr() function declared in <curses.h>. */
static int getstr(char **lineptr, size_t *n, FILE *stream,
char terminator, size_t offset)
{
int nchars_avail; /* Allocated but unused chars in *LINEPTR. */
char *read_pos; /* Where we're reading into *LINEPTR. */
int ret;
if (!lineptr || !n || !stream)
return -1;
if (!*lineptr) {
*n = MIN_CHUNK;
*lineptr = malloc(*n);
if (!*lineptr)
return -1;
}
nchars_avail = *n - offset;
read_pos = *lineptr + offset;
for (;;) {
register int c = getc(stream);
/* We always want at least one char left in the buffer, since we
always (unless we get an error while reading the first char)
NUL-terminate the line buffer. */
assert(*n - nchars_avail == read_pos - *lineptr);
if (nchars_avail < 2) {
if (*n > MIN_CHUNK)
*n *= 2;
else
*n += MIN_CHUNK;
nchars_avail = *n + *lineptr - read_pos;
*lineptr = realloc(*lineptr, *n);
if (!*lineptr)
return -1;
read_pos = *n - nchars_avail + *lineptr;
assert(*n - nchars_avail == read_pos - *lineptr);
}
if (c == EOF || ferror (stream)) {
/* Return partial line, if any. */
if (read_pos == *lineptr)
return -1;
else
break;
}
*read_pos++ = c;
nchars_avail--;
if (c == terminator)
/* Return the line. */
break;
}
/* Done - NUL terminate and return the number of chars read. */
*read_pos = '\0';
ret = read_pos - (*lineptr + offset);
return ret;
}
int getline (char **lineptr, size_t *n, FILE *stream)
{
return getstr(lineptr, n, stream, '\n', 0);
}

View file

@ -0,0 +1 @@
int getline(char **lineptr, size_t *n, FILE *stream);

View file

@ -0,0 +1,54 @@
/*
* (C) Copyright 2013
*
* Written by Guilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include "imagetool.h"
/*
* Callback function to register a image type within a tool
*/
static imagetool_register_t register_func;
/*
* register_image_tool -
*
* The tool provides its own registration function in order to all image
* types initialize themselves.
*/
void register_image_tool(imagetool_register_t image_register)
{
/*
* Save the image tool callback function. It will be used to register
* image types within that tool
*/
register_func = image_register;
/* Init Kirkwood Boot image generation/list support */
init_kwb_image_type();
/* Init Freescale imx Boot image generation/list support */
init_imx_image_type();
/* Init FIT image generation/list support */
init_fit_image_type();
/* Init TI OMAP Boot image generation/list support */
init_omap_image_type();
/* Init Default image generation/list support */
init_default_image_type();
/* Init Davinci UBL support */
init_ubl_image_type();
/* Init Davinci AIS support */
init_ais_image_type();
}
/*
* register_image_type -
*
* Register a image type within a tool
*/
void register_image_type(struct image_type_params *tparams)
{
register_func(tparams);
}

View file

@ -0,0 +1,161 @@
/*
* (C) Copyright 2013
*
* Written by Guilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _IMAGETOOL_H_
#define _IMAGETOOL_H_
#include "os_support.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include <u-boot-sha1.h>
#include "fdt_host.h"
/*
* This structure defines all such variables those are initialized by
* mkimage and dumpimage main core and need to be referred by image
* type specific functions
*/
struct image_tool_params {
int dflag;
int eflag;
int fflag;
int iflag;
int lflag;
int pflag;
int vflag;
int xflag;
int skipcpy;
int os;
int arch;
int type;
int comp;
char *dtc;
unsigned int addr;
unsigned int ep;
char *imagename;
char *imagename2;
char *datafile;
char *imagefile;
char *cmdname;
const char *outfile; /* Output filename */
};
/*
* image type specific variables and callback functions
*/
struct image_type_params {
/* name is an identification tag string for added support */
char *name;
/*
* header size is local to the specific image type to be supported,
* mkimage core treats this as number of bytes
*/
uint32_t header_size;
/* Image type header pointer */
void *hdr;
/*
* There are several arguments that are passed on the command line
* and are registered as flags in image_tool_params structure.
* This callback function can be used to check the passed arguments
* are in-lined with the image type to be supported
*
* Returns 1 if parameter check is successful
*/
int (*check_params) (struct image_tool_params *);
/*
* This function is used by list command (i.e. mkimage -l <filename>)
* image type verification code must be put here
*
* Returns 0 if image header verification is successful
* otherwise, returns respective negative error codes
*/
int (*verify_header) (unsigned char *, int, struct image_tool_params *);
/* Prints image information abstracting from image header */
void (*print_header) (const void *);
/*
* The header or image contents need to be set as per image type to
* be generated using this callback function.
* further output file post processing (for ex. checksum calculation,
* padding bytes etc..) can also be done in this callback function.
*/
void (*set_header) (void *, struct stat *, int,
struct image_tool_params *);
/*
* This function is used by the command to retrieve a data file from
* the image (i.e. dumpimage -i <image> -p <position> <data_file>).
* Thus the code to extract a file from an image must be put here.
*
* Returns 0 if the file was successfully retrieved from the image,
* or a negative value on error.
*/
int (*extract_datafile) (void *, struct image_tool_params *);
/*
* Some image generation support for ex (default image type) supports
* more than one type_ids, this callback function is used to check
* whether input (-T <image_type>) is supported by registered image
* generation/list low level code
*/
int (*check_image_type) (uint8_t);
/* This callback function will be executed if fflag is defined */
int (*fflag_handle) (struct image_tool_params *);
/*
* This callback function will be executed for variable size record
* It is expected to build this header in memory and return its length
* and a pointer to it by using image_type_params.header_size and
* image_type_params.hdr. The return value shall indicate if an
* additional padding should be used when copying the data image
* by returning the padding length.
*/
int (*vrec_header) (struct image_tool_params *,
struct image_type_params *);
/* pointer to the next registered entry in linked list */
struct image_type_params *next;
};
/*
* Tool registration function.
*/
typedef void (*imagetool_register_t)(struct image_type_params *);
/*
* Initializes all image types with the given registration callback
* function.
* An image tool uses this function to initialize all image types.
*/
void register_image_tool(imagetool_register_t image_register);
/*
* Register a image type within a tool.
* An image type uses this function to register itself within
* all tools.
*/
void register_image_type(struct image_type_params *tparams);
/*
* There is a c file associated with supported image type low level code
* for ex. default_image.c, fit_image.c
* init_xxx_type() is the only function referred by image tool core to avoid
* a single lined header file, you can define them here
*
* Supported image types init functions
*/
void init_default_image_type(void);
void init_ais_image_type(void);
void init_kwb_image_type(void);
void init_imx_image_type(void);
void init_fit_image_type(void);
void init_ubl_image_type(void);
void init_omap_image_type(void);
#endif /* _IMAGETOOL_H_ */

View file

@ -0,0 +1,388 @@
#!/bin/sh
# This script converts binary files (u-boot.bin) into so called
# bootstrap records that are accepted by Motorola's MC9328MX1/L
# (a.k.a. DragaonBall i.MX) in "Bootstrap Mode"
#
# The code for the SynchFlash programming routines is taken from
# Bootloader\Bin\SyncFlash\programBoot_b.txt contained in
# Motorolas LINUX_BSP_0_3_8.tar.gz
#
# The script could easily extended for AMD flash routines.
#
# 2004-06-23 - steven.scholz@imc-berlin.de
#################################################################################
# From the posting to the U-Boot-Users mailing list, 23 Jun 2004:
# ===============================================================
# I just hacked a simple script that converts u-boot.bin into a text file
# containg processor init code, SynchFlash programming code and U-Boot data in
# form of so called b-records.
#
# This can be used to programm U-Boot into (Synch)Flash using the Bootstrap
# Mode of the MC9328MX1/L
#
# 0AFE1F3410202E2E2E000000002073756363656564/
# 0AFE1F44102E0A0000206661696C656420210A0000/
# 0AFE100000
# ...
# MX1ADS Sync-flash Programming Utility v0.5 2002/08/21
#
# Source address (stored in 0x0AFE0000): 0x0A000000
# Target address (stored in 0x0AFE0004): 0x0C000000
# Size (stored in 0x0AFE0008): 0x0001A320
#
# Press any key to start programming ...
# Erasing ...
# Blank checking ...
# Programming ...
# Verifying flash ... succeed.
#
# Programming finished.
#
# So no need for a BDI2000 anymore... ;-)
#
# This is working on my MX1ADS eval board. Hope this could be useful for
# someone.
#################################################################################
if [ "$#" -lt 1 -o "$#" -gt 2 ] ; then
echo "Usage: $0 infile [outfile]" >&2
echo " $0 u-boot.bin [u-boot.brec]" >&2
exit 1
fi
if [ "$#" -ge 1 ] ; then
INFILE=$1
fi
if [ ! -f $INFILE ] ; then
echo "Error: file '$INFILE' does not exist." >&2
exit 1
fi
FILESIZE=`filesize $INFILE`
output_init()
{
echo "\
********************************************
* Initialize I/O Pad Driving Strength *
********************************************
0021B80CC4000003AB
********************************************
* Initialize SDRAM *
********************************************
00221000C492120200 ; pre-charge command
08200000E4 ; special read
00221000C4A2120200 ; auto-refresh command
08000000E4 ; 8 special read
08000000E4 ; 8 special read
08000000E4 ; 8 special read
08000000E4 ; 8 special read
08000000E4 ; 8 special read
08000000E4 ; 8 special read
08000000E4 ; 8 special read
08000000E4 ; 8 special read
00221000C4B2120200 ; set mode register
08111800E4 ; special read
00221000C482124200 ; set normal mode
"
}
output_uboot()
{
echo "\
********************************************
* U-Boot image as bootstrap records *
* will be stored in SDRAM at 0x0A000000 *
********************************************
"
cat $INFILE | \
hexdump -v -e "\"0A0%05.5_ax10\" 16/1 \"%02x\"\"\r\n\"" | \
tr [:lower:] [:upper:]
}
output_flashprog()
{
echo "\
********************************************
* Address of arguments to flashProg *
* ---------------------------------------- *
* Source : 0x0A000000 *
* Destination : 0x0C000000 * "
# get the real size of the U-Boot image
printf "* Size : 0x%08X *\r\n" $FILESIZE
printf "********************************************\r\n"
printf "0AFE0000CC0A0000000C000000%08X\r\n" $FILESIZE
#;0AFE0000CC0A0000000C00000000006000
echo "\
********************************************
* Flash Program *
********************************************
0AFE10001008D09FE5AC0000EA00F0A0E1A42DFE0A
0AFE1010100080FE0A0DC0A0E100D82DE904B04CE2
0AFE1020109820A0E318309FE5003093E5033082E0
0AFE103010003093E5013003E2FF3003E20300A0E1
0AFE10401000A81BE9A01DFE0A0DC0A0E100D82DE9
0AFE10501004B04CE204D04DE20030A0E10D304BE5
0AFE1060109820A0E330309FE5003093E5033082E0
0AFE107010003093E5013903E2000053E3F7FFFF0A
0AFE1080104020A0E310309FE5003093E5032082E0
0AFE1090100D305BE5003082E500A81BE9A01DFE0A
0AFE10A0100DC0A0E100D82DE904B04CE20000A0E1
0AFE10B010D7FFFFEB0030A0E1FF3003E2000053E3
0AFE10C010FAFFFF0A10309FE5003093E5003093E5
0AFE10D010FF3003E20300A0E100A81BE9A01DFE0A
0AFE10E0100DC0A0E100D82DE904B04CE204D04DE2
0AFE10F0100030A0E10D304BE50D305BE52332A0E1
0AFE1100100E304BE50E305BE5090053E30300009A
0AFE1110100E305BE5373083E20E304BE5020000EA
0AFE1120100E305BE5303083E20E304BE50E305BE5
0AFE1130100300A0E1C3FFFFEB0D305BE50F3003E2
0AFE1140100E304BE50E305BE5090053E30300009A
0AFE1150100E305BE5373083E20E304BE5020000EA
0AFE1160100E305BE5303083E20E304BE50E305BE5
0AFE1170100300A0E1B3FFFFEB00A81BE90DC0A0E1
0AFE11801000D82DE904B04CE21CD04DE210000BE5
0AFE11901014100BE518200BE588009FE5E50200EB
0AFE11A01010301BE51C300BE514301BE520300BE5
0AFE11B0100030A0E324300BE524201BE518301BE5
0AFE11C010030052E10000003A120000EA1C004BE2
0AFE11D010002090E520104BE2003091E500C093E5
0AFE11E010043083E2003081E5003092E5042082E2
0AFE11F010002080E50C0053E10200000A0030A0E3
0AFE12001028300BE5050000EA24301BE5043083E2
0AFE12101024300BE5E7FFFFEA0130A0E328300BE5
0AFE12201028001BE500A81BE9E81EFE0A0DC0A0E1
0AFE12301000D82DE904B04CE214D04DE210000BE5
0AFE12401014100BE56C009FE5BA0200EB10301BE5
0AFE12501018300BE50030A0E31C300BE51C201BE5
0AFE12601014301BE5030052E10000003A0D0000EA
0AFE12701018304BE2002093E5001092E5042082E2
0AFE128010002083E5010071E30200000A0030A0E3
0AFE12901020300BE5050000EA1C301BE5043083E2
0AFE12A0101C300BE5ECFFFFEA0130A0E320300BE5
0AFE12B01020001BE500A81BE9001FFE0A0DC0A0E1
0AFE12C01000D82DE904B04CE224D04DE20130A0E3
0AFE12D01024300BE5A4229FE58139A0E3023A83E2
0AFE12E010003082E59820A0E390329FE5003093E5
0AFE12F010033082E0003093E5023903E2000053E3
0AFE1300100300001A74229FE58139A0E3033A83E2
0AFE131010003082E568029FE5860200EBAF36A0E3
0AFE1320100E3883E2003093E510300BE554029FE5
0AFE133010800200EB10301BE5233CA0E1FF3003E2
0AFE1340100300A0E165FFFFEB10301BE52338A0E1
0AFE135010FF3003E20300A0E160FFFFEB10301BE5
0AFE1360102334A0E1FF3003E20300A0E15BFFFFEB
0AFE13701010305BE50300A0E158FFFFEB0A00A0E3
0AFE13801030FFFFEB0D00A0E32EFFFFEBAF36A0E3
0AFE1390100E3883E2043083E2003093E514300BE5
0AFE13A010E4019FE5630200EB14301BE5233CA0E1
0AFE13B010FF3003E20300A0E148FFFFEB14301BE5
0AFE13C0102338A0E1FF3003E20300A0E143FFFFEB
0AFE13D01014301BE52334A0E1FF3003E20300A0E1
0AFE13E0103EFFFFEB14305BE50300A0E13BFFFFEB
0AFE13F0100A00A0E313FFFFEB0D00A0E311FFFFEB
0AFE140010AF36A0E30E3883E2083083E2003093E5
0AFE14101018300BE574019FE5460200EB18301BE5
0AFE142010233CA0E1FF3003E20300A0E12BFFFFEB
0AFE14301018301BE52338A0E1FF3003E20300A0E1
0AFE14401026FFFFEB18301BE52334A0E1FF3003E2
0AFE1450100300A0E121FFFFEB18305BE50300A0E1
0AFE1460101EFFFFEB0A00A0E3F6FEFFEB0D00A0E3
0AFE147010F4FEFFEBE6FEFFEB0030A0E1FF3003E2
0AFE148010000053E30000001A020000EA03FFFFEB
0AFE1490102D004BE5F6FFFFEAF4009FE5250200EB
0AFE14A010FEFEFFEB2D004BE5CD0000EBC00000EB
0AFE14B010E0009FE51F0200EB18301BE528300BE5
0AFE14C01014301BE52C300BE52C001BE5100100EB
0AFE14D01028301BE5013643E228300BE52C301BE5
0AFE14E010013683E22C300BE528301BE5000053E3
0AFE14F010F4FFFFCAAE0000EB14001BE518101BE5
0AFE15001049FFFFEB0030A0E1FF3003E2000053E3
0AFE151010E6FFFF0A80009FE5060200EB10001BE5
0AFE15201014101BE518201BE5D00000EB10001BE5
0AFE15301014101BE518201BE50FFFFFEB0030A0E1
0AFE154010FF3003E2000053E30200000A4C009FE5
0AFE155010F80100EB010000EA44009FE5F50100EB
0AFE156010930000EB3C009FE5F20100EB0000A0E3
0AFE157010A4FEFFEB0030A0E30300A0E100A81BE9
0AFE158010A01DFE0AA41DFE0AE01DFE0A0C1EFE0A
0AFE159010381EFE0A641EFE0A181FFE0A281FFE0A
0AFE15A0103C1FFE0A481FFE0AB41EFE0A0DC0A0E1
0AFE15B01000D82DE904B04CE204D04DE210000BE5
0AFE15C01010301BE5013043E210300BE5010073E3
0AFE15D010FAFFFF1A00A81BE90DC0A0E100D82DE9
0AFE15E01004B04CE208D04DE210000BE510301BE5
0AFE15F01014300BE514301BE50300A0E100A81BE9
0AFE1600100DC0A0E100D82DE904B04CE204D04DE2
0AFE1610102228A0E3012A82E2042082E2E134A0E3
0AFE162010023883E2033C83E2003082E50333A0E3
0AFE163010053983E2003093E510300BE500A81BE9
0AFE1640100DC0A0E100D82DE904B04CE204D04DE2
0AFE1650102228A0E3012A82E2042082E29134A0E3
0AFE166010023883E2033C83E2003082E5C136A0E3
0AFE167010003093E510300BE52228A0E3012A82E2
0AFE168010042082E2E134A0E3023883E2033C83E2
0AFE169010003082E50333A0E3073983E20020A0E3
0AFE16A010002083E52228A0E3012A82E2042082E2
0AFE16B0108134A0E3023883E2033C83E2003082E5
0AFE16C0100333A0E3003093E510300BE5CBFFFFEB
0AFE16D01010301BE50300A0E100A81BE90DC0A0E1
0AFE16E01000D82DE904B04CE208D04DE2D3FFFFEB
0AFE16F0100030A0E110300BE510301BE5023503E2
0AFE170010000053E30500000A10301BE5073703E2
0AFE171010000053E30100000A10001BE5ADFFFFEB
0AFE17201010301BE5803003E2000053E30500000A
0AFE17301010301BE51C3003E2000053E30100000A
0AFE17401010001BE5A3FFFFEB10201BE50235A0E3
0AFE175010803083E2030052E10200001A0130A0E3
0AFE17601014300BE5010000EA0030A0E314300BE5
0AFE17701014001BE500A81BE90DC0A0E100D82DE9
0AFE17801004B04CE204D04DE22228A0E3012A82E2
0AFE179010042082E29134A0E3023883E2033C83E2
0AFE17A010003082E5C136A0E3003093E510300BE5
0AFE17B01000A81BE90DC0A0E100D82DE904B04CE2
0AFE17C010ECFFFFEB2228A0E3012A82E2042082E2
0AFE17D0108134A0E3023883E2033C83E2003082E5
0AFE17E01000A81BE90DC0A0E100D82DE904B04CE2
0AFE17F01004D04DE22228A0E3012A82E2042082E2
0AFE1800102238A0E3013A83E2043083E2003093E5
0AFE181010023183E3003082E52228A0E3012A82E2
0AFE1820102238A0E3013A83E2003093E5023183E3
0AFE183010003082E5FA0FA0E35BFFFFEB2228A0E3
0AFE184010012A82E2042082E2B134A0E3023883E2
0AFE185010033C83E2003082E50333A0E3233983E2
0AFE186010033B83E2003093E510300BE500A81BE9
0AFE1870100DC0A0E100D82DE904B04CE21CD04DE2
0AFE18801010000BE514100BE518200BE50030A0E3
0AFE1890101C300BE51C201BE518301BE5030052E1
0AFE18A0100000003A190000EAB2FFFFEB2228A0E3
0AFE18B010012A82E2042082E2F134A0E3023883E2
0AFE18C010033C83E2003082E514201BE51C301BE5
0AFE18D010031082E010201BE51C301BE5033082E0
0AFE18E010003093E5003081E57BFFFFEB0030A0E1
0AFE18F010FF3003E2000053E3FAFFFF0AACFFFFEB
0AFE1900101C301BE5043083E21C300BE5E0FFFFEA
0AFE19101000A81BE90DC0A0E100D82DE904B04CE2
0AFE1920100CD04DE210000BE52228A0E3012A82E2
0AFE193010042082E28134A0E3023883E2033C83E2
0AFE194010003082E510301BE5003093E514300BE5
0AFE1950102228A0E3012A82E2042082E29134A0E3
0AFE196010023883E2033C83E2003082E510301BE5
0AFE197010003093E518300BE52228A0E3012A82E2
0AFE198010042082E2E134A0E3023883E2033C83E2
0AFE199010003082E50229A0E310301BE5032082E0
0AFE19A0100030A0E3003082E52228A0E3012A82E2
0AFE19B010042082E28134A0E3023883E2033C83E2
0AFE19C010003082E510201BE50D3AA0E3D03083E2
0AFE19D010033883E1003082E53FFFFFEB0030A0E1
0AFE19E010FF3003E2000053E3FAFFFF0A70FFFFEB
0AFE19F01000A81BE90DC0A0E100D82DE904B04CE2
0AFE1A00105CFFFFEB2228A0E3012A82E2042082E2
0AFE1A1010E134A0E3023883E2033C83E2003082E5
0AFE1A20100333A0E3033983E20020A0E3002083E5
0AFE1A30102228A0E3012A82E2042082E28134A0E3
0AFE1A4010023883E2033C83E2003082E50323A0E3
0AFE1A5010032982E20339A0E3C03083E2033883E1
0AFE1A6010003082E500A81BE90DC0A0E100D82DE9
0AFE1A701004B04CE23FFFFFEB2228A0E3012A82E2
0AFE1A8010042082E2E134A0E3023883E2033C83E2
0AFE1A9010003082E50333A0E30A3983E20020A0E3
0AFE1AA010002083E52228A0E3012A82E2042082E2
0AFE1AB0108134A0E3023883E2033C83E2003082E5
0AFE1AC0100323A0E30A2982E20339A0E3C03083E2
0AFE1AD010033883E1003082E500A81BE90DC0A0E1
0AFE1AE01000D82DE904B04CE28729A0E3222E82E2
0AFE1AF0108739A0E3223E83E2003093E51E3CC3E3
0AFE1B0010003082E58729A0E38E2F82E28739A0E3
0AFE1B10108E3F83E2003093E51E3CC3E3003082E5
0AFE1B20108139A0E3823D83E20520A0E3002083E5
0AFE1B30108129A0E3822D82E2042082E20139A0E3
0AFE1B4010273083E2003082E58139A0E3823D83E2
0AFE1B50100C3083E20120A0E3002083E58129A0E3
0AFE1B6010822D82E2102082E22A3DA0E3013083E2
0AFE1B7010003082E58139A0E3823D83E2243083E2
0AFE1B80100F20A0E3002083E58139A0E3823D83E2
0AFE1B9010283083E28A20A0E3002083E58139A0E3
0AFE1BA010823D83E22C3083E20820A0E3002083E5
0AFE1BB01000A81BE90DC0A0E100D82DE904B04CE2
0AFE1BC0108139A0E3823D83E2183083E2003093E5
0AFE1BD010013003E2FF3003E20300A0E100A81BE9
0AFE1BE0100DC0A0E100D82DE904B04CE204D04DE2
0AFE1BF0100030A0E10D304BE58139A0E3823D83E2
0AFE1C0010183083E2003093E5013903E2000053E3
0AFE1C1010F8FFFF0A8139A0E3813D83E20D205BE5
0AFE1C2010002083E50D305BE50A0053E30A00001A
0AFE1C30108139A0E3823D83E2183083E2003093E5
0AFE1C4010013903E2000053E3F8FFFF0A8139A0E3
0AFE1C5010813D83E20D20A0E3002083E500A81BE9
0AFE1C60100DC0A0E100D82DE904B04CE20000A0E1
0AFE1C7010CFFFFFEB0030A0E1FF3003E2000053E3
0AFE1C8010FAFFFF0A8139A0E3023A83E2003093E5
0AFE1C9010FF3003E20300A0E100A81BE90DC0A0E1
0AFE1CA01000D82DE904B04CE204D04DE20030A0E1
0AFE1CB0100D304BE50D305BE52332A0E10E304BE5
0AFE1CC0100E305BE5090053E30300009A0E305BE5
0AFE1CD010373083E20E304BE5020000EA0E305BE5
0AFE1CE010303083E20E304BE50E305BE50300A0E1
0AFE1CF010BAFFFFEB0D305BE50F3003E20E304BE5
0AFE1D00100E305BE5090053E30300009A0E305BE5
0AFE1D1010373083E20E304BE5020000EA0E305BE5
0AFE1D2010303083E20E304BE50E305BE50300A0E1
0AFE1D3010AAFFFFEB00A81BE90DC0A0E100D82DE9
0AFE1D401004B04CE204D04DE210000BE510301BE5
0AFE1D50100030D3E5000053E30000001A080000EA
0AFE1D601010104BE2003091E50320A0E10020D2E5
0AFE1D7010013083E2003081E50200A0E197FFFFEB
0AFE1D8008F1FFFFEA00A81BE9
0AFE1DA4100A0D4D58314144532053796E632D666C
0AFE1DB4106173682050726F6772616D6D696E6720
0AFE1DC4105574696C6974792076302E3520323030
0AFE1DD410322F30382F32310A0D000000536F7572
0AFE1DE41063652061646472657373202873746F72
0AFE1DF410656420696E2030783041464530303030
0AFE1E0410293A2030780000005461726765742061
0AFE1E1410646472657373202873746F7265642069
0AFE1E24106E2030783041464530303034293A2030
0AFE1E34107800000053697A652020202020202020
0AFE1E44102020202873746F72656420696E203078
0AFE1E54103041464530303038293A203078000000
0AFE1E6410507265737320616E79206B657920746F
0AFE1E74102073746172742070726F6772616D6D69
0AFE1E84106E67202E2E2E00000A0D45726173696E
0AFE1E94106720666C617368202E2E2E000A0D5072
0AFE1EA4106F6772616D6D696E67202E2E2E000000
0AFE1EB4100A0D50726F6772616D6D696E67206669
0AFE1EC4106E69736865642E0A0D50726573732027
0AFE1ED410612720746F20636F6E74696E7565202E
0AFE1EE4102E2E2E000A0D566572696679696E6720
0AFE1EF410666C617368202E2E2E0000000A0D426C
0AFE1F0410616E6B20636865636B696E67202E2E2E
0AFE1F1410000000000A45726173696E67202E2E2E
0AFE1F2410000000000A50726F6772616D6D696E67
0AFE1F3410202E2E2E000000002073756363656564
0AFE1F44102E0A0000206661696C656420210A0000
0AFE100000
"
}
#########################################################
if [ "$#" -eq 2 ] ; then
output_init > $2
output_uboot >> $2
output_flashprog >> $2
else
output_init;
output_uboot;
output_flashprog;
fi

View file

@ -0,0 +1,372 @@
/*************************************************************************
| COPYRIGHT (c) 2000 BY ABATRON AG
|*************************************************************************
|
| PROJECT NAME: Linux Image to S-record Conversion Utility
| FILENAME : img2srec.c
|
| COMPILER : GCC
|
| TARGET OS : LINUX / UNIX
| TARGET HW : -
|
| PROGRAMMER : Abatron / RD
| CREATION : 07.07.00
|
|*************************************************************************
|
| DESCRIPTION :
|
| Utility to convert a Linux Boot Image to S-record:
| ==================================================
|
| This command line utility can be used to convert a Linux boot image
| (zimage.initrd) to S-Record format used for flash programming.
| This conversion takes care of the special sections "IMAGE" and INITRD".
|
| img2srec [-o offset] image > image.srec
|
|
| Build the utility:
| ==================
|
| To build the utility use GCC as follows:
|
| gcc img2srec.c -o img2srec
|
|
|*************************************************************************
|
|
| UPDATES :
|
| DATE NAME CHANGES
| -----------------------------------------------------------
| Latest update
|
| 07.07.00 aba Initial release
|
|*************************************************************************/
/*************************************************************************
| INCLUDES
|*************************************************************************/
#include "os_support.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <elf.h>
#include <unistd.h>
#include <errno.h>
/*************************************************************************
| FUNCTIONS
|*************************************************************************/
static char* ExtractHex (uint32_t* value, char* getPtr)
{
uint32_t num;
uint32_t digit;
uint8_t c;
while (*getPtr == ' ') getPtr++;
num = 0;
for (;;) {
c = *getPtr;
if ((c >= '0') && (c <= '9')) digit = (uint32_t)(c - '0');
else if ((c >= 'A') && (c <= 'F')) digit = (uint32_t)(c - 'A' + 10);
else if ((c >= 'a') && (c <= 'f')) digit = (uint32_t)(c - 'a' + 10);
else break;
num <<= 4;
num += digit;
getPtr++;
} /* for */
*value = num;
return getPtr;
} /* ExtractHex */
static char* ExtractDecimal (uint32_t* value, char* getPtr)
{
uint32_t num;
uint32_t digit;
uint8_t c;
while (*getPtr == ' ') getPtr++;
num = 0;
for (;;) {
c = *getPtr;
if ((c >= '0') && (c <= '9')) digit = (uint32_t)(c - '0');
else break;
num *= 10;
num += digit;
getPtr++;
} /* for */
*value = num;
return getPtr;
} /* ExtractDecimal */
static void ExtractNumber (uint32_t* value, char* getPtr)
{
bool neg = false;;
while (*getPtr == ' ') getPtr++;
if (*getPtr == '-') {
neg = true;
getPtr++;
} /* if */
if ((*getPtr == '0') && ((*(getPtr+1) == 'x') || (*(getPtr+1) == 'X'))) {
getPtr +=2;
(void)ExtractHex(value, getPtr);
} /* if */
else {
(void)ExtractDecimal(value, getPtr);
} /* else */
if (neg) *value = -(*value);
} /* ExtractNumber */
static uint8_t* ExtractWord(uint16_t* value, uint8_t* buffer)
{
uint16_t x;
x = (uint16_t)*buffer++;
x = (x<<8) + (uint16_t)*buffer++;
*value = x;
return buffer;
} /* ExtractWord */
static uint8_t* ExtractLong(uint32_t* value, uint8_t* buffer)
{
uint32_t x;
x = (uint32_t)*buffer++;
x = (x<<8) + (uint32_t)*buffer++;
x = (x<<8) + (uint32_t)*buffer++;
x = (x<<8) + (uint32_t)*buffer++;
*value = x;
return buffer;
} /* ExtractLong */
static uint8_t* ExtractBlock(uint16_t count, uint8_t* data, uint8_t* buffer)
{
while (count--) *data++ = *buffer++;
return buffer;
} /* ExtractBlock */
static char* WriteHex(char* pa, uint8_t value, uint16_t* pCheckSum)
{
uint16_t temp;
static char ByteToHex[] = "0123456789ABCDEF";
*pCheckSum += value;
temp = value / 16;
*pa++ = ByteToHex[temp];
temp = value % 16;
*pa++ = ByteToHex[temp];
return pa;
}
static char* BuildSRecord(char* pa, uint16_t sType, uint32_t addr,
const uint8_t* data, int nCount)
{
uint16_t addrLen;
uint16_t sRLen;
uint16_t checkSum;
uint16_t i;
switch (sType) {
case 0:
case 1:
case 9:
addrLen = 2;
break;
case 2:
case 8:
addrLen = 3;
break;
case 3:
case 7:
addrLen = 4;
break;
default:
return pa;
} /* switch */
*pa++ = 'S';
*pa++ = (char)(sType + '0');
sRLen = addrLen + nCount + 1;
checkSum = 0;
pa = WriteHex(pa, (uint8_t)sRLen, &checkSum);
/* Write address field */
for (i = 1; i <= addrLen; i++) {
pa = WriteHex(pa, (uint8_t)(addr >> (8 * (addrLen - i))), &checkSum);
} /* for */
/* Write code/data fields */
for (i = 0; i < nCount; i++) {
pa = WriteHex(pa, *data++, &checkSum);
} /* for */
/* Write checksum field */
checkSum = ~checkSum;
pa = WriteHex(pa, (uint8_t)checkSum, &checkSum);
*pa++ = '\0';
return pa;
}
static void ConvertELF(char* fileName, uint32_t loadOffset)
{
FILE* file;
int i;
int rxCount;
uint8_t rxBlock[1024];
uint32_t loadSize;
uint32_t firstAddr;
uint32_t loadAddr;
uint32_t loadDiff = 0;
Elf32_Ehdr elfHeader;
Elf32_Shdr sectHeader[32];
uint8_t* getPtr;
char srecLine[128];
char *hdr_name;
/* open file */
if ((file = fopen(fileName,"rb")) == NULL) {
fprintf (stderr, "Can't open %s: %s\n", fileName, strerror(errno));
return;
} /* if */
/* read ELF header */
rxCount = fread(rxBlock, 1, sizeof elfHeader, file);
getPtr = ExtractBlock(sizeof elfHeader.e_ident, elfHeader.e_ident, rxBlock);
getPtr = ExtractWord(&elfHeader.e_type, getPtr);
getPtr = ExtractWord(&elfHeader.e_machine, getPtr);
getPtr = ExtractLong((uint32_t *)&elfHeader.e_version, getPtr);
getPtr = ExtractLong((uint32_t *)&elfHeader.e_entry, getPtr);
getPtr = ExtractLong((uint32_t *)&elfHeader.e_phoff, getPtr);
getPtr = ExtractLong((uint32_t *)&elfHeader.e_shoff, getPtr);
getPtr = ExtractLong((uint32_t *)&elfHeader.e_flags, getPtr);
getPtr = ExtractWord(&elfHeader.e_ehsize, getPtr);
getPtr = ExtractWord(&elfHeader.e_phentsize, getPtr);
getPtr = ExtractWord(&elfHeader.e_phnum, getPtr);
getPtr = ExtractWord(&elfHeader.e_shentsize, getPtr);
getPtr = ExtractWord(&elfHeader.e_shnum, getPtr);
getPtr = ExtractWord(&elfHeader.e_shstrndx, getPtr);
if ( (rxCount != sizeof elfHeader)
|| (elfHeader.e_ident[0] != ELFMAG0)
|| (elfHeader.e_ident[1] != ELFMAG1)
|| (elfHeader.e_ident[2] != ELFMAG2)
|| (elfHeader.e_ident[3] != ELFMAG3)
|| (elfHeader.e_type != ET_EXEC)
) {
fclose(file);
fprintf (stderr, "*** illegal file format\n");
return;
} /* if */
/* read all section headers */
fseek(file, elfHeader.e_shoff, SEEK_SET);
for (i = 0; i < elfHeader.e_shnum; i++) {
rxCount = fread(rxBlock, 1, sizeof sectHeader[0], file);
getPtr = ExtractLong((uint32_t *)&sectHeader[i].sh_name, rxBlock);
getPtr = ExtractLong((uint32_t *)&sectHeader[i].sh_type, getPtr);
getPtr = ExtractLong((uint32_t *)&sectHeader[i].sh_flags, getPtr);
getPtr = ExtractLong((uint32_t *)&sectHeader[i].sh_addr, getPtr);
getPtr = ExtractLong((uint32_t *)&sectHeader[i].sh_offset, getPtr);
getPtr = ExtractLong((uint32_t *)&sectHeader[i].sh_size, getPtr);
getPtr = ExtractLong((uint32_t *)&sectHeader[i].sh_link, getPtr);
getPtr = ExtractLong((uint32_t *)&sectHeader[i].sh_info, getPtr);
getPtr = ExtractLong((uint32_t *)&sectHeader[i].sh_addralign, getPtr);
getPtr = ExtractLong((uint32_t *)&sectHeader[i].sh_entsize, getPtr);
if (rxCount != sizeof sectHeader[0]) {
fclose(file);
fprintf (stderr, "*** illegal file format\n");
return;
} /* if */
} /* for */
if ((hdr_name = strrchr(fileName, '/')) == NULL) {
hdr_name = fileName;
} else {
++hdr_name;
}
/* write start record */
(void)BuildSRecord(srecLine, 0, 0, (uint8_t *)hdr_name, strlen(hdr_name));
printf("%s\r\n",srecLine);
/* write data records */
firstAddr = ~0;
loadAddr = 0;
for (i = 0; i < elfHeader.e_shnum; i++) {
if ( (sectHeader[i].sh_type == SHT_PROGBITS)
&& (sectHeader[i].sh_size != 0)
) {
loadSize = sectHeader[i].sh_size;
if (sectHeader[i].sh_flags != 0) {
loadAddr = sectHeader[i].sh_addr;
loadDiff = loadAddr - sectHeader[i].sh_offset;
} /* if */
else {
loadAddr = sectHeader[i].sh_offset + loadDiff;
} /* else */
if (loadAddr < firstAddr)
firstAddr = loadAddr;
/* build s-records */
loadSize = sectHeader[i].sh_size;
fseek(file, sectHeader[i].sh_offset, SEEK_SET);
while (loadSize) {
rxCount = fread(rxBlock, 1, (loadSize > 32) ? 32 : loadSize, file);
if (rxCount < 0) {
fclose(file);
fprintf (stderr, "*** illegal file format\n");
return;
} /* if */
(void)BuildSRecord(srecLine, 3, loadAddr + loadOffset, rxBlock, rxCount);
loadSize -= rxCount;
loadAddr += rxCount;
printf("%s\r\n",srecLine);
} /* while */
} /* if */
} /* for */
/* add end record */
(void)BuildSRecord(srecLine, 7, firstAddr + loadOffset, 0, 0);
printf("%s\r\n",srecLine);
fclose(file);
} /* ConvertELF */
/*************************************************************************
| MAIN
|*************************************************************************/
int main( int argc, char *argv[ ])
{
uint32_t offset;
if (argc == 2) {
ConvertELF(argv[1], 0);
} /* if */
else if ((argc == 4) && (strcmp(argv[1], "-o") == 0)) {
ExtractNumber(&offset, argv[2]);
ConvertELF(argv[3], offset);
} /* if */
else {
fprintf (stderr, "Usage: img2srec [-o offset] <image>\n");
} /* if */
return 0;
} /* main */

View file

@ -0,0 +1,97 @@
#
# (C) Copyright 2009 Marco Stornelli <marco.stornelli@gmail.com>
#
# 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
# Generated executable files
BIN_FILES-y += imls
# Source files which exist outside the tools/imls directory
EXT_OBJ_FILES-y += lib/crc32.o
EXT_OBJ_FILES-y += lib/md5.o
EXT_OBJ_FILES-y += lib/sha1.o
EXT_OBJ_FILES-y += common/image.o
# Source files located in the tools/imls directory
OBJ_FILES-y += imls.o
# Flattened device tree objects
LIBFDT_OBJ_FILES-y += fdt.o
LIBFDT_OBJ_FILES-y += fdt_ro.o
LIBFDT_OBJ_FILES-y += fdt_rw.o
LIBFDT_OBJ_FILES-y += fdt_strerror.o
LIBFDT_OBJ_FILES-y += fdt_wip.o
# now $(obj) is defined
SRCS += $(addprefix $(SRCTREE)/,$(EXT_OBJ_FILES-y:.o=.c))
SRCS += $(addprefix $(SRCTREE)/tools/,$(OBJ_FILES-y:.o=.c))
SRCS += $(addprefix $(SRCTREE)/lib/libfdt/,$(LIBFDT_OBJ_FILES-y:.o=.c))
BINS := $(addprefix $(obj),$(sort $(BIN_FILES-y)))
LIBFDT_OBJS := $(addprefix $(obj),$(LIBFDT_OBJ_FILES-y))
#
# Compile for a hosted environment on the target
# Define __KERNEL_STRICT_NAMES to prevent typedef overlaps
#
HOSTCPPFLAGS = -idirafter $(SRCTREE)/include \
-idirafter $(OBJTREE)/include2 \
-idirafter $(OBJTREE)/include \
-I $(SRCTREE)/lib/libfdt \
-I $(SRCTREE)/tools \
-DUSE_HOSTCC -D__KERNEL_STRICT_NAMES
ifeq ($(MTD_VERSION),old)
HOSTCPPFLAGS += -DMTD_OLD
endif
all: $(BINS)
$(obj)imls: $(obj)imls.o $(obj)crc32.o $(obj)image.o $(obj)md5.o \
$(obj)sha1.o $(LIBFDT_OBJS)
@$(call compile,$(CC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^)
@$(call compile,$(STRIP) $@)
# Some files complain if compiled with -pedantic, use HOSTCFLAGS_NOPED
$(obj)image.o: $(SRCTREE)/common/image.c
@$(call compile,$(CC) -g $(HOSTCFLAGS_NOPED) -c -o $@ $<)
$(obj)imls.o: $(SRCTREE)/tools/imls/imls.c
@$(call compile,$(CC) -g $(HOSTCFLAGS_NOPED) -c -o $@ $<)
# Some of the tool objects need to be accessed from outside the tools/imls directory
$(obj)%.o: $(SRCTREE)/common/%.c
@$(call compile,$(CC) -g $(HOSTCFLAGS_NOPED) -c -o $@ $<)
$(obj)%.o: $(SRCTREE)/lib/%.c
@$(call compile,$(CC) -g $(HOSTCFLAGS) -c -o $@ $<)
$(obj)%.o: $(SRCTREE)/lib/libfdt/%.c
@$(call compile,$(CC) -g $(HOSTCFLAGS_NOPED) -c -o $@ $<)
clean:
rm -rf *.o imls
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################

View file

@ -0,0 +1,57 @@
#
# (C) Copyright 2009 Marco Stornelli <marco.stornelli@gmail.com>
#
# See file CREDITS for list of people who contributed to this
# project.
#
# The files in this directory are free software; you can redistribute
# them and/or modify them 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.
#
# These files are distributed in the hope that they 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
#
IMLS
-------------
imls is an implementation of a Linux command line tool to access
to raw flash partitions and list images made with mkimage command.
For building against older versions of the MTD headers (meaning before
v2.6.8-rc1) it is required to pass the argument "MTD_VERSION=old" to
make.
Usage examples
--------------
1) Flash with sectors of 128KiB and 32 sectors:
> imls -c 32 -s 131072 /dev/mtd0
Searching...
Image Name: foo
Created: Fri Apr 10 18:11:30 2009
Image Type: Intel x86 Linux Standalone Program (uncompressed)
Data Size: 10716 Bytes = 10.46 kB = 0.01 MB
Load Address: 00000000
Entry Point: 00000000
2) Flash with sectors of 64KiB and 128 sectors and with a search offset of one
sector:
> imls -o 1 -c 128 -s 65536 /dev/mtd0
Searching...
Image Name: foo
Created: Fri Apr 10 18:11:30 2009
Image Type: Intel x86 Linux Standalone Program (uncompressed)
Data Size: 10716 Bytes = 10.46 kB = 0.01 MB
Load Address: 00000000
Entry Point: 00000000

View file

@ -0,0 +1,270 @@
/*
* (C) Copyright 2009 Marco Stornelli
*
* 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 <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <asm/page.h>
#ifdef MTD_OLD
#include <stdint.h>
#include <linux/mtd/mtd.h>
#else
#define __user /* nothing */
#include <mtd/mtd-user.h>
#endif
#include <u-boot-sha1.h>
#include <fdt.h>
#include <libfdt.h>
#include <fdt_support.h>
#include <image.h>
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
extern unsigned long crc32(unsigned long crc, const char *buf, unsigned int len);
static void usage(void);
static int image_verify_header(char *ptr, int fd);
static int flash_bad_block(int fd, uint8_t mtd_type, loff_t start);
char *cmdname;
char *devicefile;
unsigned int sectorcount = 0;
int sflag = 0;
unsigned int sectoroffset = 0;
unsigned int sectorsize = 0;
int cflag = 0;
int main (int argc, char **argv)
{
int fd = -1, err = 0, readbyte = 0, j;
struct mtd_info_user mtdinfo;
char buf[sizeof(image_header_t)];
int found = 0;
cmdname = *argv;
while (--argc > 0 && **++argv == '-') {
while (*++*argv) {
switch (**argv) {
case 'c':
if (--argc <= 0)
usage ();
sectorcount = (unsigned int)atoi(*++argv);
cflag = 1;
goto NXTARG;
case 'o':
if (--argc <= 0)
usage ();
sectoroffset = (unsigned int)atoi(*++argv);
goto NXTARG;
case 's':
if (--argc <= 0)
usage ();
sectorsize = (unsigned int)atoi(*++argv);
sflag = 1;
goto NXTARG;
default:
usage ();
}
}
NXTARG: ;
}
if (argc != 1 || cflag == 0 || sflag == 0)
usage();
devicefile = *argv;
fd = open(devicefile, O_RDONLY);
if (fd < 0) {
fprintf (stderr, "%s: Can't open %s: %s\n",
cmdname, devicefile, strerror(errno));
exit(EXIT_FAILURE);
}
err = ioctl(fd, MEMGETINFO, &mtdinfo);
if (err < 0) {
fprintf(stderr, "%s: Cannot get MTD information: %s\n",cmdname,
strerror(errno));
exit(EXIT_FAILURE);
}
if (mtdinfo.type != MTD_NORFLASH && mtdinfo.type != MTD_NANDFLASH) {
fprintf(stderr, "%s: Unsupported flash type %u\n",
cmdname, mtdinfo.type);
exit(EXIT_FAILURE);
}
if (sectorsize * sectorcount != mtdinfo.size) {
fprintf(stderr, "%s: Partition size (%d) incompatible with "
"sector size and count\n", cmdname, mtdinfo.size);
exit(EXIT_FAILURE);
}
if (sectorsize * sectoroffset >= mtdinfo.size) {
fprintf(stderr, "%s: Partition size (%d) incompatible with "
"sector offset given\n", cmdname, mtdinfo.size);
exit(EXIT_FAILURE);
}
if (sectoroffset > sectorcount - 1) {
fprintf(stderr, "%s: Sector offset cannot be grater than "
"sector count minus one\n", cmdname);
exit(EXIT_FAILURE);
}
printf("Searching....\n");
for (j = sectoroffset; j < sectorcount; ++j) {
if (lseek(fd, j*sectorsize, SEEK_SET) != j*sectorsize) {
fprintf(stderr, "%s: lseek failure: %s\n",
cmdname, strerror(errno));
exit(EXIT_FAILURE);
}
err = flash_bad_block(fd, mtdinfo.type, j*sectorsize);
if (err < 0)
exit(EXIT_FAILURE);
if (err)
continue; /* Skip and jump to next */
readbyte = read(fd, buf, sizeof(image_header_t));
if (readbyte != sizeof(image_header_t)) {
fprintf(stderr, "%s: Can't read from device: %s\n",
cmdname, strerror(errno));
exit(EXIT_FAILURE);
}
if (fdt_check_header(buf)) {
/* old-style image */
if (image_verify_header(buf, fd)) {
found = 1;
image_print_contents((image_header_t *)buf);
}
} else {
/* FIT image */
fit_print_contents(buf);
}
}
close(fd);
if(!found)
printf("No images found\n");
exit(EXIT_SUCCESS);
}
void usage()
{
fprintf (stderr, "Usage:\n"
" %s [-o offset] -s size -c count device\n"
" -o ==> number of sectors to use as offset\n"
" -c ==> number of sectors\n"
" -s ==> size of sectors (byte)\n",
cmdname);
exit(EXIT_FAILURE);
}
static int image_verify_header(char *ptr, int fd)
{
int len, nread;
char *data;
uint32_t checksum;
image_header_t *hdr = (image_header_t *)ptr;
char buf[PAGE_SIZE];
if (image_get_magic(hdr) != IH_MAGIC)
return 0;
data = (char *)hdr;
len = image_get_header_size();
checksum = image_get_hcrc(hdr);
hdr->ih_hcrc = htonl(0); /* clear for re-calculation */
if (crc32(0, data, len) != checksum) {
fprintf(stderr,
"%s: Maybe image found but it has bad header checksum!\n",
cmdname);
return 0;
}
len = image_get_size(hdr);
checksum = 0;
while (len > 0) {
nread = read(fd, buf, MIN(len,PAGE_SIZE));
if (nread != MIN(len,PAGE_SIZE)) {
fprintf(stderr,
"%s: Error while reading: %s\n",
cmdname, strerror(errno));
exit(EXIT_FAILURE);
}
checksum = crc32(checksum, buf, nread);
len -= nread;
}
if (checksum != image_get_dcrc(hdr)) {
fprintf (stderr,
"%s: Maybe image found but it has corrupted data!\n",
cmdname);
return 0;
}
return 1;
}
/*
* Test for bad block on NAND, just returns 0 on NOR, on NAND:
* 0 - block is good
* > 0 - block is bad
* < 0 - failed to test
*/
static int flash_bad_block(int fd, uint8_t mtd_type, loff_t start)
{
if (mtd_type == MTD_NANDFLASH) {
int badblock = ioctl(fd, MEMGETBADBLOCK, &start);
if (badblock < 0) {
fprintf(stderr,"%s: Cannot read bad block mark: %s\n",
cmdname, strerror(errno));
return badblock;
}
if (badblock) {
return badblock;
}
}
return 0;
}

View file

@ -0,0 +1,586 @@
/*
* (C) Copyright 2009
* Stefano Babic, DENX Software Engineering, sbabic@denx.de.
*
* (C) Copyright 2008
* Marvell Semiconductor <www.marvell.com>
* Written-by: Prafulla Wadaskar <prafulla@marvell.com>
*
* 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
*/
/* Required to obtain the getline prototype from stdio.h */
#define _GNU_SOURCE
#include "imagetool.h"
#include <image.h>
#include "imximage.h"
/*
* Supported commands for configuration file
*/
static table_entry_t imximage_cmds[] = {
{CMD_BOOT_FROM, "BOOT_FROM", "boot command", },
{CMD_DATA, "DATA", "Reg Write Data", },
{CMD_IMAGE_VERSION, "IMAGE_VERSION", "image version", },
{-1, "", "", },
};
/*
* Supported Boot options for configuration file
* this is needed to set the correct flash offset
*/
static table_entry_t imximage_bootops[] = {
{FLASH_OFFSET_ONENAND, "onenand", "OneNAND Flash",},
{FLASH_OFFSET_NAND, "nand", "NAND Flash", },
{FLASH_OFFSET_NOR, "nor", "NOR Flash", },
{FLASH_OFFSET_SATA, "sata", "SATA Disk", },
{FLASH_OFFSET_SD, "sd", "SD Card", },
{FLASH_OFFSET_SPI, "spi", "SPI Flash", },
{-1, "", "Invalid", },
};
/*
* IMXIMAGE version definition for i.MX chips
*/
static table_entry_t imximage_versions[] = {
{IMXIMAGE_V1, "", " (i.MX25/35/51 compatible)", },
{IMXIMAGE_V2, "", " (i.MX53/6 compatible)", },
{-1, "", " (Invalid)", },
};
static struct imx_header imximage_header;
static uint32_t imximage_version;
static set_dcd_val_t set_dcd_val;
static set_dcd_rst_t set_dcd_rst;
static set_imx_hdr_t set_imx_hdr;
static uint32_t get_cfg_value(char *token, char *name, int linenr)
{
char *endptr;
uint32_t value;
errno = 0;
value = strtoul(token, &endptr, 16);
if (errno || (token == endptr)) {
fprintf(stderr, "Error: %s[%d] - Invalid hex data(%s)\n",
name, linenr, token);
exit(EXIT_FAILURE);
}
return value;
}
static uint32_t detect_imximage_version(struct imx_header *imx_hdr)
{
imx_header_v1_t *hdr_v1 = &imx_hdr->header.hdr_v1;
imx_header_v2_t *hdr_v2 = &imx_hdr->header.hdr_v2;
flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr;
flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
/* Try to detect V1 */
if ((fhdr_v1->app_code_barker == APP_CODE_BARKER) &&
(hdr_v1->dcd_table.preamble.barker == DCD_BARKER))
return IMXIMAGE_V1;
/* Try to detect V2 */
if ((fhdr_v2->header.tag == IVT_HEADER_TAG) &&
(hdr_v2->dcd_table.header.tag == DCD_HEADER_TAG))
return IMXIMAGE_V2;
return IMXIMAGE_VER_INVALID;
}
static void err_imximage_version(int version)
{
fprintf(stderr,
"Error: Unsupported imximage version:%d\n", version);
exit(EXIT_FAILURE);
}
static void set_dcd_val_v1(struct imx_header *imxhdr, char *name, int lineno,
int fld, uint32_t value, uint32_t off)
{
dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table;
switch (fld) {
case CFG_REG_SIZE:
/* Byte, halfword, word */
if ((value != 1) && (value != 2) && (value != 4)) {
fprintf(stderr, "Error: %s[%d] - "
"Invalid register size " "(%d)\n",
name, lineno, value);
exit(EXIT_FAILURE);
}
dcd_v1->addr_data[off].type = value;
break;
case CFG_REG_ADDRESS:
dcd_v1->addr_data[off].addr = value;
break;
case CFG_REG_VALUE:
dcd_v1->addr_data[off].value = value;
break;
default:
break;
}
}
static void set_dcd_val_v2(struct imx_header *imxhdr, char *name, int lineno,
int fld, uint32_t value, uint32_t off)
{
dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
switch (fld) {
case CFG_REG_ADDRESS:
dcd_v2->addr_data[off].addr = cpu_to_be32(value);
break;
case CFG_REG_VALUE:
dcd_v2->addr_data[off].value = cpu_to_be32(value);
break;
default:
break;
}
}
/*
* Complete setting up the rest field of DCD of V1
* such as barker code and DCD data length.
*/
static void set_dcd_rst_v1(struct imx_header *imxhdr, uint32_t dcd_len,
char *name, int lineno)
{
dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table;
if (dcd_len > MAX_HW_CFG_SIZE_V1) {
fprintf(stderr, "Error: %s[%d] -"
"DCD table exceeds maximum size(%d)\n",
name, lineno, MAX_HW_CFG_SIZE_V1);
exit(EXIT_FAILURE);
}
dcd_v1->preamble.barker = DCD_BARKER;
dcd_v1->preamble.length = dcd_len * sizeof(dcd_type_addr_data_t);
}
/*
* Complete setting up the reset field of DCD of V2
* such as DCD tag, version, length, etc.
*/
static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
char *name, int lineno)
{
dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
if (dcd_len > MAX_HW_CFG_SIZE_V2) {
fprintf(stderr, "Error: %s[%d] -"
"DCD table exceeds maximum size(%d)\n",
name, lineno, MAX_HW_CFG_SIZE_V2);
exit(EXIT_FAILURE);
}
dcd_v2->header.tag = DCD_HEADER_TAG;
dcd_v2->header.length = cpu_to_be16(
dcd_len * sizeof(dcd_addr_data_t) + 8);
dcd_v2->header.version = DCD_VERSION;
dcd_v2->write_dcd_command.tag = DCD_COMMAND_TAG;
dcd_v2->write_dcd_command.length = cpu_to_be16(
dcd_len * sizeof(dcd_addr_data_t) + 4);
dcd_v2->write_dcd_command.param = DCD_COMMAND_PARAM;
}
static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
struct stat *sbuf,
struct image_tool_params *params)
{
imx_header_v1_t *hdr_v1 = &imxhdr->header.hdr_v1;
flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr;
dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table;
uint32_t base_offset;
/* Exit if there is no BOOT_FROM field specifying the flash_offset */
if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
fprintf(stderr, "Error: Header v1: No BOOT_FROM tag in %s\n",
params->imagename);
exit(EXIT_FAILURE);
}
/* Set magic number */
fhdr_v1->app_code_barker = APP_CODE_BARKER;
fhdr_v1->app_dest_ptr = params->addr;
fhdr_v1->app_dest_ptr = params->ep - imxhdr->flash_offset -
sizeof(struct imx_header);
fhdr_v1->app_code_jump_vector = params->ep;
base_offset = fhdr_v1->app_dest_ptr + imxhdr->flash_offset ;
fhdr_v1->dcd_ptr_ptr =
(uint32_t) (offsetof(flash_header_v1_t, dcd_ptr) -
offsetof(flash_header_v1_t, app_code_jump_vector) +
base_offset);
fhdr_v1->dcd_ptr = base_offset +
offsetof(imx_header_v1_t, dcd_table);
/* The external flash header must be at the end of the DCD table */
dcd_v1->addr_data[dcd_len].type = sbuf->st_size +
imxhdr->flash_offset +
sizeof(struct imx_header);
/* Security feature are not supported */
fhdr_v1->app_code_csf = 0;
fhdr_v1->super_root_key = 0;
}
static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
struct stat *sbuf,
struct image_tool_params *params)
{
imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
/* Exit if there is no BOOT_FROM field specifying the flash_offset */
if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
fprintf(stderr, "Error: Header v2: No BOOT_FROM tag in %s\n",
params->imagename);
exit(EXIT_FAILURE);
}
/* Set magic number */
fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */
fhdr_v2->header.length = cpu_to_be16(sizeof(flash_header_v2_t));
fhdr_v2->header.version = IVT_VERSION; /* 0x40 */
fhdr_v2->entry = params->ep;
fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
fhdr_v2->self = params->ep - sizeof(struct imx_header);
fhdr_v2->dcd_ptr = fhdr_v2->self +
offsetof(imx_header_v2_t, dcd_table);
fhdr_v2->boot_data_ptr = fhdr_v2->self +
offsetof(imx_header_v2_t, boot_data);
hdr_v2->boot_data.start = fhdr_v2->self - imxhdr->flash_offset;
hdr_v2->boot_data.size = sbuf->st_size +
imxhdr->flash_offset +
sizeof(struct imx_header);
/* Security feature are not supported */
fhdr_v2->csf = 0;
}
static void set_hdr_func(struct imx_header *imxhdr)
{
switch (imximage_version) {
case IMXIMAGE_V1:
set_dcd_val = set_dcd_val_v1;
set_dcd_rst = set_dcd_rst_v1;
set_imx_hdr = set_imx_hdr_v1;
break;
case IMXIMAGE_V2:
set_dcd_val = set_dcd_val_v2;
set_dcd_rst = set_dcd_rst_v2;
set_imx_hdr = set_imx_hdr_v2;
break;
default:
err_imximage_version(imximage_version);
break;
}
}
static void print_hdr_v1(struct imx_header *imx_hdr)
{
imx_header_v1_t *hdr_v1 = &imx_hdr->header.hdr_v1;
flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr;
dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table;
uint32_t size, length, ver;
size = dcd_v1->preamble.length;
if (size > (MAX_HW_CFG_SIZE_V1 * sizeof(dcd_type_addr_data_t))) {
fprintf(stderr,
"Error: Image corrupt DCD size %d exceed maximum %d\n",
(uint32_t)(size / sizeof(dcd_type_addr_data_t)),
MAX_HW_CFG_SIZE_V1);
exit(EXIT_FAILURE);
}
length = dcd_v1->preamble.length / sizeof(dcd_type_addr_data_t);
ver = detect_imximage_version(imx_hdr);
printf("Image Type: Freescale IMX Boot Image\n");
printf("Image Ver: %x", ver);
printf("%s\n", get_table_entry_name(imximage_versions, NULL, ver));
printf("Data Size: ");
genimg_print_size(dcd_v1->addr_data[length].type);
printf("Load Address: %08x\n", (uint32_t)fhdr_v1->app_dest_ptr);
printf("Entry Point: %08x\n", (uint32_t)fhdr_v1->app_code_jump_vector);
}
static void print_hdr_v2(struct imx_header *imx_hdr)
{
imx_header_v2_t *hdr_v2 = &imx_hdr->header.hdr_v2;
flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
dcd_v2_t *dcd_v2 = &hdr_v2->dcd_table;
uint32_t size, version;
size = be16_to_cpu(dcd_v2->header.length) - 8;
if (size > (MAX_HW_CFG_SIZE_V2 * sizeof(dcd_addr_data_t))) {
fprintf(stderr,
"Error: Image corrupt DCD size %d exceed maximum %d\n",
(uint32_t)(size / sizeof(dcd_addr_data_t)),
MAX_HW_CFG_SIZE_V2);
exit(EXIT_FAILURE);
}
version = detect_imximage_version(imx_hdr);
printf("Image Type: Freescale IMX Boot Image\n");
printf("Image Ver: %x", version);
printf("%s\n", get_table_entry_name(imximage_versions, NULL, version));
printf("Data Size: ");
genimg_print_size(hdr_v2->boot_data.size);
printf("Load Address: %08x\n", (uint32_t)fhdr_v2->boot_data_ptr);
printf("Entry Point: %08x\n", (uint32_t)fhdr_v2->entry);
}
static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
char *name, int lineno, int fld, int dcd_len)
{
int value;
static int cmd_ver_first = ~0;
switch (cmd) {
case CMD_IMAGE_VERSION:
imximage_version = get_cfg_value(token, name, lineno);
if (cmd_ver_first == 0) {
fprintf(stderr, "Error: %s[%d] - IMAGE_VERSION "
"command need be the first before other "
"valid command in the file\n", name, lineno);
exit(EXIT_FAILURE);
}
cmd_ver_first = 1;
set_hdr_func(imxhdr);
break;
case CMD_BOOT_FROM:
imxhdr->flash_offset = get_table_entry_id(imximage_bootops,
"imximage boot option", token);
if (imxhdr->flash_offset == -1) {
fprintf(stderr, "Error: %s[%d] -Invalid boot device"
"(%s)\n", name, lineno, token);
exit(EXIT_FAILURE);
}
if (unlikely(cmd_ver_first != 1))
cmd_ver_first = 0;
break;
case CMD_DATA:
value = get_cfg_value(token, name, lineno);
(*set_dcd_val)(imxhdr, name, lineno, fld, value, dcd_len);
if (unlikely(cmd_ver_first != 1))
cmd_ver_first = 0;
break;
}
}
static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd,
char *token, char *name, int lineno, int fld, int *dcd_len)
{
int value;
switch (fld) {
case CFG_COMMAND:
*cmd = get_table_entry_id(imximage_cmds,
"imximage commands", token);
if (*cmd < 0) {
fprintf(stderr, "Error: %s[%d] - Invalid command"
"(%s)\n", name, lineno, token);
exit(EXIT_FAILURE);
}
break;
case CFG_REG_SIZE:
parse_cfg_cmd(imxhdr, *cmd, token, name, lineno, fld, *dcd_len);
break;
case CFG_REG_ADDRESS:
case CFG_REG_VALUE:
if (*cmd != CMD_DATA)
return;
value = get_cfg_value(token, name, lineno);
(*set_dcd_val)(imxhdr, name, lineno, fld, value, *dcd_len);
if (fld == CFG_REG_VALUE)
(*dcd_len)++;
break;
default:
break;
}
}
static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name)
{
FILE *fd = NULL;
char *line = NULL;
char *token, *saveptr1, *saveptr2;
int lineno = 0;
int fld;
size_t len;
int dcd_len = 0;
int32_t cmd;
fd = fopen(name, "r");
if (fd == 0) {
fprintf(stderr, "Error: %s - Can't open DCD file\n", name);
exit(EXIT_FAILURE);
}
/* Very simple parsing, line starting with # are comments
* and are dropped
*/
while ((getline(&line, &len, fd)) > 0) {
lineno++;
token = strtok_r(line, "\r\n", &saveptr1);
if (token == NULL)
continue;
/* Check inside the single line */
for (fld = CFG_COMMAND, cmd = CMD_INVALID,
line = token; ; line = NULL, fld++) {
token = strtok_r(line, " \t", &saveptr2);
if (token == NULL)
break;
/* Drop all text starting with '#' as comments */
if (token[0] == '#')
break;
parse_cfg_fld(imxhdr, &cmd, token, name,
lineno, fld, &dcd_len);
}
}
(*set_dcd_rst)(imxhdr, dcd_len, name, lineno);
fclose(fd);
return dcd_len;
}
static int imximage_check_image_types(uint8_t type)
{
if (type == IH_TYPE_IMXIMAGE)
return EXIT_SUCCESS;
else
return EXIT_FAILURE;
}
static int imximage_verify_header(unsigned char *ptr, int image_size,
struct image_tool_params *params)
{
struct imx_header *imx_hdr = (struct imx_header *) ptr;
if (detect_imximage_version(imx_hdr) == IMXIMAGE_VER_INVALID)
return -FDT_ERR_BADSTRUCTURE;
return 0;
}
static void imximage_print_header(const void *ptr)
{
struct imx_header *imx_hdr = (struct imx_header *) ptr;
uint32_t version = detect_imximage_version(imx_hdr);
switch (version) {
case IMXIMAGE_V1:
print_hdr_v1(imx_hdr);
break;
case IMXIMAGE_V2:
print_hdr_v2(imx_hdr);
break;
default:
err_imximage_version(version);
break;
}
}
static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
struct image_tool_params *params)
{
struct imx_header *imxhdr = (struct imx_header *)ptr;
uint32_t dcd_len;
/*
* In order to not change the old imx cfg file
* by adding VERSION command into it, here need
* set up function ptr group to V1 by default.
*/
imximage_version = IMXIMAGE_V1;
/* Be able to detect if the cfg file has no BOOT_FROM tag */
imxhdr->flash_offset = FLASH_OFFSET_UNDEFINED;
set_hdr_func(imxhdr);
/* Parse dcd configuration file */
dcd_len = parse_cfg_file(imxhdr, params->imagename);
/* Set the imx header */
(*set_imx_hdr)(imxhdr, dcd_len, sbuf, params);
}
int imximage_check_params(struct image_tool_params *params)
{
if (!params)
return CFG_INVALID;
if (!strlen(params->imagename)) {
fprintf(stderr, "Error: %s - Configuration file not specified, "
"it is needed for imximage generation\n",
params->cmdname);
return CFG_INVALID;
}
/*
* Check parameters:
* XIP is not allowed and verify that incompatible
* parameters are not sent at the same time
* For example, if list is required a data image must not be provided
*/
return (params->dflag && (params->fflag || params->lflag)) ||
(params->fflag && (params->dflag || params->lflag)) ||
(params->lflag && (params->dflag || params->fflag)) ||
(params->xflag) || !(strlen(params->imagename));
}
/*
* imximage parameters
*/
static struct image_type_params imximage_params = {
.name = "Freescale i.MX 5x Boot Image support",
.header_size = sizeof(struct imx_header),
.hdr = (void *)&imximage_header,
.check_image_type = imximage_check_image_types,
.verify_header = imximage_verify_header,
.print_header = imximage_print_header,
.set_header = imximage_set_header,
.check_params = imximage_check_params,
};
void init_imx_image_type(void)
{
register_image_type(&imximage_params);
}

View file

@ -0,0 +1,176 @@
/*
* (C) Copyright 2009
* Stefano Babic, DENX Software Engineering, sbabic@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 _IMXIMAGE_H_
#define _IMXIMAGE_H_
#define MAX_HW_CFG_SIZE_V2 121 /* Max number of registers imx can set for v2 */
#define MAX_HW_CFG_SIZE_V1 60 /* Max number of registers imx can set for v1 */
#define APP_CODE_BARKER 0xB1
#define DCD_BARKER 0xB17219E9
#define HEADER_OFFSET 0x400
#define CMD_DATA_STR "DATA"
#define FLASH_OFFSET_UNDEFINED 0xFFFFFFFF
#define FLASH_OFFSET_STANDARD 0x400
#define FLASH_OFFSET_NAND FLASH_OFFSET_STANDARD
#define FLASH_OFFSET_SD FLASH_OFFSET_STANDARD
#define FLASH_OFFSET_SPI FLASH_OFFSET_STANDARD
#define FLASH_OFFSET_ONENAND 0x100
#define FLASH_OFFSET_NOR 0x1000
#define FLASH_OFFSET_SATA FLASH_OFFSET_STANDARD
#define IVT_HEADER_TAG 0xD1
#define IVT_VERSION 0x40
#define DCD_HEADER_TAG 0xD2
#define DCD_COMMAND_TAG 0xCC
#define DCD_VERSION 0x40
#define DCD_COMMAND_PARAM 0x4
enum imximage_cmd {
CMD_INVALID,
CMD_IMAGE_VERSION,
CMD_BOOT_FROM,
CMD_DATA
};
enum imximage_fld_types {
CFG_INVALID = -1,
CFG_COMMAND,
CFG_REG_SIZE,
CFG_REG_ADDRESS,
CFG_REG_VALUE
};
enum imximage_version {
IMXIMAGE_VER_INVALID = -1,
IMXIMAGE_V1 = 1,
IMXIMAGE_V2
};
typedef struct {
uint32_t type; /* Type of pointer (byte, halfword, word, wait/read) */
uint32_t addr; /* Address to write to */
uint32_t value; /* Data to write */
} dcd_type_addr_data_t;
typedef struct {
uint32_t barker; /* Barker for sanity check */
uint32_t length; /* Device configuration length (without preamble) */
} dcd_preamble_t;
typedef struct {
dcd_preamble_t preamble;
dcd_type_addr_data_t addr_data[MAX_HW_CFG_SIZE_V1];
} dcd_v1_t;
typedef struct {
uint32_t app_code_jump_vector;
uint32_t app_code_barker;
uint32_t app_code_csf;
uint32_t dcd_ptr_ptr;
uint32_t super_root_key;
uint32_t dcd_ptr;
uint32_t app_dest_ptr;
} flash_header_v1_t;
typedef struct {
uint32_t length; /* Length of data to be read from flash */
} flash_cfg_parms_t;
typedef struct {
flash_header_v1_t fhdr;
dcd_v1_t dcd_table;
flash_cfg_parms_t ext_header;
} imx_header_v1_t;
typedef struct {
uint32_t addr;
uint32_t value;
} dcd_addr_data_t;
typedef struct {
uint8_t tag;
uint16_t length;
uint8_t version;
} __attribute__((packed)) ivt_header_t;
typedef struct {
uint8_t tag;
uint16_t length;
uint8_t param;
} __attribute__((packed)) write_dcd_command_t;
typedef struct {
ivt_header_t header;
write_dcd_command_t write_dcd_command;
dcd_addr_data_t addr_data[MAX_HW_CFG_SIZE_V2];
} dcd_v2_t;
typedef struct {
uint32_t start;
uint32_t size;
uint32_t plugin;
} boot_data_t;
typedef struct {
ivt_header_t header;
uint32_t entry;
uint32_t reserved1;
uint32_t dcd_ptr;
uint32_t boot_data_ptr;
uint32_t self;
uint32_t csf;
uint32_t reserved2;
} flash_header_v2_t;
typedef struct {
flash_header_v2_t fhdr;
boot_data_t boot_data;
dcd_v2_t dcd_table;
} imx_header_v2_t;
struct imx_header {
union {
imx_header_v1_t hdr_v1;
imx_header_v2_t hdr_v2;
} header;
uint32_t flash_offset;
};
typedef void (*set_dcd_val_t)(struct imx_header *imxhdr,
char *name, int lineno,
int fld, uint32_t value,
uint32_t off);
typedef void (*set_dcd_rst_t)(struct imx_header *imxhdr,
uint32_t dcd_len,
char *name, int lineno);
typedef void (*set_imx_hdr_t)(struct imx_header *imxhdr,
uint32_t dcd_len,
struct stat *sbuf,
struct mkimage_params *params);
#endif /* _IMXIMAGE_H_ */

View file

@ -0,0 +1,39 @@
#!/bin/sh
usage() {
(
echo "Usage: $0 [board IP] [board port]"
echo ""
echo "If IP is not specified, 'localhost' will be used"
echo "If port is not specified, '2001' will be used"
[ -z "$*" ] && exit 0
echo ""
echo "ERROR: $*"
exit 1
) 1>&2
exit $?
}
while [ -n "$1" ] ; do
case $1 in
-h|--help) usage;;
--) break;;
-*) usage "Invalid option $1";;
*) break;;
esac
shift
done
ip=${1:-localhost}
port=${2:-2001}
if [ -z "${ip}" ] || [ -n "$3" ] ; then
usage "Invalid number of arguments"
fi
trap "stty icanon echo opost intr ^C" 0 2 3 5 10 13 15
echo "NOTE: the interrupt signal (normally ^C) has been remapped to ^T"
stty -icanon -echo -opost intr ^T
nc ${ip} ${port}
exit 0

View file

@ -0,0 +1,405 @@
/*
* (C) Copyright 2008
* Marvell Semiconductor <www.marvell.com>
* Written-by: Prafulla Wadaskar <prafulla@marvell.com>
*
* 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
*/
/* Required to obtain the getline prototype from stdio.h */
#define _GNU_SOURCE
#include "imagetool.h"
#include <image.h>
#include "kwbimage.h"
/*
* Supported commands for configuration file
*/
static table_entry_t kwbimage_cmds[] = {
{CMD_BOOT_FROM, "BOOT_FROM", "boot command", },
{CMD_NAND_ECC_MODE, "NAND_ECC_MODE", "NAND mode", },
{CMD_NAND_PAGE_SIZE, "NAND_PAGE_SIZE", "NAND size", },
{CMD_SATA_PIO_MODE, "SATA_PIO_MODE", "SATA mode", },
{CMD_DDR_INIT_DELAY, "DDR_INIT_DELAY", "DDR init dly", },
{CMD_DATA, "DATA", "Reg Write Data", },
{CMD_INVALID, "", "", },
};
/*
* Supported Boot options for configuration file
*/
static table_entry_t kwbimage_bootops[] = {
{IBR_HDR_SPI_ID, "spi", "SPI Flash", },
{IBR_HDR_NAND_ID, "nand", "NAND Flash", },
{IBR_HDR_SATA_ID, "sata", "Sata port", },
{IBR_HDR_PEX_ID, "pex", "PCIe port", },
{IBR_HDR_UART_ID, "uart", "Serial port", },
{-1, "", "Invalid", },
};
/*
* Supported NAND ecc options configuration file
*/
static table_entry_t kwbimage_eccmodes[] = {
{IBR_HDR_ECC_DEFAULT, "default", "Default mode", },
{IBR_HDR_ECC_FORCED_HAMMING, "hamming", "Hamming mode", },
{IBR_HDR_ECC_FORCED_RS, "rs", "RS mode", },
{IBR_HDR_ECC_DISABLED, "disabled", "ECC Disabled", },
{-1, "", "", },
};
static struct kwb_header kwbimage_header;
static int datacmd_cnt = 0;
static char * fname = "Unknown";
static int lineno = -1;
/*
* Report Error if xflag is set in addition to default
*/
static int kwbimage_check_params (struct image_tool_params *params)
{
if (!strlen (params->imagename)) {
printf ("Error:%s - Configuration file not specified, "
"it is needed for kwbimage generation\n",
params->cmdname);
return CFG_INVALID;
}
return ((params->dflag && (params->fflag || params->lflag)) ||
(params->fflag && (params->dflag || params->lflag)) ||
(params->lflag && (params->dflag || params->fflag)) ||
(params->xflag) || !(strlen (params->imagename)));
}
static uint32_t check_get_hexval (char *token)
{
uint32_t hexval;
if (!sscanf (token, "%x", &hexval)) {
printf ("Error:%s[%d] - Invalid hex data(%s)\n", fname,
lineno, token);
exit (EXIT_FAILURE);
}
return hexval;
}
/*
* Generates 8 bit checksum
*/
static uint8_t kwbimage_checksum8 (void *start, uint32_t len, uint8_t csum)
{
register uint8_t sum = csum;
volatile uint8_t *p = (volatile uint8_t *)start;
/* check len and return zero checksum if invalid */
if (!len)
return 0;
do {
sum += *p;
p++;
} while (--len);
return (sum);
}
/*
* Generates 32 bit checksum
*/
static uint32_t kwbimage_checksum32 (uint32_t *start, uint32_t len, uint32_t csum)
{
register uint32_t sum = csum;
volatile uint32_t *p = start;
/* check len and return zero checksum if invalid */
if (!len)
return 0;
if (len % sizeof(uint32_t)) {
printf ("Error:%s[%d] - length is not in multiple of %zu\n",
__FUNCTION__, len, sizeof(uint32_t));
return 0;
}
do {
sum += *p;
p++;
len -= sizeof(uint32_t);
} while (len > 0);
return (sum);
}
static void kwbimage_check_cfgdata (char *token, enum kwbimage_cmd cmdsw,
struct kwb_header *kwbhdr)
{
bhr_t *mhdr = &kwbhdr->kwb_hdr;
extbhr_t *exthdr = &kwbhdr->kwb_exthdr;
int i;
switch (cmdsw) {
case CMD_BOOT_FROM:
i = get_table_entry_id (kwbimage_bootops,
"Kwbimage boot option", token);
if (i < 0)
goto INVL_DATA;
mhdr->blockid = i;
printf ("Preparing kirkwood boot image to boot "
"from %s\n", token);
break;
case CMD_NAND_ECC_MODE:
i = get_table_entry_id (kwbimage_eccmodes,
"NAND ecc mode", token);
if (i < 0)
goto INVL_DATA;
mhdr->nandeccmode = i;
printf ("Nand ECC mode = %s\n", token);
break;
case CMD_NAND_PAGE_SIZE:
mhdr->nandpagesize =
(uint16_t) check_get_hexval (token);
printf ("Nand page size = 0x%x\n", mhdr->nandpagesize);
break;
case CMD_SATA_PIO_MODE:
mhdr->satapiomode =
(uint8_t) check_get_hexval (token);
printf ("Sata PIO mode = 0x%x\n",
mhdr->satapiomode);
break;
case CMD_DDR_INIT_DELAY:
mhdr->ddrinitdelay =
(uint16_t) check_get_hexval (token);
printf ("DDR init delay = %d msec\n", mhdr->ddrinitdelay);
break;
case CMD_DATA:
exthdr->rcfg[datacmd_cnt].raddr =
check_get_hexval (token);
break;
case CMD_INVALID:
goto INVL_DATA;
default:
goto INVL_DATA;
}
return;
INVL_DATA:
printf ("Error:%s[%d] - Invalid data\n", fname, lineno);
exit (EXIT_FAILURE);
}
/*
* this function sets the kwbimage header by-
* 1. Abstracting input command line arguments data
* 2. parses the kwbimage configuration file and update extebded header data
* 3. calculates header, extended header and image checksums
*/
static void kwdimage_set_ext_header (struct kwb_header *kwbhdr, char* name) {
bhr_t *mhdr = &kwbhdr->kwb_hdr;
extbhr_t *exthdr = &kwbhdr->kwb_exthdr;
FILE *fd = NULL;
int j;
char *line = NULL;
char * token, *saveptr1, *saveptr2;
size_t len = 0;
enum kwbimage_cmd cmd;
fname = name;
/* set dram register offset */
exthdr->dramregsoffs = (intptr_t)&exthdr->rcfg - (intptr_t)mhdr;
if ((fd = fopen (name, "r")) == 0) {
printf ("Error:%s - Can't open\n", fname);
exit (EXIT_FAILURE);
}
/* Simple kwimage.cfg file parser */
lineno=0;
while ((getline (&line, &len, fd)) > 0) {
lineno++;
token = strtok_r (line, "\r\n", &saveptr1);
/* drop all lines with zero tokens (= empty lines) */
if (token == NULL)
continue;
for (j = 0, cmd = CMD_INVALID, line = token; ; line = NULL) {
token = strtok_r (line, " \t", &saveptr2);
if (token == NULL)
break;
/* Drop all text starting with '#' as comments */
if (token[0] == '#')
break;
/* Process rest as valid config command line */
switch (j) {
case CFG_COMMAND:
cmd = get_table_entry_id (kwbimage_cmds,
"Kwbimage command", token);
if (cmd == CMD_INVALID)
goto INVL_CMD;
break;
case CFG_DATA0:
kwbimage_check_cfgdata (token, cmd, kwbhdr);
break;
case CFG_DATA1:
if (cmd != CMD_DATA)
goto INVL_CMD;
exthdr->rcfg[datacmd_cnt].rdata =
check_get_hexval (token);
if (datacmd_cnt > KWBIMAGE_MAX_CONFIG ) {
printf ("Error:%s[%d] - Found more "
"than max(%zd) allowed "
"data configurations\n",
fname, lineno,
KWBIMAGE_MAX_CONFIG);
exit (EXIT_FAILURE);
} else
datacmd_cnt++;
break;
default:
goto INVL_CMD;
}
j++;
}
}
if (line)
free (line);
fclose (fd);
return;
/*
* Invalid Command error reporring
*
* command CMD_DATA needs three strings on a line
* whereas other commands need only two.
*
* if more than two/three (as per command type) are observed,
* then error will be reported
*/
INVL_CMD:
printf ("Error:%s[%d] - Invalid command\n", fname, lineno);
exit (EXIT_FAILURE);
}
static void kwbimage_set_header (void *ptr, struct stat *sbuf, int ifd,
struct image_tool_params *params)
{
struct kwb_header *hdr = (struct kwb_header *)ptr;
bhr_t *mhdr = &hdr->kwb_hdr;
extbhr_t *exthdr = &hdr->kwb_exthdr;
uint32_t checksum;
int size;
/* Build and add image checksum header */
checksum = kwbimage_checksum32 ((uint32_t *)ptr, sbuf->st_size, 0);
size = write (ifd, &checksum, sizeof(uint32_t));
if (size != sizeof(uint32_t)) {
printf ("Error:%s - Checksum write %d bytes %s\n",
params->cmdname, size, params->imagefile);
exit (EXIT_FAILURE);
}
sbuf->st_size += sizeof(uint32_t);
mhdr->blocksize = sbuf->st_size - sizeof(struct kwb_header);
mhdr->srcaddr = sizeof(struct kwb_header);
mhdr->destaddr= params->addr;
mhdr->execaddr =params->ep;
mhdr->ext = 0x1; /* header extension appended */
kwdimage_set_ext_header (hdr, params->imagename);
/* calculate checksums */
mhdr->checkSum = kwbimage_checksum8 ((void *)mhdr, sizeof(bhr_t), 0);
exthdr->checkSum = kwbimage_checksum8 ((void *)exthdr,
sizeof(extbhr_t), 0);
}
static int kwbimage_verify_header (unsigned char *ptr, int image_size,
struct image_tool_params *params)
{
struct kwb_header *hdr = (struct kwb_header *)ptr;
bhr_t *mhdr = &hdr->kwb_hdr;
extbhr_t *exthdr = &hdr->kwb_exthdr;
uint8_t calc_hdrcsum;
uint8_t calc_exthdrcsum;
calc_hdrcsum = kwbimage_checksum8 ((void *)mhdr,
sizeof(bhr_t) - sizeof(uint8_t), 0);
if (calc_hdrcsum != mhdr->checkSum)
return -FDT_ERR_BADSTRUCTURE; /* mhdr csum not matched */
calc_exthdrcsum = kwbimage_checksum8 ((void *)exthdr,
sizeof(extbhr_t) - sizeof(uint8_t), 0);
if (calc_exthdrcsum != exthdr->checkSum)
return -FDT_ERR_BADSTRUCTURE; /* exthdr csum not matched */
return 0;
}
static void kwbimage_print_header (const void *ptr)
{
struct kwb_header *hdr = (struct kwb_header *) ptr;
bhr_t *mhdr = &hdr->kwb_hdr;
char *name = get_table_entry_name (kwbimage_bootops,
"Kwbimage boot option",
(int) mhdr->blockid);
printf ("Image Type: Kirkwood Boot from %s Image\n", name);
printf ("Data Size: ");
genimg_print_size (mhdr->blocksize - sizeof(uint32_t));
printf ("Load Address: %08x\n", mhdr->destaddr);
printf ("Entry Point: %08x\n", mhdr->execaddr);
}
static int kwbimage_check_image_types (uint8_t type)
{
if (type == IH_TYPE_KWBIMAGE)
return EXIT_SUCCESS;
else
return EXIT_FAILURE;
}
/*
* kwbimage type parameters definition
*/
static struct image_type_params kwbimage_params = {
.name = "Kirkwood Boot Image support",
.header_size = sizeof(struct kwb_header),
.hdr = (void*)&kwbimage_header,
.check_image_type = kwbimage_check_image_types,
.verify_header = kwbimage_verify_header,
.print_header = kwbimage_print_header,
.set_header = kwbimage_set_header,
.check_params = kwbimage_check_params,
};
void init_kwb_image_type (void)
{
register_image_type (&kwbimage_params);
}

View file

@ -0,0 +1,106 @@
/*
* (C) Copyright 2008
* Marvell Semiconductor <www.marvell.com>
* Written-by: Prafulla Wadaskar <prafulla@marvell.com>
*
* 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 _KWBIMAGE_H_
#define _KWBIMAGE_H_
#include <stdint.h>
#define KWBIMAGE_MAX_CONFIG ((0x1dc - 0x20)/sizeof(struct reg_config))
#define MAX_TEMPBUF_LEN 32
/* NAND ECC Mode */
#define IBR_HDR_ECC_DEFAULT 0x00
#define IBR_HDR_ECC_FORCED_HAMMING 0x01
#define IBR_HDR_ECC_FORCED_RS 0x02
#define IBR_HDR_ECC_DISABLED 0x03
/* Boot Type - block ID */
#define IBR_HDR_I2C_ID 0x4D
#define IBR_HDR_SPI_ID 0x5A
#define IBR_HDR_NAND_ID 0x8B
#define IBR_HDR_SATA_ID 0x78
#define IBR_HDR_PEX_ID 0x9C
#define IBR_HDR_UART_ID 0x69
#define IBR_DEF_ATTRIB 0x00
enum kwbimage_cmd {
CMD_INVALID,
CMD_BOOT_FROM,
CMD_NAND_ECC_MODE,
CMD_NAND_PAGE_SIZE,
CMD_SATA_PIO_MODE,
CMD_DDR_INIT_DELAY,
CMD_DATA
};
enum kwbimage_cmd_types {
CFG_INVALID = -1,
CFG_COMMAND,
CFG_DATA0,
CFG_DATA1
};
/* typedefs */
typedef struct bhr_t {
uint8_t blockid; /*0 */
uint8_t nandeccmode; /*1 */
uint16_t nandpagesize; /*2-3 */
uint32_t blocksize; /*4-7 */
uint32_t rsvd1; /*8-11 */
uint32_t srcaddr; /*12-15 */
uint32_t destaddr; /*16-19 */
uint32_t execaddr; /*20-23 */
uint8_t satapiomode; /*24 */
uint8_t rsvd3; /*25 */
uint16_t ddrinitdelay; /*26-27 */
uint16_t rsvd2; /*28-29 */
uint8_t ext; /*30 */
uint8_t checkSum; /*31 */
} bhr_t, *pbhr_t;
struct reg_config {
uint32_t raddr;
uint32_t rdata;
};
typedef struct extbhr_t {
uint32_t dramregsoffs;
uint8_t rsrvd1[0x20 - sizeof(uint32_t)];
struct reg_config rcfg[KWBIMAGE_MAX_CONFIG];
uint8_t rsrvd2[7];
uint8_t checkSum;
} extbhr_t, *pextbhr_t;
struct kwb_header {
bhr_t kwb_hdr;
extbhr_t kwb_exthdr;
};
/*
* functions
*/
void init_kwb_image_type (void);
#endif /* _KWBIMAGE_H_ */

View file

@ -0,0 +1,742 @@
/*
* Boot a Marvell Kirkwood SoC, with Xmodem over UART0.
*
* (c) 2012 Daniel Stodden <daniel.stodden@gmail.com>
*
* References: marvell.com, "88F6180, 88F6190, 88F6192, and 88F6281
* Integrated Controller: Functional Specifications" December 2,
* 2008. Chapter 24.2 "BootROM Firmware".
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <libgen.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdint.h>
#include <termios.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include "kwbimage.h"
#ifdef __GNUC__
#define PACKED __attribute((packed))
#else
#define PACKED
#endif
/*
* Marvell BootROM UART Sensing
*/
static unsigned char kwboot_msg_boot[] = {
0xBB, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
};
#define KWBOOT_MSG_REQ_DELAY 10 /* ms */
#define KWBOOT_MSG_RSP_TIMEO 50 /* ms */
/*
* Xmodem Transfers
*/
#define SOH 1 /* sender start of block header */
#define EOT 4 /* sender end of block transfer */
#define ACK 6 /* target block ack */
#define NAK 21 /* target block negative ack */
#define CAN 24 /* target/sender transfer cancellation */
struct kwboot_block {
uint8_t soh;
uint8_t pnum;
uint8_t _pnum;
uint8_t data[128];
uint8_t csum;
} PACKED;
#define KWBOOT_BLK_RSP_TIMEO 1000 /* ms */
static int kwboot_verbose;
static void
kwboot_printv(const char *fmt, ...)
{
va_list ap;
if (kwboot_verbose) {
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
fflush(stdout);
}
}
static void
__spinner(void)
{
const char seq[] = { '-', '\\', '|', '/' };
const int div = 8;
static int state, bs;
if (state % div == 0) {
fputc(bs, stdout);
fputc(seq[state / div % sizeof(seq)], stdout);
fflush(stdout);
}
bs = '\b';
state++;
}
static void
kwboot_spinner(void)
{
if (kwboot_verbose)
__spinner();
}
static void
__progress(int pct, char c)
{
const int width = 70;
static const char *nl = "";
static int pos;
if (pos % width == 0)
printf("%s%3d %% [", nl, pct);
fputc(c, stdout);
nl = "]\n";
pos++;
if (pct == 100) {
while (pos++ < width)
fputc(' ', stdout);
fputs(nl, stdout);
}
fflush(stdout);
}
static void
kwboot_progress(int _pct, char c)
{
static int pct;
if (_pct != -1)
pct = _pct;
if (kwboot_verbose)
__progress(pct, c);
}
static int
kwboot_tty_recv(int fd, void *buf, size_t len, int timeo)
{
int rc, nfds;
fd_set rfds;
struct timeval tv;
ssize_t n;
rc = -1;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
tv.tv_sec = 0;
tv.tv_usec = timeo * 1000;
if (tv.tv_usec > 1000000) {
tv.tv_sec += tv.tv_usec / 1000000;
tv.tv_usec %= 1000000;
}
do {
nfds = select(fd + 1, &rfds, NULL, NULL, &tv);
if (nfds < 0)
goto out;
if (!nfds) {
errno = ETIMEDOUT;
goto out;
}
n = read(fd, buf, len);
if (n < 0)
goto out;
buf = (char *)buf + n;
len -= n;
} while (len > 0);
rc = 0;
out:
return rc;
}
static int
kwboot_tty_send(int fd, const void *buf, size_t len)
{
int rc;
ssize_t n;
rc = -1;
do {
n = write(fd, buf, len);
if (n < 0)
goto out;
buf = (char *)buf + n;
len -= n;
} while (len > 0);
rc = tcdrain(fd);
out:
return rc;
}
static int
kwboot_tty_send_char(int fd, unsigned char c)
{
return kwboot_tty_send(fd, &c, 1);
}
static speed_t
kwboot_tty_speed(int baudrate)
{
switch (baudrate) {
case 115200:
return B115200;
case 57600:
return B57600;
case 38400:
return B38400;
case 19200:
return B19200;
case 9600:
return B9600;
}
return -1;
}
static int
kwboot_open_tty(const char *path, speed_t speed)
{
int rc, fd;
struct termios tio;
rc = -1;
fd = open(path, O_RDWR|O_NOCTTY|O_NDELAY);
if (fd < 0)
goto out;
memset(&tio, 0, sizeof(tio));
tio.c_iflag = 0;
tio.c_cflag = CREAD|CLOCAL|CS8;
tio.c_cc[VMIN] = 1;
tio.c_cc[VTIME] = 10;
cfsetospeed(&tio, speed);
cfsetispeed(&tio, speed);
rc = tcsetattr(fd, TCSANOW, &tio);
if (rc)
goto out;
rc = fd;
out:
if (rc < 0) {
if (fd >= 0)
close(fd);
}
return rc;
}
static int
kwboot_bootmsg(int tty, void *msg)
{
int rc;
char c;
kwboot_printv("Sending boot message. Please reboot the target...");
do {
rc = tcflush(tty, TCIOFLUSH);
if (rc)
break;
rc = kwboot_tty_send(tty, msg, 8);
if (rc) {
usleep(KWBOOT_MSG_REQ_DELAY * 1000);
continue;
}
rc = kwboot_tty_recv(tty, &c, 1, KWBOOT_MSG_RSP_TIMEO);
kwboot_spinner();
} while (rc || c != NAK);
kwboot_printv("\n");
return rc;
}
static int
kwboot_xm_makeblock(struct kwboot_block *block, const void *data,
size_t size, int pnum)
{
const size_t blksz = sizeof(block->data);
size_t n;
int i;
block->pnum = pnum;
block->_pnum = ~block->pnum;
n = size < blksz ? size : blksz;
memcpy(&block->data[0], data, n);
memset(&block->data[n], 0, blksz - n);
block->csum = 0;
for (i = 0; i < n; i++)
block->csum += block->data[i];
return n;
}
static int
kwboot_xm_sendblock(int fd, struct kwboot_block *block)
{
int rc, retries;
char c;
retries = 16;
do {
rc = kwboot_tty_send(fd, block, sizeof(*block));
if (rc)
break;
rc = kwboot_tty_recv(fd, &c, 1, KWBOOT_BLK_RSP_TIMEO);
if (rc)
break;
if (c != ACK)
kwboot_progress(-1, '+');
} while (c == NAK && retries-- > 0);
rc = -1;
switch (c) {
case ACK:
rc = 0;
break;
case NAK:
errno = EBADMSG;
break;
case CAN:
errno = ECANCELED;
break;
default:
errno = EPROTO;
break;
}
return rc;
}
static int
kwboot_xmodem(int tty, const void *_data, size_t size)
{
const uint8_t *data = _data;
int rc, pnum, N, err;
pnum = 1;
N = 0;
kwboot_printv("Sending boot image...\n");
do {
struct kwboot_block block;
int n;
n = kwboot_xm_makeblock(&block,
data + N, size - N,
pnum++);
if (n < 0)
goto can;
if (!n)
break;
rc = kwboot_xm_sendblock(tty, &block);
if (rc)
goto out;
N += n;
kwboot_progress(N * 100 / size, '.');
} while (1);
rc = kwboot_tty_send_char(tty, EOT);
out:
return rc;
can:
err = errno;
kwboot_tty_send_char(tty, CAN);
errno = err;
goto out;
}
static int
kwboot_term_pipe(int in, int out, char *quit, int *s)
{
ssize_t nin, nout;
char _buf[128], *buf = _buf;
nin = read(in, buf, sizeof(buf));
if (nin < 0)
return -1;
if (quit) {
int i;
for (i = 0; i < nin; i++) {
if (*buf == quit[*s]) {
(*s)++;
if (!quit[*s])
return 0;
buf++;
nin--;
} else
while (*s > 0) {
nout = write(out, quit, *s);
if (nout <= 0)
return -1;
(*s) -= nout;
}
}
}
while (nin > 0) {
nout = write(out, buf, nin);
if (nout <= 0)
return -1;
nin -= nout;
}
return 0;
}
static int
kwboot_terminal(int tty)
{
int rc, in, s;
char *quit = "\34c";
struct termios otio, tio;
rc = -1;
in = STDIN_FILENO;
if (isatty(in)) {
rc = tcgetattr(in, &otio);
if (!rc) {
tio = otio;
cfmakeraw(&tio);
rc = tcsetattr(in, TCSANOW, &tio);
}
if (rc) {
perror("tcsetattr");
goto out;
}
kwboot_printv("[Type Ctrl-%c + %c to quit]\r\n",
quit[0]|0100, quit[1]);
} else
in = -1;
rc = 0;
s = 0;
do {
fd_set rfds;
int nfds = 0;
FD_SET(tty, &rfds);
nfds = nfds < tty ? tty : nfds;
if (in >= 0) {
FD_SET(in, &rfds);
nfds = nfds < in ? in : nfds;
}
nfds = select(nfds + 1, &rfds, NULL, NULL, NULL);
if (nfds < 0)
break;
if (FD_ISSET(tty, &rfds)) {
rc = kwboot_term_pipe(tty, STDOUT_FILENO, NULL, NULL);
if (rc)
break;
}
if (FD_ISSET(in, &rfds)) {
rc = kwboot_term_pipe(in, tty, quit, &s);
if (rc)
break;
}
} while (quit[s] != 0);
tcsetattr(in, TCSANOW, &otio);
out:
return rc;
}
static void *
kwboot_mmap_image(const char *path, size_t *size, int prot)
{
int rc, fd, flags;
struct stat st;
void *img;
rc = -1;
fd = -1;
img = NULL;
fd = open(path, O_RDONLY);
if (fd < 0)
goto out;
rc = fstat(fd, &st);
if (rc)
goto out;
flags = (prot & PROT_WRITE) ? MAP_PRIVATE : MAP_SHARED;
img = mmap(NULL, st.st_size, prot, flags, fd, 0);
if (img == MAP_FAILED) {
img = NULL;
goto out;
}
rc = 0;
*size = st.st_size;
out:
if (rc && img) {
munmap(img, st.st_size);
img = NULL;
}
if (fd >= 0)
close(fd);
return img;
}
static uint8_t
kwboot_img_csum8(void *_data, size_t size)
{
uint8_t *data = _data, csum;
for (csum = 0; size-- > 0; data++)
csum += *data;
return csum;
}
static int
kwboot_img_patch_hdr(void *img, size_t size)
{
int rc;
bhr_t *hdr;
uint8_t csum;
const size_t hdrsz = sizeof(*hdr);
rc = -1;
hdr = img;
if (size < hdrsz) {
errno = EINVAL;
goto out;
}
csum = kwboot_img_csum8(hdr, hdrsz) - hdr->checkSum;
if (csum != hdr->checkSum) {
errno = EINVAL;
goto out;
}
if (hdr->blockid == IBR_HDR_UART_ID) {
rc = 0;
goto out;
}
hdr->blockid = IBR_HDR_UART_ID;
hdr->nandeccmode = IBR_HDR_ECC_DISABLED;
hdr->nandpagesize = 0;
hdr->srcaddr = hdr->ext
? sizeof(struct kwb_header)
: sizeof(*hdr);
hdr->checkSum = kwboot_img_csum8(hdr, hdrsz) - csum;
rc = 0;
out:
return rc;
}
static void
kwboot_usage(FILE *stream, char *progname)
{
fprintf(stream,
"Usage: %s -b <image> [ -p ] [ -t ] "
"[-B <baud> ] <TTY>\n", progname);
fprintf(stream, "\n");
fprintf(stream, " -b <image>: boot <image>\n");
fprintf(stream, " -p: patch <image> to type 0x69 (uart boot)\n");
fprintf(stream, "\n");
fprintf(stream, " -t: mini terminal\n");
fprintf(stream, "\n");
fprintf(stream, " -B <baud>: set baud rate\n");
fprintf(stream, "\n");
}
int
main(int argc, char **argv)
{
const char *ttypath, *imgpath;
int rv, rc, tty, term, prot, patch;
void *bootmsg;
void *img;
size_t size;
speed_t speed;
rv = 1;
tty = -1;
bootmsg = NULL;
imgpath = NULL;
img = NULL;
term = 0;
patch = 0;
size = 0;
speed = B115200;
kwboot_verbose = isatty(STDOUT_FILENO);
do {
int c = getopt(argc, argv, "hb:ptB:");
if (c < 0)
break;
switch (c) {
case 'b':
bootmsg = kwboot_msg_boot;
imgpath = optarg;
break;
case 'p':
patch = 1;
break;
case 't':
term = 1;
break;
case 'B':
speed = kwboot_tty_speed(atoi(optarg));
if (speed == -1)
goto usage;
break;
case 'h':
rv = 0;
default:
goto usage;
}
} while (1);
if (!bootmsg && !term)
goto usage;
if (patch && !imgpath)
goto usage;
if (argc - optind < 1)
goto usage;
ttypath = argv[optind++];
tty = kwboot_open_tty(ttypath, speed);
if (tty < 0) {
perror(ttypath);
goto out;
}
if (imgpath) {
prot = PROT_READ | (patch ? PROT_WRITE : 0);
img = kwboot_mmap_image(imgpath, &size, prot);
if (!img) {
perror(imgpath);
goto out;
}
}
if (patch) {
rc = kwboot_img_patch_hdr(img, size);
if (rc) {
fprintf(stderr, "%s: Invalid image.\n", imgpath);
goto out;
}
}
if (bootmsg) {
rc = kwboot_bootmsg(tty, bootmsg);
if (rc) {
perror("bootmsg");
goto out;
}
}
if (img) {
rc = kwboot_xmodem(tty, img, size);
if (rc) {
perror("xmodem");
goto out;
}
}
if (term) {
rc = kwboot_terminal(tty);
if (rc && !(errno == EINTR)) {
perror("terminal");
goto out;
}
}
rv = 0;
out:
if (tty >= 0)
close(tty);
if (img)
munmap(img, size);
return rv;
usage:
kwboot_usage(rv ? stderr : stdout, basename(argv[0]));
goto out;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -0,0 +1,139 @@
/*
* Copyright 2008 Extreme Engineering Solutions, Inc.
*
* mmap/munmap implementation derived from:
* Clamav Native Windows Port : mmap win32 compatibility layer
* Copyright (c) 2005-2006 Gianluigi Tiesi <sherpya@netfarm.it>
* Parts by Kees Zeelenberg <kzlg@users.sourceforge.net> (LibGW32C)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this software; if not, write to the
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "mingw_support.h"
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <io.h>
int fsync(int fd)
{
return _commit(fd);
}
void *mmap(void *addr, size_t len, int prot, int flags, int fd, int offset)
{
void *map = NULL;
HANDLE handle = INVALID_HANDLE_VALUE;
DWORD cfm_flags = 0, mvf_flags = 0;
switch (prot) {
case PROT_READ | PROT_WRITE:
cfm_flags = PAGE_READWRITE;
mvf_flags = FILE_MAP_ALL_ACCESS;
break;
case PROT_WRITE:
cfm_flags = PAGE_READWRITE;
mvf_flags = FILE_MAP_WRITE;
break;
case PROT_READ:
cfm_flags = PAGE_READONLY;
mvf_flags = FILE_MAP_READ;
break;
default:
return MAP_FAILED;
}
handle = CreateFileMappingA((HANDLE) _get_osfhandle(fd), NULL,
cfm_flags, HIDWORD(len), LODWORD(len), NULL);
if (!handle)
return MAP_FAILED;
map = MapViewOfFile(handle, mvf_flags, HIDWORD(offset),
LODWORD(offset), len);
CloseHandle(handle);
if (!map)
return MAP_FAILED;
return map;
}
int munmap(void *addr, size_t len)
{
if (!UnmapViewOfFile(addr))
return -1;
return 0;
}
/* Reentrant string tokenizer. Generic version.
Copyright (C) 1991,1996-1999,2001,2004,2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
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, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* Parse S into tokens separated by characters in DELIM.
If S is NULL, the saved pointer in SAVE_PTR is used as
the next starting point. For example:
char s[] = "-abc-=-def";
char *sp;
x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def"
x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL
x = strtok_r(NULL, "=", &sp); // x = NULL
// s = "abc\0-def\0"
*/
char *strtok_r(char *s, const char *delim, char **save_ptr)
{
char *token;
if (s == NULL)
s = *save_ptr;
/* Scan leading delimiters. */
s += strspn(s, delim);
if (*s == '\0') {
*save_ptr = s;
return NULL;
}
/* Find the end of the token. */
token = s;
s = strpbrk (token, delim);
if (s == NULL) {
/* This token finishes the string. */
*save_ptr = memchr(token, '\0', strlen(token));
} else {
/* Terminate the token and make *SAVE_PTR point past it. */
*s = '\0';
*save_ptr = s + 1;
}
return token;
}
#include "getline.c"

View file

@ -0,0 +1,58 @@
/*
* Copyright 2008 Extreme Engineering Solutions, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this software; if not, write to the
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __MINGW_SUPPORT_H_
#define __WINGW_SUPPORT_H_ 1
/* Defining __INSIDE_MSYS__ helps to prevent u-boot/mingw overlap */
#define __INSIDE_MSYS__ 1
#include <windows.h>
/* mmap protections */
#define PROT_READ 0x1 /* Page can be read */
#define PROT_WRITE 0x2 /* Page can be written */
#define PROT_EXEC 0x4 /* Page can be executed */
#define PROT_NONE 0x0 /* Page can not be accessed */
/* Sharing types (must choose one and only one of these) */
#define MAP_SHARED 0x01 /* Share changes */
#define MAP_PRIVATE 0x02 /* Changes are private */
/* File perms */
#ifndef S_IRGRP
# define S_IRGRP 0
#endif
#ifndef S_IWGRP
# define S_IWGRP 0
#endif
/* Windows 64-bit access macros */
#define LODWORD(x) ((DWORD)((DWORDLONG)(x)))
#define HIDWORD(x) ((DWORD)(((DWORDLONG)(x) >> 32) & 0xffffffff))
typedef UINT uint;
typedef ULONG ulong;
int fsync(int fd);
void *mmap(void *, size_t, int, int, int, int);
int munmap(void *, size_t);
char *strtok_r(char *s, const char *delim, char **save_ptr);
#include "getline.h"
#endif /* __MINGW_SUPPORT_H_ */

View file

@ -0,0 +1,314 @@
/*
* (C) Copyright 2011 Free Electrons
* David Wagner <david.wagner@free-electrons.com>
*
* Inspired from envcrc.c:
* (C) Copyright 2001
* Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
*
* 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
*/
/* We want the GNU version of basename() */
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <libgen.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include "compiler.h"
#include <u-boot/crc.h>
#include <version.h>
#define CRC_SIZE sizeof(uint32_t)
static void usage(const char *exec_name)
{
fprintf(stderr, "%s [-h] [-r] [-b] [-p <byte>] -s <environment partition size> -o <output> <input file>\n"
"\n"
"This tool takes a key=value input file (same as would a `printenv' show) and generates the corresponding environment image, ready to be flashed.\n"
"\n"
"\tThe input file is in format:\n"
"\t\tkey1=value1\n"
"\t\tkey2=value2\n"
"\t\t...\n"
"\t-r : the environment has multiple copies in flash\n"
"\t-b : the target is big endian (default is little endian)\n"
"\t-p <byte> : fill the image with <byte> bytes instead of 0xff bytes\n"
"\t-V : print version information and exit\n"
"\n"
"If the input file is \"-\", data is read from standard input\n",
exec_name);
}
long int xstrtol(const char *s)
{
long int tmp;
errno = 0;
tmp = strtol(s, NULL, 0);
if (!errno)
return tmp;
if (errno == ERANGE)
fprintf(stderr, "Bad integer format: %s\n", s);
else
fprintf(stderr, "Error while parsing %s: %s\n", s,
strerror(errno));
exit(EXIT_FAILURE);
}
int main(int argc, char **argv)
{
uint32_t crc, targetendian_crc;
const char *txt_filename = NULL, *bin_filename = NULL;
int txt_fd, bin_fd;
unsigned char *dataptr, *envptr;
unsigned char *filebuf = NULL;
unsigned int filesize = 0, envsize = 0, datasize = 0;
int bigendian = 0;
int redundant = 0;
unsigned char padbyte = 0xff;
int option;
int ret = EXIT_SUCCESS;
struct stat txt_file_stat;
int fp, ep;
const char *prg;
prg = basename(argv[0]);
/* Turn off getopt()'s internal error message */
opterr = 0;
/* Parse the cmdline */
while ((option = getopt(argc, argv, ":s:o:rbp:hV")) != -1) {
switch (option) {
case 's':
datasize = xstrtol(optarg);
break;
case 'o':
bin_filename = strdup(optarg);
if (!bin_filename) {
fprintf(stderr, "Can't strdup() the output filename\n");
return EXIT_FAILURE;
}
break;
case 'r':
redundant = 1;
break;
case 'b':
bigendian = 1;
break;
case 'p':
padbyte = xstrtol(optarg);
break;
case 'h':
usage(prg);
return EXIT_SUCCESS;
case 'V':
printf("%s version %s\n", prg, PLAIN_VERSION);
return EXIT_SUCCESS;
case ':':
fprintf(stderr, "Missing argument for option -%c\n",
optopt);
usage(prg);
return EXIT_FAILURE;
default:
fprintf(stderr, "Wrong option -%c\n", optopt);
usage(prg);
return EXIT_FAILURE;
}
}
/* Check datasize and allocate the data */
if (datasize == 0) {
fprintf(stderr, "Please specify the size of the environment partition.\n");
usage(prg);
return EXIT_FAILURE;
}
dataptr = malloc(datasize * sizeof(*dataptr));
if (!dataptr) {
fprintf(stderr, "Can't alloc %d bytes for dataptr.\n",
datasize);
return EXIT_FAILURE;
}
/*
* envptr points to the beginning of the actual environment (after the
* crc and possible `redundant' byte
*/
envsize = datasize - (CRC_SIZE + redundant);
envptr = dataptr + CRC_SIZE + redundant;
/* Pad the environment with the padding byte */
memset(envptr, padbyte, envsize);
/* Open the input file ... */
if (optind >= argc || strcmp(argv[optind], "-") == 0) {
int readbytes = 0;
int readlen = sizeof(*envptr) * 4096;
txt_fd = STDIN_FILENO;
do {
filebuf = realloc(filebuf, readlen);
if (!filebuf) {
fprintf(stderr, "Can't realloc memory for the input file buffer\n");
return EXIT_FAILURE;
}
readbytes = read(txt_fd, filebuf + filesize, readlen);
if (errno) {
fprintf(stderr, "Error while reading stdin: %s\n",
strerror(errno));
return EXIT_FAILURE;
}
filesize += readbytes;
} while (readbytes == readlen);
} else {
txt_filename = argv[optind];
txt_fd = open(txt_filename, O_RDONLY);
if (txt_fd == -1) {
fprintf(stderr, "Can't open \"%s\": %s\n",
txt_filename, strerror(errno));
return EXIT_FAILURE;
}
/* ... and check it */
ret = fstat(txt_fd, &txt_file_stat);
if (ret == -1) {
fprintf(stderr, "Can't stat() on \"%s\": %s\n",
txt_filename, strerror(errno));
return EXIT_FAILURE;
}
filesize = txt_file_stat.st_size;
filebuf = mmap(NULL, sizeof(*envptr) * filesize, PROT_READ,
MAP_PRIVATE, txt_fd, 0);
if (filebuf == MAP_FAILED) {
fprintf(stderr, "mmap (%zu bytes) failed: %s\n",
sizeof(*envptr) * filesize,
strerror(errno));
fprintf(stderr, "Falling back to read()\n");
filebuf = malloc(sizeof(*envptr) * filesize);
ret = read(txt_fd, filebuf, sizeof(*envptr) * filesize);
if (ret != sizeof(*envptr) * filesize) {
fprintf(stderr, "Can't read the whole input file (%zu bytes): %s\n",
sizeof(*envptr) * filesize,
strerror(errno));
return EXIT_FAILURE;
}
}
ret = close(txt_fd);
}
/* The +1 is for the additionnal ending \0. See below. */
if (filesize + 1 > envsize) {
fprintf(stderr, "The input file is larger than the environment partition size\n");
return EXIT_FAILURE;
}
/* Replace newlines separating variables with \0 */
for (fp = 0, ep = 0 ; fp < filesize ; fp++) {
if (filebuf[fp] == '\n') {
if (ep == 0) {
/*
* Newlines at the beginning of the file ?
* Ignore them.
*/
continue;
} else if (filebuf[fp-1] == '\\') {
/*
* Embedded newline in a variable.
*
* The backslash was added to the envptr; rewind
* and replace it with a newline
*/
ep--;
envptr[ep++] = '\n';
} else {
/* End of a variable */
envptr[ep++] = '\0';
}
} else {
envptr[ep++] = filebuf[fp];
}
}
/*
* Make sure there is a final '\0'
* And do it again on the next byte to mark the end of the environment.
*/
if (envptr[ep-1] != '\0') {
envptr[ep++] = '\0';
/*
* The text file doesn't have an ending newline. We need to
* check the env size again to make sure we have room for two \0
*/
if (ep >= envsize) {
fprintf(stderr, "The environment file is too large for the target environment storage\n");
return EXIT_FAILURE;
}
envptr[ep] = '\0';
} else {
envptr[ep] = '\0';
}
/* Computes the CRC and put it at the beginning of the data */
crc = crc32(0, envptr, envsize);
targetendian_crc = bigendian ? cpu_to_be32(crc) : cpu_to_le32(crc);
memcpy(dataptr, &targetendian_crc, sizeof(targetendian_crc));
if (redundant)
dataptr[sizeof(targetendian_crc)] = 1;
if (!bin_filename || strcmp(bin_filename, "-") == 0) {
bin_fd = STDOUT_FILENO;
} else {
bin_fd = creat(bin_filename, S_IRUSR | S_IWUSR | S_IRGRP |
S_IWGRP);
if (bin_fd == -1) {
fprintf(stderr, "Can't open output file \"%s\": %s\n",
bin_filename, strerror(errno));
return EXIT_FAILURE;
}
}
if (write(bin_fd, dataptr, sizeof(*dataptr) * datasize) !=
sizeof(*dataptr) * datasize) {
fprintf(stderr, "write() failed: %s\n", strerror(errno));
return EXIT_FAILURE;
}
ret = close(bin_fd);
return ret;
}

View file

@ -0,0 +1,122 @@
/*
* Copyright (C) 2012 Samsung Electronics
*
* 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <compiler.h>
#define CHECKSUM_OFFSET (14*1024-4)
#define BUFSIZE (14*1024)
#define FILE_PERM (S_IRUSR | S_IWUSR | S_IRGRP \
| S_IWGRP | S_IROTH | S_IWOTH)
/*
* Requirement:
* IROM code reads first 14K bytes from boot device.
* It then calculates the checksum of 14K-4 bytes and compare with data at
* 14K-4 offset.
*
* This function takes two filenames:
* IN "u-boot-spl.bin" and
* OUT "$(BOARD)-spl.bin as filenames.
* It reads the "u-boot-spl.bin" in 16K buffer.
* It calculates checksum of 14K-4 Bytes and stores at 14K-4 offset in buffer.
* It writes the buffer to "$(BOARD)-spl.bin" file.
*/
int main(int argc, char **argv)
{
unsigned char buffer[BUFSIZE];
int i, ifd, ofd;
uint32_t checksum = 0;
off_t len;
ssize_t count;
struct stat stat;
if (argc != 3) {
fprintf(stderr, "Usage: %s <infile> <outfile>\n", argv[0]);
exit(EXIT_FAILURE);
}
ifd = open(argv[1], O_RDONLY);
if (ifd < 0) {
fprintf(stderr, "%s: Can't open %s: %s\n",
argv[0], argv[1], strerror(errno));
exit(EXIT_FAILURE);
}
ofd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, FILE_PERM);
if (ifd < 0) {
fprintf(stderr, "%s: Can't open %s: %s\n",
argv[0], argv[2], strerror(errno));
close(ifd);
exit(EXIT_FAILURE);
}
if (fstat(ifd, &stat)) {
fprintf(stderr, "%s: Unable to get size of %s: %s\n",
argv[0], argv[1], strerror(errno));
close(ifd);
close(ofd);
exit(EXIT_FAILURE);
}
len = stat.st_size;
count = (len < CHECKSUM_OFFSET) ? len : CHECKSUM_OFFSET;
if (read(ifd, buffer, count) != count) {
fprintf(stderr, "%s: Can't read %s: %s\n",
argv[0], argv[1], strerror(errno));
close(ifd);
close(ofd);
exit(EXIT_FAILURE);
}
for (i = 0, checksum = 0; i < CHECKSUM_OFFSET; i++)
checksum += buffer[i];
checksum = cpu_to_le32(checksum);
memcpy(&buffer[CHECKSUM_OFFSET], &checksum, sizeof(checksum));
if (write(ofd, buffer, BUFSIZE) != BUFSIZE) {
fprintf(stderr, "%s: Can't write %s: %s\n",
argv[0], argv[2], strerror(errno));
close(ifd);
close(ofd);
exit(EXIT_FAILURE);
}
close(ifd);
close(ofd);
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,96 @@
#
# Copyright (c) 2014 The Linux Foundation. All rights reserved.
#
import sys
import struct
def create_header(base, size, img_type):
"""Returns a packed MBN header image with the specified base and size.
@arg base: integer, specifies the image load address in RAM
@arg size: integer, specifies the size of the image
@arg img_type: integer, specifies the image type
@returns: string, the MBN header
"""
header = [
img_type, # Type: APPSBL
0x3, # Version: 3
0x0, # Image source pointer
base, # Image destination pointer
size, # Code Size + Cert Size + Signature Size
size, # Code Size
base + size, # Destination + Code Size
0x0, # Signature Size
base + size, # Destination + Code Size + Signature Size
0x0, # Cert Size
]
header_packed = struct.pack('<10I', *header)
return header_packed
def mkheader(base_addr, img_type, infname, outfname):
"""Prepends the image with the MBN header.
@arg base_addr: integer, specifies the image load address in RAM
@arg img_type: integer, specifies the image type
@arg infname: string, image filename
@arg outfname: string, output image with header prepended
@raises IOError: if reading/writing input/output file fails
"""
with open(infname, "rb") as infp:
image = infp.read()
insize = len(image)
if base_addr > 0xFFFFFFFF:
raise ValueError("invalid base address")
if base_addr + insize > 0xFFFFFFFF:
raise ValueError("invalid destination range")
header = create_header(base_addr, insize, img_type)
with open(outfname, "wb") as outfp:
outfp.write(header)
outfp.write(image)
def usage(msg=None):
"""Print command usage.
@arg msg: string, error message if any (default: None)
"""
if msg != None:
sys.stderr.write("mkheader: %s\n" % msg)
print "Usage: mkheader.py <base-addr> <img_type> <input-file> <output-file>"
if msg != None:
exit(1)
def main():
"""Main entry function"""
if len(sys.argv) != 5:
usage("incorrect no. of arguments")
try:
base_addr = int(sys.argv[1], 0)
img_type = int(sys.argv[2], 0)
infname = sys.argv[3]
outfname = sys.argv[4]
except ValueError as e:
sys.stderr.write("mkheader: invalid base address '%s'\n" % sys.argv[1])
exit(1)
try:
mkheader(base_addr, img_type, infname, outfname)
except IOError as e:
sys.stderr.write("mkheader: %s\n" % e)
exit(1)
except ValueError as e:
sys.stderr.write("mkheader: %s\n" % e)
exit(1)
if __name__ == "__main__":
main()

View file

@ -0,0 +1,605 @@
/*
* (C) Copyright 2008 Semihalf
*
* (C) Copyright 2000-2009
* DENX Software Engineering
* Wolfgang Denk, wd@denx.de
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include "mkimage.h"
#include <image.h>
#include <version.h>
static void copy_file(int, const char *, int);
static void usage(void);
/* image_type_params link list to maintain registered image type supports */
struct image_type_params *mkimage_tparams = NULL;
/* parameters initialized by core will be used by the image type code */
struct image_tool_params params = {
.os = IH_OS_LINUX,
.arch = IH_ARCH_PPC,
.type = IH_TYPE_KERNEL,
.comp = IH_COMP_GZIP,
.dtc = MKIMAGE_DEFAULT_DTC_OPTIONS,
.imagename = "",
};
/*
* mkimage_register -
*
* It is used to register respective image generation/list support to the
* mkimage core
*
* the input struct image_type_params is checked and appended to the link
* list, if the input structure is already registered, error
*/
void mkimage_register (struct image_type_params *tparams)
{
struct image_type_params **tp;
if (!tparams) {
fprintf (stderr, "%s: %s: Null input\n",
params.cmdname, __FUNCTION__);
exit (EXIT_FAILURE);
}
/* scan the linked list, check for registry and point the last one */
for (tp = &mkimage_tparams; *tp != NULL; tp = &(*tp)->next) {
if (!strcmp((*tp)->name, tparams->name)) {
fprintf (stderr, "%s: %s already registered\n",
params.cmdname, tparams->name);
return;
}
}
/* add input struct entry at the end of link list */
*tp = tparams;
/* mark input entry as last entry in the link list */
tparams->next = NULL;
debug ("Registered %s\n", tparams->name);
}
/*
* mkimage_get_type -
*
* It scans all registers image type supports
* checks the input type_id for each supported image type
*
* if successful,
* returns respective image_type_params pointer if success
* if input type_id is not supported by any of image_type_support
* returns NULL
*/
struct image_type_params *mkimage_get_type(int type)
{
struct image_type_params *curr;
for (curr = mkimage_tparams; curr != NULL; curr = curr->next) {
if (curr->check_image_type) {
if (!curr->check_image_type (type))
return curr;
}
}
return NULL;
}
/*
* mkimage_verify_print_header -
*
* It scans mkimage_tparams link list,
* verifies image_header for each supported image type
* if verification is successful, prints respective header
*
* returns negative if input image format does not match with any of
* supported image types
*/
int mkimage_verify_print_header (void *ptr, struct stat *sbuf)
{
int retval = -1;
struct image_type_params *curr;
for (curr = mkimage_tparams; curr != NULL; curr = curr->next ) {
if (curr->verify_header) {
retval = curr->verify_header (
(unsigned char *)ptr, sbuf->st_size,
&params);
if (retval == 0) {
/*
* Print the image information
* if verify is successful
*/
if (curr->print_header)
curr->print_header (ptr);
else {
fprintf (stderr,
"%s: print_header undefined for %s\n",
params.cmdname, curr->name);
}
break;
}
}
}
return retval;
}
int
main (int argc, char **argv)
{
int ifd = -1;
struct stat sbuf;
char *ptr;
int retval = 0;
struct image_type_params *tparams = NULL;
/* Init all image generation/list support */
register_image_tool(mkimage_register);
params.cmdname = *argv;
params.addr = params.ep = 0;
while (--argc > 0 && **++argv == '-') {
while (*++*argv) {
switch (**argv) {
case 'l':
params.lflag = 1;
break;
case 'A':
if ((--argc <= 0) ||
(params.arch =
genimg_get_arch_id (*++argv)) < 0)
usage ();
goto NXTARG;
case 'C':
if ((--argc <= 0) ||
(params.comp =
genimg_get_comp_id (*++argv)) < 0)
usage ();
goto NXTARG;
case 'D':
if (--argc <= 0)
usage ();
params.dtc = *++argv;
goto NXTARG;
case 'O':
if ((--argc <= 0) ||
(params.os =
genimg_get_os_id (*++argv)) < 0)
usage ();
goto NXTARG;
case 'T':
if ((--argc <= 0) ||
(params.type =
genimg_get_type_id (*++argv)) < 0)
usage ();
goto NXTARG;
case 'a':
if (--argc <= 0)
usage ();
params.addr = strtoul (*++argv, &ptr, 16);
if (*ptr) {
fprintf (stderr,
"%s: invalid load address %s\n",
params.cmdname, *argv);
exit (EXIT_FAILURE);
}
goto NXTARG;
case 'd':
if (--argc <= 0)
usage ();
params.datafile = *++argv;
params.dflag = 1;
goto NXTARG;
case 'e':
if (--argc <= 0)
usage ();
params.ep = strtoul (*++argv, &ptr, 16);
if (*ptr) {
fprintf (stderr,
"%s: invalid entry point %s\n",
params.cmdname, *argv);
exit (EXIT_FAILURE);
}
params.eflag = 1;
goto NXTARG;
case 'f':
if (--argc <= 0)
usage ();
/*
* The flattened image tree (FIT) format
* requires a flattened device tree image type
*/
params.type = IH_TYPE_FLATDT;
params.datafile = *++argv;
params.fflag = 1;
goto NXTARG;
case 'n':
if (--argc <= 0)
usage ();
params.imagename = *++argv;
goto NXTARG;
case 's':
params.skipcpy = 1;
break;
case 'v':
params.vflag++;
break;
case 'V':
printf("mkimage version %s\n", PLAIN_VERSION);
exit(EXIT_SUCCESS);
case 'x':
params.xflag++;
break;
default:
usage ();
}
}
NXTARG: ;
}
if (argc != 1)
usage ();
/* set tparams as per input type_id */
tparams = mkimage_get_type(params.type);
if (tparams == NULL) {
fprintf (stderr, "%s: unsupported type %s\n",
params.cmdname, genimg_get_type_name(params.type));
exit (EXIT_FAILURE);
}
/*
* check the passed arguments parameters meets the requirements
* as per image type to be generated/listed
*/
if (tparams->check_params)
if (tparams->check_params (&params))
usage ();
if (!params.eflag) {
params.ep = params.addr;
/* If XIP, entry point must be after the U-Boot header */
if (params.xflag)
params.ep += tparams->header_size;
}
params.imagefile = *argv;
if (params.fflag){
if (tparams->fflag_handle)
/*
* in some cases, some additional processing needs
* to be done if fflag is defined
*
* For ex. fit_handle_file for Fit file support
*/
retval = tparams->fflag_handle(&params);
if (retval != EXIT_SUCCESS)
exit (retval);
}
if (params.lflag || params.fflag) {
ifd = open (params.imagefile, O_RDONLY|O_BINARY);
} else {
ifd = open (params.imagefile,
O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666);
}
if (ifd < 0) {
fprintf (stderr, "%s: Can't open %s: %s\n",
params.cmdname, params.imagefile,
strerror(errno));
exit (EXIT_FAILURE);
}
if (params.lflag || params.fflag) {
/*
* list header information of existing image
*/
if (fstat(ifd, &sbuf) < 0) {
fprintf (stderr, "%s: Can't stat %s: %s\n",
params.cmdname, params.imagefile,
strerror(errno));
exit (EXIT_FAILURE);
}
if ((unsigned)sbuf.st_size < tparams->header_size) {
fprintf (stderr,
"%s: Bad size: \"%s\" is not valid image\n",
params.cmdname, params.imagefile);
exit (EXIT_FAILURE);
}
ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0);
if (ptr == MAP_FAILED) {
fprintf (stderr, "%s: Can't read %s: %s\n",
params.cmdname, params.imagefile,
strerror(errno));
exit (EXIT_FAILURE);
}
/*
* scan through mkimage registry for all supported image types
* and verify the input image file header for match
* Print the image information for matched image type
* Returns the error code if not matched
*/
retval = mkimage_verify_print_header (ptr, &sbuf);
(void) munmap((void *)ptr, sbuf.st_size);
(void) close (ifd);
exit (retval);
}
/*
* In case there an header with a variable
* length will be added, the corresponding
* function is called. This is responsible to
* allocate memory for the header itself.
*/
if (tparams->vrec_header)
tparams->vrec_header(&params, tparams);
else
memset(tparams->hdr, 0, tparams->header_size);
if (write(ifd, tparams->hdr, tparams->header_size)
!= tparams->header_size) {
fprintf (stderr, "%s: Write error on %s: %s\n",
params.cmdname, params.imagefile, strerror(errno));
exit (EXIT_FAILURE);
}
if (!params.skipcpy) {
if (params.type == IH_TYPE_MULTI ||
params.type == IH_TYPE_SCRIPT) {
char *file = params.datafile;
uint32_t size;
for (;;) {
char *sep = NULL;
if (file) {
if ((sep = strchr(file, ':')) != NULL) {
*sep = '\0';
}
if (stat (file, &sbuf) < 0) {
fprintf (stderr, "%s: Can't stat %s: %s\n",
params.cmdname, file, strerror(errno));
exit (EXIT_FAILURE);
}
size = cpu_to_uimage (sbuf.st_size);
} else {
size = 0;
}
if (write(ifd, (char *)&size, sizeof(size)) != sizeof(size)) {
fprintf (stderr, "%s: Write error on %s: %s\n",
params.cmdname, params.imagefile,
strerror(errno));
exit (EXIT_FAILURE);
}
if (!file) {
break;
}
if (sep) {
*sep = ':';
file = sep + 1;
} else {
file = NULL;
}
}
file = params.datafile;
for (;;) {
char *sep = strchr(file, ':');
if (sep) {
*sep = '\0';
copy_file (ifd, file, 1);
*sep++ = ':';
file = sep;
} else {
copy_file (ifd, file, 0);
break;
}
}
} else {
copy_file (ifd, params.datafile, 0);
}
}
/* We're a bit of paranoid */
#if defined(_POSIX_SYNCHRONIZED_IO) && \
!defined(__sun__) && \
!defined(__FreeBSD__) && \
!defined(__APPLE__)
(void) fdatasync (ifd);
#else
(void) fsync (ifd);
#endif
if (fstat(ifd, &sbuf) < 0) {
fprintf (stderr, "%s: Can't stat %s: %s\n",
params.cmdname, params.imagefile, strerror(errno));
exit (EXIT_FAILURE);
}
ptr = mmap(0, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0);
if (ptr == MAP_FAILED) {
fprintf (stderr, "%s: Can't map %s: %s\n",
params.cmdname, params.imagefile, strerror(errno));
exit (EXIT_FAILURE);
}
/* Setup the image header as per input image type*/
if (tparams->set_header)
tparams->set_header (ptr, &sbuf, ifd, &params);
else {
fprintf (stderr, "%s: Can't set header for %s: %s\n",
params.cmdname, tparams->name, strerror(errno));
exit (EXIT_FAILURE);
}
/* Print the image information by processing image header */
if (tparams->print_header)
tparams->print_header (ptr);
else {
fprintf (stderr, "%s: Can't print header for %s: %s\n",
params.cmdname, tparams->name, strerror(errno));
exit (EXIT_FAILURE);
}
(void) munmap((void *)ptr, sbuf.st_size);
/* We're a bit of paranoid */
#if defined(_POSIX_SYNCHRONIZED_IO) && \
!defined(__sun__) && \
!defined(__FreeBSD__) && \
!defined(__APPLE__)
(void) fdatasync (ifd);
#else
(void) fsync (ifd);
#endif
if (close(ifd)) {
fprintf (stderr, "%s: Write error on %s: %s\n",
params.cmdname, params.imagefile, strerror(errno));
exit (EXIT_FAILURE);
}
exit (EXIT_SUCCESS);
}
static void
copy_file (int ifd, const char *datafile, int pad)
{
int dfd;
struct stat sbuf;
unsigned char *ptr;
int tail;
int zero = 0;
int offset = 0;
int size;
struct image_type_params *tparams = mkimage_get_type (params.type);
if (params.vflag) {
fprintf (stderr, "Adding Image %s\n", datafile);
}
if ((dfd = open(datafile, O_RDONLY|O_BINARY)) < 0) {
fprintf (stderr, "%s: Can't open %s: %s\n",
params.cmdname, datafile, strerror(errno));
exit (EXIT_FAILURE);
}
if (fstat(dfd, &sbuf) < 0) {
fprintf (stderr, "%s: Can't stat %s: %s\n",
params.cmdname, datafile, strerror(errno));
exit (EXIT_FAILURE);
}
ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, dfd, 0);
if (ptr == MAP_FAILED) {
fprintf (stderr, "%s: Can't read %s: %s\n",
params.cmdname, datafile, strerror(errno));
exit (EXIT_FAILURE);
}
if (params.xflag) {
unsigned char *p = NULL;
/*
* XIP: do not append the image_header_t at the
* beginning of the file, but consume the space
* reserved for it.
*/
if ((unsigned)sbuf.st_size < tparams->header_size) {
fprintf (stderr,
"%s: Bad size: \"%s\" is too small for XIP\n",
params.cmdname, datafile);
exit (EXIT_FAILURE);
}
for (p = ptr; p < ptr + tparams->header_size; p++) {
if ( *p != 0xff ) {
fprintf (stderr,
"%s: Bad file: \"%s\" has invalid buffer for XIP\n",
params.cmdname, datafile);
exit (EXIT_FAILURE);
}
}
offset = tparams->header_size;
}
size = sbuf.st_size - offset;
if (write(ifd, ptr + offset, size) != size) {
fprintf (stderr, "%s: Write error on %s: %s\n",
params.cmdname, params.imagefile, strerror(errno));
exit (EXIT_FAILURE);
}
if (pad && ((tail = size % 4) != 0)) {
if (write(ifd, (char *)&zero, 4-tail) != 4-tail) {
fprintf (stderr, "%s: Write error on %s: %s\n",
params.cmdname, params.imagefile,
strerror(errno));
exit (EXIT_FAILURE);
}
}
(void) munmap((void *)ptr, sbuf.st_size);
(void) close (dfd);
}
void
usage ()
{
fprintf (stderr, "Usage: %s -l image\n"
" -l ==> list image header information\n",
params.cmdname);
fprintf (stderr, " %s [-x] -A arch -O os -T type -C comp "
"-a addr -e ep -n name -d data_file[:data_file...] image\n"
" -A ==> set architecture to 'arch'\n"
" -O ==> set operating system to 'os'\n"
" -T ==> set image type to 'type'\n"
" -C ==> set compression type 'comp'\n"
" -a ==> set load address to 'addr' (hex)\n"
" -e ==> set entry point to 'ep' (hex)\n"
" -n ==> set image name to 'name'\n"
" -d ==> use image data from 'datafile'\n"
" -x ==> set XIP (execute in place)\n",
params.cmdname);
fprintf (stderr, " %s [-D dtc_options] -f fit-image.its fit-image\n",
params.cmdname);
fprintf (stderr, " %s -V ==> print version information and exit\n",
params.cmdname);
exit (EXIT_FAILURE);
}

View file

@ -0,0 +1,52 @@
/*
* (C) Copyright 2000-2004
* DENX Software Engineering
* Wolfgang Denk, wd@denx.de
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef _MKIIMAGE_H_
#define _MKIIMAGE_H_
#include "os_support.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include <u-boot-sha1.h>
#include "fdt_host.h"
#include "imagetool.h"
#undef MKIMAGE_DEBUG
#ifdef MKIMAGE_DEBUG
#define debug(fmt,args...) printf (fmt ,##args)
#else
#define debug(fmt,args...)
#endif /* MKIMAGE_DEBUG */
#define MKIMAGE_TMPFILE_SUFFIX ".tmp"
#define MKIMAGE_MAX_TMPFILE_LEN 256
#define MKIMAGE_DEFAULT_DTC_OPTIONS "-I dts -O dtb -p 500"
#define MKIMAGE_MAX_DTC_CMDLINE_LEN 512
#define MKIMAGE_DTC "dtc" /* assume dtc is in $PATH */
#endif /* _MKIIMAGE_H_ */

View file

@ -0,0 +1,218 @@
/*
* (C) Copyright 2003 Intracom S.A.
* Pantelis Antoniou <panto@intracom.gr>
*
* This little program makes an exhaustive search for the
* correct terms of pdf, mfi, mfn, mfd, s, dbrmo, in PLPRCR.
* The goal is to produce a gclk2 from a xin input, while respecting
* all the restrictions on their combination.
*
* Generaly you select the first row of the produced table.
*
* 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 <stdio.h>
#include <stdlib.h>
#define DPREF_MIN 10000000
#define DPREF_MAX 32000000
#define DPGDCK_MAX 320000000
#define DPGDCK_MIN 160000000
#define S_MIN 0
#define S_MAX 2
#define MFI_MIN 5
#define MFI_MAX 15
#define MFN_MIN 0
#define MFN_MAX 15
#define MFD_MIN 0
#define MFD_MAX 31
#define MF_MIN 5
#define MF_MAX 15
#define PDF_MIN 0
#define PDF_MAX 15
#define GCLK2_MAX 150000000
static int calculate (int xin, int target_clock,
int ppm, int pdf, int mfi, int mfn, int mfd, int s,
int *dprefp, int *dpgdckp, int *jdbckp,
int *gclk2p, int *dbrmop)
{
unsigned int dpref, dpgdck, jdbck, gclk2, t1, t2, dbrmo;
/* valid MFI? */
if (mfi < MFI_MIN)
return -1;
/* valid num, denum? */
if (mfn > 0 && mfn >= mfd)
return -1;
dpref = xin / (pdf + 1);
/* valid dpef? */
if (dpref < DPREF_MIN || dpref > DPREF_MAX)
return -1;
if (mfn == 0) {
dpgdck = (2 * mfi * xin) / (pdf + 1) ;
dbrmo = 0;
} else {
/* 5 <= mfi + (mfn / mfd + 1) <= 15 */
t1 = mfd + 1;
t2 = mfi * t1 + mfn;
if ( MF_MIN * t1 > t2 || MF_MAX * t1 < t2)
return -1;
dpgdck = (unsigned int)(2 * (mfi * mfd + mfi + mfn) *
(unsigned int)xin) /
((mfd + 1) * (pdf + 1));
dbrmo = 10 * mfn < (mfd + 1);
}
/* valid dpgclk? */
if (dpgdck < DPGDCK_MIN || dpgdck > DPGDCK_MAX)
return -1;
jdbck = dpgdck >> s;
gclk2 = jdbck / 2;
/* valid gclk2 */
if (gclk2 > GCLK2_MAX)
return -1;
t1 = abs(gclk2 - target_clock);
/* XXX max 1MHz dev. in clock */
if (t1 > 1000000)
return -1;
/* dev within range (XXX gclk2 scaled to avoid overflow) */
if (t1 * 1000 > (unsigned int)ppm * (gclk2 / 1000))
return -1;
*dprefp = dpref;
*dpgdckp = dpgdck;
*jdbckp = jdbck;
*gclk2p = gclk2;
*dbrmop = dbrmo;
return gclk2;
}
int conf_clock(int xin, int target_clock, int ppm)
{
int pdf, s, mfn, mfd, mfi;
int dpref, dpgdck, jdbck, gclk2, xout, dbrmo;
int found = 0;
/* integer multipliers */
for (pdf = PDF_MIN; pdf <= PDF_MAX; pdf++) {
for (mfi = MFI_MIN; mfi <= MFI_MAX; mfi++) {
for (s = 0; s <= S_MAX; s++) {
xout = calculate(xin, target_clock,
ppm, pdf, mfi, 0, 0, s,
&dpref, &dpgdck, &jdbck,
&gclk2, &dbrmo);
if (xout < 0)
continue;
if (found == 0) {
printf("pdf mfi mfn mfd s dbrmo dpref dpgdck jdbck gclk2 exact?\n");
printf("--- --- --- --- - ----- ----- ------ ----- ----- ------\n");
}
printf("%3d %3d --- --- %1d %5d %9d %9d %9d %9d%s\n",
pdf, mfi, s, dbrmo,
dpref, dpgdck, jdbck, gclk2,
gclk2 == target_clock ? " YES" : "");
found++;
}
}
}
/* fractional multipliers */
for (pdf = PDF_MIN; pdf <= PDF_MAX; pdf++) {
for (mfi = MFI_MIN; mfi <= MFI_MAX; mfi++) {
for (mfn = 1; mfn <= MFN_MAX; mfn++) {
for (mfd = 1; mfd <= MFD_MAX; mfd++) {
for (s = 0; s <= S_MAX; s++) {
xout = calculate(xin, target_clock,
ppm, pdf, mfi, mfn, mfd, s,
&dpref, &dpgdck, &jdbck,
&gclk2, &dbrmo);
if (xout < 0)
continue;
if (found == 0) {
printf("pdf mfi mfn mfd s dbrmo dpref dpgdck jdbck gclk2 exact?\n");
printf("--- --- --- --- - ----- ----- ------ ----- ----- ------\n");
}
printf("%3d %3d %3d %3d %1d %5d %9d %9d %9d %9d%s\n",
pdf, mfi, mfn, mfd, s,
dbrmo, dpref, dpgdck, jdbck, gclk2,
gclk2 == target_clock ? " YES" : "");
found++;
}
}
}
}
}
return found;
}
int main(int argc, char *argv[])
{
int xin, want_gclk2, found, ppm = 100;
if (argc < 3) {
fprintf(stderr, "usage: mpc86x_clk <xin> <want_gclk2> [ppm]\n");
fprintf(stderr, " default ppm is 100\n");
return 10;
}
xin = atoi(argv[1]);
want_gclk2 = atoi(argv[2]);
if (argc >= 4)
ppm = atoi(argv[3]);
found = conf_clock(xin, want_gclk2, ppm);
if (found <= 0) {
fprintf(stderr, "cannot produce gclk2 %d from xin %d\n",
want_gclk2, xin);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,687 @@
/*
* Freescale i.MX28 image generator
*
* Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
* on behalf of DENX Software Engineering GmbH
*
* 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 <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "compiler.h"
/*
* Default BCB layout.
*
* TWEAK this if you have blown any OCOTP fuses.
*/
#define STRIDE_PAGES 64
#define STRIDE_COUNT 4
/*
* Layout for 256Mb big NAND with 2048b page size, 64b OOB size and
* 128kb erase size.
*
* TWEAK this if you have different kind of NAND chip.
*/
uint32_t nand_writesize = 2048;
uint32_t nand_oobsize = 64;
uint32_t nand_erasesize = 128 * 1024;
/*
* Sector on which the SigmaTel boot partition (0x53) starts.
*/
uint32_t sd_sector = 2048;
/*
* Each of the U-Boot bootstreams is at maximum 1MB big.
*
* TWEAK this if, for some wild reason, you need to boot bigger image.
*/
#define MAX_BOOTSTREAM_SIZE (1 * 1024 * 1024)
/* i.MX28 NAND controller-specific constants. DO NOT TWEAK! */
#define MXS_NAND_DMA_DESCRIPTOR_COUNT 4
#define MXS_NAND_CHUNK_DATA_CHUNK_SIZE 512
#define MXS_NAND_METADATA_SIZE 10
#define MXS_NAND_COMMAND_BUFFER_SIZE 32
struct mx28_nand_fcb {
uint32_t checksum;
uint32_t fingerprint;
uint32_t version;
struct {
uint8_t data_setup;
uint8_t data_hold;
uint8_t address_setup;
uint8_t dsample_time;
uint8_t nand_timing_state;
uint8_t rea;
uint8_t rloh;
uint8_t rhoh;
} timing;
uint32_t page_data_size;
uint32_t total_page_size;
uint32_t sectors_per_block;
uint32_t number_of_nands; /* Ignored */
uint32_t total_internal_die; /* Ignored */
uint32_t cell_type; /* Ignored */
uint32_t ecc_block_n_ecc_type;
uint32_t ecc_block_0_size;
uint32_t ecc_block_n_size;
uint32_t ecc_block_0_ecc_type;
uint32_t metadata_bytes;
uint32_t num_ecc_blocks_per_page;
uint32_t ecc_block_n_ecc_level_sdk; /* Ignored */
uint32_t ecc_block_0_size_sdk; /* Ignored */
uint32_t ecc_block_n_size_sdk; /* Ignored */
uint32_t ecc_block_0_ecc_level_sdk; /* Ignored */
uint32_t num_ecc_blocks_per_page_sdk; /* Ignored */
uint32_t metadata_bytes_sdk; /* Ignored */
uint32_t erase_threshold;
uint32_t boot_patch;
uint32_t patch_sectors;
uint32_t firmware1_starting_sector;
uint32_t firmware2_starting_sector;
uint32_t sectors_in_firmware1;
uint32_t sectors_in_firmware2;
uint32_t dbbt_search_area_start_address;
uint32_t badblock_marker_byte;
uint32_t badblock_marker_start_bit;
uint32_t bb_marker_physical_offset;
};
struct mx28_nand_dbbt {
uint32_t checksum;
uint32_t fingerprint;
uint32_t version;
uint32_t number_bb;
uint32_t number_2k_pages_bb;
};
struct mx28_nand_bbt {
uint32_t nand;
uint32_t number_bb;
uint32_t badblock[510];
};
struct mx28_sd_drive_info {
uint32_t chip_num;
uint32_t drive_type;
uint32_t tag;
uint32_t first_sector_number;
uint32_t sector_count;
};
struct mx28_sd_config_block {
uint32_t signature;
uint32_t primary_boot_tag;
uint32_t secondary_boot_tag;
uint32_t num_copies;
struct mx28_sd_drive_info drv_info[1];
};
static inline uint32_t mx28_nand_ecc_size_in_bits(uint32_t ecc_strength)
{
return ecc_strength * 13;
}
static inline uint32_t mx28_nand_get_ecc_strength(uint32_t page_data_size,
uint32_t page_oob_size)
{
if (page_data_size == 2048)
return 8;
if (page_data_size == 4096) {
if (page_oob_size == 128)
return 8;
if (page_oob_size == 218)
return 16;
}
return 0;
}
static inline uint32_t mx28_nand_get_mark_offset(uint32_t page_data_size,
uint32_t ecc_strength)
{
uint32_t chunk_data_size_in_bits;
uint32_t chunk_ecc_size_in_bits;
uint32_t chunk_total_size_in_bits;
uint32_t block_mark_chunk_number;
uint32_t block_mark_chunk_bit_offset;
uint32_t block_mark_bit_offset;
chunk_data_size_in_bits = MXS_NAND_CHUNK_DATA_CHUNK_SIZE * 8;
chunk_ecc_size_in_bits = mx28_nand_ecc_size_in_bits(ecc_strength);
chunk_total_size_in_bits =
chunk_data_size_in_bits + chunk_ecc_size_in_bits;
/* Compute the bit offset of the block mark within the physical page. */
block_mark_bit_offset = page_data_size * 8;
/* Subtract the metadata bits. */
block_mark_bit_offset -= MXS_NAND_METADATA_SIZE * 8;
/*
* Compute the chunk number (starting at zero) in which the block mark
* appears.
*/
block_mark_chunk_number =
block_mark_bit_offset / chunk_total_size_in_bits;
/*
* Compute the bit offset of the block mark within its chunk, and
* validate it.
*/
block_mark_chunk_bit_offset = block_mark_bit_offset -
(block_mark_chunk_number * chunk_total_size_in_bits);
if (block_mark_chunk_bit_offset > chunk_data_size_in_bits)
return 1;
/*
* Now that we know the chunk number in which the block mark appears,
* we can subtract all the ECC bits that appear before it.
*/
block_mark_bit_offset -=
block_mark_chunk_number * chunk_ecc_size_in_bits;
return block_mark_bit_offset;
}
static inline uint32_t mx28_nand_mark_byte_offset(void)
{
uint32_t ecc_strength;
ecc_strength = mx28_nand_get_ecc_strength(nand_writesize, nand_oobsize);
return mx28_nand_get_mark_offset(nand_writesize, ecc_strength) >> 3;
}
static inline uint32_t mx28_nand_mark_bit_offset(void)
{
uint32_t ecc_strength;
ecc_strength = mx28_nand_get_ecc_strength(nand_writesize, nand_oobsize);
return mx28_nand_get_mark_offset(nand_writesize, ecc_strength) & 0x7;
}
static uint32_t mx28_nand_block_csum(uint8_t *block, uint32_t size)
{
uint32_t csum = 0;
int i;
for (i = 0; i < size; i++)
csum += block[i];
return csum ^ 0xffffffff;
}
static struct mx28_nand_fcb *mx28_nand_get_fcb(uint32_t size)
{
struct mx28_nand_fcb *fcb;
uint32_t bcb_size_bytes;
uint32_t stride_size_bytes;
uint32_t bootstream_size_pages;
uint32_t fw1_start_page;
uint32_t fw2_start_page;
fcb = malloc(nand_writesize);
if (!fcb) {
printf("MX28 NAND: Unable to allocate FCB\n");
return NULL;
}
memset(fcb, 0, nand_writesize);
fcb->fingerprint = 0x20424346;
fcb->version = 0x01000000;
/*
* FIXME: These here are default values as found in kobs-ng. We should
* probably retrieve the data from NAND or something.
*/
fcb->timing.data_setup = 80;
fcb->timing.data_hold = 60;
fcb->timing.address_setup = 25;
fcb->timing.dsample_time = 6;
fcb->page_data_size = nand_writesize;
fcb->total_page_size = nand_writesize + nand_oobsize;
fcb->sectors_per_block = nand_erasesize / nand_writesize;
fcb->num_ecc_blocks_per_page = (nand_writesize / 512) - 1;
fcb->ecc_block_0_size = 512;
fcb->ecc_block_n_size = 512;
fcb->metadata_bytes = 10;
if (nand_writesize == 2048) {
fcb->ecc_block_n_ecc_type = 4;
fcb->ecc_block_0_ecc_type = 4;
} else if (nand_writesize == 4096) {
if (nand_oobsize == 128) {
fcb->ecc_block_n_ecc_type = 4;
fcb->ecc_block_0_ecc_type = 4;
} else if (nand_oobsize == 218) {
fcb->ecc_block_n_ecc_type = 8;
fcb->ecc_block_0_ecc_type = 8;
}
}
if (fcb->ecc_block_n_ecc_type == 0) {
printf("MX28 NAND: Unsupported NAND geometry\n");
goto err;
}
fcb->boot_patch = 0;
fcb->patch_sectors = 0;
fcb->badblock_marker_byte = mx28_nand_mark_byte_offset();
fcb->badblock_marker_start_bit = mx28_nand_mark_bit_offset();
fcb->bb_marker_physical_offset = nand_writesize;
stride_size_bytes = STRIDE_PAGES * nand_writesize;
bcb_size_bytes = stride_size_bytes * STRIDE_COUNT;
bootstream_size_pages = (size + (nand_writesize - 1)) /
nand_writesize;
fw1_start_page = 2 * bcb_size_bytes / nand_writesize;
fw2_start_page = (2 * bcb_size_bytes + MAX_BOOTSTREAM_SIZE) /
nand_writesize;
fcb->firmware1_starting_sector = fw1_start_page;
fcb->firmware2_starting_sector = fw2_start_page;
fcb->sectors_in_firmware1 = bootstream_size_pages;
fcb->sectors_in_firmware2 = bootstream_size_pages;
fcb->dbbt_search_area_start_address = STRIDE_PAGES * STRIDE_COUNT;
return fcb;
err:
free(fcb);
return NULL;
}
static struct mx28_nand_dbbt *mx28_nand_get_dbbt(void)
{
struct mx28_nand_dbbt *dbbt;
dbbt = malloc(nand_writesize);
if (!dbbt) {
printf("MX28 NAND: Unable to allocate DBBT\n");
return NULL;
}
memset(dbbt, 0, nand_writesize);
dbbt->fingerprint = 0x54424244;
dbbt->version = 0x1;
return dbbt;
}
static inline uint8_t mx28_nand_parity_13_8(const uint8_t b)
{
uint32_t parity = 0, tmp;
tmp = ((b >> 6) ^ (b >> 5) ^ (b >> 3) ^ (b >> 2)) & 1;
parity |= tmp << 0;
tmp = ((b >> 7) ^ (b >> 5) ^ (b >> 4) ^ (b >> 2) ^ (b >> 1)) & 1;
parity |= tmp << 1;
tmp = ((b >> 7) ^ (b >> 6) ^ (b >> 5) ^ (b >> 1) ^ (b >> 0)) & 1;
parity |= tmp << 2;
tmp = ((b >> 7) ^ (b >> 4) ^ (b >> 3) ^ (b >> 0)) & 1;
parity |= tmp << 3;
tmp = ((b >> 6) ^ (b >> 4) ^ (b >> 3) ^
(b >> 2) ^ (b >> 1) ^ (b >> 0)) & 1;
parity |= tmp << 4;
return parity;
}
static uint8_t *mx28_nand_fcb_block(struct mx28_nand_fcb *fcb)
{
uint8_t *block;
uint8_t *ecc;
int i;
block = malloc(nand_writesize + nand_oobsize);
if (!block) {
printf("MX28 NAND: Unable to allocate FCB block\n");
return NULL;
}
memset(block, 0, nand_writesize + nand_oobsize);
/* Update the FCB checksum */
fcb->checksum = mx28_nand_block_csum(((uint8_t *)fcb) + 4, 508);
/* Figure 12-11. in iMX28RM, rev. 1, says FCB is at offset 12 */
memcpy(block + 12, fcb, sizeof(struct mx28_nand_fcb));
/* ECC is at offset 12 + 512 */
ecc = block + 12 + 512;
/* Compute the ECC parity */
for (i = 0; i < sizeof(struct mx28_nand_fcb); i++)
ecc[i] = mx28_nand_parity_13_8(block[i + 12]);
return block;
}
static int mx28_nand_write_fcb(struct mx28_nand_fcb *fcb, char *buf)
{
uint32_t offset;
uint8_t *fcbblock;
int ret = 0;
int i;
fcbblock = mx28_nand_fcb_block(fcb);
if (!fcbblock)
return -1;
for (i = 0; i < STRIDE_PAGES * STRIDE_COUNT; i += STRIDE_PAGES) {
offset = i * nand_writesize;
memcpy(buf + offset, fcbblock, nand_writesize + nand_oobsize);
}
free(fcbblock);
return ret;
}
static int mx28_nand_write_dbbt(struct mx28_nand_dbbt *dbbt, char *buf)
{
uint32_t offset;
int i = STRIDE_PAGES * STRIDE_COUNT;
for (; i < 2 * STRIDE_PAGES * STRIDE_COUNT; i += STRIDE_PAGES) {
offset = i * nand_writesize;
memcpy(buf + offset, dbbt, sizeof(struct mx28_nand_dbbt));
}
return 0;
}
static int mx28_nand_write_firmware(struct mx28_nand_fcb *fcb, int infd,
char *buf)
{
int ret;
off_t size;
uint32_t offset1, offset2;
size = lseek(infd, 0, SEEK_END);
lseek(infd, 0, SEEK_SET);
offset1 = fcb->firmware1_starting_sector * nand_writesize;
offset2 = fcb->firmware2_starting_sector * nand_writesize;
ret = read(infd, buf + offset1, size);
if (ret != size)
return -1;
memcpy(buf + offset2, buf + offset1, size);
return 0;
}
void usage(void)
{
printf(
"Usage: mxsboot [ops] <type> <infile> <outfile>\n"
"Augment BootStream file with a proper header for i.MX28 boot\n"
"\n"
" <type> type of image:\n"
" \"nand\" for NAND image\n"
" \"sd\" for SD image\n"
" <infile> input file, the u-boot.sb bootstream\n"
" <outfile> output file, the bootable image\n"
"\n");
printf(
"For NAND boot, these options are accepted:\n"
" -w <size> NAND page size\n"
" -o <size> NAND OOB size\n"
" -e <size> NAND erase size\n"
"\n"
"For SD boot, these options are accepted:\n"
" -p <sector> Sector where the SGTL partition starts\n"
);
}
static int mx28_create_nand_image(int infd, int outfd)
{
struct mx28_nand_fcb *fcb;
struct mx28_nand_dbbt *dbbt;
int ret = -1;
char *buf;
int size;
ssize_t wr_size;
size = nand_writesize * 512 + 2 * MAX_BOOTSTREAM_SIZE;
buf = malloc(size);
if (!buf) {
printf("Can not allocate output buffer of %d bytes\n", size);
goto err0;
}
memset(buf, 0, size);
fcb = mx28_nand_get_fcb(MAX_BOOTSTREAM_SIZE);
if (!fcb) {
printf("Unable to compile FCB\n");
goto err1;
}
dbbt = mx28_nand_get_dbbt();
if (!dbbt) {
printf("Unable to compile DBBT\n");
goto err2;
}
ret = mx28_nand_write_fcb(fcb, buf);
if (ret) {
printf("Unable to write FCB to buffer\n");
goto err3;
}
ret = mx28_nand_write_dbbt(dbbt, buf);
if (ret) {
printf("Unable to write DBBT to buffer\n");
goto err3;
}
ret = mx28_nand_write_firmware(fcb, infd, buf);
if (ret) {
printf("Unable to write firmware to buffer\n");
goto err3;
}
wr_size = write(outfd, buf, size);
if (wr_size != size) {
ret = -1;
goto err3;
}
ret = 0;
err3:
free(dbbt);
err2:
free(fcb);
err1:
free(buf);
err0:
return ret;
}
static int mx28_create_sd_image(int infd, int outfd)
{
int ret = -1;
uint32_t *buf;
int size;
off_t fsize;
ssize_t wr_size;
struct mx28_sd_config_block *cb;
fsize = lseek(infd, 0, SEEK_END);
lseek(infd, 0, SEEK_SET);
size = fsize + 512;
buf = malloc(size);
if (!buf) {
printf("Can not allocate output buffer of %d bytes\n", size);
goto err0;
}
ret = read(infd, (uint8_t *)buf + 512, fsize);
if (ret != fsize) {
ret = -1;
goto err1;
}
cb = (struct mx28_sd_config_block *)buf;
cb->signature = 0x00112233;
cb->primary_boot_tag = 0x1;
cb->secondary_boot_tag = 0x1;
cb->num_copies = 1;
cb->drv_info[0].chip_num = 0x0;
cb->drv_info[0].drive_type = 0x0;
cb->drv_info[0].tag = 0x1;
cb->drv_info[0].first_sector_number = sd_sector + 1;
cb->drv_info[0].sector_count = (size - 1) / 512;
wr_size = write(outfd, buf, size);
if (wr_size != size) {
ret = -1;
goto err1;
}
ret = 0;
err1:
free(buf);
err0:
return ret;
}
int parse_ops(int argc, char **argv)
{
int i;
int tmp;
char *end;
enum param {
PARAM_WRITE,
PARAM_OOB,
PARAM_ERASE,
PARAM_PART,
PARAM_SD,
PARAM_NAND
};
int type;
if (argc < 4)
return -1;
for (i = 1; i < argc; i++) {
if (!strncmp(argv[i], "-w", 2))
type = PARAM_WRITE;
else if (!strncmp(argv[i], "-o", 2))
type = PARAM_OOB;
else if (!strncmp(argv[i], "-e", 2))
type = PARAM_ERASE;
else if (!strncmp(argv[i], "-p", 2))
type = PARAM_PART;
else /* SD/MMC */
break;
tmp = strtol(argv[++i], &end, 10);
if (tmp % 2)
return -1;
if (tmp <= 0)
return -1;
if (type == PARAM_WRITE)
nand_writesize = tmp;
if (type == PARAM_OOB)
nand_oobsize = tmp;
if (type == PARAM_ERASE)
nand_erasesize = tmp;
if (type == PARAM_PART)
sd_sector = tmp;
}
if (strcmp(argv[i], "sd") && strcmp(argv[i], "nand"))
return -1;
if (i + 3 != argc)
return -1;
return i;
}
int main(int argc, char **argv)
{
int infd, outfd;
int ret = 0;
int offset;
offset = parse_ops(argc, argv);
if (offset < 0) {
usage();
ret = 1;
goto err1;
}
infd = open(argv[offset + 1], O_RDONLY);
if (infd < 0) {
printf("Input BootStream file can not be opened\n");
ret = 2;
goto err1;
}
outfd = open(argv[offset + 2], O_CREAT | O_TRUNC | O_WRONLY,
S_IRUSR | S_IWUSR);
if (outfd < 0) {
printf("Output file can not be created\n");
ret = 3;
goto err2;
}
if (!strcmp(argv[offset], "sd"))
ret = mx28_create_sd_image(infd, outfd);
else if (!strcmp(argv[offset], "nand"))
ret = mx28_create_nand_image(infd, outfd);
close(outfd);
err2:
close(infd);
err1:
return ret;
}

View file

@ -0,0 +1,38 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main (int argc, char *argv[])
{
int s, len, o, port = 6666;
char buf[512];
struct sockaddr_in addr;
socklen_t addr_len = sizeof addr;
if (argc > 1)
port = atoi (argv[1]);
s = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
o = 1;
len = 4;
setsockopt (3, SOL_SOCKET, SO_REUSEADDR, &o, len);
addr.sin_family = AF_INET;
addr.sin_port = htons (port);
addr.sin_addr.s_addr = INADDR_ANY; /* receive broadcasts */
bind (s, (struct sockaddr *) &addr, sizeof addr);
for (;;) {
len = recvfrom (s, buf, sizeof buf, 0, (struct sockaddr *) &addr, &addr_len);
if (len < 0)
break;
if (write (1, buf, len) != len)
fprintf(stderr, "WARNING: serial characters dropped\n");
}
return 0;
}

View file

@ -0,0 +1,59 @@
#!/bin/sh
usage() {
(
echo "Usage: $0 <board IP> [board port]"
echo ""
echo "If port is not specified, '6666' will be used"
[ -z "$*" ] && exit 0
echo ""
echo "ERROR: $*"
exit 1
) 1>&2
exit $?
}
while [ -n "$1" ] ; do
case $1 in
-h|--help) usage;;
--) break;;
-*) usage "Invalid option $1";;
*) break;;
esac
shift
done
ip=$1
port=${2:-6666}
if [ -z "${ip}" ] || [ -n "$3" ] ; then
usage "Invalid number of arguments"
fi
for nc in netcat nc ; do
type ${nc} >/dev/null 2>&1 && break
done
trap "stty icanon echo intr ^C" 0 2 3 5 10 13 15
echo "NOTE: the interrupt signal (normally ^C) has been remapped to ^T"
stty -icanon -echo intr ^T
(
if type ncb 2>/dev/null ; then
# see if ncb is in $PATH
exec ncb ${port}
elif [ -x ${0%/*}/ncb ] ; then
# maybe it's in the same dir as the netconsole script
exec ${0%/*}/ncb ${port}
else
# blah, just use regular netcat
while ${nc} -u -l -p ${port} < /dev/null ; do
:
done
fi
) &
pid=$!
${nc} -u ${ip} ${port}
kill ${pid} 2>/dev/null

View file

@ -0,0 +1,202 @@
/*
* Program for finding M & N values for DPLLs
* To be run on Host PC
*
* (C) Copyright 2010
* Texas Instruments, <www.ti.com>
*
* Aneesh V <aneesh@ti.com>
*
* 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 <stdlib.h>
#include <stdio.h>
typedef unsigned int u32;
#define MAX_N 127
/*
* get_m_n_optimized() - Finds optimal DPLL multiplier(M) and divider(N)
* values based on the reference frequency, required output frequency,
* maximum tolerance for output frequency etc.
*
* target_freq_khz - output frequency required in KHz
* ref_freq_khz - reference(input) frequency in KHz
* m - pointer to computed M value
* n - pointer to computed N value
* tolerance_khz - tolerance for the output frequency. When the algorithm
* succeeds in finding vialble M and N values the corresponding output
* frequency will be in the range:
* [target_freq_khz - tolerance_khz, target_freq_khz]
*
* Formula:
* Fdpll = (2 * M * Fref) / (N + 1)
*
* Considerations for lock-time:
* - Smaller the N, better lock-time, especially lock-time will be
* - For acceptable lock-times:
* Fref / (M + 1) >= 1 MHz
*
* Considerations for power:
* - The difference in power for different N values giving the same
* output is negligible. So, we optimize for lock-time
*
* Hard-constraints:
* - N can not be greater than 127(7 bit field for representing N)
*
* Usage:
* $ gcc clocks_get_m_n.c
* $ ./a.out
*/
int get_m_n_optimized(u32 target_freq_khz, u32 ref_freq_khz, u32 *M, u32 *N)
{
u32 freq = target_freq_khz;
u32 m_optimal, n_optimal, freq_optimal = 0, freq_old;
u32 m, n;
n = 1;
while (1) {
m = target_freq_khz / ref_freq_khz / 2 * n;
freq_old = 0;
while (1) {
freq = ref_freq_khz * 2 * m / n;
if (freq > target_freq_khz) {
freq = freq_old;
m--;
break;
}
m++;
freq_old = freq;
}
if (freq > freq_optimal) {
freq_optimal = freq;
m_optimal = m;
n_optimal = n;
}
n++;
if ((freq_optimal == target_freq_khz) ||
((ref_freq_khz / n) < 1000)) {
break;
}
}
n--;
*M = m_optimal;
*N = n_optimal - 1;
printf("ref %d m %d n %d target %d locked %d\n", ref_freq_khz,
m_optimal, n_optimal - 1, target_freq_khz, freq_optimal);
return 0;
}
void main(void)
{
u32 m, n;
printf("\nMPU - 2000000\n");
get_m_n_optimized(2000000, 12000, &m, &n);
get_m_n_optimized(2000000, 13000, &m, &n);
get_m_n_optimized(2000000, 16800, &m, &n);
get_m_n_optimized(2000000, 19200, &m, &n);
get_m_n_optimized(2000000, 26000, &m, &n);
get_m_n_optimized(2000000, 27000, &m, &n);
get_m_n_optimized(2000000, 38400, &m, &n);
printf("\nMPU - 1200000\n");
get_m_n_optimized(1200000, 12000, &m, &n);
get_m_n_optimized(1200000, 13000, &m, &n);
get_m_n_optimized(1200000, 16800, &m, &n);
get_m_n_optimized(1200000, 19200, &m, &n);
get_m_n_optimized(1200000, 26000, &m, &n);
get_m_n_optimized(1200000, 27000, &m, &n);
get_m_n_optimized(1200000, 38400, &m, &n);
printf("\nMPU - 1584000\n");
get_m_n_optimized(1584000, 12000, &m, &n);
get_m_n_optimized(1584000, 13000, &m, &n);
get_m_n_optimized(1584000, 16800, &m, &n);
get_m_n_optimized(1584000, 19200, &m, &n);
get_m_n_optimized(1584000, 26000, &m, &n);
get_m_n_optimized(1584000, 27000, &m, &n);
get_m_n_optimized(1584000, 38400, &m, &n);
printf("\nCore 1600000\n");
get_m_n_optimized(1600000, 12000, &m, &n);
get_m_n_optimized(1600000, 13000, &m, &n);
get_m_n_optimized(1600000, 16800, &m, &n);
get_m_n_optimized(1600000, 19200, &m, &n);
get_m_n_optimized(1600000, 26000, &m, &n);
get_m_n_optimized(1600000, 27000, &m, &n);
get_m_n_optimized(1600000, 38400, &m, &n);
printf("\nPER 1536000\n");
get_m_n_optimized(1536000, 12000, &m, &n);
get_m_n_optimized(1536000, 13000, &m, &n);
get_m_n_optimized(1536000, 16800, &m, &n);
get_m_n_optimized(1536000, 19200, &m, &n);
get_m_n_optimized(1536000, 26000, &m, &n);
get_m_n_optimized(1536000, 27000, &m, &n);
get_m_n_optimized(1536000, 38400, &m, &n);
printf("\nIVA 1862000\n");
get_m_n_optimized(1862000, 12000, &m, &n);
get_m_n_optimized(1862000, 13000, &m, &n);
get_m_n_optimized(1862000, 16800, &m, &n);
get_m_n_optimized(1862000, 19200, &m, &n);
get_m_n_optimized(1862000, 26000, &m, &n);
get_m_n_optimized(1862000, 27000, &m, &n);
get_m_n_optimized(1862000, 38400, &m, &n);
printf("\nIVA Nitro - 1290000\n");
get_m_n_optimized(1290000, 12000, &m, &n);
get_m_n_optimized(1290000, 13000, &m, &n);
get_m_n_optimized(1290000, 16800, &m, &n);
get_m_n_optimized(1290000, 19200, &m, &n);
get_m_n_optimized(1290000, 26000, &m, &n);
get_m_n_optimized(1290000, 27000, &m, &n);
get_m_n_optimized(1290000, 38400, &m, &n);
printf("\nABE 196608 sys clk\n");
get_m_n_optimized(196608, 12000, &m, &n);
get_m_n_optimized(196608, 13000, &m, &n);
get_m_n_optimized(196608, 16800, &m, &n);
get_m_n_optimized(196608, 19200, &m, &n);
get_m_n_optimized(196608, 26000, &m, &n);
get_m_n_optimized(196608, 27000, &m, &n);
get_m_n_optimized(196608, 38400, &m, &n);
printf("\nABE 196608 32K\n");
get_m_n_optimized(196608000/4, 32768, &m, &n);
printf("\nUSB 1920000\n");
get_m_n_optimized(1920000, 12000, &m, &n);
get_m_n_optimized(1920000, 13000, &m, &n);
get_m_n_optimized(1920000, 16800, &m, &n);
get_m_n_optimized(1920000, 19200, &m, &n);
get_m_n_optimized(1920000, 26000, &m, &n);
get_m_n_optimized(1920000, 27000, &m, &n);
get_m_n_optimized(1920000, 38400, &m, &n);
printf("\nCore ES1 1523712\n");
get_m_n_optimized(1524000, 12000, &m, &n);
get_m_n_optimized(1524000, 13000, &m, &n);
get_m_n_optimized(1524000, 16800, &m, &n);
get_m_n_optimized(1524000, 19200, &m, &n);
get_m_n_optimized(1524000, 26000, &m, &n);
get_m_n_optimized(1524000, 27000, &m, &n);
/* exact recommendation for SDPs */
get_m_n_optimized(1523712, 38400, &m, &n);
}

View file

@ -0,0 +1,223 @@
/*
* (C) Copyright 2010
* Linaro LTD, www.linaro.org
* Author: John Rigby <john.rigby@linaro.org>
* Based on TI's signGP.c
*
* (C) Copyright 2009
* Stefano Babic, DENX Software Engineering, sbabic@denx.de.
*
* (C) Copyright 2008
* Marvell Semiconductor <www.marvell.com>
* Written-by: Prafulla Wadaskar <prafulla@marvell.com>
*
* 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
*/
/* Required to obtain the getline prototype from stdio.h */
#define _GNU_SOURCE
#include "imagetool.h"
#include <image.h>
#include "omapimage.h"
/* Header size is CH header rounded up to 512 bytes plus GP header */
#define OMAP_CH_HDR_SIZE 512
#define OMAP_GP_HDR_SIZE (sizeof(struct gp_header))
#define OMAP_FILE_HDR_SIZE (OMAP_CH_HDR_SIZE+OMAP_GP_HDR_SIZE)
static uint8_t omapimage_header[OMAP_FILE_HDR_SIZE];
static int omapimage_check_image_types(uint8_t type)
{
if (type == IH_TYPE_OMAPIMAGE)
return EXIT_SUCCESS;
else {
return EXIT_FAILURE;
}
}
/*
* Only the simplest image type is currently supported:
* TOC pointing to CHSETTINGS
* TOC terminator
* CHSETTINGS
*
* padding to OMAP_CH_HDR_SIZE bytes
*
* gp header
* size
* load_addr
*/
static int valid_gph_size(uint32_t size)
{
return size;
}
static int valid_gph_load_addr(uint32_t load_addr)
{
return load_addr;
}
static int omapimage_verify_header(unsigned char *ptr, int image_size,
struct image_tool_params *params)
{
struct ch_toc *toc = (struct ch_toc *)ptr;
struct gp_header *gph = (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE);
uint32_t offset, size;
while (toc->section_offset != 0xffffffff
&& toc->section_size != 0xffffffff) {
offset = toc->section_offset;
size = toc->section_size;
if (!offset || !size)
return -1;
if (offset >= OMAP_CH_HDR_SIZE ||
offset+size >= OMAP_CH_HDR_SIZE)
return -1;
toc++;
}
if (!valid_gph_size(gph->size))
return -1;
if (!valid_gph_load_addr(gph->load_addr))
return -1;
return 0;
}
static void omapimage_print_section(struct ch_settings *chs)
{
const char *section_name;
if (chs->section_key)
section_name = "CHSETTINGS";
else
section_name = "UNKNOWNKEY";
printf("%s (%x) "
"valid:%x "
"version:%x "
"reserved:%x "
"flags:%x\n",
section_name,
chs->section_key,
chs->valid,
chs->version,
chs->reserved,
chs->flags);
}
static void omapimage_print_header(const void *ptr)
{
const struct ch_toc *toc = (struct ch_toc *)ptr;
const struct gp_header *gph =
(struct gp_header *)(ptr+OMAP_CH_HDR_SIZE);
uint32_t offset, size;
while (toc->section_offset != 0xffffffff
&& toc->section_size != 0xffffffff) {
offset = toc->section_offset;
size = toc->section_size;
if (offset >= OMAP_CH_HDR_SIZE ||
offset+size >= OMAP_CH_HDR_SIZE)
exit(EXIT_FAILURE);
printf("Section %s offset %x length %x\n",
toc->section_name,
toc->section_offset,
toc->section_size);
omapimage_print_section((struct ch_settings *)(ptr+offset));
toc++;
}
if (!valid_gph_size(gph->size)) {
fprintf(stderr,
"Error: invalid image size %x\n",
gph->size);
exit(EXIT_FAILURE);
}
if (!valid_gph_load_addr(gph->load_addr)) {
fprintf(stderr,
"Error: invalid image load address %x\n",
gph->size);
exit(EXIT_FAILURE);
}
printf("GP Header: Size %x LoadAddr %x\n",
gph->size, gph->load_addr);
}
static int toc_offset(void *hdr, void *member)
{
return member - hdr;
}
static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd,
struct image_tool_params *params)
{
struct ch_toc *toc = (struct ch_toc *)ptr;
struct ch_settings *chs = (struct ch_settings *)
(ptr + 2 * sizeof(*toc));
struct gp_header *gph = (struct gp_header *)(ptr + OMAP_CH_HDR_SIZE);
toc->section_offset = toc_offset(ptr, chs);
toc->section_size = sizeof(struct ch_settings);
strcpy((char *)toc->section_name, "CHSETTINGS");
chs->section_key = KEY_CHSETTINGS;
chs->valid = 0;
chs->version = 1;
chs->reserved = 0;
chs->flags = 0;
toc++;
memset(toc, 0xff, sizeof(*toc));
gph->size = sbuf->st_size - OMAP_FILE_HDR_SIZE;
gph->load_addr = params->addr;
}
int omapimage_check_params(struct image_tool_params *params)
{
return (params->dflag && (params->fflag || params->lflag)) ||
(params->fflag && (params->dflag || params->lflag)) ||
(params->lflag && (params->dflag || params->fflag));
}
/*
* omapimage parameters
*/
static struct image_type_params omapimage_params = {
.name = "TI OMAP CH/GP Boot Image support",
.header_size = OMAP_FILE_HDR_SIZE,
.hdr = (void *)&omapimage_header,
.check_image_type = omapimage_check_image_types,
.verify_header = omapimage_verify_header,
.print_header = omapimage_print_header,
.set_header = omapimage_set_header,
.check_params = omapimage_check_params,
};
void init_omap_image_type(void)
{
register_image_type(&omapimage_params);
}

View file

@ -0,0 +1,50 @@
/*
* (C) Copyright 2010
* Linaro LTD, www.linaro.org
* Author John Rigby <john.rigby@linaro.org>
* Based on TI's signGP.c
*
* 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 _OMAPIMAGE_H_
#define _OMAPIMAGE_H_
struct ch_toc {
uint32_t section_offset;
uint32_t section_size;
uint8_t unused[12];
uint8_t section_name[12];
};
struct ch_settings {
uint32_t section_key;
uint8_t valid;
uint8_t version;
uint16_t reserved;
uint32_t flags;
};
struct gp_header {
uint32_t size;
uint32_t load_addr;
};
#define KEY_CHSETTINGS 0xC0C0C0C1
#endif /* _OMAPIMAGE_H_ */

View file

@ -0,0 +1,28 @@
/*
* Copyright 2009 Extreme Engineering Solutions, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this software; if not, write to the
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* Include additional files required for supporting different operating systems
*/
#include "compiler.h"
#ifdef __MINGW32__
#include "mingw_support.c"
#endif
#if defined(__APPLE__) && __DARWIN_C_LEVEL < 200809L
#include "getline.c"
#endif

View file

@ -0,0 +1,35 @@
/*
* Copyright 2009 Extreme Engineering Solutions, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this software; if not, write to the
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __OS_SUPPORT_H_
#define __OS_SUPPORT_H_
#include "compiler.h"
/*
* Include additional files required for supporting different operating systems
*/
#ifdef __MINGW32__
#include "mingw_support.h"
#endif
#if defined(__APPLE__) && __DARWIN_C_LEVEL < 200809L
#include "getline.h"
#endif
#endif /* __OS_SUPPORT_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
*.pyc

View file

@ -0,0 +1,411 @@
# Copyright (c) 2011 The Chromium OS Authors.
#
# 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
#
What is this?
=============
This tool is a Python script which:
- Creates patch directly from your branch
- Cleans them up by removing unwanted tags
- Inserts a cover letter with change lists
- Runs the patches through checkpatch.pl and its own checks
- Optionally emails them out to selected people
It is intended to automate patch creation and make it a less
error-prone process. It is useful for U-Boot and Linux work so far,
since it uses the checkpatch.pl script.
It is configured almost entirely by tags it finds in your commits.
This means that you can work on a number of different branches at
once, and keep the settings with each branch rather than having to
git format-patch, git send-email, etc. with the correct parameters
each time. So for example if you put:
Series-to: fred.blogs@napier.co.nz
in one of your commits, the series will be sent there.
How to use this tool
====================
This tool requires a certain way of working:
- Maintain a number of branches, one for each patch series you are
working on
- Add tags into the commits within each branch to indicate where the
series should be sent, cover letter, version, etc. Most of these are
normally in the top commit so it is easy to change them with 'git
commit --amend'
- Each branch tracks the upstream branch, so that this script can
automatically determine the number of commits in it (optional)
- Check out a branch, and run this script to create and send out your
patches. Weeks later, change the patches and repeat, knowing that you
will get a consistent result each time.
How to configure it
===================
For most cases patman will locate and use the file 'doc/git-mailrc' in
your U-Boot directory. This contains most of the aliases you will need.
During the first run patman creates a config file for you by taking the default
user name and email address from the global .gitconfig file.
To add your own, create a file ~/.patman like this:
>>>>
# patman alias file
[alias]
me: Simon Glass <sjg@chromium.org>
u-boot: U-Boot Mailing List <u-boot@lists.denx.de>
wolfgang: Wolfgang Denk <wd@denx.de>
others: Mike Frysinger <vapier@gentoo.org>, Fred Bloggs <f.bloggs@napier.net>
<<<<
Aliases are recursive.
The checkpatch.pl in the U-Boot tools/ subdirectory will be located and
used. Failing that you can put it into your path or ~/bin/checkpatch.pl
How to run it
=============
First do a dry run:
$ ./tools/patman/patman -n
If it can't detect the upstream branch, try telling it how many patches
there are in your series:
$ ./tools/patman/patman -n -c5
This will create patch files in your current directory and tell you who
it is thinking of sending them to. Take a look at the patch files.
$ ./tools/patman/patman -n -c5 -s1
Similar to the above, but skip the first commit and take the next 5. This
is useful if your top commit is for setting up testing.
How to add tags
===============
To make this script useful you must add tags like the following into any
commit. Most can only appear once in the whole series.
Series-to: email / alias
Email address / alias to send patch series to (you can add this
multiple times)
Series-cc: email / alias, ...
Email address / alias to Cc patch series to (you can add this
multiple times)
Series-version: n
Sets the version number of this patch series
Series-prefix: prefix
Sets the subject prefix. Normally empty but it can be RFC for
RFC patches, or RESEND if you are being ignored.
Cover-letter:
This is the patch set title
blah blah
more blah blah
END
Sets the cover letter contents for the series. The first line
will become the subject of the cover letter
Series-notes:
blah blah
blah blah
more blah blah
END
Sets some notes for the patch series, which you don't want in
the commit messages, but do want to send, The notes are joined
together and put after the cover letter. Can appear multiple
times.
Signed-off-by: Their Name <email>
A sign-off is added automatically to your patches (this is
probably a bug). If you put this tag in your patches, it will
override the default signoff that patman automatically adds.
Tested-by: Their Name <email>
Acked-by: Their Name <email>
These indicate that someone has acked or tested your patch.
When you get this reply on the mailing list, you can add this
tag to the relevant commit and the script will include it when
you send out the next version. If 'Tested-by:' is set to
yourself, it will be removed. No one will believe you.
Series-changes: n
- Guinea pig moved into its cage
- Other changes ending with a blank line
<blank line>
This can appear in any commit. It lists the changes for a
particular version n of that commit. The change list is
created based on this information. Each commit gets its own
change list and also the whole thing is repeated in the cover
letter (where duplicate change lines are merged).
By adding your change lists into your commits it is easier to
keep track of what happened. When you amend a commit, remember
to update the log there and then, knowing that the script will
do the rest.
Cc: Their Name <email>
This copies a single patch to another email address.
Various other tags are silently removed, like these Chrome OS and
Gerrit tags:
BUG=...
TEST=...
Change-Id:
Review URL:
Reviewed-on:
Reviewed-by:
Exercise for the reader: Try adding some tags to one of your current
patch series and see how the patches turn out.
Where Patches Are Sent
======================
Once the patches are created, patman sends them using git send-email. The
whole series is sent to the recipients in Series-to: and Series-cc.
You can Cc individual patches to other people with the Cc: tag. Tags in the
subject are also picked up to Cc patches. For example, a commit like this:
>>>>
commit 10212537b85ff9b6e09c82045127522c0f0db981
Author: Mike Frysinger <vapier@gentoo.org>
Date: Mon Nov 7 23:18:44 2011 -0500
x86: arm: add a git mailrc file for maintainers
This should make sending out e-mails to the right people easier.
Cc: sandbox, mikef, ag
Cc: afleming
<<<<
will create a patch which is copied to x86, arm, sandbox, mikef, ag and
afleming.
Example Work Flow
=================
The basic workflow is to create your commits, add some tags to the top
commit, and type 'patman' to check and send them.
Here is an example workflow for a series of 4 patches. Let's say you have
these rather contrived patches in the following order in branch us-cmd in
your tree where 'us' means your upstreaming activity (newest to oldest as
output by git log --oneline):
7c7909c wip
89234f5 Don't include standard parser if hush is used
8d640a7 mmc: sparc: Stop using builtin_run_command()
0c859a9 Rename run_command2() to run_command()
a74443f sandbox: Rename run_command() to builtin_run_command()
The first patch is some test things that enable your code to be compiled,
but that you don't want to submit because there is an existing patch for it
on the list. So you can tell patman to create and check some patches
(skipping the first patch) with:
patman -s1 -n
If you want to do all of them including the work-in-progress one, then
(if you are tracking an upstream branch):
patman -n
Let's say that patman reports an error in the second patch. Then:
git rebase -i HEAD~6
<change 'pick' to 'edit' in 89234f5>
<use editor to make code changes>
git add -u
git rebase --continue
Now you have an updated patch series. To check it:
patman -s1 -n
Let's say it is now clean and you want to send it. Now you need to set up
the destination. So amend the top commit with:
git commit --amend
Use your editor to add some tags, so that the whole commit message is:
The current run_command() is really only one of the options, with
hush providing the other. It really shouldn't be called directly
in case the hush parser is bring used, so rename this function to
better explain its purpose.
Series-to: u-boot
Series-cc: bfin, marex
Series-prefix: RFC
Cover-letter:
Unified command execution in one place
At present two parsers have similar code to execute commands. Also
cmd_usage() is called all over the place. This series adds a single
function which processes commands called cmd_process().
END
Change-Id: Ica71a14c1f0ecb5650f771a32fecb8d2eb9d8a17
You want this to be an RFC and Cc the whole series to the bfin alias and
to Marek. Two of the patches have tags (those are the bits at the front of
the subject that say mmc: sparc: and sandbox:), so 8d640a7 will be Cc'd to
mmc and sparc, and the last one to sandbox.
Now to send the patches, take off the -n flag:
patman -s1
The patches will be created, shown in your editor, and then sent along with
the cover letter. Note that patman's tags are automatically removed so that
people on the list don't see your secret info.
Of course patches often attract comments and you need to make some updates.
Let's say one person sent comments and you get an Acked-by: on one patch.
Also, the patch on the list that you were waiting for has been merged,
so you can drop your wip commit. So you resync with upstream:
git fetch origin (or whatever upstream is called)
git rebase origin/master
and use git rebase -i to edit the commits, dropping the wip one. You add
the ack tag to one commit:
Acked-by: Heiko Schocher <hs@denx.de>
update the Series-cc: in the top commit:
Series-cc: bfin, marex, Heiko Schocher <hs@denx.de>
and remove the Series-prefix: tag since it it isn't an RFC any more. The
series is now version two, so the series info in the top commit looks like
this:
Series-to: u-boot
Series-cc: bfin, marex, Heiko Schocher <hs@denx.de>
Series-version: 2
Cover-letter:
...
Finally, you need to add a change log to the two commits you changed. You
add change logs to each individual commit where the changes happened, like
this:
Series-changes: 2
- Updated the command decoder to reduce code size
- Wound the torque propounder up a little more
(note the blank line at the end of the list)
When you run patman it will collect all the change logs from the different
commits and combine them into the cover letter, if you have one. So finally
you have a new series of commits:
faeb973 Don't include standard parser if hush is used
1b2f2fe mmc: sparc: Stop using builtin_run_command()
cfbe330 Rename run_command2() to run_command()
0682677 sandbox: Rename run_command() to builtin_run_command()
so to send them:
patman
and it will create and send the version 2 series.
General points:
1. When you change back to the us-cmd branch days or weeks later all your
information is still there, safely stored in the commits. You don't need
to remember what version you are up to, who you sent the last lot of patches
to, or anything about the change logs.
2. If you put tags in the subject, patman will Cc the maintainers
automatically in many cases.
3. If you want to keep the commits from each series you sent so that you can
compare change and see what you did, you can either create a new branch for
each version, or just tag the branch before you start changing it:
git tag sent/us-cmd-rfc
...later...
git tag sent/us-cmd-v2
4. If you want to modify the patches a little before sending, you can do
this in your editor, but be careful!
5. If you want to run git send-email yourself, use the -n flag which will
print out the command line patman would have used.
6. It is a good idea to add the change log info as you change the commit,
not later when you can't remember which patch you changed. You can always
go back and change or remove logs from commits.
Other thoughts
==============
This script has been split into sensible files but still needs work.
Most of these are indicated by a TODO in the code.
It would be nice if this could handle the In-reply-to side of things.
The tests are incomplete, as is customary. Use the -t flag to run them,
and make sure you are in the tools/scripts/patman directory first:
$ cd /path/to/u-boot
$ cd tools/scripts/patman
$ patman -t
Error handling doesn't always produce friendly error messages - e.g.
putting an incorrect tag in a commit may provide a confusing message.
There might be a few other features not mentioned in this README. They
might be bugs. In particular, tags are case sensitive which is probably
a bad thing.
Simon Glass <sjg@chromium.org>
v1, v2, 19-Oct-11
revised v3 24-Nov-11

View file

@ -0,0 +1,161 @@
# Copyright (c) 2011 The Chromium OS Authors.
#
# 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
#
import command
import gitutil
import os
import re
import terminal
def FindCheckPatch():
try_list = [
os.getcwd(),
os.path.join(os.getcwd(), '..', '..'),
os.path.join(gitutil.GetTopLevel(), 'tools'),
'%s/bin' % os.getenv('HOME'),
]
# Look in current dir
for path in try_list:
fname = os.path.join(path, 'checkpatch.pl')
if os.path.isfile(fname):
return fname
# Look upwwards for a Chrome OS tree
while not os.path.ismount(path):
fname = os.path.join(path, 'src', 'third_party', 'kernel', 'files',
'scripts', 'checkpatch.pl')
if os.path.isfile(fname):
return fname
path = os.path.dirname(path)
print 'Could not find checkpatch.pl'
return None
def CheckPatch(fname, verbose=False):
"""Run checkpatch.pl on a file.
Returns:
4-tuple containing:
result: False=failure, True=ok
problems: List of problems, each a dict:
'type'; error or warning
'msg': text message
'file' : filename
'line': line number
lines: Number of lines
"""
result = False
error_count, warning_count, lines = 0, 0, 0
problems = []
chk = FindCheckPatch()
if not chk:
raise OSError, ('Cannot find checkpatch.pl - please put it in your ' +
'~/bin directory')
item = {}
stdout = command.Output(chk, '--no-tree', fname)
#pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE)
#stdout, stderr = pipe.communicate()
# total: 0 errors, 0 warnings, 159 lines checked
re_stats = re.compile('total: (\\d+) errors, (\d+) warnings, (\d+)')
re_ok = re.compile('.*has no obvious style problems')
re_bad = re.compile('.*has style problems, please review')
re_error = re.compile('ERROR: (.*)')
re_warning = re.compile('WARNING: (.*)')
re_file = re.compile('#\d+: FILE: ([^:]*):(\d+):')
for line in stdout.splitlines():
if verbose:
print line
# A blank line indicates the end of a message
if not line and item:
problems.append(item)
item = {}
match = re_stats.match(line)
if match:
error_count = int(match.group(1))
warning_count = int(match.group(2))
lines = int(match.group(3))
elif re_ok.match(line):
result = True
elif re_bad.match(line):
result = False
match = re_error.match(line)
if match:
item['msg'] = match.group(1)
item['type'] = 'error'
match = re_warning.match(line)
if match:
item['msg'] = match.group(1)
item['type'] = 'warning'
match = re_file.match(line)
if match:
item['file'] = match.group(1)
item['line'] = int(match.group(2))
return result, problems, error_count, warning_count, lines, stdout
def GetWarningMsg(col, msg_type, fname, line, msg):
'''Create a message for a given file/line
Args:
msg_type: Message type ('error' or 'warning')
fname: Filename which reports the problem
line: Line number where it was noticed
msg: Message to report
'''
if msg_type == 'warning':
msg_type = col.Color(col.YELLOW, msg_type)
elif msg_type == 'error':
msg_type = col.Color(col.RED, msg_type)
return '%s: %s,%d: %s' % (msg_type, fname, line, msg)
def CheckPatches(verbose, args):
'''Run the checkpatch.pl script on each patch'''
error_count = 0
warning_count = 0
col = terminal.Color()
for fname in args:
ok, problems, errors, warnings, lines, stdout = CheckPatch(fname,
verbose)
if not ok:
error_count += errors
warning_count += warnings
print '%d errors, %d warnings for %s:' % (errors,
warnings, fname)
if len(problems) != error_count + warning_count:
print "Internal error: some problems lost"
for item in problems:
print GetWarningMsg(col, item['type'], item['file'],
item['line'], item['msg'])
#print stdout
if error_count != 0 or warning_count != 0:
str = 'checkpatch.pl found %d error(s), %d warning(s)' % (
error_count, warning_count)
color = col.GREEN
if warning_count:
color = col.YELLOW
if error_count:
color = col.RED
print col.Color(color, str)
return False
return True

Some files were not shown because too many files have changed in this diff Show more