Skip to content

Instantly share code, notes, and snippets.

@bitofhope
Last active August 14, 2023 23:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bitofhope/b47b09e9923504a453b00cd4ee228d0a to your computer and use it in GitHub Desktop.
Save bitofhope/b47b09e9923504a453b00cd4ee228d0a to your computer and use it in GitHub Desktop.
Why is my Openfirmware freezing?

This is driving me nuts.

How to reproduce issue

Assemble and link the binary as per the included Makefile. Optionally strip it with llvm-strip minimal-boot

What I expect to happen

OpenBIOS (OpenFirmware implementation used by qemu) should run the executable which then should immediately exit through by invoking the "exit" service through OpenFirmware client handler API.

What happens instead

Execution freezes without further output upon (presumably) executing my binary.

Further information

I've looked at OpenBSD and NetBSD ofwboot bootloaders for reference and I can't figure out why none of my attempts are working.

OpenBSD

https://cdn.openbsd.org/pub/OpenBSD/7.2/sparc64/ofwboot https://cvsweb.openbsd.org/src/sys/arch/sparc64/stand/ofwboot/

NetBSD

https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.2/sparc64/installation/misc/ofwboot https://github.com/NetBSD/src/tree/trunk/sys/arch/sparc/stand/ofwboot

OpenFirmware docs

https://www.openbios.org/data/docs/12751d1a.pdf https://www.openfirmware.info/IEEE_1275-1994 https://www.openfirmware.info/Bindings

Running either of the above ofwboot files will actually do something, though they aren't intended to be run this way and will error out. In OpenBSD's case ofwboot will print the bootloader version, then a notice Invalid Openfirmware environment and then exit.

I have tried more complex versions that set up the stack and stdin/stdout handles like the BSD ofwboots do, but those fail in the exact same manner.

AS = clang
LD = ld.lld
ASFLAGS = -fintegrated-as --target=sparc64-unknown-none -c
LDFLAGS += --Ttext=0x100000 --omagic --entry=_start -N --no-pie
minimal-boot: minimal-boot.o
$(LD) $(LDFLAGS) -o $@ $^
run: minimal-boot
qemu-system-sparc64 -kernel minimal-boot
/*
* Entry point
*/
.text
.globl _start
_start:
/* Apparently .text has to start with nop for whatever reason */
nop
set args, %o0
/* Open Firmware SPARC bindings doc says the client handler address is passed in %o3
* OpenBSD and NetBSD pass it in %o4 and seem to work.
*/
jmpl %o4, %o7 ! Call handler in %o4, place return address on %o7
nop ! Delay slot
args:
.xword exit_str ! name: service to be invoked ("exit")
.xword 0 ! nargs: number of input arguments
.xword 0 ! nreturns: number of output values
exit_str:
.asciz "exit"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment