Update of /cvsroot/blob/blob/src In directory usw-pr-cvs1:/tmp/cvs-serv25835/src Modified Files: Tag: blob_1_0_9_hack Makefile.am linux.c main.c memory.c rest-ld-script start.S util.c Log Message: Kernel command line support. - linux.c handles parameter list setup and also passes the correct memory layout to the kernel - cleanup in main.c - add strlen() and strcpy() functions - move blob to 0xc0000400 instead of 0xc000000 because the parameter list has to live at 0xc0000100 - minor cleanups Index: Makefile.am =================================================================== RCS file: /cvsroot/blob/blob/src/Makefile.am,v retrieving revision 1.1.1.1.2.3 retrieving revision 1.1.1.1.2.4 diff -u -r1.1.1.1.2.3 -r1.1.1.1.2.4 --- Makefile.am 2001/07/22 22:54:26 1.1.1.1.2.3 +++ Makefile.am 2001/07/26 00:33:03 1.1.1.1.2.4 @@ -54,6 +54,7 @@ command.c \ flash.c \ led.c \ + linux.c \ main.c \ memory.c \ serial.c \ Index: linux.c =================================================================== RCS file: /cvsroot/blob/blob/src/Attic/linux.c,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -r1.1.2.1 -r1.1.2.2 --- linux.c 2001/07/24 13:57:47 1.1.2.1 +++ linux.c 2001/07/26 00:33:03 1.1.2.2 @@ -1 +1,121 @@ +/* + * linux.c: support functions for booting a kernel + * + * Copyright (C) 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 + * 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$" + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "linux.h" +#include "main.h" +#include "memory.h" +#include "serial.h" +#include "util.h" + +#include <asm/setup.h> + + +static void setup_start_tag(void); +static void setup_memory_tags(void); +static void setup_commandline_tag(char *commandline); +static void setup_end_tag(void); + + +static struct tag *params; + + +void boot_linux(char *commandline) +{ + 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_end_tag(); + + /* we assume that the kernel is in place */ + SerialOutputString("\nStarting kernel ...\n\n"); + + /* turn off I-cache */ + asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i)); + i &= ~0x1000; + asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i)); + + /* flush I-cache */ + asm ("mcr p15, 0, %0, c7, c5, 0": : "r" (i)); + + theKernel(0, ARCH_NUMBER); + + SerialOutputString("Hey, the kernel returned! This should not happen.\n"); +} + + +static void setup_start_tag(void) +{ + params = (struct tag *)BOOT_PARAMS; + + params->hdr.tag = ATAG_CORE; + params->hdr.size = tag_size(tag_core); + + params->u.core.flags = 0; + params->u.core.pagesize = 0; + params->u.core.rootdev = 0; + + params = tag_next(params); +} + + +static void setup_memory_tags(void) +{ + int i; + + for(i = 0; i < NUM_MEM_AREAS; i++) { + if(memory_map[i].used) { + params->hdr.tag = ATAG_MEM; + params->hdr.size = tag_size(tag_mem32); + + params->u.mem.start = memory_map[i].start; + params->u.mem.size = memory_map[i].len; + + params = tag_next(params); + } + } +} + + +static void setup_commandline_tag(char *commandline) +{ + params->hdr.tag = ATAG_CMDLINE; + params->hdr.size = (sizeof(struct tag_header) + strlen(commandline) + 1 + 4) >> 2; + + strcpy(params->u.cmdline.cmdline, commandline); + + params = tag_next(params); +} + + +static void setup_end_tag(void) +{ + params->hdr.tag = ATAG_NONE; + params->hdr.size = 0; +} Index: main.c =================================================================== RCS file: /cvsroot/blob/blob/src/main.c,v retrieving revision 1.1.1.1.2.11 retrieving revision 1.1.1.1.2.12 diff -u -r1.1.1.1.2.11 -r1.1.1.1.2.12 --- main.c 2001/07/24 13:23:54 1.1.1.1.2.11 +++ main.c 2001/07/26 00:33:03 1.1.1.1.2.12 @@ -42,6 +42,7 @@ #include "command.h" #include "flash.h" #include "led.h" +#include "linux.h" #include "main.h" #include "memory.h" #include "sa1100.h" @@ -52,40 +53,14 @@ -typedef enum { - fromFlash = 0, - fromDownload = 1 -} blockSource; - - - -typedef struct { - int kernelSize; - blockSource kernelType; - - int ramdiskSize; - blockSource ramdiskType; - - int blobSize; - blockSource blobType; - - u32 blockSize; - - eBauds downloadSpeed; -} blobStatus; - - - - -void BootKernel(char *commandline); -void Download(char *commandline, blobStatus *status); -void Flash(char *commandline, blobStatus *status); +void Download(char *commandline); +void Flash(char *commandline); void PrintHelp(void); -void SetDownloadSpeed(char *commandline, blobStatus *status); -void PrintStatus(blobStatus *status); +void SetDownloadSpeed(char *commandline); +void PrintStatus(void); void ResetTerminal(void); -void Reload(char *commandline, blobStatus *status); +void Reload(char *commandline); void PrintSerialSpeed(eBauds speed); void Reboot(void); void Reblob(void); @@ -93,12 +68,16 @@ +blob_status_t blob_status; + + + + int main(void) { u32 blockSize = 0x00800000; int numRead = 0; char commandline[128]; - blobStatus status; int i; int retval = 0; @@ -125,25 +104,25 @@ SerialOutputString("This is free software, and you are welcome " "to redistribute it\n"); SerialOutputString("under certain conditions; " - "read the GNU GPL for details.\n\n"); + "read the GNU GPL for details.\n"); /* get the amount of memory */ get_memory_map(); /* initialise status */ - status.kernelSize = 0; - status.kernelType = fromFlash; - status.ramdiskSize = 0; - status.ramdiskType = fromFlash; - status.blockSize = blockSize; - status.downloadSpeed = baud115k2; + 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", &status); - Reload("kernel", &status); - Reload("ramdisk", &status); + Reload("blob"); + Reload("kernel"); + Reload("ramdisk"); #ifdef BLOB_DEBUG /* print some information */ @@ -171,7 +150,7 @@ /* no key was pressed, so proceed booting the kernel */ if(retval == 0) { commandline[0] = '\0'; - BootKernel(commandline); + boot_linux(commandline); } SerialOutputString("\nAutoboot aborted\n"); @@ -186,13 +165,13 @@ if(numRead > 0) { if(MyStrNCmp(commandline, "boot", 4) == 0) { - BootKernel(commandline + 4); + boot_linux(commandline + 4); } else if(MyStrNCmp(commandline, "clock", 5) == 0) { SetClock(commandline + 5); } else if(MyStrNCmp(commandline, "download ", 9) == 0) { - Download(commandline + 9, &status); + Download(commandline + 9); } else if(MyStrNCmp(commandline, "flash ", 6) == 0) { - Flash(commandline + 6, &status); + Flash(commandline + 6); } else if(MyStrNCmp(commandline, "help", 4) == 0) { PrintHelp(); } else if(MyStrNCmp(commandline, "reblob", 6) == 0) { @@ -200,14 +179,14 @@ } else if(MyStrNCmp(commandline, "reboot", 6) == 0) { Reboot(); } else if(MyStrNCmp(commandline, "reload ", 7) == 0) { - Reload(commandline + 7, &status); + Reload(commandline + 7); } else if(MyStrNCmp(commandline, "reset", 5) == 0) { ResetTerminal(); } else if(MyStrNCmp(commandline, "speed ", 6) == 0) { - SetDownloadSpeed(commandline + 6, &status); + SetDownloadSpeed(commandline + 6); } else if(MyStrNCmp(commandline, "status", 6) == 0) { - PrintStatus(&status); + PrintStatus(); } else { SerialOutputString("*** Unknown command: "); SerialOutputString(commandline); @@ -217,62 +196,12 @@ } return 0; -} /* c_main */ - - - - -void BootKernel(char *commandline) -{ - register u32 i; - void (*theKernel)(int zero, int arch) = (void (*)(int, int))KERNEL_RAM_BASE; - -#warning "FIXME: should set kernel commandline parameters -- Erik" - -#ifdef BLOB_DEBUG - SerialOutputString("\n*** Ignoring kernel parameters\n"); -#endif - - /* we assume that the kernel is in place */ - /* See linux/include/asm-arm/system.h for architecture numbers */ - SerialOutputString("\nStarting kernel ...\n\n"); - - /* turn off I-cache */ - asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i)); - i &= ~0x1000; - asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i)); - - /* flush I-cache */ - asm ("mcr p15, 0, %0, c7, c5, 0": : "r" (i)); - -#if defined ASSABET - theKernel(0, 25); -#elif defined BRUTUS - theKernel(0, 16); -#elif defined CLART - theKernel(0, 68); -#elif defined LART - theKernel(0, 27); -#elif defined NESA - theKernel(0, 75); -#elif defined PLEB - theKernel(0, 20); -#elif defined SHANNON - theKernel(0, 97); -#else - /* Be generic and just tell the kernel that we are an SA1100 - architecture */ -#warning "Calling the kernel with a generic SA1100 architecture code. YMMV!" - theKernel(0,18); -#endif - - SerialOutputString("Hey, the kernel returned! This should not happen.\n"); -} +} /* main */ -void Download(char *commandline, blobStatus *status) +void Download(char *commandline) { u32 startAddress = 0; int bufLen; @@ -281,21 +210,21 @@ if(MyStrNCmp(commandline, "blob", 4) == 0) { /* download blob */ startAddress = BLOB_RAM_BASE; - bufLen = status->blockSize - BLOB_BLOCK_OFFSET; - numRead = &status->blobSize; - status->blobType = fromDownload; + 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 = status->blockSize - KERNEL_BLOCK_OFFSET; - numRead = &status->kernelSize; - status->kernelType = fromDownload; + 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 = status->blockSize - RAMDISK_BLOCK_OFFSET; - numRead = &status->ramdiskSize; - status->ramdiskType = fromDownload; + 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); @@ -305,13 +234,13 @@ SerialOutputString("Switching to "); - PrintSerialSpeed(status->downloadSpeed); + 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(status->downloadSpeed); + SerialInit(blob_status.downloadSpeed); *numRead = UUDecode((char *)startAddress, bufLen); @@ -322,7 +251,7 @@ SerialOutputString("*** Uudecode receive failed\n"); /* reload the correct memory */ - Reload(commandline, status); + Reload(commandline); SerialInit(baud9k6); return; @@ -340,7 +269,7 @@ -void Flash(char *commandline, blobStatus *status) +void Flash(char *commandline) { u32 startAddress = 0; tBlockType block; @@ -349,9 +278,9 @@ if(MyStrNCmp(commandline, "blob", 4) == 0) { startAddress = BLOB_RAM_BASE; block = blBlob; - numBytes = status->blobSize; + numBytes = blob_status.blobSize; - if(status->blobType == fromFlash) { + if(blob_status.blobType == fromFlash) { SerialOutputString("*** No blob downloaded\n"); return; } @@ -360,9 +289,9 @@ } else if(MyStrNCmp(commandline, "kernel", 6) == 0) { startAddress = KERNEL_RAM_BASE; block = blKernel; - numBytes = status->kernelSize; + numBytes = blob_status.kernelSize; - if(status->kernelType == fromFlash) { + if(blob_status.kernelType == fromFlash) { SerialOutputString("*** No kernel downloaded\n"); return; } @@ -371,9 +300,9 @@ } else if(MyStrNCmp(commandline, "ramdisk", 7) == 0) { startAddress = RAMDISK_RAM_BASE; block = blRamdisk; - numBytes = status->ramdiskSize; + numBytes = blob_status.ramdiskSize; - if(status->ramdiskType == fromFlash) { + if(blob_status.ramdiskType == fromFlash) { SerialOutputString("*** No ramdisk downloaded\n"); return; } @@ -417,32 +346,32 @@ -void SetDownloadSpeed(char *commandline, blobStatus *status) +void SetDownloadSpeed(char *commandline) { if(MyStrNCmp(commandline, "1200", 4) == 0) { - status->downloadSpeed = baud1k2; + blob_status.downloadSpeed = baud1k2; } else if(MyStrNCmp(commandline, "1k2", 3) == 0) { - status->downloadSpeed = baud1k2; + blob_status.downloadSpeed = baud1k2; } else if(MyStrNCmp(commandline, "9600", 4) == 0) { - status->downloadSpeed = baud9k6; + blob_status.downloadSpeed = baud9k6; } else if(MyStrNCmp(commandline, "9k6", 3) == 0) { - status->downloadSpeed = baud9k6; + blob_status.downloadSpeed = baud9k6; } else if(MyStrNCmp(commandline, "19200", 5) == 0) { - status->downloadSpeed = baud19k2; + blob_status.downloadSpeed = baud19k2; } else if(MyStrNCmp(commandline, "19k2", 4) == 0) { - status->downloadSpeed = baud19k2; + blob_status.downloadSpeed = baud19k2; } else if(MyStrNCmp(commandline, "38400", 5) == 0) { - status->downloadSpeed = baud38k4; + blob_status.downloadSpeed = baud38k4; } else if(MyStrNCmp(commandline, "38k4", 4) == 0) { - status->downloadSpeed = baud38k4; + blob_status.downloadSpeed = baud38k4; } else if(MyStrNCmp(commandline, "57600", 5) == 0) { - status->downloadSpeed = baud57k6; + blob_status.downloadSpeed = baud57k6; } else if(MyStrNCmp(commandline, "57k6", 4) == 0) { - status->downloadSpeed = baud57k6; + blob_status.downloadSpeed = baud57k6; } else if(MyStrNCmp(commandline, "115200", 6) == 0) { - status->downloadSpeed = baud115k2; + blob_status.downloadSpeed = baud115k2; } else if(MyStrNCmp(commandline, "115k2", 5) == 0) { - status->downloadSpeed = baud115k2; + blob_status.downloadSpeed = baud115k2; } else { SerialOutputString("*** Invalid download speed value \""); SerialOutputString(commandline); @@ -452,14 +381,14 @@ } SerialOutputString("Download speed set to "); - PrintSerialSpeed(status->downloadSpeed); + PrintSerialSpeed(blob_status.downloadSpeed); SerialOutputString(" baud\n"); } -void PrintStatus(blobStatus *status) +void PrintStatus(void) { SerialOutputString("Bootloader : " PACKAGE "\n"); SerialOutputString("Version : " VERSION "\n"); @@ -471,36 +400,36 @@ SerialOutputString("external"); SerialOutputString(" flash\nBlocksize : 0x"); - SerialOutputHex(status->blockSize); + SerialOutputHex(blob_status.blockSize); SerialOutputString("\nDownload speed: "); - PrintSerialSpeed(status->downloadSpeed); + PrintSerialSpeed(blob_status.downloadSpeed); SerialOutputString(" baud\n"); SerialOutputString("Blob : "); - if(status->blobType == fromFlash) { + if(blob_status.blobType == fromFlash) { SerialOutputString("from flash\n"); } else { SerialOutputString("downloaded, "); - SerialOutputDec(status->blobSize); + SerialOutputDec(blob_status.blobSize); SerialOutputString(" bytes\n"); } SerialOutputString("Kernel : "); - if(status->kernelType == fromFlash) { + if(blob_status.kernelType == fromFlash) { SerialOutputString("from flash\n"); } else { SerialOutputString("downloaded, "); - SerialOutputDec(status->kernelSize); + SerialOutputDec(blob_status.kernelSize); SerialOutputString(" bytes\n"); } SerialOutputString("Ramdisk : "); - if(status->ramdiskType == fromFlash) { + if(blob_status.ramdiskType == fromFlash) { SerialOutputString("from flash\n"); } else { SerialOutputString("downloaded, "); - SerialOutputDec(status->ramdiskSize); + SerialOutputDec(blob_status.ramdiskSize); SerialOutputString(" bytes\n"); } } @@ -523,7 +452,7 @@ -void Reload(char *commandline, blobStatus *status) +void Reload(char *commandline) { u32 *src = 0; u32 *dst = 0; @@ -533,22 +462,22 @@ src = (u32 *)BLOB_RAM_BASE; dst = (u32 *)BLOB_START; numWords = BLOB_LEN / 4; - status->blobSize = 0; - status->blobType = fromFlash; + 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; - status->kernelSize = 0; - status->kernelType = fromFlash; + 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; - status->ramdiskSize = 0; - status->ramdiskType = fromFlash; + blob_status.ramdiskSize = 0; + blob_status.ramdiskType = fromFlash; SerialOutputString("Loading ramdisk from flash "); } else { SerialOutputString("*** Don't know how to reload \""); Index: memory.c =================================================================== RCS file: /cvsroot/blob/blob/src/Attic/memory.c,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -r1.1.2.1 -r1.1.2.2 --- memory.c 2001/07/22 22:54:26 1.1.2.1 +++ memory.c 2001/07/26 00:33:03 1.1.2.2 @@ -56,9 +56,6 @@ memory_map[i].used = 0; /* first write a 0 to all memory locations */ - /* this will overwrite the first word of the second stage - * bootloader, but that's a branch to main() anyway - */ for(addr = MEMORY_START; addr < MEMORY_END; addr += TEST_BLOCK_SIZE) * (u32 *)addr = 0; @@ -108,11 +105,11 @@ if(memory_map[i].used) { SerialOutputString(" 0x"); SerialOutputHex(memory_map[i].len); + SerialOutputString(" @ 0x"); + SerialOutputHex(memory_map[i].start); SerialOutputString(" ("); SerialOutputDec(memory_map[i].len / (1024 * 1024)); - SerialOutputString(" MB) @ 0x"); - SerialOutputHex(memory_map[i].start); - SerialOutputByte('\n'); + SerialOutputString(" MB)\n"); } } } Index: rest-ld-script =================================================================== RCS file: /cvsroot/blob/blob/src/Attic/rest-ld-script,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -r1.1.2.1 -r1.1.2.2 --- rest-ld-script 2001/07/08 22:34:14 1.1.2.1 +++ rest-ld-script 2001/07/26 00:33:03 1.1.2.2 @@ -15,7 +15,7 @@ ENTRY(_trampoline) SECTIONS { - . = 0xc0000000; + . = 0xc0000400; . = ALIGN(4); .text : { *(.text) } Index: start.S =================================================================== RCS file: /cvsroot/blob/blob/src/start.S,v retrieving revision 1.1.1.1.2.12 retrieving revision 1.1.1.1.2.13 diff -u -r1.1.1.1.2.12 -r1.1.1.1.2.13 --- start.S 2001/07/24 13:23:54 1.1.1.1.2.12 +++ start.S 2001/07/26 00:33:03 1.1.1.1.2.13 @@ -175,6 +175,7 @@ add r2, r0, #(128 * 1024) /* blob is 128kB */ add r0, r0, #0x400 /* skip first 1024 bytes */ ldr r1, MEM_START + add r1, r1, #0x400 /* skip over here as well */ /* r0 = source address * r1 = target address Index: util.c =================================================================== RCS file: /cvsroot/blob/blob/src/util.c,v retrieving revision 1.1.1.1.2.1 retrieving revision 1.1.1.1.2.2 diff -u -r1.1.1.1.2.1 -r1.1.1.1.2.2 --- util.c 2001/07/22 23:55:22 1.1.1.1.2.1 +++ util.c 2001/07/26 00:33:03 1.1.1.1.2.2 @@ -126,3 +126,25 @@ return(c); } + + +int strlen(const char *s) +{ + int i = 0; + + for(;*s != '\0'; s++) + i++; + + return i; +} + + +char *strcpy(char *dest, const char *src) +{ + while(*src != '\0') + *dest++ = *src++; + + *dest = '\0'; + + return dest; +} |