⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 LUBBOCK板的BLOB
💻 C
📖 第 1 页 / 共 2 页
字号:
/*-------------------------------------------------------------------------
 * Filename:      main.c
 * Version:       $Id: main.c,v 1.23 2002/01/07 14:48:25 seletz Exp $
 * Copyright:     Copyright (C) 1999, Jan-Derk Bakker
 * Author:        Jan-Derk Bakker <J.D.Bakker@its.tudelft.nl>
 * Description:   Main file for the trivially simple bootloader for the 
 *                LART boards
 * Created at:    Mon Aug 23 20:00:00 1999
 * Modified by:   Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
 * Modified at:   Sat Mar 25 14:31:16 2000
 *-----------------------------------------------------------------------*/
/*
 * main.c: main file for the blob bootloader
 *
 * Copyright (C) 1999 2000 2001
 *   Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) and
 *   Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
 *
 * 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
 *
 */

#ident "$Id: main.c,v 1.23 2002/01/07 14:48:25 seletz Exp $"

#ifdef HAVE_CONFIG_H
# include <blob/config.h>
#endif

#include <blob/arch.h>
#include <blob/command.h>
#include <blob/errno.h>
#include <blob/error.h>
#include <blob/flash.h>
#include <blob/init.h>
#include <blob/led.h>
#include <blob/main.h>
#include <blob/md5.h>
#include <blob/md5support.h>
#include <blob/memory.h>
#include <blob/param_block.h>
#include <blob/serial.h>
#include <blob/time.h>
#include <blob/util.h>
#include <blob/uucodec.h>
#include <blob/xmodem.h>
#include <blob/time.h>




static int do_reload(char *what);
static void PrintSerialSpeed(serial_baud_t speed);
static void print_elf_sections(void);




blob_status_t blob_status;
static char *version_str = PACKAGE " version " VERSION " for " BOARD_NAME "\n";

int main(void)
{
	int numRead = 0;
	int done=0;
	char commandline[MAX_COMMANDLINE_LENGTH];
	int i,count;
	int retval = 0;
#ifdef PARAM_START
	u32 conf;
#endif

	/* call subsystems */
	init_subsystems();

	/* initialise status */
	blob_status.paramType = fromFlash;
	blob_status.kernelType = fromFlash;
	blob_status.ramdiskType = fromFlash;
	blob_status.downloadSpeed = baud_115200;
	blob_status.terminalSpeed = baud_115200;
	blob_status.load_ramdisk = 1;
	blob_status.cmdline[0] = '\0';
	blob_status.boot_delay = 10;

	/* call serial_init() because the default 9k6 speed might not
           be what the user requested */
#if defined(H3600) || defined(SHANNON) || defined(IDR) || defined(BADGE4) || defined(JORNADA720)
	blob_status.terminalSpeed = baud_115200; /* DEBUG */
#endif
#if defined(PT_SYSTEM3)
	blob_status.terminalSpeed = baud_38400;
#endif
	serial_init(blob_status.terminalSpeed);

	/* parse the core tag, for critical things like terminal speed */
#ifdef PARAM_START
	//parse_ptag((void *) PARAM_START, &conf);
#endif

	/* Print the required GPL string */
	SerialOutputString("\nConsider yourself LARTed!\n\n");
	SerialOutputString(version_str);
	SerialOutputString("Copyright (C) 1999 2000 2001 "
			   "Jan-Derk Bakker and Erik Mouw\n");
	SerialOutputString(PACKAGE " comes with ABSOLUTELY NO WARRANTY; "
			   "read the GNU GPL for details.\n");
	SerialOutputString("This is free software, and you are welcome "
			   "to redistribute it\n");
	SerialOutputString("under certain conditions; "
			   "read the GNU GPL for details.\n");

	/* get the amount of memory */
	get_memory_map();

	print_elf_sections();
#ifdef BLOB_DEBUG
	{
		register u32 stackptr;
		SerialOutputString("Current stack pointer: 0x");
		asm("mov %0, sp": "=r" (stackptr));
		SerialOutputHex(stackptr);
		serial_write('\n');
	}
#endif

	/* Parse all the tags in the paramater block */
#ifdef PARAM_START
	//parse_ptags((void *) PARAM_START, &conf);
#endif

	/* Load kernel and ramdisk from flash to RAM */
	do_reload("blob");
	do_reload("kernel");
	/*
	if(blob_status.load_ramdisk)
		do_reload("ramdisk");
	*/

	/* wait 10 seconds before starting autoboot */
	SerialOutputString("Autoboot in progress, press any key to stop ");
	for(i = 0; i < blob_status.boot_delay; i++) {
		serial_write('.');

 		retval = SerialInputBlock(commandline, 1, 1); 

		if(retval > 0)
			break;
	}


	/* no key was pressed, so proceed booting the kernel */
	if(retval == 0) {
		commandline[0] = '\0';
		parse_command("boot");
	}


	SerialOutputString("\nAutoboot aborted\n");
	SerialOutputString("Type \"help\" to get a list of commands\n");

	DisplayPrompt(NULL);
	numRead = 0;
	done = 0;

	/* the command loop. endless, of course */
	for(;;) {
		char c;
		char ready;

		/* wait 10 minutes for a command */
		//numRead = GetCommand(commandline, MAX_COMMANDLINE_LENGTH, 600);

#if ( defined(LUBBOCK) )
		eth_rx();
#endif

		ready = serial_poll();
		if ( ready == 1 )  {

			c = serial_read();

			if(c < 0) {
				serial_write('\n');
				continue;
			}

			if((c == '\r') || (c == '\n')) {
				commandline[numRead++] = '\0';
				done = 1;

				serial_write('\n');
			} else if(c == '\b') { 
				if(numRead > 0) {
					numRead--;
					SerialOutputString("\b \b");
				}
			} else {
				commandline[numRead++] = c;

				serial_write(c);
			}
		}


		if(done) {
			if((retval = parse_command(commandline)) < 0 )
				printerror(retval, NULL);

			/* reset count */
			done = 0;
			numRead = 0;

			DisplayPrompt(NULL);
		}
	}

	return 0;
} /* main */




static int set_download_parameters(char *name, u32 *startAddress, 
				    int *bufLen, int **numRead,
				   u32 **digest)
{
	if(strncmp(name, "blob", 5) == 0) {
		/* download blob */
		*startAddress = BLOB_RAM_BASE;
		*bufLen = BLOB_FLASH_LEN;
		*numRead = &blob_status.blobSize;
		*digest = blob_status.blob_md5_digest;
		blob_status.blobType = fromDownload;
#ifdef PARAM_START
	} else if(strncmp(name, "param", 6) == 0) {
		/* download param */
		*startAddress = PARAM_RAM_BASE;
		*bufLen = PARAM_FLASH_LEN;
		*numRead = &blob_status.paramSize;
		*digest = blob_status.param_md5_digest;
		blob_status.paramType = fromDownload;
#endif
	} else if(strncmp(name, "kernel", 7) == 0) {
		/* download kernel */
		*startAddress = KERNEL_RAM_BASE;
		*bufLen = KERNEL_FLASH_LEN;
		*numRead = &blob_status.kernelSize;
		*digest = blob_status.kernel_md5_digest;
		blob_status.kernelType = fromDownload;
	} else if(strncmp(name, "ramdisk", 8) == 0) {
		/* download ramdisk */
		*startAddress = RAMDISK_RAM_BASE;
		*bufLen = RAMDISK_FLASH_LEN;
		*numRead = &blob_status.ramdiskSize;
		*digest = blob_status.ramdisk_md5_digest;
		blob_status.ramdiskType = fromDownload;
	} else {
		printerror(-EINVAL, name);
		return -EINVAL;
	}

	return 0;
}




static void do_md5sum(u32 *addr, size_t len, u32 *digest)
{
#ifdef CONFIG_MD5_SUPPORT
	md5_buffer((const char *)addr, len, digest);
#endif
}




