Article 13078 of alt.sources:
Path: nntpd.lkg.dec.com!crl.dec.com!crl.dec.com!decwrl!infopiz!news1.best.com!news.texas.net!news.sprintlink.net!usenet.kornet.nm.kr!news.kreonet.re.kr!usenet.seri.re.kr!news.dacom.co.kr!newsfeed.internetmci.com!howland.reston.ans.net!ix.netcom.com!netcom.com!henderso
Newsgroups: alt.sources
Subject: change sun hostid 1.6.1 -- part 4/5
Message-ID: <hendersoDJyIzG.2so@netcom.com>
From: henderso@netcom.com (Mark C. Henderson)
Date: Thu, 21 Dec 1995 22:11:39 GMT
Sender: henderso@netcom12.netcom.com
Organization: Netcom
Lines: 1758

#!/bin/sh
# This is part 04 of a multipart archive
# ============= hid-1.6.1/nvram.info ==============
if test ! -d 'hid-1.6.1'; then
    echo 'x - creating directory hid-1.6.1'
    mkdir 'hid-1.6.1'
fi
if test -f 'hid-1.6.1/nvram.info' -a X"$1" != X"-c"; then
	echo 'x - skipping hid-1.6.1/nvram.info (File already exists)'
else
echo 'x - extracting hid-1.6.1/nvram.info (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'hid-1.6.1/nvram.info' &&
USE THIS AT YOUR OWN RISK. IF THIS INFORMATION IS ABUSED OR INCORRECT
YOU CAN RENDER YOUR COMPUTER UNBOOTABLE AND MY BET IS THAT SUN WILL
CHARGE A LOT OF MONEY TO FIX THE DAMAGE.
X 
Be careful, mistakes can cost a lot.
X 
The information in this document is distributed in the hope that
it will be useful, but without any warranty; without even the
implied warranty of merchantability or fitness for a particular
purpose. You use this document at your own risk. The author
disclaims responsibility for any damages that might result from the
use of this document, even if they result from negligence or errors
on the part of the author.
X 
Placed in the public domain by the author - Dec 1995
- Mark Henderson <markh@wimsey.bc.ca>
X
Thanks to Kevin Murty for the use of an SS1000 (and to the Sun FE
Handbook for the magic "update-system-idprom" command). Other contributors
are noted in the body of the text.
X
I've broken this document into the following parts.
X
I.      Introduction and Hardware
II.     General sun4c, sun4m, sun4d IDPROM Programming
III.    A Quick-and-Dirty Guide to Restoring the NVRAM of a sun4c/m Machine
IV.     The Sun 3/80
V.      Examples
VI.     Odds and Ends
X
-----
X
I.      Introduction and Hardware
X
Every Sun 3/80, sun4c, and sun4m architecture machine contains an NVRAM
chip. This NVRAM chip stores various configuration parameters (e.g.
boot device, amount of RAM to test), maintains the clock, and also
contains the IDPROM data, which is composed of the ethernet address,
date of manufacture, hostid, a version number, and a checksum.  The
name IDPROM is historical.  On older machines (sun2, sun3) the hostid
and ethernet address were stored in a PROM
X
sun4d machines (e.g. SS1000) also have an NVRAM chip. However, the
IDPROM information is stored in a flash EEPROM and is downloaded into
the NVRAM during POST. You can also upload information from the NVRAM
chip to the flash EEPROM. So you can change the value of the flash
EEPROM by merely changing the NVRAM and uploading the new values.
X
At this point I have no information on the new UltraSPARC machines.
X
This document is for people who want to accomplish one of the
following tasks
X
1. Install a virgin NVRAM chip in a Sun 3/80, sun4c, or sun4m machine. 
X   Usually this will be due to NVRAM failure or loss of the NVRAM password in
X   full security mode.
2. Change the hostid/ethernet address of a Sun 3/80, sun4c, sun4m, or
X   sun4d machine.
3. Restore a machine with a corrupted NVRAM chip in a Sun 3/80, sun4c,
X   or sun4m machine to working order.
X
I'm going to focus on methods that involve reprogramming the chip from
the FORTH OPENPROM monitor ("ok" prompt).
X
The NVRAM chip has a usually will have a barcode on it (except for
sun4d).  Given the barcode, Sun can reconstruct your original hostid
and ethernet address. I have no idea how this is done, but the barcode
serves as an easy way to identify the chip.
X
The NVRAM chips are SGS-Thomson Timekeeper (formerly Mostek) chips. They
contain an embedded battery with a fixed life. When the machine is off,
the battery runs down.  It is very common for the battery embedded in
the Timekeeper chip in an older Sun (sun4c, sun3x) to fail.
X
X    Architecture        Chip Type
X    sun3x (3/80)        M48T02
X    sun4c               M48T02
X    sun4m               M48T08
X    sun4d               M48T08
X    sun4u               M48T08
X
X
These chips come in various speeds. The SGS-Thomson part numbers are
M48T02-200PC1 for the 200ns M48T02, M48T08-100PC1 for the 100ns M48T08.
200ns is adequate for any Sun, but often the faster chips are easier to
come by, and there is no harm in buying them. If you have trouble
tracking down a local SGS-Thomson distributor, Mauser electronics sells
the SGS-Thomson Timekeeper chips (800-346-6873, 817-483-5712). The
Mauser part numbers as of 1995 are slighly different and are as
follows:
X
Part no.            Mauser part no.     speed         capacity
M48T02-200PC1       511-M48T02-20PC1    200ns   M48T02  2kB
M48T02-150PC1       511-M48T02-15PC1    150ns   M48T02  2kB
M48T02-120PC1       511-M48T02-12PC1    120ns   M48T02  2kB
M48T08-150PC1       511-M48T08-15PC1    150ns   M48T08  8kB
M48T08-100PC1       511-M48T08-10PC1    100ns   M48T08  8kB
X
As of Oct 1995, the prices for these chips from Mauser range from
US$16.00-23.12.  I have no affiliation with Mauser other than as a
customer
X
Dallas Semicondutor makes a clone of the SGS-Thomson M48T02 chips, the
DS1642.  I've had mixed experience using the Dallas chips in a Sun. My
experience is that these chips do NOT work properly in the following
machines:  3/80, SS2, IPX (they fail POST, but otherwise seem OK)
X
However, I have successfully used them in an SS1 and an IPC.
X
I have no idea whether the Dallas chips work properly in the following:
SLC, ELC, SS1+
X
You can order these chips in 120ns or 150ns speeds (150ns is fine)
directly from Dallas in quantities up to 10 by calling 1-800-336-6933
and giving Dallas a credit card number.  Data sheets and distrubutor
lists for Dallas are available from http://www.dalsemi.com
X
-----
II.     General sun4c, sun4m, sun4d IDPROM Programming
X
If you have a valid NVRAM chip installed (IDPROM is ok) then
before doing anything else, write down a copy of the nvram IDPROM
information. You can get it under Sun OS 4.1.x by running
/usr/etc/devinfo -vp (on Solaris 2.x, /usr/sbin/prtconf -vp) or at
the Openprom monitor "ok" prompt by typing the command
.idprom
(yes the "." is part of the command)
You'll need this information if the NVRAM gets screwed up and you need
to try and back out. 
X
Step 1. 
X
Go to the OpenBoot monitor (ok prompt). You can do this by turning on
your machine, pressing L1/Stop-A to interrupt the boot sequence, and
entering "new command mode". Alternatively, if your machine is running, 
just shut down your operating system.
X
If you are installing a virgin NVRAM type
set-defaults
Generally a machine will reset the NVRAM to the default values (excluding
the IDPROM information) when it detects a virgin NVRAM. Still, it is
good to do a "set-defaults" just in case this fails.
X
--
Step 2. 
X
The command to reprogram the IDPROM part of NVRAM is "mkp". The format
for the command is
X
<value> <location> mkp
X
where location is read off the following table (all values are in hexadecimal)
X
byte    contents
0       01    - version number - always 01
1       first byte of hostid (system type)
2-7     6 byte ethernet address (first three bytes are 08,00,20)
8-b     date of manufacture. Often all 0s. Doesn't matter.
c       second byte of hostid
d       third byte of hostid
e       fourth byte of hostid
f       IDPROM checksum  - bitwise xor of contents of bytes 0-e
X
You can look at the complete idprom by executing .idprom
X
Alternatively the command 
<location> idprom@
returns the IDPROM value of byte <location>
X
so 
<location> idprom@ .
prints the IDPROM value of byte <location>
X
Now make the changes using mkp. Be very careful and be sure to
compute the checksum after making changes. If you don't, you'll get
nasty warnings about an incorrect IDPROM checksum on boot.
X
A quick and dirty way to compute and store the checksum in location f
is to execute the following at the "ok" prompt _after_ you have
made your changes to locations 0-e.
X
0 f 0 do i idprom@ xor loop f mkp
X
I'm know repeating myself, but don't change the first byte of the
hostid to something that doesn't correspond to your system type (see
table below) or the first three bytes of the ethernet address from
(0x08,0x00,0x20). The first byte of the hostid is often used to
determine the architecture when booting from CDROM on most current Sun
models. If you alter the first three bytes of the ethernet address you
might get message which say that you have a defective motherboard (but
then I don't know of any other consequences of changing this to some
_reasonable_ value, especially avoid ff:ff:ff:ff:ff:ff !)
X
e.g.  modify the hostid of an IPX to be 57c0ffee and the ethernet address
X      to be 08:00:20:c0:ff:ee. 
X
X   at the forth monitor prompt (ok)
X
X   1 0 mkp
X   57 1 mkp
X   8 2 mkp
X   0 3 mkp
X   20 4 mkp
X   c0 5 mkp
X   ff 6 mkp
X   ee 7 mkp
X   0 8 mkp
X   0 9 mkp
X   0 a mkp
X   0 b mkp
X   c0 c mkp
X   ff d mkp
X   ee e mkp
X   0 f 0 do i idprom@ xor loop f mkp
X
--
Step 3.
X
X If you are on an SS1000, type
X update-system-idprom 
X at the ok prompt.
X
X For any of the above machines, now type reset at the ok prompt. Your
X machine should then attempt to reboot with your new hostid/enet addr. 
X
--
Here's a table which matches system models with the first byte of the
hostid. This is from a posting to comp.sys.sun.admin by
Andy.Behrens@coat.com
X
X    01  2/1x0
X    02  2/50
X    11  3/160
X    12  3/50
X    13  3/2x0
X    14  3/110
X    17  3/60
X    18  3/e
X    21  4/2x0
X    22  4/1x0
X    23  4/3x0
X    24  4/4x0
X    31  386i/150 or 386i/250
X    41  3/4x0
X    42  3/80
X    51  SPARCstation 1   (4/60)
X    52  SPARCstation IPC (4/40)
X    53  SPARCstation 1+  (4/65)
X    54  SPARCstation SLC (4/20)
X    55  SPARCstation 2   (4/75)
X    56  SPARCstation ELC (4/25)
X    57  SPARCstation IPX (4/50)
X    61  4/e
X    71  4/6x0   (670)
X    72  SPARCstation 10,20
X    80  SPARCclassic, LX, SPARC 5, SPARC 4, SS1000, Voyager
X
X
-----
III.    A Quick-and-Dirty Guide to Restoring the NVRAM of a sun4c/m Machine
X
This is for folks who need to replace their NVRAM chip in a sun4c/m
machine and don't want to bother with XOR calculations or the details
above with mkp. I am assuming that you have a brand new NVRAM chip in
hand.
X
All numbers below are in hex.
X
Decide what ethernet address you want to use and what you want for the
last three byte of the hostid. The ethernet address must begin with
08:00:20. There are no restrictions on the last three bytes of the
hostid. Say the ethernet address is E0:E1:E2:E3:E4:E5 and the last
three bytes of the hostid are H1, H2, H3. The first byte of the hostid
will automatically be set according to the system type.
X
Turn off the machine. Remove the old NVRAM chip (note the
orientation).  Insert the new NVRAM chip. Be sure to insert it in the
correct orientation as installing it in the wrong orientation and
powering on the machine will generally destroy the chip. Power up the
machine and bring it to the "ok" prompt.
X
now at the "ok" prompt...
set-defaults
setenv diag-switch? false
E0 E1 E2 E3 E4 E5 H1H2H3 mkpl
X
mkpl expects some input (but it doesn't prompt you). The input is a 
Control-D followed by a Control-R. If mkpl does _not_ print a copyright
notice, then it changed the IDPROM, but you can look at the idprom after
doing this with the command
.idprom
to make sure that things look sane.
X
e.g.
X
08 00 20 13 de ad c0ffee mkpl
X
will set the last three bytes of the hostid to c0ffee and the ethernet
address to 08:00:20:13:de:ad. 
X
N.B. mkpl will only work if the IDPROM checksum is _invalid_. Otherwise
it will simply print a copyright notice after you type the Control-R.
You can invalidate the IDPROM checksum in an NVRAM with a valid IDPROM
checksum by executing 
f idprom@ 1 + f mkp
X
-----
IV.     The Sun 3/80
X
Here's a way to modify NVRAM IDPROM info on a Sun 3/80 (people have
to do this because of the usual battery problem, as with the sun4c
machines)
X
This may not be the most elegant procedure, but this should allow you
to modify the NVRAM IDPROM info on a sun 3/80. At first glance you
might think that the q command would work, but it doesn't seem to
actually modify anything when given addresses >= 0x7d8
X
Hit L1-A after you turn it on
X
N.B.: ^t is a command. Don't try control-T. 
X
Only tested with 2.9.2 PROMS.
X
> ^t fef04000
you'll get output which includes the following (samples included)
TIA entry = 33FA500
TIB entry = 33FB80A
PTE = 64000049
X
Write these values down!!
X
now change the TIA entry for fedfa000 to match the above
X
> m a fedfa000
TIA MAP FEDFA000 [...] ? 33FA500
X   hit control-D at next ? prompt
X
now change the TIB entry to match the above
X
> m b fedfa000
TIB MAP FEDFA000 [...] ? 33FB80A
X
now change the pagemap entry to match the above
> p fedfa000
PageMap FEDFA000 [...] ? 64000049
X
> o fedfa7d8
...
X
now enter new IDPROM values. You need to get the checksum right.
X
byte          contents
fedfa7d8      01    - version number - always 01
fedfa7d9      first byte of hostid (system type, 42 for sun 3/80)
fedfa7da-df   6 byte ethernet address (first three bytes are 08,00,20)
fedfa7e0-e3   date of manufacture. Often all 0s
fedfa7e4      second byte of hostid
fedfa7e5      third byte of hostid
fedfa7e6      fourth byte of hostid
fedfa7e7      IDPROM checksum  - xor of contents of bytes d8-e6
X
X
Note if you have SUN OS 4.1.1 booted (i.e. you're doing this for some other
reason than an IDPROM with invalid data), you can just write values into
fedfa7d8 ... fedfa7e7 with the o command. You don't need to do all the
mapping stuff.
X
If you are installing a virgin M48T02 chip, you'll also need to initialise
the other values in NVRAM, e.g. boot device, memory, etc. Unlike the
sun4c machines, the Sun 3/80 does not set these parameters to sane
defaults when it detects a virgin M48T02. To modify the rest of NVRAM 
you can use the "q" command in the monitor.
X
The following table of memory locations in NVRAM for the Sun 3 series
machines is from the Sun Hardware Reference 
by James W. Birdsall <jwbirdsa@picarefy.com>
X
I provide it here so you won't have to dig up the Sun Hardware Reference
to restore a 3/80 to working order.
X
X
X        SUN 3 EEPROM/NVRAM Parameters
X
X        0x14    Installed memory
X          Megabytes of memory installed
X
X        0x15    Tested memory
X          Megabytes of memory tested during power-on self test (POST)
X
X        0x16    Monitor screen size
X          0x00   1152 x 900 (standard resolution)
X          0x12   1024 x 1024 (1Kx1K)
X          0x13   1600 x 1280 (high resolution, see locations 0x50 and 0x51)
X          0x14   1440 x 1440
X          0x15   1024 x 768 (low resolution)
X
X        0x17    Watchdog reset action
X          0x00   invoke ROM monitor
X          0x12   imitate power-on reset (default)
X
X        0x18    Operating system boot device
X          0x00   poll (default)
X          0x12   boot from EEPROM/NVRAM specified boot device
X
X        0x19-0x1A  SunOS boot device name (in ASCII)
X          0x78 0x79 (xy)  Xylogics 450/451 SMD controller
X          0x78 0x64 (xd)  Xylogics 7053 SMD controller
X          0x73 0x64 (sd)  SCSI disk
X          0x69 0x65 (ie)  Ethernet (Intel-based controller)
X          0x69 0x64 (id)  IPI disk
X          0x67 0x6E (gn)  ???
X          0x6C 0x65 (le)  Ethernet (Lance-based controller)
X
X        0x1B-0x1D  SunOS boot device controller, unit, partition numbers
X          0x00 0x00 0x00 (0,0,0) (default)
X
X        0x1F    Primary terminal
X          0x00   monochrome framebuffer
X          0x10   serial port A
X          0x11   serial port B
X          0x12   VMEbus and 3/60-P4 color frame buffers (configure
X                  locations 0x60C-0x613 when VX and MVX graphics options
X                  are installed)
X          0x20   non-3/60 P4 color frame buffer
X
X        0x20    Power-up banner
X          0x00   Sun logo display
X          0x12   custom banner stored in 0x68-0xB7
X
X        0x21    Keyboard click
X          0x00   OFF
X          0x12   ON (default)
X
X        0x22-0x23  Diagnostic boot device name (in ASCII)
X          Used when NORM/DIAG switch in DIAG position. As 0x19-0x1A, or
X          0x00 0x00 to invoke ROM monitor.
X
X        0x24-0x26  Diagnotic boot device controller, unit, partition numbers
X          Used when NORM/DIAG switch in DIAG position. As 0x1B-0x1D.
X
X        0x28-0x4F  Diagnostic boot path
X          Used when NORM/DIAG switch in DIAG position. ASCII codes for
X           path and filename(?) to boot, or all zeroes to invoke ROM
X           monitor.
X
X        0x50    High resolution number of columns
X
X        0x51    High resolution number of rows
X
X        0x58    Serial port A default baud rate
X          0x00   9600 baud
X          0x12   use rate stored at 0x59-0x5A
X
X        0x59-0x5A  Serial port A baud rate
X          The baud rate as a 16-bit number, MSB first (e.g. 0x04 0xB0
X           for 1200, 0x12 0xC0 for 4800, 0x25 0x80 for 9600).
X
X        0x5B    Serial port A DTR/RTS
X          0x00   assert DTR and RTS signals
X          0x12   do not assert DTR and RTS signals
X
X        0x60    Serial port B default baud rate
X          0x00   9600 baud
X          0x12   use rate stored at 0x61-0x62
X           Note that when the NORM/DIAG switch is in the DIAG position,
X           port B runs at 1200 baud and the settings of locations
X           0x60-0x62 are ignored.
X
X        0x61-0x62  Serial port B baud rate
X          The baud rate as a 16-bit number, MSB first (e.g. 0x04 0xB0
X           for 1200, 0x12 0xC0 for 4800, 0x25 0x80 for 9600).
X
X        0x63    Serial port B DTR/RTS
X          0x00   assert DTR and RTS signals
X          0x12   do not assert DTR and RTS signals
X
X        0x68-0xB7  Custom banner
X          ASCII codes for desired banner, padded with spaces and ending
X           with 0x0D, 0x0A in locations 0xB6 and 0xB7
X
X        0x111   Sun386i CPU revision level
X          0x01   P1.5 CPU (should not be in the field)
X          0x02   501-1241/1324-xx
X          0x03   501-1413/1414-xx
X
X        0x112   Sun386i CPU revision level
X          0x00   P1.5 CPU (should not be in the field)  ([0x111] = 0x01)
X          0x00   <= 501-1241-02 Rev 15                  ([0x111] = 0x02)
X                 <= 501-1324-02 Rev 15
X          0x02   >= 501-1241-02 Rev 16                  ([0x111] = 0x02)
X                 >= 501-1324-02 Rev 16
X          0x00   501-1413/1414-xx                       ([0x111] = 0x03)
X
X        0x154   Sun386i SCSI spin-up delay (boot ROM >= 4.5 only)
X          0x00   no delay (default)
X          0xnn   delay nn seconds
X
X        0x162   Sun386i password mode select (boot ROM >= 4.5 only)
X          0x01   command secure mode
X          0x5E   fully secure mode
X          other  non-secure mode
X
X        0x163-0x16A  Sun386i password
X          Eight bytes of password in ASCII.
X
X        0x18F   Logo type
X          0x00   normal Sun logo
X          0x06   3D logo for cgsix framebuffers
X          0x12   custom logo
X
X        0x492   Sun386i power-on mode
X          0x02   bypass mode
X          0x06   diagnostic boot
X          0x07   normal boot
X
X                Sun-3 and Sun-4 password mode select (boot ROM >= 2.7.1 only)
X          0x01   command secure mode
X          0x5E   fully secure mode
X          other  non-secure mode
X
X        0x493-0x49A  Sun-3 and Sun-4 password (boot ROM >= 2.7.1 only)
X          Eight bytes of password in ASCII. If the ROM is 2.8, enter a
X          '@' character before each letter of the password. Enter one
X          letter per location, followed by <Return>. If the password is
X          less than eight letters, enter 0x00 in the remaining
X          locations. The hexadecimal values of the letters can also be
X          used to enter the password.
X
X        0x494   Sun386i autoconfig message flag
X          0x00   no messages
X          0x01   Sun-3 (UNIX expert type messages)
X          0x02   verbose messages
X
X        0x60C-0x60F  VX and MVX options boot code
X          0x31 0x40 0x00 0x00   use the VX/MVX as the system console
X
X        0x610-0x61e  VX and MVX options bus type
X          0xFC 0x00 0x00 0x00   use the VX/MVX as the system console
X
X        0x70B   3/80 power-on mode (boot ROM >= 2.3 only)
X          0x06   normal boot
X          0x12   diagnostic mode
X          other full diagnostic boot
X
-----
V.      Examples
X
N.B. AS I'VE SAID ABOVE, YOU SHOULD BE CAREFUL THAT THE FIRST BYTE OF THE 
X     HOSTID MATCHES YOUR SYSTEM TYPE.
X
X   
1. modify the hostid of an IPX to be 57c0ffee and the ethernet address
X   to be 08:00:20:c0:ff:ee
X
X   at the forth monitor prompt
X
X   01 0 mkp
X   57 1 mkp
X   08 2 mkp
X   0 3 mkp
X   20 4 mkp
X   c0 5 mkp
X   ff 6 mkp
X   ee 7 mkp
X   57 8 mkp
X   0 9 mkp
X   0 a mkp
X   0 b mkp
X   c0 c mkp
X   ff d mkp
X   ee e mkp
X   29 f mkp
X
Notice the simplification in the above example. If you make the
ethernet address 08:00:20:H1:H2:H3 and the four bytes of the hostid
ST,H1,H2,H3 resp.  where ST is the system type byte, and you put
ST,0,0,0 in the date of manufacture field, then the IDPROM checksum
will always be 29 (remember all of these numbers are hexadecimal).
This make things a bit easier, you can, in general, just enter
X   01 0 mkp
X   ST 1 mkp
X   08 2 mkp
X   0 3 mkp
X   20 4 mkp
X   H1 5 mkp
X   H2 6 mkp
X   H3 7 mkp
X   ST 8 mkp
X   0 9 mkp
X   0 a mkp
X   0 b mkp
X   H1 c mkp
X   H2 d mkp
X   H3 e mkp
X   29 f mkp
X
without worrying about the checksum
X
X
2. modify the hostid of an SS10 to be 72c0ffee and the ethernet address
X   to be 08:00:20:c0:ff:ee
X
X   at the forth monitor prompt
X
X   01 0 mkp
X   72 1 mkp
X   08 2 mkp
X   0  3 mkp
X   20 4 mkp
X   c0 5 mkp
X   ff 6 mkp
X   ee 7 mkp
X   0 8 mkp
X   0 9 mkp
X   0 a mkp
X   0 b mkp
X   c0 c mkp
X   ff d mkp
X   ee e mkp
X   0 f 0 do i idprom@ xor loop f mkp
X
3. modify the hostid of an SS1000 to be 80c0ffee and the ethernet address
X   of 08:00:20:c0:ff:ee
X
X   at the forth monitor prompt
X
X   01 0 mkp
X   80 1 mkp
X   08 2 mkp
X   0 3 mkp
X   20 4 mkp
X   c0 5 mkp
X   ff 6 mkp
X   ee 7 mkp
X   80 8 mkp
X   0 9 mkp
X   0 a mkp
X   0 b mkp
X   c0 c mkp
X   ff d mkp
X   ee e mkp
X   29 f mkp
X   update-system-idprom
X
4. Install a virgin NVRAM in an IPX. Set the hostid to 57c0ffee and the
X   ethernet address to be 08:00:20:c0:ff:ee
X
X   Remove the old NVRAM
X   Install the new NVRAM (correct orientation!)
X
X   at the forth monitor prompt
X
X   set-defaults
X   setenv diag-switch? false
X   08 00 20 c0 ff ee c0ffee mkpl
X   ^D^R
X
X   (where ^D represents Control-D etc.)
X
X
-----
X
VI.     Odds and Ends
X
X
Resetting the NVRAM (when L1-N doesn't do it)
X
You might want to do this to recover from the loss of an NVRAM password
(in full security mode) or if you mess up your nvramrc. My take on this
situtation is that the safest thing to do is pay the $20 for a new
Timekeeper chip. But several people have reported to me that it is safe
to hot-swap the NVRAM when the system is on.
X
dowdy@cs.colorado.edu (Stephen Dowdy) writes:
> (this may apply to other SPARC models.)
> IPC --  remove NVRAM, power-up without.  *carefully* hot-plug it in when OK
>     prompt comes up (after it says CHECKSUM failure).  do:
>         OK set-defaults
>         OK set-defaults
>     then power-cycle
> 
> SS2 --  you need to boot from a good NVRAM, then hot-swap the "bad" one
>     and "set-defaults".  Only if the L1-N (or is it L1-D) thingy
>     doesn't work for you.
X
SHAR_EOF
chmod 0600 hid-1.6.1/nvram.info ||
echo 'restore of hid-1.6.1/nvram.info failed'
Wc_c="`wc -c < 'hid-1.6.1/nvram.info'`"
test 22487 -eq "$Wc_c" ||
	echo 'hid-1.6.1/nvram.info: original size 22487, current size' "$Wc_c"
fi
# ============= hid-1.6.1/nvram_old.c ==============
if test -f 'hid-1.6.1/nvram_old.c' -a X"$1" != X"-c"; then
	echo 'x - skipping hid-1.6.1/nvram_old.c (File already exists)'
else
echo 'x - extracting hid-1.6.1/nvram_old.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'hid-1.6.1/nvram_old.c' &&
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
X
/* 
get/change hostid in NVRAM --
X
old version -- I should throw this away. Less friendly but perhaps
X  easier to modify for other types of machines.
X
only tested on sun4m architecture and sun4c architecture. The
kernel patches will be different for Sun4 and I don't have one
to play with. 
X
This program is still experimental. Dangerous and tricky stuff.
If you are unwilling to experiment and clean up after disasters
don't use it. hid is probably safer. USE AT YOUR OWN RISK.
X
Note the define OFFSET below!
X
running this will invalidate the overall NVRAM checksum. So after it
make some trivial change with the eeprom command (change the baud
rate on a serial port or something like that
e.g.
/usr/etc/eeprom diag-switch?=false
)
X
first you need to turn off the protection in the OS to keep
you from modifying /dev/eeprom locations after 017730 
use adb
adb -k -w /vmunix /dev/mem
_mmeeprom+8/W 901223ff
X
which changes
or      %o1, 0x3d8, %o1
to
or      %o1, 0x3ff, %o1
X
X
Unfortunately this change with adb to the eeprom device seems to depend
on the exact version of Sun OS you are running. Don't assume it will
work without looking around intelligently.
X
e.g. For SUN OS 4.1.1 on a Sun 4c you need to:
adb -w /vmunix /dev/mem
_mmeeprom+4/W 80a6a7ff
_mmeeprom+0x28/W 80a6a7ff
which changes a couple of compare operations. 
X
Also be very careful. The first byte of the hostid identifies the type 
of system you are running. On modern Suns OS boot CDs depend on this 
information to get the correct architecture. If you change it you may 
be reduced to poking around in NVRAM from the monitor next time you have
to boot from CD.
X
Here's a mapping of what gets read into buf (at OFFSET)
buf[0] = always 01?
buf[1] = system id/first byte of hostid.
buf[2] \
buf[3]  \
buf[4]   \  HW ethernet address (6 bytes)
buf[5]    /  
buf[6]  /
buf[7]/
buf[8],...,buf[11] = always 00?
buf[12] = second byte of hostid
buf[13] = third byte of hostid
buf[14] = fourth byte of hostid
buf[15] = checksum
X
the checksum is buf[0] ^ buf[1] ^ ... ^ buf[14]
i.e. it must be the case that the  xor of buf[0] through buf[15] is 0
X
Without any parameters, it reports the hostid from NVRAM. Otherwise it
changes it. 
X
Mark Henderson <markh@wimsey.bc.ca>
Placed in the public domain by the author - 23 June 1994
X
This program is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose. You use
this program at your own risk. The author disclaims responsibility for
any damages that might result from the use of this program, even
if they result from negligence on the part of the author.
X
Also, please don't use this program to steal software. The intended
use is for emergency situations where an application has to be moved from
one computer to another (e.g. in the event of a hardware malfunction)
and licence keys cannot be obtained quickly from the vendor. Many
vendors will not supply licence keys outside of business hours.
X
*/
X
X
#define OFFSET 017730       /* for Sun 4m, Sun OS 4.1.3 */
/* #define OFFSET 03730     /* for Sun 4c, SUN OS 4.1.1 */
X
#define SANITY_CHECK        /* don't turn this off unless you need to. If this
X                               fails it generally means that the program won't
X                               work and very well may be destructive */
X
#undef TEST         /* doesn't actually do mods if TEST is defined */
unsigned char buf[17]; 
X
main(argc,argv)
int argc;
char *argv[];
{
X    unsigned int hid;
X    int fd;
X    int i;
X    unsigned int acc;
X    int read_hostid;
X    unsigned int hid_reported_by_gethostid = gethostid();
X
X    if (argc == 1) {
X        /* no args - just get hostid from prom */
X        read_hostid = 1;
X    }
X    else if (argc == 2) {
X        read_hostid = 0;
X        sscanf(argv[1],"%08x",&hid);
X    }
X    else {
X        fprintf(stderr, "usage: %s [hostid]\n",argv[0]);
X        fprintf(stderr, "  e.g. %s b0b1fb0b\n", argv[0]);
X        exit(1);
X    }
X    if (read_hostid) {
X        if ((fd = open("/dev/eeprom", O_RDONLY)) < 0) {
X            fprintf(stderr, "cannot open /dev/eeprom for read\n");
X            exit(1);
X        }
X    } 
X    else {
#ifdef TEST
X        if ((fd = open("/dev/eeprom", O_RDONLY)) < 0) {
X            fprintf(stderr, "cannot open /dev/eeprom for read\n");
X            exit(1);
X        }
#else
X        if ((fd = open("/dev/eeprom", O_RDWR)) < 0) {
X            fprintf(stderr, "cannot open /dev/eeprom for read\n");
X            exit(1);
X        }
#endif
X    }
X
X    if (lseek(fd,OFFSET,SEEK_SET) < 0) { 
X        fprintf(stderr, "lseek failed\n");
X        exit(1);
X    }
X
X    if (read_hostid) {
X        if (read(fd,buf,16) < 16) {
X            fprintf(stderr, "read of /dev/eeprom failed\n");
X            exit(1);
X        }
X        printf("%02x%02x%02x%02x\n", buf[1], buf[12], buf[13], buf[14]);
X        for (acc = 0 , i=0; i<15; i++) acc^=buf[i];
X        if (acc != buf[15])  {
X            fprintf(stderr, "warning: ID CHKSUM INVALID\n");
X            fprintf(stderr,"^buf = %02x\n", acc & 0xff);
X            fprintf(stderr,"buf[15] = %02x\n", buf[15] & 0xff);
X        }
X    }
X    else {
#ifdef SANITY_CHECK 
/* this will fail if you have modified the value returned by
X   gethostid by using one of the other programs in this package.
X   In that case I wouldn't turn this off but restore your old 
X   gethostid behaviour or replace the gethostid call above with
X   a reference to your "real" hostid, if your architecture 
X   is weird this should detect the problem and not try and
X   write into places we shouldn't. */
X
X        if (read(fd,buf,16) < 16) {
X            fprintf(stderr, "read of /dev/eeprom failed\n");
X            exit(1);
X        }
#ifdef TEST
X        for (i=0; i<16; i++)
X            printf("%02x ", buf[i]);
X        printf("\n");
#endif
X        for (acc = 0 , i=0; i<15; i++) acc^=buf[i];
X        if ((acc != buf[15]) 
X            || (buf[1] != (hid_reported_by_gethostid >> 24) )
X            || (buf[12] != ((hid_reported_by_gethostid >> 16) &0xff))
X            || (buf[13] != ((hid_reported_by_gethostid >> 8) &0xff))
X            || (buf[14] != (hid_reported_by_gethostid &0xff))) {
X        
X            fprintf(stderr, "SANITY CHECK FAILED -- aborting\n");
X            fprintf(stderr, 
X                "perhaps the value of the define OFFSET is wrong\n");
X            exit(1);
X        }
X            
X        if (lseek(fd,OFFSET,SEEK_SET) < 0) { 
X            fprintf(stderr, "lseek failed\n");
X            exit(1);
X        }
X
#endif
X        buf[1] = hid >> 24;
X        buf[12] = (hid >> 16) &0xff;
X        buf[13] = (hid >> 8) &0xff;
X        buf[14] = hid &0xff;
X        for (acc = 0 , i=0; i<15; i++) acc^=buf[i];
X        buf[15] = acc & 0xff;
#ifndef TEST
X        if (write(fd,buf,16) < 16) {
X            fprintf(stderr, "write failed\n");
X        }
#else
X    for (i=0; i<16; i++)
X        printf("%02x ", buf[i]);
X    printf("\n");
X
#endif
X    }
X    close(fd);
}
X
SHAR_EOF
chmod 0600 hid-1.6.1/nvram_old.c ||
echo 'restore of hid-1.6.1/nvram_old.c failed'
Wc_c="`wc -c < 'hid-1.6.1/nvram_old.c'`"
test 7012 -eq "$Wc_c" ||
	echo 'hid-1.6.1/nvram_old.c: original size 7012, current size' "$Wc_c"
fi
# ============= hid-1.6.1/sidump.c ==============
if test -f 'hid-1.6.1/sidump.c' -a X"$1" != X"-c"; then
	echo 'x - skipping hid-1.6.1/sidump.c (File already exists)'
else
echo 'x - extracting hid-1.6.1/sidump.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'hid-1.6.1/sidump.c' &&
/* modify hostid reported by gethostid and sysinfo for Solaris 2.3 and 1.1
X   dynamically linked binaries 
Placed in the public domain by the author 
Mark Henderson - markh@wimsey.bc.ca - 18 July 1994
X
This program is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose. You use
this program at your own risk. The author disclaims responsibility for
any damages that might result from the use of this program, even
if they result from negligence on the part of the author.
X
Also, please don't use this program to steal software. The intended
use is for emergency situations where an application has to be moved from
one computer to another (e.g. in the event of a hardware malfunction)
and licence keys cannot be obtained quickly from the vendor. Many
vendors will not supply licence keys outside of business hours.
X
New feature to be included in version 1.0 of the package: 18 July 1994
the environment variable HID can be set to the desired hostid in hex.
(no leading 0x, a-f lower case)
X
In retrospect, I should have written this in perl.
X
Instructions:
X
Solaris 1.x
1. compile this program
X    cc -o sidump sidump.c
2. run it with the desired hostid as the first parameter and save the output
X    in a file with the extension .c 
X    ./sidump b0b1fb0b >foo.c
3. make foo.o from foo.c
X      gcc -fpic -c foo.c
X      ld foo.o  -assert pure-text -o foo.so
X   OR
X      cc -PIC -c foo.c
X      ld foo.o -assert pure-text -o foo.so
4. export LD_PRELOAD=$PWD/foo.so      (ksh)
X   setenv LD_PRELOAD $PWD/foo.so      (csh)
5. run the desired program
X
here's a sample session
feral> cc -o sidump sidump.c
feral> ./sidump b0b1fb0b >foo.c
feral> cc -PIC -c foo.c
feral> ld -assert pure-text foo.o -o foo.so
feral> export LD_PRELOAD=$PWD/foo.so
feral> lmhostid
feral> lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc.
The FLEXlm host ID of this machine is "b0b1fb0b"
feral> export HID=72000000
feral> lmhostid
lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc.
The FLEXlm host ID of this machine is "72000000"
X
--------------
Solaris 2.x
X
1. compile this program
X    gcc -DSOLARIS2 -o sidump sidump.c
2. run it with the desired hostid as the first parameter and save the output
X    in a file with the extension .c 
X    ./sidump b0b1fb0b >foo.c
3. make foo.o from foo.c
X      gcc -fpic -c foo.c
X      ld foo.o  -G -o foo.so
4. export LD_PRELOAD=$PWD/foo.so      (ksh)
X   setenv LD_PRELOAD $PWD/foo.so      (csh)
5. run the desired program
X
here's a sample session:
X
ratatosk> gcc -o sidump sidump.c
ratatosk> ./sidump b0b1fb0b >foo.c
ratatosk> gcc -fpic -c foo.c
ratatosk> ld foo.o  -G -o foo.so
ratatosk> export LD_PRELOAD=$PWD/foo.so
ratatosk> hostid
b0b1fb0b
ratatosk> lmhostid
lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc.
The FLEXlm host ID of this machine is "b0b1fb0b"
ratatosk> export HID=72000000
ratatosk> lmhostid
lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc.
The FLEXlm host ID of this machine is "72000000"
X
X
*/
X
X
#include <stdio.h>
#ifdef SOLARIS2
#include <sys/systeminfo.h>
int commands[] = {SI_HW_SERIAL, SI_SYSNAME,SI_HOSTNAME,
X SI_RELEASE,SI_VERSION,SI_MACHINE,SI_ARCHITECTURE,SI_HW_PROVIDER,
X SI_SRPC_DOMAIN};
#endif
X
#define NCOMMANDS (sizeof(commands)/sizeof(int))
X
main(argc,argv)
int argc;
char *argv[];
{
X    int i,j;
X    char buf[1024];
X    unsigned int hostid;
X    if (argc != 2) {
X        fprintf(stderr, "usage: %s hostid\n", argv[0]);
X        exit(1);
X    }
X    sscanf(argv[1], "%x", &hostid);
X    printf("#include <string.h>\n");
X    printf("#include <stdlib.h>\n");
X    printf("extern char **environ;\n");
X    printf("unsigned int xyzzy_ghid()\n");
X    printf("{\n");
X    printf("    int i,j,c; char **s; char *e;\n");
X    printf("    unsigned int hid;\n");
X    printf("    hid = 0;\n");
X    printf("    s = environ;\n");
X    printf("    for (; *s; s++) {\n");
X    printf("        e = *s;\n");
X    printf("        if (*e++ == \'H\' \n");
X    printf("            && (*e++ == \'I\')\n");
X    printf("            && (*e++ == \'D\')\n");
X    printf("            && (*e++ == \'=\'))  {\n");
X    printf("                for (j=28; (*e) && j>=0; j -=4 ) {\n");
X    printf("                    c = (-1);\n");
X    printf("                    if (*e >= \'0\' && *e <= \'9\') \n");
X    printf("                        c = *e - \'0\';\n");
X    printf("                    if (*e >= \'a\' && *e <= \'f\') \n");
X    printf("                        c = *e - \'a\' + 10;\n");
X    printf("                    e++;\n");
X    printf("                    if (c == (-1))\n");
X    printf("                        break;\n");
X    printf("                    hid = hid | (c << j);\n");
X    printf("                }\n");
X    printf("            return hid;\n");
X    printf("        }\n");
X    printf("    }\n");
X    printf("    return 0;\n");
X    printf("}\n");
X    printf("gethostid() { \n");
X    printf("unsigned x;\n");
X    printf("if (x=xyzzy_ghid()) \n");
X    printf("{return x; }");
X    printf("else return 0x%08x; }\n", hostid);
#ifdef SOLARIS2
X    printf("long sysinfo(command,buf,count)\nint command;\nchar *buf;\n");
X    printf("long count;\n{\nchar *c = buf; int i; unsigned int x,y;\n");
X    printf("switch(command) { \n");
X    printf("case %u:\n", commands[0]);
X    sprintf(buf,"%u",hostid);  /* should this be %010u ??? */
X    printf("if (!(x = xyzzy_ghid())) {\n");
X    for (j=0; j < strlen(buf); j++)
X        printf("if (c < (buf + count)) *c++ = '%c';\n", buf[j]);
X    printf("if (c < (buf + count)) *c++ = 0;\n");
X    printf("buf[count-1] = 0;\n");
X    printf("}\n");
X    printf("else {\n");
X    printf("y = 1000000000;\n");
X    printf("for (i=0; (i<10) && (i<count); i++) {\n");
X    printf("buf[i] = (x/y) + '0'; x -= (x/y) * y;");
X    printf("y/=10; }\n");
X    printf("if (count < 11) buf[count - 1] = 0 ; else buf[10] = 0;}\n");
X    printf("break;\n");
X    for (i=1; i< NCOMMANDS; i++) {
X        sysinfo(commands[i], buf,1024);
X        printf("case %u:\n", commands[i]);
X        for (j=0; j < strlen(buf); j++)
X            printf("if (c < (buf + count)) *c++ = '%c';\n", buf[j]);
X        printf("if (c < (buf + count)) *c++ = 0;\n");
X        printf("buf[count-1] = 0;\n");
X        printf("break;\n");
X    }
X    printf("default: \nreturn(-1); \n}\n");
X    printf("return(strlen(buf) + 1);}\n");
#endif
}
SHAR_EOF
chmod 0600 hid-1.6.1/sidump.c ||
echo 'restore of hid-1.6.1/sidump.c failed'
Wc_c="`wc -c < 'hid-1.6.1/sidump.c'`"
test 6378 -eq "$Wc_c" ||
	echo 'hid-1.6.1/sidump.c: original size 6378, current size' "$Wc_c"
fi
# ============= hid-1.6.1/sidump_old.c ==============
if test -f 'hid-1.6.1/sidump_old.c' -a X"$1" != X"-c"; then
	echo 'x - skipping hid-1.6.1/sidump_old.c (File already exists)'
else
echo 'x - extracting hid-1.6.1/sidump_old.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'hid-1.6.1/sidump_old.c' &&
/* modify hostid reported by gethostid and sysinfo for Solaris 2.3 
X   dynamically linked binaries 
Basically a simpler version of sidump.c - this one doesn't have hooks for
X   the HID environment variable. 
Placed in the public domain by the author 
Mark Henderson - markh@wimsey.bc.ca - 8 July 1994
X
This program is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose. You use
this program at your own risk. The author disclaims responsibility for
any damages that might result from the use of this program, even
if they result from negligence on the part of the author.
X
Also, please don't use this program to steal software. The intended
use is for emergency situations where an application has to be moved from
one computer to another (e.g. in the event of a hardware malfunction)
and licence keys cannot be obtained quickly from the vendor. Many
vendors will not supply licence keys outside of business hours.
X
Instructions:
1. compile this program
X    gcc -o sidump sidump_old.c
2. run it with the desired hostid as the first parameter and save the output
X    in a file with the extension .c 
X    ./sidump b0b1fb0b >foo.c
3. make foo.o from foo.c
X      gcc -fpic -c foo.c
X      ld foo.o  -G -o foo.so
4. export LD_PRELOAD=$PWD/foo.so      (ksh)
X   setenv LD_PRELOAD $PWD/foo.so      (csh)
5. run the desired program
X
(Note: it actually seems enough to do the following in 3/4:
gcc -c foo.c
export LD_PRELOAD=$PWD/foo.o
)
X
here's a sample session:
X
ratatosk> gcc -o sidump sidump_old.c
ratatosk> ./sidump b0b1fb0b >foo.c
ratatosk> gcc -fpic -c foo.c
ratatosk> ld foo.o  -G -o foo.so
ratatosk> export LD_PRELOAD=$PWD/foo.so
ratatosk> hostid
b0b1fb0b
ratatosk> lmhostid
lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc.
The FLEXlm host ID of this machine is "b0b1fb0b"
X
You could wrap this in a script for convenience (q.v. newhostid)
X       Solaris 1.1)
X
*/
X
X
#include <stdio.h>
#include <sys/systeminfo.h>
int commands[] = {SI_HW_SERIAL, SI_SYSNAME,SI_HOSTNAME,
X SI_RELEASE,SI_VERSION,SI_MACHINE,SI_ARCHITECTURE,SI_HW_PROVIDER,
X SI_SRPC_DOMAIN};
X
#define NCOMMANDS (sizeof(commands)/sizeof(int))
X
main(argc,argv)
int argc;
char *argv[];
{
X    int i,j;
X    char buf[1024];
X    unsigned int hostid;
X    if (argc != 2) {
X        fprintf(stderr, "usage: %s hostid\n", argv[0]);
X        exit(1);
X    }
X    sscanf(argv[1], "%x", &hostid);
X    printf("#include <string.h>\n");
X    printf("gethostid() { return 0x%08x; }\n", hostid);
X    printf("long sysinfo(command,buf,count)\nint command;\nchar *buf;\n");
X    printf("long count;\n{\nchar *c = buf;\n");
X    printf("switch(command) { \n");
X    printf("case %u:\n", commands[0]);
X    sprintf(buf,"%u",hostid);
X    for (j=0; j < strlen(buf); j++)
X        printf("if (c < (buf + count)) *c++ = '%c';\n", buf[j]);
X    printf("if (c < (buf + count)) *c++ = 0;\n");
X    printf("buf[count-1] = 0;\n");
X    printf("break;\n");
X    for (i=1; i< NCOMMANDS; i++) {
X        sysinfo(commands[i], buf,1024);
X        printf("case %u:\n", commands[i]);
X        for (j=0; j < strlen(buf); j++)
X            printf("if (c < (buf + count)) *c++ = '%c';\n", buf[j]);
X        printf("if (c < (buf + count)) *c++ = 0;\n");
X        printf("buf[count-1] = 0;\n");
X        printf("break;\n");
X    }
X    printf("default: \nreturn(-1); \n}\n");
X    printf("return(strlen(buf) + 1);}\n");
}
SHAR_EOF
chmod 0600 hid-1.6.1/sidump_old.c ||
echo 'restore of hid-1.6.1/sidump_old.c failed'
Wc_c="`wc -c < 'hid-1.6.1/sidump_old.c'`"
test 3434 -eq "$Wc_c" ||
	echo 'hid-1.6.1/sidump_old.c: original size 3434, current size' "$Wc_c"
fi
# ============= hid-1.6.1/changelog ==============
if test -f 'hid-1.6.1/changelog' -a X"$1" != X"-c"; then
	echo 'x - skipping hid-1.6.1/changelog (File already exists)'
else
echo 'x - extracting hid-1.6.1/changelog (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'hid-1.6.1/changelog' &&
0.8.6
-Added file called INSTRUCTIONS which contains documentation. You can
X now probably use the stuff now without looking at the comments in the C
X code.
X
0.8.7
-minor change to nvram.info
-minor fix to hostid-by-egid/sethostid. Passing bad parameters
X could have caused problems.
-changed name of distribution.
-unless some serious problems come up, 0.8.7 will be the last public release
X before version 1.0
X
1.0
-changed sidump.c so that the hostid can also be set be an environment
X variable (for dynamically linked executables, SUN OS 4.1, 5.3)
-cosmetic changes to documentation
X
1.1
- hostid-by-egid now available as a loadable module. Sun OS 4.1 only.
X  can load and unload via modload
X
1.2
- obvious bug fix to chenet.c
- hostid-by-egid now available as a loadable module for both Solaris
X  2.3 and 1.1.  Can load and unload via modload.
X
1.2b
- 1.2 and 1.2a had a nasty bug in the sethostid module for Solaris 2.3.
X  If the module failed to load, the sysent table was often left in a bad
X  state which would lead to a kernel panic pretty soon.
- added Makefile lines to install sid in /usr/local/bin and sethostid
X  in /kernel/sys (if one does "make install"). I'm actually beginning
X  to appreciate Solaris 2.x; automatically loading system calls into the
X  kernel on the fly when they are called is pretty cool.
X
1.2c
- bug in some of the user sethostid programs (not the kernel modules)
X  would not allow hostid > 0x7fffffff because of signed vs unsigned
X  problems. On solaris 2.3 changes strtol to strtoul. On Solaris 1.1
X  changed strtol to appropriate sscanf calls. The sscanf calls are not
X  tolerant of a leading 0x as are strtol and strtoul, but this doesn't
X  really both me.
X
1.3
- minor changes to documentation
X
1.3.1
- added information about sun 3/80 to nvram.info
X
1.3.2
- fixed solaris 2 instructions. important to reboot after modifying
X  /etc/name_to_sysnum
- added a couple of systems to nvram.info
- explicit path to ld added in solaris 2 makefiles (/usr/ccs/bin/ld)
X
1.3.3
- added nvram-sol2.c
- minor change to nvram.c that should be harmless.
X
1.3.4 
- cosmetic changes to nvram-sol2.c and nvram.c
X
1.3.5
- mods to nvram-sol2.c for sun4m
X
1.4.0
- correction to nvram.info
- spoof-solaris and spoof-solaris2 released.
X
1.4.2
- by default sun4m installations don't include the eeprom driver. But you
X  can get the eeprom driver from a sun4c machine and it is smart enough
X  to work nicely. Forgot to mention this in 1.4.1.
X
1.4.5
- added SS1000 Flash EEPROM repogramming information.
- added Solaris 2.4 x86 support
X
1.4.6
- fixed stupid bug introduced at last minite into nvram-sol2.c in 1.4.5
X
1.4.8 
- updated nvram.info. Quick and dirty instructions for NVRAM replacement.
X
1.4.9 
- added the examples to nvram.info which will hopefully make things
X  a little more clear
X
1.5.0 
- added bits and pieces from Stephen Dowdy <dowdy@cs.colorado.edu> to
X  nvram.info
X
1.5.1
- complete rewrite of nvram.info
X
1.6.0
- support for Sun OS 5.5 (at least for SPARC, x86 untested)
-DPRE_SOLARIS_2_5 for the loadable sethostid versions if you want
X  to run 2.3/2.4
X
1.6.1
- overhaul of nvram.info to use mkp command instead of the address mapping
X  and c!/dump. Added FORTH code to do xor calcs to nvram.info.
SHAR_EOF
chmod 0600 hid-1.6.1/changelog ||
echo 'restore of hid-1.6.1/changelog failed'
Wc_c="`wc -c < 'hid-1.6.1/changelog'`"
test 3235 -eq "$Wc_c" ||
	echo 'hid-1.6.1/changelog: original size 3235, current size' "$Wc_c"
fi
# ============= hid-1.6.1/nvram-sol2.c ==============
if test -f 'hid-1.6.1/nvram-sol2.c' -a X"$1" != X"-c"; then
	echo 'x - skipping hid-1.6.1/nvram-sol2.c (File already exists)'
else
echo 'x - extracting hid-1.6.1/nvram-sol2.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'hid-1.6.1/nvram-sol2.c' &&
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <nlist.h>
#include <sys/systeminfo.h>
#include <sys/openpromio.h>
X
X
/* 
get/change hostid in NVRAM -- Solaris 2.4 only 
X
Instructions:
see the file INSTRUCTIONS. Especially important for sun4d and sun4m
X  class machines.
X
X
UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING, YOU SHOULD AVOID CHANGING
THE FIRST BYTE OF YOUR HOSTID WHICH IDENTIFIES YOUR SYSTEM TYPE. 
CHANGING THIS BYTE COULD RENDER YOUR SYSTEM UNBOOTABLE.
X
Mark Henderson <markh@wimsey.bc.ca>
Placed in the public domain by the author - Jan 1995
X
This program is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose. You use
this program at your own risk. The author disclaims responsibility for
any damages that might result from the use of this program, even
if they result from negligence on the part of the author.
X
Also, please don't use this program to steal software. The intended
use is for emergency situations where an application has to be moved from
one computer to another (e.g. in the event of a hardware malfunction)
and licence keys cannot be obtained quickly from the vendor. Many
vendors will not supply licence keys outside of business hours.
X
Sorry about all the legal BS, but given that use of this program is
dangerous and inexperienced people will use it, I don't have much choice
from both an ethical and legal point of view.
X
*/
X
X
/* 
X * getobphostid - gets hostid according to the openprom driver
X * returns 0 on failure 
X */
unsigned int getobphostid()
{
X    struct opio {
X       unsigned int size;
X       unsigned char arr[OPROMMAXPARAM];
X    } foo;
X    int fd,done = 0;
X    if ((fd = open("/dev/openprom", O_RDONLY)) < 0) {
X        return (0);
X    }
X    foo.size =  OPROMMAXPARAM;
X    memset(&foo.arr[0],0,OPROMMAXPARAM);
X    if (ioctl(fd, OPROMNEXT, &foo) < 0) {
X        return(0);
X    }
X    foo.size =  OPROMMAXPARAM;
X    memset(&foo.arr[0],0,OPROMMAXPARAM);
X    for (;!done;) {
X        foo.size =  OPROMMAXPARAM;
X        if (ioctl(fd, OPROMNXTPROP, &foo) < 0) {
X            return(0);
X        }
X        if (foo.size == 0)   /* not on list ! */
X            return 0;
X        if (strncmp(&foo.arr[0], "idprom", 6)) 
X            continue;
X        strcpy(&foo.arr[0],&foo.arr[0]);
X        foo.size=OPROMMAXPARAM;
X        if (ioctl(fd, OPROMGETPROP, &foo) < 0) {
X            return(0);
X        }
X        done=1;
X    }   
X    close(fd);
X    return ((foo.arr[1] << 24)|(foo.arr[12] << 16)|(foo.arr[13] << 8)
X            |(foo.arr[14]));
}
X
#define OFFSET1 017730       /* for Sun 4m */
#define OFFSET2 03730     /* for Sun 4c */
X
/* #define TEST        /* doesn't actually do mods if TEST is defined */
unsigned char buf[17];  /* larger than it needs to be */ 
X
/* offset table -- in ascending order of magnitude */
off_t offtab[2] = { OFFSET2, OFFSET1 };
#define nofftab  (sizeof(offtab) / sizeof(off_t))
off_t offset;
struct nlist nl[2];
X
unsigned int bsd_gethostid()
{
X    unsigned char buf[1024];
X    buf[0] = 0;
X    sysinfo(SI_HW_SERIAL, buf, 1024);
X    return (strtoul(buf,NULL,10));
}
void check_eeprom_driver()
{
X    int kmem;
X    off_t where;
X    unsigned int kbuf[12];
X    fprintf(stderr,"nvram-sol2 - Mark Henderson <markh@wimsey.bc.ca>\n");
X    fprintf(stderr,
X        "Placed in the public domain by the author - Jan 1995\n\n");
X    fprintf(stderr,
X        "This program is distributed in the hope that it will be useful,\n");
X    fprintf(stderr,
X        "but without any warranty; without even the implied warranty of\n");
X    fprintf(stderr,
X        "merchantability or fitness for a particular purpose. You use\n");
X    fprintf(stderr,
X    "this program at your own risk. The author disclaims responsibility for\n");
X    fprintf(stderr,
X        "any damages that might result from the use of this program, even\n");
X    fprintf(stderr,
X        "if they result from negligence on the part of the author.\n");
X    fprintf(stderr, 
X        "Malfunction or misuse of this program can damage your computer.\n\n");
X    if ((kmem = open("/dev/kmem", O_RDONLY)) < 0) {
X        fprintf(stderr, "cannot open /dev/kmem\n");
X        exit(1);
X    }
X    nl[0].n_name = "nvram";
X    nl[1].n_name = NULL;
X    if (nlist("/dev/ksyms", nl) < 0) {
X        fprintf(stderr, "cannot read namelist out of /vmunix\n");
X        exit(1);
X    }
X    if ((where = nl[0].n_value) == 0) {
X        fprintf(stderr, "unknown kernel variable nvram\n");
X        fprintf(stderr, "execute the following and try again\n");
X        fprintf(stderr, "/usr/sbin/modload /kernel/drv/eeprom\n");
X        exit(1);
X    }
X    if (lseek(kmem, where, SEEK_SET) == (-1)) {
X        fprintf(stderr, "lseek on /dev/kmem failed\n");
X        fprintf(stderr,
X            "your kernel is strange - nvram modifier won't operate\n");
X        exit(1);
X    }
X    if (read(kmem, (char *)&kbuf[0], 48) < 48) {
X        fprintf(stderr, "read from /dev/kmem failed\n");
X        fprintf(stderr,
X            "your kernel is strange - nvram modifier won't operate\n");
X        exit(1);
X    }
X    close(kmem);
X    if (kbuf[11] == 0x9422a028) {
X        fprintf(stderr, "please execute the following\n");
X        fprintf(stderr,
X            "adb -k -w /dev/ksyms /dev/mem <<END\nnvram+2c/W 9422a000\nEND\n");
X        exit(0);
X    }
X    if (kbuf[11] == 0x9422a000) {
X        fprintf(stderr, "your kernel looks good\n");
X    }
}
X
/* #define gethostid() getobphostid() */
#define gethostid() bsd_gethostid()
X
main(argc,argv)
int argc;
char *argv[];
{
X    unsigned int hid;
X    int fd;
X    int i;
X    int j;
X    unsigned int acc;
X    char obuf[20];
X    int read_hostid;
X    unsigned int hid_reported_by_gethostid = gethostid();
X
X    if (argc == 1) {
X        /* no args - just get hostid from prom */
X        read_hostid = 1;
X    }
X    else if (argc == 2 || argc == 3) {
X        read_hostid = 0;
X        sscanf(argv[1],"%08x",&hid);
X        if (argc == 3)  /* undocumented -- allows you to override the
X                           value returned by sysinfo in the sanity checks */
X            sscanf(argv[2],"%08x",&hid_reported_by_gethostid);
X    }
X    else {
X        fprintf(stderr, "usage: %s [hostid]\n",argv[0]);
X        fprintf(stderr, "  e.g. %s\n", argv[0]);
X        fprintf(stderr, "       %s b0b1fb0b\n", argv[0]);
X        exit(1);
X    }
X
X    check_eeprom_driver();
X    
X    if (read_hostid) {
X        if ((fd = open("/dev/eeprom", O_RDONLY)) < 0) {
X            fprintf(stderr, "cannot open /dev/eeprom for read\n");
X            exit(1);
X        }
X    } 
X    else {
#ifdef TEST
X        if ((fd = open("/dev/eeprom", O_RDONLY)) < 0) {
X            fprintf(stderr, "cannot open /dev/eeprom for read\n");
X            exit(1);
X        }
#else
X        if ((fd = open("/dev/eeprom", O_RDWR)) < 0) {
X            fprintf(stderr, "cannot open /dev/eeprom for write\n");
X            exit(1);
X        }
#endif
X    }
X
X    offset = 0xffffffff;     /* dummy value */
X
X    for (j = 0; j < nofftab; j++) {
X        if (lseek(fd,offtab[j],SEEK_SET) < 0) { 
X            fprintf(stderr, "lseek failed for %o\n", offtab[j]);
X            continue;
X        }
X        if (read(fd,buf,16) < 16) {
X            fprintf(stderr, "read of /dev/eeprom failed for %o\n", offtab[j]);
X            fprintf(stderr, "read of /dev/eeprom failed for %o\n", offtab[j]);
X            continue;
X        }
#ifdef TEST
X        for (i=0; i<16; i++)
X            printf("%02x ", buf[i]);
X        printf("\n");
#endif
X
/*
X The check below will fail if sysinfo does not return the same hostid
X as in NVRAM. This can happen because you've already modified the NVRAM
X and not rebooted since then, or because you've modified the kernel
X so that sysinfo does not return the same hostid as in NVRAM
*/
X
X        for (acc = 0 , i=0; i<15; i++) acc^=buf[i];
X        if ((acc != buf[15]) 
X            || (buf[1] != (hid_reported_by_gethostid >> 24) )
X            || (buf[12] != ((hid_reported_by_gethostid >> 16) &0xff))
X            || (buf[13] != ((hid_reported_by_gethostid >> 8) &0xff))
X            || (buf[14] != (hid_reported_by_gethostid &0xff))) {
X            continue;
X        }
X        offset = offtab[j];
X        break;
X    }
X    if (offset == 0xffffffff) {
X        fprintf(stderr, "perhaps you have a weird kernel -- failed\n");
X        exit(1);
X    }
X    printf("current hostid = %02x%02x%02x%02x\n", 
X    buf[1], buf[12], buf[13], buf[14]);
X
X    /* may as well print this out */
X    printf("enetaddr       = %02x:%02x:%02x:%02x:%02x:%02x\n", 
X    buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
X    if (!read_hostid) {
X        if (lseek(fd,offset,SEEK_SET) < 0) { 
X            fprintf(stderr, "lseek failed\n");
X            exit(1);
X        }
X
X        buf[1] = hid >> 24;
X        buf[12] = (hid >> 16) &0xff;
X        buf[13] = (hid >> 8) &0xff;
X        buf[14] = hid &0xff;
X        for (acc = 0 , i=0; i<15; i++) acc^=buf[i];
X        buf[15] = acc & 0xff;
#ifndef TEST
X        if (write(fd,buf,16) < 16) {
X            fprintf(stderr, "write failed\n");
X        }
X        fprintf(stderr,"new hostid is %08x\n", hid);
X		fprintf(stderr, "if you are NOT executing this on an SC1000/2000, skip to (*)\n");
X		fprintf(stderr, "\tpress STOP-A\n");
X		fprintf(stderr, "\ttype \"update-system-idprom\" at the ok prompt\n");
X		fprintf(stderr, "\ttype \"go\" at the ok prompt\n");
X		fprintf(stderr, "\treboot with \"init 6\"\n");
X        fprintf(stderr,"(*) now please execute the following or reboot:\n\n");
X        sprintf(obuf,"%u", hid);  
X        printf("adb -w -k /dev/ksyms /dev/mem <<END\n");
X        printf("hw_serial/W 0x");
X        for (i=0; i<4; i++)
X            printf("%02x", obuf[i]);
X        printf("\n");
X        printf("hw_serial+4/W 0x");
X        for (; i<8; i++)
X            printf("%02x", obuf[i]);
X        printf("\n");
X        printf("hw_serial+8/W 0x");
X        for (; i<12; i++)
X            printf("%02x", obuf[i]);
X        printf("\n");
X        printf("END\n");
#else
X    for (i=0; i<16; i++)
X        printf("%02x ", buf[i]);
X    printf("\n");
#endif
X    }
X    close(fd);
}
X
SHAR_EOF
chmod 0600 hid-1.6.1/nvram-sol2.c ||
echo 'restore of hid-1.6.1/nvram-sol2.c failed'
Wc_c="`wc -c < 'hid-1.6.1/nvram-sol2.c'`"
test 10093 -eq "$Wc_c" ||
	echo 'hid-1.6.1/nvram-sol2.c: original size 10093, current size' "$Wc_c"
fi
# ============= hid-1.6.1/sysinfo.c ==============
if test -f 'hid-1.6.1/sysinfo.c' -a X"$1" != X"-c"; then
	echo 'x - skipping hid-1.6.1/sysinfo.c (File already exists)'
else
echo 'x - extracting hid-1.6.1/sysinfo.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'hid-1.6.1/sysinfo.c' &&
/* make sure that errno is set correctly in MT applications */
#define _REENTRANT
X
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <errno.h>
#include <sys/systeminfo.h>
X
int sysinfo(command, buf, count)
int command; char *buf; long count;
{
switch (command)
X  {
X  case SI_HW_SERIAL:
X    {
X      char *hid;
X
X      if ((hid = getenv ("SI_HW_SERIAL")) != 0)
X	{
X	  strncpy (buf, hid, count);
X	  buf[count - 1] = '\0';
X	  return strlen (hid) + 1;
X	}
X    }
X  default:
X    {
X      long (*real_sysinfo) ();
X
X      if ((real_sysinfo = (long (*)()) dlsym (RTLD_NEXT, "sysinfo")) == 0)
X	{
X	  errno = EINVAL;
X	  return -1;
X	}
X      return real_sysinfo (command, buf, count);
X    }
X  }
}
SHAR_EOF
chmod 0600 hid-1.6.1/sysinfo.c ||
echo 'restore of hid-1.6.1/sysinfo.c failed'
Wc_c="`wc -c < 'hid-1.6.1/sysinfo.c'`"
test 695 -eq "$Wc_c" ||
	echo 'hid-1.6.1/sysinfo.c: original size 695, current size' "$Wc_c"
fi
true || echo 'restore of hid-1.6.1/dloverlay.c failed'
echo End of part 4, continue with part 5
exit 0
-- 
Mark Henderson -- markh@wimsey.bc.ca, henderso@netcom.com (personal accounts)
ViaCrypt PGP Key Fingerprint: 21 F6 AF 2B 6A 8A 0B E1  A1 2A 2A 06 4A D5 92 46
cryptography archive maintainer -- ftp://ftp.wimsey.com/pub/crypto
ftp://ftp.wimsey.com/pub/crypto/sun-stuff/change-sun-hostid-1.6.1.tar.gz


