From: Erik M. <er...@us...> - 2001-09-17 00:05:34
|
Update of /cvsroot/blob/blob/src In directory usw-pr-cvs1:/tmp/cvs-serv8549/src Modified Files: command.c linux.c main.c util.c Log Message: The new command line stuff. Most of the commands are converted, only a couple of them still need to be done. Anyway, it makes the code a lot easier and smaller. Index: command.c =================================================================== RCS file: /cvsroot/blob/blob/src/command.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- command.c 2001/09/16 15:44:00 1.5 +++ command.c 2001/09/17 00:05:31 1.6 @@ -11,7 +11,7 @@ /* * command.c: Command line functions for blob * - * Copyright (C) 1999 Erik Mouw (J.A...@it...) + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A...@it...) * * 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 @@ -48,12 +48,12 @@ /* the first command */ -static commandlist_t *commands; -static commandlist_t *lastcommand; +commandlist_t *commands; void init_commands(void) { + commandlist_t *lastcommand; commandlist_t *cmd, *next_cmd; commands = (commandlist_t *) &__commandlist_start; @@ -74,9 +74,60 @@ -static int parse_args(char *cmdline, int *argc, char **argv) +#define STATE_WHITESPACE (0) +#define STATE_WORD (1) +void parse_args(char *cmdline, int *argc, char **argv) { + char *c; + int state = STATE_WHITESPACE; + int i; + + *argc = 0; + + if(strlen(cmdline) == 0) + return; + + /* convert all tabs into single spaces */ + c = cmdline; + while(*c != '\0') { + if(*c == '\t') + *c = ' '; + + c++; + } + c = cmdline; + i = 0; + + /* now find all words on the command line */ + while(*c != '\0') { + if(state == STATE_WHITESPACE) { + if(*c != ' ') { + argv[i] = c; + i++; + state = STATE_WORD; + } + } else { /* state == STATE_WORD */ + if(*c == ' ') { + *c = '\0'; + state = STATE_WHITESPACE; + } + } + + c++; + } + + *argc = i; + +#ifdef BLOB_DEBUG + for(i = 0; i < *argc; i++) { + SerialOutputString("*** argv["); + SerialOutputDec(i); + SerialOutputString("] = "); + SerialOutputString(argv[i]); + SerialOutputByte('\n'); + } +#endif } @@ -85,19 +136,19 @@ int parse_command(char *cmdline) { commandlist_t *cmd; - int len; + int argc; + char *argv[MAX_ARGS]; - for(cmd = commands; cmd != NULL; cmd = cmd->next) { - if(cmd->magic != COMMAND_MAGIC) { - SerialOutputString("*** Invalid command list entry\n"); - return -1; - } + parse_args(cmdline, &argc, argv); + + /* only whitespace */ + if(argc == 0) + return 0; - len = strlen(cmd->name); - - if(strncmp(cmd->name, cmdline, len) == 0) { + for(cmd = commands; cmd != NULL; cmd = cmd->next) { + if(strcmp(cmd->name, cmdline) == 0) { /* call function */ - return cmd->callback(1, cmdline); + return cmd->callback(argc, argv); } } @@ -107,30 +158,32 @@ -static int foo(int argc, char *argv[]) +static int test_command(int argc, char *argv[]) { - SerialOutputString("*** foo() got called!\n"); - return 0; -} - + int i; -static char fooname[] = "foo"; -static char foohelp[] = "foo help"; + SerialOutputString("*** test_command() got called!\n"); -__commandlist(foo, fooname, foohelp); - - + SerialOutputString("*** argc = "); + SerialOutputDec(argc); + SerialOutputByte('\n'); + + for(i = 0; i < argc; i++) { + SerialOutputString("*** argv["); + SerialOutputDec(i); + SerialOutputString("] = '"); + SerialOutputString(argv[i]); + SerialOutputString("'\n"); + } -static int bar(int argc, char *argv[]) -{ - SerialOutputString("*** bar() got called!\n"); return 0; } -__commandlist(bar, "bar", "bar help"); - +static char testhelp[] = "test_command\n" +"Test new command line functions\n"; +__commandlist(test_command, "test", testhelp); Index: linux.c =================================================================== RCS file: /cvsroot/blob/blob/src/linux.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- linux.c 2001/08/31 06:26:59 1.4 +++ linux.c 2001/09/17 00:05:31 1.5 @@ -26,6 +26,7 @@ #endif #include "linux.h" +#include "command.h" #include "main.h" #include "flash.h" #include "memory.h" @@ -37,7 +38,7 @@ static void setup_start_tag(void); static void setup_memory_tags(void); -static void setup_commandline_tag(char *commandline); +static void setup_commandline_tag(int argc, char *argv[]); static void setup_ramdisk_tag(void); static void setup_initrd_tag(void); static void setup_end_tag(void); @@ -46,14 +47,14 @@ static struct tag *params; -void boot_linux(char *commandline) +int boot_linux(int argc, char *argv[]) { register u32 i; void (*theKernel)(int zero, int arch) = (void (*)(int, int))KERNEL_RAM_BASE; setup_start_tag(); setup_memory_tags(); - setup_commandline_tag(commandline); + setup_commandline_tag(argc, argv); setup_initrd_tag(); setup_ramdisk_tag(); setup_end_tag(); @@ -74,7 +75,12 @@ SerialOutputString("Hey, the kernel returned! This should not happen.\n"); } +static char boothelp[] = "boot [kernel options]\n" +"Boot Linux with optional kernel options\n"; +__commandlist(boot_linux, "boot", boothelp); + + static void setup_start_tag(void) { params = (struct tag *)BOOT_PARAMS; @@ -108,29 +114,39 @@ } -static void setup_commandline_tag(char *commandline) +static void setup_commandline_tag(int argc, char *argv[]) { char *p; - - /* eat leading white space */ - for(p = commandline; *p == ' '; p++) - ; - - /* skip non-existent command lines so the kernel will still - * use its default command line. - */ - if(*p == '\0') { - if(*blob_status.cmdline != '\0') - p = blob_status.cmdline; - else return; - } + int i; - params->hdr.tag = ATAG_CMDLINE; - params->hdr.size = (sizeof(struct tag_header) + strlen(p) + 1 + 4) >> 2; + /* initialise commandline */ + params->u.cmdline.cmdline[0] = '\0'; - strcpy(params->u.cmdline.cmdline, p); + /* copy default commandline from parameter block */ + if(blob_status.cmdline[0] != '\0') + strcpy(params->u.cmdline.cmdline, blob_status.cmdline); + + /* copy commandline */ + if(argc >= 2) { + p = params->u.cmdline.cmdline; + + for(i = 1; i < argc; i++) { + strcpy(p, argv[i]); + p += strlen(argv[i]); + *p++ = ' '; + } + + p--; + *p = '\0'; + } - params = tag_next(params); + if(strlen(params->u.cmdline.cmdline) > 0) { + params->hdr.tag = ATAG_CMDLINE; + params->hdr.size = (sizeof(struct tag_header) + + strlen(params->u.cmdline.cmdline) + 1 + 4) >> 2; + + params = tag_next(params); + } } Index: main.c =================================================================== RCS file: /cvsroot/blob/blob/src/main.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- main.c 2001/09/16 15:44:00 1.10 +++ main.c 2001/09/17 00:05:31 1.11 @@ -57,14 +57,8 @@ 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); +static int do_reload(char *what); +static void PrintSerialSpeed(eBauds speed); @@ -78,7 +72,7 @@ { u32 blockSize = 0x00800000; int numRead = 0; - char commandline[128]; + char commandline[MAX_COMMANDLINE_LENGTH]; int i; int retval = 0; u32 conf; @@ -125,20 +119,22 @@ SerialOutputString("under certain conditions; " "read the GNU GPL for details.\n"); - init_commands(); - /* get the amount of memory */ get_memory_map(); + /* initialise command line parser */ + init_commands(); + /* 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 */ - Reload("blob"); - Reload("kernel"); - if(blob_status.load_ramdisk) Reload("ramdisk"); + do_reload("blob"); + do_reload("kernel"); + if(blob_status.load_ramdisk) + do_reload("ramdisk"); #ifdef BLOB_DEBUG /* print some information */ @@ -166,7 +162,7 @@ /* no key was pressed, so proceed booting the kernel */ if(retval == 0) { commandline[0] = '\0'; - boot_linux(commandline); + boot_linux(0, NULL); } SerialOutputString("\nAutoboot aborted\n"); @@ -177,32 +173,15 @@ DisplayPrompt(NULL); /* wait 10 minutes for a command */ - numRead = GetCommand(commandline, 128, 600); + numRead = GetCommand(commandline, MAX_COMMANDLINE_LENGTH, 600); if(numRead > 0) { - if(strncmp(commandline, "boot", 4) == 0) { - boot_linux(commandline + 4); - } else if(strncmp(commandline, "clock", 5) == 0) { + if(strncmp(commandline, "clock", 5) == 0) { SetClock(commandline + 5); } else if(strncmp(commandline, "download ", 9) == 0) { Download(commandline + 9); } else if(strncmp(commandline, "flash ", 6) == 0) { Flash(commandline + 6); - } else if(strncmp(commandline, "help", 4) == 0) { - PrintHelp(); - } else if(strncmp(commandline, "reblob", 6) == 0) { - Reblob(); - } else if(strncmp(commandline, "reboot", 6) == 0) { - Reboot(); - } else if(strncmp(commandline, "reload ", 7) == 0) { - Reload(commandline + 7); - } else if(strncmp(commandline, "reset", 5) == 0) { - ResetTerminal(); - } else if(strncmp(commandline, "speed ", 6) == 0) { - SetDownloadSpeed(commandline + 6); - } - else if(strncmp(commandline, "status", 6) == 0) { - PrintStatus(); } else if(parse_command(commandline) != 0 ) { SerialOutputString("*** Unknown command: "); SerialOutputString(commandline); @@ -279,7 +258,7 @@ SerialOutputString("*** Uudecode receive failed\n"); /* reload the correct memory */ - Reload(commandline); + do_reload(commandline); SerialInit(blob_status.terminalSpeed); return; @@ -381,61 +360,97 @@ -void PrintHelp(void) +static int PrintHelp(int argc, char *argv[]) { - 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"); +#if 0 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|param|kernel|ramdisk} Download <argument> image to RAM\n"); SerialOutputString("* flash {blob|param|kernel|ramdisk} Copy <argument> 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|param|kernel|ramdisk} Reload <argument> from flash to RAM\n"); - SerialOutputString("* reset Reset terminal\n"); - SerialOutputString("* speed Set download speed\n"); - SerialOutputString("* status Display current status\n"); +#endif + commandlist_t *cmd; + + /* help on a command? */ + if(argc >= 2) { + for(cmd = commands; cmd != NULL; cmd = cmd->next) { + if(strcmp(cmd->name, argv[1]) == 0) { + SerialOutputString("Help for '"); + SerialOutputString(argv[1]); + SerialOutputString("':\n\nUsage: "); + SerialOutputString(cmd->help); + return 0; + } + } + + SerialOutputString("*** Can't find help for '"); + SerialOutputString(argv[1]); + SerialOutputString("'\n"); + return 0; + } + + /* generic help */ + SerialOutputString("Help for " PACKAGE " " VERSION ", the LART bootloader\n"); + SerialOutputString("The following commands are supported:"); + + for(cmd = commands; cmd != NULL; cmd = cmd->next) { + SerialOutputString("\n* "); + SerialOutputString(cmd->name); + } + + SerialOutputString("\nUse \"help command\" to get help on a specific command\n"); + + return 0; } +static char helphelp[] = "help\n" +"Get this help\n"; + +__commandlist(PrintHelp, "help", helphelp); -void SetDownloadSpeed(char *commandline) + +static int SetDownloadSpeed(int argc, char *argv[]) { - if(strncmp(commandline, "1200", 4) == 0) { + if(argc < 2) { + /* FIXME: return -EINVAL and let the command line + stuff print the error */ + SerialOutputString("*** not enough parameters\n"); + return 0; + } + + if(strcmp(argv[1], "1200") == 0) { blob_status.downloadSpeed = baud1k2; - } else if(strncmp(commandline, "1k2", 3) == 0) { + } else if(strcmp(argv[1], "1k2") == 0) { blob_status.downloadSpeed = baud1k2; - } else if(strncmp(commandline, "9600", 4) == 0) { + } else if(strcmp(argv[1], "9600") == 0) { blob_status.downloadSpeed = baud9k6; - } else if(strncmp(commandline, "9k6", 3) == 0) { + } else if(strcmp(argv[1], "9k6") == 0) { blob_status.downloadSpeed = baud9k6; - } else if(strncmp(commandline, "19200", 5) == 0) { + } else if(strcmp(argv[1], "19200") == 0) { blob_status.downloadSpeed = baud19k2; - } else if(strncmp(commandline, "19k2", 4) == 0) { + } else if(strcmp(argv[1], "19k2") == 0) { blob_status.downloadSpeed = baud19k2; - } else if(strncmp(commandline, "38400", 5) == 0) { + } else if(strcmp(argv[1], "38400") == 0) { blob_status.downloadSpeed = baud38k4; - } else if(strncmp(commandline, "38k4", 4) == 0) { + } else if(strcmp(argv[1], "38k4") == 0) { blob_status.downloadSpeed = baud38k4; - } else if(strncmp(commandline, "57600", 5) == 0) { + } else if(strcmp(argv[1], "57600") == 0) { blob_status.downloadSpeed = baud57k6; - } else if(strncmp(commandline, "57k6", 4) == 0) { + } else if(strcmp(argv[1], "57k6") == 0) { blob_status.downloadSpeed = baud57k6; - } else if(strncmp(commandline, "115200", 6) == 0) { + } else if(strcmp(argv[1], "115200") == 0) { blob_status.downloadSpeed = baud115k2; - } else if(strncmp(commandline, "115k2", 5) == 0) { + } else if(strcmp(argv[1], "115k2") == 0) { blob_status.downloadSpeed = baud115k2; - } else if(strncmp(commandline, "230400", 6) == 0) { + } else if(strcmp(argv[1], "230400") == 0) { blob_status.downloadSpeed = baud230k4; - } else if(strncmp(commandline, "230k4", 5) == 0) { + } else if(strcmp(argv[1], "230k4") == 0) { blob_status.downloadSpeed = baud230k4; } else { SerialOutputString("*** Invalid download speed value \""); - SerialOutputString(commandline); + SerialOutputString(argv[1]); SerialOutputString("\"\n*** Valid values are:\n"); SerialOutputString("*** 1200, 9600, 19200, 38400, 57600, 115200, 230400\n"); SerialOutputString("*** 1k2, 9k6, 19k2, 38k4, 57k6, 115k2, and 230k4\n"); @@ -444,12 +459,19 @@ SerialOutputString("Download speed set to "); PrintSerialSpeed(blob_status.downloadSpeed); SerialOutputString(" baud\n"); + + return 0; } +static char speedhelp[] = "speed\n" +"Set download speed\n"; + +__commandlist(SetDownloadSpeed, "speed", speedhelp); + -void PrintStatus(void) +static int PrintStatus(int argc, char *argv[]) { SerialOutputString("Bootloader : " PACKAGE "\n"); SerialOutputString("Version : " VERSION "\n"); @@ -467,7 +489,7 @@ PrintSerialSpeed(blob_status.downloadSpeed); SerialOutputString(" baud\n"); - SerialOutputString("\nTerminal speed: "); + SerialOutputString("Terminal speed: "); PrintSerialSpeed(blob_status.terminalSpeed); SerialOutputString(" baud\n"); @@ -510,12 +532,19 @@ SerialOutputDec(blob_status.ramdiskSize); SerialOutputString(" bytes\n"); } + + return 0; } +static char statushelp[] = "status\n" +"Display current status\n"; + +__commandlist(PrintStatus, "status", statushelp); -void ResetTerminal(void) + +static int ResetTerminal(int argc, char *argv[]) { int i; @@ -525,18 +554,25 @@ SerialOutputByte('\n'); SerialOutputString("c"); + + return 0; } +static char resethelp[] = "reset\n" +"Reset terminal\n"; + +__commandlist(ResetTerminal, "reset", resethelp); -void Reload(char *commandline) + +static int do_reload(char *what) { u32 *src = 0; u32 *dst = 0; int numWords; - if(strncmp(commandline, "blob", 4) == 0) { + if(strcmp(what, "blob") == 0) { src = (u32 *)BLOB_RAM_BASE; dst = (u32 *)BLOB_START; numWords = BLOB_LEN / 4; @@ -544,7 +580,7 @@ blob_status.blobType = fromFlash; SerialOutputString("Loading blob from flash "); #ifdef PARAM_START - } else if(strncmp(commandline, "param", 6) == 0) { + } else if(strcmp(what, "param") == 0) { src = (u32 *)PARAM_RAM_BASE; dst = (u32 *)PARAM_START; numWords = PARAM_LEN / 4; @@ -552,14 +588,14 @@ blob_status.paramType = fromFlash; SerialOutputString("Loading paramater block from flash "); #endif - } else if(strncmp(commandline, "kernel", 6) == 0) { + } else if(strcmp(what, "kernel") == 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(strncmp(commandline, "ramdisk", 7) == 0) { + } else if(strcmp(what, "ramdisk") == 0) { src = (u32 *)RAMDISK_RAM_BASE; dst = (u32 *)INITRD_START; numWords = INITRD_LEN / 4; @@ -568,19 +604,41 @@ SerialOutputString("Loading ramdisk from flash "); } else { SerialOutputString("*** Don't know how to reload \""); - SerialOutputString(commandline); + SerialOutputString(what); SerialOutputString("\"\n"); - return; + return 0; } MyMemCpy(src, dst, numWords); SerialOutputString(" done\n"); + + return 0; +} + + + + +static int Reload(int argc, char *argv[]) +{ + if(argc < 2) { + /* FIXME: return -EINVAL and let the command line + stuff print the error */ + SerialOutputString("*** not enough parameters\n"); + return 0; + } + + return do_reload(argv[1]); } +static char reloadhelp[] = "reload {blob|param|kernel|ramdisk}\n" +"Reload <argument> from flash to RAM\n"; + +__commandlist(Reload, "reload", reloadhelp); -void PrintSerialSpeed(eBauds speed) + +static void PrintSerialSpeed(eBauds speed) { switch(speed) { case baud1k2: @@ -620,7 +678,7 @@ -void Reboot(void) +static int Reboot(int argc, char *argv[]) { SerialOutputString("Rebooting...\n\n"); @@ -628,12 +686,20 @@ RCSR = 0; RSRR = 1; + + /* never reached, but anyway... */ + return 0; } +static char reboothelp[] = "reboot\n" +"Reboot system\n"; + +__commandlist(Reboot, "reboot", reboothelp); -void Reblob(void) + +int Reblob(int argc, char *argv[]) { void (*blob)(void) = (void (*)(void))BLOB_RAM_BASE; @@ -642,4 +708,12 @@ msleep(500); blob(); + + /* never reached, but anyway... */ + return 0; } + +static char reblobhelp[] = "reblob\n" +"Restart blob from RAM\n"; + +__commandlist(Reblob, "reblob", reblobhelp); Index: util.c =================================================================== RCS file: /cvsroot/blob/blob/src/util.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- util.c 2001/09/16 15:44:00 1.4 +++ util.c 2001/09/17 00:05:31 1.5 @@ -119,6 +119,8 @@ } + + char *strcpy(char *dest, const char *src) { while(*src != '\0') |