Merge branch 'front' of git://git.9front.org/plan9front/plan9front into front

This commit is contained in:
xfnw 2022-07-11 16:39:58 -04:00
commit 3449d477a2
18 changed files with 429 additions and 102 deletions

View file

@ -11,6 +11,7 @@ d=0
fn roff {
preproc=()
Jpflag=()
postproc=cat
x=`{doctype $2}
if (~ $1 t) {
@ -19,6 +20,8 @@ fn roff {
if(~ $x *pic*)
preproc=($preproc pic)
Nflag=-Tutf
if(grep -s '^.ft Jp|\f\[Jp\]' $2)
Jpflag='-mnihongo'
}
if not {
Nflag='-N'
@ -34,17 +37,17 @@ fn roff {
{echo -n $FONTS; cat $2 </dev/null} |
switch($#preproc) {
case 0
troff $Nflag $Lflag -$MAN
troff $Nflag $Lflag -$MAN $Jpflag
case 1
$preproc | troff $Nflag $Lflag -$MAN
$preproc | troff $Nflag $Lflag -$MAN $Jpflag
case 2
$preproc(1) | $preproc(2) | troff $Nflag $Lflag -$MAN
$preproc(1) | $preproc(2) | troff $Nflag $Lflag -$MAN $Jpflag
case 3
$preproc(1) | $preproc(2) | $preproc(3) |
troff $Nflag $Lflag -$MAN
troff $Nflag $Lflag -$MAN $Jpflag
case *
$preproc(1) | $preproc(2) | $preproc(3) |
$preproc(4) | troff $Nflag $Lflag -$MAN
$preproc(4) | troff $Nflag $Lflag -$MAN $Jpflag
} | $postproc
}

3
sys/lib/dist/mkfile vendored
View file

@ -92,7 +92,8 @@ cd:V: /tmp/9front.386.iso.gz
@{
objtype=arm64
kernel=/n/src9/$objtype/9reform.u
fatfiles=(/n/src9/sys/src/boot/reform/boot.scr $kernel)
echo 'bootargs=local!/dev/sdM0/fs' > /env/plan9.ini
fatfiles=(/n/src9/sys/src/boot/reform/boot.scr /env/plan9.ini $kernel)
mb=1885 # storage vendors idea of 2GB
mk $target.$pid.disk
mv $target.$pid.disk $target && dd -trunc 0 -bs 1024 -oseek 33 -if /n/src9/sys/src/boot/reform/flash.bin -of $target

View file

@ -19,7 +19,7 @@ return to default English mode (no transliteration).
.B ctl-n
Japanese hiragana: interpret lower-case letters as a Hepburn
representation of hiragana. In this mode, typing ctl-\\ looks up the
last `word' in a hiragana-kanji dictionary and replaces it.
last `word' in a kana-kanji dictionary and replaces it.
Subsequent ctl-\\ characters cycle through the possibilities. A word
is the longest immediately preceding unbroken string of hiragana
characters.
@ -28,15 +28,14 @@ characters.
Japanese katakana.
.TP
.B ctl-l
If you want to put the hiragana not converted, you can type.
If you want to put the hiragana without modification.
.TP
.B ctl-x
Read kana-kanji conversion dictionary once more, and renews it. This
will be convenient when you updated kana-kanji conversion dictionary
on such acme editor.In default, the kana-kanji conversion dictionary
is read once at beginning and to make a hashed table, which will be
arranged so that the last selected candidate will be the first
candidate for later search.
Reload the in-memory kana-kanji conversion dictionary (kanji jisho).
This is so you can update the kanji jisho on-the-fly. By default, the
kanji jisho is read once at the beginning, to make a hash table, which
will be arranged so that the last selected candidate will be the first
candidate for later searches.
.TP
.B ctl-r
Russian: interpret letters as Cyrillic; the transliteration is mostly
@ -62,7 +61,10 @@ Greek.
.B ctl-s
Korean.
.PP
To use it you have to run it before a rio session. You can put it on your $home/lib/profile like:
To use
.I ktrans
you have to run it before a rio session. You can put it on your
$home/lib/profile like:
.EX
...
ktrans
@ -74,6 +76,13 @@ or run it with a sub-rio on a window like:
% @{ktrans; rio}
.EE
.PP
The default location of the kanji jisho is
.LR /lib/kanji.jisho .
You can change that by means of the
.L $jisho
environment variable, so you can keep a customized version of the
dictionary that fits your personal needs.
.PP
.SH SOURCE
.B /sys/src/cmd/ktrans
.SH SEE ALSO
@ -86,8 +95,10 @@ or run it with a sub-rio on a window like:
.SH EXAMPLES
If you want to make the Japanese text as below:
.ft Jp
私は毎日35分以上歩いて、 更に10分電車に乗って学校に通います。
健康の維持にも役だっていますが、 なかなかたのしいものです。
.ft
your keyboard typing stream should be:
@ -104,3 +115,7 @@ method.
There is no way to generate the control characters literally. At the
beggining of a new line, you have to begin with ctl-l for successful
kana-kanji conversion.
.SH HISTORY
Ktrans was originally written by Kenji Okamoto in August of 2000 for
the 2nd edition of Plan 9. It was imported in to 9front in July of
2022, with patches by several contributors.

View file

@ -296,7 +296,11 @@ removes access to all kernel drivers from
the child namespace; the
.B -e
flag specifies a string of driver
characters to keep.
characters to keep. The
.B -s
flag gives a base set of namespace
components, ones expected by rc, then passes
the first argument as a script file to rc.
.PP
.I As
executes

View file

@ -146,7 +146,7 @@ enum {
};
static int input_clk_freq[] = {
[ARM_PLL_CLK] 1600*Mhz,
[ARM_PLL_CLK] 1400*Mhz,
[GPU_PLL_CLK] 1600*Mhz,
[VPU_PLL_CLK] 800*Mhz,
[DRAM_PLL1_CLK] 800*Mhz,
@ -977,25 +977,21 @@ enablefracpll(u32int *reg, int ref_sel, int ref_freq, int freq)
error = freq;
for(divq = 2; divq <= 64; divq += 2){
for(divr = 1; divr <= 64; divr++){
for(divr = 2; divr <= 64; divr++){
ref = ref_freq/divr;
if(ref < 10*Mhz || ref > 300*Mhz)
v = (vlong)freq*divq;
v <<= 24;
v /= ref * 8;
divfi = v >> 24;
divff = v & 0xFFFFFF;
if(divfi < 1 || divfi > 128)
continue;
ref *= 8;
divfi = ((vlong)freq*divq) / ref;
if(divfi < 1 || divfi > 32)
continue;
v = ((vlong)freq*divq) - (vlong)ref*divfi;
divff = (v<<24) / ref;
if(divff < 1 || divff > (1<<24))
continue;
v = (vlong)ref*(vlong)divff;
pllout = (ref*divfi + (v>>24))/divq;
if(pllout < 30*Mhz || pllout > 2000*Mhz)
continue;
v *= (vlong)ref * 8;
v /= (vlong)divq << 24;
pllout = v;
if(pllout > freq)
continue;
@ -1003,16 +999,15 @@ enablefracpll(u32int *reg, int ref_sel, int ref_freq, int freq)
if(freq - pllout > error)
continue;
// iprint("%p enablefracpll: freq=%d (actual %d)\n", PADDR(reg), freq, pllout);
cfg0 = 1<<21 | ref_sel<<16 | 1<<15 | (divr-1)<<5 | (divq/2)-1;
cfg1 = divff<<7 | divfi-1;
cfg1 = divff<<7 | (divfi-1);
error = freq - pllout;
if(error == 0)
goto Found;
}
}
panic("enablefracpll: %#p freq %d: out of range", PADDR(reg), freq);
Found:
/* skip if nothing has changed */
@ -1022,19 +1017,16 @@ Found:
reg[0] |= 1<<14; /* bypass */
// iprint("%p cfg1=%.8ux\n", PADDR(reg), cfg1);
reg[1] = cfg1;
// iprint("%p cfg0=%.8ux\n", PADDR(reg), cfg0);
reg[0] = cfg0 | (1<<14) | (1<<12);
/* unbypass */
reg[0] &= ~(1<<14);
// iprint("%p wait for lock...", PADDR(reg));
while((reg[0] & (1<<31)) == 0)
;
// iprint("locked!\n");
reg[0] &= ~(1<<12);
}

View file

@ -29,6 +29,9 @@ localclockintr(Ureg *ureg, void *)
void
clockinit(void)
{
uvlong tstart, tend;
ulong t0, t1;
syswr(PMCR_EL0, 1<<6 | 7);
syswr(PMCNTENSET, 1<<31);
syswr(PMUSERENR_EL0, 1<<2);
@ -40,7 +43,28 @@ clockinit(void)
if(m->machno == 0){
freq = sysrd(CNTFRQ_EL0);
print("timer frequency %lld Hz\n", freq);
/* TURBO! */
setclkrate("ccm_arm_a53_clk_root", "osc_25m_ref_clk", 25*Mhz);
setclkrate("ccm_arm_a53_clk_root", "arm_pll_clk", 1400*Mhz);
}
tstart = sysrd(CNTPCT_EL0);
do{
t0 = lcycles();
}while(sysrd(CNTPCT_EL0) == tstart);
tend = tstart + (freq/100);
do{
t1 = lcycles();
}while(sysrd(CNTPCT_EL0) < tend);
t1 -= t0;
m->cpuhz = 100 * t1;
m->cpumhz = (m->cpuhz + Mhz/2 - 1) / Mhz;
/*
* we are using virtual counter register CNTVCT_EL0
* instead of the performance counter in userspace.
*/
m->cyclefreq = freq;
intrenable(IRQcntpns, localclockintr, nil, BUSUNKNOWN, "clock");
}

View file

@ -655,18 +655,22 @@ ctl(Ether*, void*, long len)
static int
reset(Ether *edev)
{
Ctlr *ctlr = edev->ctlr;
u32int paddr1, paddr2;
enum {
OCOTP_HW_OCOTP_MAC_ADDR0 = 0x640/4,
OCOTP_HW_OCOTP_MAC_ADDR1 = 0x650/4,
};
static u32int *ocotp = (u32int*)(VIRTIO + 0x350000);
u32int a0, a1;
/* steal mac address from uboot */
paddr1 = rr(ctlr, ENET_PALR);
paddr2 = rr(ctlr, ENET_PAUR);
edev->ea[0] = paddr1>>24;
edev->ea[1] = paddr1>>16;
edev->ea[2] = paddr1>>8;
edev->ea[3] = paddr1>>0;
edev->ea[4] = paddr2>>24;
edev->ea[5] = paddr2>>16;
a0 = ocotp[OCOTP_HW_OCOTP_MAC_ADDR0];
a1 = ocotp[OCOTP_HW_OCOTP_MAC_ADDR1];
edev->ea[0] = a1>>8;
edev->ea[1] = a1>>0;
edev->ea[2] = a0>>24;
edev->ea[3] = a0>>16;
edev->ea[4] = a0>>8;
edev->ea[5] = a0>>0;
shutdown(edev);

View file

@ -96,6 +96,10 @@ el2:
MSR R0, MDCR_EL2
ISB $SY
/* set virtual timer offset to zero */
MOV $0, R0
MSR R0, CNTVOFF_EL2
/* HCR = RW, HCD, SWIO, BSU, FB */
MOVWU $(1<<31 | 1<<29 | 1<<2 | 0<<10 | 0<<9), R0
MSR R0, HCR_EL2

View file

@ -440,6 +440,14 @@ dsiparams(struct dsi_cfg *cfg, int lanes, int hs_clk, int ref_clk, int tx_esc_cl
cfg->wakeup_ps = 1000000000000LL;
}
static void
lcdifreset(void)
{
wr(lcdif, LCDIF_CTRL_SET, CTRL_SFTRST);
delay(1);
wr(lcdif, LCDIF_CTRL_SET, CTRL_CLKGATE);
}
static void
lcdifinit(struct video_mode *mode)
{
@ -501,6 +509,11 @@ bridgeinit(I2Cdev *dev, struct video_mode *mode, struct dsi_cfg *cfg)
{
int n;
// soft reset
i2cwritebyte(dev, 0x09, 1);
while(i2creadbyte(dev, 0x09) & 1)
;
// clock derived from dsi clock
switch(cfg->hs_clk/2000000){
case 384:
@ -812,6 +825,12 @@ backlighton(void)
gpioout(GPIO_PIN(1, 10), 1);
}
void
blankscreen(int blank)
{
gpioout(GPIO_PIN(1, 10), blank == 0);
}
void
lcdinit(void)
{
@ -832,8 +851,10 @@ lcdinit(void)
gpioout(GPIO_PIN(3, 20), 1);
bridge = i2cdev(i2cbus("i2c4"), 0x2C);
if(bridge == nil)
return;
if(bridge == nil){
err = "could not find bridge";
goto out;
}
bridge->subaddr = 1;
/* power on mipi dsi */
@ -852,6 +873,8 @@ lcdinit(void)
setclkgate("disp.axi_clk", 1);
setclkgate("sim_display.mainclk", 1);
lcdifreset();
setclkrate("mipi.core", "system_pll1_div3", 266*Mhz);
setclkrate("mipi.CLKREF", "system_pll2_clk", 25*Mhz);
setclkrate("mipi.RxClkEsc", "system_pll1_clk", 80*Mhz);

View file

@ -10,8 +10,118 @@
#include "sysreg.h"
#include "ureg.h"
#include "rebootcode.i"
Conf conf;
#define MAXCONF 64
static char *confname[MAXCONF];
static char *confval[MAXCONF];
static int nconf;
void
bootargsinit(void)
{
int i, j, n;
char *cp, *line[MAXCONF], *p, *q;
/*
* parse configuration args from dos file plan9.ini
*/
cp = BOOTARGS; /* where b.com leaves its config */
cp[BOOTARGSLEN-1] = 0;
/*
* Strip out '\r', change '\t' -> ' '.
*/
p = cp;
for(q = cp; *q; q++){
if(*q == -1)
break;
if(*q == '\r')
continue;
if(*q == '\t')
*q = ' ';
*p++ = *q;
}
*p = 0;
n = getfields(cp, line, MAXCONF, 1, "\n");
for(i = 0; i < n; i++){
if(*line[i] == '#')
continue;
cp = strchr(line[i], '=');
if(cp == nil)
continue;
*cp++ = '\0';
for(j = 0; j < nconf; j++){
if(cistrcmp(confname[j], line[i]) == 0)
break;
}
confname[j] = line[i];
confval[j] = cp;
if(j == nconf)
nconf++;
}
}
char*
getconf(char *name)
{
int i;
for(i = 0; i < nconf; i++)
if(cistrcmp(confname[i], name) == 0)
return confval[i];
return nil;
}
void
setconfenv(void)
{
int i;
for(i = 0; i < nconf; i++){
if(confname[i][0] != '*')
ksetenv(confname[i], confval[i], 0);
ksetenv(confname[i], confval[i], 1);
}
}
void
writeconf(void)
{
char *p, *q;
int n;
p = getconfenv();
if(waserror()) {
free(p);
nexterror();
}
/* convert to name=value\n format */
for(q=p; *q; q++) {
q += strlen(q);
*q = '=';
q += strlen(q);
*q = '\n';
}
n = q - p + 1;
if(n >= BOOTARGSLEN)
error("kernel configuration too large");
memmove(BOOTARGS, p, n);
memset(BOOTARGS+n, 0, BOOTARGSLEN-n);
poperror();
free(p);
}
int
isaconfig(char *, int, ISAConf *)
{
return 0;
}
/*
* starting place for first process
*/
@ -29,6 +139,7 @@ init0(void)
else
ksetenv("service", "terminal", 0);
ksetenv("console", "0", 0);
setconfenv();
poperror();
}
kproc("alarm", alarmkproc, 0);
@ -124,7 +235,7 @@ mpinit(void)
MACHP(i)->machno = i;
cachedwbinvse(MACHP(i), MACHSIZE);
u.r0 = 0x84000003;
u.r0 = 0x84000003; /* CPU_ON */
u.r1 = (sysrd(MPIDR_EL1) & ~0xFF) | i;
u.r2 = PADDR(_start);
u.r3 = i;
@ -134,6 +245,12 @@ mpinit(void)
spllo();
}
void
cpuidprint(void)
{
iprint("cpu%d: %dMHz ARM Cortex A53\n", m->machno, m->cpumhz);
}
void
main(void)
{
@ -143,6 +260,7 @@ main(void)
fpuinit();
intrinit();
clockinit();
cpuidprint();
synccycles();
timersinit();
flushtlb();
@ -152,6 +270,7 @@ main(void)
return;
}
quotefmtinstall();
bootargsinit();
meminit();
confinit();
xinit();
@ -162,6 +281,7 @@ main(void)
fpuinit();
intrinit();
clockinit();
cpuidprint();
timersinit();
pageinit();
procinit0();
@ -180,35 +300,64 @@ main(void)
void
exit(int)
{
Ureg u = { .r0 = 0x84000009 };
Ureg u = { .r0 = 0x84000002 }; /* CPU_OFF */
cpushutdown();
splfhi();
/* system reset */
if(m->machno == 0)
u.r0 = 0x84000009; /* SYSTEM RESET */
smccall(&u);
}
int
isaconfig(char *, int, ISAConf *)
static void
rebootjump(void *entry, void *code, ulong size)
{
return 0;
}
void (*f)(void*, void*, ulong);
char*
getconf(char *)
{
return nil;
intrcpushutdown();
/* redo identity map */
mmuidmap((uintptr*)L1);
/* setup reboot trampoline function */
f = (void*)REBOOTADDR;
memmove(f, rebootcode, sizeof(rebootcode));
cachedwbinvse(f, sizeof(rebootcode));
cacheiinvse(f, sizeof(rebootcode));
(*f)(entry, code, size);
for(;;);
}
void
writeconf(void)
reboot(void*, void *code, ulong size)
{
}
writeconf();
while(m->machno != 0){
procwired(up, 0);
sched();
}
void
reboot(void *, void *, ulong)
{
cpushutdown();
delay(2000);
splfhi();
/* turn off buffered serial console */
serialoq = nil;
/* shutdown devices */
chandevshutdown();
/* stop the clock */
clockshutdown();
intrsoff();
/* off we go - never to return */
rebootjump((void*)(KTZERO-KZERO), code, size);
}
void

View file

@ -44,9 +44,8 @@
#define UCRAMSIZE (8*MiB)
#define VDRAM (0xFFFFFFFFC0000000ULL) /* 0x40000000 - 0x80000000 */
#define KTZERO (VDRAM + 0x100000) /* kernel text start */
#define KTZERO (VDRAM + 0x100000) /* 0x40100000 - kernel text start */
#define ARMLOCAL (0xFFFFFFFFB1000000ULL) /* 0x31000000 */
#define VIRTIO (0xFFFFFFFFB0000000ULL) /* 0x30000000 */
#define KZERO (0xFFFFFFFF80000000ULL) /* 0x00000000 - kernel address space */
@ -64,6 +63,13 @@
#define MACHADDR(n) (KTZERO-((n)+1)*MACHSIZE)
#define CONFADDR (VDRAM + 0x10000) /* 0x40010000 */
#define BOOTARGS ((char*)CONFADDR)
#define BOOTARGSLEN 0x10000
#define REBOOTADDR (VDRAM-KZERO + 0x20000) /* 0x40020000 */
#define UZERO 0ULL /* user segment */
#define UTZERO (UZERO+0x10000) /* user text start */
#define USTKTOP ((EVAMASK>>1)-0xFFFF) /* user segment end +1 */

View file

@ -87,8 +87,15 @@ install:V: /$objtype/$p$CONF
<../port/portmkfile
<|../port/mkbootrules $CONF
main.$O: rebootcode.i
pciimx.$O: ../port/pci.h
initcode.out: init9.$O initcode.$O /$objtype/lib/libc.a
$LD -l -R1 -s -o $target $prereq
rebootcode.out: rebootcode.$O cache.v8.$O
$LD -l -H6 -R1 -T0x40020000 -s -o $target $prereq
$CONF.clean:
rm -rf $p$CONF $p$CONF.u errstr.h $CONF.c boot$CONF.c

View file

@ -60,6 +60,24 @@ mmu0clear(uintptr *l1)
l1[PTL1X(pa, 3)] = 0;
}
void
mmuidmap(uintptr *l1)
{
uintptr va, pa, pe;
pe = -VDRAM;
for(pa = VDRAM - KZERO, va = VDRAM; pa < pe; pa += PGLSZ(1), va += PGLSZ(1))
l1[PTL1X(pa, 1)] = l1[PTL1X(va, 1)];
if(PTLEVELS > 2)
for(pa = VDRAM - KZERO, va = VDRAM; pa < pe; pa += PGLSZ(2), va += PGLSZ(2))
l1[PTL1X(pa, 2)] = l1[PTL1X(va, 2)];
if(PTLEVELS > 3)
for(pa = VDRAM - KZERO, va = VDRAM; pa < pe; pa += PGLSZ(3), va += PGLSZ(3))
l1[PTL1X(pa, 3)] = l1[PTL1X(va, 3)];
setttbr(PADDR(&l1[L1TABLEX(0, PTLEVELS-1)]));
flushtlb();
}
void
mmu1init(void)
{

View file

@ -0,0 +1,48 @@
#include "mem.h"
#include "sysreg.h"
#undef SYSREG
#define SYSREG(op0,op1,Cn,Cm,op2) SPR(((op0)<<19|(op1)<<16|(Cn)<<12|(Cm)<<8|(op2)<<5))
TEXT _start(SB), 1, $-4
MOV $setSB(SB), R28
MOV R0, R27
MOV code+8(FP), R1
MOVWU size+16(FP), R2
BIC $3, R2
ADD R1, R2, R3
_copy:
MOVW (R1)4!, R4
MOVW R4, (R0)4!
CMP R1, R3
BNE _copy
BL cachedwbinv(SB)
BL l2cacheuwbinv(SB)
ISB $SY
MRS SCTLR_EL1, R0
BIC $(1<<0 | 1<<2 | 1<<12), R0
ISB $SY
MSR R0, SCTLR_EL1
ISB $SY
DSB $NSHST
TLBI R0, 0,8,7,0 /* VMALLE1 */
DSB $NSH
ISB $SY
BL cachedwbinv(SB)
BL cacheiinv(SB)
MOVWU $0, R0
MOVWU $0, R1
MOVWU $0, R2
MOVWU $0, R3
MOV R27, LR
RETURN

View file

@ -178,11 +178,6 @@ setcolor(ulong p, ulong r, ulong g, ulong b)
return 0;
}
void
blankscreen(int)
{
}
static void
myscreenputs(char *s, int n)
{

View file

@ -38,6 +38,7 @@
#define CNTP_TVAL_EL0 SYSREG(3,3,14,2,0)
#define CNTP_CTL_EL0 SYSREG(3,3,14,2,1)
#define CNTP_CVAL_EL0 SYSREG(3,3,14,2,2)
#define CNTVOFF_EL2 SYSREG(3,4,14,0,3)
#define TPIDR_EL0 SYSREG(3,3,13,0,2)
#define TPIDR_EL1 SYSREG(3,0,13,0,4)

View file

@ -1,2 +1,4 @@
load ${devtype} ${devnum}:${bootpart} ${kernel_addr_r} ${prefix}9reform.u
bootm ${kernel_addr_r}
mw.b 0x40010000 0x0 0x10000
load ${devtype} ${devnum}:${bootpart} 0x40010000 ${prefix}plan9.ini
load ${devtype} ${devnum}:${bootpart} 0x40100000 ${prefix}9reform.u
bootm 0x40100000

View file

@ -10,11 +10,11 @@ binderr(char *new, char *old, int flag)
char dash[4] = { '-' };
if(debug){
if(flag & MCREATE){
if(flag & MCREATE)
dash[2] = 'c';
flag &= ~MCREATE;
}
switch(flag){
case MCREATE|MREPL:
case MREPL:
dash[0] = ' ';
if(dash[2] == 'c')
@ -133,26 +133,40 @@ skelfs(void)
sysfatal("/mnt/d mount setup: %r");
}
static char *parts[256];
static int mflags[nelem(parts)];
static int nparts;
static char *rc[] = { "/bin/rc", nil , nil};
static void
push(char *path, int flag)
{
if(nparts == nelem(parts))
sysfatal("component overflow");
parts[nparts] = path;
mflags[nparts++] = flag;
}
void
usage(void)
{
fprint(2, "usage %s: [ -d ] [ -r file ] [ -c dir ] [ -e devs ] cmd args...\n", argv0);
fprint(2, "usage %s: [ -d ] [ -r file ] [ -c dir ] [ -e devs ] [ -. path ] cmd args...\n", argv0);
exits("usage");
}
void
main(int argc, char **argv)
{
char *b;
Dir *d;
char devs[1024];
int dfd;
char *parts[256];
int mflags[256];
int nparts;
char *path;
char *a;
int sflag;
nparts = 0;
path = "/";
memset(devs, 0, sizeof devs);
sflag = 0;
ARGBEGIN{
case 'D':
debug++;
@ -160,35 +174,48 @@ main(int argc, char **argv)
debug++;
break;
case 'r':
parts[nparts] = EARGF(usage());
mflags[nparts++] = MREPL;
a = EARGF(usage());
push(a, MREPL);
break;
case 'c':
parts[nparts] = EARGF(usage());
mflags[nparts++] = MCREATE|MREPL;
a = EARGF(usage());
push(a, MREPL|MCREATE);
break;
case 'e':
snprint(devs, sizeof devs, "%s%s", devs, EARGF(usage()));
break;
case '.':
path = EARGF(usage());
break;
case 's':
sflag = 1;
break;
default:
usage();
break;
}ARGEND
if(argc == 0)
usage();
b = argv[0];
d = dirstat(b);
if(d == nil){
b = smprint("/bin/%s", b);
d = dirstat(b);
if(d == nil)
if(sflag){
snprint(devs, sizeof devs, "%s%s", devs, "|d");
push("/srv", MREPL|MCREATE);
push("/env", MREPL|MCREATE);
push("/rc", MREPL);
push("/bin", MREPL);
push(argv[0], MREPL);
rc[1] = argv[0];
argv = rc;
} else {
if(access(argv[0], AEXIST) == -1){
if((argv[0] = smprint("/bin/%s", argv[0])) == nil)
sysfatal("smprint: %r");
if(access(argv[0], AEXIST) == -1)
sysfatal("could not stat %s %r", argv[0]);
}
free(d);
parts[nparts] = b;
mflags[nparts++] = MREPL;
argv[0] = b;
push(argv[0], MREPL);
}
rfork(RFNAMEG|RFFDG);
skelfs();
@ -210,5 +237,9 @@ main(int argc, char **argv)
sysfatal("could not write chdev: %r");
}
close(dfd);
if(chdir(path) < 0)
sysfatal("can not cd to %s", path);
exec(argv[0], argv);
sysfatal("exec: %r");
}