The Forth dictionary was relocated at run time, incurring also a copy operation. The source dictionary remained in memory. It was not possible to run forthstrap without any input files besides the base dictionary.
Make forthstrap generate a hex dump which can be included in C, but also contains relocations, so that relocations are performed by the linker at compile time. Allow dictionary compilation with no source files.
Don't allocate the dictionary dynamically; reduce ofmem supply accordingly.
Signed-off-by: Blue Swirl blauwirbel@gmail.com --- arch/sparc32/build.xml | 6 +--- arch/sparc32/builtin.c | 9 ++++- arch/sparc32/ofmem_sparc32.c | 2 +- arch/sparc32/openbios.c | 10 ++--- include/libopenbios/sys_info.h | 2 + kernel/bootstrap.c | 71 +++++++++++++++++++++++++++++++++++---- 6 files changed, 78 insertions(+), 22 deletions(-)
diff --git a/arch/sparc32/build.xml b/arch/sparc32/build.xml index 3d2f71d..47ad01a 100644 --- a/arch/sparc32/build.xml +++ b/arch/sparc32/build.xml @@ -42,11 +42,7 @@
<executable name="target/include/static-dict.h" target="target" condition="IMAGE_ELF_EMBEDDED"> <rule><![CDATA[ - $(call quiet-command,true, " GEN $(TARGET_DIR)$@") - @echo "static const char forth_dictionary[] = {" > $@ - @cat $< | hexdump -ve '1/0 "\t" 8/1 "0x%02x, " 1/0 "\n"' \ - | sed 's/0x ,//g' >> $@ - @echo "};" >> $@]]></rule> + $(call quiet-command,$(ODIR)/forthstrap -x -D $@ -d $< </dev/null, " GEN $(TARGET_DIR)$@")]]></rule> <external-object source="openbios-sparc32.dict"/> </executable>
diff --git a/arch/sparc32/builtin.c b/arch/sparc32/builtin.c index 8bcce4c..839ffd6 100644 --- a/arch/sparc32/builtin.c +++ b/arch/sparc32/builtin.c @@ -14,12 +14,17 @@ * wrap an array around the hex'ed dictionary file */
+/* 256K for the dictionary */ +#define DICTIONARY_SIZE (256 * 1024 / sizeof(ucell)) + #include "static-dict.h"
void collect_multiboot_info(struct sys_info *info); void collect_multiboot_info(struct sys_info *info) { info->dict_start=(unsigned long *)forth_dictionary; - info->dict_end=(unsigned long *)((ucell)forth_dictionary + - sizeof(forth_dictionary)); + info->dict_end = (unsigned long *)FORTH_DICTIONARY_END; + info->dict_last = (ucell *)((unsigned char *)forth_dictionary + + FORTH_DICTIONARY_LAST); + info->dict_limit = sizeof(forth_dictionary); } diff --git a/arch/sparc32/ofmem_sparc32.c b/arch/sparc32/ofmem_sparc32.c index 6815349..72079b2 100644 --- a/arch/sparc32/ofmem_sparc32.c +++ b/arch/sparc32/ofmem_sparc32.c @@ -21,7 +21,7 @@
#define OF_MALLOC_BASE ((char*)OFMEM + ALIGN_SIZE(sizeof(ofmem_t), 8))
-#define MEMSIZE (512 * 1024) +#define MEMSIZE (256 * 1024) static union { char memory[MEMSIZE]; ofmem_t ofmem; diff --git a/arch/sparc32/openbios.c b/arch/sparc32/openbios.c index c940a5f..1d8842a 100644 --- a/arch/sparc32/openbios.c +++ b/arch/sparc32/openbios.c @@ -28,7 +28,6 @@ #include "libopenbios/ofmem.h"
#define MEMORY_SIZE (16*1024) /* 16K ram for hosted system */ -#define DICTIONARY_SIZE (256*1024) /* 256K for the dictionary */ #define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" #define FW_CFG_SUN4M_DEPTH (FW_CFG_ARCH_LOCAL + 0x00)
@@ -968,12 +967,11 @@ int openbios(void)
collect_sys_info(&sys_info);
- dict = malloc(DICTIONARY_SIZE); - dictlimit = DICTIONARY_SIZE; + dict = (unsigned char *)sys_info.dict_start; + dicthead = (cell)sys_info.dict_end; + last = sys_info.dict_last; + dictlimit = sys_info.dict_limit;
- load_dictionary((char *)sys_info.dict_start, - (unsigned long)sys_info.dict_end - - (unsigned long)sys_info.dict_start); forth_init();
#ifdef CONFIG_DEBUG_BOOT diff --git a/include/libopenbios/sys_info.h b/include/libopenbios/sys_info.h index 2eea9af..a8b3cce 100644 --- a/include/libopenbios/sys_info.h +++ b/include/libopenbios/sys_info.h @@ -20,6 +20,8 @@ struct sys_info { } *memrange; unsigned long *dict_start; unsigned long *dict_end; + cell dict_limit; + ucell *dict_last; };
extern void *elf_boot_notes; diff --git a/kernel/bootstrap.c b/kernel/bootstrap.c index 94aaeb8..68fe5dd 100644 --- a/kernel/bootstrap.c +++ b/kernel/bootstrap.c @@ -237,6 +237,48 @@ static void write_dictionary(const char *filename) #endif }
+static void write_dictionary_hex(const char *filename) +{ + FILE *f; + ucell *walk; + + f = fopen(filename, "w"); + if (!f) { + printk("panic: can't write to dictionary '%s'.\n", filename); + exit(1); + } + + fprintf(f, "static ucell forth_dictionary[DICTIONARY_SIZE] = {\n"); + for (walk = (ucell *)dict; walk < (ucell *)(dict + dicthead); walk++) { + int pos, bit, l; + ucell val; + + l = (walk - (ucell *)dict); + pos = l / BITS; + bit = l & ~(-BITS); + + val = read_ucell(walk); + if (relocation_address[pos] & target_ucell((ucell)1ULL << bit)) { + fprintf(f, "(ucell)((char *)&forth_dictionary + 0x%" FMT_CELL_x + "),\n", val); + } else { + fprintf(f, "0x%" FMT_CELL_x",\n", val); + } + } + + fprintf(f, "};\n"); + + fprintf(f, "#define FORTH_DICTIONARY_LAST 0x%" FMT_CELL_x"\n", + (ucell)((unsigned long)last - (unsigned long)dict)); + fprintf(f, "#define FORTH_DICTIONARY_END 0x%" FMT_CELL_x"\n", + (ucell)dicthead); + fclose(f); + +#ifdef CONFIG_DEBUG_DICTIONARY + printk("wrote dictionary to file %s.\n", filename); +#endif +} + static ucell read_dictionary(char *fil) { int ilen; @@ -1032,7 +1074,8 @@ static void new_dictionary(const char *source) " write kernel console output to log file\n" \ " -s|--segfault install segfault handler\n" \ " -M|--dependency-dump file\n" \ - " dump dependencies in Makefile format\n\n" + " dump dependencies in Makefile format\n\n" \ + " -x|--hexdump output format is C language hex dump\n" #else #define USAGE "Usage: %s [options] [dictionary file|source file]\n\n" \ " -h show this help\n" \ @@ -1045,8 +1088,9 @@ static void new_dictionary(const char *source) " write to output.dict\n" \ " -c output.log\n" \ " write kernel console output to log file\n" \ - " -s install segfault handler\n\n" - " -M file dump dependencies in Makefile format\n\n" + " -s install segfault handler\n\n" \ + " -M file dump dependencies in Makefile format\n\n" \ + " -x output format is C language hex dump\n" #endif
int main(int argc, char *argv[]) @@ -1054,15 +1098,15 @@ int main(int argc, char *argv[]) struct sigaction sa;
unsigned char *ressources=NULL; /* All memory used by us */ - char *dictname = NULL; + const char *dictname = NULL; char *basedict = NULL; char *consolefile = NULL; char *depfilename = NULL;
unsigned char *bootstrapdict[2]; - int c, cnt; + int c, cnt, hexdump = 0;
- const char *optstring = "VvhsI:d:D:c:M:?"; + const char *optstring = "VvhsI:d:D:c:M:x?";
while (1) { #ifdef __GLIBC__ @@ -1077,6 +1121,7 @@ int main(int argc, char *argv[]) {"target-dictionary", 1, NULL, 'D'}, {"console", 1, NULL, 'c'}, {"dependency-dump", 1, NULL, 'M'}, + {"hexdump", 0, NULL, 'x'}, };
/* @@ -1132,11 +1177,17 @@ int main(int argc, char *argv[]) depfilename = optarg; } break; + case 'x': + hexdump = 1; + break; default: return 1; } }
+ if (!dictname) { + dictname = "bootstrap.dict"; + } if (verbose) { printk(BANNER); printk("Using source dictionary '%s'\n", basedict); @@ -1144,7 +1195,7 @@ int main(int argc, char *argv[]) printk("Dumping dependencies to '%s'\n", depfilename); }
- if (argc < optind + 1) { + if (argc < optind) { printk(USAGE, argv[0]); return 1; } @@ -1243,7 +1294,11 @@ int main(int argc, char *argv[]) #endif { relocation_table( bootstrapdict[0], bootstrapdict[1], dicthead); - write_dictionary( dictname ? dictname : "bootstrap.dict"); + if (hexdump) { + write_dictionary_hex(dictname); + } else { + write_dictionary(dictname); + } }
free(ressources);