static int Download(int argc, char *argv[])
{
	u32 startAddress;
	int bufLen;
	int *numRead;
	int retval;
	u32 *digest;

	if(argc < 2)
		return -ENOPARAMS;

	retval = set_download_parameters(argv[1], &startAddress,
					 &bufLen, &numRead, &digest);

	if (blob_status.terminalSpeed != blob_status.downloadSpeed) {
		SerialOutputString("Switching to ");
		PrintSerialSpeed(blob_status.downloadSpeed);
		SerialOutputString(" baud\n");

		SerialOutputString("You have 60 seconds to switch your terminal emulator to the same speed and\n");
		SerialOutputString("start downloading. After that " PACKAGE " will switch back to ");
		PrintSerialSpeed(blob_status.terminalSpeed);
		SerialOutputString(" baud.\n");
	
		serial_init(blob_status.downloadSpeed);
	} else {
		SerialOutputString("You have 60 seconds to start downloading.\n");
	}

	*numRead = UUDecode((char *)startAddress, bufLen);
	
	if (blob_status.terminalSpeed != blob_status.downloadSpeed) {
		SerialOutputString("\n(Please switch your terminal emulator back to ");
		PrintSerialSpeed(blob_status.terminalSpeed);
		SerialOutputString(" baud)\n");
	}
	
	if(*numRead < 0) {
		/* something went wrong */
		retval = *numRead;
		
		/* reload the correct memory */
		do_reload(argv[1]);

		serial_init(blob_status.terminalSpeed);
		return retval;
	}

	do_md5sum((u32 *)startAddress, *numRead, digest);

	SerialOutputString("Received ");
	SerialOutputDec(*numRead);
	SerialOutputString(" (0x");
	SerialOutputHex(*numRead);
	SerialOutputString(") bytes");
#ifdef BLOB_DEBUG
	SerialOutputString(" at 0x");
	SerialOutputHex((u32) startAddress);
#ifdef CONFIG_MD5_SUPPORT
	SerialOutputString(", MD5: ");
	print_md5_digest(digest);
#endif
#endif
	serial_write('\n');


	serial_init(blob_status.terminalSpeed);

	return 0;
}

static char downloadhelp[] = "download {blob|param|kernel|ramdisk}\n"
"Download <argument> image to RAM using uuencode\n";

__commandlist(Download, "download", downloadhelp);

#if ( defined(LUBBOCK) )
static int Go(int argc, char *argv[]){
	unsigned long go, unused;
	
	if(argc < 2)
		return -ENOPARAMS;

	strtou32(argv[1], (unsigned long*)(&go));
	__asm("
	@ drain pending loads and stores
	mcr 	p15, 0, r0, c7, c10, 4		
	mrc  	p15,0,%1,c2,c0,0
	mov  	%1,%1
	sub  	pc,pc,#4

	mov    	%1, #0x78			@turn everything off 
      	mcr    	p15, 0, %1, c1, c0, 0		@(caches off, MMU off, etc.)
	mrc  	p15,0,%1,c2,c0,0
	mov  	%1,%1
	sub  	pc,pc,#4

	mov 	pc, %0
	"
	:
	:"r"(go), "r"(unused)
	);
	return 0;
}

static char gohelp[] = "go address\n"
"go and execute code at <address>, address in hex \n";

__commandlist(Go, "go", gohelp);

#endif

static int xdownload(int argc, char *argv[])
{
	u32 startAddress;
	int bufLen;
	int *numRead;
	int retval;
	u32 *digest;

	if(argc < 2)
		return -ENOPARAMS;

	retval = set_download_parameters(argv[1], &startAddress,
					 &bufLen, &numRead, &digest);

	if (blob_status.terminalSpeed != blob_status.downloadSpeed) {
		SerialOutputString("Switching to ");
		PrintSerialSpeed(blob_status.downloadSpeed);
		SerialOutputString(" baud\n");

		SerialOutputString("Switch your terminal emulator to the same speed and\n");
		SerialOutputString("start sending using the XMODEM protocl (repeated ^X) to quit.\n");
		SerialOutputString(PACKAGE " will switch back to ");
		PrintSerialSpeed(blob_status.terminalSpeed);
		SerialOutputString(" baud after XMODEM succeeds or times out.\n");
	
		serial_init(blob_status.downloadSpeed);
	} else {
		SerialOutputString("Start sending using the XMODEM protocol (repeated ^X to quit).\n\n");
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -