notes on using open firmware with the G3 powerbook

Joshua LeVasseur, February 2002

docs

booting an image

For an image on parition 17, called bootme, try
boot hd:17,bootme

For an image served by a tftp server, try

boot enet:0

Hold down the option key during machine boot to get a list of bootable partitions.

reloading a binary without a reboot

The open firmware on my PowerBook fails to release the memory associated with the elf image after the image exits via the client exit call. You can see the available memory regions by inspecting the properties of the /memory@0 device node.
		dev /memory@0
		.properties
	
You'll see a range of available memory regions, and if you consider the negative (the claimed memory regions), one of them will overlap with the memory claimed by the elf binary. And this prevents you from reloading the elf binary. So release the conflicting memory region. For example, if the region starts at 0x30054 with a length of 0xa000 bytes, execute
		30054 a000 release-mem
	
I automate this call, and release immediately before calling the client exit function. But to successfully execute, I found that I had to call the client interpreter entry point, and pass the Forth code which releases the memory. For example:
		struct {
			const char *service;
			int nargs;
			int nret;
			const char *forth;
			int result;
		} args;
		args.service = "interpret";
		args.nargs = 1;
		args.nret = 1;
		args.forth = "30054 a000 release-mem";
		args.result = -1;
		(*prom_entry)( &args );
	
I do not know the consequences of executing a release-mem on the memory of an actively executing process. I suspect that it would be appropriate to first set the memory management callbacks so that open firmware transfers memory management to the client.

hot keys

the note section

Supposedly the PowerPC Open Firmware spec requires a modified elf binary. The elf file should contain an elf note section with some data that describes the boot environment required by the client. It seems that Apple's implementation of Open Firmware doesn't require the note section.

To easily define an elf note section, try adding the following lines to an assembler file:

	        .section ".note"
		.align  2
	.note_section_header:
		.long   8               /* note name length (including null byte) */
		.long   24              /* note descriptor length */
		.long   0x1275          /* note type */
		.string "PowerPC"	/* note name */
	.note_descriptor:
		.long   0x0             /* real-mode */
		.long   0xffffffff      /* real-base */
		.long   0xffffffff      /* real-size */
		.long   0xffffffff      /* virt-base */
		.long   0xffffffff      /* virt-size */
		.long   0x00030000      /* load-base */
	
Be warned that the linker's default settings or the linker script may cause the linker to discard the note section.

Some implementations may also require an elf note program header, which contains the note section. Use a linker script to define the elf note program header. A partial example:

		PHDRS { 
			kernel_phdr PT_LOAD;
			note_phdr PT_NOTE;
		}

		SECTIONS {
			.text . : { *(.text .rodata) } : kernel_phdr

			.data . : { *(.data .sdata .sdata2) } : kernel_phdr

			.bss . : { *(.bss) } : kernel_phdr

			.note : { *(.note) } : note_phdr
		}
	
And I haven't tested any of this to verify that it works with hardware, since I have a PowerBook that ignores it. But perhaps it ignores the note info because I implemented it incorrectly.

I have tested with the psim simulator, which reads and tries to enforce the .note section I added to one of my assembler files. I linked with the linker's default link script, for the target powerpc-unknown-eabi. So I'm positive that it works.

open firmware elf limitations

Open Firmware dislikes complex elf files. To minimize the size of the elf file, one often needs to use multiple elf program headers to distinguish sections that reside in different regions of memory. Open Firmware will accept many elf program headers, but they must load data into memory at addresses congruent with their file offset. For example, elf files ensure that the data sections and code sections live on different pages, and so move the virtual load address to the next page. To satisfy Open Firmware, the load address must be incremented while preserving the current page offset. For example, use
. = ALIGN(4K) + (. & (4K - 1));
instead of
. = ALIGN(4K)

An example linker script which generates a binary compatible with Open Firmware, and which has multiple elf program headers.

useful open firmware commands

To see all available commands, execute sifting

To search for a command, execute sifting command