boot(8): fix it
This commit is contained in:
parent
3029059953
commit
1b1fac3874
11 changed files with 111 additions and 415 deletions
|
@ -16,7 +16,3 @@ $BOOTFILES: $BOOTDIR/boot.h
|
|||
|
||||
%.$O: $BOOTDIR/%.c
|
||||
$CC -I$BOOTDIR $CFLAGS $BOOTDIR/$stem.c
|
||||
|
||||
tread: tread.c
|
||||
$CC tread.c
|
||||
$LD -o tread tread.8
|
||||
|
|
|
@ -13,15 +13,10 @@ mtcp = (configtcp connecttcp)
|
|||
mtab = (mlocal mtcp)
|
||||
config=1
|
||||
connect=2
|
||||
bootargs=()
|
||||
|
||||
. /rc/lib/conf.rc
|
||||
. /rc/lib/menu.rc
|
||||
. /rc/lib/local.rc
|
||||
. /rc/lib/tcp.rc
|
||||
|
||||
cputype=`{cat '#e'/cputype}
|
||||
|
||||
fn fatal {
|
||||
echo $*
|
||||
exit $"*
|
||||
|
@ -31,74 +26,66 @@ fn must {
|
|||
$* || fatal $"*^': '^$status
|
||||
}
|
||||
|
||||
fn devinit{
|
||||
bind -qa '#c' /dev
|
||||
bind -qa '#S' /dev
|
||||
bind -qa '#f' /dev
|
||||
bind -qa '#k' /dev
|
||||
bind -qa '#æ' /dev
|
||||
}
|
||||
|
||||
fn usbinit{
|
||||
if(test -e '#u'){
|
||||
bind -a '#u' /dev
|
||||
usb/usbd
|
||||
fn ask {
|
||||
echo -n $1
|
||||
echo -n $2
|
||||
if(! ~ $#3 0){
|
||||
echo -n ' ['
|
||||
echo -n $3
|
||||
echo -n '] '
|
||||
}
|
||||
}
|
||||
|
||||
fn kbmap{
|
||||
if(! ~ $#kbmap 0){
|
||||
bind -a '#κ' /dev
|
||||
cat $kbmap > /dev/kbmap
|
||||
$1=`{read}
|
||||
if(~ $#$1 0)
|
||||
$1=$3
|
||||
if(~ $"$1 '!rc'){
|
||||
rc -i
|
||||
$1=()
|
||||
}
|
||||
if(~ $#$1 0)
|
||||
ask $*
|
||||
}
|
||||
|
||||
fn readmethod{
|
||||
echo
|
||||
echo Storage devices
|
||||
for(i in /dev/sd[A-Z][0-9]*){
|
||||
echo -n local!^$i' '
|
||||
echo `{sed 's/inquiry[ ]+//g; q' $i/ctl}\
|
||||
partitions: `{cat $i/ctl | grep part | awk '{print $2}'}
|
||||
}
|
||||
|
||||
found=0
|
||||
while(~ $found 0){
|
||||
timeo=5
|
||||
resp=()
|
||||
while(~ $#resp 0){
|
||||
echo -n 'root is from: '
|
||||
resp=`{tread $timeo}
|
||||
if(! ~ $status ''){
|
||||
bootconf # set configuration from file
|
||||
if(! ~ $#nobootprompt 0)
|
||||
bootargs=$nobootprompt
|
||||
resp=$bootargs
|
||||
}
|
||||
if(~ $resp !rc)
|
||||
rc -i
|
||||
timeo=0
|
||||
if(~ $#nobootprompt 0){
|
||||
echo
|
||||
showlocaldevs
|
||||
ask bootargs ' are? (tcp, local!device)' $"bootargs
|
||||
}
|
||||
|
||||
method=`{echo $resp | awk -F! '{print $1}'}
|
||||
NF=`{echo $resp | awk -F! '{print NF}'}
|
||||
|
||||
if not {
|
||||
bootargs=$nobootprompt
|
||||
nobootprompt=()
|
||||
}
|
||||
method=`{echo $bootargs | awk -F! '{print $1}'}
|
||||
NF=`{echo $bootargs | awk -F! '{print NF}'}
|
||||
for(i in `{seq 1 $#mtab}){
|
||||
if(~ $mtab($i) m^$method)
|
||||
found = $i
|
||||
found=$i
|
||||
}
|
||||
if(~ $found 0){
|
||||
if(~ $found 0)
|
||||
echo method $method not found
|
||||
}
|
||||
}
|
||||
|
||||
methodarg = `{echo $resp | sed 's/^[A-Za-z]+!(.*)$/\1/'}
|
||||
methodarg = `{echo $bootargs | awk -F! '{print $2}'}
|
||||
mp = $$mtab($found)
|
||||
}
|
||||
|
||||
fn authentication{
|
||||
fn main{
|
||||
rm -f /srv/boot
|
||||
|
||||
readmethod
|
||||
$mp($config) $methodarg
|
||||
|
||||
switch($method){
|
||||
case local
|
||||
islocal=1
|
||||
case hybrid
|
||||
ishybrid=1
|
||||
}
|
||||
|
||||
# authentication agent
|
||||
if(! test -f /srv/factotum){
|
||||
x=(auth/factotum -sfactotum)
|
||||
x=(/boot/factotum -sfactotum)
|
||||
if(~ $cpuflag 1)
|
||||
x=($x -kS)
|
||||
if not
|
||||
|
@ -109,38 +96,20 @@ fn authentication{
|
|||
x=($x -p)
|
||||
must $x
|
||||
}
|
||||
}
|
||||
|
||||
fn swapproc{
|
||||
if(test -x '#c'/swap)
|
||||
echo -n start > '#c'/swap
|
||||
}
|
||||
|
||||
fn main{
|
||||
readmethod
|
||||
$mp($config)
|
||||
|
||||
switch($method){
|
||||
case local
|
||||
islocal=1
|
||||
case hybrid
|
||||
ishybrid=1
|
||||
}
|
||||
|
||||
# authentication agent
|
||||
authentication
|
||||
|
||||
# connect to the root file system
|
||||
$mp($connect)
|
||||
$mp($connect) $methodarg
|
||||
|
||||
# mount root filesystem
|
||||
must mount -c /srv/boot /root
|
||||
|
||||
swapproc
|
||||
# start pager
|
||||
if(test -x /dev/swap)
|
||||
echo -n start >/dev/swap
|
||||
|
||||
# remove part of our temporary root
|
||||
unmount /$cputype/bin /bin
|
||||
/mnt/broot/$cputype/bin/unmount /$cputype/bin /bin
|
||||
/mnt/broot/$cputype/bin/unmount /rc/bin /bin
|
||||
/mnt/broot/$cputype/bin/unmount /boot /bin
|
||||
/mnt/broot/$cputype/bin/unmount /
|
||||
|
||||
# create the name space, mount the root fs
|
||||
|
@ -165,12 +134,26 @@ fn main{
|
|||
|
||||
bind -q '#p' /proc
|
||||
|
||||
devinit
|
||||
usbinit # set up usb keyboard, mouse, and disk, if any
|
||||
kbmap
|
||||
bind -qa '#S' /dev
|
||||
bind -qa '#f' /dev
|
||||
bind -qa '#k' /dev
|
||||
bind -qa '#æ' /dev
|
||||
|
||||
if(test -e '#u'){
|
||||
bind -a '#u' /dev
|
||||
usb/usbd
|
||||
sleep 1
|
||||
}
|
||||
|
||||
if(! ~ $#kbmap 0){
|
||||
bind -a '#κ' /dev
|
||||
if(test -r $"kbmap)
|
||||
cat $"kbmap >/dev/kbmap
|
||||
}
|
||||
|
||||
configlocal # add partitions and binds
|
||||
|
||||
while(){
|
||||
@{rfork n; main}
|
||||
while()@{
|
||||
rfork n
|
||||
main
|
||||
}
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
#!/bin/rc
|
||||
|
||||
mounted=0
|
||||
found=0
|
||||
|
||||
fn confmount{
|
||||
part=`{echo $1 | sed 's!^.*/!!g; s!''$!!g'}
|
||||
|
||||
switch($part){
|
||||
case dos
|
||||
mprog=dossrv
|
||||
case 9fat
|
||||
mprog=dossrv
|
||||
case fd?disk
|
||||
mprog=dossrv
|
||||
case data
|
||||
mprog=9660srv
|
||||
case *
|
||||
mprog=0
|
||||
mounted=0
|
||||
}
|
||||
|
||||
if(! ~ $mprog 0){
|
||||
$mprog -f $1 conf >/dev/null >[2=1]
|
||||
mount /srv/conf /mnt/conf
|
||||
mounted=1
|
||||
}
|
||||
}
|
||||
|
||||
fn findconf{
|
||||
for(d in /dev/sd*)
|
||||
for(p in `{ls $d}){
|
||||
if(~ $found 0){
|
||||
confmount $p
|
||||
if(test -e /mnt/conf/plan9.ini)
|
||||
found=1
|
||||
if(test $mounted -eq 1 -a $found -eq 0){
|
||||
unmount /mnt/conf
|
||||
rm /srv/conf
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn bootconf{
|
||||
findconf
|
||||
if(~ $found 1)
|
||||
parseconf
|
||||
}
|
|
@ -1,23 +1,39 @@
|
|||
#!/bin/rc
|
||||
|
||||
fn configlocal{
|
||||
disk=`{echo $methodarg | sed 's,(.*)!.*,\1,g'}
|
||||
fstype=`{echo $disk | sed 's,.*/(.*)$,\1,g'}
|
||||
disk=`{echo $disk | sed 's,(.*)/.*$,\1,'}
|
||||
fn showlocaldevs{
|
||||
echo local devices found:
|
||||
for(c in /dev/sd*/ctl){
|
||||
d=`{echo $c | sed 's,/ctl,,g'}
|
||||
echo $d':' `{sed 's/inquiry[ ]+//g; q' $c}
|
||||
for(i in `{awk '/^part/{print $2}' $c})
|
||||
echo $d'/'$i
|
||||
echo
|
||||
}
|
||||
}
|
||||
|
||||
fn configlocal{
|
||||
if(~ $pcload 1){
|
||||
kern=`{echo $* | sed 's,.*!(.*)$,\1,g'}
|
||||
|
||||
# for now we only allow kernels in the same dev/part of $methodargs
|
||||
if(~ $#kern 0 || ! ~ $#bootfile 0)
|
||||
kern=`{echo $bootfile | sed 's,.*!(.*)$,\1,g'}
|
||||
}
|
||||
diskparts
|
||||
|
||||
}
|
||||
|
||||
fn connectlocal{
|
||||
rm -f /srv/boot
|
||||
switch($fstype){
|
||||
part=`{echo $* | sed 's,.*/([^ ]+),\1,g'}
|
||||
part=$part(1)
|
||||
switch($part){
|
||||
case kfs fs
|
||||
must disk/kfs -n boot -f $disk^/$fstype
|
||||
must disk/kfs -n boot -f $*
|
||||
case cwfs fscache fsworm w0 w1 w2 w3
|
||||
must cwfs64x -n boot -f $disk^/$fstype
|
||||
must cwfs64x -n boot -f $*
|
||||
case data
|
||||
must 9660srv -f $disk^/$fstype boot
|
||||
must 9660srv -f $* boot
|
||||
case *
|
||||
fatal unknown partition $fstype
|
||||
fatal unknown partition $part
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,134 +0,0 @@
|
|||
#!/bin/rc
|
||||
|
||||
conffile=/mnt/conf/plan9.ini
|
||||
items=()
|
||||
|
||||
fn menuitems{
|
||||
oifs=$ifs
|
||||
ifs='
|
||||
'
|
||||
# get menu items and save them in the form 'item\tstring'
|
||||
x=(`{awk -F'\n' '
|
||||
$0 ~ /\[menu\]/ {
|
||||
FS="[= ]"
|
||||
for(nitem=1;;nitem++){
|
||||
getline
|
||||
if(match($0, /\[/)) # if we entered a block, we are done
|
||||
break
|
||||
sub(/\,/, "") # remove comma
|
||||
if(match($0, /^#/)) # comments
|
||||
continue
|
||||
if(match($0, /^$/)) # empty line
|
||||
continue
|
||||
printf("%s\t\" %d. ", $2, nitem)
|
||||
for(i=3; i <= NF; i++)
|
||||
printf("%s ", $i)
|
||||
printf("\"\t\n")
|
||||
}
|
||||
}
|
||||
' $conffile})
|
||||
|
||||
ifs=' '
|
||||
for(itemline in $x){
|
||||
# separate item from string
|
||||
item=`{echo $itemline(1)}
|
||||
|
||||
# $menuitemtext holds the string for the item
|
||||
$item(1)^text=$item(2)
|
||||
items=($items $item(1))
|
||||
}
|
||||
if(! ~ $#items 0){
|
||||
echo 'Plan 9 Startup Menu:'
|
||||
echo '--------------------'
|
||||
}
|
||||
ifs=$oifs
|
||||
}
|
||||
|
||||
# load block definitions
|
||||
fn menublock{
|
||||
for(i in `{
|
||||
awk -F'\n' -v item'='`{echo '['$1']' | sed 's/ //g'} '
|
||||
{
|
||||
# find menuitem block
|
||||
if(index($0, item)){
|
||||
for(;;){
|
||||
if(getline <= 0)
|
||||
break
|
||||
if(match($0, /\[/)) # entered a block, we are done
|
||||
break
|
||||
if(match($0, /^$/))
|
||||
continue
|
||||
|
||||
# skip comments, quote kernel devices
|
||||
if(index($0, "#") == 1)
|
||||
continue
|
||||
else
|
||||
gsub("#", "''#''")
|
||||
printf("%s\n", $1)
|
||||
}
|
||||
}
|
||||
}' $conffile}){
|
||||
name=`{echo $i | awk -F'=' '{print $1}'}
|
||||
val=`{echo $i | awk -F'=' '{print $2}'}
|
||||
|
||||
# a name beginning with * denotes
|
||||
# a kernel variable, save to #ec
|
||||
v0=`{echo $i | sed 's/(\*).*/\1/'}
|
||||
if(~ $v0 '*'){
|
||||
bind -bc '#ec' /env
|
||||
eval $name'='$val
|
||||
unmount '#ec' /env
|
||||
}
|
||||
if not
|
||||
eval $name'='$val
|
||||
}
|
||||
}
|
||||
|
||||
fn freevars{
|
||||
for(i in `{
|
||||
awk -F'\n' '{
|
||||
if(match($0, /\[/)) # entered a block, we are done
|
||||
exit
|
||||
if(match($0, /^$/))
|
||||
exit
|
||||
# skip comments, quote kernel devices
|
||||
if(index($0, "#") == 1)
|
||||
exit
|
||||
else
|
||||
gsub("#", "''#''")
|
||||
printf("%s\n", $1)
|
||||
}' $conffile}){
|
||||
# a name beginning with * denotes
|
||||
# a kernel variable, save to #ec
|
||||
val=`{echo $i | sed 's/(\*).*/\1/'}
|
||||
if(~ $val '*'){
|
||||
bind -bc '#ec' /env
|
||||
eval $i
|
||||
unmount '#ec' /env
|
||||
}
|
||||
if not eval $i
|
||||
}
|
||||
}
|
||||
|
||||
fn parseconf{
|
||||
opt=0
|
||||
if(test -f $conffile){
|
||||
freevars
|
||||
menuitems
|
||||
menublock 'common'
|
||||
|
||||
if(! ~ $#items 0){
|
||||
while(test $opt -lt 1 || test $opt -gt $#items){
|
||||
for(item in $items)
|
||||
echo -n $`{echo $item^text} | sed 's/"//g'
|
||||
|
||||
echo -n ' Selection: '
|
||||
opt=`{read}
|
||||
|
||||
if(test $opt -ge 1 && test $opt -le $#items)
|
||||
menublock $items($opt)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,61 +1,25 @@
|
|||
#!/bin/rc
|
||||
|
||||
fn isvalidip{
|
||||
# TODO: more precise test
|
||||
if(! ~ $#1 0 && ! test `{echo $1 | sed '/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/d'})
|
||||
echo -n
|
||||
}
|
||||
|
||||
fn configtcp{
|
||||
# TODO:
|
||||
# should we accept a different mount point?
|
||||
# should we add more interfaces?
|
||||
|
||||
# bind in an ip interface
|
||||
for(i in I l`{seq 0 3})
|
||||
bind -a '#'$i /net >/dev/null >[2=1]
|
||||
|
||||
if(! test -x /bin/ip/ipconfig){
|
||||
echo no ipconfig
|
||||
exit noipconfig
|
||||
}
|
||||
|
||||
ip/ipconfig # TODO: should receive args passed to boot(8)
|
||||
must ip/ipconfig -p $*
|
||||
|
||||
# XXX: should configuration from file override the values from ipconfig(8)?
|
||||
if(~ $#fs 0){
|
||||
_fsip=`{grep fs /net/ndb | awk -F'=' '{print $2}' >/dev/null >[2=1]}
|
||||
if(! ~ $#_fsip 0 && `{isvalidip $_fsip})
|
||||
fsip=$_fsip
|
||||
}
|
||||
|
||||
# if we didn't get a file and auth server from either
|
||||
# the configuration file or ipconfig(8), ask the user
|
||||
if(~ $#fsip 0){
|
||||
while(! isvalidip $fsip){
|
||||
echo -n 'filesystem IP address: '
|
||||
fsip=`{read}
|
||||
}
|
||||
}
|
||||
if(~ $#fs 0)
|
||||
fs=`{awk -F'=' '/fs=/{print $2; exit}' /net/ndb}
|
||||
if(~ $#auth 0)
|
||||
auth=`{awk -F'=' '/auth=/{print $2; exit}' /net/ndb}
|
||||
if(~ $#fs 0)
|
||||
ask fs ' ip is?' $"auth
|
||||
if(~ $#auth 0)
|
||||
ask auth ' ip is?' $"fs
|
||||
|
||||
if(~ $#auth 0){
|
||||
_authip=`{grep auth /net/ndb | awk -F'=' '{print $2}' >/dev/null >[2=1]}
|
||||
if(! ~ $#_authip 0 && `{isvalidip $_authip})
|
||||
authip=_authip
|
||||
}
|
||||
|
||||
if(~ $#authip 0){
|
||||
while(! isvalidip $authip){
|
||||
echo -n 'authentication server IP address: '
|
||||
authip=`{read}
|
||||
}
|
||||
}
|
||||
|
||||
authaddr=tcp!$authip!567 # leave this for factotum(4)
|
||||
|
||||
rm -f /env/_authip /env/_fsip
|
||||
fsaddr=tcp!$fs!564
|
||||
authaddr=tcp!$auth!567
|
||||
}
|
||||
|
||||
fn connecttcp{
|
||||
srv -q tcp!$fsip!564 boot
|
||||
srv -q $"fsaddr boot
|
||||
}
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
int c;
|
||||
|
||||
int
|
||||
alarmed(void *a, char *msg)
|
||||
{
|
||||
USED(a);
|
||||
USED(msg);
|
||||
if(!c)
|
||||
exits("timedout");
|
||||
noted(NCONT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
readline(int fd, char *buf, int nbuf)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
i = 0;
|
||||
while(i < nbuf-1){
|
||||
n = read(fd, &c, sizeof c);
|
||||
alarm(0);
|
||||
c &= 0xff;
|
||||
write(fd, &c, 1);
|
||||
if(n != 1 || c == '\04' || c == '\177'){
|
||||
i = 0;
|
||||
break;
|
||||
} else if(c == '\n')
|
||||
break;
|
||||
else if(c == '\b' && i > 0)
|
||||
--i;
|
||||
else if(c == ('u' & 037)){
|
||||
c = '\b';
|
||||
for(n=0; n <= i; n++)
|
||||
write(fd, &c, 1);
|
||||
i = 0;
|
||||
} else
|
||||
buf[i++] = c;
|
||||
}
|
||||
buf[i] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int fd, ctl, i;
|
||||
char buf[256];
|
||||
long n;
|
||||
|
||||
if(argc < 2)
|
||||
sysfatal("usage: tread timeout");
|
||||
|
||||
atnotify(alarmed, 1);
|
||||
|
||||
fd = open("/dev/cons", ORDWR);
|
||||
if(fd < 0)
|
||||
sysfatal("open cons: %r");
|
||||
ctl = open("/dev/consctl", OWRITE);
|
||||
if(ctl < 0)
|
||||
sysfatal("open consctl: %r");
|
||||
|
||||
write(ctl, "rawon", 5);
|
||||
alarm(atoi(argv[1])*1000);
|
||||
|
||||
readline(fd, buf, sizeof(buf));
|
||||
close(ctl);
|
||||
close(fd);
|
||||
print("%s", buf);
|
||||
exits(nil);
|
||||
}
|
|
@ -132,4 +132,5 @@ bootdir
|
|||
bootpcf.out boot
|
||||
/386/bin/bzfs
|
||||
/386/bin/mntgen
|
||||
/386/bin/auth/factotum
|
||||
rootfs.bz2
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
$cputype
|
||||
bin
|
||||
9660srv
|
||||
auth
|
||||
factotum
|
||||
awk
|
||||
bind
|
||||
bzfs
|
||||
|
@ -28,9 +26,9 @@ $cputype
|
|||
rm
|
||||
sed
|
||||
seq
|
||||
sleep
|
||||
srv
|
||||
test
|
||||
tread 555 sys sys ../boot/tread
|
||||
unmount
|
||||
usb
|
||||
usbd
|
||||
|
@ -38,12 +36,9 @@ $cputype
|
|||
rc
|
||||
lib
|
||||
rcmain
|
||||
conf.rc 555 sys sys ../boot/conf.rc
|
||||
local.rc 555 sys sys ../boot/local.rc
|
||||
menu.rc 555 sys sys ../boot/menu.rc
|
||||
tcp.rc 555 sys sys ../boot/tcp.rc
|
||||
bin
|
||||
diskparts
|
||||
bootrc 555 sys sys ../boot/bootrc
|
||||
tmp
|
||||
|
||||
|
|
|
@ -33,11 +33,6 @@ fn rootbz2 {
|
|||
rm boot.bz2
|
||||
}
|
||||
|
||||
@{cd ../boot
|
||||
. /$cputype/mkfile
|
||||
mk -f bootmkfile tread
|
||||
}
|
||||
|
||||
bootraw
|
||||
bootbz2
|
||||
rootbz2
|
||||
|
|
|
@ -128,7 +128,9 @@ configure(void *f, char *path)
|
|||
Clear:
|
||||
kern = 0;
|
||||
inblock = 0;
|
||||
p = (char*)((CONFADDR + 64) & ~0xF0000000UL);
|
||||
p = (char*)(CONFADDR & ~0xF0000000UL);
|
||||
memset(p, 0, 0xE00);
|
||||
p += 64;
|
||||
Loop:
|
||||
while((n = readline(f, line)) > 0){
|
||||
if(*line == 0 || strchr("#;=", *line))
|
||||
|
|
Loading…
Reference in a new issue