[ Index ] [ Prev: Getting Started ] [ Next: Blinking The LED ]
There were two ways I could play with the hardware: either with Forth commands at the PROM prompt, or by getting it to download binary code.
I have no disk (yet) in this machine. But it is no surprise that the PROM can boot off the network, in the same way as the Sun workstations. There is a subtle difference, though: the PROM directly downloads its kernel from tftp. No need for intermediate boot code.
Moreover, if you try to have the prom netboot the genuine SunOS bootloader, you will be rewarded with an enigmatic message:
ok boot tftp.ei()netboot.solbourne rarp: using IP address 10.0.1.164 = A0001A4 rarp: server at IP address 10.0.1.101 = A000165 tftp.ei()netboot.solbourne: conflicts with rom (entry must be greater than 0xfd044000)
No more luck, but different message, with OpenBSD's netboot:
ok boot tftp.ei()netboot.sparc rarp: using IP address 10.0.1.164 = A0001A4 rarp: server at IP address 10.0.1.101 = A000165 tftp.ei()netboot.sparc: overlaps current image
Of course, the OS/MP kernel boots fine:
ok boot tftp.ei()vmunix rarp: using IP address 10.0.1.164 = A0001A4 rarp: server at IP address 10.0.1.101 = A000165 Boot: tftp.ei()vmunix Entry: 0xfd080000 Size: 0x12e000+0x43710+0x8b3e0 OS/MP 4.1C Export(GENERIC/Root)#0: ...
The seasoned OpenBSD/sparc hacker will quickly notice that a few things feel wrong here. The OpenBSD/sparc code gets linked at a lower address, with the kernel image at (virtual) 0xf8000000 and the kernel entry at (virtual) 0xf8004000. But it is loaded by the Sun PROM low in memory, at physical address zero onwards.
Here, it seems that
So, to get the PROM to accept loading my code, all I need would be changing the link address. This would imply changing the constant KERNELBASE in <machine/param.h>, so the S4000 port would need to be a distinct architecture from OpenBSD/sparc.
Being bold, I decided I could as well start by getting the PROM to load a full-blown kernel; it took only a few minutes to create a new architecture in the source tree, OpenBSD/solbourne, which would be a compound architecture with MACHINE being solbourne but MACHINE_ARCH being sparc. I populated almost everything inside /sys/arch/solbourne/include/ with two-line wrappers to the sparc include files, like this:
/* $OpenBSD$ */ /* public domain */ #include <sparc/foo.h>Except for /sys/arch/solbourne/include/param.h, which was almost identical to /sys/arch/sparc/include/param.h, minus this:
#define KERNBASE 0xfd080000 /* start of kernel virtual space */ #define KERNTEXTOFF 0xfd080000 /* start of kernel text */
Of course, I knew this kernel would die very early, if only because it would not drive the MMU properly, but what I wanted was to get something loaded. It could be made working later...
The astute reader will raise the concern that OpenBSD/sparc (and thus, OpenBSD/solbourne) uses the ELF binary file format, while SunOS 4 (and thus, OS/MP) uses the a.out binary file format, and it is unlikely that the Solbourne PROM can read ELF binaries.
Since the BSD kernel is a standalone, statically linked executable, it is very easy to convert the ELF binary to a.out. The steps are as follows:
clean-elf bsd
objcopy -j .text -j .data -j .bss -O a.out-sparc-netbsd bsd aoutbsd
So I had an a.out file (aoutbsd), and I was ready to boot it.
ok boot tftp.ei()aoutbsd rarp: using IP address 10.0.1.164 = A0001A4 rarp: server at IP address 10.0.1.101 = A000165 Boot: tftp.ei()aoutbsd Entry: 0xfd080000 Size: 0xfbd20+0x147b0+0x32fd0 Error on word boot
The cursor would spin for a while, with data effectively transmitted across the wire, but would always end with this cryptic error message.
What could possibly cause loading my binary to fail? Let's have a look at the a.out headers for both kernels:
$ hexdump -C -n32 vmunix 00000000 01 03 01 07 00 12 e0 00 00 04 37 10 00 08 b3 e0 |......à...7...³à| 00000010 00 02 01 24 fd 08 00 00 00 00 00 00 00 00 00 00 |...$ý...........| $ hexdump -C -n32 aoutbsd 00000000 00 8a 01 07 00 0f bd 20 00 01 47 b0 00 03 2f d0 |......½ ..G°../Ð| 00000010 00 00 b7 d8 fd 08 00 00 00 00 00 00 00 00 00 00 |..·Øý.@.........|
Apart from the machine ID in the magic number (3 = M_SPARC for OS/MP, 8a = MID_SPARC for OpenBSD), nothing looks wrong (of course, sections size differ). Wait! The OS/MP kernel has a very round number for the text size... It looks like it is aligned to an 0x2000 boundary... which happens to be the MMU page size!
I had nothing to lose, and much to gain, trying to also round my text section to a page size. To save me time, I ended up doing it in the following way:
$ cat /sys/arch/solbourne/solbourne/prom_pad.s /* $OpenBSD$ */ /* public domain */ #include <machine/asm.h> #include <machine/param.h> #define PROM_TEXT_PAD PAGE_SIZE .text .align PROM_TEXT_PAD .globl _C_LABEL(prom_pad) .type _C_LABEL(prom_pad),@object _C_LABEL(prom_pad):
With a text section correctly padded, the PROM was finally happy and loaded my kernel entirely, then ran it, and... well, what did you expect? Of course it froze the machine! Then, I realized that this machine lacks a physical reset switch. I had to power-cycle it (countless times since then), and I am glad there are no hard drives in it, or they would not survive this on the long run...
[ Index ] [ Prev: Getting Started ] [ Next: Blinking The LED ]