Home | History | Annotate | Line # | Download | only in hints
      1 #!/bin/ksh
      2 
      3 #
      4 # File:         patchfreq
      5 # Author:       Bryan Cantrill (bmc (at] eng.sun.com), Solaris Performance
      6 # Modified:     Sat Apr 26 04:00:59 PDT 1997
      7 #
      8 # This is a little script to patch a 5.5 or 5.5.1 kernel to get around
      9 # the cpu_tick_freq inaccuracy.  Before running this script, one must
     10 # know the true frequency of one's CPU;  this can be derived by NTP,
     11 # or by observing the clock relative to the time-of-day chip over a
     12 # long period of time (the TOD will pull system time when it drifts
     13 # by more than two seconds).
     14 #
     15 # Patching a kernel can render a machine unbootable;  do not run this
     16 # script unless you are prepared to accept that possibility.  It
     17 # is advisable to have a backout path (e.g. net booting, an alternate
     18 # boot disk, an installation CD) should your machine fail to boot.
     19 #
     20 # This is not a product of Sun Microsystems, and is provided "as is",
     21 # without warranty of any kind expressed or implied including, but not
     22 # limited to, the suitability of this script for any purpose.
     23 #
     24 
     25 if [ $# -eq 0 ]; then
     26         echo "Usage:  $0 cpu_tick_freq [ alternate_kernel ]"
     27         exit 1
     28 fi
     29 
     30 cpu_tick_freq=$1
     31 kernel=/platform/sun4u/kernel/unix
     32 
     33 if [ $# -eq 2 ]; then
     34         kernel=$2
     35 fi
     36 
     37 if [ ! -w $kernel ]; then
     38         echo "$0:  Cannot open $kernel for writing."
     39         exit 1
     40 fi
     41 
     42 arch=`echo utsname+404?s | adb $kernel | cut -d: -f2`
     43 
     44 if [ ! $arch = "sun4u" ]; then
     45         echo "Patch only applies to sun4u"
     46         exit 1
     47 fi
     48 
     49 rel=`echo utsname+202?s | adb $kernel | cut -d: -f2`
     50 
     51 if [ ! $rel = "5.5" ] && [ ! $rel = "5.5.1" ]; then
     52         echo "Patch only applies to 5.5 or 5.5.1..."
     53         exit 1
     54 fi
     55 
     56 nop="1000000"           # nop
     57 store_mask="ffffe000"   # mask out low 13 bits
     58 store="da256000"        # st      %o5, [%l5 + offset]
     59 
     60 instr=`echo setcpudelay+34?X | adb $kernel | cut -d: -f 2 | nawk '{ print $1 }'`
     61 
     62 if [ $instr = $nop ]; then
     63         echo "Instruction already patched..."
     64 else
     65         let masked="(16#$store_mask & 16#$instr) - 16#$store"
     66         if [ $masked -ne 0 ]; then
     67                 echo "Couldn't find instruction to patch;  aborting."
     68                 exit 1
     69         fi
     70 
     71         if ! echo setcpudelay+34?W $nop | adb -w $kernel 1> /dev/null
     72         then
     73                 echo "adb returned an unexpected error;  aborting."
     74         fi
     75 fi
     76 
     77 echo "Patching cpu_tick_freq to $cpu_tick_freq..."
     78 
     79 if ! echo cpu_tick_freq?W 0t$cpu_tick_freq | adb -w $kernel 1> /dev/null; then
     80         echo "adb returned an unexpected error;  aborting."
     81         exit 1
     82 fi
     83 
     84 echo "$kernel successfully patched."
     85 exit 0
     86