[OpenBIOS] Current finding on booting Mac OS 9.2

Programmingkid programmingkidx at gmail.com
Thu Apr 21 18:26:06 CEST 2016


As Segher had suggested, I executed the boot script one line at a time. This enabled me to see what line failed. The line that is failing is this:

r> here - allot

The message printed after this line is executed is:

"Dictionary space overflow: dicthead=000c3fe4 dictlimit=00080000"

So I decide to find out what value was being allot'ed. Using this code:

r> here - dup ." Calling allot with " . cr allot

The value that is being allocated is 0xa43ef or 672,751. Just for a comparison, I tried my code on Apple's Open Firmware. The value it allocates is 0xffffffd7. So I think the solution might be to increase available memory to OpenBIOS's dictionary. I'm thinking the kernel.c file is where things might need adjusting. 

This is the patch I used. It replaces r> and >r with substitute words that don't touch the return stack. This patch also executes one line at a time. 

Index: include/libc/string.h
===================================================================
--- include/libc/string.h	(revision 1395)
+++ include/libc/string.h	(working copy)
@@ -47,7 +47,7 @@
 extern char	*strdup( const char *str );
 extern int	strcasecmp( const char *cs, const char *ct );
 extern int	strncasecmp( const char *cs, const char *ct, size_t count );
-
+extern char *strstr(char *buffer, const char *search_string);
 extern  char 	*strncpy_nopad( char *dest, const char *src, size_t n );
 
 #define _U      0x01    /* upper */
Index: kernel/bootstrap.c
===================================================================
--- kernel/bootstrap.c	(revision 1395)
+++ kernel/bootstrap.c	(working copy)
@@ -89,7 +89,7 @@
 	"here", "here!", "dobranch", "do?branch", "unaligned-w@",
 	"unaligned-w!", "unaligned-l@", "unaligned-l!", "ioc@", "iow@",
 	"iol@", "ioc!", "iow!", "iol!", "i", "j", "call", "sys-debug",
-	"$include", "$encode-file", "(debug", "(debug-off)"
+	"$include", "$encode-file", "(debug", "(debug-off)", "sub_>r", "sub_r>"
 };
 
 /*
Index: kernel/forth.c
===================================================================
--- kernel/forth.c	(revision 1395)
+++ kernel/forth.c	(working copy)
@@ -1848,6 +1848,37 @@
 	PUSH(rstack[rstackcnt - 2]);
 }
 
+/* The substitute return stack */
+#define MAX_SUB_RSTACK_SIZE 100
+static int sub_return_stack[MAX_SUB_RSTACK_SIZE];
+static int top = 0;
+
+/*  
+ *   sub_>r ( i -- )  (Substitute R: -- i )
+ */
+
+static void sub_gt_r(void)
+{
+    if (top >= MAX_SUB_RSTACK_SIZE) {
+        printf_console("Stack overflow\n");
+        return;
+    }
+    sub_return_stack[top++] = POP();
+}
+
+/*
+ *     sub_r> ( -- i )  (Substitute R: i -- )
+ */
+
+static void sub_r_gt(void)
+{
+    if (top < 0 ) {
+        printf_console("Stack underflow\n");
+        return;
+    }
+    PUSH(sub_return_stack[top--]);
+}
+
 /* words[] is a function array of all native code functions used by
  * the dictionary, i.e. CFAs and primitives.
  * Any change here needs a matching change in the primitive word's
@@ -1963,4 +1994,6 @@
     do_encode_file,         /* $encode-file */
     do_debug_xt,            /* (debug  */
     do_debug_off,           /* (debug-off) */
+    sub_gt_r,               /* sub_>r  */
+    sub_r_gt                /* sub_r>  */
 };
Index: libc/string.c
===================================================================
--- libc/string.c	(revision 1395)
+++ libc/string.c	(working copy)
@@ -385,3 +385,30 @@
 	return __res;
 }
 
