📄 main.c
字号:
/*-------------------------------------------------------------------------
* 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 + -