📄 main.c
字号:
/*------------------------------------------------------------------------- * Filename: main.c * Version: $Id: main.c,v 1.3 2001/08/07 17:36:48 erikm 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.3 2001/08/07 17:36:48 erikm Exp $"#ifdef HAVE_CONFIG_H# include "config.h"#endif#include "clock.h"#include "command.h"#include "flash.h"#include "led.h"#include "linux.h"#include "main.h"#include "memory.h"#include "sa1100.h"#include "serial.h"#include "time.h"#include "util.h"#include "uucodec.h"void Download(char *commandline);void Flash(char *commandline);void PrintHelp(void);void SetDownloadSpeed(char *commandline);void PrintStatus(void);void ResetTerminal(void);void Reload(char *commandline);void PrintSerialSpeed(eBauds speed);void Reboot(void);void Reblob(void);blob_status_t blob_status;int main(void){ u32 blockSize = 0x00800000; int numRead = 0; char commandline[128]; int i; int retval = 0; /* Turn the LED on again, so we can see that we safely made it * into C code. */ led_on(); /* We really want to be able to communicate, so initialise the * serial port at 9k6 (which works good for terminals) */ SerialInit(baud9k6); TimerInit(); /* Print the required GPL string */ SerialOutputString("\nConsider yourself LARTed!\n\n"); SerialOutputString(PACKAGE " version " VERSION "\n" "Copyright (C) 1999 2000 2001 " "Jan-Derk Bakker and Erik Mouw\n" "Copyright (C) 2000 " "Johan Pouwelse\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(); /* initialise status */ blob_status.kernelSize = 0; blob_status.kernelType = fromFlash; blob_status.ramdiskSize = 0; blob_status.ramdiskType = fromFlash; blob_status.blockSize = blockSize; blob_status.downloadSpeed = baud115k2; /* Load kernel and ramdisk from flash to RAM */ Reload("blob"); Reload("kernel"); Reload("ramdisk");#ifdef BLOB_DEBUG /* print some information */ SerialOutputString("Running from "); if(RunningFromInternal()) SerialOutputString("internal"); else SerialOutputString("external"); SerialOutputString(" flash, blockSize = 0x"); SerialOutputHex(blockSize); SerialOutputByte('\n');#endif /* wait 10 seconds before starting autoboot */ SerialOutputString("Autoboot in progress, press any key to stop "); for(i = 0; i < 10; i++) { SerialOutputByte('.'); retval = SerialInputBlock(commandline, 1, 1); if(retval > 0) break; } /* no key was pressed, so proceed booting the kernel */ if(retval == 0) { commandline[0] = '\0'; boot_linux(commandline); } SerialOutputString("\nAutoboot aborted\n"); SerialOutputString("Type \"help\" to get a list of commands\n"); /* the command loop. endless, of course */ for(;;) { DisplayPrompt(NULL); /* wait 10 minutes for a command */ numRead = GetCommand(commandline, 128, 600); if(numRead > 0) { if(MyStrNCmp(commandline, "boot", 4) == 0) { boot_linux(commandline + 4); } else if(MyStrNCmp(commandline, "clock", 5) == 0) { SetClock(commandline + 5); } else if(MyStrNCmp(commandline, "download ", 9) == 0) { Download(commandline + 9); } else if(MyStrNCmp(commandline, "flash ", 6) == 0) { Flash(commandline + 6); } else if(MyStrNCmp(commandline, "help", 4) == 0) { PrintHelp(); } else if(MyStrNCmp(commandline, "reblob", 6) == 0) { Reblob(); } else if(MyStrNCmp(commandline, "reboot", 6) == 0) { Reboot(); } else if(MyStrNCmp(commandline, "reload ", 7) == 0) { Reload(commandline + 7); } else if(MyStrNCmp(commandline, "reset", 5) == 0) { ResetTerminal(); } else if(MyStrNCmp(commandline, "speed ", 6) == 0) { SetDownloadSpeed(commandline + 6); } else if(MyStrNCmp(commandline, "status", 6) == 0) { PrintStatus(); } else { SerialOutputString("*** Unknown command: "); SerialOutputString(commandline); SerialOutputByte('\n'); } } } return 0;} /* main */void Download(char *commandline){ u32 startAddress = 0; int bufLen; int *numRead = 0; if(MyStrNCmp(commandline, "blob", 4) == 0) { /* download blob */ startAddress = BLOB_RAM_BASE; bufLen = blob_status.blockSize - BLOB_BLOCK_OFFSET; numRead = &blob_status.blobSize; blob_status.blobType = fromDownload; } else if(MyStrNCmp(commandline, "kernel", 6) == 0) { /* download kernel */ startAddress = KERNEL_RAM_BASE; bufLen = blob_status.blockSize - KERNEL_BLOCK_OFFSET; numRead = &blob_status.kernelSize; blob_status.kernelType = fromDownload; } else if(MyStrNCmp(commandline, "ramdisk", 7) == 0) { /* download ramdisk */ startAddress = RAMDISK_RAM_BASE; bufLen = blob_status.blockSize - RAMDISK_BLOCK_OFFSET; numRead = &blob_status.ramdiskSize; blob_status.ramdiskType = fromDownload; } else { SerialOutputString("*** Don't know how to download \""); SerialOutputString(commandline); SerialOutputString("\"\n"); return; } 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 9600 baud.\n"); SerialInit(blob_status.downloadSpeed); *numRead = UUDecode((char *)startAddress, bufLen); SerialOutputString("\n(Please switch your terminal emulator back to 9600 baud)\n"); if(*numRead < 0) { /* something went wrong */ SerialOutputString("*** Uudecode receive failed\n"); /* reload the correct memory */ Reload(commandline); SerialInit(baud9k6); return; } SerialOutputString("Received "); SerialOutputDec(*numRead); SerialOutputString(" (0x"); SerialOutputHex(*numRead); SerialOutputString(") bytes.\n"); SerialInit(baud9k6);}void Flash(char *commandline){ u32 startAddress = 0; tBlockType block; int numBytes = 0; int maxSize = 0; if(MyStrNCmp(commandline, "blob", 4) == 0) { startAddress = BLOB_RAM_BASE; block = blBlob; numBytes = blob_status.blobSize; maxSize = BLOB_LEN; if(blob_status.blobType == fromFlash) { SerialOutputString("*** No blob downloaded\n"); return; } SerialOutputString("Saving blob to flash "); } else if(MyStrNCmp(commandline, "kernel", 6) == 0) { startAddress = KERNEL_RAM_BASE; block = blKernel; numBytes = blob_status.kernelSize; maxSize = KERNEL_LEN; if(blob_status.kernelType == fromFlash) { SerialOutputString("*** No kernel downloaded\n"); return; } SerialOutputString("Saving kernel to flash "); } else if(MyStrNCmp(commandline, "ramdisk", 7) == 0) { startAddress = RAMDISK_RAM_BASE; block = blRamdisk; numBytes = blob_status.ramdiskSize; maxSize = INITRD_LEN; if(blob_status.ramdiskType == fromFlash) { SerialOutputString("*** No ramdisk downloaded\n"); return; } SerialOutputString("Saving ramdisk to flash "); } else { SerialOutputString("*** Don't know how to flash \""); SerialOutputString(commandline); SerialOutputString("\"\n"); return; } if(numBytes > maxSize) { SerialOutputString("*** Downloaded image too large for flash area\n"); SerialOutputString("*** (0x"); SerialOutputHex(numBytes); SerialOutputString(" downloaded, maximum size is 0x"); SerialOutputHex(maxSize); SerialOutputString(" bytes)\n"); return; } EraseBlocks(block); SerialOutputByte(' '); WriteBlocksFromMem(block, (u32 *)startAddress, numBytes); SerialOutputString(" done\n");}void PrintHelp(void){ SerialOutputString("Help for " PACKAGE " " VERSION ", the LART bootloader\n"); SerialOutputString("The following commands are supported:\n"); SerialOutputString("* boot [kernel options] Boot Linux with optional kernel options\n"); SerialOutputString("* clock PPCR MDCNFG MDCAS0 MDCAS1 MDCAS2\n"); SerialOutputString(" Set the SA1100 core clock and DRAM timings\n"); SerialOutputString(" (WARNING: dangerous command!)\n"); SerialOutputString("* download {blob|kernel|ramdisk} Download blob/kernel/ramdisk image to RAM\n"); SerialOutputString("* flash {blob|kernel|ramdisk} Copy blob/kernel/ramdisk from RAM to flash\n"); SerialOutputString("* help Get this help\n"); SerialOutputString("* reblob Restart blob from RAM\n"); SerialOutputString("* reboot Reboot system\n"); SerialOutputString("* reload {blob|kernel|ramdisk} Reload blob/kernel/ramdisk from flash to RAM\n"); SerialOutputString("* reset Reset terminal\n"); SerialOutputString("* speed Set download speed\n"); SerialOutputString("* status Display current status\n");}void SetDownloadSpeed(char *commandline){ if(MyStrNCmp(commandline, "1200", 4) == 0) { blob_status.downloadSpeed = baud1k2; } else if(MyStrNCmp(commandline, "1k2", 3) == 0) { blob_status.downloadSpeed = baud1k2; } else if(MyStrNCmp(commandline, "9600", 4) == 0) { blob_status.downloadSpeed = baud9k6; } else if(MyStrNCmp(commandline, "9k6", 3) == 0) { blob_status.downloadSpeed = baud9k6; } else if(MyStrNCmp(commandline, "19200", 5) == 0) { blob_status.downloadSpeed = baud19k2; } else if(MyStrNCmp(commandline, "19k2", 4) == 0) { blob_status.downloadSpeed = baud19k2; } else if(MyStrNCmp(commandline, "38400", 5) == 0) { blob_status.downloadSpeed = baud38k4; } else if(MyStrNCmp(commandline, "38k4", 4) == 0) { blob_status.downloadSpeed = baud38k4; } else if(MyStrNCmp(commandline, "57600", 5) == 0) { blob_status.downloadSpeed = baud57k6; } else if(MyStrNCmp(commandline, "57k6", 4) == 0) { blob_status.downloadSpeed = baud57k6; } else if(MyStrNCmp(commandline, "115200", 6) == 0) { blob_status.downloadSpeed = baud115k2; } else if(MyStrNCmp(commandline, "115k2", 5) == 0) { blob_status.downloadSpeed = baud115k2; } else { SerialOutputString("*** Invalid download speed value \""); SerialOutputString(commandline); SerialOutputString("\"\n*** Valid values are:\n"); SerialOutputString("*** 1200, 9600, 19200, 38400, 57600, 115200,\n"); SerialOutputString("*** 1k2, 9k6, 19k2, 38k4, 57k6, and 115k2\n"); } SerialOutputString("Download speed set to "); PrintSerialSpeed(blob_status.downloadSpeed); SerialOutputString(" baud\n");}void PrintStatus(void){ SerialOutputString("Bootloader : " PACKAGE "\n"); SerialOutputString("Version : " VERSION "\n"); SerialOutputString("Running from : "); if(RunningFromInternal()) SerialOutputString("internal"); else SerialOutputString("external"); SerialOutputString(" flash\nBlocksize : 0x"); SerialOutputHex(blob_status.blockSize); SerialOutputString("\nDownload speed: "); PrintSerialSpeed(blob_status.downloadSpeed); SerialOutputString(" baud\n"); SerialOutputString("Blob : "); if(blob_status.blobType == fromFlash) { SerialOutputString("from flash\n"); } else { SerialOutputString("downloaded, "); SerialOutputDec(blob_status.blobSize); SerialOutputString(" bytes\n"); } SerialOutputString("Kernel : "); if(blob_status.kernelType == fromFlash) { SerialOutputString("from flash\n"); } else { SerialOutputString("downloaded, "); SerialOutputDec(blob_status.kernelSize); SerialOutputString(" bytes\n"); } SerialOutputString("Ramdisk : "); if(blob_status.ramdiskType == fromFlash) { SerialOutputString("from flash\n"); } else { SerialOutputString("downloaded, "); SerialOutputDec(blob_status.ramdiskSize); SerialOutputString(" bytes\n"); }}void ResetTerminal(void){ int i; SerialInit(baud9k6); SerialOutputString(" c"); for(i = 0; i < 100; i++) SerialOutputByte('\n'); SerialOutputString("c");}void Reload(char *commandline){ u32 *src = 0; u32 *dst = 0; int numWords; if(MyStrNCmp(commandline, "blob", 4) == 0) { src = (u32 *)BLOB_RAM_BASE; dst = (u32 *)BLOB_START; numWords = BLOB_LEN / 4; blob_status.blobSize = 0; blob_status.blobType = fromFlash; SerialOutputString("Loading blob from flash "); } else if(MyStrNCmp(commandline, "kernel", 6) == 0) { src = (u32 *)KERNEL_RAM_BASE; dst = (u32 *)KERNEL_START; numWords = KERNEL_LEN / 4; blob_status.kernelSize = 0; blob_status.kernelType = fromFlash; SerialOutputString("Loading kernel from flash "); } else if(MyStrNCmp(commandline, "ramdisk", 7) == 0) { src = (u32 *)RAMDISK_RAM_BASE; dst = (u32 *)INITRD_START; numWords = INITRD_LEN / 4; blob_status.ramdiskSize = 0; blob_status.ramdiskType = fromFlash; SerialOutputString("Loading ramdisk from flash "); } else { SerialOutputString("*** Don't know how to reload \""); SerialOutputString(commandline); SerialOutputString("\"\n"); return; } MyMemCpy(src, dst, numWords); SerialOutputString(" done\n");}void PrintSerialSpeed(eBauds speed){ switch(speed) { case baud1k2: SerialOutputDec(1200); break; case baud9k6: SerialOutputDec(9600); break; case baud19k2: SerialOutputDec(19200); break; case baud38k4: SerialOutputDec(38400); break; case baud57k6: SerialOutputDec(57600); break; case baud115k2: SerialOutputDec(115200); break; default: SerialOutputString("(unknown)"); break; }}void Reboot(void){ SerialOutputString("Rebooting...\n\n"); msleep(500); RCSR = 0; RSRR = 1;}void Reblob(void){ void (*blob)(void) = (void (*)(void))BLOB_RAM_BASE; SerialOutputString("Restarting blob from RAM...\n\n"); msleep(500); blob();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -