All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marek Vasut <marex@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v3 8/8] palmtreo680: add utility that writes u-boot to flash
Date: Sun, 14 Apr 2013 19:38:18 +0200	[thread overview]
Message-ID: <201304141938.18234.marex@denx.de> (raw)
In-Reply-To: <1365793160-18247-9-git-send-email-mikedunn@newsguy.com>

Dear Mike Dunn,

> This adds a userspace linux utility that writes the u-boot image to an mtd
> partition on the docg4 nand flash.
> 
> A special utility is required to do this because u-boot is partially loaded
> by an initial program loader (IPL) that is permanently programmed to the
> boot region of the flash.  This IPL expects the image to be written in a
> unique format. The characteristics of this format can be summarized as
> follows: - Flash blocks to be loaded must have a magic number in the oob
> bytes of the first page of the block.
>   - Each page must be written redundantly in the subsequent page.
>   - The integrated flash controller's "reliable mode" is used, requiring
> that alternate 2k regions (4 pages) are skipped when writing.
> For these reasons, a u-boot image can not be written using nandwrite from
> mtd-utils.
> 
> Signed-off-by: Mike Dunn <mikedunn@newsguy.com>
> ---
> Changelog:
>   v3: new patch; split off from patch 7 in v2 of patchset
> 
>  tools/palmtreo680/flash_u-boot.c |  167
> ++++++++++++++++++++++++++++++++++++++ 1 files changed, 167 insertions(+),
> 0 deletions(-)
>  create mode 100644 tools/palmtreo680/flash_u-boot.c
> 
> diff --git a/tools/palmtreo680/flash_u-boot.c
> b/tools/palmtreo680/flash_u-boot.c new file mode 100644
> index 0000000..97b336f
> --- /dev/null
> +++ b/tools/palmtreo680/flash_u-boot.c
> @@ -0,0 +1,167 @@
> +/*
> + * Copyright (C) 2013 Mike Dunn <mikedunn@newsguy.com>
> + *
> + * This file is released under the terms of GPL v2 and any later version.
> + * See the file COPYING in the root directory of the source tree for
> details. + *
> + *
> + * This is a userspace Linux utility that, when run on the Treo 680, will
> + * program u-boot to flash.  The docg4 driver *must* be loaded with the
> + * reliable_mode and ignore_badblocks parameters enabled:
> + *
> + *        modprobe docg4 ignore_badblocks=1 reliable_mode=1
> + *
> + * This utility writes the concatenated spl + u-boot image to the start of
> the + * mtd device in the format expected by the IPL/SPL.  The image file
> and mtd + * device node are passed to the utility as arguments.  The
> blocks must have + * been erased beforehand.
> + *
> + * When you compile this, note that it links to libmtd from mtd-utils, so
> ensure + * that your include and lib paths include this.
> + */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
> +#include <string.h>
> +#include <sys/types.h>
> +#include <unistd.h>
> +#include <errno.h>
> +#include <mtd/mtd-user.h>
> +#include "libmtd.h"
> +
> +#define RELIABLE_BLOCKSIZE  0x10000 /* block capacity in reliable mode */
> +#define STANDARD_BLOCKSIZE  0x40000 /* block capacity in normal mode */
> +#define PAGESIZE 512
> +#define PAGES_PER_BLOCK 512
> +#define OOBSIZE 7		/* available to user (16 total) */
> +
> +uint8_t ff_oob[OOBSIZE] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
> +
> +/* this is the magic number the IPL looks for (ASCII "BIPO") */
> +uint8_t page0_oob[OOBSIZE] = {'B', 'I', 'P', 'O', 0xff, 0xff, 0xff};
> +
> +int main(int argc, char * const argv[])
> +{
> +	int devfd, datafd, num_blocks, block;
> +	off_t file_size;
> +	libmtd_t mtd_desc;
> +	struct mtd_dev_info devinfo;
> +	uint8_t *blockbuf;
> +	char response[8];
> +
> +	if (argc != 3) {
> +		printf("usage: %s <image file> <mtd dev node>\n", argv[0]);
> +		exit(-1);

Use proper errno and "return" as you're returning from main() anyway.

> +	}
> +
> +	mtd_desc = libmtd_open();
> +	if (mtd_desc == NULL) {
> +		fprintf(stderr, "can't initialize libmtd\n");
> +		exit(-1);
> +	}
> +
> +	/* open the spl image file and mtd device */
> +	datafd = open(argv[1], O_RDONLY);
> +	if (datafd == -1) {
> +		perror(argv[1]);
> +		exit(-1);
> +	}
> +	devfd = open(argv[2], O_WRONLY);
> +	if (devfd == -1) {
> +		perror(argv[2]);
> +		exit(-1);
> +	}
> +	if (mtd_get_dev_info(mtd_desc, argv[2], &devinfo) < 0) {
> +		fprintf(stderr, "mtd_get_dev_info failed\n");
> +		exit(-1);
> +	}
> +
> +	/* determine the number of blocks needed by the image */
> +	file_size = lseek(datafd, 0, SEEK_END);
> +	if (file_size == (off_t)-1) {
> +		perror("lseek");
> +		exit(-1);
> +	}
> +	num_blocks = (file_size + RELIABLE_BLOCKSIZE - 1) / RELIABLE_BLOCKSIZE;
> +	file_size = lseek(datafd, 0, SEEK_SET);
> +	if (file_size == (off_t)-1) {
> +		perror("lseek");
> +		exit(-1);
> +	}
> +	printf("The mtd partition contains %d blocks\n", devinfo.eb_cnt);
> +	printf("U-boot will occupy %d blocks\n", num_blocks);
> +	if (num_blocks > devinfo.eb_cnt) {
> +		fprintf(stderr, "Insufficient blocks on partition\n");
> +		exit(-1);
> +	}
> +
> +	printf("IMPORTANT: These blocks must be in an erased state!\n");
> +	printf("Do you want to proceed?\n");
> +	scanf("%s", response);
> +	if ((response[0] != 'y') && (response[0] != 'Y')) {
> +		printf("Exiting\n");
> +		close(devfd);
> +		close(datafd);
> +		exit(-1);
> +	}
> +
> +	blockbuf = malloc(RELIABLE_BLOCKSIZE);

Do you not want to use some calloc() here to make sure the "blockbuf" is zeroed?

> +	if (blockbuf == NULL) {
> +		perror("malloc");
> +		exit(-1);
> +	}
> +
> +	for (block = 0; block < num_blocks; block++) {
> +		int ofs, page;
> +		ssize_t read_ret;
> +		uint8_t *pagebuf = blockbuf, *buf = blockbuf;
> +		uint8_t *oobbuf = page0_oob; /* magic num in oob of 1st page */
> +		size_t len = RELIABLE_BLOCKSIZE;
> +		int ret;
> +
> +		/* read data for one block from file */
> +		while (len != 0 && (read_ret = read(datafd, buf, len)) != 0) {

Uh, this really might be a candidate for IOCCC, split this please ...

> +			if (read_ret == -1) {
> +				if (errno == EINTR)
> +					continue;
> +				perror("read");
> +				exit(-1);
> +			}
> +			len -= read_ret;
> +			buf += read_ret;
> +		}
> +
> +		printf("Block %d: writing\r", block + 1);
> +		fflush(stdout);
> +
> +		for (page = 0, ofs = 0;
> +		     page < PAGES_PER_BLOCK;
> +		     page++, ofs += PAGESIZE) {
> +			if (page & 0x04)  /* Odd-numbered 2k page */
> +				continue; /* skipped in reliable mode */
> +
> +			ret = mtd_write(mtd_desc, &devinfo, devfd, block, ofs,
> +					pagebuf, PAGESIZE, oobbuf, OOBSIZE,
> +					MTD_OPS_PLACE_OOB);
> +			if (ret) {
> +				fprintf(stderr,
> +					"\nmtd_write returned %d on block %d, 
ofs %x\n",
> +					ret, block + 1, ofs);
> +				exit(-1);
> +			}
> +			oobbuf = ff_oob;  /* oob for subsequent pages */
> +
> +			if (page & 0x01)  /* odd-numbered subpage */
> +				pagebuf += PAGESIZE;
> +		}
> +	}
> +
> +	printf("\nDone\n");
> +
> +	close(devfd);
> +	close(datafd);
> +	free(blockbuf);
> +	return 0;
> +}

  reply	other threads:[~2013-04-14 17:38 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-12 18:59 [U-Boot] [PATCH v3 0/8] palm treo 680 smartphone board support Mike Dunn
2013-04-12 18:59 ` [U-Boot] [PATCH v3 1/8] pxa_lcd: add the ACX544AKN lcd device Mike Dunn
2013-04-12 18:59 ` [U-Boot] [PATCH v3 2/8] pxa_lcd: make lcd_enable() a weak pointer Mike Dunn
2013-04-12 18:59 ` [U-Boot] [PATCH v3 3/8] pxa27x_udc: remove call to unimplemented set_GPIO_mode() Mike Dunn
2013-04-12 18:59 ` [U-Boot] [PATCH v3 4/8] arm: bootm: call udc_disable() before booting linux Mike Dunn
2013-04-14 17:26   ` Marek Vasut
2013-04-14 19:22   ` Albert ARIBAUD
2013-04-14 20:12     ` Marek Vasut
2013-04-15 12:45       ` Tom Rini
2013-04-15 12:56         ` Albert ARIBAUD
2013-04-15 13:08           ` Marek Vasut
2013-04-12 18:59 ` [U-Boot] [PATCH 5/8] lib: import bitrev library from the linux kernel Mike Dunn
2013-04-12 18:59 ` [U-Boot] [PATCH v3 6/8] mtd: nand: add driver for diskonchip g4 nand flash Mike Dunn
2013-04-12 19:21   ` Scott Wood
2013-04-13 14:42     ` Marek Vasut
2013-04-15 17:51       ` Scott Wood
2013-04-12 18:59 ` [U-Boot] [PATCH v3 7/8] add support for palm treo 680 board Mike Dunn
2013-04-14 17:34   ` Marek Vasut
2013-04-15 17:34     ` Mike Dunn
2013-04-15 18:33       ` Marek Vasut
2013-04-15 19:11         ` Mike Dunn
2013-04-12 18:59 ` [U-Boot] [PATCH v3 8/8] palmtreo680: add utility that writes u-boot to flash Mike Dunn
2013-04-14 17:38   ` Marek Vasut [this message]
2013-04-16 17:50     ` Mike Dunn
2013-04-16 18:06       ` Marek Vasut

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201304141938.18234.marex@denx.de \
    --to=marex@denx.de \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.