#!/bin/bash -- # $Id: mach_acs,v 1.72 2010/06/03 17:37:43 bsittler Exp bsittler $ # # WARNING: This script modifies your running operating system kernel. # This is potentially very risky, as the kernel is what allows everything # else to run. Although I have made every attempt to ensure it is safe # (and believe it is), I can't guarantee it or be held liable if things # go wrong. in particular: # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHOR OR ANY OTHER CONTRIBUTOR BE LIABLE FOR # ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Apparently the Darwin/Mac OS X Console does support a VT100-style # alternate character set, but all the alternate character set # positions have been left blank in the font. This fixes the broken # support for the VT100 alternate character set at boot time. To run # it, save this to a file called 'mach_acs' and type: # # sudo /bin/bash mach_acs --install # # Get terminfo for TERM=xnuppc-acs here: # # http://xent.com/~bsittler/xnuppc.ti # # On Intel and PowerPC platforms, Apple's Darwin operating system and # Mac OS X use a full-screen system console derived from a NetBSD # framebuffer console. It is an ANSI-style terminal, and is not really # VT100 compatible. # # Under Mac OS X (both PowerPC and Intel), this is the system console # driver used while in single-user mode [reachable by holding down # Command-S during the boot process] and when logged in using console # mode [reachable by typing ">console" at the graphical login prompt.] # # NOTE: In single user mode you'll need to switch display color # depths, echo a character, and switch back for the new font to take # effect. So far I have not discovered a way to automate this. The # regular console mode does not suffer from this deficiency. # # NOTE: Under Mac OS X version 10.4, you'll need to enable the # password dialog inside the System Preferences | Accounts | Login # Options panel by disabling the "Automatically log in as" option and # setting the "Display login window as" option to "Name and password" # # NOTE: Under Mac OS X version 10.4 (and possibly other versions) the # console is only usable when the "Apple Remote Desktop" service is # disabled in System Preferences | Sharing | Services. # # NOTE: Alternate boot loaders such as rEFIt may interfere with the # boot arguments needed to enable /dev/kmem -- if you have problems # consider disabling or reconfiguring the alternate boot loader to # send the boot-args kmem=1 to the Darwin kernel. # # NOTE: This script requires access to kernel memory. By default it # enables the built-in /dev/kmem by adding the kmem=1 option to the # nvram boot-args -- however, it may be possible to use it with Amit # Singh's alternate implementation (not tested, though.) For more # information, see: # # http://www.osxbook.com/book/bonus/chapter8/kma/ # # NOTE: This script needs the 'nm' utility; get it from Xcode or # odcctools export KERNEL_FILE="$(test -f /mach_kernel && echo /mach_kernel || echo /mach)" export KERNEL_FONT_SYMBOL="_iso_font" export KERNEL_MEMORY="/dev/kmem" export KERNEL_FONT_SIZE=$((256 * 16)) export PATH=/sbin:/bin:/usr/sbin:/usr/bin if test -r /etc/defaults/mach_console then . /etc/defaults/mach_console fi on_console=0 if test -t then if test :"${TTY:-`tty 2>/dev/null`}" = :"/dev/console" then on_console=1 fi fi if test :"$*" = :"--test" then ret=0 if test $on_console != 1 then echo "Error: Not connected to tty /dev/console" >&2 ret=1 fi if test ! -x /usr/sbin/mach_acs then echo "Error: /usr/sbin/mach_acs is not executable" >&2 ret=1 fi if test ! -e /dev/kmem then echo "Error: /dev/kmem does not exist" >&2 ret=1 fi sgr () { printf '\x1b[%dm' "$1" } setaf () { sgr $(( 30 + $1 )) } setab () { sgr $(( 40 + $1 )) } enacs="$(printf '\x1b)0')" smacs="$(printf '\x0e')" rmacs="$(printf '\x0f')" sgr0="$(sgr 0)" s=" " h="a" rs="$(sgr 7)${s}$(sgr 27)" if test :"${TERM-unknown}" != :"" -a -t then tput_enacs="$(tput enacs 2>/dev/null)" tput_smacs="$(tput smacs 2>/dev/null)" tput_rmacs="$(tput rmacs 2>/dev/null)" if test \ :"${tput_enacs/${enacs}/}" = :"${tput_enacs}" -o \ :"${tput_smacs/${smacs}/}" = :"${tput_smacs}" -o \ :"${tput_rmacs/${rmacs}/}" = :"${tput_rmacs}" then echo "Error: terminfo does not know how to use the altcharset for TERM=${TERM}" >&2 ret=1 fi fi echo "" echo -n "${enacs}" for fg in 0 1 2 3 4 5 6 7 do for bg in 0 1 2 3 4 5 6 7 do for cell in s h do eval "${cell}${fg}${bg}"'="$(setaf $fg; setab $bg)${!cell}${!cell}${sgr0}"' done done done wheel0="$s70$s70$h10$h30$h20$s70$s70" wheel1="$s70$h10$h13$s03$h23$h20$s70" wheel2="$h01$s01$h17$h37$h27$s02$h02" wheel3="$h51$h51$h57$s07$h67$h62$h62" wheel4="$h50$s05$h57$s07$h67$s06$h60" wheel5="$s70$h05$h45$h47$h46$h06$s70" wheel6="$s70$s70$h40$s04$h40$s70$s70" echo " " " VT100 " " " " ASCII " " " " " "${smacs}${wheel0}${rmacs}" echo " " "${smacs}"'lqqqwq''q''qk'"${rmacs}" " " "+---+-""-""-+" " " "Other VT100 graphics: " "${smacs}${wheel1}${rmacs}" echo " " "${smacs}"'x ` x ''f'' x'"${rmacs}" " " "| * | ""'"" |" " " "${smacs}g y z | { } b c d e h i ${rmacs}" "${smacs}${wheel2}${rmacs}" echo " " "${smacs}"'trsrnp''o''pu'"${rmacs}" " " "+-_-+-""^""-+" " " " " "${smacs}${wheel3}${rmacs}" echo " " "${smacs}""x ~ xa${rs}ax""${rmacs}" " " "| . |#${rs}#|" " " "ASCII approximations: " "${smacs}${wheel4}${rmacs}" echo " " "${smacs}"'mqqqvq''q''qj'"${rmacs}" " " "+---+-""-""-+" " " "+- <= >= != pi L- HT FF CR LF NL VT" "${smacs}${wheel5}${rmacs}" echo " " " VT100 " " " " ASCII " " " " " "${smacs}${wheel6}${rmacs}" echo "" echo "You should see two grids, one using the VT100 altcharset and one using ASCII" echo "" exit $ret fi test :"$(uname -s)" = :"Darwin" || { echo "$0: this is not Darwin, exiting" >&2 exit 1 } if test $((${KERNEL_FONT_SIZE} / 256)) != 16 then echo "Kernel is not using 8x16 font, exiting" >&2 exit 1 fi if test :"$*" = :"--uninstall" then chmod 644 /usr/sbin/mach_acs || exit $? echo "" >&2 echo "After the next reboot your Darwin console should" >&2 echo "use the default character set." >&2 echo "" >&2 echo "You may optionally remove the /usr/sbin/mach_acs line from" >&2 echo "/etc/rc.local by hand." >&2 echo "" >&2 exit 0 fi test -x "$(type -p nm 2>/dev/null || echo /usr/bin/nm)" || { echo "$0: you need to install Xcode or odcctools, exiting" >&2 exit 1 } if test :"$*" = :"--install" then if test :"$0" != :/usr/sbin/mach_acs; then cp "$0" /usr/sbin/mach_acs || exit $? fi chmod 755 /usr/sbin/mach_acs || exit $? nvram boot-args="$(echo "kmem=1 $(nvram boot-args 2>/dev/null | cut -f 2- | sed 's/^kmem=1$//;s/^kmem=1 //;s/ kmem=1 //;s/ kmem=1$//')" | sed '$ s/ *$//')" || exit $? fgrep /usr/sbin/mach_acs /etc/rc.local >/dev/null 2>&1 || echo "test -x /usr/sbin/mach_acs && /usr/sbin/mach_acs" >> /etc/rc.local || exit $? echo "" >&2 echo "After the next reboot your Darwin console should" >&2 echo "support the VT-100 alternate character set." >&2 if test -d /System/Library/CoreServices/loginwindow.app -a $on_console != 1; then echo "" >&2 echo "Type \">console\" at the Mac OS X login window to get to the Darwin console." >&2 echo "" >&2 echo "NOTE: Under Mac OS X version 10.4, you'll need to enable the" >&2 echo "password dialog inside the System Preferences | Accounts | Login" >&2 echo "Options panel by disabling the \"Automatically log in as\" option and" >&2 echo "setting the \"Display login window as\" option to \"Name and password\"" >&2 echo "" >&2 echo "NOTE: Under Mac OS X version 10.4 (and possibly other versions) the" >&2 echo "console is only usable when the \"Apple Remote Desktop\" service is" >&2 echo "disabled in System Preferences | Sharing | Services." >&2 fi if test -d /efi/refit -a ! -e /dev/kmem; then echo "" >&2 echo "NOTE: Alternate boot loaders such as rEFIt may interfere with the" >&2 echo "boot arguments needed to enable /dev/kmem -- if you have problems" >&2 echo "consider disabling or reconfiguring the alternate boot loader to" >&2 echo "send the boot-args kmem=1 to the Darwin kernel." >&2 fi if ! TERM=xnuppc-acs infocmp 2>/dev/null > /dev/null then echo "" >&2 echo "Get terminfo for TERM=xnuppc-acs here:" >&2 echo " http://xent.com/~bsittler/xnuppc.ti" >&2 fi echo "" >&2 echo "To test, run the following on the console:" >&2 echo " /bin/bash /usr/sbin/mach_acs --test" >&2 echo "" >&2 echo "To uninstall, type the following command:" >&2 echo " sudo /bin/bash /usr/sbin/mach_acs --uninstall" >&2 echo "" >&2 exit 0 fi test $# = 0 && test :"${KERNEL_FONT_FILE}" != :"" -a -r "${KERNEL_FONT_FILE}" && dd of="${KERNEL_MEMORY}" bs=1 if="${KERNEL_FONT_FILE}" seek=$(( 0x$(nm "${KERNEL_FILE}" | grep ' '"${KERNEL_FONT_SYMBOL}"'$' | awk '{print $1}') )) count=${KERNEL_FONT_SIZE} conv=notrunc 2>/dev/null test $# = 0 && cmp <( dd if=/dev/zero bs=1 count=$((32*16)) 2>/dev/null ) <( dd if="${KERNEL_MEMORY}" bs=1 skip=$(( 0x$(nm "${KERNEL_FILE}" | grep ' '"${KERNEL_FONT_SYMBOL}"'$' | awk '{print $1}') + 128 * 16 )) count=$((32*16)) 2>/dev/null ) >/dev/null 2>&1 && dd of="${KERNEL_MEMORY}" bs=1 seek=$(( 0x$(nm "${KERNEL_FILE}" | grep ' '"${KERNEL_FONT_SYMBOL}"'$' | awk '{print $1}') + 128 * 16 )) count=$((32*16)) conv=notrunc if=<( printf "$( rev < /dev/console && stty -f /dev/console gfmt1:cflag=cb00:iflag=2302:lflag=200005cf:oflag=7:discard=f:dsusp=19:eof=4:eol=ff:eol2=ff:erase=7f:intr=3:kill=15:lnext=16:min=1:quit=1c:reprint=12:start=11:status=14:stop=13:susp=1a:time=0:werase=17:ispeed=9600:ospeed=9600 || { echo "To install this, type the following command:" >&2 echo " sudo /bin/bash $0 --install" >&2 echo "To uninstall, type the following command:" >&2 echo " sudo /bin/bash $0 --uninstall" >&2 echo "To test, run the following on the console:" >&2 echo " /bin/bash $0 --test" >&2 if ! TERM=xnuppc-acs infocmp 2>/dev/null > /dev/null then echo "Get terminfo for TERM=xnuppc-acs here:" >&2 echo " http://xent.com/~bsittler/xnuppc.ti" >&2 fi exit 1 } exit 0 # # $Log: mach_acs,v $ # Revision 1.72 2010/06/03 17:37:43 bsittler # allow --test even in foreign OSes and on foreign terminals # # Revision 1.71 2009/05/15 21:51:53 bsittler # work-around for some artifacts from misaligned adjacent stipples # # Revision 1.70 2009/05/15 18:10:43 bsittler # add a color wheel "splat" # # Revision 1.69 2009/05/14 19:19:49 bsittler # better test # # Revision 1.68 2009/05/14 18:57:21 bsittler # better all-in-one test # # Revision 1.67 2009/05/14 18:36:40 bsittler # use installed version for --test example # # Revision 1.66 2009/05/14 18:34:53 bsittler # test entire ACS # # Revision 1.65 2009/05/14 18:10:23 bsittler # add blank lines before and after the sample # # Revision 1.64 2009/05/14 17:55:42 bsittler # link to terminfo when installing too # # Revision 1.63 2009/05/14 17:53:34 bsittler # link to terminfo if it's not installed # # Revision 1.62 2009/05/14 17:49:21 bsittler # clean up console checks and link to terminfo # # Revision 1.61 2009/05/14 14:53:47 bsittler # note that rEFIt may cause problems # # Revision 1.60 2009/05/14 01:02:04 bsittler # note that Apple Remote Desktop needs to be disabled # # Revision 1.59 2009/05/14 00:52:49 bsittler # clearer wording # # Revision 1.58 2009/05/14 00:45:45 bsittler # test, not [ # # Revision 1.57 2009/05/14 00:45:30 bsittler # typo # # Revision 1.56 2009/05/14 00:45:04 bsittler # test terminfo too # # Revision 1.55 2009/05/14 00:37:53 bsittler # fix typo: plus is k # # Revision 1.54 2009/05/14 00:34:53 bsittler # ooops! # # Revision 1.53 2009/05/14 00:34:03 bsittler # warn if stuff does not line up # # Revision 1.52 2009/05/14 00:12:55 bsittler # clearer wording, and no sudo needed for --test # # Revision 1.51 2009/05/14 00:07:24 bsittler # better caption # # Revision 1.50 2009/05/14 00:06:12 bsittler # added --test # # Revision 1.49 2009/04/15 18:21:18 bsittler # newer kernels are /mach_kernel with no /mach symlink # # Revision 1.48 2008/01/24 04:30:20 bsittler # more whitespace # # Revision 1.47 2008/01/18 18:07:07 bsittler # better glyphs for 80 and "NL" # # Revision 1.46 2008/01/17 15:15:23 bsittler # rounded corners for boxes # # Revision 1.45 2008/01/17 15:09:45 bsittler # move off-centered glyphs left one pixel to better match the main font # # Revision 1.44 2008/01/17 06:35:40 bsittler # custom font is independent of the rest # # Revision 1.43 2008/01/17 06:30:34 bsittler # added optional KERNEL_FONT_FILE (disabled by default) # # Revision 1.42 2008/01/17 05:28:48 bsittler # minor font cleanup # # Revision 1.41 2008/01/17 04:29:36 bsittler # minor glyph patch-up # # Revision 1.40 2008/01/17 03:55:17 bsittler # thicker, more symmetric box drawing characters and bullet # # Revision 1.39 2008/01/17 00:59:39 bsittler # additional uninstall note # # Revision 1.38 2008/01/17 00:56:59 bsittler # /mach rather than /mach_kernel # # Revision 1.37 2008/01/17 00:40:35 bsittler # stray arguments = do nothing # # Revision 1.36 2008/01/12 20:53:49 bsittler # ascii # # Revision 1.35 2008/01/12 20:36:11 bsittler # *** empty log message *** # # Revision 1.34 2008/01/12 20:34:37 bsittler # big fat disclaimer # # Revision 1.33 2008/01/12 19:32:02 bsittler # *** empty log message *** # # Revision 1.32 2008/01/12 19:30:49 bsittler # *** empty log message *** # # Revision 1.31 2008/01/12 19:30:21 bsittler # you need nm # # Revision 1.30 2008/01/12 19:11:34 bsittler # added an install-time note on how to enable the console # # Revision 1.29 2008/01/12 19:08:39 bsittler # added a note on amit singh's /dev/kmem # # Revision 1.28 2008/01/12 18:57:48 bsittler # explicit path to bash # # Revision 1.27 2008/01/12 18:55:44 bsittler # generic blurb about reaching the console # # Revision 1.26 2008/01/12 18:44:28 bsittler # minor cleanup, and better permissions-tweaking logic # # Revision 1.25 2008/01/12 17:11:21 bsittler # added a log # #