1 /* tag: forth bootstrap environment
3 * Copyright (C) 2003-2006 Stefan Reinauer, Patrick Mauritz
5 * See the file "COPYING" for further information about
6 * the copyright and warranty status of this work.
9 #include "sysinclude.h"
25 #include "kernel/stack.h"
26 #include "sysinclude.h"
27 #include "kernel/kernel.h"
30 #include "openbios-version.h"
32 #define MAX_PATH_LEN 256
34 #define MEMORY_SIZE (1024*1024) /* 1M ram for hosted system */
35 #define DICTIONARY_SIZE (256*1024) /* 256k for the dictionary */
36 #define TRAMPOLINE_SIZE (4*sizeof(cell)) /* 4 cells for the trampoline */
39 static ucell
*latest
, *state
, *base
;
44 static int errors
= 0;
45 static int segfault
= 0;
46 static int verbose
= 0;
48 #define MAX_SRC_FILES 128
50 static FILE *srcfiles
[MAX_SRC_FILES
];
51 static char *srcfilenames
[MAX_SRC_FILES
];
52 static int srclines
[MAX_SRC_FILES
];
53 static unsigned int cursrc
= 0;
55 static char *srcbasedict
;
57 /* console variables */
60 #ifdef NATIVE_BITWIDTH_SMALLER_THAN_HOST_BITWIDTH
61 unsigned long base_address
;
64 /* include path handling */
65 typedef struct include_path include
;
71 static include includes
= { ".", NULL
};
74 static ucell
* relocation_address
=NULL
;
75 static int relocation_length
=0;
77 /* the word names are used to generate the prim words in the
78 * dictionary. This is done by the C written interpreter.
80 static const char *wordnames
[] = {
81 "(semis)", "", "(lit)", "", "", "", "", "(do)", "(?do)", "(loop)",
82 "(+loop)", "", "", "", "dup", "2dup", "?dup", "over", "2over", "pick", "drop",
83 "2drop", "nip", "roll", "rot", "-rot", "swap", "2swap", ">r", "r>",
84 "r@", "depth", "depth!", "rdepth", "rdepth!", "+", "-", "*", "u*",
85 "mu/mod", "abs", "negate", "max", "min", "lshift", "rshift", ">>a",
86 "and", "or", "xor", "invert", "d+", "d-", "m*", "um*", "@", "c@",
87 "w@", "l@", "!", "+!", "c!", "w!", "l!", "=", ">", "<", "u>", "u<",
88 "sp@", "move", "fill", "(emit)", "(key?)", "(key)", "execute",
89 "here", "here!", "dobranch", "do?branch", "unaligned-w@",
90 "unaligned-w!", "unaligned-l@", "unaligned-l!", "ioc@", "iow@",
91 "iol@", "ioc!", "iow!", "iol!", "i", "j", "call", "sys-debug",
92 "$include", "$encode-file", "(debug", "(debug-off)"
96 * dictionary related functions.
99 static void relocation_table(unsigned char * dict_one
, unsigned char *dict_two
, int length
)
101 ucell
*d1
=(ucell
*)dict_one
, *d2
=(ucell
*)dict_two
;
104 int l
=(length
+(sizeof(cell
)-1))/sizeof(ucell
), i
;
106 /* prepare relocation table */
107 relocation_length
=(length
+BITS
-1)/BITS
;
108 reloc_table
= malloc(relocation_length
*sizeof(cell
));
109 memset(reloc_table
,0,relocation_length
*sizeof(cell
));
111 for (i
=0; i
<l
; i
++) {
117 reloc_table
[pos
] &= target_ucell(~((ucell
)1ULL << bit
));
119 // This check might bring false positives in data.
120 //if(d1[i] >= pointer2cell(dict_one) &&
121 // d1[i] <= pointer2cell(dict_one+length))
122 // printk("\nWARNING: inconsistent relocation (%x:%x)!\n", d1[i], d2[i]);
124 /* This is a pointer, it needs relocation, d2==dict */
125 reloc_table
[pos
] |= target_ucell((ucell
)1ULL << bit
);
126 d2
[i
] = target_ucell(target_ucell(d2
[i
]) - pointer2cell(d2
));
130 #ifdef CONFIG_DEBUG_DICTIONARY
131 printk("dict1 %lx dict2 %lx dict %lx\n",dict_one
, dict_two
, dict
);
132 for (i
=0; i
< relocation_length
; i
++)
133 printk("reloc %d %lx\n",i
+1, reloc_table
[i
]);
135 relocation_address
=reloc_table
;
138 static void write_dictionary(const char *filename
)
141 unsigned char *write_data
, *walk_data
;
143 dictionary_header_t
*header
;
147 * get memory for dictionary
150 write_len
= sizeof(dictionary_header_t
)+dicthead
+relocation_length
*sizeof(cell
);
151 write_data
= malloc(write_len
);
153 printk("panic: can't allocate memory for output dictionary (%d"
154 " bytes\n", write_len
);
157 memset(write_data
, 0, write_len
);
160 * prepare dictionary header
163 header
= (dictionary_header_t
*)write_data
;
164 *header
= (dictionary_header_t
){
167 .cellsize
= sizeof(ucell
),
168 #ifdef CONFIG_BIG_ENDIAN
176 .length
= target_ulong((uint32_t)dicthead
),
177 .last
= target_ucell((ucell
)((unsigned long)last
178 - (unsigned long)dict
)),
182 * prepare dictionary data
185 walk_data
=write_data
+sizeof(dictionary_header_t
);
186 memcpy (walk_data
, dict
, dicthead
);
189 * prepare relocation data.
190 * relocation_address is zero when writing a dictionary core.
193 if (relocation_address
) {
194 #ifdef CONFIG_DEBUG_DICTIONARY
195 printk("writing %d reloc cells \n",relocation_length
);
197 walk_data
+= dicthead
;
198 memcpy(walk_data
, relocation_address
,
199 relocation_length
*sizeof(cell
));
200 /* free relocation information */
201 free(relocation_address
);
202 relocation_address
=NULL
;
204 header
->relocation
=0;
211 walk_data
=write_data
;
212 while (walk_data
<write_data
+write_len
) {
213 checksum
+=read_long(walk_data
);
214 walk_data
+=sizeof(u32
);
216 checksum
=(u32
)-checksum
;
218 header
->checksum
=target_long(checksum
);
224 f
= fopen(filename
, "w");
226 printk("panic: can't write to dictionary '%s'.\n", filename
);
230 fwrite(write_data
, write_len
, 1, f
);
235 #ifdef CONFIG_DEBUG_DICTIONARY
236 printk("wrote dictionary to file %s.\n", filename
);
240 static ucell
read_dictionary(char *fil
)
248 if (stat(fil
, &finfo
))
251 ilen
= finfo
.st_size
;
253 if ((mem
= malloc(ilen
)) == NULL
) {
254 printk("panic: not enough memory.\n");
260 printk("panic: can't open dictionary.\n");
264 if (fread(mem
, ilen
, 1, f
) != 1) {
265 printk("panic: can't read dictionary.\n");
271 ret
= load_dictionary(mem
, ilen
);
279 * C Parser related functions
283 * skipws skips all whitespaces (space, tab, newline) from the input file
286 static void skipws(FILE * f
)
292 if (c
== ' ' || c
== '\t')
296 srclines
[cursrc
- 1]++;
306 * parse gets the next word from the input stream, delimited by
307 * delim. If delim is 0, any word delimiter will end the stream
308 * word delimiters are space, tab and newline. The resulting word
309 * will be put zero delimited to the char array line.
312 static int parse(FILE * f
, char *line
, char delim
)
319 if (delim
&& c
== delim
)
322 if ((!delim
) && (c
== ' ' || c
== '\t' || c
== '\n'))
328 /* Update current line number */
330 srclines
[cursrc
- 1]++;
339 * parse_word is a small helper that skips whitespaces before a word.
340 * it's behaviour is similar to the forth version parse-word.
343 static void parse_word(FILE * f
, char *line
)
350 static void writestring(const char *str
)
353 for (i
= 0; i
< strlen(str
); i
++) {
354 dict
[dicthead
+ i
] = str
[i
];
357 dict
[dicthead
- 1] = (char) strlen(str
) + 128;
360 #define writebyte(value) {write_byte(dict+dicthead,value); dicthead++;}
361 #define writecell(value) {write_cell(dict+dicthead, value); dicthead+=sizeof(cell);}
364 * reveal a word, ie. make it visible.
367 static void reveal(void)
376 static void paddict(ucell align
)
378 while (dicthead
% align
!= 0)
383 * generic forth word creator function.
386 static void fcreate(const char *word
, ucell cfaval
)
388 if (strlen(word
) == 0) {
389 printk("WARNING: tried to create unnamed word.\n");
394 /* get us at least 1 byte for flags */
396 paddict(sizeof(cell
));
397 /* set flags high bit. */
398 dict
[dicthead
- 1] = 128;
400 writecell(read_ucell(latest
));
401 *latest
= target_ucell(pointer2cell(dict
) + dicthead
- sizeof(cell
));
406 static ucell
*buildvariable(const char *name
, cell defval
)
408 fcreate(name
, DOVAR
); /* see dict.h for DOVAR and other CFA ids */
410 return (ucell
*) (dict
+ dicthead
- sizeof(cell
));
413 static void buildconstant(const char *name
, cell defval
)
415 fcreate(name
, DOCON
); /* see dict.h for DOCON and other CFA ids */
419 static void builddefer(const char *name
)
421 fcreate(name
, DODFR
); /* see dict.h for DODFR and other CFA ids */
423 writecell((ucell
)findword("(semis)"));
427 * Include file handling
430 static void add_includepath(char *path
)
432 include
*incl
= &includes
;
438 newpath
= malloc(sizeof(include
));
440 printk("panic: not enough memory for include path.\n");
444 incl
->next
= newpath
;
445 newpath
->path
= path
;
446 newpath
->next
= NULL
;
450 static FILE *fopen_include(const char *fil
)
452 char fullpath
[MAX_PATH_LEN
];
454 include
*incl
= &includes
;
457 snprintf(fullpath
, sizeof(fullpath
), "%s/%s", incl
->path
, fil
);
459 ret
= fopen(fullpath
, "r");
462 #ifdef CONFIG_DEBUG_INTERPRETER
463 printk("Including '%s'\n", name
);
465 srcfilenames
[cursrc
] = strdup(fil
);
466 srclines
[ cursrc
] = 1;
467 srcfiles
[ cursrc
++ ] = ret
;
470 fprintf(depfile
, " %s", fullpath
);
483 * Forth exception handler
486 void exception(cell no
)
488 printk("%s:%d: ", srcfilenames
[cursrc
- 1], srclines
[cursrc
- 1]);
490 /* See also forth/bootstrap/interpreter.fs */
494 printk("Aborted.\n");
497 printk("Stack Overflow.\n");
500 printk("Stack Underflow.\n");
503 printk("Return Stack Overflow.\n");
506 printk("Return Stack Underflow.\n");
509 printk("undefined word.\n");
512 printk("out of memory.\n");
515 printk("undefined method.\n");
518 printk("no such device.\n");
521 printk("error %" FMT_CELL_d
" occured.\n", no
);
528 * This is the C version of the forth interpreter
531 static int interpret_source(char *fil
)
538 const ucell SEMIS
= (ucell
)findword("(semis)");
539 const ucell LIT
= (ucell
)findword("(lit)");
540 const ucell DOBRANCH
= (ucell
)findword("dobranch");
542 if ((f
= fopen_include(fil
)) == NULL
) {
543 printk("error while loading source file '%s'\n", fil
);
548 /* FIXME: We should read this file at
549 * once. No need to get it char by char
556 /* if there is actually no word, we continue right away */
557 if (strlen(tib
) == 0) {
561 /* Checking for builtin words that are needed to
562 * bootstrap the forth base dictionary.
565 if (!strcmp(tib
, "(")) {
570 if (!strcmp(tib
, "\\")) {
575 if (!strcmp(tib
, ":")) {
578 #ifdef CONFIG_DEBUG_INTERPRETER
579 printk("create colon word %s\n\n", tib
);
581 fcreate(tib
, DOCOL
); /* see dict.h for DOCOL and other CFA ids */
582 *state
= (ucell
) (-1);
586 if (!strcmp(tib
, ";")) {
587 #ifdef CONFIG_DEBUG_INTERPRETER
588 printk("finish colon definition\n\n");
590 writecell((cell
)SEMIS
);
596 if (!strcasecmp(tib
, "variable")) {
598 #ifdef CONFIG_DEBUG_INTERPRETER
599 printk("defining variable %s\n\n", tib
);
601 buildvariable(tib
, 0);
606 if (!strcasecmp(tib
, "constant")) {
608 #ifdef CONFIG_DEBUG_INTERPRETER
609 printk("defining constant %s\n\n", tib
);
611 buildconstant(tib
, POP());
616 if (!strcasecmp(tib
, "value")) {
618 #ifdef CONFIG_DEBUG_INTERPRETER
619 printk("defining value %s\n\n", tib
);
621 buildconstant(tib
, POP());
626 if (!strcasecmp(tib
, "defer")) {
628 #ifdef CONFIG_DEBUG_INTERPRETER
629 printk("defining defer word %s\n\n", tib
);
636 if (!strcasecmp(tib
, "include")) {
638 #ifdef CONFIG_DEBUG_INTERPRETER
639 printk("including file %s\n\n", tib
);
641 interpret_source(tib
);
645 if (!strcmp(tib
, "[']")) {
650 #ifdef CONFIG_DEBUG_INTERPRETER
652 ("writing address of %s to stack\n\n",
657 #ifdef CONFIG_DEBUG_INTERPRETER
658 printk("writing lit, addr(%s) to dict\n\n",
661 writecell(LIT
); /* lit */
665 /* we have no error detection here */
668 if (!strcasecmp(tib
, "s\"")) {
672 cnt
= parse(f
, tib
, '"');
673 #ifdef CONFIG_DEBUG_INTERPRETER
674 printk("compiling string %s\n", tib
);
676 loco
= dicthead
+ (6 * sizeof(cell
));
678 writecell(pointer2cell(dict
) + loco
);
680 writecell((ucell
)cnt
);
682 loco
= cnt
+ sizeof(cell
) - 1;
683 loco
&= ~(sizeof(cell
) - 1);
685 memcpy(dict
+ dicthead
, tib
, cnt
);
687 paddict(sizeof(cell
));
691 /* look if tib is in dictionary. */
692 /* should the dictionary be searched before the builtins ? */
695 u8 flags
= read_byte((u8
*)cell2pointer(res
) -
697 #ifdef CONFIG_DEBUG_INTERPRETER
698 printk("%s is 0x%" FMT_CELL_x
"\n", tib
, (ucell
) res
);
700 if (!(*state
) || (flags
& 3)) {
701 #ifdef CONFIG_DEBUG_INTERPRETER
702 printk("executing %s, %" FMT_CELL_d
705 (flags
& 1) ? "immediate" : "",
706 (flags
& 2) ? "compile-only" : "");
711 #ifdef CONFIG_DEBUG_INTERPRETER
712 printk("writing %s to dict\n\n", tib
);
714 writecell((cell
)res
);
719 /* if not look if it's a number */
721 num
= strtoll(tib
, &test
, read_ucell(base
));
723 num
= strtoull(tib
, &test
, read_ucell(base
));
728 printk("%s:%d: %s is not defined.\n\n", srcfilenames
[cursrc
- 1], srclines
[cursrc
- 1], tib
);
730 #ifdef CONFIG_DEBUG_INTERPRETER
738 #ifdef CONFIG_DEBUG_INTERPRETER
739 printk("pushed %" FMT_CELL_x
" to stack\n\n", num
);
743 #ifdef CONFIG_DEBUG_INTERPRETER
744 printk("writing lit, %" FMT_CELL_x
" to dict\n\n", num
);
746 writecell(LIT
); /* lit */
757 static int build_dictionary(void)
762 /* we need a temporary place for latest outside the dictionary */
765 /* starting a new dictionary: clear dicthead */
768 #ifdef CONFIG_DEBUG_DICTIONARY
769 printk("building dictionary, %d primitives.\nbuilt words:",
770 sizeof(wordnames
) / sizeof(void *));
773 for (i
= 0; i
< sizeof(wordnames
) / sizeof(void *); i
++) {
774 if (strlen(wordnames
[i
]) != 0) {
775 fcreate((char *) wordnames
[i
], i
);
776 #ifdef CONFIG_DEBUG_DICTIONARY
777 printk(" %s", wordnames
[i
]);
781 #ifdef CONFIG_DEBUG_DICTIONARY
785 /* get last/latest and state */
786 state
= buildvariable("state", 0);
787 last
= buildvariable("forth-last", 0);
788 latest
= buildvariable("latest", 0);
790 *latest
= target_ucell(pointer2cell(latest
)-2*sizeof(cell
));
792 base
=buildvariable("base", 10);
794 buildconstant("/c", sizeof(u8
));
795 buildconstant("/w", sizeof(u16
));
796 buildconstant("/l", sizeof(u32
));
797 buildconstant("/n", sizeof(ucell
));
798 buildconstant("/x", sizeof(u64
));
802 printk("Dictionary initialization finished.\n");
808 * functions used by primitives
815 interruptforth
|= FORTH_INTSTAT_STOP
;
816 /* return -1 in order to exit the loop in key() */
820 tmp
= getc( srcfiles
[cursrc
-1] );
822 ungetc(tmp
, srcfiles
[cursrc
-1]);
826 fclose(srcfiles
[--cursrc
]);
831 int get_inputbyte( void )
836 interruptforth
|= FORTH_INTSTAT_STOP
;
840 tmp
= getc( srcfiles
[cursrc
-1] );
842 /* Update current line number */
844 srclines
[cursrc
- 1]++;
851 fclose(srcfiles
[--cursrc
]);
853 return get_inputbyte();
856 void put_outputbyte( int c
)
863 * segmentation fault handler. linux specific?
867 segv_handler(int signo
__attribute__ ((unused
)),
868 siginfo_t
* si
, void *context
__attribute__ ((unused
)))
870 static int count
= 0;
871 ucell addr
= 0xdeadbeef;
874 printk("Died while dumping forth dictionary core.\n");
880 if (PC
>= pointer2cell(dict
) && PC
<= pointer2cell(dict
) + dicthead
)
881 addr
= read_cell(cell2pointer(PC
));
883 printk("panic: segmentation violation at %p\n", (char *)si
->si_addr
);
884 printk("dict=%p here=%p(dict+0x%" FMT_CELL_x
") pc=0x%" FMT_CELL_x
"(dict+0x%" FMT_CELL_x
")\n",
885 dict
, dict
+ dicthead
, dicthead
, PC
, PC
- pointer2cell(dict
));
886 printk("dstackcnt=%d rstackcnt=%d instruction=%" FMT_CELL_x
"\n",
887 dstackcnt
, rstackcnt
, addr
);
892 printk("Writing dictionary core file\n");
893 write_dictionary("forth.dict.core");
900 * allocate memory and prepare engine for memory management.
903 static void init_memory(void)
905 memset(memory
, 0, MEMORY_SIZE
);
907 /* we push start and end of memory to the stack
908 * so that it can be used by the forth word QUIT
909 * to initialize the memory allocator.
910 * Add a cell to the start address so we don't end
911 * up with a start address of zero during bootstrap
914 PUSH(pointer2cell(memory
)+sizeof(cell
));
915 PUSH(pointer2cell(memory
) + MEMORY_SIZE
-1);
920 include_file( const char *name
)
924 if( cursrc
>= sizeof(srcfiles
)/sizeof(srcfiles
[0]) ) {
925 printk("\npanic: Maximum include depth reached!\n");
929 file
= fopen_include( name
);
931 printk("\npanic: Failed opening file '%s'\n", name
);
938 encode_file( const char *name
)
940 FILE *file
= fopen_include(name
);
944 printk("\npanic: Can't open '%s'\n", name
);
947 fseek( file
, 0, SEEK_END
);
948 size
= ftell( file
);
949 fseek( file
, 0, SEEK_SET
);
952 printk("\nEncoding %s [%d bytes]\n", name
, size
);
954 fread( dict
+ dicthead
, size
, 1, file
);
955 PUSH( pointer2cell(dict
+ dicthead
) );
961 static void run_dictionary(char *basedict
, char *confile
)
966 read_dictionary(basedict
);
967 PC
= (ucell
)findword("initialize");
971 printk("Unable to find initialize word in dictionary %s; ignoring\n", basedict
);
978 srcfiles
[cursrc
-1] = stdin
;
986 printk("Jumping to dictionary %s...\n", basedict
);
988 /* If a console file has been specified, open it */
990 console
= fopen(confile
, "w");
992 srcbasedict
= basedict
;
994 enterforth((xt_t
)PC
);
996 /* Close the console file */
1001 static void new_dictionary(const char *source
)
1005 interpret_source((char *)source
);
1007 if (verbose
|| errors
> 0) {
1008 printk("interpretion finished. %d errors occured.\n",
1017 #define BANNER "OpenBIOS bootstrap kernel. (C) 2003-2006 Patrick Mauritz, Stefan Reinauer\n"\
1018 "This software comes with absolutely no warranty. "\
1019 "All rights reserved.\n\n"
1022 #define USAGE "Usage: %s [options] [dictionary file|source file]\n\n" \
1023 " -h|--help show this help\n" \
1024 " -V|--version print version and exit\n" \
1025 " -v|--verbose print debugging information\n" \
1026 " -I|--include dir add dir to include path\n" \
1027 " -d|--source-dictionary bootstrap.dict\n" \
1028 " use this dictionary as base\n" \
1029 " -D|--target-dictionary output.dict\n" \
1030 " write to output.dict\n" \
1031 " -c|--console output.log\n" \
1032 " write kernel console output to log file\n" \
1033 " -s|--segfault install segfault handler\n" \
1034 " -M|--dependency-dump file\n" \
1035 " dump dependencies in Makefile format\n\n"
1037 #define USAGE "Usage: %s [options] [dictionary file|source file]\n\n" \
1038 " -h show this help\n" \
1039 " -V print version and exit\n" \
1040 " -v print debugging information\n" \
1041 " -I add dir to include path\n" \
1042 " -d bootstrap.dict\n" \
1043 " use this dictionary as base\n" \
1044 " -D output.dict\n" \
1045 " write to output.dict\n" \
1046 " -c output.log\n" \
1047 " write kernel console output to log file\n" \
1048 " -s install segfault handler\n\n"
1049 " -M file dump dependencies in Makefile format\n\n"
1052 int main(int argc
, char *argv
[])
1054 struct sigaction sa
;
1056 unsigned char *ressources
=NULL
; /* All memory used by us */
1057 char *dictname
= NULL
;
1058 char *basedict
= NULL
;
1059 char *consolefile
= NULL
;
1060 char *depfilename
= NULL
;
1062 unsigned char *bootstrapdict
[2];
1065 const char *optstring
= "VvhsI:d:D:c:M:?";
1069 int option_index
= 0;
1070 static struct option long_options
[] = {
1071 {"version", 0, NULL
, 'V'},
1072 {"verbose", 0, NULL
, 'v'},
1073 {"help", 0, NULL
, 'h'},
1074 {"segfault", 0, NULL
, 's'},
1075 {"include", 1, NULL
, 'I'},
1076 {"source-dictionary", 1, NULL
, 'd'},
1077 {"target-dictionary", 1, NULL
, 'D'},
1078 {"console", 1, NULL
, 'c'},
1079 {"dependency-dump", 1, NULL
, 'M'},
1086 c
= getopt_long(argc
, argv
, optstring
, long_options
,
1089 c
= getopt(argc
, argv
, optstring
);
1096 printk("Version " OPENBIOS_VERSION_STR
"\n");
1100 printk("Version " OPENBIOS_VERSION_STR
"\n" USAGE
,
1110 #ifdef CONFIG_DEBUG_INTERPRETER
1111 printk("adding '%s' to include path\n", optarg
);
1113 add_includepath(optarg
);
1127 consolefile
= optarg
;
1132 depfilename
= optarg
;
1142 printk("Using source dictionary '%s'\n", basedict
);
1143 printk("Dumping final dictionary to '%s'\n", dictname
);
1144 printk("Dumping dependencies to '%s'\n", depfilename
);
1147 if (argc
< optind
+ 1) {
1148 printk(USAGE
, argv
[0]);
1153 depfile
= fopen(depfilename
, "w");
1155 printk("panic: can't write to dependency file '%s'.\n",
1159 fprintf(depfile
, "%s:", dictname
);
1163 * Get all required resources
1167 ressources
= malloc(MEMORY_SIZE
+ (2 * DICTIONARY_SIZE
) + TRAMPOLINE_SIZE
);
1169 printk("panic: not enough memory on host system.\n");
1173 #ifdef NATIVE_BITWIDTH_SMALLER_THAN_HOST_BITWIDTH
1174 base_address
=(unsigned long)ressources
;
1177 memory
= (ucell
*)ressources
;
1179 bootstrapdict
[0] = ressources
+ MEMORY_SIZE
;
1180 bootstrapdict
[1] = ressources
+ MEMORY_SIZE
+ DICTIONARY_SIZE
;
1181 trampoline
= (ucell
*)(ressources
+ MEMORY_SIZE
+ DICTIONARY_SIZE
+ DICTIONARY_SIZE
);
1183 #ifdef CONFIG_DEBUG_INTERPRETER
1184 printf("memory: %p\n",memory
);
1185 printf("dict1: %p\n",bootstrapdict
[0]);
1186 printf("dict2: %p\n",bootstrapdict
[1]);
1187 printf("trampoline: %p\n",trampoline
);
1188 printf("size=%d, trampoline_size=%d\n",MEMORY_SIZE
+ (2 *
1189 DICTIONARY_SIZE
) + TRAMPOLINE_SIZE
,
1193 if (trampoline
== NULL
) {
1194 /* We're using side effects which is to some extent nasty */
1195 printf("WARNING: no trampoline!\n");
1197 init_trampoline(trampoline
);
1202 printk("Installing SIGSEGV handler...");
1204 sa
.sa_sigaction
= segv_handler
;
1205 sigemptyset(&sa
.sa_mask
);
1206 sa
.sa_flags
= SA_SIGINFO
| SA_NODEFER
;
1207 sigaction(SIGSEGV
, &sa
, NULL
);
1214 * Now do the real work
1217 for (cnt
=0; cnt
<2; cnt
++) {
1219 printk("Compiling dictionary %d/%d\n", cnt
+1, 2);
1221 dict
=bootstrapdict
[cnt
];
1223 new_dictionary(argv
[optind
]);
1225 for (c
=argc
-1; c
>=optind
; c
--)
1226 include_file(argv
[c
]);
1228 run_dictionary(basedict
, consolefile
);
1231 fprintf(depfile
, "\n");
1239 #ifndef CONFIG_DEBUG_INTERPRETER
1241 printk("dictionary not dumped to file.\n");
1245 relocation_table( bootstrapdict
[0], bootstrapdict
[1], dicthead
);
1246 write_dictionary( dictname
? dictname
: "bootstrap.dict");