• Please review our updated Terms and Rules here

Net boot a Sparcstation 2

OK, so finally resolve the swap issue. bootparamd is asked for "swap" and gives a path. I was seeing the sparc trying to NFS mount it, so presumed it must be a directory. As it turns out, a not well documented feature, is NFSv2 can mount a flat file! None of the rfc1094 talk about it. But because mountd:mount creates a filehandle, all the software machinery just "works" if you allow a regular file to be mounted since the client doesn't do a LookUp and uses the filehandle. SunOS boot prom is happy and finds a 16MB file and continues...

So 1 step closer..
 
More progress. vmunix tries to load /sbin/init and then stops.

[I was surprised it expects 8K chunks when my NFS server says it likes 4K, but hey ho.]

Code:
bootparamd: getfile: got question for 'sparc2' asking for 'swap'
bootparamd: getfile: client:sparc2 swap => /Users/Shared/export/swap/sparc2
portmapd: prog:100005 vers:1 prot:17 => registeredport:6135
mountd: mount File = /Users/Shared/export/swap/sparc2 for client@192.168.1.71
nfsd: get_attr: /Users/Shared/export/swap/sparc2  uid:0 perm:-rw-rw-rw- size:67108864
nfsd: statfs: disk:131072 free:114688
bootparamd: getfile: got question for 'sparc2' asking for 'dump'
bootparamd: getfile: client:sparc2 dump => /Users/Shared/export/dump/sparc2
portmapd: prog:100005 vers:1 prot:17 => registeredport:6135
mountd: mount Path = /Users/Shared/export/dump/sparc2 for client@192.168.1.71
nfsd: get_attr: /Users/Shared/export/dump/sparc2  uid:505 perm:-rwxr-xr-x size:64
nfsd: statfs: disk:131072 free:114688
nfsd: get_attr: /Users/Shared/export/swap/sparc2  uid:0 perm:-rw-rw-rw- size:67108864
nfsd: lookup = /Users/Shared/export/root/sparc2/sbin size:96
nfsd: lookup = /Users/Shared/export/root/sparc2/sbin/init size:65536
  read: /Users/Shared/export/root/sparc2/sbin/init: 8192 bytes at 0
  read: /Users/Shared/export/root/sparc2/sbin/init: 8192 bytes at 8192
  read: /Users/Shared/export/root/sparc2/sbin/init: 8192 bytes at 16384
  read: /Users/Shared/export/root/sparc2/sbin/init: 8192 bytes at 24576
  read: /Users/Shared/export/root/sparc2/sbin/init: 8192 bytes at 32768
  read: /Users/Shared/export/root/sparc2/sbin/init: 8192 bytes at 40960
  read: /Users/Shared/export/root/sparc2/sbin/init: 8192 bytes at 49152
  read: /Users/Shared/export/root/sparc2/sbin/init: 8192 bytes at 57344

So /sbin/init is 65536 bytes and it reads 65536 bytes - but then stops.
Not even a terminal Break gets back the ok prompt and machine needs to be power cycled..
 
root_squash? My NFS server doesn't even consult an /etc/exports! It goes right ahead and tries opening any file or folder you give it. 🤪

BUT, the uid question reminds me that because I own the nfs server I can spoof any uid/gid/perms I like - which could make installing less error prone. On it.


[But I have done 'sudo tar xvf blah' just now to be sure]
 
Last edited:
This is a braindump with a bit of copy paste from my server.
If you (or anyone) needs any further clarification, or would like me to dust off the IPX and netboot it (using a serial console), let me know.
Most of the netbooting effort went into the sun4c (IPX), then moved onto sun4m (Sparc 5, should be OK with SS10/SS20), and then sun4u (Ultra 5/10).
Never got around to netbooting Solaris 8 and upwards (was on the to-do list for work and then dropped off).
For the record, you can ufsdump old Solaris UFS file systems by netbooting to Solaris 7 regardless of the release on disc.
Similarly, if you have ufsdumps generated from an old Solaris release, you can netboot to Solaris 7 to restore.

Braindump:
I've got a diskless SparcIPX (sun4c, pretty much a lunchbox version of the SS2).
This has booted to:
Solaris 1.1.2 (aka SunOS 4.1.4) (For old time's sake, it was the first version of SunOS I got trained and worked on back in the day)
Solaris 2.3, (because I had to support other systems, and I wanted a Solaris 2.3 environment to play with, even if those other systems were sun4m)
Solaris 7. (prototype for netbooting other boxes to allow network based backups)
Solaris version selection is clunky - need to edit files on the server to switch, never got as far as trialling some kind of boot menu on the client, or maybe trying some kind of specific boot path.
The server was last used to boot the IPX into an unpatched install of Solaris 2.3

The IPX is set to "boot net" on power up (dremmelled 48T02, with CR2032 holder+new crystal soldered on the back).
The boxes use RARPD, bootparamd and nfsd as detailed elsewhere in the thread
The objective was to get the box to boot diskless so that I could t

My server runs Slackware 13.37 x64 (old, v old) but it works. Attempts to create a backup solution using Slackware 15.0 failed (long story, see the end).

/etc/exports:
/home/data/sunos/export/root/sparcipx 192.168.x.y/255.255.255.255(fsid=1401,rw,sync,no_subtree_check,no_root_squash)
/home/data/sunos/export/exec/sparcipx 192.168.x.y/255.255.255.255(fsid=1402,rw,sync,no_subtree_check,no_root_squash)
Note the /32 netmask - the exec share could be expanded for more than one client, but the root is a "per client"
Hint:
The two shared "directories" are actually where two loopback mounted filesystems can be found.
/etc/fstab contains
/home/data/sunos/export/images/root.S23unp.sun4c.sparcipx.20210314 /home/data/sunos/export/root/sparcipx ext4 loop 0 0
/home/data/sunos/export/images/usr.S23unp.sun4c.sparcipx.20210314 /home/data/sunos/export/exec/sparcipx ext4 loop 0 0
and root.S23unp.sun4c.sparcipx.20210314 and usr.S23unp.sun4c.sparcipx.20210314 are/were 4Gb files that hold the respective file systems (Solaris 2.3 unpatched for sun4c for hostname sparcipx)
This constrains the total available space on the NFS share to 4G, so you will never get package installer scripts asking "How much free space on /usr and /" , receiving a message which cause an overflow which is interpreted as "no space"
The files were created using dd, and mkfs.ext4 <filename>
To be honest I can't remember how I generated contents of the file systems - the notes have been long lost. I have vague memories of either booting the SPARC box off CD-ROM, or using a Solaris x86 virtual machine to install the required Sparc packages to an alternate filesystem tree.
(The Solaris 1.1.2 install was done by installing to hard disk, booting off CDROM, mount NFS, copying across, edit as required).
Swap is exported as
/home/data/sunos/export/swap/ 192.168.x.y/255.255.255.248(fsid=1300,rw,insecure,no_subtree_check,no_root_squash)
Note 1: You are exporting the directory containing the swapfile (/home/data/sunos/export/swap/) see below for the actual swapfile
Note 2: The /29 subnet - this directory can serve more than one box

Swap
See /etc/exports above
For the ipx this is a 128Mb file with the T (sticky) bit set.
Size was set as memory*2 to suit Solaris 1.1.2 (and more than enough for anything else), and the box only supports upto 64Mb but had 56Mb fitted.
For Solaris 2.x onwards, use "normal rules"/common sense when defining the amount of space required.

Can't remember if I did any kind of mkswap type command. ISTR that Solaris just uses the space as is.
so the basic idea is
# dd if=/dev/zero of=/home/data/sunos/export/swap/sparcipx bs=1048576 count=128
# chmod 1600 /home/data/sunos/export/swap/sparcipx
# ls -alh /home/data/sunos/export/swap/sparcipx
and expect to see - note the "T":
-rw------T 1 root root 128M Jul 5 2021 sparcipx

/etc/bootparams (used by bootparamd)
sparcipx root=servername:/home/data/sunos/export/root/sparcipx swap=servername:/home/data/sunos/export/swap/sparcipx rootopts=:rsize=32768 domainname=myinternaldnsdomainname

Note the root entry points to a shared directory, swap points to a file in a shared directory. Can't remember why I set rsize and boot failed if domainname wasn't set.

/etc/ethers (used by rarpd)
8:00:20:c0:ff:ee<tab>192.168.x.y

Replace the obviously madeup MAC (as seen in the Sun NVRAM/hostid FAQ) with the actual MAC of the client.

/tftpboot (or wherever your tftpboot "root" directory is sat)
For my IPX (sun4c) I have the following files/links
lrwxrwxrwx 1 root root 18 Mar 2 2021 C0A8458C.SUN4C -> inetboot.S23.sun4c
-rw-r--r-- 1 root root 162932 Feb 19 2020 inetboot.S23.sun4c

My version of tftpd is happy following soft links, your mileage may vary...

Server OS setup notes
At boot time:
bootparamd gets started using "/usr/sbin/rpc.bootparamd -s" (log to syslog)
rarpd gets started using "/usr/sbin/rarpd -v -e" (verbose on, respond if MAC is in /etc/ethers)

For my release of Slackware I used iputils-s20101006-x86_64-1 for rarpd and netkit-bootparamd-0.17-x86_64-2.

A lot of the setup was "smoke and mirrors" to be honest. The client tells you nothing other than something failed, the error reporting for the server functions varies from cryptic down to none at all.
When I came to create a virtual machine to be run using Virtualbox on a laptop, to allow netbooting of Solaris 7 on Sparc 5/Ultra 5/Ultra 10 to backup/restore Solaris 2.3 and Solaris 2.6. I tried using Slackware 15.0 (the latest release) as the server and I couldn't get NFS to work properly. I threw my hands in the air, said "sod it" and went back to using Slackware 13.37 as the thing was a "tool" not a production system).
If you are using Debian or Ubuntu you may have the same frustration, however once you find out which packages work, you'll find it a lot easier to recreate in the future :)
I stuck with Slackware as it's really easy for me to strip out unwanted/not needed stuff for a virtual machine which would spend most of its life consuming hard disc space.

Hope this helps
 
[Cheers @mdog69, useful info.]

When Sparcstation downloads vmunix from NFSv2, it does so in chunks of 1024 bytes and boots the executable happily.
When vmunix then downloads /sbin/init, it does so in chunks of 8192 bytes..(no idea why the change)

Now I read the NFSv2 spec as saying if you are asked for N bytes, you can return <N bytes. However, if I limit the 8192 byte read request to say, 1024 bytes, the next request read offset increases by 8192 as if the client has totally ignored the fact it got less than 8192 bytes..

Code:
nfsd: lookup = /Users/Shared/export/root/sparc2/sbin/init uid=0 perms=-F/rwxr-xr-x size:65536
  read: /Users/Shared/export/root/sparc2/sbin/init: 1024 bytes at 0
  read: /Users/Shared/export/root/sparc2/sbin/init: 1024 bytes at 8192
  read: /Users/Shared/export/root/sparc2/sbin/init: 1024 bytes at 16384
  read: /Users/Shared/export/root/sparc2/sbin/init: 1024 bytes at 24576
  read: /Users/Shared/export/root/sparc2/sbin/init: 1024 bytes at 32768
  read: /Users/Shared/export/root/sparc2/sbin/init: 1024 bytes at 40960
  read: /Users/Shared/export/root/sparc2/sbin/init: 1024 bytes at 49152
  read: /Users/Shared/export/root/sparc2/sbin/init: 1024 bytes at 57344

Question: How come?

And the reason I am concerned, is Wireshark shows all those large UDP packets being fragmented:

Code:
No.    Time    Source    Destination    Protocol    Length    Info
29142    2520.997051    192.168.1.71    192.168.1.233    NFS    158    V2 READ Call (Reply In 29148), FH: 0x7e33f8af Offset: 49152 Count: 8192 TotalCount: 8192
29143    2520.997667    192.168.1.233    192.168.1.71    IPv4    1514    Fragmented IP protocol (proto=UDP 17, off=0, ID=4bcb) [Reassembled in #29148]
29144    2520.997672    192.168.1.233    192.168.1.71    IPv4    1514    Fragmented IP protocol (proto=UDP 17, off=1480, ID=4bcb) [Reassembled in #29148]
29145    2520.997673    192.168.1.233    192.168.1.71    IPv4    1514    Fragmented IP protocol (proto=UDP 17, off=2960, ID=4bcb) [Reassembled in #29148]
29146    2520.997675    192.168.1.233    192.168.1.71    IPv4    1514    Fragmented IP protocol (proto=UDP 17, off=4440, ID=4bcb) [Reassembled in #29148]
29147    2520.997701    192.168.1.233    192.168.1.71    IPv4    1514    Fragmented IP protocol (proto=UDP 17, off=5920, ID=4bcb) [Reassembled in #29148]
29148    2520.997703    192.168.1.233    192.168.1.71    NFS    834    V2 READ Reply (Call In 29142)
29149    2521.009902    192.168.1.71    192.168.1.233    NFS    158    V2 READ Call (Reply In 29155), FH: 0x7e33f8af Offset: 57344 Count: 8192 TotalCount: 8192

Question: When a UDP packet length is >MTU and split up, thats a BadThing right? In the sense my sparc client is going to get 5 UDP packets and would be expected to glue them back together.
 
The reason you're seeing different sizes for the read of vmunix vs /sbin/init is that the NFS client in inetboot is less sofisticated (for instance, I don't think it bothers with the portmapper either, and just goes straight for port 2049). It's to be expected.

Fragmented packets on a local network that isn't saturated is also nothing to worry about. The reason we try to avoid it is that if a fragment is dropped, the whole packet needs to be resent. But that is mostly a concern when you're going over the Internet. If you're loosing packets on your LAN you should fix it (find out what's spamming, or upgrade to a faster network). For NFS, larger read blocks will generally be faster, even with fragmenting.

That you're only reading 1k at every 8k offset sounds like a bug of some sort. The packet you see in Wireshark looks like it should be an 8k block, and if the nfs server is only filling it with 1k from the file it would explain why the boot hangs trying to start init
 
When Sparcstation downloads vmunix from NFSv2, it does so in chunks of 1024 bytes and boots the executable happily.
When vmunix then downloads /sbin/init, it does so in chunks of 8192 bytes..(no idea why the change)
Simplicity of implementation in the bootstrap code (smaller buffers, less/no fragmentation, lower probability of packet corruption -> better reliability) vs. performance (larger packets reduce per-packet overhead cost -> fewer packets, less overhead). It's a trade-off and makes sense.

Now I read the NFSv2 spec as saying if you are asked for N bytes, you can return <N bytes. However, if I limit the 8192 byte read request to say, 1024 bytes, the next request read offset increases by 8192 as if the client has totally ignored the fact it got less than 8192 bytes..
I have not checked the specification in detail, but it is possible that no real implementation ever did that, so maybe that codepath was never implemented or tested. Or maybe because no real servers ever limited the requests in such a way, clients never implemented it. Either way, don't do that.

Question: When a UDP packet length is >MTU and split up, thats a BadThing right? In the sense my sparc client is going to get 5 UDP packets and would be expected to glue them back together.
IP supports packets of up to 64 KB and will fragment if needed. This applies for both TCP and UDP and is required for packets to traverse low-MTU links (serial links) transparently. Implementations have to opt-out through the "don't fragment" bit, but that risks loss of communication to the target system (used for path MTU detection).

Some firewalls and networks will not pass UDP fragments, but that should not affect your local network.
 
Thanks all for your advice.

Some good progress on getting it boot; reading the Wireshark capture I noticed the NFS READ Reply had a <DATA> length of 8092 - not 8192.
I have a compile time TRANSFER_SIZE of 8192 for my reply struct. Because my buffer filler function truncates to what remaining space is in the buffer, and for a 8192 byte transfer including XDR headers etc etc, its >8192... Doh..

/sbin/init now runs! Gets busy reading various files but then dies...

i still think its pretty neat having a single executable serving everything without polluting your machine with a whole bunch of guff. But debugging it while debugging a possible sick sparc is a bit like this:

giphy.gif
 
Soooo close now. After switching to 7-bit serial, I now have a root prompt. Tadaaa.

However..

Trying to run anything gives a loader error:

Code:
ld.so: map heap error (19) for /dev/zero


In the tar file the /dev/XXX list with major/minor numbers, but in my exported root/dev they show as character devices, but not showing the major,minor listing - because they're SunOS not MacOS I guess?

adam@tosh-4 % ls -l /Users/Shared/export/root/sparc2/dev/zero
crw-rw-rw- 1 root daemon 0x300000c 14 Oct 1994 /Users/Shared/export/root/sparc2/dev/zero

yet in tar its listed as:
crw-rw-rw- 0 root daemon 3,12 14 Oct 1994 miniroot_img/dev/zero

The device maj,min are in the NFS getattr reply field that I'm copying in with htonl(info.st_dev) but perhaps its needs 2 htons() to pick out both major and minor to swizzle..
 
Last edited:
[yes default (shown by printenv) is 8,n,1. Setting to 7b did resolve the prompt from checkerboards to actual text..]

I dunno, you look away for one second.. (well, 30 years :rolleyes: ).. and device major,minor are no longer 8:8. Grr. Another fix for my little NFSv2 server done.
 
When I run 'suninstall', when it shows a menu of options, the cursor is all over the place and ^F/^B dont set the cursor onto a selection..

I did: TERM=vt100; export TERM

I did notice stty gives:
Code:
speed 9600 baud; evenp
-inpck imaxbel -tabs
iextern crt

Does that smell right?
 
On my run this morning I decided the ideal name for this is... polyd

I made a little repos with just polyd.c in it if you want to play. It should compile on MacOS and linux with: cc -o polyd polyd.c
[I did try and get git to keep the history when I split it off into its own repo, but given I have never, ever, ever got git to do what I want, it probably didn't work]

https://github.com/Elektraglide/polyd
 
Back
Top