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