Hi,

I have add the possibility to automatic update entire flash using a USB pendrive.

To make it, need the following steps:
1) insert usb pendrive. In pendrive must be present these files: install.dat and the files we want to copy.
2) from uboot console: => usb_system_autoupdate
3) the system update start, reading information from install.dat file.

The install.dat file raws has this syntax:
<file_type> "<file_name>" <star_flash_addr_partition> <end_flash_addr_partition>

file_type values: kernel, uboot, fdt, rootfs.

In attachment there's an example of install.dat and the source code.

Now using it on my system (mpc5200, uboot_1.3.1) but there's a problem that I can't fix: if try to update uboot partition, it freeze in line 211 when call do_flerase().

debugging I can see that it freeze in:
cmd_flash.c
434:     printf ("Erased %d sectors\n", erased);
after uboot partition erasing.


Can you help me?


Thanks in advance.
Matteo Facchinetti







/*
 * (C) Copyright 2008
 * Matteo Facchinetti, Sirius Electronic Systems S.R.L., [EMAIL PROTECTED]
 *
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <command.h>
#include <usb.h>
#include <fat.h>

#define INSTALL_DAT_FILENAME "install.dat"
#define INSTALL_DAT_PTR (char *)0x100000
#define MAX_FILE_TO_UPDATE 6


struct install_dat {
	int type;
	char file_name[255];
	unsigned long file_size;
	unsigned long flash_s_address;
	unsigned long flash_e_address;
	unsigned long mem_address;
};


struct install_dat files_to_update[MAX_FILE_TO_UPDATE];

char *param_fat_fsload[] = {"fatload", "usb", "0", "100000", INSTALL_DAT_FILENAME};
char *param_protect_off[] = {"protect", "off", "all"};
char *param_flerase[] = {"erase", "ff000000", "ffffffff"};	
char *param_memcp[] = {"cp.b", "100000", "ff000000", "$(filesize)"};	


static void print_cmd(char *param_cmd[], int num_param) {
	int i;
	
	for (i=0; i<num_param; i++) printf("%s ", param_cmd[i]);
	printf("\n");
}


static unsigned long read_ex_env(char *env) {
	char *ptr_s, *ptr_e;

	ptr_s = getenv(env);
	ptr_e = ptr_s + 8;
	return simple_strtoul(ptr_s, &ptr_e, 16);
}


static int parse_installdat(char* start_file_ptr, int file_size, struct install_dat fupdate[]) {

	char *open_quote=NULL, *file_ptr=start_file_ptr;
	char *end_file_ptr, *end_fladdr_ptr;
	int idx=0;
	

	fupdate[0].type = -1;
	*fupdate[0].file_name='\0';
	fupdate[0].flash_s_address = 0x00000000;
	fupdate[0].flash_e_address = 0x00000000;
	end_file_ptr = file_ptr + file_size;
	while (file_ptr < end_file_ptr)
	{
		switch (*file_ptr) {
			case '\n':
				open_quote=NULL;
				start_file_ptr = file_ptr; 
				files_to_update[idx].type = -1; 
				*fupdate[idx].file_name='\0';
				fupdate[idx].flash_s_address = 0x00000000;
				fupdate[idx].flash_e_address = 0x00000000;
				break;  
			
			case '"':
				if (open_quote) {
					/* close_quote --> copy quote content to filename */
					*file_ptr='\0';
					strcpy(fupdate[idx].file_name, open_quote); 
				} else {
					open_quote=file_ptr + 1;
					/* validate image type "uboot - kernel - rootfs" */
					*file_ptr='\0';
					if (strstr(start_file_ptr, "uboot"))
						fupdate[idx].type = 1; 
					else if (strstr(start_file_ptr, "kernel"))
						fupdate[idx].type = 2; 
					else if (strstr(start_file_ptr, "fdt"))
						fupdate[idx].type = 3; 
					else if (strstr(start_file_ptr, "rootfs"))
						fupdate[idx].type = 4; 
					else
						*open_quote='\n'; /* error: invalidate line */
				}			
				break;
				
			case '#':
				if (!fupdate[idx].flash_s_address) 
				{
					/* parse start address */
					file_ptr+=1;
					end_fladdr_ptr=file_ptr+8; 
					*end_fladdr_ptr='\0';
					fupdate[idx].flash_s_address = simple_strtoul(file_ptr, &end_fladdr_ptr, 16);
				}
				else
				{
					/* parse start address */
					file_ptr+=1;
					end_fladdr_ptr=file_ptr+8; 
					*end_fladdr_ptr='\n';
					fupdate[idx].flash_e_address = simple_strtoul(file_ptr, &end_fladdr_ptr, 16);
					
					if ((fupdate[idx].type != -1) && 
						(*fupdate[idx].file_name != '\0')) 
					{
						/* line parse OK */
						file_ptr+=8;
						idx++;
						open_quote=NULL;
						start_file_ptr = file_ptr;
					}
					else
						*file_ptr='\n'; /* error: invalidate line */
				}
				break;
		}

		file_ptr++;
	}
	
	return idx;
}


