diff --git a/sys/lib/dist/cdstub/.dummy b/mnt/acme/.dummy similarity index 100% rename from sys/lib/dist/cdstub/.dummy rename to mnt/acme/.dummy diff --git a/sys/lib/dist/cdstub/bootdisk.img b/mnt/apeselect/.dummy similarity index 100% rename from sys/lib/dist/cdstub/bootdisk.img rename to mnt/apeselect/.dummy diff --git a/mnt/apm/.dummy b/mnt/apm/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/arch/.dummy b/mnt/arch/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/cd/.dummy b/mnt/cd/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/cons/.dummy b/mnt/cons/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/cons/cons/.dummy b/mnt/cons/cons/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/cons/consctl/.dummy b/mnt/cons/consctl/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/consoles/.dummy b/mnt/consoles/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/doc/.dummy b/mnt/doc/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/.dummy b/mnt/exportfs/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/0/.dummy b/mnt/exportfs/0/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/1/.dummy b/mnt/exportfs/1/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/10/.dummy b/mnt/exportfs/10/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/11/.dummy b/mnt/exportfs/11/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/12/.dummy b/mnt/exportfs/12/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/13/.dummy b/mnt/exportfs/13/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/14/.dummy b/mnt/exportfs/14/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/15/.dummy b/mnt/exportfs/15/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/16/.dummy b/mnt/exportfs/16/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/2/.dummy b/mnt/exportfs/2/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/3/.dummy b/mnt/exportfs/3/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/4/.dummy b/mnt/exportfs/4/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/5/.dummy b/mnt/exportfs/5/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/6/.dummy b/mnt/exportfs/6/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/7/.dummy b/mnt/exportfs/7/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/8/.dummy b/mnt/exportfs/8/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/exportfs/9/.dummy b/mnt/exportfs/9/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/keys/.dummy b/mnt/keys/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/lp/.dummy b/mnt/lp/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/netkeys/.dummy b/mnt/netkeys/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/news/.dummy b/mnt/news/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/plumb/.dummy b/mnt/plumb/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/rdb/.dummy b/mnt/rdb/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/temp/.dummy b/mnt/temp/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/term/.dummy b/mnt/term/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/ums/.dummy b/mnt/ums/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/vmware/.dummy b/mnt/vmware/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/web/.dummy b/mnt/web/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/webcookies/.dummy b/mnt/webcookies/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/wiki/.dummy b/mnt/wiki/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/wrap/.dummy b/mnt/wrap/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/mnt/wsys/.dummy b/mnt/wsys/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/n/.dummy b/n/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/sys/lib/dist.old/cdstub/.dummy b/sys/lib/dist.old/cdstub/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/sys/lib/dist/cmd/bargraph.c b/sys/lib/dist.old/cmd/bargraph.c similarity index 100% rename from sys/lib/dist/cmd/bargraph.c rename to sys/lib/dist.old/cmd/bargraph.c diff --git a/sys/lib/dist/cmd/bflz.c b/sys/lib/dist.old/cmd/bflz.c similarity index 100% rename from sys/lib/dist/cmd/bflz.c rename to sys/lib/dist.old/cmd/bflz.c diff --git a/sys/lib/dist/cmd/bzfs/bzfs.h b/sys/lib/dist.old/cmd/bzfs/bzfs.h similarity index 100% rename from sys/lib/dist/cmd/bzfs/bzfs.h rename to sys/lib/dist.old/cmd/bzfs/bzfs.h diff --git a/sys/lib/dist/cmd/bzfs/mkext.c b/sys/lib/dist.old/cmd/bzfs/mkext.c similarity index 100% rename from sys/lib/dist/cmd/bzfs/mkext.c rename to sys/lib/dist.old/cmd/bzfs/mkext.c diff --git a/sys/lib/dist/cmd/bzfs/mkfile b/sys/lib/dist.old/cmd/bzfs/mkfile similarity index 100% rename from sys/lib/dist/cmd/bzfs/mkfile rename to sys/lib/dist.old/cmd/bzfs/mkfile diff --git a/sys/lib/dist/cmd/bzfs/oramfs.c b/sys/lib/dist.old/cmd/bzfs/oramfs.c similarity index 100% rename from sys/lib/dist/cmd/bzfs/oramfs.c rename to sys/lib/dist.old/cmd/bzfs/oramfs.c diff --git a/sys/lib/dist/cmd/bzfs/unbflz.c b/sys/lib/dist.old/cmd/bzfs/unbflz.c similarity index 100% rename from sys/lib/dist/cmd/bzfs/unbflz.c rename to sys/lib/dist.old/cmd/bzfs/unbflz.c diff --git a/sys/lib/dist/cmd/bzfs/unbzip.c b/sys/lib/dist.old/cmd/bzfs/unbzip.c similarity index 100% rename from sys/lib/dist/cmd/bzfs/unbzip.c rename to sys/lib/dist.old/cmd/bzfs/unbzip.c diff --git a/sys/lib/dist/cmd/cdsh.c b/sys/lib/dist.old/cmd/cdsh.c similarity index 100% rename from sys/lib/dist/cmd/cdsh.c rename to sys/lib/dist.old/cmd/cdsh.c diff --git a/sys/lib/dist/cmd/clog.c b/sys/lib/dist.old/cmd/clog.c similarity index 100% rename from sys/lib/dist/cmd/clog.c rename to sys/lib/dist.old/cmd/clog.c diff --git a/sys/lib/dist/cmd/mkfile b/sys/lib/dist.old/cmd/mkfile similarity index 100% rename from sys/lib/dist/cmd/mkfile rename to sys/lib/dist.old/cmd/mkfile diff --git a/sys/lib/dist/cmd/multi/mkfile b/sys/lib/dist.old/cmd/multi/mkfile similarity index 100% rename from sys/lib/dist/cmd/multi/mkfile rename to sys/lib/dist.old/cmd/multi/mkfile diff --git a/sys/lib/dist/cmd/multi/mkmulti b/sys/lib/dist.old/cmd/multi/mkmulti similarity index 100% rename from sys/lib/dist/cmd/multi/mkmulti rename to sys/lib/dist.old/cmd/multi/mkmulti diff --git a/sys/lib/dist/cmd/multi/multi.c b/sys/lib/dist.old/cmd/multi/multi.c similarity index 100% rename from sys/lib/dist/cmd/multi/multi.c rename to sys/lib/dist.old/cmd/multi/multi.c diff --git a/sys/lib/dist/cmd/tailfsrv.c b/sys/lib/dist.old/cmd/tailfsrv.c similarity index 100% rename from sys/lib/dist/cmd/tailfsrv.c rename to sys/lib/dist.old/cmd/tailfsrv.c diff --git a/sys/lib/dist/cmd/touchfs.c b/sys/lib/dist.old/cmd/touchfs.c similarity index 100% rename from sys/lib/dist/cmd/touchfs.c rename to sys/lib/dist.old/cmd/touchfs.c diff --git a/sys/lib/dist/cmd/unbflz.c b/sys/lib/dist.old/cmd/unbflz.c similarity index 100% rename from sys/lib/dist/cmd/unbflz.c rename to sys/lib/dist.old/cmd/unbflz.c diff --git a/sys/lib/dist/logcompress.awk b/sys/lib/dist.old/logcompress.awk old mode 100644 new mode 100755 similarity index 100% rename from sys/lib/dist/logcompress.awk rename to sys/lib/dist.old/logcompress.awk diff --git a/sys/lib/dist/logtime.awk b/sys/lib/dist.old/logtime.awk old mode 100644 new mode 100755 similarity index 100% rename from sys/lib/dist/logtime.awk rename to sys/lib/dist.old/logtime.awk diff --git a/sys/lib/dist.old/mkfile b/sys/lib/dist.old/mkfile new file mode 100644 index 000000000..f9739e427 --- /dev/null +++ b/sys/lib/dist.old/mkfile @@ -0,0 +1,221 @@ +# /sys/lib/dist/mkfile +src9=/n/sources/plan9 # what to export +dist=/sys/lib/dist.old # where this machinery lives +scr=/n/other/dist # scratch space before copying to web.protect +# import /sys/lib/dist/web.protect from the outside +x=`{setup} + +cd:V: $scr/plan9.iso + +ncd:V: $scr/plan9-new.iso.bz2 + +ncd-dist:V: $scr/plan9-new.iso.bz2 + mk $dist/web.protect/plan9-new.iso.bz2 + +cd-dist:V: $scr/plan9.iso.bz2 + mk $dist/web.protect/plan9.iso.bz2 + +contrib-cd:V: $scr/contrib.iso.bz2 + mk $dist/web.protect/contrib.iso.bz2 + +$scr/%.iso:D: $src9/dist/replica/plan9.log + @ { cd pc; mk cddisk } + rm -f $target + bind pc/cddisk cdstub/bootdisk.img + if(! test -f $src9/bootdisk.img) + bind -a cdstub $src9 + title=`{date | sed 's/(...) (...) (..) (..:..):.. (...) (....)/Plan 9 - \2 \3 \6 \4/'} + title=$"title + echo 'CD:' $title + disk/mk9660 -9cj -v $title -s $src9 -b bootdisk.img $target + +# copy compressed file from scratch space to the distribution, carefully +$dist/web.protect/%.iso.bz2: $scr/%.iso.bz2 + >>$target.new + chmod +t $target.new # waste write buf, not venti store + cp $prereq $target.new + # replace previous version with a flash cut + if (test -e $target) + mv $target $target.old # try to not clobber downloads in progress + mv $target.new $target + +cd-cleanup:V: + rm -f $dist/web.protect/*.iso.bz2.old # remove old versions after a delay + +# generate replica log & db for $src9 only +scan:V: + test -d $scr # make sure other was mounted above + test -d $src9 + test -d $dist/web.protect + lock scan.lock replica/scan $dist/sources.replica + chmod +t $src9/dist/replica/*.^(db log) + +# generate replica log & db for all of /n/sources +scanall:V: + @ { + rfork ne + d=/n/sources + test -d $src9 + lock scanall.lock replica/scan $dist/sourcesall.replica + chmod +t $src9/dist/replica/*.^(db log) + } + +compresslog:V: + { + awk -f logcompress.awk $src9/dist/replica/plan9.log | + awk -f logtime.awk -v 't='^`{date -n} >/tmp/plan9.log + rm -f $src9/dist/replica/plan9.new.log + cp /tmp/plan9.log $src9/dist/replica/plan9.new.log && + mv $src9/dist/replica/plan9.new.log $src9/dist/replica/plan9.log + } $src9/dist/replica/plan9.db +# chmod 664 $src9/dist/replica/plan9.log >$src9/dist/replica/plan9.log +# chmod +a $src9/dist/replica/plan9.log +# mk scan + +odump:V: + disk/dump9660 -9cj -v 'Plan 9 4e Dumps' -s $src9 \ + -p /sys/lib/sysconfig/proto/allproto $scr/distdump.iso + +cd.install:V: +# if(~ $sysname achille){ +# echo; echo; echo '*** run this on a real machine, like chips.' +# exit bad +# } + bzip2 -9 <$scr/plan9.iso >web.protect/nplan9.iso.bz2 + +D.install:V: + D=/n/roro/usr/rob/testplan9 + 9fs roro + test -d $D + cp $D$dist/pc/ndisk $dist/web.protect/ndisk + cp $D$dist/pc/9loaddebug $dist/web.protect/n9loaddebug + +reallyinstall:V: + if(! ~ $sysname achille){ + echo; echo; echo '*** this needs to run on achille.' + exit bad + } + cd web.protect + for (i in plan9.iso.bz2 disk 9loaddebug vmware.zip) + if(test -f n$i){ + mv $i _$i && { mv n$i $i || mv _$i $i } + } + rm /srv/ramfs.9down4e + $dist/startcache + +dump:V: + rm -f /srv/9660.xxx + 9660srv 9660.xxx + mount /srv/9660.xxx /n/kremvax $scr/plan9.iso + now=`{mtime $dist/web.protect/plan9.iso.bz2 | awk '{print $1}'} + ls -l /rls/plan9/4e.iso + disk/dump9660 -9cj -s /n/kremvax -n $now /rls/plan9/4e.iso + ls -l /rls/plan9/4e.iso + rm /srv/9660.xxx + +reencode:V: + rm -f $scr/nplan9.iso + rm -f /srv/9660.xxx + 9660srv 9660.xxx + mount /srv/9660.xxx /n/kremvax $scr/plan9.iso + disk/mk9660 -9cj -v 'Plan 9 4th Edition' -s /n/kremvax \ + -b bootdisk.img $scr/nplan9.iso + rm /srv/9660.xxx + +# compress a cd image in scratch space +$scr/%.iso.bz2:D: $scr/%.iso + @ { + cd $scr + bzip2 -9 <$stem.iso >n$stem.iso.bz2 && + { + if (test -e $stem.iso.bz2) + mv $stem.iso.bz2 _$stem.iso.bz2 + mv n$stem.iso.bz2 $stem.iso.bz2 + } + echo `{date} md5 `{md5sum <$stem.iso.bz2} \ + sha1 `{sha1sum <$stem.iso.bz2} \ + $stem.iso.bz2 >>/usr/web/plan9checksums.txt + } + +$scr/contrib.iso:DV: + rm -f $target + disk/mk9660 -9cj -v 'Plan 9 Extras' -s /n/sources \ + -p ./contrib.proto $target + +rebuild:V: + chmod +l build.lock >>build.lock + rebuild >build.lock + rebuild $target + +9-export:V: 9.tar.gz + 9fs sources + cp 9.tar.gz /n/sources/extra/9.tgz + chmod +t /n/sources/extra/9.tgz + +plan9.tar.bz2:V: + @{ + rfork n + 9fs sources + cd /n/sources + test -e $src9 + bind /n/empty $src9/lib/font + bind /n/empty $src9/sys/lib/postscript/font + bind /n/empty $src9/sys/lib/ghostscript + bind /n/empty $src9/sys/src/cmd/gs + tar c plan9/LICENSE* plan9/NOTICE plan9/*/mkfile plan9/*/include \ + plan9/acme/*/src plan9/acme/bin/source \ + plan9/^(adm cron lib lp mail rc sys tmp usr) + } | bzip2 >$target + +plan9-export:V: plan9.tar.bz2 + 9fs sources + chmod +t plan9.tar.bz2 + mv plan9.tar.bz2 /n/sources/extra/plan9.tar.bz2 diff --git a/sys/lib/dist/pc/cd0.proto b/sys/lib/dist.old/pc/cd0.proto similarity index 100% rename from sys/lib/dist/pc/cd0.proto rename to sys/lib/dist.old/pc/cd0.proto diff --git a/sys/lib/dist.old/pc/emptyfile b/sys/lib/dist.old/pc/emptyfile new file mode 100644 index 000000000..e69de29bb diff --git a/sys/lib/dist.old/pc/glenda/bin/rc/riostart b/sys/lib/dist.old/pc/glenda/bin/rc/riostart new file mode 100755 index 000000000..cc5dfa8f2 --- /dev/null +++ b/sys/lib/dist.old/pc/glenda/bin/rc/riostart @@ -0,0 +1,4 @@ +#!/bin/rc + +window '0 0 100 100' games/clock +window '80 80 610 360' /usr/glenda/lib/first.window diff --git a/sys/lib/dist.old/pc/glenda/lib/first.window b/sys/lib/dist.old/pc/glenda/lib/first.window new file mode 100644 index 000000000..c4f264ef2 --- /dev/null +++ b/sys/lib/dist.old/pc/glenda/lib/first.window @@ -0,0 +1,11 @@ +#!/bin/rc +echo -n readme > /dev/label +echo 'You have completed the Installation Process.' + +cat<<'!' + +Welcome to Plan 9. +This is rc. +! + +exec rc diff --git a/sys/lib/dist.old/pc/glenda/lib/profile b/sys/lib/dist.old/pc/glenda/lib/profile new file mode 100644 index 000000000..7767e8a01 --- /dev/null +++ b/sys/lib/dist.old/pc/glenda/lib/profile @@ -0,0 +1,16 @@ +if(test -f '#m/mousectl') { + echo -n accelerated > '#m/mousectl' + echo -n 'res 3' > '#m/mousectl' +} +user=`{cat /dev/user} +home=/usr/$user +bind -a $home/bin/rc /bin +bind -a $home/bin/$cputype /bin +bind -c $home/tmp /tmp +rio -si inst/gui +echo +echo +echo 'failed to start rio. you can start a text-based installation by running' +echo +echo ' inst/textonly' +echo diff --git a/sys/lib/dist.old/pc/inst/bootfloppy b/sys/lib/dist.old/pc/inst/bootfloppy new file mode 100755 index 000000000..c9aebbc51 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/bootfloppy @@ -0,0 +1,47 @@ +#!/bin/rc + +rfork e + +echo +echo 'Insert a disk other than your installation boot disk' +echo 'into your floppy drive; it will be erased to create' +echo 'the boot floppy.' +echo +echo -n 'Press enter when ready.' +read >/dev/null >[2]/dev/null + +if(~ $#adisk 1) + ; # do nothing +if not if(~ $#bootfile 0) + adisk=/dev/fd0disk +if not { + switch($bootfile) { + case sd* + adisk=`{echo $bootfile | sed 's#(sd..).*#/dev/\1/data#'} + case fd* + adisk=`{echo $bootfile | sed 's#(fd.).*#/dev/\1disk#'} + case * + echo 'unknown bootfile '^$bootfile^'; mail 9trouble@plan9.bell-labs.com' + exit oops + } +} + +if(! ~ `{ls -l $adisk | awk '{print $6}'} 1474560){ + echo 'Will not format non-floppy disk '^$"adisk. >[1=2] + exit 'bad adisk' +} + +log Formatting boot floppy +if (test -e /n/newfs/386/9loadnousb) + bind /n/newfs/386/9loadnousb /n/newfs/386/9load # cater to old bioses +disk/format -b /386/pbs \ + -fd $adisk /n/newfs/386/9load /n/newfs/386/9pcdisk.gz \ + /tmp/plan9ini.bak +x=$status + +if(~ $x ''){ + echo + echo 'Done!' + echo +} +exit $x diff --git a/sys/lib/dist.old/pc/inst/bootplan9 b/sys/lib/dist.old/pc/inst/bootplan9 new file mode 100755 index 000000000..942c043b0 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/bootplan9 @@ -0,0 +1,55 @@ +#!/bin/rc + +first=`{ls -p '#S' | sed 1q} +if(! ~ $first $disk) { + echo 'warning: The plan 9 partition is not on the boot disk,' + echo 'so making it the active partition will have no effect.' +} + +p9offset=`{grep '^part 9fat ' /dev/$disk/ctl |awk '{print $3}'} +if(! ~ $#p9offset 1) { + echo 'could not find plan 9 partition.' + echo 'cannot happen' + exit bad +} + +if(test $p9offset -gt 4128695) { # 65536 * 63 - 10 + echo + echo 'Your Plan 9 partition is more than 2GB into your disk,' + echo 'and the master boot records used by Windows 9x/ME' + echo 'cannot access it (and thus cannot boot it).' + echo + echo 'You can install the Plan 9 master boot record, which can load' + echo 'partitions far into the disk.' + echo +} + +echo 'If you use the Windows NT/2000/XP master boot record' +echo 'or a master boot record from a Unix clone (e.g., LILO or' +echo 'FreeBSD bootmgr), it is probably safe to continue using' +echo 'that boot record rather than install the Plan 9 boot record.' +echo +prompt 'Install the Plan 9 master boot record' y n +switch($rd) { +case n + ; +case y + disk/mbr -m /386/mbr /dev/$disk/data +} + +log Setting Plan 9 partition active. +p9part=`{disk/fdisk /dev/$disk/data >[2]/dev/null [1=2] + exit 'no plan 9 partition found' +} +p9part=$p9part(1) +{ echo 'A '^$p9part; echo w } | disk/fdisk /dev/$disk/data >[2]/dev/null >/dev/null +x=$status +if(~ $x '' '|'){ + echo + echo 'The Plan 9 partition is now marked as active.' + exit '' +} +exit $x diff --git a/sys/lib/dist.old/pc/inst/bootsetup b/sys/lib/dist.old/pc/inst/bootsetup new file mode 100755 index 000000000..cc22fe6ee --- /dev/null +++ b/sys/lib/dist.old/pc/inst/bootsetup @@ -0,0 +1,125 @@ +#!/bin/rc + +# desc: create a boot floppy or configure hard disk to boot plan 9 +# prereq: copydist + +switch($1) { +case go + echo + echo 'Initializing Plan 9 FAT configuration partition (9fat)' + echo + + fat=(/dev/sd*/9fat) + fat=$fat(1) + disk=`{echo $fat | sed 's:/dev/::;s:/9fat::'} + bootfs=`{echo $fs | sed 's:/dev/(sd..)/(.*):\1!\2:'} + bootfat=`{echo $fs | sed 's:/dev/(sd..)/(.*):\1!9fat:'} + if(! test -f /dev/$disk/9fat) { + echo 'You have no 9fat partition. Can''t setup booting.' + exit + } + + if(! test -f /tmp/plan9.ini) { + { + sfs=`{echo $fs | sed 's;/dev;#S;'} + if(~ $fstype fossil fossil+venti){ + echo bootfile'='$bootfat!9pcf + echo 'bootargs=local!'^$sfs + echo 'bootdisk=local!'^$sfs + } + if not { + echo bootfile'='$bootfs!/386/9pcdisk + echo 'bootdisk=local!'^$sfs + } + if(~ $fstype fossil+venti){ + venti=`{echo $ventiarena | sed 's;/dev;#S;'} + echo venti'='^$venti + } + # sort -u avoids dups which could otherwise trigger + # pointless boot menus. + grep -v '(^\[)|menuitem|adisk|bootfile|bootdisk|bootargs|nobootprompt|mouseport|vgasize|monitor|cdboot' /tmp/plan9.orig | + sort -u + echo 'mouseport='^$mouseport + echo 'monitor='^$monitor + echo 'vgasize='^$vgasize + } >/tmp/plan9.ini + } + if(! test -f /tmp/plan9ini.bak) + cp /tmp/plan9.ini /tmp/plan9ini.bak + + need9fatformat=no + if(! isfat /dev/$disk/9fat) + need9fatformat=yes + if not if(! mount -c /srv/dos /n/9fat /dev/$disk/9fat >[2]/dev/null) + need9fatformat=yes + if not if(! test -f /n/9fat/plan9.ini) + need9fatformat=yes + + if (test -e /n/newfs/386/9loadnousb) + bind /n/newfs/386/9loadnousb /n/newfs/386/9load # cater to old bioses + if(~ $need9fatformat yes){ + log Initializing Plan 9 FAT partition. + disk/format -r 2 -d -b /386/pbs \ + /dev/$disk/9fat /n/newfs/386/9load + # silently install pbslba if the partition is way into the disk. + # it''s our only hope. only need this for >8.5GB into the disk. + # but... + # there are so few non-LBA bioses out + # there anymore that we'll do this even if we're only 2GB into + # the disk. it's just not worth the headaches of dealing with + # crappy bioses that don't address the whole 8.5GB properly + + 9fatoffset=`{grep '^part 9fat ' /dev/$disk/ctl | awk '{print $4}'} + if(! ~ $#9fatoffset 1) { + echo 'could not find plan 9 partition.' + echo 'cannot happen' + exit bad + } + if(test $9fatoffset -gt 2097152) # 2GB + disk/format -b /386/pbslba /dev/$disk/9fat + + mount -c /srv/dos /n/9fat /dev/$disk/9fat + } + + if(! test -f /n/9fat/4e){ + logprog cp /n/newfs/386/9load /n/9fat/9load + logprog cp /n/newfs/386/9pcf /n/9fat/9pcf + if(test -f /n/9fat/plan9.ini && ! test -f /n/9fat/plan9-3e.ini) + logprog mv /n/9fat/plan9.ini /n/9fat/plan9-3e.ini + if(test -f /n/9fat/9pcdisk && ! test -f /n/9fat/9pc3e) + logprog mv /n/9fat/9pcdisk /n/9fat/9pc3e + + awk -f /bin/inst/mkini.awk >/n/9fat/plan9.ini + >/n/9fat/4e + } + + echo + echo 'There are myriad ways to boot a Plan 9 system.' + echo 'You can use any of the following.' + echo + echo ' floppy - create a boot floppy' + echo ' plan9 - make the plan 9 disk partition the default for booting' + echo ' win9x - add a plan 9 option to windows 9x boot menu' + echo ' winnt - add a plan 9 option to windows nt/2000/xp boot manager' + echo + echo 'If you are upgrading an extant third edition installation and booting' + echo 'from something other than a floppy, you needn''t run anything here.' + echo 'Just type ctl-d.' + + oldbootsetup=$didbootsetup + didbootsetup=1 + export didbootsetup + prompt 'Enable boot method' floppy plan9 win9x winnt + + if(! boot$rd){ + didbootsetup=$oldbootsetup + export didbootsetup + } + +case checkdone + xxxfat=(/dev/sd*/9fat) + if(! isfat $xxxfat(1) || ! ~ $didbootsetup 1){ + bootsetup=ready + export bootsetup + } +} diff --git a/sys/lib/dist.old/pc/inst/bootwin9x b/sys/lib/dist.old/pc/inst/bootwin9x new file mode 100755 index 000000000..68c2d1923 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/bootwin9x @@ -0,0 +1,117 @@ +#!/bin/rc + +dosdisk=`{ls /dev/sd??/dos >[2]/dev/null | sed 1q | sed 's!.*/(.*)/dos!\1!'} +if(~ $#dosdisk 0 || ! c: || ! test -f /n/c:/autoexec.bat || ! test -f /n/c:/config.sys) { + echo 'Could not find autoexec.bat or config.sys on the first FAT disk.' + exit bad +} + +for (i in autoexec config msdos) + if(test -f /n/c:/$i.p9) { + echo 'A Plan 9 backup already exists; will not edit system files again.' + exit bad + } + +for (i in autoexec.bat config.sys msdos.sys) + if(! cp /n/c:/$i /n/c:/^`{echo $i | sed 's/\.(bat|sys)$/.p9/'}) { + echo 'Could not back up '^$i^'; will not continue.' + exit bad + } + +if(! test -d /n/c:/plan9 && ! mkdir /n/c:/plan9) { + echo 'Could not create directory /n/c:/plan9.' + exit bad +} + +if(! cp /n/newfs/386/^(9load ld.com 9pcdisk) /tmp/plan9ini.bak /n/c:/plan9) { + echo 'Could not copy Plan 9 boot files into /n/c:/plan9.' + exit bad +} + +chmod +w /n/c:/autoexec.bat /n/c:/config.sys /n/c:/msdos.sys + +if(grep -si 'Plan ?9' /n/c:/config.sys || grep -si 'Plan ?9' /n/c:/autoexec.bat) { + echo 'Plan 9 entries already in config.sys or autoexec.bat.' + echo 'Not changing them; refer to Plan 9 install documentation' + echo 'to configure manually.' + exit bad +} + +if(! grep -si '\[menu\]' /n/c:/config.sys) { + { + echo 1 + echo i + echo '[menu] ' + echo 'menuitem=windows, Windows ' + echo 'menudefault=windows ' + echo ' ' + echo '[common] ' + echo ' ' + echo '[windows] ' + echo . + echo w + echo q + } | ed /n/c:/config.sys >/dev/null >[2]/dev/null +} + +{ + echo 1 + echo '/\[[Mm][Ee][Nn][Uu]\]' + echo '?^[Mm][Ee][Nn][Uu][Ii][Tt][Ee][Mm]=' + echo a + echo 'menuitem=plan9, Plan 9 from Bell Labs ' + echo . + echo '$' + echo a + echo ' ' + echo '[plan9] ' + echo ' ' + echo . + echo w + echo q +} | ed /n/c:/config.sys >/dev/null>[2]/dev/null + +{ + echo 1 + echo i + echo '@echo off ' + echo 'if %config%==plan9 goto plan9 ' + echo 'goto notplan9 ' + echo ':plan9 ' + echo 'plan9\ld '^$dosdisk^'!dos!plan9/9load ' + echo ':notplan9 ' + echo . + echo w + echo q +} | ed /n/c:/autoexec.bat >/dev/null>[2]/dev/null + +fn zeroopt { + if(grep -s '^'^$1^'=1' /n/c:/msdos.sys) { + { + echo '/^'^$1^'=1/s/=1/=0/' + echo w + echo q + } | ed /n/c:/msdos.sys>/dev/null>[2]/dev/null + } + if not if (grep -s '^'^$1^'=0' /n/c:/msdos.sys) + ; + if not { + { + echo 1 + echo i + echo '[Options] ' + echo 'Logo=0 ' + echo . + echo w + echo q + } | ed /n/c:/msdos.sys>/dev/null>[2]/dev/null + } +} + +if(grep -si '^\[paths\]' /n/c:/msdos.sys){ # Windows 9x rather than DOS + zeroopt Logo +# zeroopt BootGUI +} + +echo 'Plan 9 added to Windows 9X boot menu.' +exit '' diff --git a/sys/lib/dist.old/pc/inst/bootwinnt b/sys/lib/dist.old/pc/inst/bootwinnt new file mode 100755 index 000000000..ee92f5d76 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/bootwinnt @@ -0,0 +1,47 @@ +#!/bin/rc + +if(! c: || ! test -f /n/c:/boot.ini) { + echo 'Could not find NT''s boot.ini on the first FAT disk.' + exit bad +} + +if(test -f /n/c:/boot.p9) { + echo 'A Plan 9 backup already exists; will not edit boot.ini again.' + exit bad +} + +if(! cp /n/c:/boot.ini /n/c:/boot.p9) { + echo 'Could not back up boot.ini; will not continue.' + exit bad +} + +chmod +w /n/c:/boot.ini + +if(! grep -si '\[operating systems\]' /n/c:/boot.ini) { + echo 'Could not parse boot.ini.' + exit bad +} + +if(grep -si 'Plan 9' /n/c:/boot.ini) { + p9file=`{grep 'Plan 9' /n/c:/boot.ini | sed 1q | sed 's/=.*//'} + if(! ~ $p9file [Cc]:'\'*) { + echo 'Unexpected Plan 9 entry in boot.ini already; not continuing.' + exit bad + } +} + +if not { + p9file='c:\bootsect.p9' + echo 'c:\bootsect.p9 = "Plan 9 from Bell Labs" ' >>/n/c:/boot.ini +} + +p9file=/n/^`{echo $p9file | sed 's!\\!/!g'} + + +if(dd -if /dev/$disk/plan9 -bs 512 -count 1 -of $p9file >/dev/null >[2]/dev/null) { + echo 'Plan 9 added to Windows NT boot menu.' + exit '' +} + +echo 'Error copying Plan 9 boot sector to file.' +exit bad diff --git a/sys/lib/dist.old/pc/inst/configarch b/sys/lib/dist.old/pc/inst/configarch new file mode 100755 index 000000000..61912bfdb --- /dev/null +++ b/sys/lib/dist.old/pc/inst/configarch @@ -0,0 +1,40 @@ +#!/bin/rc + +# desc: set source of distribution archives +# prereq: mountfs + +switch($1) { +case go + echo + echo 'Will you be using a distribution archive on local media or the internet?' + echo + + prompt 'Distribution is from' local internet + archmedium=$rd + export archmedium + + switch($archmedium) { + case local + exec configlocal go + case internet + exec configip go + } + +case checkdone + switch($#archmedium) { + case 1 + switch($archmedium) { + case local + exec configlocal checkdone + case internet + exec configip checkdone + case * + configarch=notdone + export configarch + } + case * + configarch=notdone + export configarch + } +} + diff --git a/sys/lib/dist.old/pc/inst/configdist b/sys/lib/dist.old/pc/inst/configdist new file mode 100755 index 000000000..3e99bea0d --- /dev/null +++ b/sys/lib/dist.old/pc/inst/configdist @@ -0,0 +1,22 @@ +#!/bin/rc + +# prereq: mountfs +# desc: choose the source of the distribution archive + +switch($1){ +case checkdone + if(! ~ $distisfrom net local){ + configdist=ready + export configdist + } + +case go + echo 'Are you going to download the distribution' + echo 'from the internet or do you have it on local media?' + echo + prompt -d local 'Distribution is from' local net + distisfrom=$rd + export distisfrom +} + + diff --git a/sys/lib/dist.old/pc/inst/configether b/sys/lib/dist.old/pc/inst/configether new file mode 100755 index 000000000..0922ea339 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/configether @@ -0,0 +1,53 @@ +#!/bin/rc + +# desc: configure your internet connection via an ethernet card + +switch($1) { +case go + echo + echo 'Please choose a method for configuring your ethernet connection.' + echo + echo ' manual - specify IP address, network mask, gateway IP address' + echo ' dhcp - use DHCP to automatically configure' + echo + + prompt 'Configuration method' manual dhcp + ethermethod=$rd + gwaddr=xxx + ipaddr=xxx + ipmask=xxx + switch($ethermethod){ + case dhcp + echo + echo 'Some ISPs, notably @HOME, require a host name passed with DHCP' + echo 'requests. An example for @HOME would be "cc1018221-a". If your' + echo 'ISP supplied you such a name, enter it.' + echo + prompt -d none 'host name'; dhcphost=$rd + switch($dhcphost){ + case none + dhcphost=(); + case * + dhcphost=(-h $dhcphost) + } + export dhcphost + case manual + prompt 'ip address'; ipaddr=$rd + prompt 'network mask'; ipmask=$rd + prompt 'gateway address'; gwaddr=$rd + export ipaddr ipmask gwaddr + } + + export ethermethod gwaddr ipaddr ipmask dhcphost + exec startether go + +case checkdone + if(! ~ $ethermethod manual dhcp) { + configether=notdone + export configether + } + if(~ $ethermethod manual && ~ 0 $#ipaddr $#ipmask $#gwaddr) { + configether=notdone + export configether + } +} diff --git a/sys/lib/dist.old/pc/inst/configfs b/sys/lib/dist.old/pc/inst/configfs new file mode 100755 index 000000000..81f82897c --- /dev/null +++ b/sys/lib/dist.old/pc/inst/configfs @@ -0,0 +1,23 @@ +#!/bin/rc + +# desc: choose the type of file system to install + +switch($1){ +case checkdone + if(! ~ $fstype fossil fossil+venti){ + configfs=ready + export configfs + } + +case go + echo 'You can install the following types of file systems:' + echo + echo ' fossil the new Plan9 fileserver' + echo ' fossil+venti fossil + a archival dump server' + echo + prompt -d fossil 'File system' fossil fossil+venti + fstype=$rd + export fstype +} + + diff --git a/sys/lib/dist.old/pc/inst/configip b/sys/lib/dist.old/pc/inst/configip new file mode 100755 index 000000000..a7873c9f1 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/configip @@ -0,0 +1,64 @@ +#!/bin/rc + +switch($1) { +case go + + devs='' + if(test -d '#l/ether0' >[2]/dev/null) + devs=$devs^ether + if(test -f '#t'/eia? >[2]/dev/null) + devs=$devs^ppp + + switch($devs){ + case '' + echo + echo 'Could not find ethernet card nor serial port nor modem.' + echo 'Please use a local copy of the distribution archive.' + echo + ifc=none + + case ppp + echo + echo 'No ethernet card was detected, but there is a serial port or modem.' + echo 'We will configure PPP.' + echo + ifc=ppp + + case ether + echo + echo 'No serial port or modem detected, but there is an ethernet card.' + echo 'We will configure the ethernet.' + echo + ifc=ether + + case etherppp + echo + echo 'You can connect to the internet via' + echo 'a local ethernet or a dial-up PPP connection.' + echo + prompt 'Interface to use' ether ppp + ifc=$rd + } + + ipinterface=$ifc + export ipinterface + + switch($ifc) { + case ether + exec configether go + case ppp + exec configppp go + } + +case checkdone + if(~ $#ipinterface 1) + switch($ipinterface) { + case ether + exec configether checkdone + case ppp + exec configppp checkdone + } + configarch=notdone + export configarch + +} diff --git a/sys/lib/dist.old/pc/inst/confignet b/sys/lib/dist.old/pc/inst/confignet new file mode 100755 index 000000000..182ed40cb --- /dev/null +++ b/sys/lib/dist.old/pc/inst/confignet @@ -0,0 +1,67 @@ +#!/bin/rc + +# prereq: configdist +# desc: configure the network to download the distribution + +switch($1){ +case checkready checkdone + if(! ~ $distisfrom net){ + confignet=notdone + export confignet + exit + } + if(~ $distisfrom net && ~ $netisfrom ppp ether){ + x=config$netisfrom + $x=done + config$netisfrom checkdone + confignet=$$x + export confignet + exit + } + confignet=ready + export confignet + exit + +case go + devs='' + if(test -d '#l/ether0' >[2]/dev/null) + devs=$devs^ether + if(test -f '#t'/eia? >[2]/dev/null) + devs=$devs^ppp + + switch($devs){ + case '' + echo + echo 'Could not find ethernet card nor serial port nor modem.' + echo 'Please use a local copy of the distribution archive.' + echo + netisfrom=none + + case ppp + echo + echo 'No ethernet card was detected, but there is a serial port or modem.' + echo 'We will configure PPP.' + echo + netisfrom=ppp + + case ether + echo + echo 'No serial port or modem detected, but there is an ethernet card.' + echo 'We will configure the ethernet.' + echo + netisfrom=ether + + case etherppp + echo + echo 'You can connect to the internet via' + echo 'a local ethernet or a dial-up PPP connection.' + echo + prompt 'Interface to use' ether ppp + netisfrom=$rd + } + + export netisfrom + if(~ $netisfrom ether ppp) + exec config$netisfrom go +} + diff --git a/sys/lib/dist.old/pc/inst/configppp b/sys/lib/dist.old/pc/inst/configppp new file mode 100755 index 000000000..6bbffc4f0 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/configppp @@ -0,0 +1,63 @@ +#!/bin/rc + +# desc: configure your internet connection via ppp over a modem + +switch($1) { +case go + devs=`{ls -p '#t/'eia? >[2]/dev/null} + if(~ $#devs 0) { + echo 'No serial port found; this can''t happen.' # because configip checks + exit + } + + # not going to use the mouse for PPP + if(~ eia^$mouseport $devs) + devs=`{echo $devs | sed 's/eia'^$mouseport^'//'} + + if(~ $#devs 0) { + echo 'The only serial port you have is your mouse.' + echo 'Cannot configure PPP.' + exit + } + + echo + echo 'Please choose the serial port or modem to use to connect to your ISP.' + echo + for(i in $devs) { + n=`{echo $i | sed 's/eia//'} + n=`{hoc -e 1+$n} + echo ' '^$i^'(Windows'' COM'^$n^')' + } + echo + prompt 'Serial device' $devs + pppdev=$rd + + echo + echo 'Pick a baud rate for the PPP connection.' + echo + prompt -d 115200 'Baud rate' + pppbaud=$rd + + echo + echo 'You can specify your dialup phone number, username, and password,' + echo 'or you can log in manually by typing the modem commands yourself.' + echo + prompt 'Dialing method' auto manual + pppmethod=$rd + + switch($pppmethod){ + case auto + prompt 'PPP phone number'; pppphone=$rd + prompt 'PPP phone username'; pppuser=$rd + prompt 'PPP phone password'; ppppasswd=$rd + } + + export pppdev pppmethod pppphone ppppasswd pppuser pppbaud + exec startppp go + +case checkdone + if(! ~ $#pppmethod 1 || ! test -f /dev/$pppdev){ + configppp=notdone + export configppp + } +} diff --git a/sys/lib/dist.old/pc/inst/copydist b/sys/lib/dist.old/pc/inst/copydist new file mode 100755 index 000000000..507d5602b --- /dev/null +++ b/sys/lib/dist.old/pc/inst/copydist @@ -0,0 +1,31 @@ +#!/bin/rc + +# prereq: mountdist +# desc: copy the distribution into the file system + +switch($1){ +case checkready + if(! test -d /n/dist/dist/replica){ + copydist=notdone + export copydist + exit + } + if(test -f /n/newfs/dist/replica/didplan9){ + copydist=done + export copydist + exit + } +case go + inst/watchfd applylog 0 `{ls -l /n/dist/dist/replica/plan9.log | awk '{print $6}'} 'Installing file system' & + replica/pull -c / /rc/bin/inst/replcfg + if(~ $status '' *conflicts || test -f /n/newfs/dist/replica/didplan9witherrors) + >/n/newfs/dist/replica/didplan9 + if not + >/n/newfs/dist/replica/didplan9witherrors + +case checkdone + if(! test -f /n/newfs/dist/replica/didplan9){ + copydist=notdone + export copydist + } +} diff --git a/sys/lib/dist.old/pc/inst/defs b/sys/lib/dist.old/pc/inst/defs new file mode 100755 index 000000000..f9c9454c0 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/defs @@ -0,0 +1,162 @@ +nl=' +' +tab=' ' +if(~ $#distname 0) + distname=plan9 + +wctl=/dev/null +if(test -w /dev/wctl) + wctl=/dev/wctl + +fn log { + echo $* >>/srv/log +} + +fn logprog { + echo '% '^$"* >>/srv/log + $* >[2=1] >>/srv/log +} + +fn sigint { + # nothing happens +} + +fn prompt { + def=() + what=() + if(~ $1 -d && ! ~ $#* 1){ + def=$2 + shift + shift + } + + optstr=() + if(~ $1 -w && ! ~ $#* 1){ + optstr=$2 + shift + shift + } + + pr=$1 + shift + + opts=($*) + if(~ $#opts 0) { + suf=' ' + } + if not if(! ~ $#optstr 0) { + if(~ $optstr '') + suf=' ' + if not { + pr=$pr^' ('^$"optstr^')' + suf='' + } + } + if not { + pr=$pr^' ('^$1 + shift + for(i) + pr=$pr^', '^$i + pr=$pr^')' + suf='' + } + + if(~ $#def 1) + pr=$pr^$suf^'['^$def^']' + if not + pr=$pr^$suf^'[no default]' + + pr=$pr^': ' + + + okay=no + while(~ $okay no) { + echo -n current >$wctl + echo -n top >$wctl + echo -n $pr >[1=2] + ifs='' {rd=`{read}} + if(~ $#rd 0) + exit notdone + if(~ $rd !*){ + ifs='' {rd=`{echo $rd | sed 's/!//'}} + echo $rd + rc -c $rd + echo !$status + } + if not{ + rd=`{echo $rd} + if(~ $#rd 0 || ~ $rd '') + rd=$def + + switch($#opts){ + case 0 + if(! ~ $rd '') + okay=yes + case * + if(~ $rd $opts) + okay=yes + } + } + } + echo -n $rd >/env/rd # just in case +} + +fn desc { + echo -n ' '^$1^' - ' + grep '^# desc: ' $1 | sed 's/# desc: //' +} + +fn prereq { + grep '^# prereq:' $1 | sed 's/# prereq://' +} + +fn mustdo { + echo You must `{grep '^# mustdo:' $1 | sed 's/# mustdo://'} +} + +# there's no easy way to pass shell variables +# up from children to parents; the parents have +# to be coerced into noticing that the environment +# changed, even when in the same environment group. +# +# instead, we explicitly export the variables we want +# to percolate, and the parent calls coherence to reread +# the variables. +# +# we just append to the vars file, so that later exports +# override earlier ones; when we call coherence, +# the duplicates are thrown out. + +fn export { + null=() + nonnull=() + for(i in $*){ + if(~ $#$i 0) + null=($null $i) + if not + nonnull=($nonnull $i) + } + if(! ~ $#nonnull 0) + whatis $nonnull |grep -v '^\./' >>/tmp/vars >[2]/dev/null + for(i in $null) + echo $i^'=()' >>/tmp/vars +} + +fn coherence { + if(test -f /tmp/vars) { + grep '^[a-z]*=' /tmp/vars >/tmp/vars2 + v=`{sed 's/^([a-z]*)=.*/\1/' /tmp/vars2 | sort -u} + . /tmp/vars2 + rm /tmp/vars2 + rm /tmp/vars + export $v + } +} + +# ip device stats + +fn isipdevup { + grep -s $1 /net/ipifc/*/status >[2]/dev/null +} + + diff --git a/sys/lib/dist.old/pc/inst/download b/sys/lib/dist.old/pc/inst/download new file mode 100755 index 000000000..70d7f5ba7 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/download @@ -0,0 +1,56 @@ +#!/bin/rc + +# prereq: mountfs +# desc: download or continue to download the distribution archives + +switch($1) { +case checkready + devs=(`{cat /net/ipifc/*/status >[2]/dev/null | + grep -v '127\.0\.0\.1' | + sed 's/ .*//'}) + if(~ $#devs 0) { + download=notdone + export download + } + if(~ $mountdist done){ + download=notdone + export download + } + +case go + if(! test -f /srv/cs) { + log starting cs, dns + logprog ndb/cs >>/srv/log >[2=1] + logprog ndb/dns -r >>/srv/log >[2=1] + } + if(! test -f /net/cs) { + logprog mount -a /srv/cs /net + logprog mount -a /srv/dns /net + } + + # BUG make restartable + echo 'Downloading distribution package...' + baropt='-w 145,129,445,168' + if(~ $textinst 1) + baropt=-t + if(! hget -vo /n/newfs/dist/_plan9.iso.bz2 $installurl/plan9.iso.bz2 |[2] bargraph $baropt 'downloading '^plan9.iso.bz2) + exit + mv /n/newfs/dist/_plan9.iso.bz2 /n/newfs/dist/plan9.iso.bz2 + if(~ $fstype fossil){ + echo fsys main sync >>/srv/fscons + } + + echo 'The distribution is downloaded.' + + srvmedia=() + mountmedia=(mount /srv/fossil /n/distmedia) + distmediadir=/dist + export distmediadir mountmedia distmedia + +case checkdone + if(! test -f /n/newfs/dist/plan9.iso.bz2) { + download=notdone + export download + } +} + diff --git a/sys/lib/dist.old/pc/inst/finish b/sys/lib/dist.old/pc/inst/finish new file mode 100755 index 000000000..e616e64e1 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/finish @@ -0,0 +1,19 @@ +#!/bin/rc + +# desc: finish the installation and reboot +# prereq: bootsetup +# mustdo: + +switch($1) { +case checkdone + finish=ready + export finish + +case go + if(~ $cdboot yes){ + echo 'Congratulations; you''ve completed the install.' + echo + halt + } + stop go finished +} diff --git a/sys/lib/dist.old/pc/inst/fmtfossil b/sys/lib/dist.old/pc/inst/fmtfossil new file mode 100755 index 000000000..98bf33fc1 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/fmtfossil @@ -0,0 +1,91 @@ +#!/bin/rc + +# desc: initialize disks for a fossil server +# prereq: configfs + +switch($1){ +case checkready checkdone + if(! ~ $fstype fossil+venti fossil){ + fmtfossil=notdone + export fmtfossil + exit + } + ff=`{ls /dev/sd*/fossil* /dev/fs/fossil* >[2]/dev/null} + if(~ $#ff 0){ + fmtfossil=notdone + export fmtfossil + exit + } + gg=() + for(f in $ff) + if(isfossil $f) + gg=($gg $f) + if(~ $#gg 0){ + fmtfossil=ready + export fmtfossil + exit + } + fmtfossil=done + export fmtfossil + exit + +case go + ff=`{ls /dev/sd*/fossil* /dev/fs/fossil* >[2]/dev/null} + if(~ $#ff 0){ + echo 'You need to create a partition or partitions to hold the Fossil write cache.' + echo 'The partition name must begin with "fossil".' + echo + fmtfossil=notdone + export fmtfossil + exit + } + default=() + if(~ $#ff 1){ + default=(-d $ff) + } + echo You have the following fossil partitions. + echo + prompt $default 'Fossil partition to format' $ff + f=$rd + + do=yes + if(isfossil $f){ + echo $f appears to already be formatted as Fossil file system. + echo Do you really want to reformat it? + echo + prompt -d no 'Reformat '$f yes no + do=$rd + } + if(~ $do yes){ + fossil/flfmt -y $f + n=`{cat /dev/swap | grep ' user' | sed 's/^[0-9]+\/([0-9]+) .*/\1/'} + if(test $n -gt 32768) + m=3000 # if have at least 128 user MB, use 24MB for fossil + if not if(test $n -gt 16384) + m=1500 # 64 user MB => 12MB for fossil + if not if(test $n -gt 8192) + m=750 # 32 user MB => 6MB for fossil + if not + m=256 # 2MB for fossil (this will be slow) + + # if we're using a venti in the back, take hourly snapshots + # that retire after three days, in addition to the daily dumps at 5am + if(~ $fstype fossil+venti){ + v='' + snap='fsys main snaptime -s 60 -a 0500 -t 2880' + } + # otherwise, take the daily dumps but nothing else -- + # we can't retire snapshots unless dumps are being archived + if not{ + v='-V' + snap='' + } + echo \ +'fsys main config '^$f^' +fsys main open '^$v^' -c '^$m^' +'^$snap^' +' | fossil/conf -w $f + } + + echo Done. +} diff --git a/sys/lib/dist.old/pc/inst/fmtventi b/sys/lib/dist.old/pc/inst/fmtventi new file mode 100755 index 000000000..db79440ac --- /dev/null +++ b/sys/lib/dist.old/pc/inst/fmtventi @@ -0,0 +1,190 @@ +#!/bin/rc + +# desc: initialize disks for a venti server +# prereq: mountdist + +switch($1){ +case checkready checkdone + if(! ~ $fstype fossil+venti){ + fmtventi=notdone + export fmtventi + exit + } + if(! test -e /bin/venti/fmtarenas || ! test -e /bin/venti/fmtisect || ! test -e /bin/venti/fmtindex){ + bind -a /n/dist/386/bin/venti /bin/venti + if(! test -e /bin/venti/fmtarenas || ! test -e /bin/venti/fmtisect || ! test -e /bin/venti/fmtindex){ + fmtventi=notdone + export fmtventi + exit + } + } + ff=`{ls /dev/sd*/arenas* /dev/fs/arenas* >[2]/dev/null} + if(~ $#ff 0){ + fmtventi=notdone + export fmtventi + exit + } + gg=() + for(f in $ff) + if(isventi $f) + gg=($gg $f) + if(~ $#gg 0){ + fmtventi=ready + export fmtventi + exit + } + + ventiarena=$gg(1) + export ventiarena + + fmtventi=done + export fmtventi + exit + +case go + ff=`{ls /dev/sd*/arenas* /dev/fs/arenas* >[2]/dev/null} + if(~ $#ff 0){ + echo 'You need to create a partition or partitions to hold the Venti arenas.' + echo 'The arena partition names must begin with "arenas".' + echo + fmtventi=notdone + export fmtventi + exit + } + default=(-d $"ff) + if(! ~ $#ventiarena 0){ + default=(-d $"ventiarena) + } + echo You have the following Venti arena partitions. + ls -l $ff + echo + + prompt $default 'Venti arena partitions to use' + aa=`{echo $rd} + bad=no + for(a in $aa){ + if(! ~ $a $ff){ + echo 'Bad venti arena partition' $a + fmtventi=notdone + export fmtventi + exit + } + } + ventiarena=$aa + export ventiarena + + gg=`{ls /dev/sd*/isect* /dev/fs/isect* >[2]/dev/null} + if(~ $#gg 0){ + echo 'You need to create a partition or partitions to hold the Venti indices.' + echo 'The index partition names must begin with "isect".' + echo + fmtventi=notdone + export fmtventi + exit + } + default=(-d $"gg) + if(! ~ $#ventiindex 0){ + default=(-d $"ventiindex) + } + + echo You have the following Venti index partitions. + ls -l $gg + echo + + prompt $default 'Venti index partitions to use' + aa=`{echo $rd} + bad=no + for(a in $aa){ + if(! ~ $a $gg){ + echo 'Bad venti index partition' $a + fmtventi=notdone + export fmtventi + exit + } + } + ventiindex=$aa + export ventiindex + + n=-1 + fmta=() + for(a in $ventiarena){ + do=yes + n=`{hoc -e 1+$n} + if(isventiarenas $a){ + echo File $a is already formatted as a Venti arenas partition. + prompt -d no 'Reformat '$a yes no + do=$rd + } + if(~ $do yes) + fmta=($fmta arenas$n:$a) + } + + n=-1 + fmti=() + for(a in $ventiindex){ + do=yes + n=`{hoc -e 1+$n} + if(isventiisect $a){ + echo File $a is already formatted as a Venti index section. + prompt -d no 'Reformat '$a yes no + do=$rd + } + if(~ $do yes) + fmti=($fmti isect$n:$a) + } + + echo Formatting Venti arenas and indices (this takes a while). + # do each disk in parallel + echo good >/tmp/fmt + dd=() + for(a in $fmta $fmti){ + d=`{echo $a | sed 's!.*:(/.*/).*!\1!'} + if(! ~ $d $dd) + dd=($dd $d) + } + for(d in $dd){ + { + for(a in $fmta){ + i=`{echo $a | sed 's!(.*):(/.*/)(.*)!\1 \2 \2\3!'} + if(~ $i(2) $d){ + echo $i(3) ... + venti/fmtarenas $i(1) $i(3) || echo bad >/tmp/fmt + echo done with $i(3) + } + } + for(a in $fmti){ + i=`{echo $a | sed 's!(.*):(/.*/)(.*)!\1 \2 \2\3!'} + if(~ $i(2) $d){ + echo $i(3) ... + venti/fmtisect $i(1) $i(3) || echo bad >/tmp/fmt + echo done with $i(3) + } + } + } & + } + wait + if(~ bad `{cat /tmp/fmt}){ + echo There were errors formatting the indices and arenas. + fmtventi=ready + export fmtventi + exit errors + } + + echo Done formatting Venti arenas and indices. + + v=$ventiarena(1) + echo Storing Venti config on $v... + { + echo index main + for(i in $ventiindex) + echo isect $i + for(a in $ventiarena) + echo arenas $a + } | venti/conf -w $v + + echo Initializing index... + venti/fmtindex $v + + echo Done with Venti! +} + diff --git a/sys/lib/dist.old/pc/inst/gui b/sys/lib/dist.old/pc/inst/gui new file mode 100755 index 000000000..afb0981d0 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/gui @@ -0,0 +1,7 @@ +#!/bin/rc + +cd /bin/inst +echo blanktime 0 >/dev/vgactl +. defs + +startwin 640 480 diff --git a/sys/lib/dist.old/pc/inst/halt b/sys/lib/dist.old/pc/inst/halt new file mode 100755 index 000000000..4554359f0 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/halt @@ -0,0 +1,18 @@ +#!/bin/rc + +echo -n 'Halting file systems...' + +if(ps | grep -s ' venti$') + venti/sync -h tcp!127.0.0.1!17034 +if(ps | grep -s ' fossil$'){ + echo fsys all halt >>/srv/fscons + slay fossil|rc +} + +echo done +echo +echo Remember to take the install disk out of the drive. +echo Feel free to turn off your computer. +while() + sleep 3600 + diff --git a/sys/lib/dist.old/pc/inst/hasmbr b/sys/lib/dist.old/pc/inst/hasmbr new file mode 100755 index 000000000..1adaa0a5b --- /dev/null +++ b/sys/lib/dist.old/pc/inst/hasmbr @@ -0,0 +1,12 @@ +#!/bin/rc + +if(! ~ $#* 1) { + echo 'usage: hasmbr /dev/sdC0/part' >[1=2] + exit usage +} + +x=`{xd -b $1 | sed -n '32p;32q'} +if(~ $x(16) 55 && ~ $x(17) aa) + exit '' +exit nope + diff --git a/sys/lib/dist.old/pc/inst/hdrs b/sys/lib/dist.old/pc/inst/hdrs new file mode 100755 index 000000000..0b934999f --- /dev/null +++ b/sys/lib/dist.old/pc/inst/hdrs @@ -0,0 +1,7 @@ +#!/bin/rc + +if(! ~ $#* 1) { + echo 'usage: hdrs file.9gz' >[1=2] + exit usage +} +gunzip < $1 | disk/mkext -h diff --git a/sys/lib/dist.old/pc/inst/is9660 b/sys/lib/dist.old/pc/inst/is9660 new file mode 100755 index 000000000..1d138e55e --- /dev/null +++ b/sys/lib/dist.old/pc/inst/is9660 @@ -0,0 +1,12 @@ +#!/bin/rc + +# 0000000 01 C D 0 0 1 01 00 P L A N 9 + +if(! ~ $#* 1) { + echo 'usage: is9660 /dev/sdC0/part' >[1=2] + exit usage +} + +ifs=$nl {id=`{dd -if $1 -bs 2048 -skip 16>[2]/dev/null | xd -c | sed 1q | sed 's/.........(....................).*/\1/'}} +~ $id '01 C D 0 0 1 01' +exit $status diff --git a/sys/lib/dist.old/pc/inst/isext2 b/sys/lib/dist.old/pc/inst/isext2 new file mode 100755 index 000000000..b79265f6a --- /dev/null +++ b/sys/lib/dist.old/pc/inst/isext2 @@ -0,0 +1,11 @@ +#!/bin/rc + +if(! ~ $#* 1) { + echo 'usage: isext2 /dev/sdC0/part' >[1=2] + exit usage +} + +cmp -s <{dd -if $1 -bs 1 -count 2 -skip 1080 >[2]/dev/null | xd -b |sed 1q} \ + <{echo '0000000 53 ef'} + +exit $status diff --git a/sys/lib/dist.old/pc/inst/isfat b/sys/lib/dist.old/pc/inst/isfat new file mode 100755 index 000000000..860278571 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/isfat @@ -0,0 +1,22 @@ +#!/bin/rc + +rfork e + +# 0000000 eb 3c 90 P l a n 9 . 0 0 00 02 04 02 00 +# 0000010 02 00 02 02 P f8 14 00 ? 00 ff 00 ~ 04 } 00 +# 0000020 02 P 00 00 80 00 ) a8 04 } 00 C Y L I N +# 0000030 D R I C A L F A T 1 6 fa 8c + +if(! ~ $#* 1) { + echo 'usage: isfat /dev/sdC0/part' >[1=2] + exit usage +} + +arg=$1 +fn fat { + cmp -s <{dd -if $arg -bs 1 -count 3 -skip $1 >[2]/dev/null} <{echo -n FAT} +} + +fat 54 || fat 82 +exit $status + diff --git a/sys/lib/dist.old/pc/inst/isfossil b/sys/lib/dist.old/pc/inst/isfossil new file mode 100755 index 000000000..21c7d3e29 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/isfossil @@ -0,0 +1,16 @@ +#!/bin/rc + +if(! ~ $#* 1){ + echo 'usage: isfossil /dev/sdC0/part' >[1=2] + exit usage +} + +arg=$1 +if(! cmp -s <{dd -quiet 1 -if $arg -bs 1024 -iseek 127 | + dd -quiet 1 -bs 14 -count 1} <{echo 'fossil config'}) + exit noconfig +if(! cmp -s <{dd -quiet 1 -if $arg -bs 1024 -iseek 128 | + dd -quiet 1 -bs 4 -count 1 | xd -b | sed 1q} <{echo '0000000 37 76 ae 89'}) + exit notwritebuffer +exit 0 + diff --git a/sys/lib/dist.old/pc/inst/isventi b/sys/lib/dist.old/pc/inst/isventi new file mode 100755 index 000000000..555c27a7f --- /dev/null +++ b/sys/lib/dist.old/pc/inst/isventi @@ -0,0 +1,13 @@ +#!/bin/rc + +if(! ~ $#* 1){ + echo 'usage: isventi /dev/sdC0/part' >[1=2] + exit usage +} + +arg=$1 +if(! cmp -s <{dd -quiet 1 -if $arg -bs 1024 -iseek 248 | + dd -quiet 1 -bs 13 -count 1} <{echo 'venti config'}) + exit noconfig +exit 0 + diff --git a/sys/lib/dist.old/pc/inst/isventiarenas b/sys/lib/dist.old/pc/inst/isventiarenas new file mode 100755 index 000000000..dfce274de --- /dev/null +++ b/sys/lib/dist.old/pc/inst/isventiarenas @@ -0,0 +1,13 @@ +#!/bin/rc + +if(! ~ $#* 1){ + echo 'usage: isventiarenas /dev/sdC0/part' >[1=2] + exit usage +} + +arg=$1 +if(! cmp -s <{dd -quiet 1 -if $arg -bs 1024 -iseek 256 | + dd -quiet 1 -bs 4 -count 1 | xd -b | sed 1q} <{echo '0000000 a9 e4 a5 e7'}) + exit notarenas +exit 0 + diff --git a/sys/lib/dist.old/pc/inst/isventiisect b/sys/lib/dist.old/pc/inst/isventiisect new file mode 100755 index 000000000..0b11c9c4e --- /dev/null +++ b/sys/lib/dist.old/pc/inst/isventiisect @@ -0,0 +1,13 @@ +#!/bin/rc + +if(! ~ $#* 1){ + echo 'usage: isventiisect /dev/sdC0/part' >[1=2] + exit usage +} + +arg=$1 +if(! cmp -s <{dd -quiet 1 -if $arg -bs 1024 -iseek 256 | + dd -quiet 1 -bs 4 -count 1 | xd -b | sed 1q} <{echo '0000000 d1 5c 5e c7'}) + exit notisect +exit 0 + diff --git a/sys/lib/dist.old/pc/inst/main b/sys/lib/dist.old/pc/inst/main new file mode 100755 index 000000000..25ac0d168 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/main @@ -0,0 +1,115 @@ +#!/bin/rc + +. defs + +while() +{ +div=-------------------------------------- +echo +echo $div +echo +echo -n 'Preparing menu...' + +# must be topologically sorted (by prereq) +tasks=(\ + configfs\ + partdisk prepdisk\ + fmtfossil\ + mountfs\ + configdist\ + confignet\ + mountdist\ + fmtventi\ + download\ + copydist\ + bootsetup finish stop\ + stopether stopppp\ +) +# startether startppp stopether stopppp download\ + +# these don't show up in the menu but still matter +pseudotasks=(configip havefiles etherup etherdown pppup pppdown) + +for(i in $tasks $pseudotasks) + $i=notdone + +coherence + +for(i in $tasks $pseudotasks) + if(~ $#$i 0) + $i=notdone + +# +# we believe the environment about what is done +# only if we've confirmed it. since the tasks list is sorted so that +# prereqs of xxx come before xxx, it's okay to assume xxx +# is done until proven otherwise -- either a prereq or checkdone +# will say so. +# + +done=() +ready=() +rm /env/done +rm /env/ready +for(i in $tasks) { + $i=done + for(j in `{prereq $i}) + if(! ~ $$j done) + $i=notdone + if(~ $$i done) { + export $i + $i checkdone + $i=`{grep '^'$i^'=' /tmp/vars | sed -n '$p' | sed 's/.*=//'} + } + + if(~ $$i notdone ready) { + okay=yes + for(j in `{prereq $i}) + if(! ~ $$j done) + okay=no + switch($okay){ + case yes + $i=ready + export $i + $i checkready + $i=`{grep '^'$i^'=' /tmp/vars | sed -n '$p' | sed 's/.*=//'} + case no + $i=notdone + } + } + + if(~ $$i done ready) + $$i=($$$i $i) # rc can be just as complicated as perl! +} + +export $tasks $pseudotasks done ready +coherence +echo + +if(! ~ $#done 0) { + echo 'The following tasks are done: ' + for(i in $done) + desc $i + echo +} + +echo 'The following unfinished tasks are ready to be done:' +for(i in $ready) + desc $i +echo + +if(~ $#ready 0) { + echo hey you finished everything! not supposed to happen. + sleep 100 + exit +} + +prompt -d $ready(1) -w '' 'Task to do' $done $ready + +echo +echo $div + +$rd go +$rd=done # if it's not, the check will figure that out +export $rd +} diff --git a/sys/lib/dist.old/pc/inst/mainloop b/sys/lib/dist.old/pc/inst/mainloop new file mode 100755 index 000000000..94d58efc4 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/mainloop @@ -0,0 +1,23 @@ +#!/bin/rc + +sleep 86400 & +cd /bin/inst +. defs +fn sigint { } + +coherence + +disks=`{ls /dev/sd*/data >[2]/dev/null | sed 's!/dev/(sd..)/data!\1!'} +for (i in /dev/sd*/data) + if(test -f $i) + disk/fdisk -p $i>`{basename -d $i}^/ctl >[2]/dev/null +for(i in /dev/sd*/plan9*) + if(test -f $i) + disk/prep -p $i >`{basename -d $i}^/ctl >[2]/dev/null + +# we run this while() here so that ctl-d won''t exit from us -- it''ll only exit main! +# main contains a while() loop too, to avoid the hit of +# continually reexecing from here. + +while() + main diff --git a/sys/lib/dist.old/pc/inst/mkini.awk b/sys/lib/dist.old/pc/inst/mkini.awk new file mode 100755 index 000000000..7ddf6a80f --- /dev/null +++ b/sys/lib/dist.old/pc/inst/mkini.awk @@ -0,0 +1,59 @@ +BEGIN{ + m = "common" + haveold = 0; + while(getline <"/n/9fat/plan9-3e.ini" > 0){ + haveold = 1 + if($0 ~ /\[.*\]/){ + m = substr($0, 2, length($0)-2) + continue + } + if(m=="menu" && $0 ~ /^menuitem=4e,/) + continue + a[m] = a[m] $0 "\n" + } + + a["4e"] = "" + while(getline <"/tmp/plan9.ini" > 0) + a["4e"] = a["4e"] $0 "\n" + + if(a["menu"] == "" && haveold){ + a["menu"] = "menuitem=3e, Plan 9 Third Edition\n" + a["3e"] = "" + } + + if(a["common"] != ""){ + for(i in a) + if(i != "4e" && i != "common" && i != "menu") + a[i] = a["common"] a[i] + delete a["common"] + } + + bootdisk4e=ENVIRON["fs"] + gsub("/dev/", "boot(args|disk|file)=local!#S/", bootdisk4e) + + if(!haveold) + print a["4e"] + else{ + print "[menu]" + print "menuitem=4e, Plan 9 Fourth Edition" + print a["menu"] + print "" + delete a["menu"] + + print "[4e]" + print a["4e"] + print "" + delete a["4e"] + + for(i in a){ + # BUG: if rootdir is already there we should rewrite it + # sometimes into /3e/whatwasthere + if(a[i] ~ bootdisk4e && !(a[i] ~ /rootdir=/)) + a[i] = "rootdir=/root/3e\n" a[i] + print "[" i "]" + gsub(/9fat!9pcdisk/, "9fat!9pc3e", a[i]) + print a[i] + print "" + } + } +} diff --git a/sys/lib/dist.old/pc/inst/mountdist b/sys/lib/dist.old/pc/inst/mountdist new file mode 100755 index 000000000..8d171a1cc --- /dev/null +++ b/sys/lib/dist.old/pc/inst/mountdist @@ -0,0 +1,222 @@ +#!/bin/rc + +# prereq: mountfs configdist +# desc: locate and mount the distribution + +fn domount{ + if(! test -e $mountmedia(2)) + logprog $srvmedia + unmount /n/distmedia >[2]/dev/null + logprog $mountmedia +} + +fn exitifdone{ + if(test -f /n/dist/dist/replica/plan9.db) + exit +} + +fn trycdimage{ + if(test -f $1){ + rm -f /srv/9660.dist + unmount /n/dist + 9660srv 9660.dist >[2]/dev/null + logprog mount /srv/9660.dist /n/dist $1 + exitifdone + mountdist=notdone + export mountdist + exit notdone + } +} + +fn trycdimagebz2 { + if(test -f $1){ + echo -n 'bunzip2 < '^$1^' >/n/newfs/dist/plan9.iso' + bunzip2 < $1 >/n/newfs/dist/_plan9.iso && + mv /n/newfs/dist/_plan9.iso /n/newfs/dist/plan9.iso + echo + trycdimage /n/newfs/dist/plan9.iso + mountdist=notdone + export mountdist + exit notdone + } +} + +fn havedist { + test -f $1/dist/replica/plan9.db || + test -f $1/plan9.iso || + test -f $1/plan9.iso.bz2 +} + +switch($1){ +case checkready + if(! ~ $distisfrom local && ! ~ $download done){ + mountdist=notdone + export mountdist + } + if(! ~ $#mountmedia 0 1){ + if(domount){ + mountdist=done + export mountdist + if(mountdist checkdone) + exit + } + srvmedia=() + mountmedia=() + mountdist=ready + export srvmedia mountmedia mountdist + } + +case go + fat=() + ext2=() + x9660=() + fossil=() + + echo Please wait... Scanning storage devices... + + parts=`{ls /dev/sd??/* >[2]/dev/null | grep -v '/(plan9.*|ctl|log|raw)$'} + for (i in $parts) { + echo -n ' '^$i + n=`{echo $i | sed 's;/;_;g'} + if(! test -f /tmp/localpart.$n) + dd -if $i -bs 2048 -count 32 -of /tmp/localpart.$n >[2]/dev/null + if(isfat /tmp/localpart.$n) + fat=($fat $i) + if(isext2 /tmp/localpart.$n) + ext2=($ext2 $i) + if(is9660 /tmp/localpart.$n) + x9660=($x9660 $i) + if(isfossil $i) + fossil=($fossil $i) + echo + } + echo + echo The following storage media were detected. + echo Choose the one containing the distribution. + echo + for(i in $parts){ + switch($i){ + case $fat + echo ' '^$i^' (microsoft fat)' + case $ext2 + echo ' '^$i^' (linux ext2)' + case $x9660 + echo ' '^$i^' (iso9660 cdrom)' + case $fossil + echo ' '^$i^' (plan9 fossil)' + } + } + echo + + mountstatus=x + while(! ~ $mountstatus ''){ + prompt -w '' 'Distribution disk' $fat $x9660 $fossil + disk=$rd + + srvmedia=() + mountmedia=() + switch($disk){ + case $fs + mountmedia=(bind /n/newfs /n/distmedia) + case $fat + srvmedia=(dossrv) + mountmedia=(mount /srv/dos /n/distmedia $disk) + case $ext2 + srvmedia=(ext2srv -r) + mountmedia=(mount /srv/ext2 /n/distmedia $disk) + case $x9660 + srvmedia=(9660srv) + mountmedia=(mount /srv/9660 /n/distmedia $disk) + case $fossil + echo 'srv fossil.mountdist' > /tmp/fossi.conf + echo 'fsys main config '^$disk >> /tmp/fossil.conf + echo 'fsys main open -AWVP' >> /tmp/fossil.conf + echo 'fsys main' >> /tmp/fossil.conf + srvmedia=(fossil/fossil -c '. /tmp/fossil.conf') + mountmedia=(mount /srv/fossil.mountdist /n/distmedia) + case * + echo Unknown disk type '(cannot happen)' + exit oops + } + export srvmedia mountmedia + domount + mountstatus=$status + } + + first=yes + dir=/ + while(~ $first yes || ! havedist /n/distmedia/$dir){ + if(~ $first yes){ + echo + echo Which directory contains the distribution? + echo 'Any of the following will suffice (in order of preference):' + echo ' - the root directory of the cd image' + echo ' - the directory containing plan9.iso' + echo ' - the directory containing plan9.iso.bz2' + echo 'Typing `browse'' will put you in a shell that you can use to' + echo 'look for the directory.' + echo + first=no + } + + prompt -d browse 'Location of archives' + dir=$rd + if(~ $dir browse){ + echo This is a simple shell. Commands are: + echo ' cd directory - change to directory' + echo ' lc - list contents of current directory' + echo ' exit - exit shell' + echo + echo 'Move to the directory containing the distribution' + echo 'and then exit.' + echo + oifs=$ifs + ifs=$nl + dir=`{cdsh -r /n/distmedia} + ifs=$oifs + } + if(~ $#dir 0) + dir=safdsfdsfdsf + if(! ~ $#dir 1) + dir=$"dir + if(! havedist /n/distmedia/$dir) + echo 'No distribution found in '^`{cleanname /$dir} + } + + distmediadir=$dir + export distmediadir + +case checkdone + if(! ~ $#distmediadir 1){ + mountdist=notdone + export mountdist + exit notdone + } + if(! havedist /n/distmedia/$distmediadir && ! havedist /n/newfs/dist){ + mountdist=notdone + export mountdist + exit notdone + } + + exitifdone + + if(test -f /n/distmedia/$distmediadir/dist/replica/plan9.db){ + bind /n/distmedia/$distmediadir /n/dist + bind -a /n/dist/386/bin /bin + bind -a /n/dist/rc/bin /bin + exitifdone + mountdist=notdone + export mountdist + exit notdone + } + + trycdimage /n/distmedia/$distmediadir/plan9.iso + trycdimage /n/newfs/dist/plan9.iso + + trycdimagebz2 /n/distmedia/$distmediadir/plan9.iso.bz2 + trycdimagebz2 /n/newfs/dist/plan9.iso.bz2 + + mountdist=notdone + export mountdist + exit notdone +} diff --git a/sys/lib/dist.old/pc/inst/mountfossil b/sys/lib/dist.old/pc/inst/mountfossil new file mode 100755 index 000000000..e98a3f48c --- /dev/null +++ b/sys/lib/dist.old/pc/inst/mountfossil @@ -0,0 +1,104 @@ +#!/bin/rc + +switch($1){ +case checkready checkdone + if(! ~ $fmtfossil done){ + mountfs=notdone + export mountfs + exit + } + if(! test -f /dev/sd*/fossil* && ! test -f /dev/fs/fossil*){ + mountfs=notdone + export mountfs + exit + } + if(! ~ $#fossil 1 || ! test -f $fossil){ + mountfs=ready + export mountfs + exit + } + if(! ps | grep -s ' fossil$'){ + echo 'srv -p fscons' > /env/fossilconf + echo 'srv -AP fossil' >> /env/fossilconf + fossil/conf $fossil | sed 's/^fsys main open .*/& -AWVP/' | + sed 's/^fsys main snaptime .*//' >> /env/fossilconf + if(! logprog fossil/fossil -c .' /env/fossilconf'>>[2]/srv/log){ + echo 'fossil: '^$status + mountfs=ready + export mountfs + exit oops + } + if(! test -f /srv/fossil){ + echo 'fossil did not create /srv/fossil' + mountfs=ready + exit oops + } + cat /srv/fscons >>/srv/log & + if(! logprog mount -c /srv/fossil /n/newfs){ + echo 'mount: '^$status + mountfs=ready + export mountfs + exit oops + } + fs=$fossil + export fs + } + if(! test -s /n/newfs/adm/users){ + echo fsys main create /active/adm adm sys d775 >>/srv/fscons + echo fsys main create /active/adm/users adm sys 664 >>/srv/fscons + echo uname upas :upas >>/srv/fscons + echo users -w >>/srv/fscons + sleep 2 + } + if(! test -s /n/newfs/adm/users){ + echo 'could not create /adm/users' + mountfs=ready + export mountfs + exit oops + } + for(i in dist dist/replica dist/replica/client){ + if(! test -d /n/newfs/$i) + echo fsys main create /active/$i sys sys d775 >>/srv/fscons + sleep 2 + } + if(! test -d /n/newfs/dist/replica/client){ + echo 'could not create /dist/replica/client' + mountfs=ready + export mountfs + exit oops + } + if(! test -e /n/newfs/dist/replica/client/plan9.db){ + echo fsys main create /active/dist/replica/client/plan9.db sys sys 664 >>/srv/fscons + echo fsys main create /active/dist/replica/client/plan9.log sys sys a664 >>/srv/fscons + } + if(test -d /n/newfs/dist/replica/client && test -f /n/newfs/adm/users){ + mountfs=done + export mountfs + exit + } + mountfs=ready + export mountfs + exit + +case go + echo 'The following partitions named fossil* were found.' + echo + echo 'Please choose one to use as the installation file system' + echo 'for your Plan 9 installation.' + echo + files=(`{ls /dev/sd*/fossil* /dev/fs/fossil* >[2]/dev/null}) + ls -l $files + echo + if(~ $#fossil 1 && ~ $fossil $files) + default=(-d $fossil) + if not if(~ $#files 1) + default=(-d $files) + if not + default=() + prompt $default 'Fossil partition' $files + slay fossil|rc + fossil=$rd + export fossil +} + + diff --git a/sys/lib/dist.old/pc/inst/mountfs b/sys/lib/dist.old/pc/inst/mountfs new file mode 100755 index 000000000..8aa9b16ff --- /dev/null +++ b/sys/lib/dist.old/pc/inst/mountfs @@ -0,0 +1,14 @@ +#!/bin/rc + +# desc: choose and mount file system partition +# prereq: configfs + +switch($fstype){ +case fossil fossil+venti + exec mountfossil $* +case * + mountfs=notdone + export mountfs + exit +} + diff --git a/sys/lib/dist.old/pc/inst/moveoldfs b/sys/lib/dist.old/pc/inst/moveoldfs new file mode 100755 index 000000000..819beeb39 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/moveoldfs @@ -0,0 +1,72 @@ +#!/bin/rc + +# desc: move an old third edition plan 9 file system out of the way +# prereq: mountfs + +rootfiles=(\ + 386\ + 68000\ + 68020\ + LICENSE\ + NOTICE\ + acme\ + adm\ + alpha\ + arm\ + cron\ + dist\ + fd\ + lib\ + lp\ + mail\ + mips\ + mnt\ + n\ + power\ + rc\ + sparc\ + sys\ + tmp\ + usr/glenda\ + wrap\ +) + +switch($1){ +case checkready + if(! test -d /n/kfs/wrap){ + moveoldfs=done + export moveoldfs + } + +case go + if(test -d /n/kfs/wrap){ + echo 'You have a Third Edition Plan 9 installation on '^$fs^'.' + echo 'We need to move the old file system out of the way (into /3e)' + echo 'in order to continue.' + echo + prompt 'Move old file system' y n + switch($rd){ + case y + kname=`{kfsname $fs} + log Moving old Plan 9 installation into /3e on kfs + logprog disk/kfscmd -n$kname 'create /3e sys sys 555 d' >>[2]/srv/log + logprog disk/kfscmd -n$kname 'create /3e/usr sys sys 555 d' >>[2]/srv/log + for(i in $rootfiles) + if(test -e /n/kfs/$i) + logprog disk/kfscmd -n$kname 'rename /'^$i^' /3e/'^$i + # copy extant /adm/users in case there have been modifications + logprog disk/kfscmd -n$kname 'create /adm adm adm 555 d' >>[2]/srv/log + logprog cp /n/kfs/3e/adm/users /n/kfs/adm/users >>[2]/srv/log + + case n + echo 'Okay, but we can''t continue.' + echo + } + } + +case checkdone + if(test -d /n/kfs/wrap){ + moveoldfs=notdone + export moveoldfs + } +} diff --git a/sys/lib/dist.old/pc/inst/partdisk b/sys/lib/dist.old/pc/inst/partdisk new file mode 100755 index 000000000..430d45f3f --- /dev/null +++ b/sys/lib/dist.old/pc/inst/partdisk @@ -0,0 +1,73 @@ +#!/bin/rc + +# desc: edit partition tables (e.g., to create a plan 9 partition) +# prereq: configfs + +switch($1){ +case go + disks=`{ls /dev/sd*/data >[2]/dev/null | sed 's!/dev/(sd..)/data!\1!'} + if(~ $#disks 0) { + echo 'No disk devices were found on your system.' + echo 'The installation process cannot continue.' + exit giveup + } + + echo 'The following disk devices were found.' + echo + for(i in $disks) { + desc=`{cat /dev/$i/ctl | sed 1q | sed 's/inquiry //'} + echo $i '-' $desc + echo e | disk/fdisk -r /dev/$i/data >[2]/dev/null | grep -v '^ mbr' + echo + } + + okay=no + defdisk=$disks(1) + + if(~ $#disks 1) + default=(-d $disks) + if not + default=() + prompt $default 'Disk to partition' $disks + disk=$rd + + if(! hasmbr /dev/$disk/data) { + echo 'The disk you selected HAS NO master boot record on its first sector.' + echo '(Perhaps it is a completely blank disk.)' + echo 'You need a master boot record to use the disk.' + echo 'Should we install a default master boot record?' + echo + prompt 'Install mbr' y n + switch($rd) { + case y + disk/mbr -m /386/mbr /dev/$disk/data + pickdisk=done + } + } + echo + echo 'This is disk/fdisk; use it to create a Plan 9 partition.' + echo 'If there is enough room, a Plan 9 partition will be' + echo 'suggested; you can probably just type ''w'' and then ''q''.' + echo + disk/fdisk -a /dev/$disk/data + disk/fdisk -p /dev/$disk/data >/dev/$disk/ctl >[2]/dev/null + for(i in /dev/sd*/plan9*){ + if(test -f $i){ + d=`{basename -d $i} + disk/prep -p $i >$d/ctl >[2]/dev/null + } + } + +case checkdone + # we want at least one disk with both an mbr and a plan9 partition + mbrandplan9=0 + disks=`{ls /dev/sd*/plan9 >[2]/dev/null | sed 's!/dev/(sd..)/plan9!\1!'} + for(disk in $disks) { + if(hasmbr /dev/$disk/data) + mbrandplan9=1 + } + if(~ $mbrandplan9 0){ + partdisk=notdone + export partdisk + } +} diff --git a/sys/lib/dist.old/pc/inst/prepdisk b/sys/lib/dist.old/pc/inst/prepdisk new file mode 100755 index 000000000..6ef4a92f8 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/prepdisk @@ -0,0 +1,63 @@ +#!/bin/rc + +# desc: subdivide plan 9 disk partition +# prereq: partdisk + +fn autotype { + if(~ $fstype fossil) + echo -a 9fat -a nvram -a fossil -a swap + if(~ $fstype fossil+venti) + echo -a 9fat -a nvram -a arenas -a isect -a fossil -a swap # -a other +} + +switch($1) { +case checkready + if(! test -f /dev/sd*/plan9*){ + prepdisk=notdone + export prepdisk + } + +case go + echo 'The following Plan 9 disk partitions were found.' + echo + disks=(/dev/sd*/plan9*) + for (i in $disks){ + echo $i + echo q | disk/prep -r $i >[2]/dev/null + echo + } + if(~ $#disks 1) + default=(-d $disks) + if not + default=() + prompt $default 'Plan 9 partition to subdivide' $disks + disk=$rd + + echo 'This is disk/prep; use it to subdivide the Plan 9 partition.' + echo 'If it is not yet subdivided, a sensible layout will be suggested;' + echo 'you can probably just type ''w'' and then ''q''.' + echo + disk/prep `{autotype} $disk + disk/prep -p $disk >`{basename -d $disk}^/ctl >[2]/dev/null + +case checkdone + if(! test -f /dev/sd*/9fat) + prepdisk=ready + + if(! ~ $prepdisk ready){ + prepdisk=done + switch($fstype){ + case fossil + if(! test -f /dev/sd*/fossil* && ! test -f /dev/fs/fossil*) + prepdisk=ready + case fossil+venti + if(! test -f /dev/sd*/fossil* && ! test -f /dev/fs/fossil*) + prepdisk=ready + if(! test -f /dev/sd*/arenas && ! test -f /dev/fs/arenas*) + prepdisk=ready + if(! test -f /dev/sd*/isect && ! test -f /dev/fs/isect*) + prepdisk=ready + } + } + export prepdisk +} diff --git a/sys/lib/dist.old/pc/inst/replcfg b/sys/lib/dist.old/pc/inst/replcfg new file mode 100755 index 000000000..30aed8607 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/replcfg @@ -0,0 +1,18 @@ +#!/bin/rc + +s=/n/dist/dist/replica +serverroot=/n/dist +serverlog=$s/plan9.log +serverproto=$s/plan9.proto +fn servermount { status='' } +fn serverupdate { status='' } + +fn clientmount { status='' } +c=/n/newfs/dist/replica +clientroot=/n/newfs +clientproto=$c/plan9.proto +clientdb=$c/client/plan9.db +clientexclude=(dist/replica/client) +clientlog=$c/client/plan9.log + +applyopt=(-t -u -T$c/client/plan9.time) diff --git a/sys/lib/dist.old/pc/inst/startether b/sys/lib/dist.old/pc/inst/startether new file mode 100755 index 000000000..077504c1a --- /dev/null +++ b/sys/lib/dist.old/pc/inst/startether @@ -0,0 +1,30 @@ +#!/bin/rc + +# desc: activate ethernet card +# prereq: configether + +switch($1) { +case checkready + if(isipdevup /net/ether0) { + startether=done + export startether + } + +case go + if(isipdevup /net/ether0) + exit + + log starting ethernet $ethermethod config + switch($ethermethod) { + case manual + ip/ipconfig -g $gwaddr ether /net/ether0 $ipaddr $ipmask >>[2]/srv/log + case dhcp + ip/ipconfig $dhcphost -D >>/srv/log >[2=1] + } + +case checkdone + if(! isipdevup /net/ether0) { + startether=notdone + export startether + } +} diff --git a/sys/lib/dist.old/pc/inst/startppp b/sys/lib/dist.old/pc/inst/startppp new file mode 100755 index 000000000..02bc090ef --- /dev/null +++ b/sys/lib/dist.old/pc/inst/startppp @@ -0,0 +1,30 @@ +#!/bin/rc + +# desc: activate ppp connection +# prereq: configppp + +switch($1) { +case checkready checkdone + if (isipdevup '^pkt[0-9]') + startppp=done + export startppp + +case go + if(isipdevup '^pkt[0-9]') + exit + + ctl=$pppdev^ctl + echo b115200 >$ctl + + switch($pppmethod) { + case manual + echo + echo 'Please dial the modem, and type ctl-d when PPP has started.' + echo 'You may need to type ctl-m to send modem commands.' + echo + ip/ppp -f -u -b b^$pppbaud -p /dev/^$pppdev + + case auto + ip/ppp -f -b b^$pppbaud -p /dev/^$pppdev -s $"pppuser:$"ppppasswd -t 'atdt'^$"pppphone + } +} diff --git a/sys/lib/dist.old/pc/inst/startwin b/sys/lib/dist.old/pc/inst/startwin new file mode 100755 index 000000000..bcd542890 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/startwin @@ -0,0 +1,46 @@ +#!/bin/rc + +fn time { date | sed 's/.........$//'} + +rm -f /srv/log + +if(~ $#* 2) { + wid=$1 + ht=$2 +} +if not { + scr=(`{cat /dev/draw/new >[2]/dev/null || status=''}) + wid=$scr(7) + ht=$scr(8) +} + +if(test $ht -gt 800) + ht=800 + +if(test $wid -gt 800) + wid=800 + +statwid=`{hoc -e $wid^'*.2'} +if(test $statwid -lt 180) + statwid=180 +if(test $statwid -gt 300) + statwid=300 + +logwid=`{hoc -e $wid^-$statwid} +if(test $logwid -gt 1000) + logwid=1000 + +loght=`{hoc -e $ht^'*.25'} +if(test $loght -lt 130) + loght=130 + +textht=`{hoc -e $ht^-$loght} + +window 0,$textht,$statwid,$ht stats -lmisce +window $statwid,$textht,^`{hoc -e $logwid+$statwid}^,$ht tailfsrv +window 0,0,^`{hoc -e $logwid+$statwid}^,$textht inst/mainloop + +while(! test -f /srv/log) + sleep 1 + +log `{time} Installation process started diff --git a/sys/lib/dist.old/pc/inst/stop b/sys/lib/dist.old/pc/inst/stop new file mode 100755 index 000000000..a1d48694f --- /dev/null +++ b/sys/lib/dist.old/pc/inst/stop @@ -0,0 +1,50 @@ +#!/bin/rc + +# desc: save the current installation state, to be resumed later +# prereq: +# mustdo: + +switch($1) { +case checkdone + stop=notdone + export stop + +case checkready + if(~ $cdboot yes){ + stop=notdone + export stop + } + +case go + coherence + switch($2){ + case finished + echo 'We need to write the state of the current installation to the install floppy,' + echo 'so that you can pick up from here if, for example, you want to set up' + echo 'more boot methods.' + echo + case * + echo 'We need to write the state of the current installation to the install floppy.' + echo 'so that you can pick up from here when you wish to continue.' + echo + } + echo -n 'Please make sure the install floppy is in the floppy drive and press enter.' + read >/dev/null >[2]/dev/null + + if(! a:) { + echo 'Couldn''t mount the floppy disk; sorry.' + exit + } + + if(cp /tmp/vars /n/a:/9inst.cnf || cp /tmp/vars /n/a:/9inst.cnf) { + echo 'Your install state has been saved to the install floppy.' + if(~ $2 finished){ + echo + echo 'Congratulations; you''ve completed the install.' + } + echo + halt + } + + echo 'Couldn''t save the state to your install floppy. Sorry.' +} diff --git a/sys/lib/dist.old/pc/inst/stopether b/sys/lib/dist.old/pc/inst/stopether new file mode 100755 index 000000000..59063f0e0 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/stopether @@ -0,0 +1,20 @@ +#!/bin/rc + +# desc: shut down the ethernet connection +# prereq: + + +switch($1) { +case checkready + if(! isipdevup /net/ether0) { + stopether=notdone + export stopether + } + +case go + ip/ipconfig ether /net/ether0 unbind + +case checkdone + stopether=notdone + export stopether +} diff --git a/sys/lib/dist.old/pc/inst/stopppp b/sys/lib/dist.old/pc/inst/stopppp new file mode 100755 index 000000000..70b9ce1fe --- /dev/null +++ b/sys/lib/dist.old/pc/inst/stopppp @@ -0,0 +1,19 @@ +#!/bin/rc + +# desc: shut down the ppp connection +# prereq: + +switch($1) { +case checkready + if(! ~ $#pppdev 1 || ! isipdevup '^pkt[0-9]') { + stopppp=notdone + export stopppp + } + +case go + kill ppp | rc + +case checkdone + stopppp=notdone + export stopppp +} diff --git a/sys/lib/dist.old/pc/inst/textonly b/sys/lib/dist.old/pc/inst/textonly new file mode 100755 index 000000000..1c3922ce4 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/textonly @@ -0,0 +1,15 @@ +#!/bin/rc + +# text-only install +cd /bin/inst +. defs + +textinst=1 +export textinst + +tailfsrv & +while(! test -f /srv/log) + sleep 1 +log `{date} Installation process started +inst/mainloop + diff --git a/sys/lib/dist.old/pc/inst/watchfd b/sys/lib/dist.old/pc/inst/watchfd new file mode 100755 index 000000000..ca37294e3 --- /dev/null +++ b/sys/lib/dist.old/pc/inst/watchfd @@ -0,0 +1,17 @@ +#!/bin/rc + +p=`{ps | grep $1 | sed 's/[^ ]* +([^ ]+) .*/\1/' } +while(! ~ $#p 1) { + sleep 1 + p=`{ps | grep $1 | sed 's/[^ ]* +([^ ]+) .*/\1/'} +} +p=$p(1) + +baropt='-w 145,129,445,168' +if(~ $textinst 1) + baropt=-t + +{ + while(test -f /proc/$p/fd) + grep '^ *'^$2^' ' /proc/$p/fd >[2]/dev/null +} | awk '{print $9 " '^$3^'"; fflush("/dev/stdout")}' | bargraph $baropt $4 diff --git a/sys/lib/dist.old/pc/inst/xxx b/sys/lib/dist.old/pc/inst/xxx new file mode 100755 index 000000000..56b4eb23a --- /dev/null +++ b/sys/lib/dist.old/pc/inst/xxx @@ -0,0 +1,9 @@ +#!/bin/rc + +ip/ipconfig +echo ' auth=204.178.31.3 + authdom=cs.bell-labs.com' >>/net/ndb +ndb/cs +auth/factotum +bind -a /bin/auth / +cpu -e clear -h tcp!204.178.31.2 diff --git a/sys/lib/dist.old/pc/mkfile b/sys/lib/dist.old/pc/mkfile new file mode 100644 index 000000000..43ee0b751 --- /dev/null +++ b/sys/lib/dist.old/pc/mkfile @@ -0,0 +1,100 @@ +out=outside # outside web server +s=/sys/lib/dist/pc +x=`{bind -b /sys/lib/dist/bin/$cputype /bin} +default:V: ndisk + ls -l ndisk + +SUB=`{ls sub inst} +boot.raw:Q: proto $SUB + rm -rf boot + mkdir boot + bind /dev/null /sys/log/timesync + # make files writable for now. + cat proto | sed 's!d000!d775!;s!000!664!;s!555!775!;s!444!664!' >proto.cp + disk/mkfs -a proto.cp | disk/mkext -d boot + @{ + cd boot/386 + strip init + cd bin + strip * */* >[2]/dev/null || status='' + } + cat proto | sed 's!/.*!!' >proto.cp + disk/mkfs -a -s boot proto.cp | tee >{wc -c >[1=2]} | + touchfs 1000000000 >boot.raw + +boot.bz2:Q: boot.raw + ls -l boot.raw + bflz -n 32 < boot.raw >boot.bflz + ls -l boot.bflz + bzip2 -9 < boot.bflz >$target + ls -l $target + +root.bz2:Q: boot.bz2 + { + echo bzfilesystem + cat boot.bz2 + dd -if /dev/zero -bs 1024 -count 1 >[2]/dev/null + } >$target + ls -l $target + +/sys/src/9/pc/9pcflop.gz: root.bz2 + @{ + rfork n + cd /sys/src/9/pc + mk 'CONF=pcflop' 9pcflop.gz + } + +/sys/src/9/pc/9pccd.gz: + @{ + cd /sys/src/9/pc + mk 'CONF=pccd' 9pccd.gz + } + +# disk/format apparently uses stat to obtain a file's real name, so +# binding 9loadusb onto 9load will store the name 9loadusb in the +# generated fat filesystem. the same is true for plan9.ini.cd and plan9.ini. + +9load: /386/9loadlite +# cp $prereq $target + if (test -e /386/9loadnousb) + cp /386/9loadnousb $target # cater to old bioses + cp /386/9loadlitedebug 9loaddebug + +ndisk: 9load /sys/src/9/pc/9pcflop.gz plan9.ini /lib/vgadb + dd -if /dev/zero -of ndisk -bs 1024 -count 1440 >[2]/dev/null + disk/format -f -b /386/pbs -d ndisk \ + 9load /sys/src/9/pc/9pcflop.gz plan9.ini /lib/vgadb + ls -l ndisk + +# cannot list both 9pcflop.gz and 9pccd.gz because they cannot be built +# in parallel. stupid mk +cddisk:DV: 9load /sys/src/9/pc/9pcflop.gz plan9.ini.cd /lib/vgadb + mk -a /sys/src/9/pc/9pccd.gz + mk -a /sys/src/9/pc/9pcflop.gz + rfork n + cp -x plan9.ini.cd subst/plan9.ini + dd -if /dev/zero -of cddisk -bs 1024 -count 2880 >[2]/dev/null + disk/format -t 3½QD -f -b /386/pbs -d cddisk \ + 9load /sys/src/9/pc/^(9pcflop.gz 9pccd.gz) \ + subst/plan9.ini /lib/vgadb + ls -l cddisk + +clean:V: + if (! unmount 9load >[2]/dev/null) + ; + rm -rf boot boot.bz2 boot.bflz boot.raw root.bz2 9pcflop ndisk 9load cddisk proto.cp 9loaddebug + +install:V: ndisk 9loaddebug + 9fs $out + dst=/n/$out/sys/lib/dist/web.protect + cp 9loaddebug $dst + gzip -9 < ndisk > $dst/plan9.flp.gz + # mk clean + +test:V: ndisk 9loaddebug + cp 9loaddebug ../web.protect2/n9loaddebug + cp ndisk ../web.protect2/ndisk + +cd0:D: cddisk + rm -f cd0 + disk/mk9660 -9cj -v 'Plan 9 4th Edition' -s . -p cd0.proto -b cddisk cd0 diff --git a/sys/lib/dist.old/pc/plan9.ini b/sys/lib/dist.old/pc/plan9.ini new file mode 100644 index 000000000..71f98e5e1 --- /dev/null +++ b/sys/lib/dist.old/pc/plan9.ini @@ -0,0 +1,37 @@ +# config for initial floppy booting + +[menu] +menuitem=boot, Boot Plan 9 +# menuitem=debug, Boot Plan 9 and debug 9load +menudefault=boot, 10 + +[common] +# very cautious settings to get started. +# will defeat booting from usb devices. +*nomp=1 +*nobiosload=1 +# *noahciload=1 +# *debugload=1 +*nodumpstack=1 +# this would disable ether and usb probing. +# *nousbprobe=1 +# *noetherprobe=1 +distname=plan9 +partition=new +mouseport=ask +monitor=ask +vgasize=ask +dmamode=ask +nobootprompt=local!/boot/bzroot +installurl=http://plan9.bell-labs.com/plan9/download/plan9.iso.bz2 +# serial console on COM1 +#console=0 + +[boot] +bootargs=local!#S/sdD0/data +bootfile=sdD0!cdboot!9pccd.gz + +# [debug] +# bootargs=local!#S/sdD0/data +# bootfile=sdD0!cdboot!9pccd.gz +# *debugload=1 diff --git a/sys/lib/dist.old/pc/plan9.ini.blank b/sys/lib/dist.old/pc/plan9.ini.blank new file mode 100644 index 000000000..be51a5dd4 --- /dev/null +++ b/sys/lib/dist.old/pc/plan9.ini.blank @@ -0,0 +1,10 @@ +THIS IS A 512 byte BLANK PLAN9.INI + + + + + + + + + diff --git a/sys/lib/dist.old/pc/plan9.ini.cd b/sys/lib/dist.old/pc/plan9.ini.cd new file mode 100644 index 000000000..11a2435ca --- /dev/null +++ b/sys/lib/dist.old/pc/plan9.ini.cd @@ -0,0 +1,40 @@ +# config for initial cd booting + +[menu] +menuitem=install, Install Plan 9 from this CD +menuitem=cdboot, Boot Plan 9 from this CD +# menuitem=debug, Boot Plan 9 from this CD and debug 9load + +[common] +# very cautious settings to get started. +# will defeat booting from usb devices. +*nomp=1 +*nobiosload=1 +# *noahciload=1 +# *debugload=1 +*nodumpstack=1 +# this would disable ether and usb probing. +# *nousbprobe=1 +# *noetherprobe=1 +partition=new +mouseport=ask +monitor=ask +vgasize=ask +dmamode=ask +adisk=/dev/sdD0/cdboot +cdboot=yes +# console=0 +# baud=9600 + +[install] +nobootprompt=local!/boot/bzroot +bootfile=sdD0!cdboot!9pcflop.gz + +[cdboot] +bootargs=local!#S/sdD0/data +bootfile=sdD0!cdboot!9pccd.gz + +# [debug] +# bootargs=local!#S/sdD0/data +# bootfile=sdD0!cdboot!9pccd.gz +# *debugload=1 diff --git a/sys/lib/dist.old/pc/plan9.ini.vmware b/sys/lib/dist.old/pc/plan9.ini.vmware new file mode 100644 index 000000000..dfee230ad --- /dev/null +++ b/sys/lib/dist.old/pc/plan9.ini.vmware @@ -0,0 +1,20 @@ +# config for initial vmware booting + +# very cautious settings to get started. +# will defeat booting from usb devices. +*nomp=1 +*nobiosload=1 +# *noahciload=1 +# *debugload=1 +# *nodumpstack=1 + +partition=new +nobootprompt=local!/boot/bzroot +bootfile=fd0!9pcflop.gz + +mouseport=ps2 +monitor=xga +vgasize=1024x768x16 +#adisk=/dev/sdD0/cdboot +console=0 +baud=9600 diff --git a/sys/lib/dist.old/pc/proto b/sys/lib/dist.old/pc/proto new file mode 100644 index 000000000..a12695d44 --- /dev/null +++ b/sys/lib/dist.old/pc/proto @@ -0,0 +1,175 @@ +386 d775 sys sys +# 9load 555 sys sys + init 555 sys sys +# ld.com 555 sys sys + mbr 555 sys sys + pbs 555 sys sys + pbslba 555 sys sys + bin d775 sys sys + auth d555 sys sys +# i think factotum is only needed if we include cpu +# factotum 555 sys sys + aux d555 sys sys + isvmware 555 sys sys + mouse 555 sys sys /sys/lib/dist/pc/multi/mouse + pcmcia 555 sys sys /sys/lib/dist/pc/multi/pcmcia + # stub 555 sys sys + vga 555 sys sys /sys/lib/dist/pc/multi/vga + vmware 555 sys sys /sys/lib/dist/pc/sub/vmware + # vmware 555 sys sys + # vmwarefs 555 sys sys + # vmmousepoll 555 sys sys + zerotrunc 555 sys sys /sys/lib/dist/pc/multi/zerotrunc + disk d555 sys sys + fdisk 555 sys sys /sys/lib/dist/pc/multi/fdisk + format 555 sys sys /sys/lib/dist/pc/multi/format +# kfs 555 sys sys +# kfscmd 555 sys sys + mbr 555 sys sys /sys/lib/dist/pc/multi/mbr + prep 555 sys sys /sys/lib/dist/pc/multi/prep + fossil d555 sys sys + fossil 555 sys sys + flfmt 555 sys sys + conf 555 sys sys + ip d555 sys sys + ipconfig 555 sys sys /sys/lib/dist/pc/multi/ipconfig + ppp 555 sys sys /sys/lib/dist/pc/multi/ppp + ndb d555 sys sys +# csquery and dnsquery could go + cs 555 sys sys /sys/lib/dist/pc/multi/cs +# csquery 555 sys sys + dns 555 sys sys /sys/lib/dist/pc/multi/dns +# dnsquery 555 sys sys + replica d555 sys sys + applylog 555 sys sys + changes 555 sys sys + compactdb 555 sys sys /sys/lib/dist/pc/sub/compactdb + pull 555 sys sys + venti d555 sys sys +# venti 555 sys sys +# conf 555 sys sys +# fmtarenas 555 sys sys +# fmtindex 555 sys sys +# fmtisect 555 sys sys + 9660srv 555 sys sys /sys/lib/dist/pc/multi/9660srv +# acme could go +# acme 555 sys sys + awk 555 sys sys + bargraph 555 sys sys /sys/lib/dist/bin/386/bargraph + basename 555 sys sys /sys/lib/dist/pc/multi/basename + cat 555 sys sys /sys/lib/dist/pc/multi/cat + chgrp 555 sys sys /sys/lib/dist/pc/multi/chgrp + chmod 555 sys sys /sys/lib/dist/pc/multi/chmod + cleanname 555 sys sys /sys/lib/dist/pc/multi/cleanname + cmp 555 sys sys /sys/lib/dist/pc/multi/cmp + cdsh 555 sys sys /sys/lib/dist/bin/386/cdsh + cp 555 sys sys /sys/lib/dist/pc/multi/cp +# cpu could go +# cpu 555 sys sys + date 555 sys sys /sys/lib/dist/pc/multi/date + dd 555 sys sys /sys/lib/dist/pc/multi/dd + dossrv 555 sys sys /sys/lib/dist/pc/multi/dossrv + echo 555 sys sys /sys/lib/dist/pc/multi/echo + ed 555 sys sys /sys/lib/dist/pc/multi/ed +# if cpu goes, exportfs could go +# exportfs 555 sys sys + ext2srv 555 sys sys /sys/lib/dist/pc/multi/ext2srv + fcp 555 sys sys + grep 555 sys sys /sys/lib/dist/pc/multi/grep + hget 555 sys sys /sys/lib/dist/pc/multi/hget + hoc 555 sys sys /sys/lib/dist/pc/multi/hoc + ls 555 sys sys /sys/lib/dist/pc/multi/ls + mc 555 sys sys /sys/lib/dist/pc/multi/mc + mount 555 sys sys /sys/lib/dist/pc/multi/mount + multi 555 sys sys /sys/lib/dist/bin/386/multi + mv 555 sys sys /sys/lib/dist/pc/multi/mv +# netkey 555 sys sys + ps 555 sys sys /sys/lib/dist/pc/multi/ps + rc 555 sys sys + read 555 sys sys /sys/lib/dist/pc/multi/read + rio 555 sys sys + rm 555 sys sys /sys/lib/dist/pc/multi/rm + sed 555 sys sys /sys/lib/dist/pc/multi/sed +# snoopy could go +# snoopy 555 sys sys + sort 555 sys sys /sys/lib/dist/pc/multi/sort + srv 555 sys sys /sys/lib/dist/pc/multi/srv +# ssh 555 sys sys + stats 555 sys sys + syscall 555 sys sys /sys/lib/dist/pc/multi/syscall + tail 555 sys sys /sys/lib/dist/pc/multi/tail + tailfsrv 555 sys sys /sys/lib/dist/bin/386/tailfsrv + tee 555 sys sys /sys/lib/dist/pc/multi/tee +# telnet 555 sys sys + test 555 sys sys /sys/lib/dist/pc/multi/test + wc 555 sys sys /sys/lib/dist/pc/multi/wc + xd 555 sys sys /sys/lib/dist/pc/multi/xd +adm d555 adm adm + timezone d555 sys sys + local 555 sys sys +lib d777 sys sys + font d555 sys sys + bit d555 sys sys + lucidasans d555 sys sys + lstr.12 444 sys sys + typelatin1.7.font 444 sys sys +# lucm d555 sys sys +# latin1.9 444 sys sys +# latin1.9.font 444 sys sys + namespace 444 sys sys + ndb d555 sys sys + common 444 sys sys /sys/lib/dist/pc/sub/common + local 444 sys sys /sys/lib/dist/pc/sub/local + vgadb 666 sys sys /dev/null +fd d555 sys sys +mnt d777 sys sys + arch d000 sys sys + temp d000 sys sys + vmware d000 sys sys + wsys d000 sys sys +n d777 sys sys + a: d000 sys sys + a d000 sys sys + c: d000 sys sys + c d000 sys sys + 9fat d000 sys sys + kremvax d000 sys sys /sys/lib/dist/pc/empty + newfs d000 sys sys + dist d000 sys sys /sys/lib/dist/pc/empty + distmedia d000 sys sys /sys/lib/dist/pc/empty +rc d555 sys sys + bin d775 sys sys + inst d775 sys sys /sys/lib/dist/pc/empty + + - sys sys /sys/lib/dist/pc/inst + 9fat: 555 sys sys + a: 555 sys sys /sys/lib/dist/pc/sub/a: + bind 555 sys sys /sys/lib/dist/pc/sub/bind + boota: 555 sys sys /sys/lib/dist/pc/sub/boota: + bunzip2 555 sys sys /sys/lib/dist/pc/sub/bunzip2 + c: 555 sys sys + dosmnt 555 sys sys + kill 555 sys sys + lc 555 sys sys + mkdir 555 sys sys /sys/lib/dist/pc/sub/mkdir + pci 555 sys sys + pwd 555 sys sys /sys/lib/dist/pc/sub/pwd + ramfs 555 sys sys /sys/lib/dist/pc/sub/ramfs + replica d555 sys sys + changes 555 sys sys + defs 555 sys sys + pull 555 sys sys + slay 555 sys sys + sleep 555 sys sys /sys/lib/dist/pc/sub/sleep + termrc 555 sys sys /sys/lib/dist/pc/sub/termrc + unmount 555 sys sys /sys/lib/dist/pc/sub/unmount + window 555 sys sys + lib d555 sys sys + rcmain 444 sys sys +sys d555 sys sys + log d555 sys sys + dns 444 sys sys /sys/lib/dist/pc/emptyfile + timesync 444 sys sys /sys/lib/dist/pc/emptyfile +tmp d555 sys sys +usr d555 sys sys + glenda d775 glenda glenda + + - glenda glenda /sys/lib/dist/pc/glenda diff --git a/sys/lib/dist.old/pc/sub/D003753 b/sys/lib/dist.old/pc/sub/D003753 new file mode 100755 index 000000000..8624d6ea1 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/D003753 @@ -0,0 +1,22 @@ +#!/bin/rc +if(! test -f /srv/dos) + dossrv >/dev/null [2]/dev/null +unmount /n/a:>[2]/dev/null + +if(~ $#adisk 1) + ; # do nothing +if not if(~ $#bootfile 0) + adisk=/dev/fd0disk +if not { + switch($bootfile) { + case sd* + adisk=`{echo $bootfile | sed 's#(sd..).*#/dev/\1/data#'} + case fd* + adisk=`{echo $bootfile | sed 's#(fd.).*#/dev/\1disk#'} + case * + echo 'unknown bootfile '^$bootfile^'; mail 9trouble@plan9.bell-labs.com' + exit oops + } +} + +mount -c /srv/dos /n/a: $adisk diff --git a/sys/lib/dist.old/pc/sub/F004116 b/sys/lib/dist.old/pc/sub/F004116 new file mode 100755 index 000000000..5f6809b3b --- /dev/null +++ b/sys/lib/dist.old/pc/sub/F004116 @@ -0,0 +1,24 @@ +#!/bin/rc + +rfork e +if(! test -f /srv/dos) + dossrv >/dev/null [2]/dev/null +unmount /n/a:>[2]/dev/null + +switch($bootfile) { +case sd*!cdboot!* + # just look for the right file. bootfile isn''t trustworthy + adisk=/dev/sd*/cdboot + if(! ~ $#adisk 1) + adisk=$adisk(1) +case sd* + adisk=`{echo $bootfile | sed 's#(sd..).*#/dev/\1/dos#'} +case fd* + adisk=`{echo $bootfile | sed 's#(fd.).*#/dev/\1disk#'} +case * + echo 'unknown bootfile '^$bootfile^'; mail 9trouble@plan9.bell-labs.com' + exit oops +} + +mount -c /srv/dos /n/a: $adisk + diff --git a/sys/lib/dist.old/pc/sub/bind b/sys/lib/dist.old/pc/sub/bind new file mode 100755 index 000000000..bc01455d7 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/bind @@ -0,0 +1,21 @@ +#!/bin/rc + +rfork e +flag=0 +while(~ $1 -*){ + switch($1){ + case -b + flag=1 + case -a + flag=2 + case -c + flag=4 + case -ac -ca + flag=6 + case -bc -cb + flag=5 + } + shift +} + +syscall bind $1 $2 $flag >[2]/dev/null diff --git a/sys/lib/dist.old/pc/sub/bunzip2 b/sys/lib/dist.old/pc/sub/bunzip2 new file mode 100755 index 000000000..0a876c6c2 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/bunzip2 @@ -0,0 +1,4 @@ +#!/bin/rc + +exec /boot/kfs BUNZIP +# kfs is bzfs \ No newline at end of file diff --git a/sys/lib/dist.old/pc/sub/common b/sys/lib/dist.old/pc/sub/common new file mode 100755 index 000000000..ec3e1bca2 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/common @@ -0,0 +1,123 @@ +# +# services +# +tcp=cs port=1 +tcp=echo port=7 +tcp=discard port=9 +tcp=systat port=11 +tcp=daytime port=13 +tcp=netstat port=15 +tcp=chargen port=19 +tcp=ftp-data port=20 +tcp=ftp port=21 +tcp=ssh port=22 +tcp=telnet port=23 +tcp=smtp port=25 +tcp=time port=37 +tcp=whois port=43 +tcp=domain port=53 +tcp=uucp port=64 +tcp=gopher port=70 +tcp=rje port=77 +tcp=finger port=79 +tcp=http port=80 +tcp=link port=87 +tcp=supdup port=95 +tcp=hostnames port=101 +tcp=iso-tsap port=102 +tcp=x400 port=103 +tcp=x400-snd port=104 +tcp=csnet-ns port=105 +tcp=pop-2 port=109 +tcp=pop3 port=110 +tcp=sunrpc port=111 +tcp=uucp-path port=117 +tcp=nntp port=119 +tcp=netbios port=139 +tcp=NeWS port=144 +tcp=print-srv port=170 +tcp=z39.50 port=210 +tcp=fsb port=400 +tcp=sysmon port=401 +tcp=proxy port=402 +tcp=proxyd port=404 +tcp=https port=443 +tcp=ssmtp port=465 +tcp=snntp port=563 +tcp=rexec port=512 restricted= +tcp=login port=513 restricted= +tcp=shell port=514 restricted= +tcp=printer port=515 +tcp=courier port=530 +tcp=cscan port=531 +tcp=uucp port=540 +tcp=9fs port=564 +tcp=whoami port=565 +tcp=guard port=566 +tcp=ticket port=567 +tcp=fmclient port=729 +tcp=ingreslock port=1524 +tcp=webster port=2627 +tcp=weather port=3000 +tcp=Xdisplay port=6000 +tcp=styx port=6666 +tcp=mpeg port=6667 +tcp=rstyx port=6668 +tcp=infdb port=6669 +tcp=infsigner port=6671 +tcp=infcsigner port=6672 +tcp=inflogin port=6673 +tcp=bandt port=7330 +tcp=face port=32000 +tcp=ocpu port=17005 +tcp=ocpunote port=17006 +tcp=exportfs port=17007 +tcp=rexexec port=17009 +tcp=ncpu port=17010 +tcp=ncpunote port=17011 +tcp=cpu port=17013 +tcp=video port=17028 +tcp=vgen port=17029 +tcp=alefnslook port=17030 +tcp=411 port=17031 +tcp=flyboy port=17032 + +il=echo port=7 +il=discard port=9 +il=chargen port=19 +il=whoami port=565 +il=ticket port=566 +il=challbox port=567 +il=ocpu port=17005 +il=ocpunote port=17006 +il=exportfs port=17007 +il=9fs port=17008 +il=rexexec port=17009 +il=ncpu port=17010 +il=ncpunote port=17011 +il=tcpu port=17012 +il=cpu port=17013 +il=fsauth port=17020 +il=rexauth port=17021 +il=changekey port=17022 +il=chal port=17023 +il=check port=17024 +il=juke port=17026 +il=video port=17028 +il=vgen port=17029 +il=alefnslook port=17030 +il=ramfs port=17031 + +udp=echo port=7 +udp=tacacs port=49 +udp=tftp port=69 +udp=bootpc port=68 +udp=bootp port=67 +udp=dns port=53 +udp=ntp port=123 +udp=rip port=520 +udp=bfs port=2201 +udp=virgil port=2202 +udp=bandt2 port=7331 + +gre=ppp port=34827 diff --git a/sys/lib/dist.old/pc/sub/compactdb b/sys/lib/dist.old/pc/sub/compactdb new file mode 100755 index 000000000..6033f7a0a --- /dev/null +++ b/sys/lib/dist.old/pc/sub/compactdb @@ -0,0 +1,4 @@ +#!/bin/rc + +exec cat $* + diff --git a/sys/lib/dist.old/pc/sub/local b/sys/lib/dist.old/pc/sub/local new file mode 100755 index 000000000..ec278a401 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/local @@ -0,0 +1,8 @@ + +# +# files comprising the database, use as many as you like +# +database= + file=/lib/ndb/local + file=/lib/ndb/common + diff --git a/sys/lib/dist.old/pc/sub/mkdir b/sys/lib/dist.old/pc/sub/mkdir new file mode 100755 index 000000000..b4452b9a9 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/mkdir @@ -0,0 +1,3 @@ +#!/bin/rc + +syscall create $1 0 020000000775 >[2]/dev/null diff --git a/sys/lib/dist.old/pc/sub/ndist b/sys/lib/dist.old/pc/sub/ndist new file mode 100755 index 000000000..2916986a1 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/ndist @@ -0,0 +1,16 @@ +#!/bin/rc + +s=/n/dist/dist/replica +serverroot=/n/dist +serverlog=$s/plan9.log +serverproto=$s/plan9.proto +fn servermount { status='' } +fn serverupdate { status='' } + +fn clientmount { status='' } +c=/n/kfs/dist/replica +clientroot=/n/kfs +clientproto=$c/plan9.proto +clientdb=$c/client/plan9.db +clientexclude=(dist/replica/client) +clientlog=$c/client/plan9.log diff --git a/sys/lib/dist.old/pc/sub/pci b/sys/lib/dist.old/pc/sub/pci new file mode 100755 index 000000000..c55d4b397 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/pci @@ -0,0 +1,5 @@ +#!/bin/rc + +rfork n +bind '#$' /mnt +cat /mnt/pci/*ctl diff --git a/sys/lib/dist.old/pc/sub/pwd b/sys/lib/dist.old/pc/sub/pwd new file mode 100755 index 000000000..f75568e7c --- /dev/null +++ b/sys/lib/dist.old/pc/sub/pwd @@ -0,0 +1,3 @@ +#!/bin/rc + +syscall -o fd2path 0 buf 1024 < . >[2]/dev/null diff --git a/sys/lib/dist.old/pc/sub/ramfs b/sys/lib/dist.old/pc/sub/ramfs new file mode 100755 index 000000000..285cd8717 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/ramfs @@ -0,0 +1,4 @@ +#!/bin/rc + +exec boot/kfs RAMFS $* +# kfs is bzfs diff --git a/sys/lib/dist.old/pc/sub/sleep b/sys/lib/dist.old/pc/sub/sleep new file mode 100755 index 000000000..07e6bb8be --- /dev/null +++ b/sys/lib/dist.old/pc/sub/sleep @@ -0,0 +1,8 @@ +#!/bin/rc + +if(! ~ $#* 1) { + echo 'usage: sleep n' >[1=2] + exit usage +} + +syscall sleep $1^000 >/dev/null >[2]/dev/null diff --git a/sys/lib/dist.old/pc/sub/termrc b/sys/lib/dist.old/pc/sub/termrc new file mode 100755 index 000000000..a194ee9b0 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/termrc @@ -0,0 +1,121 @@ +#!/bin/rc + +if(~ $#debug 1 && ~ $debug yes) + flag x + +if not + debug=0 + +if(~ $debug yes) echo env... +sysname=gnot +font=/lib/font/bit/lucidasans/typelatin1.7.font + +for (i in '#P' '#f' '#m' '#t' '#v') { + if(~ $debug yes) echo bind $i + bind -a $i /dev >/dev/null >[2=1] +} +if(~ $debug yes) echo binddev done + +for(disk in /dev/sd??) { + if(test -f $disk/data && test -f $disk/ctl){ + disk/fdisk -p $disk/data >$disk/ctl >[2]/dev/null +# if(~ $#nosddma 0) +# echo dma on >$disk/ctl +# if(~ $#nosdrwm 0) +# echo rwm on >$disk/ctl + } +} + +for (i in /sys/log/*) { + if(~ $debug yes) echo bind $i + bind /dev/null $i +} + +if(~ $debug yes) echo bindlog done + +bind -a '#l' /net >/dev/null >[2=1] + +dossrv +boota: +boota: # again, just in case a timeout made the earlier one fail +cp /n/a:/plan9.ini /tmp/plan9.orig +if(! ~ $cdboot yes){ + pci >/n/a:/pci.txt >[2]/dev/null + cp /dev/kmesg /n/a:/boot.txt >[2]/dev/null +} + +# restore a partial install +if(test -f /n/a:/9inst.cnf) + cp /n/a:/9inst.cnf /tmp/vars + +# make vgadb easier to edit +if(test -f /n/a:/vgadb) + cp /n/a:/vgadb /lib/vgadb + +aux/vmware + +# configure loopback device without touching /net/ndb +{ + echo bind loopback /dev/null + echo add 127.0.0.1 255.255.255.0 +} >/net/ipifc/clone + +if(~ $#dmamode 0) + dmamode=ask +if(~ $dmamode ask){ + echo -n 'use DMA for ide drives[yes]: ' + dmamode=`{read} + if(~ $#dmamode 0) + dmamode=yes +} +if(~ $dmamode yes) + for(i in /dev/sd*/ctl) + if(test -f $i) + {echo dma on; echo rwm on >[2]/dev/null} >$i + +if(~ $installmode ask){ + echo -n 'install mode is (text, graphics)[graphics]: ' + installmode=`{read} + if(~ $#installmode 0) + installmode=graphics +} +if(~ $installmode text){ + mouseport=() + vgasize=() + monitor=() +} +if not + installmode=graphics + +if(~ $mouseport ask){ + echo -n 'mouseport is (ps2, ps2intellimouse, 0, 1, 2)[ps2]: ' + mouseport=`{read} + if(~ $#mouseport 0) + mouseport=ps2 +} +if(~ $vgasize ask){ + echo -n 'vgasize [640x480x8]: ' + vgasize=`{read} + if(~ $#vgasize 0) + vgasize=640x480x8 +} +if(~ $monitor ask){ + echo -n 'monitor is [xga]: ' + monitor=`{read} + if(~ $#monitor 0) + monitor=xga +} +if(~ $#mouseport 1) { + aux/mouse $mouseport + if(~ $#vgasize 1 && ! ~ $vgasize '') { + vgasize=`{echo $vgasize} + if(! ~ $cdboot yes) + aux/vga -vip $vgasize >/n/a:/vgainfo.txt + sleep 2 # wait for floppy to finish + aux/vga -l $vgasize + if(! ~ $#novgaaccel 0) + echo -n 'hwaccel off' >'#v/vgactl' >[2]/dev/null + if(! ~ $#novgablank 0) + echo -n 'hwblank off' >'#v/vgactl' >[2]/dev/null + } +} + diff --git a/sys/lib/dist.old/pc/sub/unmount b/sys/lib/dist.old/pc/sub/unmount new file mode 100755 index 000000000..0c736afa6 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/unmount @@ -0,0 +1,3 @@ +#!/bin/rc + +syscall unmount 0 $1 >[2]/dev/null diff --git a/sys/lib/dist.old/pc/sub/users b/sys/lib/dist.old/pc/sub/users new file mode 100755 index 000000000..fd2edbe3d --- /dev/null +++ b/sys/lib/dist.old/pc/sub/users @@ -0,0 +1,7 @@ +-1:adm:adm: +0:none:none: +1:tor:tor: +2:glenda:glenda: +10000:sys:: +10001:upas:upas: +10002:bootes:bootes: diff --git a/sys/lib/dist.old/pc/sub/vmware b/sys/lib/dist.old/pc/sub/vmware new file mode 100755 index 000000000..8b398c972 --- /dev/null +++ b/sys/lib/dist.old/pc/sub/vmware @@ -0,0 +1,10 @@ +#!/bin/rc +# vmware - if we're running in a vmware virtual machine, tweak set up +if(aux/isvmware -s){ + echo hwaccel off >'#v/vgactl' + echo -n off >'#P/i8253timerset' + for (ctl in '#S'/sd[C-H]?/ctl) + if (test -e $ctl && grep -s '^config .* dma ' $ctl && + ! grep -s '^config (848A|.* dma 00000000 )' $ctl) + echo 'dma on' >$ctl +} diff --git a/sys/lib/dist.old/pc/subst/plan9.ini b/sys/lib/dist.old/pc/subst/plan9.ini new file mode 100644 index 000000000..11a2435ca --- /dev/null +++ b/sys/lib/dist.old/pc/subst/plan9.ini @@ -0,0 +1,40 @@ +# config for initial cd booting + +[menu] +menuitem=install, Install Plan 9 from this CD +menuitem=cdboot, Boot Plan 9 from this CD +# menuitem=debug, Boot Plan 9 from this CD and debug 9load + +[common] +# very cautious settings to get started. +# will defeat booting from usb devices. +*nomp=1 +*nobiosload=1 +# *noahciload=1 +# *debugload=1 +*nodumpstack=1 +# this would disable ether and usb probing. +# *nousbprobe=1 +# *noetherprobe=1 +partition=new +mouseport=ask +monitor=ask +vgasize=ask +dmamode=ask +adisk=/dev/sdD0/cdboot +cdboot=yes +# console=0 +# baud=9600 + +[install] +nobootprompt=local!/boot/bzroot +bootfile=sdD0!cdboot!9pcflop.gz + +[cdboot] +bootargs=local!#S/sdD0/data +bootfile=sdD0!cdboot!9pccd.gz + +# [debug] +# bootargs=local!#S/sdD0/data +# bootfile=sdD0!cdboot!9pccd.gz +# *debugload=1 diff --git a/sys/lib/dist/setup b/sys/lib/dist.old/setup old mode 100644 new mode 100755 similarity index 100% rename from sys/lib/dist/setup rename to sys/lib/dist.old/setup diff --git a/sys/lib/dist/mkfile b/sys/lib/dist/mkfile index 98dcd8fee..9fa156194 100644 --- a/sys/lib/dist/mkfile +++ b/sys/lib/dist/mkfile @@ -1,221 +1,21 @@ -# /sys/lib/dist/mkfile -src9=/n/sources/plan9 # what to export -dist=/sys/lib/dist # where this machinery lives -scr=/n/other/dist # scratch space before copying to web.protect -# import /sys/lib/dist/web.protect from the outside -x=`{setup} +src9=/n/src9 +scr=/tmp/dist + +x=`{mkdir -p $scr} cd:V: $scr/plan9.iso + +clean:V: + rm -rf $scr -ncd:V: $scr/plan9-new.iso.bz2 +$scr/cdstub:D: $src9/386/9bootiso + mkdir -p $target + cp $prereq $target + cp pc/plan9.ini.cd $target/plan9.ini -ncd-dist:V: $scr/plan9-new.iso.bz2 - mk $dist/web.protect/plan9-new.iso.bz2 - -cd-dist:V: $scr/plan9.iso.bz2 - mk $dist/web.protect/plan9.iso.bz2 - -contrib-cd:V: $scr/contrib.iso.bz2 - mk $dist/web.protect/contrib.iso.bz2 - -$scr/%.iso:D: $src9/dist/replica/plan9.log - @ { cd pc; mk cddisk } - rm -f $target - bind pc/cddisk cdstub/bootdisk.img - if(! test -f $src9/bootdisk.img) - bind -a cdstub $src9 - title=`{date | sed 's/(...) (...) (..) (..:..):.. (...) (....)/Plan 9 - \2 \3 \6 \4/'} - title=$"title - echo 'CD:' $title - disk/mk9660 -9cj -v $title -s $src9 -b bootdisk.img $target - -# copy compressed file from scratch space to the distribution, carefully -$dist/web.protect/%.iso.bz2: $scr/%.iso.bz2 - >>$target.new - chmod +t $target.new # waste write buf, not venti store - cp $prereq $target.new - # replace previous version with a flash cut - if (test -e $target) - mv $target $target.old # try to not clobber downloads in progress - mv $target.new $target - -cd-cleanup:V: - rm -f $dist/web.protect/*.iso.bz2.old # remove old versions after a delay - -# generate replica log & db for $src9 only -scan:V: - test -d $scr # make sure other was mounted above - test -d $src9 - test -d $dist/web.protect - lock scan.lock replica/scan $dist/sources.replica - chmod +t $src9/dist/replica/*.^(db log) - -# generate replica log & db for all of /n/sources -scanall:V: - @ { - rfork ne - d=/n/sources - test -d $src9 - lock scanall.lock replica/scan $dist/sourcesall.replica - chmod +t $src9/dist/replica/*.^(db log) - } - -compresslog:V: - { - awk -f logcompress.awk $src9/dist/replica/plan9.log | - awk -f logtime.awk -v 't='^`{date -n} >/tmp/plan9.log - rm -f $src9/dist/replica/plan9.new.log - cp /tmp/plan9.log $src9/dist/replica/plan9.new.log && - mv $src9/dist/replica/plan9.new.log $src9/dist/replica/plan9.log - } $src9/dist/replica/plan9.db -# chmod 664 $src9/dist/replica/plan9.log >$src9/dist/replica/plan9.log -# chmod +a $src9/dist/replica/plan9.log -# mk scan - -odump:V: - disk/dump9660 -9cj -v 'Plan 9 4e Dumps' -s $src9 \ - -p /sys/lib/sysconfig/proto/allproto $scr/distdump.iso - -cd.install:V: -# if(~ $sysname achille){ -# echo; echo; echo '*** run this on a real machine, like chips.' -# exit bad -# } - bzip2 -9 <$scr/plan9.iso >web.protect/nplan9.iso.bz2 - -D.install:V: - D=/n/roro/usr/rob/testplan9 - 9fs roro - test -d $D - cp $D$dist/pc/ndisk $dist/web.protect/ndisk - cp $D$dist/pc/9loaddebug $dist/web.protect/n9loaddebug - -reallyinstall:V: - if(! ~ $sysname achille){ - echo; echo; echo '*** this needs to run on achille.' - exit bad - } - cd web.protect - for (i in plan9.iso.bz2 disk 9loaddebug vmware.zip) - if(test -f n$i){ - mv $i _$i && { mv n$i $i || mv _$i $i } - } - rm /srv/ramfs.9down4e - $dist/startcache - -dump:V: - rm -f /srv/9660.xxx - 9660srv 9660.xxx - mount /srv/9660.xxx /n/kremvax $scr/plan9.iso - now=`{mtime $dist/web.protect/plan9.iso.bz2 | awk '{print $1}'} - ls -l /rls/plan9/4e.iso - disk/dump9660 -9cj -s /n/kremvax -n $now /rls/plan9/4e.iso - ls -l /rls/plan9/4e.iso - rm /srv/9660.xxx - -reencode:V: - rm -f $scr/nplan9.iso - rm -f /srv/9660.xxx - 9660srv 9660.xxx - mount /srv/9660.xxx /n/kremvax $scr/plan9.iso - disk/mk9660 -9cj -v 'Plan 9 4th Edition' -s /n/kremvax \ - -b bootdisk.img $scr/nplan9.iso - rm /srv/9660.xxx - -# compress a cd image in scratch space -$scr/%.iso.bz2:D: $scr/%.iso - @ { - cd $scr - bzip2 -9 <$stem.iso >n$stem.iso.bz2 && - { - if (test -e $stem.iso.bz2) - mv $stem.iso.bz2 _$stem.iso.bz2 - mv n$stem.iso.bz2 $stem.iso.bz2 - } - echo `{date} md5 `{md5sum <$stem.iso.bz2} \ - sha1 `{sha1sum <$stem.iso.bz2} \ - $stem.iso.bz2 >>/usr/web/plan9checksums.txt - } - -$scr/contrib.iso:DV: - rm -f $target - disk/mk9660 -9cj -v 'Plan 9 Extras' -s /n/sources \ - -p ./contrib.proto $target - -rebuild:V: - chmod +l build.lock >>build.lock - rebuild >build.lock - rebuild $target - -9-export:V: 9.tar.gz - 9fs sources - cp 9.tar.gz /n/sources/extra/9.tgz - chmod +t /n/sources/extra/9.tgz - -plan9.tar.bz2:V: - @{ - rfork n - 9fs sources - cd /n/sources - test -e $src9 - bind /n/empty $src9/lib/font - bind /n/empty $src9/sys/lib/postscript/font - bind /n/empty $src9/sys/lib/ghostscript - bind /n/empty $src9/sys/src/cmd/gs - tar c plan9/LICENSE* plan9/NOTICE plan9/*/mkfile plan9/*/include \ - plan9/acme/*/src plan9/acme/bin/source \ - plan9/^(adm cron lib lp mail rc sys tmp usr) - } | bzip2 >$target - -plan9-export:V: plan9.tar.bz2 - 9fs sources - chmod +t plan9.tar.bz2 - mv plan9.tar.bz2 /n/sources/extra/plan9.tar.bz2 +$scr/plan9.iso: $scr/cdstub + bind -a $src9 $scr/cdstub + bind /n/empty $scr/cdstub/.hg + disk/mk9660 -9cj -s $scr/cdstub -B 9bootiso $target + unmount $scr/cdstub/.hg + unmount $scr/cdstub diff --git a/sys/lib/dist/pc/plan9.ini b/sys/lib/dist/pc/plan9.ini index 71f98e5e1..c28f1ce43 100644 --- a/sys/lib/dist/pc/plan9.ini +++ b/sys/lib/dist/pc/plan9.ini @@ -1,15 +1,6 @@ -# config for initial floppy booting - -[menu] -menuitem=boot, Boot Plan 9 -# menuitem=debug, Boot Plan 9 and debug 9load -menudefault=boot, 10 - -[common] # very cautious settings to get started. # will defeat booting from usb devices. *nomp=1 -*nobiosload=1 # *noahciload=1 # *debugload=1 *nodumpstack=1 @@ -22,16 +13,7 @@ mouseport=ask monitor=ask vgasize=ask dmamode=ask -nobootprompt=local!/boot/bzroot -installurl=http://plan9.bell-labs.com/plan9/download/plan9.iso.bz2 # serial console on COM1 #console=0 - -[boot] bootargs=local!#S/sdD0/data -bootfile=sdD0!cdboot!9pccd.gz - -# [debug] -# bootargs=local!#S/sdD0/data -# bootfile=sdD0!cdboot!9pccd.gz -# *debugload=1 +bootfile=/386/9pccd diff --git a/sys/lib/dist/pc/plan9.ini.cd b/sys/lib/dist/pc/plan9.ini.cd index 11a2435ca..de8c1352f 100644 --- a/sys/lib/dist/pc/plan9.ini.cd +++ b/sys/lib/dist/pc/plan9.ini.cd @@ -1,15 +1,7 @@ # config for initial cd booting - -[menu] -menuitem=install, Install Plan 9 from this CD -menuitem=cdboot, Boot Plan 9 from this CD -# menuitem=debug, Boot Plan 9 from this CD and debug 9load - -[common] # very cautious settings to get started. # will defeat booting from usb devices. *nomp=1 -*nobiosload=1 # *noahciload=1 # *debugload=1 *nodumpstack=1 @@ -21,20 +13,9 @@ mouseport=ask monitor=ask vgasize=ask dmamode=ask -adisk=/dev/sdD0/cdboot +adisk=/dev/sdD0/data cdboot=yes # console=0 # baud=9600 - -[install] -nobootprompt=local!/boot/bzroot -bootfile=sdD0!cdboot!9pcflop.gz - -[cdboot] bootargs=local!#S/sdD0/data -bootfile=sdD0!cdboot!9pccd.gz - -# [debug] -# bootargs=local!#S/sdD0/data -# bootfile=sdD0!cdboot!9pccd.gz -# *debugload=1 +bootfile=/386/9pccd diff --git a/sys/src/boot/pc/iso.c b/sys/src/boot/pc/iso.c index 9f0d010aa..1d6bea2b7 100644 --- a/sys/src/boot/pc/iso.c +++ b/sys/src/boot/pc/iso.c @@ -71,7 +71,7 @@ close(void *f) static int isowalk(Extend *ex, int drive, char *path) { - char name[Maxpath], pad, *end; + char name[Maxpath], c, *end; int i; Dir d; @@ -97,8 +97,16 @@ isowalk(Extend *ex, int drive, char *path) break; i = d.dirlen - (Dirsz + d.namelen); while(i-- > 0) - read(ex, &pad, 1); - name[d.namelen] = 0; + read(ex, &c, 1); + for(i=0; i= 'A' && c <= 'Z'){ + c -= 'A'; + c += 'a'; + } + name[i] = c; + } + name[i] = 0; while(*path == '/') path++; if((end = strchr(path, '/')) == 0) diff --git a/sys/src/cmd/aux/mkfile b/sys/src/cmd/aux/mkfile index daf2213f6..471e26a92 100644 --- a/sys/src/cmd/aux/mkfile +++ b/sys/src/cmd/aux/mkfile @@ -51,7 +51,8 @@ DIRS=mnihongo\ flashfs\ gps\ na\ - vga + vga\ + realemu all:V: $DIRS diff --git a/sys/src/cmd/aux/realemu/arg.c b/sys/src/cmd/aux/realemu/arg.c new file mode 100644 index 000000000..4a67e864b --- /dev/null +++ b/sys/src/cmd/aux/realemu/arg.c @@ -0,0 +1,163 @@ +#include +#include +#include "dat.h" +#include "fns.h" + +#define ause(cpu) (cpu->abuf + (cpu->iabuf++ % nelem(cpu->abuf))) + +Iarg* +adup(Iarg *x) +{ + Iarg *a; + + a = ause(x->cpu); + *a = *x; + return a; +} + +Iarg* +areg(Cpu *cpu, uchar len, uchar reg) +{ + Iarg *a; + + a = ause(cpu); + a->cpu = cpu; + a->tag = TREG; + a->len = len; + a->reg = reg; + return a; +} + +Iarg* +amem(Cpu *cpu, uchar len, uchar sreg, ulong off) +{ + Iarg *a; + + a = ause(cpu); + a->cpu = cpu; + a->tag = TMEM; + a->len = len; + a->sreg = sreg; + a->seg = cpu->reg[sreg]; + a->off = off; + return a; +} + +Iarg* +afar(Iarg *mem, uchar len, uchar alen) +{ + Iarg *a, *p; + + p = adup(mem); + p->len = alen; + a = amem(mem->cpu, len, R0S, ar(p)); + p->off += alen; + p->len = 2; + a->seg = ar(p); + return a; +} + +Iarg* +acon(Cpu *cpu, uchar len, ulong val) +{ + Iarg *a; + + a = ause(cpu); + a->cpu = cpu; + a->tag = TCON; + a->len = len; + a->val = val; + return a; +} + +ulong +ar(Iarg *a) +{ + ulong w, o; + Bus *io; + + switch(a->tag){ + default: + abort(); + case TMEM: + o = ((a->seg<<4) + (a->off & 0xFFFF)) & 0xFFFFF; + io = a->cpu->mem + (o>>16); + w = io->r(io->aux, o, a->len); + break; + case TREG: + w = a->cpu->reg[a->reg]; + break; + case TREG|TH: + w = a->cpu->reg[a->reg] >> 8; + break; + case TCON: + w = a->val; + break; + } + switch(a->len){ + default: + abort(); + case 1: + w &= 0xFF; + break; + case 2: + w &= 0xFFFF; + break; + case 4: + break; + } + return w; +} + +long +ars(Iarg *a) +{ + ulong w = ar(a); + switch(a->len){ + default: + abort(); + case 1: + return (char)w; + case 2: + return (short)w; + case 4: + return (long)w; + } +} + +void +aw(Iarg *a, ulong w) +{ + ulong *p, o; + Cpu *cpu; + Bus *io; + + cpu = a->cpu; + switch(a->tag){ + default: + abort(); + case TMEM: + o = ((a->seg<<4) + (a->off & 0xFFFF)) & 0xFFFFF; + io = cpu->mem + (o>>16); + io->w(io->aux, o, w, a->len); + break; + case TREG: + p = cpu->reg + a->reg; + switch(a->len){ + case 4: + *p = w; + break; + case 2: + *p = (*p & ~0xFFFF) | (w & 0xFFFF); + break; + case 1: + *p = (*p & ~0xFF) | (w & 0xFF); + break; + } + break; + case TREG|TH: + p = cpu->reg + a->reg; + *p = (*p & ~0xFF00) | (w & 0xFF)<<8; + break; + } +} diff --git a/sys/src/cmd/aux/realemu/dat.h b/sys/src/cmd/aux/realemu/dat.h new file mode 100644 index 000000000..9c8ece20d --- /dev/null +++ b/sys/src/cmd/aux/realemu/dat.h @@ -0,0 +1,362 @@ +typedef struct Iarg Iarg; +typedef struct Inst Inst; +typedef struct Bus Bus; +typedef struct Cpu Cpu; +typedef struct Pit Pit; + +enum { + RAX, + RCX, + RDX, + RBX, + RSP, + RBP, + RSI, + RDI, + + RES, + RCS, + RSS, + RDS, + RFS, + RGS, + + R0S, /* 0 segment */ + + RIP, + RFL, + + NREG, +}; + +struct Iarg +{ + Cpu *cpu; + + uchar tag; + uchar len; + uchar atype; + + union { + uchar reg; + struct { + uchar sreg; + ulong seg, off; + }; + ulong val; + }; +}; + +struct Inst +{ + uchar op; + uchar code; + uchar olen; + uchar alen; + + Iarg *a1, *a2, *a3; + + uchar rep; + + uchar mod; + uchar reg; + uchar rm; + + uchar scale; + uchar index; + uchar base; + + uchar sreg; + uchar dsreg; + + ulong off; + long disp; +}; + +struct Bus +{ + void *aux; + ulong (*r)(void *aux, ulong off, int len); + void (*w)(void *aux, ulong off, ulong data, int len); +}; + +struct Cpu +{ + ulong reg[NREG]; + + /* instruction counter */ + ulong ic; + + /* mem[16], one entry for each 64k block */ + Bus *mem; + + /* port[1], in/out */ + Bus *port; + + int trap; + ulong oldip; + jmp_buf jmp; + + /* default operand, address and stack pointer length */ + uchar olen, alen, slen; + + /* argument buffers */ + ulong iabuf; + Iarg abuf[0x80]; +}; + +struct Pit +{ + ulong count; + + /* set by setgate(), cleared by clockpit() */ + uchar gateraised; + + /* signals */ + uchar gate; + uchar out; + + /* mode and flags */ + uchar count0; + + uchar bcd; + uchar amode; + uchar omode; + + /* latch for wpit initial count */ + uchar wcount; + uchar wlatched; + uchar wlatch[2]; + + /* latch for rpit status/count */ + uchar rcount; + uchar rlatched; + uchar rlatch[2]; +}; + +/* processor flags */ +enum { + CF = 1<<0, /* carry flag */ + PF = 1<<2, /* parity flag */ + AF = 1<<4, /* aux carry flag */ + ZF = 1<<6, /* zero flag */ + SF = 1<<7, /* sign flag */ + TF = 1<<8, /* trap flag */ + IF = 1<<9, /* interrupts enabled flag */ + DF = 1<<10, /* direction flag */ + OF = 1<<11, /* overflow flag */ + IOPL= 3<<12, /* I/O privelege level */ + NT = 1<<14, /* nested task */ + RF = 1<<16, /* resume flag */ + VM = 1<<17, /* virtual-8086 mode */ + AC = 1<<18, /* alignment check */ + VIF = 1<<19, /* virtual interrupt flag */ + VIP = 1<<20, /* virtual interrupt pending */ + ID = 1<<21, /* ID flag */ +}; + +/* interrupts/traps */ +enum { + EDIV0, + EDEBUG, + ENMI, + EBRK, + EINTO, + EBOUND, + EBADOP, + ENOFPU, + EDBLF, + EFPUSEG, + EBADTSS, + ENP, + ESTACK, + EGPF, + EPF, + + EHALT = 256, /* pseudo-interrupts */ + EMEM, + EIO, +}; + +/* argument tags */ +enum { + TREG, + TMEM, + TCON, + + TH = 0x80, /* special flag for AH,BH,CH,DH */ +}; + +/* argument types */ +enum { + ANONE, /* no argument */ + A0, /* constant 0 */ + A1, /* constant 1 */ + A2, /* constant 2 */ + A3, /* constant 3 */ + A4, /* constant 4 */ + AAp, /* 32-bit or 48-bit direct address */ + AEb, /* r/m8 from modrm byte */ + AEv, /* r/m16 or r/m32 from modrm byte */ + AEw, /* r/m16 */ + AFv, /* flag word */ + AGb, /* r8 from modrm byte */ + AGv, /* r16 or r32 from modrm byte */ + AGw, /* r/m16 */ + AIb, /* immediate byte */ + AIc, /* immediate byte sign-extended */ + AIw, /* immediate 16-bit word */ + AIv, /* immediate 16-bit or 32-bit word */ + AJb, /* relative offset byte */ + AJv, /* relative offset 16-bit or 32-bit word */ + AJr, /* r/m16 or r/m32 register */ + AM, /* memory address from modrm */ + AMa, /* something for bound */ + AMa2, + AMp, /* 32-bit or 48-bit memory address */ + AOb, /* immediate word-sized offset to a byte */ + AOv, /* immediate word-size offset to a word */ + ASw, /* segment register selected by r field of modrm */ + AXb, /* byte at DS:SI */ + AXv, /* word at DS:SI */ + AYb, /* byte at ES:DI */ + AYv, /* word at ES:DI */ + + AAL, + ACL, + ADL, + ABL, + AAH, + ACH, + ADH, + ABH, + + AAX, + ACX, + ADX, + ABX, + ASP, + ABP, + ASI, + ADI, + + AES, + ACS, + ASS, + ADS, + AFS, + AGS, + + NATYPE, +}; + +/* operators */ +enum { + OBAD, + O0F, + OAAA, + OAAD, + OAAM, + OAAS, + OADC, + OADD, + OAND, + OARPL, + OASIZE, + OBOUND, + OBT, + OBTS, + OBTR, + OBTC, + OBSF, + OBSR, + OCALL, + OCBW, + OCLC, + OCLD, + OCLI, + OCMC, + OCMOV, + OCMP, + OCMPS, + OCPUID, + OCWD, + ODAA, + ODAS, + ODEC, + ODIV, + OENTER, + OGP1, + OGP2, + OGP3b, + OGP3v, + OGP4, + OGP5, + OGP10, + OGP12, + OHLT, + OIDIV, + OIMUL, + OIN, + OINC, + OINS, + OINT, + OIRET, + OJUMP, + OLAHF, + OLEA, + OLEAVE, + OLFP, + OLOCK, + OLODS, + OLOOP, + OLOOPNZ, + OLOOPZ, + OMOV, + OMOVS, + OMOVZX, + OMOVSX, + OMUL, + ONEG, + ONOP, + ONOT, + OOR, + OOSIZE, + OOUT, + OOUTS, + OPOP, + OPOPA, + OPOPF, + OPUSH, + OPUSHA, + OPUSHF, + ORCL, + ORCR, + OREPE, + OREPNE, + ORET, + ORETF, + OROL, + OROR, + OSAHF, + OSAR, + OSBB, + OSCAS, + OSEG, + OSET, + OSHL, + OSHLD, + OSHR, + OSHRD, + OSTC, + OSTD, + OSTI, + OSTOS, + OSUB, + OTEST, + OWAIT, + OXCHG, + OXLAT, + OXOR, + NUMOP, +}; diff --git a/sys/src/cmd/aux/realemu/decode.c b/sys/src/cmd/aux/realemu/decode.c new file mode 100644 index 000000000..e2022a2a5 --- /dev/null +++ b/sys/src/cmd/aux/realemu/decode.c @@ -0,0 +1,619 @@ +#include +#include +#include "dat.h" +#include "fns.h" + +typedef struct Optab Optab; +struct Optab { + uchar op; + uchar a1, a2, a3; +}; + +static Optab optab[256] = { +//00 + {OADD, AEb, AGb}, {OADD, AEv, AGv}, {OADD, AGb, AEb}, {OADD, AGv, AEv}, + {OADD, AAL, AIb}, {OADD, AAX, AIv}, {OPUSH, AES, }, {OPOP, AES }, + {OOR, AEb, AGb}, {OOR, AEv, AGv}, {OOR, AGb, AEb}, {OOR, AGv, AEv}, + {OOR, AAL, AIb}, {OOR, AAX, AIv}, {OPUSH, ACS, }, {O0F, }, +//10 + {OADC, AEb, AGb}, {OADC, AEv, AGv}, {OADC, AGb, AEb}, {OADC, AGv, AEv}, + {OADC, AAL, AIb}, {OADC, AAX, AIv}, {OPUSH, ASS, }, {OPOP, ASS, }, + {OSBB, AEb, AGb}, {OSBB, AEv, AGv}, {OSBB, AGb, AEb}, {OSBB, AGv, AEv}, + {OSBB, AAL, AIb}, {OSBB, AAX, AIv}, {OPUSH, ADS, }, {OPOP, ADS, }, +//20 + {OAND, AEb, AGb}, {OAND, AEv, AGv}, {OAND, AGb, AEb}, {OAND, AGv, AEv}, + {OAND, AAL, AIb}, {OAND, AAX, AIv}, {OSEG, AES, }, {ODAA, }, + {OSUB, AEb, AGb}, {OSUB, AEv, AGv}, {OSUB, AGb, AEb}, {OSUB, AGv, AEv}, + {OSUB, AAL, AIb}, {OSUB, AAX, AIv}, {OSEG, ACS, }, {ODAS, }, +//30 + {OXOR, AEb, AGb}, {OXOR, AEv, AGv}, {OXOR, AGb, AEb}, {OXOR, AGv, AEv}, + {OXOR, AAL, AIb}, {OXOR, AAX, AIv}, {OSEG, ASS, }, {OAAA, }, + {OCMP, AEb, AGb}, {OCMP, AEv, AGv}, {OCMP, AGb, AEb}, {OCMP, AGv, AEv}, + {OCMP, AAL, AIb}, {OCMP, AAX, AIv}, {OSEG, ADS, }, {OAAS, }, +//40 + {OINC, AAX, }, {OINC, ACX, }, {OINC, ADX, }, {OINC, ABX, }, + {OINC, ASP, }, {OINC, ABP, }, {OINC, ASI, }, {OINC, ADI, }, + {ODEC, AAX, }, {ODEC, ACX, }, {ODEC, ADX, }, {ODEC, ABX, }, + {ODEC, ASP, }, {ODEC, ABP, }, {ODEC, ASI, }, {ODEC, ADI, }, +//50 + {OPUSH, AAX, }, {OPUSH, ACX, }, {OPUSH, ADX, }, {OPUSH, ABX, }, + {OPUSH, ASP, }, {OPUSH, ABP, }, {OPUSH, ASI, }, {OPUSH, ADI, }, + {OPOP, AAX, }, {OPOP, ACX, }, {OPOP, ADX, }, {OPOP, ABX, }, + {OPOP, ASP, }, {OPOP, ABP, }, {OPOP, ASI, }, {OPOP, ADI, }, +//60 + {OPUSHA, }, {OPOPA, }, {OBOUND,AGv,AMa,AMa2}, {OARPL, AEw, AGw}, + {OSEG, AFS, }, {OSEG, AGS, }, {OOSIZE, }, {OASIZE, }, + {OPUSH, AIv, }, {OIMUL,AGv,AEv,AIv},{OPUSH, AIb, }, {OIMUL,AGv,AEv,AIb}, + {OINS, AYb, ADX}, {OINS, AYv, ADX}, {OOUTS, ADX, AXb}, {OOUTS, ADX, AXv}, +//70 + {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, + {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, + {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, + {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, +//80 + {OGP1, AEb, AIb}, {OGP1, AEv, AIv}, {OGP1, AEb, AIb}, {OGP1, AEv, AIc}, + {OTEST, AEb, AGb}, {OTEST, AEv, AGv}, {OXCHG, AEb, AGb}, {OXCHG, AEv, AGv}, + {OMOV, AEb, AGb}, {OMOV, AEv, AGv}, {OMOV, AGb, AEb}, {OMOV, AGv, AEv}, + {OMOV, AEw, ASw}, {OLEA, AGv, AM }, {OMOV, ASw, AEw}, {OGP10, }, +//90 + {ONOP, }, {OXCHG, ACX, AAX}, {OXCHG, ADX, AAX}, {OXCHG, ABX, AAX}, + {OXCHG, ASP, AAX}, {OXCHG, ABP, AAX}, {OXCHG, ASI, AAX}, {OXCHG, ADI, AAX}, + {OCBW, }, {OCWD, }, {OCALL, AAp, }, {OWAIT, }, + {OPUSHF,AFv, }, {OPOPF, AFv, }, {OSAHF, AAH, }, {OLAHF, AAH, }, +//A0 + {OMOV, AAL, AOb}, {OMOV, AAX, AOv}, {OMOV, AOb, AAL}, {OMOV, AOv, AAX}, + {OMOVS, AYb, AXb}, {OMOVS, AYv, AXv}, {OCMPS, AYb, AXb}, {OCMPS, AYv, AXv}, + {OTEST, AAL, AIb}, {OTEST, AAX, AIv}, {OSTOS, AYb, AAL}, {OSTOS, AYv, AAX}, + {OLODS, AAL, AXb}, {OLODS, AAX, AXv}, {OSCAS, AYb, AAL}, {OSCAS, AYv, AAX}, +//B0 + {OMOV, AAL, AIb}, {OMOV, ACL, AIb}, {OMOV, ADL, AIb}, {OMOV, ABL, AIb}, + {OMOV, AAH, AIb}, {OMOV, ACH, AIb}, {OMOV, ADH, AIb}, {OMOV, ABH, AIb}, + {OMOV, AAX, AIv}, {OMOV, ACX, AIv}, {OMOV, ADX, AIv}, {OMOV, ABX, AIv}, + {OMOV, ASP, AIv}, {OMOV, ABP, AIv}, {OMOV, ASI, AIv}, {OMOV, ADI, AIv}, +//C0 + {OGP2, AEb, AIb}, {OGP2, AEv, AIb}, {ORET, AIw, }, {ORET, A0, }, + {OLFP,AES,AGv,AMp},{OLFP,ADS,AGv,AMp},{OGP12, AEb, AIb}, {OGP12, AEv, AIv}, + {OENTER,AIw, AIb}, {OLEAVE, }, {ORETF, AIw, }, {ORETF, A0, }, + {OINT, A3, }, {OINT, AIb, }, {OINT, A4, }, {OIRET, }, +//D0 + {OGP2, AEb, A1 }, {OGP2, AEv, A1 }, {OGP2, AEb, ACL}, {OGP2, AEv, ACL}, + {OAAM, AIb, }, {OAAD, AIb, }, {OBAD, }, {OXLAT, AAL, ABX}, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//E0 + {OLOOPNZ,AJb, }, {OLOOPZ,AJb, }, {OLOOP, AJb, }, {OJUMP, AJb, }, + {OIN, AAL, AIb}, {OIN, AAX, AIb}, {OOUT, AIb, AAL}, {OOUT, AIb, AAX}, + {OCALL, AJv, }, {OJUMP, AJv, }, {OJUMP, AAp, }, {OJUMP, AJb, }, + {OIN, AAL, ADX}, {OIN, AAX, ADX}, {OOUT, ADX, AAL}, {OOUT, ADX, AAX}, +//F0 + {OLOCK, }, {OBAD, }, {OREPNE, }, {OREPE, }, + {OHLT, }, {OCMC, }, {OGP3b, }, {OGP3v, }, + {OCLC, }, {OSTC, }, {OCLI, }, {OSTI, }, + {OCLD, }, {OSTD, }, {OGP4, }, {OGP5, }, +}; + +static Optab optab0F[256] = { +//00 + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//10 - mostly floating point and quadword moves + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//20 - doubleword <-> control register moves, other arcana + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//30 - wrmsr, rdtsc, rdmsr, rdpmc, sysenter, sysexit + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//40 - conditional moves + {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, + {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, + {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, + {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, +//50 - floating point, mmx stuff + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//60 - floating point, mmx stuff + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//70 - floating point, mmx stuff + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//80 - long-displacement jumps + {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, + {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, + {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, + {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, +//90 - conditional byte set + {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, + {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, + {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, + {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, +//A0 + {OPUSH, AFS, }, {OPOP, AFS, }, {OCPUID, }, {OBT, AEv, AGv}, + {OSHLD,AEv,AGv,AIb}, {OSHLD,AEv,AGv,ACL}, {OBAD, }, {OBAD, }, + {OPUSH, AGS, }, {OPOP, AGS, }, {OBAD, }, {OBTS, AEv, AGv}, + {OSHRD,AEv,AGv,AIb}, {OSHRD,AEv,AGv,ACL}, {OBAD, }, {OIMUL, AGv,AGv,AEv}, +//B0 - mostly arcana + {OBAD, }, {OBAD, }, {OLFP,ASS,AGv,AMp},{OBTR,AEv,AGv }, + {OLFP,AFS,AGv,AMp},{OLFP,AGS,AGv,AMp},{OMOVZX,AGv,AEb }, {OMOVZX,AGv,AEw }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBSF,AGv,AEv }, {OBSR,AGv,AEv }, {OMOVSX,AGv,AEb }, {OMOVSX,AGv,AEw }, +//C0 - more arcana + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//D0 - mmx + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//E0 - mmx + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +//F0 - mmx + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +}; + +/* some operands map to whole groups; group numbers from intel opcode map */ +/* args filled in already (in OGP1 entries) */ +static Optab optabgp1[8] = { + {OADD, }, {OOR, }, {OADC, }, {OSBB, }, + {OAND, }, {OSUB, }, {OXOR, }, {OCMP, }, +}; + +/* args filled in already (in OGP2 entries) */ +static Optab optabgp2[8] = { + {OROL, }, {OROR, }, {ORCL, }, {ORCR, }, + {OSHL, }, {OSHR, }, {OBAD, }, {OSAR, }, +}; + +static Optab optabgp3b[8] = { + {OTEST, AEb, AIb}, {OBAD, }, {ONOT, AEb, }, {ONEG, AEb, }, + {OMUL,AAX,AAL,AEb},{OIMUL,AAX,AAL,AEb},{ODIV, AEb, }, {OIDIV, AEb, }, +}; + +static Optab optabgp3v[8] = { + {OTEST, AEv, AIv}, {OBAD, }, {ONOT, AEv, }, {ONEG, AEv, }, + {OMUL,AAX,AAX,AEv},{OIMUL,AAX,AAX,AEv},{ODIV, AEv, }, {OIDIV, AEv, }, +}; + +static Optab optabgp4[8] = { + {OINC, AEb, }, {ODEC, AEb, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +}; + +static Optab optabgp5[8] = { + {OINC, AEv, }, {ODEC, AEv, }, {OCALL, AEv, }, {OCALL, AMp }, + {OJUMP, AEv, }, {OJUMP, AMp, }, {OPUSH, AEv, }, {OBAD, }, +}; + +static Optab optabgp10[8] = { + {OPOP, AEv, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +}; + +static Optab optabgp12[8] = { + {OMOV, }, {OBAD, }, {OBAD, }, {OBAD, }, + {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, }, +}; + +/* optabg6 unimplemented - mostly segment manipulation */ +/* optabg7 unimplemented - more segment manipulation */ +/* optabg8 unimplemented - bit tests */ + +/* + * most of optabg9 - optabg16 decode differently depending on the mod value of + * the modrm byte. they're mostly arcane instructions so they're not + * implemented. + */ + +static Optab *optabgp[NUMOP] = { + [OGP1] optabgp1, + [OGP2] optabgp2, + [OGP3b] optabgp3b, + [OGP3v] optabgp3v, + [OGP4] optabgp4, + [OGP5] optabgp5, + [OGP10] optabgp10, + [OGP12] optabgp12, +}; + +static uchar modrmarg[NATYPE] = { + [AEb] 1, + [AEw] 1, + [AEv] 1, + [AGb] 1, + [AGw] 1, + [AGv] 1, + [AM] 1, + [AMp] 1, + [AMa] 1, + [AMa2] 1, + [ASw] 1, + [AJr] 1, +}; + +static void +getmodrm16(Iarg *ip, Inst *i) +{ + Iarg *p; + uchar b; + + b = ar(ip); ip->off++; + + i->mod = b>>6; + i->reg = (b>>3)&7; + i->rm = b&7; + + if(i->mod == 3) + return; + + switch(i->rm){ + case 0: + i->off = ar(areg(ip->cpu, 2, RBX)) + ar(areg(ip->cpu, 2, RSI)); + i->off &= 0xFFFF; + break; + case 1: + i->off = ar(areg(ip->cpu, 2, RBX)) + ar(areg(ip->cpu, 2, RDI)); + i->off &= 0xFFFF; + break; + case 2: + i->dsreg = RSS; + i->off = ar(areg(ip->cpu, 2, RBP)) + ar(areg(ip->cpu, 2, RSI)); + i->off &= 0xFFFF; + break; + case 3: + i->dsreg = RSS; + i->off = ar(areg(ip->cpu, 2, RBP)) + ar(areg(ip->cpu, 2, RDI)); + i->off &= 0xFFFF; + break; + case 4: + i->off = ar(areg(ip->cpu, 2, RSI)); + break; + case 5: + i->off = ar(areg(ip->cpu, 2, RDI)); + break; + case 6: + if(i->mod == 0){ + p = adup(ip); ip->off += 2; + p->len = 2; + i->off = ar(p); + return; + } + i->dsreg = RSS; + i->off = ar(areg(ip->cpu, 2, RBP)); + break; + case 7: + i->off = ar(areg(ip->cpu, 2, RBX)); + break; + } + switch(i->mod){ + case 1: + i->off += (i->disp = ars(ip)); ip->off++; + i->off &= 0xFFFF; + break; + case 2: + p = adup(ip); ip->off += 2; + p->len = 2; + i->off += (i->disp = ars(p)); + i->off &= 0xFFFF; + break; + } +} + +static void +getmodrm32(Iarg *ip, Inst *i) +{ + static uchar scaler[] = {1, 2, 4, 8}; + Iarg *p; + uchar b; + + b = ar(ip); ip->off++; + + i->mod = b>>6; + i->reg = (b>>3)&7; + i->rm = b&7; + + if(i->mod == 3) + return; + + switch(i->rm){ + case 0: + case 1: + case 2: + case 3: + case 6: + case 7: + i->off = ar(areg(ip->cpu, 4, i->rm + RAX)); + break; + case 4: + b = ar(ip); i->off++; + i->scale = b>>6; + i->index = (b>>3)&7; + i->base = b&7; + + if(i->base != 5){ + i->off = ar(areg(ip->cpu, 4, i->base + RAX)); + break; + } + case 5: + if(i->mod == 0){ + p = adup(ip); ip->off += 4; + p->len = 4; + i->off = ar(p); + } else { + i->dsreg = RSS; + i->off = ar(areg(ip->cpu, 4, RBP)); + } + break; + } + + if(i->rm == 4 && i->index != 4) + i->off += ar(areg(ip->cpu, 4, i->index + RAX)) * scaler[i->scale]; + + switch(i->mod){ + case 1: + i->off += (i->disp = ars(ip)); ip->off++; + break; + case 2: + p = adup(ip); ip->off += 4; + p->len = 4; + i->off += (i->disp = ars(p)); + break; + } +} + +static Iarg* +getarg(Iarg *ip, Inst *i, uchar atype) +{ + Iarg *a; + uchar len, reg; + + len = i->olen; + switch(atype){ + default: + abort(); + + case A0: + case A1: + case A2: + case A3: + case A4: + a = acon(ip->cpu, len, atype - A0); + break; + + case AEb: + len = 1; + if(0){ + case AEw: + len = 2; + } + case AEv: + if(i->mod == 3){ + reg = i->rm; + goto REG; + } + goto MEM; + + case AM: + case AMp: + case AMa: + case AMa2: + if(i->mod == 3) + trap(ip->cpu, EBADOP); + MEM: + a = amem(ip->cpu, len, i->sreg, i->off); + if(atype == AMa2) + a->off += i->olen; + break; + + case AGb: + len = 1; + if(0){ + case AGw: + len = 2; + } + case AGv: + reg = i->reg; + REG: + a = areg(ip->cpu, len, reg + RAX); + if(len == 1 && reg >= 4){ + a->reg -= 4; + a->tag |= TH; + } + break; + + case AIb: + case AIc: + len = 1; + if(0){ + case AIw: + len = 2; + } + case AIv: + a = adup(ip); ip->off += len; + a->len = len; + break; + + case AJb: + len = 1; + case AJv: + a = adup(ip); ip->off += len; + a->len = len; + a->off = ip->off + ars(a); + break; + + case AJr: + if(i->mod != 3) + trap(ip->cpu, EBADOP); + a = adup(ip); + a->off = ar(areg(ip->cpu, i->olen, i->rm + RAX)); + break; + + case AAp: + a = afar(ip, ip->len, len); ip->off += 2+len; + break; + + case AOb: + len = 1; + case AOv: + a = adup(ip); ip->off += i->alen; + a->len = i->alen; + a = amem(ip->cpu, len, i->sreg, ar(a)); + break; + + case ASw: + reg = i->reg; + SREG: + a = areg(ip->cpu, 2, reg + RES); + break; + + case AXb: + len = 1; + case AXv: + a = amem(ip->cpu, len, i->sreg, ar(areg(ip->cpu, i->alen, RSI))); + break; + + case AYb: + len = 1; + case AYv: + a = amem(ip->cpu, len, RES, ar(areg(ip->cpu, i->alen, RDI))); + break; + + case AFv: + a = areg(ip->cpu, len, RFL); + break; + + case AAL: + case ACL: + case ADL: + case ABL: + case AAH: + case ACH: + case ADH: + case ABH: + len = 1; + reg = atype - AAL; + goto REG; + + case AAX: + case ACX: + case ADX: + case ABX: + case ASP: + case ABP: + case ASI: + case ADI: + reg = atype - AAX; + goto REG; + + case AES: + case ACS: + case ASS: + case ADS: + case AFS: + case AGS: + reg = atype - AES; + goto SREG; + } + a->atype = atype; + return a; +} + +static int +otherlen(int a) +{ + if(a == 2) + return 4; + else if(a == 4) + return 2; + abort(); + return 0; +} + +void +decode(Iarg *ip, Inst *i) +{ + Optab *t, *t2; + Cpu *cpu; + + cpu = ip->cpu; + + i->op = 0; + i->rep = 0; + i->sreg = 0; + i->dsreg = RDS; + i->olen = cpu->olen; + i->alen = cpu->alen; + + for(;;){ + i->code = ar(ip); ip->off++; + t = optab + i->code; + switch(t->op){ + case OOSIZE: + i->olen = otherlen(cpu->olen); + continue; + case OASIZE: + i->alen = otherlen(cpu->alen); + continue; + case OREPE: + case OREPNE: + i->rep = t->op; + continue; + case OLOCK: + continue; + case OSEG: + i->sreg = t->a1-AES+RES; + continue; + case O0F: + i->code = ar(ip); ip->off++; + t = optab0F + i->code; + break; + } + break; + } + t2 = optabgp[t->op]; + if(t2 || modrmarg[t->a1] || modrmarg[t->a2] || modrmarg[t->a3]) + if(i->alen == 2) + getmodrm16(ip, i); + else + getmodrm32(ip, i); + if(i->sreg == 0) + i->sreg = i->dsreg; + + i->a1 = i->a2 = i->a3 = nil; + for(;;){ + if(t->a1) + i->a1 = getarg(ip, i, t->a1); + if(t->a2) + i->a2 = getarg(ip, i, t->a2); + if(t->a3) + i->a3 = getarg(ip, i, t->a3); + if(t2 == nil) + break; + t = t2 + i->reg; + t2 = nil; + } + i->op = t->op; +} diff --git a/sys/src/cmd/aux/realemu/fmt.c b/sys/src/cmd/aux/realemu/fmt.c new file mode 100644 index 000000000..8d65fe959 --- /dev/null +++ b/sys/src/cmd/aux/realemu/fmt.c @@ -0,0 +1,385 @@ +#include +#include +#include "dat.h" +#include "fns.h" + +static char *opstr[] = { /* Edit s/O(.*),/[O\1]= "\1",/g */ + [OBAD]= "BAD", + [O0F]= "0F", + [OAAA]= "AAA", + [OAAD]= "AAD", + [OAAM]= "AAM", + [OAAS]= "AAS", + [OADC]= "ADC", + [OADD]= "ADD", + [OAND]= "AND", + [OARPL]= "ARPL", + [OASIZE]= "ASIZE", + [OBOUND]= "BOUND", + [OBT]= "BT", + [OBTC]= "BTC", + [OBTR]= "BTR", + [OBTS]= "BTS", + [OBSF]= "BSF", + [OBSR]= "BSR", + [OCALL]= "CALL", + [OCBW]= "CBW", + [OCLC]= "CLC", + [OCLD]= "CLD", + [OCLI]= "CLI", + [OCMC]= "CMC", + [OCMOV]= "CMOV", + [OCMP]= "CMP", + [OCMPS]= "CMPS", + [OCWD]= "CWD", + [ODAA]= "DAA", + [ODAS]= "DAS", + [ODEC]= "DEC", + [ODIV]= "DIV", + [OENTER]= "ENTER", + [OGP1]= "GP1", + [OGP2]= "GP2", + [OGP3b]= "GP3b", + [OGP3v]= "GP3v", + [OGP4]= "GP4", + [OGP5]= "GP5", + [OHLT]= "HLT", + [OIDIV]= "IDIV", + [OIMUL]= "IMUL", + [OIN]= "IN", + [OINC]= "INC", + [OINS]= "INS", + [OINT]= "INT", + [OIRET]= "IRET", + [OJUMP]= "JUMP", + [OLAHF]= "LAHF", + [OLFP]= "LFP", + [OLEA]= "LEA", + [OLEAVE]= "LEAVE", + [OLOCK]= "LOCK", + [OLODS]= "LODS", + [OLOOP]= "LOOP", + [OLOOPNZ]= "LOOPNZ", + [OLOOPZ]= "LOOPZ", + [OMOV]= "MOV", + [OMOVS]= "MOVS", + [OMOVZX]= "MOVZX", + [OMOVSX]= "MOVSX", + [OMUL]= "MUL", + [ONEG]= "NEG", + [ONOP]= "NOP", + [ONOT]= "NOT", + [OOR]= "OR", + [OOSIZE]= "OSIZE", + [OOUT]= "OUT", + [OOUTS]= "OUTS", + [OPOP]= "POP", + [OPOPA]= "POPA", + [OPOPF]= "POPF", + [OPUSH]= "PUSH", + [OPUSHA]= "PUSHA", + [OPUSHF]= "PUSHF", + [ORCL]= "RCL", + [ORCR]= "RCR", + [OREPE]= "REPE", + [OREPNE]= "REPNE", + [ORET]= "RET", + [ORETF]= "RETF", + [OROL]= "ROL", + [OROR]= "ROR", + [OSAHF]= "SAHF", + [OSAR]= "SAR", + [OSBB]= "SBB", + [OSCAS]= "SCAS", + [OSEG]= "SEG", + [OSET]= "SET", + [OSHL]= "SHL", + [OSHLD]= "SHLD", + [OSHR]= "SHR", + [OSHRD]= "SHRD", + [OSTC]= "STC", + [OSTD]= "STD", + [OSTI]= "STI", + [OSTOS]= "STOS", + [OSUB]= "SUB", + [OTEST]= "TEST", + [OWAIT]= "WAIT", + [OXCHG]= "XCHG", + [OXLAT]= "XLAT", + [OXOR]= "XOR", +}; + +static char *memstr16[] = { + "BX+SI", + "BX+DI", + "BP+SI", + "BP+DI", + "SI", + "DI", + "BP", + "BX", +}; + +static char *memstr32[] = { + "EAX", + "ECX", + "EDX", + "EBX", + "0", + "EBP", + "ESI", + "EDI", +}; + +static int +argconv(char *p, Inst *i, Iarg *a) +{ + jmp_buf jmp; + char *s; + + s = p; + switch(a->tag){ + default: + abort(); + + case TCON: + return sprint(p, "%lud", a->val); + case TREG: + case TREG|TH: + switch(a->len){ + case 1: + return sprint(p, "%c%c", "ACDB"[a->reg], "LH"[(a->tag & TH) != 0]); + case 4: + *p++ = 'E'; + case 2: + p += sprint(p, "%c%c", + "ACDBSBSDECSDFGIF"[a->reg], + "XXXXPPIISSSSSSPL"[a->reg]); + return p - s; + } + case TMEM: + break; + } + + /* setup trap jump in case we dereference bad memory */ + memmove(jmp, a->cpu->jmp, sizeof jmp); + if(setjmp(a->cpu->jmp)){ + p += sprint(p, "<%.4lux:%.4lux>", a->seg, a->off); + goto out; + } + + switch(a->atype){ + default: + abort(); + + case AAp: + p += sprint(p, "[%.4lux:%.4lux]", a->seg, a->off); + break; + + case AJb: + case AJv: + p += sprint(p, "[%.4lux]", a->off); + break; + + case AIc: + p += sprint(p, "$%.2lx", ars(a)); + break; + case AIb: + case AIw: + case AIv: + p += sprint(p, "$%.*lux", (int)a->len*2, ar(a)); + break; + + case AMp: + *p++ = '*'; + case AEb: + case AEw: + case AEv: + case AM: + case AMa: + case AMa2: + case AOb: + case AOv: + if(i->sreg != RDS) + p += sprint(p, "%cS:", "ECSDFG"[i->sreg - RES]); + if(a->atype == AOb || a->atype == AOv || (i->mod == 0 && + (i->alen == 2 && i->rm == 6) || + (i->alen == 4 && ((i->rm == 5) || + (i->rm == 4 && i->index == 4 && i->base == 5))))){ + p += sprint(p, "[%.*lux]", (int)i->alen*2, a->off); + break; + } + *p++ = '['; + if(i->alen == 2) + p += sprint(p, "%s", memstr16[i->rm]); + else{ + if(i->rm == 4){ + if(i->index != 4) + p += sprint(p, "%c*%s+", "1248"[i->scale], memstr32[i->index]); + if(i->base != 5) + p += sprint(p, "%s", memstr32[i->base]); + else{ + if(i->mod == 0) + p += sprint(p, "%.4lux", i->off); + else + p += sprint(p, "EBP"); + } + } else + p += sprint(p, "%s", memstr32[i->rm]); + } + if(i->mod != 0) + p += sprint(p, "%+lx", i->disp); + *p++ = ']'; + break; + + case AXb: + case AXv: + if(a->sreg != RDS) + p += sprint(p, "%cS:", "ECSDFG"[a->sreg - RES]); + p += sprint(p, "[SI]"); + break; + case AYb: + case AYv: + if(a->sreg != RDS) + p += sprint(p, "%cS:", "ECSDFG"[a->sreg - RES]); + p += sprint(p, "[DI]"); + break; + } + +out: + memmove(a->cpu->jmp, jmp, sizeof jmp); + *p = 0; + return p - s; +} + +static char *jmpstr[] = { + "JO", "JNO", "JC", "JNC", "JZ", "JNZ", "JBE", "JA", + "JS", "JNS", "JP", "JNP", "JL", "JGE", "JLE", "JG", +}; + +int +instfmt(Fmt *fmt) +{ + Inst *i; + char *p, buf[256]; + + i = va_arg(fmt->args, Inst*); + p = buf; + + if(i->olen == 4) + p += sprint(p, "O32: "); + if(i->alen == 4) + p += sprint(p, "A32: "); + if(i->rep) + p += sprint(p, "%s: ", opstr[i->rep]); + + if(i->op == OXLAT && i->sreg != RDS) + p += sprint(p, "%cS:", "ECSDFG"[i->sreg - RES]); + + if(i->op == OJUMP){ + switch(i->code){ + case 0xE3: + p += sprint(p, "%s ", "JCXZ"); + break; + case 0xEB: + case 0xE9: + case 0xEA: + case 0xFF: + p += sprint(p, "%s ", "JMP"); + break; + default: + p += sprint(p, "%s ", jmpstr[i->code&0xF]); + break; + } + } else + p += sprint(p, "%s ", opstr[i->op]); + + + for(;;){ + if(i->a1 == nil) + break; + p += argconv(p, i, i->a1); + if(i->a2 == nil) + break; + *p++ = ','; + *p++ = ' '; + p += argconv(p, i, i->a2); + if(i->a3 == nil) + break; + *p++ = ','; + *p++ = ' '; + p += argconv(p, i, i->a3); + break; + } + *p = 0; + fmtstrcpy(fmt, buf); + return 0; +} + +int +flagfmt(Fmt *fmt) +{ + char buf[16]; + ulong f; + + f = va_arg(fmt->args, ulong); + sprint(buf, "%c%c%c%c%c%c%c", + (f & CF) ? 'C' : 'c', + (f & SF) ? 'S' : 's', + (f & ZF) ? 'Z' : 'z', + (f & OF) ? 'O' : 'o', + (f & PF) ? 'P' : 'p', + (f & DF) ? 'D' : 'd', + (f & IF) ? 'I' : 'i'); + fmtstrcpy(fmt, buf); + return 0; +} + +int +cpufmt(Fmt *fmt) +{ + char buf[512]; + jmp_buf jmp; + Cpu *cpu; + Inst i; + + cpu = va_arg(fmt->args, Cpu*); + + memmove(jmp, cpu->jmp, sizeof jmp); + if(setjmp(cpu->jmp) == 0) + decode(amem(cpu, 1, RCS, cpu->reg[RIP]), &i); + memmove(cpu->jmp, jmp, sizeof jmp); + + snprint(buf, sizeof(buf), + "%.6lux " + "%.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux " + "%.4lux %.4lux %.4lux %.4lux " + "%J %.4lux %.2ux %I", + + cpu->ic, + + cpu->reg[RAX], + cpu->reg[RBX], + cpu->reg[RCX], + cpu->reg[RDX], + + cpu->reg[RDI], + cpu->reg[RSI], + + cpu->reg[RBP], + cpu->reg[RSP], + + cpu->reg[RDS], + cpu->reg[RES], + cpu->reg[RSS], + cpu->reg[RCS], + + cpu->reg[RFL], + cpu->reg[RIP], + + i.code, + &i); + + fmtstrcpy(fmt, buf); + return 0; +} diff --git a/sys/src/cmd/aux/realemu/fns.h b/sys/src/cmd/aux/realemu/fns.h new file mode 100644 index 000000000..a25f6955a --- /dev/null +++ b/sys/src/cmd/aux/realemu/fns.h @@ -0,0 +1,31 @@ +/* arg */ +Iarg *adup(Iarg *x); +Iarg *areg(Cpu *cpu, uchar len, uchar reg); +Iarg *amem(Cpu *cpu, uchar len, uchar sreg, ulong off); +Iarg *afar(Iarg *mem, uchar len, uchar alen); +Iarg *acon(Cpu *cpu, uchar len, ulong val); +ulong ar(Iarg *a); +long ars(Iarg *a); +void aw(Iarg *a, ulong w); + +/* decode */ +void decode(Iarg *ip, Inst *i); + +/* xec */ +void trap(Cpu *cpu, int e); +int intr(Cpu *cpu, int v); +int xec(Cpu *cpu, int n); + +#pragma varargck type "I" Inst* +#pragma varargck type "J" ulong +#pragma varargck type "C" Cpu* + +int instfmt(Fmt *fmt); +int flagfmt(Fmt *fmt); +int cpufmt(Fmt *fmt); + +/* pit */ +void clockpit(Pit *pit, vlong cycles); +void setgate(Pit *ch, uchar gate); +uchar rpit(Pit *pit, uchar addr); +void wpit(Pit *pit, uchar addr, uchar data); diff --git a/sys/src/cmd/aux/realemu/loadcom.c b/sys/src/cmd/aux/realemu/loadcom.c new file mode 100644 index 000000000..28c5bf6e4 --- /dev/null +++ b/sys/src/cmd/aux/realemu/loadcom.c @@ -0,0 +1,43 @@ +#include +#include + +#include "/386/include/ureg.h" + +static uchar buf[0xFF01]; + +void +main(int argc, char *argv[]) +{ + struct Ureg u; + int fd, rreg, rmem, len; + + ARGBEGIN { + } ARGEND; + + if(argc == 0){ + fprint(2, "usage:\t%s file.com\n", argv0); + exits("usage"); + } + if((fd = open(*argv, OREAD)) < 0) + sysfatal("open: %r"); + + if((rreg = open("/dev/realmode", OWRITE)) < 0) + sysfatal("open realmode: %r"); + if((rmem = open("/dev/realmodemem", OWRITE)) < 0) + sysfatal("open realmodemem: %r"); + if((len = readn(fd, buf, sizeof buf)) < 2) + sysfatal("file too small"); + + memset(&u, 0, sizeof u); + u.cs = u.ds = u.es = u.fs = u.gs = 0x1000; + u.ss = 0x0000; + u.sp = 0xfffe; + u.pc = 0x0100; + + seek(rmem, (u.cs<<4) + u.pc, 0); + if(write(rmem, buf, len) != len) + sysfatal("write mem: %r"); + + if(write(rreg, &u, sizeof u) != sizeof u) + sysfatal("write reg: %r"); +} diff --git a/sys/src/cmd/aux/realemu/main.c b/sys/src/cmd/aux/realemu/main.c new file mode 100644 index 000000000..997e75121 --- /dev/null +++ b/sys/src/cmd/aux/realemu/main.c @@ -0,0 +1,784 @@ +#include +#include +#include "dat.h" +#include "fns.h" + +/* for fs */ +#include +#include +#include +#include <9p.h> + +#include "/386/include/ureg.h" + +enum { + MEMSIZE = 0x100000, + + RMBUF = 0x9000, + RMCODE = 0x8000, + + PITHZ = 1193182, + PITNS = 1000000000/PITHZ, +}; + +static Cpu cpu; +static uchar memory[MEMSIZE+4]; +static uchar pageregtmp[0x10]; +static int portfd[5]; +static int realmemfd; +static int cputrace; +static int porttrace; +static Pit pit[3]; + +static vlong pitclock; + +static void +startclock(void) +{ + pitclock = nsec(); +} + +static void +runclock(void) +{ + vlong now, dt; + + now = nsec(); + dt = now - pitclock; + if(dt >= PITNS){ + clockpit(pit, dt/PITNS); + pitclock = now; + } +} + +static ulong +gw1(uchar *p) +{ + return p[0]; +} +static ulong +gw2(uchar *p) +{ + return (ulong)p[0] | (ulong)p[1]<<8; +} +static ulong +gw4(uchar *p) +{ + return (ulong)p[0] | (ulong)p[1]<<8 | (ulong)p[2]<<16 | (ulong)p[3]<<24; +} +static ulong (*gw[5])(uchar *p) = { + [1] gw1, + [2] gw2, + [4] gw4, +}; + +static void +pw1(uchar *p, ulong w) +{ + p[0] = w & 0xFF; +} +static void +pw2(uchar *p, ulong w) +{ + p[0] = w & 0xFF; + p[1] = (w>>8) & 0xFF; +} +static void +pw4(uchar *p, ulong w) +{ + p[0] = w & 0xFF; + p[1] = (w>>8) & 0xFF; + p[2] = (w>>16) & 0xFF; + p[3] = (w>>24) & 0xFF; +} +static void (*pw[5])(uchar *p, ulong w) = { + [1] pw1, + [2] pw2, + [4] pw4, +}; + +static ulong +rbad(void *, ulong off, int) +{ + fprint(2, "bad mem read %.5lux\n", off); + trap(&cpu, EMEM); + + /* not reached */ + return 0; +} + +static void +wbad(void *, ulong off, ulong, int) +{ + fprint(2, "bad mem write %.5lux\n", off); + trap(&cpu, EMEM); +} + +static ulong +rmem(void *, ulong off, int len) +{ + return gw[len](memory + off); +} + +static void +wmem(void *, ulong off, ulong w, int len) +{ + pw[len](memory + off, w); +} + +static ulong +rrealmem(void *, ulong off, int len) +{ + uchar data[4]; + + if(pread(realmemfd, data, len, off) != len){ + fprint(2, "bad real mem read %.5lux: %r\n", off); + trap(&cpu, EMEM); + } + return gw[len](data); +} + +static void +wrealmem(void *, ulong off, ulong w, int len) +{ + uchar data[4]; + + pw[len](data, w); + if(pwrite(realmemfd, data, len, off) != len){ + fprint(2, "bad real mem write %.5lux: %r\n", off); + trap(&cpu, EMEM); + } +} + + +static ulong +rport(void *, ulong p, int len) +{ + uchar data[4]; + ulong w; + + switch(p){ + case 0x20: /* PIC 1 */ + case 0x21: + w = 0; + break; + case 0x40: + case 0x41: + case 0x42: + case 0x43: + runclock(); + w = rpit(pit, p - 0x40); + break; + case 0x60: /* keyboard data output buffer */ + w = 0; + break; + case 0x61: /* keyboard controller port b */ + runclock(); + w = pit[2].out<<5 | pit[2].gate; + break; + case 0x62: /* PPI (XT only) */ + runclock(); + w = pit[2].out<<5; + break; + case 0x63: /* PPI (XT only) read dip switches */ + w = 0; + break; + case 0x65: /* A20 gate */ + w = 1 << 2; + break; + case 0x80: /* extra dma registers (temp) */ + case 0x84: + case 0x85: + case 0x86: + case 0x88: + case 0x8c: + case 0x8d: + case 0x8e: + w = pageregtmp[p-0x80]; + break; + case 0x92: /* A20 gate (system control port a) */ + w = 1 << 1; + break; + case 0xa0: /* PIC 2 */ + case 0xa1: + w = 0; + break; + default: + if(pread(portfd[len], data, len, p) != len){ + fprint(2, "bad %d bit port read %.4lux: %r\n", len*8, p); + trap(&cpu, EIO); + } + w = gw[len](data); + } + if(porttrace) + fprint(2, "rport %.4lux %.*lux\n", p, len<<1, w); + return w; +} + +static void +wport(void *, ulong p, ulong w, int len) +{ + uchar data[4]; + + if(porttrace) + fprint(2, "wport %.4lux %.*lux\n", p, len<<1, w); + + switch(p){ + case 0x20: /* PIC 1 */ + case 0x21: + break; + case 0x40: + case 0x41: + case 0x42: + case 0x43: + runclock(); + wpit(pit, p - 0x40, w); + break; + case 0x60: /* keyboard controller data port */ + break; + case 0x61: /* keyboard controller port B */ + setgate(&pit[2], w & 1); + break; + case 0x62: /* PPI (XT only) */ + case 0x63: + case 0x64: /* KB controller input buffer (ISA, EISA) */ + case 0x65: /* A20 gate (bit 2) */ + break; + case 0x80: + case 0x84: + case 0x85: + case 0x86: + case 0x88: + case 0x8c: + case 0x8d: + case 0x8e: + pageregtmp[p-0x80] = w & 0xFF; + break; + case 0x92: /* system control port a */ + case 0x94: /* system port enable setup register */ + case 0x96: + break; + case 0xA0: /* PIC 2 */ + case 0xA1: + break; + + default: + pw[len](data, w); + if(pwrite(portfd[len], data, len, p) != len){ + fprint(2, "bad %d bit port write %.4lux: %r\n", len*8, p); + trap(&cpu, EIO); + } + } +} + +static Bus memio[] = { + /* 0 */ memory, rmem, wmem, /* RAM: IVT, BIOS data area */ + /* 1 */ memory, rmem, wmem, /* custom */ + /* 2 */ nil, rbad, wbad, + /* 3 */ nil, rbad, wbad, + /* 4 */ nil, rbad, wbad, + /* 5 */ nil, rbad, wbad, + /* 6 */ nil, rbad, wbad, + /* 7 */ nil, rbad, wbad, + /* 8 */ nil, rbad, wbad, + /* 9 */ memory, rmem, wmem, /* RAM: extended BIOS data area */ + /* A */ nil, rrealmem, wrealmem, /* RAM: VGA framebuffer */ + /* B */ nil, rrealmem, wrealmem, /* RAM: VGA framebuffer */ + /* C */ memory, rmem, wmem, /* ROM: VGA BIOS */ + /* D */ nil, rbad, wbad, + /* E */ memory, rmem, wbad, /* ROM: BIOS */ + /* F */ memory, rmem, wbad, /* ROM: BIOS */ +}; + +static Bus portio = { + nil, rport, wport, +}; + +static void +cpuinit(void) +{ + int i; + + fmtinstall('I', instfmt); + fmtinstall('J', flagfmt); + fmtinstall('C', cpufmt); + + if((portfd[1] = open("#P/iob", ORDWR)) < 0) + sysfatal("open iob: %r"); + if((portfd[2] = open("#P/iow", ORDWR)) < 0) + sysfatal("open iow: %r"); + if((portfd[4] = open("#P/iol", ORDWR)) < 0) + sysfatal("open iol: %r"); + + if((realmemfd = open("#P/realmodemem", ORDWR)) < 0) + sysfatal("open realmodemem: %r"); + + for(i=0; ix)]((uchar*)&u->x) +#define PUTUREG(x,y) pw[sizeof(u->x)]((uchar*)&u->x,y) + +static char* +realmode(Cpu *cpu, struct Ureg *u, void *r) +{ + char *err; + int i; + + cpu->reg[RDI] = GETUREG(di); + cpu->reg[RSI] = GETUREG(si); + cpu->reg[RBP] = GETUREG(bp); + cpu->reg[RBX] = GETUREG(bx); + cpu->reg[RDX] = GETUREG(dx); + cpu->reg[RCX] = GETUREG(cx); + cpu->reg[RAX] = GETUREG(ax); + + cpu->reg[RGS] = GETUREG(gs); + cpu->reg[RFS] = GETUREG(fs); + cpu->reg[RES] = GETUREG(es); + cpu->reg[RDS] = GETUREG(ds); + + cpu->reg[RFL] = GETUREG(flags); + + if(i = GETUREG(trap)){ + cpu->reg[RSS] = 0x0000; + cpu->reg[RSP] = 0x7C00; + cpu->reg[RCS] = (RMCODE>>4)&0xF000; + cpu->reg[RIP] = RMCODE & 0xFFFF; + memory[RMCODE] = 0xf4; /* HLT instruction */ + if(intr(cpu, i) < 0) + return Ebadtrap; + } else { + cpu->reg[RSS] = GETUREG(ss); + cpu->reg[RSP] = GETUREG(sp); + cpu->reg[RCS] = GETUREG(cs); + cpu->reg[RIP] = GETUREG(pc); + } + + startclock(); + for(;;){ + if(cputrace) + fprint(2, "%C\n", cpu); + switch(i = xec(cpu, (porttrace | cputrace) ? 1 : 100000)){ + case -1: + if(flushed(r)){ + err = Eintr; + break; + } + runclock(); + continue; + + /* normal interrupts */ + default: + if(intr(cpu, i) < 0){ + err = Ebadtrap; + break; + } + continue; + + /* pseudo-interrupts */ + case EHALT: + err = nil; + break; + case EIO: + err = Eio; + break; + case EMEM: + err = Emem; + break; + + /* processor traps */ + case EDIV0: + case EDEBUG: + case ENMI: + case EBRK: + case EINTO: + case EBOUND: + case EBADOP: + case ENOFPU: + case EDBLF: + case EFPUSEG: + case EBADTSS: + case ENP: + case ESTACK: + case EGPF: + case EPF: + PUTUREG(trap, i); + err = trapstr[i]; + break; + } + + break; + } + + if(err) + fprint(2, "%s\n%C\n", err, cpu); + + PUTUREG(di, cpu->reg[RDI]); + PUTUREG(si, cpu->reg[RSI]); + PUTUREG(bp, cpu->reg[RBP]); + PUTUREG(bx, cpu->reg[RBX]); + PUTUREG(dx, cpu->reg[RDX]); + PUTUREG(cx, cpu->reg[RCX]); + PUTUREG(ax, cpu->reg[RAX]); + + PUTUREG(gs, cpu->reg[RGS]); + PUTUREG(fs, cpu->reg[RFS]); + PUTUREG(es, cpu->reg[RES]); + PUTUREG(ds, cpu->reg[RDS]); + + PUTUREG(flags, cpu->reg[RFL]); + + PUTUREG(pc, cpu->reg[RIP]); + PUTUREG(cs, cpu->reg[RCS]); + PUTUREG(sp, cpu->reg[RSP]); + PUTUREG(ss, cpu->reg[RSS]); + + return err; +} + +enum { + Qroot, + Qcall, + Qmem, + Nqid, +}; + +static struct Qtab { + char *name; + int mode; + int type; + int length; +} qtab[Nqid] = { + "/", + DMDIR|0555, + QTDIR, + 0, + + "realmode", + 0666, + 0, + 0, + + "realmodemem", + 0666, + 0, + MEMSIZE, +}; + +static int +fillstat(ulong qid, Dir *d) +{ + struct Qtab *t; + + memset(d, 0, sizeof(Dir)); + d->uid = "realemu"; + d->gid = "realemu"; + d->muid = ""; + d->qid = (Qid){qid, 0, 0}; + d->atime = time(0); + t = qtab + qid; + d->name = t->name; + d->qid.type = t->type; + d->mode = t->mode; + d->length = t->length; + return 1; +} + +static void +fsattach(Req *r) +{ + char *spec; + + spec = r->ifcall.aname; + if(spec && spec[0]){ + respond(r, Ebadspec); + return; + } + r->fid->qid = (Qid){Qroot, 0, QTDIR}; + r->ofcall.qid = r->fid->qid; + respond(r, nil); +} + +static void +fsstat(Req *r) +{ + fillstat((ulong)r->fid->qid.path, &r->d); + r->d.name = estrdup9p(r->d.name); + r->d.uid = estrdup9p(r->d.uid); + r->d.gid = estrdup9p(r->d.gid); + r->d.muid = estrdup9p(r->d.muid); + respond(r, nil); +} + +static char* +fswalk1(Fid *fid, char *name, Qid *qid) +{ + int i; + ulong path; + + path = fid->qid.path; + switch(path){ + case Qroot: + if (strcmp(name, "..") == 0) { + *qid = (Qid){Qroot, 0, QTDIR}; + fid->qid = *qid; + return nil; + } + for(i = fid->qid.path; iqid = *qid; + return nil; + } + return Enonexist; + + default: + return Ewalk; + } +} + +static void +fsopen(Req *r) +{ + static int need[4] = { 4, 2, 6, 1 }; + struct Qtab *t; + int n; + + t = qtab + r->fid->qid.path; + n = need[r->ifcall.mode & 3]; + if((n & t->mode) != n) + respond(r, Eperm); + else + respond(r, nil); +} + +static int +readtopdir(Fid*, uchar *buf, long off, int cnt, int blen) +{ + int i, m, n; + long pos; + Dir d; + + n = 0; + pos = 0; + for (i = 1; i < Nqid; i++){ + fillstat(i, &d); + m = convD2M(&d, &buf[n], blen-n); + if(off <= pos){ + if(m <= BIT16SZ || m > cnt) + break; + n += m; + cnt -= m; + } + pos += m; + } + return n; +} + +static Channel *reqchan; + +static void +cpuproc(void *) +{ + static struct Ureg rmu; + ulong path; + vlong o; + ulong n; + char *p; + Req *r; + + threadsetname("cpuproc"); + + while(r = recvp(reqchan)){ + if(flushed(r)){ + respond(r, Eintr); + continue; + } + + path = r->fid->qid.path; + + p = r->ifcall.data; + n = r->ifcall.count; + o = r->ifcall.offset; + + switch(((int)r->ifcall.type<<8)|path){ + case (Tread<<8) | Qmem: + readbuf(r, memory, MEMSIZE); + respond(r, nil); + break; + + case (Tread<<8) | Qcall: + readbuf(r, &rmu, sizeof rmu); + respond(r, nil); + break; + + case (Twrite<<8) | Qmem: + if(o < 0 || o >= MEMSIZE || o+n > MEMSIZE){ + respond(r, Ebadoff); + break; + } + memmove(memory + o, p, n); + r->ofcall.count = n; + respond(r, nil); + break; + + case (Twrite<<8) | Qcall: + if(n != sizeof rmu){ + respond(r, Ebadureg); + break; + } + memmove(&rmu, p, n); + if(p = realmode(&cpu, &rmu, r)){ + respond(r, p); + break; + } + r->ofcall.count = n; + respond(r, nil); + break; + } + } +} + +static Channel *flushchan; + +static int +flushed(void *r) +{ + return nbrecvp(flushchan) == r; +} + +static void +fsflush(Req *r) +{ + nbsendp(flushchan, r->oldreq); + respond(r, nil); +} + +static void +dispatch(Req *r) +{ + if(!nbsendp(reqchan, r)) + respond(r, Ebusy); +} + +static void +fsread(Req *r) +{ + switch((ulong)r->fid->qid.path){ + case Qroot: + r->ofcall.count = readtopdir(r->fid, (void*)r->ofcall.data, r->ifcall.offset, + r->ifcall.count, r->ifcall.count); + respond(r, nil); + break; + default: + dispatch(r); + } +} + +static void +fsend(Srv*) +{ + threadexitsall(nil); +} + +static Srv fs = { + .attach= fsattach, + .walk1= fswalk1, + .open= fsopen, + .read= fsread, + .write= dispatch, + .stat= fsstat, + .flush= fsflush, + .end= fsend, +}; + +static void +usage(void) +{ + fprint(2, "usgae:\t%s [-Dpt] [-s srvname] [-m mountpoint]\n", argv0); + exits("usage"); +} + +void +threadmain(int argc, char *argv[]) +{ + char *mnt = "/dev"; + char *srv = nil; + + ARGBEGIN{ + case 'D': + chatty9p++; + break; + case 'p': + porttrace = 1; + break; + case 't': + cputrace = 1; + break; + case 's': + srv = EARGF(usage()); + mnt = nil; + break; + case 'm': + mnt = EARGF(usage()); + break; + default: + usage(); + }ARGEND + + cpuinit(); + + reqchan = chancreate(sizeof(Req*), 8); + flushchan = chancreate(sizeof(Req*), 8); + procrfork(cpuproc, nil, 16*1024, RFNAMEG|RFNOTEG); + threadpostmountsrv(&fs, srv, mnt, MBEFORE); +} diff --git a/sys/src/cmd/aux/realemu/mkfile b/sys/src/cmd/aux/realemu/mkfile new file mode 100644 index 000000000..47fdf53a1 --- /dev/null +++ b/sys/src/cmd/aux/realemu/mkfile @@ -0,0 +1,13 @@ + +#include +#include "dat.h" +#include "fns.h" + +enum { + AC0 = 0, + AC1, + AC2, + Actl, + + Readback = 3, + + RBC0 = 1<<1, + RBC1 = 1<<2, + RBC2 = 1<<3, + RBlatchstatus = 1<<4, + RBlatchcount = 1<<5, + + AMlatchcount = 0, + AMloonly, + AMhionly, + AMlohi, + + OM0 = 0, + OM1, + OM2, + OM3, + OM4, + OM5, + OM2b, + OM3b, +}; + +static void +latchstatus(Pit *ch) +{ + if(ch->rlatched) + return; + ch->rlatch[0] = ch->bcd | ch->omode<<1 | ch->amode<<4 | ch->count0<<6 | ch->out<<7; + ch->rcount = 0; + ch->rlatched = 1; +} + +static void +latchcount(Pit *ch) +{ + ulong w; + + if(ch->rlatched) + return; + w = ch->count & 0xFFFF; + if(ch->bcd) + w = (w % 10) + ((w/10) % 10)<<4 + ((w/100) % 10)<<8 + ((w/1000) % 10)<<12; + ch->rlatch[0] = w & 0xFF; + ch->rlatch[1] = (w >> 8) & 0xFF; + ch->rcount = 0; + ch->rlatched = 1; + switch(ch->amode){ + case AMhionly: + ch->rcount++; + break; + case AMlohi: + ch->rlatched++; + break; + } +} + +static void +setcount(Pit *ch) +{ + ulong w; + + w = (ulong)ch->wlatch[0] | (ulong)ch->wlatch[1] << 8; + if(ch->bcd) + w = (w & 0xF) + 10*((w >> 4)&0xF) + 100*((w >> 8)&0xF) + 1000*((w >> 12)&0xF); + ch->count = w; + ch->count0 = 0; +} + +static int +deccount(Pit *ch, vlong *cycles) +{ + if(ch->count0){ + *cycles = 0; + return 0; + } else { + vlong passed, remain; + + passed = *cycles; + if(ch->count == 0){ + ch->count = ch->bcd ? 9999 : 0xFFFF; + passed--; + } + if(passed <= ch->count){ + remain = 0; + ch->count -= passed; + } else { + remain = passed - ch->count; + ch->count = 0; + } + *cycles = remain; + return ch->count == 0; + } +} + +void +setgate(Pit *ch, uchar gate) +{ + if(ch->gate == 0 && gate) + ch->gateraised = 1; + ch->gate = gate; +} + +static void +clockpit1(Pit *ch, vlong *cycles) +{ + switch(ch->omode){ + case OM0: /* Interrupt On Terminal Count */ + if(ch->count0){ + setcount(ch); + ch->out = 0; + Next: + --*cycles; + return; + } + if(ch->gate && deccount(ch, cycles)){ + ch->out = 1; + return; + } + break; + + case OM1: /* Hardware Re-triggerable One-shot */ + if(ch->gateraised){ + ch->gateraised = 0; + setcount(ch); + ch->out = 0; + goto Next; + } + if(deccount(ch, cycles) && ch->out == 0){ + ch->out = 1; + return; + } + break; + + case OM2: /* Rate Generator */ + case OM2b: + ch->out = 1; + if(ch->count0){ + setcount(ch); + goto Next; + } + if(ch->gate == 0) + break; + if(ch->gateraised){ + ch->gateraised = 0; + setcount(ch); + goto Next; + } + if(deccount(ch, cycles)){ + setcount(ch); + ch->out = 0; + return; + } + break; + + case OM3: /* Square Wave Generator */ + case OM3b: + if(ch->count0){ + setcount(ch); + goto Next; + } + if(ch->gate == 0) + break; + if(ch->gateraised){ + ch->gateraised = 0; + setcount(ch); + goto Next; + } + if(deccount(ch, cycles)){ + setcount(ch); + ch->out ^= 1; + return; + } + break; + + case OM4: /* Software Triggered Strobe */ + ch->out = 1; + if(ch->count0){ + setcount(ch); + goto Next; + } + if(ch->gate && deccount(ch, cycles)){ + ch->out = 0; + return; + } + break; + + case OM5: /* Hardware Triggered Strobe */ + ch->out = 1; + if(ch->gateraised){ + ch->gateraised = 0; + setcount(ch); + goto Next; + } + if(deccount(ch, cycles)){ + ch->out = 0; + return; + } + break; + } + *cycles = 0; +} + +void +clockpit(Pit *pit, vlong cycles) +{ + Pit *ch; + int i; + + if(cycles <= 0) + return; + for(i = 0; iwlatched){ + vlong c; + + switch(ch->omode){ + case OM3: + case OM3b: + c = cycles * 2; + break; + default: + c = cycles; + } + while(c > 0) + clockpit1(ch, &c); + } + ch->gateraised = 0; + } +} + +uchar +rpit(Pit *pit, uchar addr) +{ + Pit *ch; + uchar data; + + if(addr >= Actl) + return 0; + ch = pit + addr; + if(ch->rlatched){ + data = ch->rlatch[ch->rcount & 1]; + ch->rlatched--; + } else { + data = 0; + switch(ch->amode){ + case AMloonly: + data = ch->count & 0xFF; + break; + case AMhionly: + data = (ch->count >> 8) & 0xFF; + break; + case AMlohi: + data = (ch->count >> ((ch->rcount & 1)<<3)) & 0xFF; + break; + } + } + ch->rcount++; + if(0) fprint(2, "rpit %p: %.2x %.2x\n", pit, (int)addr, (int)data); + return data; +} + +void +wpit(Pit *pit, uchar addr, uchar data) +{ + Pit *ch; + + if(0) fprint(2, "wpit %p: %.2x %.2x\n", pit, (int)addr, (int)data); + if(addr > Actl) + return; + if(addr == Actl){ + uchar sc, amode, omode, bcd; + + bcd = (data & 1); + omode = (data >> 1) & 7; + amode = (data >> 4) & 3; + sc = (data >> 6) & 3; + + if(sc == Readback){ + ch = nil; + for(;;){ + if(data & RBC0){ + ch = pit; + break; + } + if(data & RBC1){ + ch = pit + 1; + break; + } + if(data & RBC2){ + ch = pit + 2; + break; + } + break; + } + if(ch == nil) + return; + if((data & RBlatchcount) == 0) + latchcount(ch); + if((data & RBlatchstatus) == 0) + latchstatus(ch); + return; + } + + ch = pit + sc; + if(amode == AMlatchcount){ + latchcount(ch); + return; + } + ch->bcd = bcd; + + ch->amode = amode; + ch->omode = omode; + + ch->rlatched = 0; + ch->rcount = 0; + ch->rlatch[0] = 0; + ch->rlatch[1] = 0; + + ch->wlatched = 0; + ch->wcount = 0; + ch->wlatch[0] = 0; + ch->wlatch[1] = 0; + + ch->count0 = 1; + ch->out = !!omode; + return; + } + + ch = pit + addr; + switch(ch->amode){ + case AMloonly: + case AMhionly: + ch->wlatch[ch->amode - AMloonly] = data; + ch->wcount++; + break; + case AMlohi: + ch->wlatch[ch->wcount++ & 1] = data; + if(ch->wcount < 2) + return; + break; + } + ch->wlatched = ch->wcount; + ch->wcount = 0; + ch->count0 = 1; +} diff --git a/sys/src/cmd/aux/realemu/realemu.man b/sys/src/cmd/aux/realemu/realemu.man new file mode 100644 index 000000000..60763b385 --- /dev/null +++ b/sys/src/cmd/aux/realemu/realemu.man @@ -0,0 +1,104 @@ +.TH realemu 8 +.SH NAME +realemu \- software emulation of /dev/realmode +.SH SYNOPSIS +.B aux/realemu +[ +.B -Dpt +] [ +.B -s +.I srvname +] [ +.B -m +.I mountpoint +] +.SH DESCRIPTION +.PP +Originally, kernel provided +.B /dev/realmode +files with the +.IR arch (3) +device to access and call the +.SM BIOS. +.PP +Interrupts had to be disabled and the processor was switched in the +legacy 16-bit +.SM realmode +with memory protection disabled to execute +.SM BIOS +code. +.PP +This is problematic in case the +.SM BIOS +reprograms hardware currently +used by the operating system or when it reenables interrupts or just +crashes. This will freeze or reboot the machine with no way to +recover or diagnose the problem. +.PP +To avoid this, +.I realemu +is used to emulate the execution of the +.SM BIOS +routines by interpreting the machine instructions and intercepting +dangerous actions that would compromise the systems stability. +.PP +Running +.I realemu +with no arguments, it mounts itself before +.B /dev +and +replaces the original +.B /dev/realmode +file in the current namespace. +.PP +Then programs like +.IR vga (8) +can use it to make ther +.SM BIOS +calls. +.PP +The +.B D +flag will enable debug messages for 9P. The +.B p +and +.B t +flags +control tracing of i/o port access and cpu instructions to +stderr (fd 2). +.PP +When a +.I srvname +is given with the +.B s +argument, the default +.I mountpoint +is ignored and a +.SM 9P +channel is created in +.B /srv +that can be used to mount +the filesystem from another namespace. If a +.I mountpoint +is given before +the +.I srvname +argument then it is ignored, otherwise it will be used. +.SH EXAMPLES +The +.I realemu +process is only needed when accessing +.B /dev/realmode. +To invoke a subshell so that +.I realemu +exits normally after +.B aux/vga +completes: +.IP +.EX +% @{rfork n; aux/realemu; aux/vga -m vesa -l $vgasize} +.SH SOURCE +.B /sys/src/cmd/aux/realemu +.SH "SEE ALSO" +.IR vga (8), +.IR arch (3) diff --git a/sys/src/cmd/aux/realemu/vgalist b/sys/src/cmd/aux/realemu/vgalist new file mode 100644 index 000000000..3a0530584 --- /dev/null +++ b/sys/src/cmd/aux/realemu/vgalist @@ -0,0 +1,9 @@ +#vid did bios wired product name +100b 0030 5.30 STI NSC Geode GX2 +5533 8c2e 1.0 - T23 / S3 savage +1002 791e 01.00 - ATI RS690 +10de 002c B1 STI NVidia RivaTNT +15ad 0405 2.0 - VMware +- - 1.26 - Bochs +102b 0519 00 STI Matrox MILLENNIUM +5333 8901 Rev E - S3 Trio64V2/DX/GX diff --git a/sys/src/cmd/aux/realemu/xec.c b/sys/src/cmd/aux/realemu/xec.c new file mode 100644 index 000000000..8d63e6155 --- /dev/null +++ b/sys/src/cmd/aux/realemu/xec.c @@ -0,0 +1,1224 @@ +#include +#include +#include "dat.h" +#include "fns.h" + +#define sign(s) (1UL<<((s)-1)) +#define mask(s) (sign(s)|(sign(s)-1)) + +int cputrace; + +static void +push(Iarg *sp, Iarg *a) +{ + Iarg *p; + + p = amem(sp->cpu, a->len, RSS, ar(sp)); + p->off -= a->len; + aw(p, ar(a)); + aw(sp, p->off); +} + +static void +pop(Iarg *sp, Iarg *a) +{ + Iarg *p; + + p = amem(sp->cpu, a->len, RSS, ar(sp)); + aw(a, ar(p)); + aw(sp, p->off + a->len); +} + +static void +jump(Iarg *to) +{ + Cpu *cpu; + + cpu = to->cpu; + switch(to->atype){ + default: + abort(); + case AMp: + to = afar(to, 1, to->len); + case AAp: + cpu->reg[RCS] = to->seg; + case AJb: + case AJv: + cpu->reg[RIP] = to->off; + break; + case AEv: + cpu->reg[RIP] = ar(to); + break; + } +} + +static void +opcall(Cpu *cpu, Inst *i) +{ + Iarg *sp; + + sp = areg(cpu, cpu->slen, RSP); + switch(i->a1->atype){ + default: + abort(); + case AAp: + case AMp: + push(sp, areg(cpu, i->olen, RCS)); + case AJv: + case AEv: + push(sp, areg(cpu, i->olen, RIP)); + break; + } + jump(i->a1); +} + +static void +opint(Cpu *cpu, Inst *i) +{ + cpu->trap = ar(i->a1); + longjmp(cpu->jmp, 1); +} + +static void +opiret(Cpu *cpu, Inst *i) +{ + Iarg *sp; + + if(i->olen != 2) + trap(cpu, EBADOP); + sp = areg(cpu, cpu->slen, RSP); + pop(sp, areg(cpu, 2, RIP)); + pop(sp, areg(cpu, 2, RCS)); + pop(sp, areg(cpu, 2, RFL)); +} + +static void +opret(Cpu *cpu, Inst *i) +{ + Iarg *sp; + ulong c; + + sp = areg(cpu, cpu->slen, RSP); + pop(sp, areg(cpu, i->olen, RIP)); + if(c = ar(i->a1)) + aw(sp, ar(sp) + c); +} + +static void +opretf(Cpu *cpu, Inst *i) +{ + Iarg *sp; + ulong c; + + sp = areg(cpu, cpu->slen, RSP); + pop(sp, areg(cpu, i->olen, RIP)); + pop(sp, areg(cpu, i->olen, RCS)); + if(c = ar(i->a1)) + aw(sp, ar(sp) + c); +} + +static void +openter(Cpu *cpu, Inst *i) +{ + Iarg *sp, *bp; + ulong oframe, nframe; + int j, n; + + sp = areg(cpu, cpu->slen, RSP); + bp = areg(cpu, cpu->slen, RBP); + push(sp, bp); + oframe = ar(bp); + nframe = ar(sp); + n = ar(i->a2) % 32; + if(n > 0){ + for(j=1; jolen*j); + push(sp, bp); + } + push(sp, acon(cpu, i->olen, nframe)); + } + aw(bp, nframe); + aw(sp, nframe - ar(i->a1)); +} + +static void +opleave(Cpu *cpu, Inst *i) +{ + Iarg *sp; + + sp = areg(cpu, cpu->slen, RSP); + aw(sp, ar(areg(cpu, cpu->slen, RBP))); + pop(sp, areg(cpu, i->olen, RBP)); +} + +static void +oppush(Cpu *cpu, Inst *i) +{ + Iarg *sp; + + sp = areg(cpu, cpu->slen, RSP); + if(i->a1->len == 1) /* 0x6A push imm8 */ + push(sp, acon(cpu, i->olen, ar(i->a1))); + else + push(sp, i->a1); +} + +static void +oppop(Cpu *cpu, Inst *i) +{ + pop(areg(cpu, cpu->slen, RSP), i->a1); +} + +static void +oppusha(Cpu *cpu, Inst *i) +{ + Iarg *sp, *osp; + + sp = areg(cpu, cpu->slen, RSP); + osp = acon(cpu, i->olen, ar(sp)); + push(sp, areg(cpu, i->olen, RAX)); + push(sp, areg(cpu, i->olen, RCX)); + push(sp, areg(cpu, i->olen, RDX)); + push(sp, areg(cpu, i->olen, RBX)); + push(sp, osp); + push(sp, areg(cpu, i->olen, RBP)); + push(sp, areg(cpu, i->olen, RSI)); + push(sp, areg(cpu, i->olen, RDI)); +} + +static void +oppopa(Cpu *cpu, Inst *i) +{ + Iarg *sp; + + sp = areg(cpu, cpu->slen, RSP); + pop(sp, areg(cpu, i->olen, RDI)); + pop(sp, areg(cpu, i->olen, RSI)); + pop(sp, areg(cpu, i->olen, RBP)); + pop(sp, areg(cpu, i->olen, RBX)); // RSP + pop(sp, areg(cpu, i->olen, RBX)); + pop(sp, areg(cpu, i->olen, RDX)); + pop(sp, areg(cpu, i->olen, RCX)); + pop(sp, areg(cpu, i->olen, RAX)); +} + +static void +oppushf(Cpu *cpu, Inst *i) +{ + push(areg(cpu, cpu->slen, RSP), areg(cpu, i->olen, RFL)); +} + +static void +oppopf(Cpu *cpu, Inst *i) +{ + ulong *f, o; + + f = cpu->reg + RFL; + o = *f; + pop(areg(cpu, cpu->slen, RSP), areg(cpu, i->olen, RFL)); + *f &= ~(VM|RF); + *f |= (o & (VM|RF)); +} + +static void +oplahf(Cpu *cpu, Inst *i) +{ + aw(i->a1, cpu->reg[RFL]); +} + +static void +opsahf(Cpu *cpu, Inst *i) +{ + enum { MASK = SF|ZF|AF|PF|CF }; + ulong *f; + + f = cpu->reg + RFL; + *f &= ~MASK; + *f |= (ar(i->a1) & MASK); +} + +static void +opcli(Cpu *cpu, Inst *) +{ + cpu->reg[RFL] &= ~IF; +} + +static void +opsti(Cpu *cpu, Inst *) +{ + cpu->reg[RFL] |= IF; +} + +static void +opcld(Cpu *cpu, Inst *) +{ + cpu->reg[RFL] &= ~DF; +} + +static void +opstd(Cpu *cpu, Inst *) +{ + cpu->reg[RFL] |= DF; +} + +static void +opclc(Cpu *cpu, Inst *) +{ + cpu->reg[RFL] &= ~CF; +} + +static void +opstc(Cpu *cpu, Inst *) +{ + cpu->reg[RFL] |= CF; +} + +static void +opcmc(Cpu *cpu, Inst *) +{ + cpu->reg[RFL] ^= CF; +} + +static void +parity(ulong *f, ulong r) +{ + static ulong tab[8] = { + 0x96696996, + 0x69969669, + 0x69969669, + 0x96696996, + 0x69969669, + 0x96696996, + 0x96696996, + 0x69969669, + }; + r &= 0xFF; + if((tab[r/32] >> (r%32)) & 1) + *f &= ~PF; + else + *f |= PF; +} + +static ulong +test(ulong *f, long r, int s) +{ + *f &= ~(CF|SF|ZF|OF|PF); + r &= mask(s); + if(r == 0) + *f |= ZF; + if(r & sign(s)) + *f |= SF; + parity(f, r); + return r; +} + +static void +opshl(Cpu *cpu, Inst *i) +{ + ulong *f, r, a, h; + int s, n; + + if((n = ar(i->a2) & 31) == 0) + return; + s = i->a1->len*8; + a = ar(i->a1); + f = cpu->reg + RFL; + r = test(f, a<a1, r); + if((a<<(n-1)) & h) + *f |= CF; + if(n == 1 && ((a^r) & h)) + *f |= OF; +} + +static void +opshr(Cpu *cpu, Inst *i) +{ + ulong *f, a; + int s, n; + + if((n = ar(i->a2) & 31) == 0) + return; + s = i->a1->len*8; + a = ar(i->a1); + f = cpu->reg + RFL; + aw(i->a1, test(f, a>>n, s)); + if(a & sign(n)) + *f |= CF; + if(n == 1 && (a & sign(s))) + *f |= OF; +} + +static void +opsar(Cpu *cpu, Inst *i) +{ + ulong *f; + long a; + int n; + + if((n = ar(i->a2) & 31) == 0) + return; + a = ars(i->a1); + f = cpu->reg + RFL; + aw(i->a1, test(f, a>>n, i->a1->len*8)); + if(a & sign(n)) + *f |= CF; +} + +static void +opshld(Cpu *cpu, Inst *i) +{ + ulong *f, a; + int s, n; + + if((n = ar(i->a3) & 31) == 0) + return; + s = i->a1->len*8; + a = ar(i->a1); + f = cpu->reg + RFL; + aw(i->a1, test(f, (a<a2)>>(s-n)), s)); + if((a<<(n-1)) & sign(s)) + *f |= CF; +} + +static void +opshrd(Cpu *cpu, Inst *i) +{ + ulong *f, a; + int s, n; + + if((n = ar(i->a3) & 31) == 0) + return; + s = i->a1->len*8; + a = ar(i->a1); + f = cpu->reg + RFL; + aw(i->a1, test(f, (a>>n)|(ar(i->a2)<<(s-n)), s)); + if(a & sign(n)) + *f |= CF; +} + + +static void +oprcl(Cpu *cpu, Inst *i) +{ + ulong *f, a, r; + int s, n; + + s = i->a1->len*8; + n = ar(i->a2) % (s+1); + a = ar(i->a1); + r = (a<>(s-n))>>1); + f = cpu->reg + RFL; + if(*f & CF) + r |= sign(n); + aw(i->a1, r); + *f &= ~(CF|OF); + if((a>>(s-n)) & 1) + *f |= CF; + if((a ^ r) & sign(s)) + *f |= OF; + parity(f, r); +} + +static void +oprcr(Cpu *cpu, Inst *i) +{ + ulong *f, a, r, h; + int s, n; + + s = i->a1->len*8; + n = ar(i->a2) % (s+1); + a = ar(i->a1); + h = a<<(s-n); + r = (a>>n) | (h<<1); + f = cpu->reg + RFL; + if(*f & CF) + r |= 1<<(s-n); + aw(i->a1, r); + *f &= ~(CF|OF); + if(h & sign(s)) + *f |= CF; + if((a ^ r) & sign(s)) + *f |= OF; + parity(f, r); +} + +static void +oprol(Cpu *cpu, Inst *i) +{ + ulong *f, a, r; + int s, n; + + s = i->a1->len*8; + n = ar(i->a2) & (s-1); + a = ar(i->a1); + r = (a<>(s-n)); + f = cpu->reg + RFL; + aw(i->a1, r); + *f &= ~(CF|OF); + if(r & 1) + *f |= CF; + if((a ^ r) & sign(s)) + *f |= OF; + parity(f, r); +} + +static void +opror(Cpu *cpu, Inst *i) +{ + ulong *f, a, r; + int s, n; + + s = i->a1->len*8; + n = ar(i->a2) & (s-1); + a = ar(i->a1); + r = (a>>n) | (a<<(s-n)); + aw(i->a1, r); + f = cpu->reg + RFL; + *f &= ~(CF|OF); + if(r & sign(s)) + *f |= CF; + if((a ^ r) & sign(s)) + *f |= OF; + parity(f, r); +} + +static void +opbts(Cpu *cpu, Inst *i) +{ + ulong a, m; + int n; + + a = ar(i->a1); + n = ar(i->a2) & 31; + m = 1<reg[RFL] |= CF; + else { + cpu->reg[RFL] &= ~CF; + aw(i->a1, a | m); + } +} + +static void +opbtr(Cpu *cpu, Inst *i) +{ + ulong a, m; + int n; + + a = ar(i->a1); + n = ar(i->a2) & 31; + m = 1<reg[RFL] |= CF; + aw(i->a1, a & ~m); + } else + cpu->reg[RFL] &= ~CF; +} + +static void +opbitscan(Cpu *cpu, Inst *i) +{ + ulong a; + + if((a = ar(i->a2)) == 0) + cpu->reg[RFL] |= ZF; + else { + int j; + + if(i->op == OBSF){ + for(j = 0; (a & (1<a2->len*8-1; (a & (1<a1, j); + cpu->reg[RFL] &= ~ZF; + } +} + +static void +opand(Cpu *cpu, Inst *i) +{ + aw(i->a1, test(cpu->reg + RFL, ars(i->a1) & ars(i->a2), i->a1->len*8)); +} + +static void +opor(Cpu *cpu, Inst *i) +{ + aw(i->a1, test(cpu->reg + RFL, ars(i->a1) | ars(i->a2), i->a1->len*8)); +} + +static void +opxor(Cpu *cpu, Inst *i) +{ + aw(i->a1, test(cpu->reg + RFL, ars(i->a1) ^ ars(i->a2), i->a1->len*8)); +} + +static void +opnot(Cpu *, Inst *i) +{ + aw(i->a1, ~ar(i->a1)); +} + +static void +optest(Cpu *cpu, Inst *i) +{ + test(cpu->reg + RFL, ars(i->a1) & ars(i->a2), i->a1->len*8); +} + +static ulong +add(ulong *f, long a, long b, int c, int s) +{ + ulong r, cc, m, n; + + *f &= ~(AF|CF|SF|ZF|OF|PF); + + n = sign(s); + m = mask(s); + r = a + b + c; + r &= m; + if(r == 0) + *f |= ZF; + if(r & n) + *f |= SF; + cc = (a & b) | (~r & (a | b)); + if(cc & n) + *f |= CF; + if((cc ^ (cc >> 1)) & (n>>1)) + *f |= OF; + parity(f, r); + return r; +} + +static ulong +sub(ulong *f, long a, long b, int c, int s) +{ + ulong r, bc, n; + + *f &= ~(AF|CF|SF|ZF|OF|PF); + + r = a - b - c; + n = sign(s); + r &= mask(s); + if(r == 0) + *f |= ZF; + if(r & n) + *f |= SF; + a = ~a; + bc = (a & b) | (r & (a | b)); + if(bc & n) + *f |= CF; + if((bc ^ (bc >> 1)) & (n>>1)) + *f |= OF; + parity(f, r); + return r; +} + +static void +opadd(Cpu *cpu, Inst *i) +{ + aw(i->a1, add(cpu->reg + RFL, ars(i->a1), ars(i->a2), 0, i->a1->len*8)); +} + +static void +opadc(Cpu *cpu, Inst *i) +{ + ulong *f = cpu->reg + RFL; + + aw(i->a1, add(f, ars(i->a1), ars(i->a2), (*f & CF) != 0, i->a1->len*8)); +} + +static void +opsub(Cpu *cpu, Inst *i) +{ + aw(i->a1, sub(cpu->reg + RFL, ars(i->a1), ars(i->a2), 0, i->a1->len*8)); +} + +static void +opsbb(Cpu *cpu, Inst *i) +{ + ulong *f = cpu->reg + RFL; + + aw(i->a1, sub(f, ars(i->a1), ars(i->a2), (*f & CF) != 0, i->a1->len*8)); +} + +static void +opneg(Cpu *cpu, Inst *i) +{ + aw(i->a1, sub(cpu->reg + RFL, 0, ars(i->a1), 0, i->a1->len*8)); +} + +static void +opcmp(Cpu *cpu, Inst *i) +{ + sub(cpu->reg + RFL, ars(i->a1), ars(i->a2), 0, i->a1->len*8); +} + +static void +opinc(Cpu *cpu, Inst *i) +{ + ulong *f, o; + + f = cpu->reg + RFL; + o = *f; + aw(i->a1, add(f, ars(i->a1), 1, 0, i->a1->len*8)); + *f = (*f & ~CF) | (o & CF); +} + +static void +opdec(Cpu *cpu, Inst *i) +{ + ulong *f, o; + + f = cpu->reg + RFL; + o = *f; + aw(i->a1, sub(f, ars(i->a1), 1, 0, i->a1->len*8)); + *f = (*f & ~CF) | (o & CF); +} + +static void +opmul(Cpu *cpu, Inst *i) +{ + Iarg *la, *ha; + ulong l, h, m; + uvlong r; + int s; + + s = i->a2->len*8; + m = mask(s); + r = ar(i->a2) * ar(i->a3); + l = r & m; + h = (r >> s) & m; + if(i->a1->atype != AAX) + abort(); + la = areg(cpu, i->a2->len, RAX); + if(s == 8){ + ha = adup(la); + ha->tag |= TH; + } else + ha = areg(cpu, i->a2->len, RDX); + aw(la, l); + aw(ha, h); + if(h) + cpu->reg[RFL] |= (CF|OF); + else + cpu->reg[RFL] &= ~(CF|OF); +} + +static void +opimul(Cpu *cpu, Inst *i) +{ + ulong l, h, m, n; + vlong r; + int s; + + s = i->a2->len*8; + m = mask(s); + n = sign(s); + r = ars(i->a2) * ars(i->a3); + h = (r >> s) & m; + l = r & m; + if(i->a1->atype == AAX){ + Iarg *la, *ha; + + la = areg(cpu, i->a2->len, RAX); + if(s == 8){ + ha = adup(la); + ha->tag |= TH; + }else + ha = areg(cpu, i->a2->len, RDX); + aw(la, l); + aw(ha, h); + } else + aw(i->a1, l); + if((r > (vlong)n-1) || (r < -(vlong)n)) + cpu->reg[RFL] |= (CF|OF); + else + cpu->reg[RFL] &= ~(CF|OF); +} + +static void +opdiv(Cpu *cpu, Inst *i) +{ + Iarg *qa, *ra; + uvlong n, q; + ulong m, r, d; + int s; + + s = i->a1->len*8; + m = mask(s); + d = ar(i->a1); + if(d == 0) + trap(cpu, EDIV0); + if(s == 8){ + qa = areg(cpu, 1, RAX); + ra = adup(qa); + ra->tag |= TH; + } else { + qa = areg(cpu, i->olen, RAX); + ra = areg(cpu, i->olen, RDX); + } + n = (uvlong)ar(ra)< m) + trap(cpu, EGPF); + r = n%d; + aw(ra, r); + aw(qa, q); +} + + +static int +cctrue(Cpu *cpu, Inst *i) +{ + enum { SO = 1<<16, /* pseudo-flag SF != OF */ }; + static ulong test[] = { + OF, /* JO, JNO */ + CF, /* JC, JNC */ + ZF, /* JZ, JNZ */ + CF|ZF, /* JBE,JA */ + SF, /* JS, JNS */ + PF, /* JP, JNP */ + SO, /* JL, JGE */ + SO|ZF, /* JLE,JG */ + }; + ulong f, t; + uchar c; + + c = i->code; + switch(c){ + case 0xE3: /* JCXZ */ + return ar(areg(cpu, i->alen, RCX)) == 0; + case 0xEB: /* JMP */ + case 0xE9: + case 0xEA: + case 0xFF: + return 1; + default: + f = cpu->reg[RFL]; + if(((f&SF)!=0) ^ ((f&OF)!=0)) + f |= SO; + t = test[(c>>1)&7]; + return ((t&f) != 0) ^ (c&1); + } +} + +static void +opjump(Cpu *cpu, Inst *i) +{ + if(cctrue(cpu, i)) + jump(i->a1); +} + +static void +oploop(Cpu *cpu, Inst *i) +{ + Iarg *cx; + ulong c; + + switch(i->op){ + default: + abort(); + case OLOOPNZ: + if(cpu->reg[RFL] & ZF) + return; + break; + case OLOOPZ: + if((cpu->reg[RFL] & ZF) == 0) + return; + break; + case OLOOP: + break; + } + cx = areg(cpu, i->alen, RCX); + c = ar(cx) - 1; + aw(cx, c); + if(c) + jump(i->a1); +} + +static void +oplea(Cpu *, Inst *i) +{ + aw(i->a1, i->a2->off); +} + +static void +opmov(Cpu *, Inst *i) +{ + aw(i->a1, ar(i->a2)); +} + +static void +opcbw(Cpu *cpu, Inst *i) +{ + aw(areg(cpu, i->olen, RAX), ars(areg(cpu, i->olen>>1, RAX))); +} + +static void +opcwd(Cpu *cpu, Inst *i) +{ + aw(areg(cpu, i->olen, RDX), ars(areg(cpu, i->olen, RAX))>>(i->olen*8-1)); +} + +static void +opmovsx(Cpu *, Inst *i) +{ + aw(i->a1, ars(i->a2)); +} + +static void +opxchg(Cpu *, Inst *i) +{ + ulong x; + + x = ar(i->a1); + aw(i->a1, ar(i->a2)); + aw(i->a2, x); +} + +static void +oplfp(Cpu *, Inst *i) +{ + Iarg *p; + + p = afar(i->a3, i->olen, i->olen); + aw(i->a1, p->seg); + aw(i->a2, p->off); +} + +static void +opbound(Cpu *cpu, Inst *i) +{ + ulong p, s, e; + + p = ar(i->a1); + s = ar(i->a2); + e = ar(i->a3); + if((p < s) || (p >= e)) + trap(cpu, EBOUND); +} + +static void +opxlat(Cpu *cpu, Inst *i) +{ + aw(i->a1, ar(amem(cpu, i->a1->len, i->sreg, ar(areg(cpu, i->alen, i->a2->reg)) + ar(i->a1)))); +} + +static void +opcpuid(Cpu *cpu, Inst *) +{ + static struct { + ulong level; + + ulong ax; + ulong bx; + ulong cx; + ulong dx; + } tab[] = { + 0, + 5, + 0x756e6547, + 0x49656e69, + 0x6c65746e, + 1, + 4<<8, + 0x00000000, + 0x00000000, + 0x00000000, + 2, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 3, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + }; + + int i; + + for(i=0; ireg[RAX]){ + cpu->reg[RAX] = tab[i].ax; + cpu->reg[RBX] = tab[i].bx; + cpu->reg[RCX] = tab[i].cx; + cpu->reg[RDX] = tab[i].dx; + return; + } + } + trap(cpu, EBADOP); +} + +static void +opmovs(Cpu *cpu, Inst *i) +{ + Iarg *cx, *d, *s; + ulong c; + int n; + + d = adup(i->a1); + s = adup(i->a2); + n = s->len; + if(cpu->reg[RFL] & DF) + n = -n; + if(i->rep){ + cx = areg(cpu, i->alen, RCX); + c = ar(cx); + } else { + cx = nil; + c = 1; + } + while(c){ + aw(d, ar(s)); + d->off += n; + s->off += n; + c--; + } + aw(areg(cpu, i->alen, RDI), d->off); + aw(areg(cpu, i->alen, RSI), s->off); + if(cx) + aw(cx, 0); +} + +static void +oplods(Cpu *cpu, Inst *i) +{ + Iarg *cx, *s; + ulong c; + int n; + + s = adup(i->a2); + n = s->len; + if(cpu->reg[RFL] & DF) + n = -n; + if(i->rep){ + cx = areg(cpu, i->alen, RCX); + c = ar(cx); + } else { + cx = nil; + c = 1; + } + if(c){ + s->off += n*(c-1); + aw(i->a1, ar(s)); + s->off += n; + } + aw(areg(cpu, i->alen, RSI), s->off); + if(cx) + aw(cx, 0); +} + +static void +opstos(Cpu *cpu, Inst *i) +{ + Iarg *cx, *d; + ulong c, a; + int n; + + d = adup(i->a1); + n = d->len; + if(cpu->reg[RFL] & DF) + n = -n; + if(i->rep){ + cx = areg(cpu, i->alen, RCX); + c = ar(cx); + } else { + cx = nil; + c = 1; + } + a = ar(i->a2); + while(c){ + aw(d, a); + d->off += n; + c--; + } + aw(areg(cpu, i->alen, RDI), d->off); + if(cx) + aw(cx, 0); +} + +static void +opin(Cpu *cpu, Inst *i) +{ + Bus *io; + + io = cpu->port; + aw(i->a1, io->r(io->aux, ar(i->a2) & 0xFFFF, i->a1->len)); +} + +static void +opout(Cpu *cpu, Inst *i) +{ + Bus *io; + + io = cpu->port; + io->w(io->aux, ar(i->a1) & 0xFFFF, ar(i->a2), i->a2->len); +} + +static void +opnop(Cpu *, Inst *) +{ +} + +static void +ophlt(Cpu *cpu, Inst *) +{ + trap(cpu, EHALT); +} + +static void (*exctab[NUMOP])(Cpu *cpu, Inst*) = { + [OINT] = opint, + [OIRET] = opiret, + + [OCALL] = opcall, + [OJUMP] = opjump, + + [OLOOP] = oploop, + [OLOOPZ] = oploop, + [OLOOPNZ] = oploop, + + [ORET] = opret, + [ORETF] = opretf, + + [OENTER] = openter, + [OLEAVE] = opleave, + + [OPUSH] = oppush, + [OPOP] = oppop, + + [OPUSHF] = oppushf, + [OPOPF] = oppopf, + [OLAHF] = oplahf, + [OSAHF] = opsahf, + + [OPUSHA] = oppusha, + [OPOPA] = oppopa, + + [OCLI] = opcli, + [OSTI] = opsti, + [OCLC] = opclc, + [OSTC] = opstc, + [OCMC] = opcmc, + [OCLD] = opcld, + [OSTD] = opstd, + + [OSHL] = opshl, + [OSHR] = opshr, + [OSAR] = opsar, + + [OSHLD] = opshld, + [OSHRD] = opshrd, + + [ORCL] = oprcl, + [ORCR] = oprcr, + [OROL] = oprol, + [OROR] = opror, + + [OBTS] = opbts, + [OBTR] = opbtr, + [OBSF] = opbitscan, + [OBSR] = opbitscan, + + [OAND] = opand, + [OOR] = opor, + [OXOR] = opxor, + [ONOT] = opnot, + [OTEST] = optest, + + [OADD] = opadd, + [OADC] = opadc, + [OSUB] = opsub, + [OSBB] = opsbb, + [ONEG] = opneg, + [OCMP] = opcmp, + + [OINC] = opinc, + [ODEC] = opdec, + + [OMUL] = opmul, + [OIMUL] = opimul, + [ODIV] = opdiv, + + [OLEA] = oplea, + [OMOV] = opmov, + [OCBW] = opcbw, + [OCWD] = opcwd, + [OMOVZX] = opmov, + [OMOVSX] = opmovsx, + [OXCHG] = opxchg, + [OLFP] = oplfp, + [OBOUND] = opbound, + [OXLAT] = opxlat, + + [OCPUID] = opcpuid, + + [OMOVS] = opmovs, + [OSTOS] = opstos, + [OLODS] = oplods, + + [OIN] = opin, + [OOUT] = opout, + + [ONOP] = opnop, + [OHLT] = ophlt, +}; + +void +trap(Cpu *cpu, int e) +{ + cpu->reg[RIP] = cpu->oldip; + cpu->trap = e; + longjmp(cpu->jmp, 1); +} + +int +intr(Cpu *cpu, int v) +{ + Iarg *sp, *ip, *cs, *iv; + + if(v < 0 || v > 0xff || cpu->olen != 2) + return -1; + + sp = areg(cpu, cpu->slen, RSP); + cs = areg(cpu, 2, RCS); + ip = areg(cpu, 2, RIP); + + iv = amem(cpu, 2, R0S, v * 4); + + push(sp, areg(cpu, 2, RFL)); + push(sp, cs); + push(sp, ip); + + cpu->reg[RIP] = ar(iv); + iv->off += 2; + cpu->reg[RCS] = ar(iv); + return 0; +} + +int +xec(Cpu *cpu, int n) +{ + if(setjmp(cpu->jmp)) + return cpu->trap; + while(n--){ + void (*f)(Cpu *, Inst *); + Iarg *ip; + Inst i; + + cpu->ic++; + + ip = amem(cpu, 1, RCS, cpu->oldip = cpu->reg[RIP]); + decode(ip, &i); + cpu->reg[RIP] = ip->off; + if((f = exctab[i.op]) == nil) + trap(cpu, EBADOP); + f(cpu, &i); + } + return n; +} diff --git a/tmp/.dummy b/tmp/.dummy new file mode 100644 index 000000000..e69de29bb diff --git a/usr/glenda/bin/rc/pull b/usr/glenda/bin/rc/pull new file mode 100755 index 000000000..42b5ecc27 --- /dev/null +++ b/usr/glenda/bin/rc/pull @@ -0,0 +1,17 @@ +#!/bin/rc + +rfork e +flags=() +while(! ~ $#* 0 && ~ $1 -*){ + if(~ $1 -c -s){ + flags=($flags $1) + shift + } + flags=($flags $1) + shift +} +if(test -f /srv/kfs.cmd) + disk/kfscmd allow +replica/pull -v $flags /dist/replica/network $* +if(test -f /srv/kfs.cmd) + disk/kfscmd disallow diff --git a/usr/glenda/bin/rc/riostart b/usr/glenda/bin/rc/riostart new file mode 100755 index 000000000..c8515d08e --- /dev/null +++ b/usr/glenda/bin/rc/riostart @@ -0,0 +1,17 @@ +#!/bin/rc + +scr=(`{cat /dev/draw/new >[2]/dev/null || status=''}) +wid=$scr(11) +ht=$scr(12) + +window 0,0,161,117 stats -lmisce +window 161,0,560,117 faces -i + +if(~ `{screensize} small) + dump=acme.dump.small +if not + dump=acme.dump + +a=`{echo $wid-35 | hoc } +window 60,90,$a,$ht acme -l lib/$dump +window 20,140,610,450 /usr/glenda/lib/first.window diff --git a/usr/glenda/bin/rc/screensize b/usr/glenda/bin/rc/screensize new file mode 100755 index 000000000..e38ed4d47 --- /dev/null +++ b/usr/glenda/bin/rc/screensize @@ -0,0 +1,9 @@ +#!/bin/rc + +scr=(`{cat /dev/draw/new >[2]/dev/null || status=''}) +wid=$scr(11) +ht=$scr(12) +if(test $wid -le 1024) + echo small +if not + echo normal diff --git a/usr/glenda/lib/acme.dump b/usr/glenda/lib/acme.dump new file mode 100644 index 000000000..1be4a18ec --- /dev/null +++ b/usr/glenda/lib/acme.dump @@ -0,0 +1,12 @@ +/usr/glenda +/lib/font/bit/lucidasans/unicode.8.font +/lib/font/bit/lucm/unicode.9.font + 0 20 75 +f 0 24 0 0 1 + 24 34 16 1 0 /usr/glenda/ Del Snarf Get | Look +f 1 25 567 567 1 + 25 34 567 0 0 readme.acme Del Snarf Undo | Look +e 2 0 0 0 1 + 23 49 52 0 0 /mail/fs/mbox/ Del Snarf | Look Put Mail Delmesg +/acme/mail +Mail mbox diff --git a/usr/glenda/lib/acme.dump.small b/usr/glenda/lib/acme.dump.small new file mode 100644 index 000000000..518a483f7 --- /dev/null +++ b/usr/glenda/lib/acme.dump.small @@ -0,0 +1,16 @@ +/usr/glenda +/lib/font/bit/lucidasans/unicode.7.font +/lib/font/bit/lucidasans/typelatin1.7.font + 0 20 75 +f 0 24 0 0 1 + 24 34 16 1 0 /usr/glenda/ Del Snarf Get | Look +e 0 0 0 0 8 + 28 51 6 0 1 /usr/glenda/-serzone Del Snarf | Look Send Noscroll +/usr/glenda +win +f 1 25 567 567 1 + 25 34 567 0 0 readme.acme Del Snarf Undo | Look +e 2 0 0 0 1 + 23 49 52 0 0 /mail/fs/mbox/ Del Snarf | Look Put Mail Delmesg +/acme/mail +Mail mbox diff --git a/usr/glenda/lib/first.window b/usr/glenda/lib/first.window new file mode 100755 index 000000000..cf9544e98 --- /dev/null +++ b/usr/glenda/lib/first.window @@ -0,0 +1,5 @@ +#!/bin/rc +echo -n readme > /dev/label +cat readme.rio +exec rc -i + diff --git a/usr/glenda/lib/newstime b/usr/glenda/lib/newstime new file mode 100644 index 000000000..e69de29bb diff --git a/usr/glenda/lib/plumbing b/usr/glenda/lib/plumbing new file mode 100644 index 000000000..b209d2d66 --- /dev/null +++ b/usr/glenda/lib/plumbing @@ -0,0 +1,6 @@ +# to update: cp /usr/glenda/lib/plumbing /mnt/plumb/rules + +editor = acme + +include basic + diff --git a/usr/glenda/lib/profile b/usr/glenda/lib/profile new file mode 100644 index 000000000..fe2728986 --- /dev/null +++ b/usr/glenda/lib/profile @@ -0,0 +1,36 @@ +bind -a $home/bin/rc /bin +bind -a $home/bin/$cputype /bin +bind -c tmp /tmp +if(! syscall create /tmp/xxx 1 0666 >[2]/dev/null) + ramfs # in case we're running off a cd +font = /lib/font/bit/pelm/euro.9.font +upas/fs +fn cd { builtin cd $* && awd } # for acme +switch($service){ +case terminal + plumber + echo -n accelerated > '#m/mousectl' + echo -n 'res 3' > '#m/mousectl' + prompt=('term% ' ' ') + fn term%{ $* } + exec rio -i riostart +case cpu + if (test -e /mnt/term/mnt/wsys) { # rio already running + bind -a /mnt/term/mnt/wsys /dev + if(test -w /dev/label) + echo -n $sysname > /dev/label + } + bind /mnt/term/dev/cons /dev/cons + bind /mnt/term/dev/consctl /dev/consctl + bind -a /mnt/term/dev /dev + prompt=('cpu% ' ' ') + fn cpu%{ $* } + news + if (! test -e /mnt/term/mnt/wsys) { # cpu call from drawterm + font=/lib/font/bit/pelm/latin1.8.font + exec rio + } +case con + prompt=('cpu% ' ' ') + news +} diff --git a/usr/glenda/readme.acme b/usr/glenda/readme.acme new file mode 100644 index 000000000..18cc16ad0 --- /dev/null +++ b/usr/glenda/readme.acme @@ -0,0 +1,102 @@ +Welcome to acme, the editor/shell/window system hybrid. Acme is a +complete environment you can use to edit, run programs, browse the +file system, etc. + +You can scroll the text this window by moving the mouse into +the window (no clicking necessary) and typing the up and down +arrows. + +When you start Acme, you see several windows layered into two +columns. Above each window, you can see a ``tag line'' (in blue). The +first thing to notice is that all the text you see is just that: +text. You can edit anything at will. + +For example, in the left column is a directory window. +If you look at the window's tag line, you will see that it contains + + /usr/glenda/ Del Snarf Get | Look + +(This might be truncated if the column is narrow.) +That is just text. + +Each mouse button (1, 2, 3, from left to right) does a different +thing in Acme: + + * Button 1 can be used to select text (press it, sweep, release it), + and also to select the point where text would be inserted in the + window. Use it now in your /usr/glenda window. + * Button 2 can be used to execute things. For example, use button 1 + to type "ls -l" before "lib/" in the window showing + /usr/glenda. Now use button 2 to select "ls -l lib/" (press + it, select, release it). As you can see, button 2 means + "execute this". + * Button 3 can be used to get things. For example, click button 3 on + "lib/" within the "/usr/glenda" window. Can you see how a new window + shows the contents of "/usr/glenda/lib"? Button 3 can also be used + to search within the body of a window. Just click button 3 on the + thing you want to search. Again, you can select something with + button 1 and then use button 3 on the selection. + +You can double-click with button 1 to select words; a double click at +the end or beginning of a line selects the whole line. Once you have +text selected, you can click on it with button 2 to execute the +selected text. A single click of button 2 would execute the word +clicked as a command. + +Now let's pay attention to the tag line once more. As you can see, +the left part has a path. That is the name for the window and shows +also the directory for the thing shown (file/directory/program +output). When you execute something using button 2, the current +directory for the command is the directory shown in the left part of +the tag (if the thing shown is a file, its directory is used). + +As you saw before in the example, there are windows labeled +"/dir/+Errors", that is where Acme shows the output of a command +executed in "/dir". + +Another thing you can see is that tag lines contain words like "New", +"Del", "Snarf", etc. Those are commands understood (implemented) by +Acme. When you request execution of one of them, Acme does the job. +For example, click with button 2 on "Del" in the +"/usr/glenda/+Errors" window: it's gone. + +The commands shown by Acme are just text and by no means special. Try +to type "Del" within the body of the window "/usr/glenda", and then +click (button-2) on it. + +These are some commands understood by Acme: + * Newcol: create a new column of windows + * Delcol: delete a column + * New: create a new window (edit it's tag to be a file name and you + would be creating a new file; you would need to click on "Put" to + put the file in the file system). + * Put: write the body to disk. The file is the one named in the tag. + * Get: refresh the body (e.g. if it's a directory, reread it and + show it). + * Snarf: What other window systems call "Copy". + * Paste: Can you guess it? + * Exit: exit acme + +Acme likes to place new windows itself. If you prefer to change the +layout of a window, you only need to drag the layout box at the left +of the tag line and drop it somewhere else. The point where you drop +it selects the column where the window is to be placed now, as well +as the line where the window should start. You can also click the +layout box to enlarge its window a small amount (button 1), as much +as possible without obscuring other tag lines in the column (button +2), and to fill the whole column (button 3). You can get your other +windows back by button-1- or button-2-clicking the layout box. + +This is mostly what you need to get started with Acme. You are +missing a very useful feature: using combinations (chords) of mouse +buttons to do things. You can cut, paste, snarf, and pass arguments +to programs using these mouse chords. You can read this in the +acme(1) manual page, but it's actually extremely simple: Select a +region with button 1 but don't release the button. Now clicking +button 2 deletes the selected text (putting it into the snarf +buffer); clicking button 3 replaces the selected text with the snarf +buffer. That's it! + +For more information, read /sys/doc/acme/acme.ps (you can just +button-3 click on that string to view the file). + diff --git a/usr/glenda/readme.rio b/usr/glenda/readme.rio new file mode 100644 index 000000000..0eb0e44db --- /dev/null +++ b/usr/glenda/readme.rio @@ -0,0 +1,178 @@ +Rio is the Plan 9 window system. + +To read more of this window, the up and down arrows +scroll the text up and down half screens. + +To effectively use rio, you need at least a three +button mouse. If you only have a two button mouse you +can emulate the middle button by holding down shift key +whilst pressing the right button. + +Button 1, 2, and 3 are used to refer to the left, +middle, and right buttons respectively. + +THE POP-UP MENU + +Pressing and holding down button 3 on the desktop or +shell window will give you a menu with the following +options: + + * New - create a new window + * Resize - reshape a window + * Move - move a window without reshaping it + * Delete - close a window + * Hide - hides a window from display (it will appear + in this menu) + *