Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

genlds.c

Go to the documentation of this file.
00001 
00006 /*
00007  *  The contents of this file are subject to the Mozilla Public License
00008  *  Version 1.0 (the "License"); you may not use this file except in
00009  *  compliance with the License. You may obtain a copy of the License at
00010  *  http://www.mozilla.org/MPL/
00011  *
00012  *  Software distributed under the License is distributed on an "AS IS"
00013  *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
00014  *  License for the specific language governing rights and limitations
00015  *  under the License.
00016  *
00017  *  The Original Code is legOS code, released October 2, 1999.
00018  *
00019  *  The Initial Developer of the Original Code is Markus L. Noga.
00020  *  Portions created by Markus L. Noga are Copyright (C) 2000
00021  *  Markus L. Noga. All Rights Reserved.
00022  *
00023  *  Contributor(s): Markus L. Noga <markus@noga.de>
00024  */
00025  
00026 #include <stdio.h>
00027 #include <time.h>
00028 #include <string.h>
00029 
00030 #define MAX_SYMBOLS 65536               
00031 #define MAX_SYMLEN  256                 
00032 
00033 
00034 typedef struct {
00035   unsigned addr;
00036   char text[MAX_SYMLEN];
00037 } symbol_t;
00038 
00040 symbol_t symbols[MAX_SYMBOLS];
00041 
00043 static unsigned read_symbols(FILE *f,symbol_t *symbols,unsigned max,unsigned *ram) {
00044   char buffer[MAX_SYMLEN];
00045   unsigned i=0;
00046   
00047   for(; i<max; ) {
00048     char symtype;
00049     
00050     if(!fgets(buffer,MAX_SYMLEN,f))
00051       break;
00052     
00053     buffer[MAX_SYMLEN-1]=0;
00054     sscanf(buffer,"%x %c %s",&(symbols[i].addr),&symtype,symbols[i].text);
00055 
00056     // keep global symbols
00057     //
00058     if(symtype=='T' || symtype=='D' || symtype=='B') {
00059       // check for start of user RAM
00060       //
00061       if(!strcmp(symbols[i].text,"_mm_start"))
00062         *ram=symbols[i].addr+2;
00063       
00064       // skip special symbols
00065       //
00066       if(!strcmp(symbols[i].text,"_main"))
00067         continue;
00068       if(!strncmp(symbols[i].text,"___text",7))
00069         continue;
00070       if(!strncmp(symbols[i].text,"___data",7))
00071         continue;
00072       if(!strncmp(symbols[i].text,"___bss" ,6))
00073         continue;
00074       
00075       i++;
00076     }
00077   }
00078   
00079   return i;
00080 }
00081 
00082 
00084 static void print_symbols(FILE *f,symbol_t *symbols,unsigned num_symbols) {
00085   unsigned i;
00086   for(i=0; i<num_symbols; i++)
00087     fprintf(f,"    %s = 0x%04x ;\n",symbols[i].text,symbols[i].addr-0x8000);
00088 }
00089 
00090 
00092 static void print_header(FILE *f,
00093                          const char *now,const char *kernel_name,
00094                          unsigned ram,unsigned kernlen, unsigned ramlen) {
00095     fprintf(f,
00096 "/*\n\
00097  * \n\
00098  *  dynamic linker command file\n\
00099  *  generated: %s\n\
00100  *  kernel   : %s\n\
00101  *  app start: 0x%04x\n\
00102  * \n\
00103  *  BrickOS for LEGO(R) Mindstorms(TM)\n\
00104  *  Originally: legOS - the independent LEGO Mindstorms OS\n\
00105  *              (c) 1999 by Markus L. Noga <markus@noga.de>    \n\
00106  * \n\
00107  */\n\
00108 \n\
00109 OUTPUT_FORMAT(\"symbolsrec\")\n\
00110 OUTPUT_ARCH(h8300)\n\
00111 ENTRY(\"_main\")\n\
00112 \n\
00113 MEMORY {\n\
00114   rom   : o = 0x0000, l = 0x8000\n\
00115   kern  : o = 0x8000, l = 0x%04x\n\
00116   ram   : o = 0x%04x, l = 0x%04x\n\
00117   stack : o = 0xfefc, l = 0x0004\n\
00118   eight : o = 0xff00, l = 0x0100\n\
00119 }\n\
00120 \n\
00121 SECTIONS {\n\
00122 \n\
00123   .rom : {\n\
00124     /* used rom functions */\n\
00125     \n\
00126     _rom_reset_vector = 0x0000;\n\
00127         \n\
00128     _reset        = 0x03ae ;\n\
00129     lcd_show      = 0x1b62 ;\n\
00130     lcd_hide      = 0x1e4a ;\n\
00131     lcd_number    = 0x1ff2 ;\n\
00132     lcd_clear     = 0x27ac ;\n\
00133     power_init    = 0x2964 ;\n\
00134     sound_system  = 0x299a ;\n\
00135     power_off     = 0x2a62 ;\n\
00136     sound_playing = 0x3ccc ;\n\
00137 \n\
00138     _rom_dummy_handler   = 0x046a ;\n\
00139     _rom_ocia_handler    = 0x04cc ;\n\
00140     _rom_ocia_return     = 0x04d4 ;\n\
00141     \n\
00142   } > rom\n\
00143 \n\
00144   .kernel :     {\n\
00145     /* kernel symbols (relative to 0x8000) */\n\
00146 ",
00147     now,kernel_name,ram,
00148     kernlen,ram,ramlen);
00149 }
00150 
00151 
00153 static void print_footer(FILE *f) {
00154   fprintf(f,
00155 "    /* end of kernel symbols */\n\
00156   }  > kern\n\
00157       \n\
00158   .text BLOCK(2) :      {\n\
00159     ___text = . ;\n\
00160     *(.text)          /* must start with text for clean entry */                        \n\
00161     *(.rodata)\n\
00162     *(.strings)\n\
00163     *(.vectors)       /* vectors region (dummy) */\n\
00164     *(.persist)\n\
00165 \n\
00166     ___text_end = . ;\n\
00167   }  > ram\n\
00168 \n\
00169   .tors BLOCK(2) : {\n\
00170     ___ctors = . ;\n\
00171     *(.ctors)\n\
00172     ___ctors_end = . ;\n\
00173     ___dtors = . ;\n\
00174     *(.dtors)\n\
00175     ___dtors_end = . ;\n\
00176   }  > ram\n\
00177 \n\
00178   .data BLOCK(2) : {\n\
00179     ___data = . ;\n\
00180     *(.data)\n\
00181     *(.tiny)\n\
00182     ___data_end = . ;\n\
00183   }  > ram\n\
00184 \n\
00185   .bss BLOCK(2) : {\n\
00186     ___bss = . ;\n\
00187     *(.bss)\n\
00188     *(COMMON)\n\
00189     ___bss_end = ALIGN(2) ;\n\
00190   }  >ram\n\
00191 \n\
00192   .stack : {\n\
00193     _stack = . ; \n\
00194     *(.stack)\n\
00195   }  > topram\n\
00196 \n\
00197   .eight 0xff00: {\n\
00198     *(.eight)\n\
00199 \n\
00200     /* on-chip module registers (relative to 0xff00) */\n\
00201 \n\
00202     _T_IER = 0x90 ;\n\
00203     _T_CSR = 0x91 ;\n\
00204     _T_CNT = 0x92 ;\n\
00205     _T_OCRA = 0x94 ;\n\
00206     _T_OCRB = 0x94 ;\n\
00207     _T_CR = 0x96 ;\n\
00208     _T_OCR = 0x97 ;\n\
00209     _T_ICRA = 0x98 ;\n\
00210     _T_ICRB = 0x9a ;\n\
00211     _T_ICRC = 0x9c ;\n\
00212     _T_ICRD = 0x9e ;\n\
00213     _WDT_CSR = 0xa8 ;\n\
00214     _WDT_CNT = 0xa9 ;\n\
00215     _PORT1_PCR = 0xac ;\n\
00216     _PORT2_PCR = 0xad ;\n\
00217     _PORT3_PCR = 0xae ;\n\
00218     _PORT1_DDR = 0xb0 ;\n\
00219     _PORT2_DDR = 0xb1 ;\n\
00220     _PORT1 = 0xb2 ;\n\
00221     _PORT2 = 0xb3 ;\n\
00222     _PORT3_DDR = 0xb4 ;\n\
00223     _PORT4_DDR = 0xb5 ;\n\
00224     _PORT3 = 0xb6 ;\n\
00225     _PORT4 = 0xb7 ;\n\
00226     _PORT5_DDR = 0xb8 ;\n\
00227     _PORT6_DDR = 0xb9 ;\n\
00228     _PORT5 = 0xba ;\n\
00229     _PORT6 = 0xbb ;\n\
00230     _PORT7 = 0xbe ;\n\
00231     _STCR = 0xc3 ;\n\
00232     _SYSCR = 0xc4 ;\n\
00233     _T0_CR = 0xc8 ;\n\
00234     _T0_CSR = 0xc9 ;\n\
00235     _T0_CORA = 0xca ;\n\
00236     _T0_CORB = 0xcb ;\n\
00237     _T0_CNT = 0xcc ;\n\
00238     _T1_CR = 0xd0 ;\n\
00239     _T1_CSR = 0xd1 ;\n\
00240     _T1_CORA = 0xd2 ;\n\
00241     _T1_CORB = 0xd3 ;\n\
00242     _T1_CNT = 0xd4 ;\n\
00243     _S_MR = 0xd8 ;\n\
00244     _S_BRR = 0xd9 ;\n\
00245     _S_CR = 0xda ;\n\
00246     _S_TDR = 0xdb ;\n\
00247     _S_SR = 0xdc ;\n\
00248     _S_RDR = 0xdd ;\n\
00249     _AD_A = 0xe0 ;\n\
00250     _AD_A_H = 0xe0 ;\n\
00251     _AD_A_L = 0xe1 ;\n\
00252     _AD_B = 0xe2 ;\n\
00253     _AD_B_H = 0xe2 ;\n\
00254     _AD_B_L = 0xe3 ;\n\
00255     _AD_C = 0xe4 ;\n\
00256     _AD_C_H = 0xe4 ;\n\
00257     _AD_C_L = 0xe5 ;\n\
00258     _AD_D = 0xe6 ;\n\
00259     _AD_D_H = 0xe6 ;\n\
00260     _AD_D_L = 0xe7 ;\n\
00261     _AD_CSR = 0xe8 ;\n\
00262     _AD_CR = 0xe9 ;\n\
00263     \n\
00264     /* end of on-chip module registers */\n\
00265     \n\
00266   }  > eight\n\
00267 \n\
00268   .stab 0 (NOLOAD) : {\n\
00269     [ .stab ]\n\
00270   }\n\
00271 \n\
00272   .stabstr 0 (NOLOAD) : {\n\
00273     [ .stabstr ]\n\
00274   }\n\
00275 \n\
00276 } /* SECTIONS */\n\
00277 "
00278     ); 
00279 }
00280 
00281 
00282 int main(int argc, char *argv[]) {
00283   const char *kernel_name;
00284   unsigned num_symbols;
00285   unsigned ram,kernlen,ramlen;
00286   time_t now_time;
00287   char *now;
00288   
00289   // determine kernel name
00290   //
00291   if(argc<2) {
00292     fprintf(stderr,"usage: %s kernelname < kernel.map\n",argv[0]);
00293     return -1;
00294   }
00295   kernel_name=argv[1];
00296 
00297   // parse kernel symbols
00298   //   
00299   num_symbols=read_symbols(stdin,symbols,MAX_SYMBOLS,&ram);
00300   
00301   // calculate kernel and ram size
00302   //
00303   kernlen=ram    - 0x8000;
00304   ramlen =0xfefc - ram;
00305  
00306   // create timestamp
00307   //
00308   now_time=time(NULL); 
00309   now     =ctime(&now_time);
00310 
00311   // print linker script
00312   //
00313   print_header (stdout,now,kernel_name,ram,kernlen,ramlen);
00314   print_symbols(stdout,symbols,num_symbols);
00315   print_footer (stdout);
00316   
00317   return 0;
00318 }

Generated on Fri Feb 25 08:02:39 2005 for brickos by  doxygen 1.3.9.1