+// Search for a string within another string
+char *strstr(char *buffer, const char *search_string)
+{
+    if (!*search_string || (strlen(search_string) == 0)) {
+        return buffer;
+    }
+ 
+    int match_found, index, index2;
+    for (index = 0; index < strlen(buffer); index++) {
+        if (buffer[index] == search_string[0]) {
+            match_found = 1;
+            // see if we have a match
+            for (index2 = 0; index2 < strlen(search_string); index2++) {
+                if (buffer[index + index2] != search_string[index2]) {
+                    match_found = 0; // match not found
+                    break;
+                }
+            }
+            if(match_found == 1) {
+                return &buffer[index];
+            }
+        }
+    }
+    
+    // Could not find search_string in buffer
+    return NULL;
+}
Index: libopenbios/bootinfo_load.c
===================================================================
--- libopenbios/bootinfo_load.c	(revision 1395)
+++ libopenbios/bootinfo_load.c	(working copy)
@@ -19,6 +19,7 @@
 #include "libopenbios/bootinfo_load.h"
 #include "libopenbios/ofmem.h"
 #include "libc/vsprintf.h"
+#include "libc/string.h"
 
 //#define DEBUG_BOOTINFO
 
@@ -116,6 +117,85 @@
 	return LOADER_NOT_SUPPORT;
 }
 
+static void erase_memory(char *memory, int size)
+{
+    int i;
+    for(i = 0; i < size; i++) {
+        memory[i] = ' ';
+    }
+}
+
+// Replace all occurrences of orig_str in buffer with replace_str
+static void replace_string(char *buffer, const char *orig_str, const char *replace_str)
+{
+    char *ptr;
+    int index, new_buf_index = 0;
+    const int max_size = 5000;
+    char *new_buffer = malloc(max_size * sizeof(char));
+    erase_memory(new_buffer, max_size);
+
+    for (index = 0; index < strlen(buffer); index++) {
+        if (buffer[index] == orig_str[0]) {
+            ptr = strstr(buffer + index, orig_str);
+
+            // if we encountered an orig_str in the buffer
+            if (index == (ptr - buffer)) {
+                sprintf(new_buffer + new_buf_index, "%s ", replace_str);
+                new_buf_index += strlen(replace_str) + 1;
+                index += strlen(orig_str);
+                continue;
+            }
+        }
+        new_buffer[new_buf_index++] = buffer[index];
+    }
+    
+    // Clear the origial buffer
+    erase_memory(buffer, max_size);
+
+    // copy new_buffer into buffer
+    for (index = 0; index < strlen(new_buffer); index++) {
+        buffer[index] = new_buffer[index];
+    }
+    buffer[index+1] = '\0';
+}
+
+/* Replace >r and r> with sub_>r and sub_r> */
+static void replace_return_stack_words(char *bootscript)
+{
+    const char *find_str1 = ">r";
+    const char *replace_str1 = "sub_>r";
+    const char *find_str2 = "r>";
+    const char *replace_str2 = "sub_r>";
+    
+    replace_string(bootscript, find_str1, replace_str1);
+    replace_string(bootscript, find_str2, replace_str2);
+}
+
+void run_script(char *bootscript)
+{
+    int index = 0, buf_index = 0;
+    char c;
+    char *buffer = malloc(1000 * sizeof(char));
+    
+    while (1) {
+        c = bootscript[index];
+        
+        // fill up buffer
+        while (c != '\n' && c != '\r' && c != '\0') {
+            buffer[buf_index++] = c;
+            c = bootscript[++index];
+        }
+        buffer[buf_index] = '\0';
+        buf_index = 0;
+        index++;
+        printk("%s\n", buffer);
+        feval(buffer);
+        if (c == '\0') {
+            return;
+        }
+    }
+}
+
 /*
   Parse SGML structure like:
   <chrp-boot>
@@ -191,7 +271,7 @@
 
 		c = base[current++];
 
-		if (c == '<') {
+        if (c == '<') {
 			script = 0;
 			tag = 1;
 			taglen = 0;
@@ -262,7 +342,8 @@
 	/* If the payload is bootinfo then we execute it immediately */
 	if (scriptvalid) {
 		DPRINTF("bootscript: %s\n", bootscript);
-		feval(bootscript);
+        replace_return_stack_words(bootscript);
+		run_script(bootscript);
 	}
 	else
 		DPRINTF("Unable to parse bootinfo bootscript\n");




More information about the OpenBIOS mailing list