int do_usb_system_autoupdate(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {

	int usb_stor_curr_dev, num_files, i;
	unsigned long mem_ptr;
	char str_mem_ptr[9], str_flash_start[9], str_flash_stop[9];

	/* usb start */
	if (usb_init() < 0) 
	 	return 1; /* usb init fails */

	udelay(1000);
	
	usb_stor_curr_dev = usb_stor_scan(1);
	if (usb_stor_curr_dev < 0) 
		goto safe_exit; /* no pendrive found */
	
	/* fatload usb 0 100000 install.dat */
	if (do_fat_fsload(NULL, 0, 5, param_fat_fsload) != 0) 
		goto error_exit; /* no install.dat present */
	
	puts("USB system autoupdate\n");
	
	/* parse install.dat */
	num_files = parse_installdat(INSTALL_DAT_PTR, read_ex_env("filesize"), files_to_update);
	
	/* 1 - verify if all files to update are present and copy in memory */
	mem_ptr = 0x100000;
	for (i=0; i<num_files; i++)
	{	
		/* load bin */
		param_fat_fsload[4] = files_to_update[i].file_name;
		sprintf(str_mem_ptr, "%lx", mem_ptr);
		param_fat_fsload[3] = str_mem_ptr;
		if (do_fat_fsload (NULL, 0, 5, param_fat_fsload) != 0) {
			goto error_exit;
		}
		files_to_update[i].file_size = read_ex_env("filesize");
		files_to_update[i].mem_address = mem_ptr;

		mem_ptr += files_to_update[i].file_size;
	}
	
	/* 2 - protect off all */
 	if (do_protect (NULL, 0, 3, param_protect_off) != 0)
		goto error_exit;


	for (i=0; i<num_files; i++)
	{
		/* 3 - erase flash $(filesize) */
		sprintf(str_flash_start, "%lx", files_to_update[i].flash_s_address);
		sprintf(str_flash_stop, "%lx", files_to_update[i].flash_e_address);
		param_flerase[1] = str_flash_start;
		param_flerase[2] = str_flash_stop;
		print_cmd(param_flerase, 3);

		do_flerase(NULL, 0, 3, param_flerase);		

		/* 4 - program flash */
		sprintf(str_mem_ptr, "%lx", files_to_update[i].mem_address);
		sprintf(str_flash_stop, "%lx", files_to_update[i].file_size);
		param_memcp[1]=str_mem_ptr;
		param_memcp[2]=str_flash_start;
		param_memcp[3]=str_flash_stop;
		print_cmd(param_memcp, 4);

		do_mem_cp(NULL, 0, 4, param_memcp);	

#ifdef DEBUG
		printf("N:%d \t\t type:%d\n", i, files_to_update[i].type);
		printf("file_name:%s [%ld], \n", files_to_update[i].file_name, files_to_update[i].file_size);
		printf("flash_s_address:%lx\n", files_to_update[i].flash_s_address);
		printf("flash_e_address:%lx\n", files_to_update[i].flash_e_address);
		printf("mem_ptr:%lx\n", files_to_update[i].mem_address);
		printf("-------------------------------------------------------------\n");
#endif

	}	

safe_exit:
	udelay(1000);
	usb_stop();
	return 0;

error_exit:
	udelay(1000);
	usb_stop();
	udelay(1000*1000*5);
	return 1;
}



/* -------------------------------------------------------------------- */

extern int do_usb_system_autoupdate(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);

U_BOOT_CMD(
	usb_system_autoupdate, 1, 1, do_usb_system_autoupdate,
	"usb_system_autoupdate - Automatically update internal flash reading install.dat file on USB disk.\n",
	NULL
);

Attachment: install.dat
Description: MOPAC data

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to