These patches fix a number of issues that hindered the Mac OS 9 boot process.
Signed-off-by: Cormac O'Brien i.am.cormac.obrien@gmail.com
Cormac O'Brien (6): bootinfo_load: recognize ASCII EOT as end of bootinfo ppc: add Adler-32 checksum capability ppc: add ROM node to device tree ppc: fix stack usage in mmu_claim, mem_claim ppc: add CPU reservation-granule-size property ppc: add Apple copyright injection to adler32
arch/ppc/qemu/init.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ arch/ppc/qemu/methods.c | 34 ++++++++++++------------- arch/ppc/qemu/qemu.fs | 28 ++++++++++++++++++++ arch/ppc/qemu/tree.fs | 8 ++++++ libopenbios/bootinfo_load.c | 10 ++++++++ 5 files changed, 125 insertions(+), 17 deletions(-)
Mac OS 9's CHRP boot info consists of the standard SGML document terminated by an ASCII EOT, followed by a large binary blob which is relocated by the Forth script. This patch allows the bootinfo loader to stop loading the script if it detects an EOT, avoiding the out-of-memory error previously encountered when booting OS 9.
Signed-off-by: Cormac O'Brien i.am.cormac.obrien@gmail.com --- libopenbios/bootinfo_load.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/libopenbios/bootinfo_load.c b/libopenbios/bootinfo_load.c index fa9e36b..4b6a52c 100644 --- a/libopenbios/bootinfo_load.c +++ b/libopenbios/bootinfo_load.c @@ -161,6 +161,16 @@ bootinfo_init_program(void) feval("load-size"); size = POP();
+ /* Check for a delimiting ASCII EOT, as in Mac OS 9 */ + current = 0; + while (current < size) { + if (base[current] == 0x04) { + size = current; + break; + } + current++; + } + bootscript = malloc(size); if (bootscript == NULL) { DPRINTF("Can't malloc %d bytes\n", size);
On 20/06/15 18:48, Cormac O'Brien wrote:
Mac OS 9's CHRP boot info consists of the standard SGML document terminated by an ASCII EOT, followed by a large binary blob which is relocated by the Forth script. This patch allows the bootinfo loader to stop loading the script if it detects an EOT, avoiding the out-of-memory error previously encountered when booting OS 9.
Signed-off-by: Cormac O'Brien i.am.cormac.obrien@gmail.com
libopenbios/bootinfo_load.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/libopenbios/bootinfo_load.c b/libopenbios/bootinfo_load.c index fa9e36b..4b6a52c 100644 --- a/libopenbios/bootinfo_load.c +++ b/libopenbios/bootinfo_load.c @@ -161,6 +161,16 @@ bootinfo_init_program(void) feval("load-size"); size = POP();
- /* Check for a delimiting ASCII EOT, as in Mac OS 9 */
- current = 0;
- while (current < size) {
if (base[current] == 0x04) {
size = current;
break;
}
current++;
- }
- bootscript = malloc(size); if (bootscript == NULL) { DPRINTF("Can't malloc %d bytes\n", size);
I've checked this patch with a debugger, and I think the use of EOT to detect the end of the bootscript isn't correct. AFAICT with gdb the Forth string is always NULL-terminated which is eluded to in the IEEE1275 specification in an indirect manner in section 6.3.2.6. Note that the patch above does work due to the position of a suitable EOT character but in my testing here it is several KB into the binary image rather than directly at the end of the Forth boundary.
I have an even simpler patch to replace this that I'll post to the list shortly.
ATB,
Mark.
This patch provides an implementation of the adler32 Forth word as required by Mac OS 9 and BootX.
Signed-off-by: Cormac O'Brien i.am.cormac.obrien@gmail.com --- arch/ppc/qemu/init.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+)
diff --git a/arch/ppc/qemu/init.c b/arch/ppc/qemu/init.c index 4fe8b72..5cc45ae 100644 --- a/arch/ppc/qemu/init.c +++ b/arch/ppc/qemu/init.c @@ -680,6 +680,60 @@ static void ffilll(void) } }
+/* + * adler32 ( adler buf len -- checksum ) + * + * Adapted from Mark Adler's original implementation (zlib license) + * + * Both OS 9 and BootX require this word for payload validation. + */ + +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +static void adler32(void) +{ + uint32_t len = (uint32_t)POP(); + char *buf = (char *)POP(); + uint32_t adler = (uint32_t)POP(); + + if (buf == NULL) { + RET(-1); + } + + uint32_t base = 65521; + uint32_t nmax = 5552; + + uint32_t s1 = adler & 0xffff; + uint32_t s2 = (adler >> 16) & 0xffff; + + uint32_t k; + while (len > 0) { + k = (len < nmax ? len : nmax); + len -= k; + + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) { + do { + s1 += *buf++; + s2 += s1; + } while (--k); + } + + s1 %= base; + s2 %= base; + } + + RET(s2 << 16 | s1); +} + void arch_of_init(void) { @@ -945,6 +999,9 @@ arch_of_init(void)
/* Implementation of filll word (required by BootX) */ bind_func("filll", ffilll); + + /* Implementation of adler32 word (required by OS 9, BootX) */ + bind_func("adler32", adler32);
bind_func("platform-boot", boot); bind_func("(go)", go);
This patch adds a ROM node to the PPC device tree as is required by Mac OS 9.
Based on a patch by John Arbuckle programmingkidx@gmail.com
Signed-off-by: Cormac O'Brien i.am.cormac.obrien@gmail.com --- arch/ppc/qemu/tree.fs | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/arch/ppc/qemu/tree.fs b/arch/ppc/qemu/tree.fs index 1ed8383..5b6bbc6 100644 --- a/arch/ppc/qemu/tree.fs +++ b/arch/ppc/qemu/tree.fs @@ -42,6 +42,14 @@ new-device : close ; finish-device
+new-device + " rom" device-name + h# ff800000 encode-int 0 encode-int encode+ " reg" property + 1 encode-int " #address-cells" property + h# ff800000 encode-int h# 800000 encode-int encode+ + h# ff800000 encode-int encode+ " ranges" property +finish-device + \ ------------------------------------------------------------- \ /packages \ -------------------------------------------------------------
The 'phys' argument to mem_claim() and 'virt' argument to mmu_claim() are now only popped from the stack if the 'align' argument is provided. Exception throws have been removed to simplify crossing C <-> Forth boundaries and to maintain consistency with other architectures.
This patch also fixes two stack diagrams with 'phys' arguments instead of 'virt' ones.
Signed-off-by: Cormac O'Brien i.am.cormac.obrien@gmail.com --- arch/ppc/qemu/methods.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/arch/ppc/qemu/methods.c b/arch/ppc/qemu/methods.c index fd993da..cb72bc1 100644 --- a/arch/ppc/qemu/methods.c +++ b/arch/ppc/qemu/methods.c @@ -164,21 +164,21 @@ DECLARE_UNNAMED_NODE( mmu, INSTALL_OPEN, 0 ); DECLARE_NODE( mmu_ciface, 0, 0, "+/openprom/client-services" );
-/* ( phys size align --- base ) */ +/* ( [phys] size align --- base ) */ static void mem_claim( void ) { ucell align = POP(); ucell size = POP(); - ucell phys = POP(); - ucell ret = ofmem_claim_phys( phys, size, align ); + phys_addr_t phys = -1;
- if( ret == -1 ) { - printk("MEM: claim failure\n"); - throw( -13 ); - return; + if (!align) { + phys = POP(); } - PUSH( ret ); + + phys = ofmem_claim_phys(phys, size, align); + + PUSH(phys); }
/* ( phys size --- ) */ @@ -188,24 +188,24 @@ mem_release( void ) POP(); POP(); }
-/* ( phys size align --- base ) */ +/* ( [virt] size align --- base ) */ static void mmu_claim( void ) { ucell align = POP(); ucell size = POP(); - ucell phys = POP(); - ucell ret = ofmem_claim_virt( phys, size, align ); + ucell virt = -1;
- if( ret == -1 ) { - printk("MMU: CLAIM failure\n"); - throw( -13 ); - return; + if (!align) { + virt = POP(); } - PUSH( ret ); + + virt = ofmem_claim_virt(virt, size, align); + + PUSH(virt); }
-/* ( phys size --- ) */ +/* ( virt size --- ) */ static void mmu_release( void ) {
This patch adds the 'reservation-granule-size' property to the CPU node, as is required by Mac OS 9.
Signed-off-by: Cormac O'Brien i.am.cormac.obrien@gmail.com --- arch/ppc/qemu/init.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/ppc/qemu/init.c b/arch/ppc/qemu/init.c index 5cc45ae..180679c 100644 --- a/arch/ppc/qemu/init.c +++ b/arch/ppc/qemu/init.c @@ -302,6 +302,11 @@ cpu_generic_init(const struct cpudef *cpu) fword("encode-string"); push_str("state"); fword("property"); + + PUSH(0x20); + fword("encode-int"); + push_str("reservation-granule-size"); + fword("property"); }
static void
Since Mac OS 9 and BootX are the only known users of the adler32 word, we use the word to add an Apple copyright message to the device tree in order to allow OS 9 to boot.
Signed-off-by: Cormac O'Brien i.am.cormac.obrien@gmail.com --- arch/ppc/qemu/init.c | 2 +- arch/ppc/qemu/qemu.fs | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/arch/ppc/qemu/init.c b/arch/ppc/qemu/init.c index 180679c..2b5b8e1 100644 --- a/arch/ppc/qemu/init.c +++ b/arch/ppc/qemu/init.c @@ -1006,7 +1006,7 @@ arch_of_init(void) bind_func("filll", ffilll);
/* Implementation of adler32 word (required by OS 9, BootX) */ - bind_func("adler32", adler32); + bind_func("(adler32)", adler32);
bind_func("platform-boot", boot); bind_func("(go)", go); diff --git a/arch/ppc/qemu/qemu.fs b/arch/ppc/qemu/qemu.fs index 458af1b..11e344a 100644 --- a/arch/ppc/qemu/qemu.fs +++ b/arch/ppc/qemu/qemu.fs @@ -93,3 +93,31 @@ variable keyboard-phandle 0 keyboard-phandle ! :noname set-defaults ; PREPOST-initializer + +\ ------------------------------------------------------------------------- +\ Adler-32 wrapper +\ ------------------------------------------------------------------------- + +: adler32 ( adler buf len -- checksum ) + \ Since Mac OS 9 is the only system using this word, we take this + \ opportunity to inject a copyright message that is necessary for the + \ system to boot. + " Copyright 1983-2001 Apple Computer, Inc. THIS MESSAGE FOR COMPATIBILITY ONLY" + encode-string " copyright" + " /" find-package if + " set-property" $find if + execute + else + 3drop drop + then + then + + ( adler buf len ) + + " (adler32)" $find if + execute + else + ." Can't find " ( adler32-name ) type cr + 3drop 0 + then +;
On Jun 20, 2015, at 1:48 PM, Cormac O'Brien wrote:
These patches fix a number of issues that hindered the Mac OS 9 boot process.
Signed-off-by: Cormac O'Brien i.am.cormac.obrien@gmail.com
Cormac O'Brien (6): bootinfo_load: recognize ASCII EOT as end of bootinfo ppc: add Adler-32 checksum capability ppc: add ROM node to device tree ppc: fix stack usage in mmu_claim, mem_claim ppc: add CPU reservation-granule-size property ppc: add Apple copyright injection to adler32
Have you know about github? You could keep a working repo there. It would allow you to have all the changes for QEMU and OpenBIOS in one place. Instead of having to download and apply all the patches you made, someone wanting to help can simply download your repository. This would be a *lot* easier than having to keep track of multiple versions of patches.
On Sat, Jun 20, 2015 at 1:14 PM, Programmingkid programmingkidx@gmail.com wrote:
Have you know about github? You could keep a working repo there. It would allow you to have all the changes for QEMU and OpenBIOS in one place. Instead of having to download and apply all the patches you made, someone wanting to help can simply download your repository. This would be a *lot* easier than having to keep track of multiple versions of patches.
https://github.com/cormac-obrien/openbios-devel/
Way ahead of ya :) New progress is on the 'hacking' branch, 'upstream' is for finalizing changes before submitting to the mailing list. Note that hacking and upstream are in the same place right now as no meaningful changes have been made.
~Cormac
On 20/06/15 18:48, Cormac O'Brien wrote:
These patches fix a number of issues that hindered the Mac OS 9 boot process.
Signed-off-by: Cormac O'Brien i.am.cormac.obrien@gmail.com
Cormac O'Brien (6): bootinfo_load: recognize ASCII EOT as end of bootinfo ppc: add Adler-32 checksum capability ppc: add ROM node to device tree ppc: fix stack usage in mmu_claim, mem_claim ppc: add CPU reservation-granule-size property ppc: add Apple copyright injection to adler32
arch/ppc/qemu/init.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ arch/ppc/qemu/methods.c | 34 ++++++++++++------------- arch/ppc/qemu/qemu.fs | 28 ++++++++++++++++++++ arch/ppc/qemu/tree.fs | 8 ++++++ libopenbios/bootinfo_load.c | 10 ++++++++ 5 files changed, 125 insertions(+), 17 deletions(-)
While I've dropped patch 1 in favour of the revised strnlen() version posted over the weekend, the remainder of the patches all apply with no regressions on any of my PPC images so I've committed them to trunk.
Thanks for your hard work on this!
ATB,
Mark.
[Note for others interested in testing the OS 9 patches: as a temporary measure you also need a patch such as the one at http://www.openfirmware.info/pipermail/openbios/2015-June/008722.html in order to successfully execute the Forth boot script. The proper fix requires more work.]