Merge branch 'front' of git://git.9front.org/plan9front/plan9front into front
This commit is contained in:
commit
3449d477a2
18 changed files with 429 additions and 102 deletions
13
rc/bin/man
13
rc/bin/man
|
@ -11,6 +11,7 @@ d=0
|
||||||
|
|
||||||
fn roff {
|
fn roff {
|
||||||
preproc=()
|
preproc=()
|
||||||
|
Jpflag=()
|
||||||
postproc=cat
|
postproc=cat
|
||||||
x=`{doctype $2}
|
x=`{doctype $2}
|
||||||
if (~ $1 t) {
|
if (~ $1 t) {
|
||||||
|
@ -19,6 +20,8 @@ fn roff {
|
||||||
if(~ $x *pic*)
|
if(~ $x *pic*)
|
||||||
preproc=($preproc pic)
|
preproc=($preproc pic)
|
||||||
Nflag=-Tutf
|
Nflag=-Tutf
|
||||||
|
if(grep -s '^.ft Jp|\f\[Jp\]' $2)
|
||||||
|
Jpflag='-mnihongo'
|
||||||
}
|
}
|
||||||
if not {
|
if not {
|
||||||
Nflag='-N'
|
Nflag='-N'
|
||||||
|
@ -34,17 +37,17 @@ fn roff {
|
||||||
{echo -n $FONTS; cat $2 </dev/null} |
|
{echo -n $FONTS; cat $2 </dev/null} |
|
||||||
switch($#preproc) {
|
switch($#preproc) {
|
||||||
case 0
|
case 0
|
||||||
troff $Nflag $Lflag -$MAN
|
troff $Nflag $Lflag -$MAN $Jpflag
|
||||||
case 1
|
case 1
|
||||||
$preproc | troff $Nflag $Lflag -$MAN
|
$preproc | troff $Nflag $Lflag -$MAN $Jpflag
|
||||||
case 2
|
case 2
|
||||||
$preproc(1) | $preproc(2) | troff $Nflag $Lflag -$MAN
|
$preproc(1) | $preproc(2) | troff $Nflag $Lflag -$MAN $Jpflag
|
||||||
case 3
|
case 3
|
||||||
$preproc(1) | $preproc(2) | $preproc(3) |
|
$preproc(1) | $preproc(2) | $preproc(3) |
|
||||||
troff $Nflag $Lflag -$MAN
|
troff $Nflag $Lflag -$MAN $Jpflag
|
||||||
case *
|
case *
|
||||||
$preproc(1) | $preproc(2) | $preproc(3) |
|
$preproc(1) | $preproc(2) | $preproc(3) |
|
||||||
$preproc(4) | troff $Nflag $Lflag -$MAN
|
$preproc(4) | troff $Nflag $Lflag -$MAN $Jpflag
|
||||||
} | $postproc
|
} | $postproc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
3
sys/lib/dist/mkfile
vendored
3
sys/lib/dist/mkfile
vendored
|
@ -92,7 +92,8 @@ cd:V: /tmp/9front.386.iso.gz
|
||||||
@{
|
@{
|
||||||
objtype=arm64
|
objtype=arm64
|
||||||
kernel=/n/src9/$objtype/9reform.u
|
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
|
mb=1885 # storage vendors idea of 2GB
|
||||||
mk $target.$pid.disk
|
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
|
mv $target.$pid.disk $target && dd -trunc 0 -bs 1024 -oseek 33 -if /n/src9/sys/src/boot/reform/flash.bin -of $target
|
||||||
|
|
|
@ -19,7 +19,7 @@ return to default English mode (no transliteration).
|
||||||
.B ctl-n
|
.B ctl-n
|
||||||
Japanese hiragana: interpret lower-case letters as a Hepburn
|
Japanese hiragana: interpret lower-case letters as a Hepburn
|
||||||
representation of hiragana. In this mode, typing ctl-\\ looks up the
|
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
|
Subsequent ctl-\\ characters cycle through the possibilities. A word
|
||||||
is the longest immediately preceding unbroken string of hiragana
|
is the longest immediately preceding unbroken string of hiragana
|
||||||
characters.
|
characters.
|
||||||
|
@ -28,15 +28,14 @@ characters.
|
||||||
Japanese katakana.
|
Japanese katakana.
|
||||||
.TP
|
.TP
|
||||||
.B ctl-l
|
.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
|
.TP
|
||||||
.B ctl-x
|
.B ctl-x
|
||||||
Read kana-kanji conversion dictionary once more, and renews it. This
|
Reload the in-memory kana-kanji conversion dictionary (kanji jisho).
|
||||||
will be convenient when you updated kana-kanji conversion dictionary
|
This is so you can update the kanji jisho on-the-fly. By default, the
|
||||||
on such acme editor.In default, the kana-kanji conversion dictionary
|
kanji jisho is read once at the beginning, to make a hash table, which
|
||||||
is read once at beginning and to make a hashed table, which will be
|
will be arranged so that the last selected candidate will be the first
|
||||||
arranged so that the last selected candidate will be the first
|
candidate for later searches.
|
||||||
candidate for later search.
|
|
||||||
.TP
|
.TP
|
||||||
.B ctl-r
|
.B ctl-r
|
||||||
Russian: interpret letters as Cyrillic; the transliteration is mostly
|
Russian: interpret letters as Cyrillic; the transliteration is mostly
|
||||||
|
@ -62,7 +61,10 @@ Greek.
|
||||||
.B ctl-s
|
.B ctl-s
|
||||||
Korean.
|
Korean.
|
||||||
.PP
|
.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
|
.EX
|
||||||
...
|
...
|
||||||
ktrans
|
ktrans
|
||||||
|
@ -74,6 +76,13 @@ or run it with a sub-rio on a window like:
|
||||||
% @{ktrans; rio}
|
% @{ktrans; rio}
|
||||||
.EE
|
.EE
|
||||||
.PP
|
.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
|
.SH SOURCE
|
||||||
.B /sys/src/cmd/ktrans
|
.B /sys/src/cmd/ktrans
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
|
@ -86,8 +95,10 @@ or run it with a sub-rio on a window like:
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
If you want to make the Japanese text as below:
|
If you want to make the Japanese text as below:
|
||||||
|
|
||||||
|
.ft Jp
|
||||||
私は毎日35分以上歩いて、 更に10分電車に乗って学校に通います。
|
私は毎日35分以上歩いて、 更に10分電車に乗って学校に通います。
|
||||||
健康の維持にも役だっていますが、 なかなかたのしいものです。
|
健康の維持にも役だっていますが、 なかなかたのしいものです。
|
||||||
|
.ft
|
||||||
|
|
||||||
your keyboard typing stream should be:
|
your keyboard typing stream should be:
|
||||||
|
|
||||||
|
@ -104,3 +115,7 @@ method.
|
||||||
There is no way to generate the control characters literally. At the
|
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
|
beggining of a new line, you have to begin with ctl-l for successful
|
||||||
kana-kanji conversion.
|
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.
|
||||||
|
|
|
@ -296,7 +296,11 @@ removes access to all kernel drivers from
|
||||||
the child namespace; the
|
the child namespace; the
|
||||||
.B -e
|
.B -e
|
||||||
flag specifies a string of driver
|
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
|
.PP
|
||||||
.I As
|
.I As
|
||||||
executes
|
executes
|
||||||
|
|
|
@ -146,7 +146,7 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int input_clk_freq[] = {
|
static int input_clk_freq[] = {
|
||||||
[ARM_PLL_CLK] 1600*Mhz,
|
[ARM_PLL_CLK] 1400*Mhz,
|
||||||
[GPU_PLL_CLK] 1600*Mhz,
|
[GPU_PLL_CLK] 1600*Mhz,
|
||||||
[VPU_PLL_CLK] 800*Mhz,
|
[VPU_PLL_CLK] 800*Mhz,
|
||||||
[DRAM_PLL1_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;
|
error = freq;
|
||||||
for(divq = 2; divq <= 64; divq += 2){
|
for(divq = 2; divq <= 64; divq += 2){
|
||||||
for(divr = 1; divr <= 64; divr++){
|
for(divr = 2; divr <= 64; divr++){
|
||||||
ref = ref_freq/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;
|
continue;
|
||||||
|
|
||||||
ref *= 8;
|
v *= (vlong)ref * 8;
|
||||||
divfi = ((vlong)freq*divq) / ref;
|
v /= (vlong)divq << 24;
|
||||||
if(divfi < 1 || divfi > 32)
|
pllout = v;
|
||||||
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;
|
|
||||||
|
|
||||||
if(pllout > freq)
|
if(pllout > freq)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1003,16 +999,15 @@ enablefracpll(u32int *reg, int ref_sel, int ref_freq, int freq)
|
||||||
if(freq - pllout > error)
|
if(freq - pllout > error)
|
||||||
continue;
|
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;
|
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;
|
error = freq - pllout;
|
||||||
if(error == 0)
|
if(error == 0)
|
||||||
goto Found;
|
goto Found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
panic("enablefracpll: %#p freq %d: out of range", PADDR(reg), freq);
|
||||||
|
|
||||||
Found:
|
Found:
|
||||||
/* skip if nothing has changed */
|
/* skip if nothing has changed */
|
||||||
|
@ -1022,19 +1017,16 @@ Found:
|
||||||
|
|
||||||
reg[0] |= 1<<14; /* bypass */
|
reg[0] |= 1<<14; /* bypass */
|
||||||
|
|
||||||
// iprint("%p cfg1=%.8ux\n", PADDR(reg), cfg1);
|
|
||||||
reg[1] = cfg1;
|
reg[1] = cfg1;
|
||||||
|
|
||||||
// iprint("%p cfg0=%.8ux\n", PADDR(reg), cfg0);
|
|
||||||
reg[0] = cfg0 | (1<<14) | (1<<12);
|
reg[0] = cfg0 | (1<<14) | (1<<12);
|
||||||
|
|
||||||
/* unbypass */
|
/* unbypass */
|
||||||
reg[0] &= ~(1<<14);
|
reg[0] &= ~(1<<14);
|
||||||
|
|
||||||
// iprint("%p wait for lock...", PADDR(reg));
|
|
||||||
while((reg[0] & (1<<31)) == 0)
|
while((reg[0] & (1<<31)) == 0)
|
||||||
;
|
;
|
||||||
// iprint("locked!\n");
|
|
||||||
reg[0] &= ~(1<<12);
|
reg[0] &= ~(1<<12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,9 @@ localclockintr(Ureg *ureg, void *)
|
||||||
void
|
void
|
||||||
clockinit(void)
|
clockinit(void)
|
||||||
{
|
{
|
||||||
|
uvlong tstart, tend;
|
||||||
|
ulong t0, t1;
|
||||||
|
|
||||||
syswr(PMCR_EL0, 1<<6 | 7);
|
syswr(PMCR_EL0, 1<<6 | 7);
|
||||||
syswr(PMCNTENSET, 1<<31);
|
syswr(PMCNTENSET, 1<<31);
|
||||||
syswr(PMUSERENR_EL0, 1<<2);
|
syswr(PMUSERENR_EL0, 1<<2);
|
||||||
|
@ -40,7 +43,28 @@ clockinit(void)
|
||||||
if(m->machno == 0){
|
if(m->machno == 0){
|
||||||
freq = sysrd(CNTFRQ_EL0);
|
freq = sysrd(CNTFRQ_EL0);
|
||||||
print("timer frequency %lld Hz\n", freq);
|
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");
|
intrenable(IRQcntpns, localclockintr, nil, BUSUNKNOWN, "clock");
|
||||||
}
|
}
|
||||||
|
|
|
@ -655,18 +655,22 @@ ctl(Ether*, void*, long len)
|
||||||
static int
|
static int
|
||||||
reset(Ether *edev)
|
reset(Ether *edev)
|
||||||
{
|
{
|
||||||
Ctlr *ctlr = edev->ctlr;
|
enum {
|
||||||
u32int paddr1, paddr2;
|
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 */
|
a0 = ocotp[OCOTP_HW_OCOTP_MAC_ADDR0];
|
||||||
paddr1 = rr(ctlr, ENET_PALR);
|
a1 = ocotp[OCOTP_HW_OCOTP_MAC_ADDR1];
|
||||||
paddr2 = rr(ctlr, ENET_PAUR);
|
|
||||||
edev->ea[0] = paddr1>>24;
|
edev->ea[0] = a1>>8;
|
||||||
edev->ea[1] = paddr1>>16;
|
edev->ea[1] = a1>>0;
|
||||||
edev->ea[2] = paddr1>>8;
|
edev->ea[2] = a0>>24;
|
||||||
edev->ea[3] = paddr1>>0;
|
edev->ea[3] = a0>>16;
|
||||||
edev->ea[4] = paddr2>>24;
|
edev->ea[4] = a0>>8;
|
||||||
edev->ea[5] = paddr2>>16;
|
edev->ea[5] = a0>>0;
|
||||||
|
|
||||||
shutdown(edev);
|
shutdown(edev);
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,10 @@ el2:
|
||||||
MSR R0, MDCR_EL2
|
MSR R0, MDCR_EL2
|
||||||
ISB $SY
|
ISB $SY
|
||||||
|
|
||||||
|
/* set virtual timer offset to zero */
|
||||||
|
MOV $0, R0
|
||||||
|
MSR R0, CNTVOFF_EL2
|
||||||
|
|
||||||
/* HCR = RW, HCD, SWIO, BSU, FB */
|
/* HCR = RW, HCD, SWIO, BSU, FB */
|
||||||
MOVWU $(1<<31 | 1<<29 | 1<<2 | 0<<10 | 0<<9), R0
|
MOVWU $(1<<31 | 1<<29 | 1<<2 | 0<<10 | 0<<9), R0
|
||||||
MSR R0, HCR_EL2
|
MSR R0, HCR_EL2
|
||||||
|
|
|
@ -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;
|
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
|
static void
|
||||||
lcdifinit(struct video_mode *mode)
|
lcdifinit(struct video_mode *mode)
|
||||||
{
|
{
|
||||||
|
@ -501,6 +509,11 @@ bridgeinit(I2Cdev *dev, struct video_mode *mode, struct dsi_cfg *cfg)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
// soft reset
|
||||||
|
i2cwritebyte(dev, 0x09, 1);
|
||||||
|
while(i2creadbyte(dev, 0x09) & 1)
|
||||||
|
;
|
||||||
|
|
||||||
// clock derived from dsi clock
|
// clock derived from dsi clock
|
||||||
switch(cfg->hs_clk/2000000){
|
switch(cfg->hs_clk/2000000){
|
||||||
case 384:
|
case 384:
|
||||||
|
@ -812,6 +825,12 @@ backlighton(void)
|
||||||
gpioout(GPIO_PIN(1, 10), 1);
|
gpioout(GPIO_PIN(1, 10), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
blankscreen(int blank)
|
||||||
|
{
|
||||||
|
gpioout(GPIO_PIN(1, 10), blank == 0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
lcdinit(void)
|
lcdinit(void)
|
||||||
{
|
{
|
||||||
|
@ -832,8 +851,10 @@ lcdinit(void)
|
||||||
gpioout(GPIO_PIN(3, 20), 1);
|
gpioout(GPIO_PIN(3, 20), 1);
|
||||||
|
|
||||||
bridge = i2cdev(i2cbus("i2c4"), 0x2C);
|
bridge = i2cdev(i2cbus("i2c4"), 0x2C);
|
||||||
if(bridge == nil)
|
if(bridge == nil){
|
||||||
return;
|
err = "could not find bridge";
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
bridge->subaddr = 1;
|
bridge->subaddr = 1;
|
||||||
|
|
||||||
/* power on mipi dsi */
|
/* power on mipi dsi */
|
||||||
|
@ -852,6 +873,8 @@ lcdinit(void)
|
||||||
setclkgate("disp.axi_clk", 1);
|
setclkgate("disp.axi_clk", 1);
|
||||||
setclkgate("sim_display.mainclk", 1);
|
setclkgate("sim_display.mainclk", 1);
|
||||||
|
|
||||||
|
lcdifreset();
|
||||||
|
|
||||||
setclkrate("mipi.core", "system_pll1_div3", 266*Mhz);
|
setclkrate("mipi.core", "system_pll1_div3", 266*Mhz);
|
||||||
setclkrate("mipi.CLKREF", "system_pll2_clk", 25*Mhz);
|
setclkrate("mipi.CLKREF", "system_pll2_clk", 25*Mhz);
|
||||||
setclkrate("mipi.RxClkEsc", "system_pll1_clk", 80*Mhz);
|
setclkrate("mipi.RxClkEsc", "system_pll1_clk", 80*Mhz);
|
||||||
|
|
|
@ -10,8 +10,118 @@
|
||||||
#include "sysreg.h"
|
#include "sysreg.h"
|
||||||
#include "ureg.h"
|
#include "ureg.h"
|
||||||
|
|
||||||
|
#include "rebootcode.i"
|
||||||
|
|
||||||
Conf conf;
|
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
|
* starting place for first process
|
||||||
*/
|
*/
|
||||||
|
@ -29,6 +139,7 @@ init0(void)
|
||||||
else
|
else
|
||||||
ksetenv("service", "terminal", 0);
|
ksetenv("service", "terminal", 0);
|
||||||
ksetenv("console", "0", 0);
|
ksetenv("console", "0", 0);
|
||||||
|
setconfenv();
|
||||||
poperror();
|
poperror();
|
||||||
}
|
}
|
||||||
kproc("alarm", alarmkproc, 0);
|
kproc("alarm", alarmkproc, 0);
|
||||||
|
@ -124,7 +235,7 @@ mpinit(void)
|
||||||
MACHP(i)->machno = i;
|
MACHP(i)->machno = i;
|
||||||
cachedwbinvse(MACHP(i), MACHSIZE);
|
cachedwbinvse(MACHP(i), MACHSIZE);
|
||||||
|
|
||||||
u.r0 = 0x84000003;
|
u.r0 = 0x84000003; /* CPU_ON */
|
||||||
u.r1 = (sysrd(MPIDR_EL1) & ~0xFF) | i;
|
u.r1 = (sysrd(MPIDR_EL1) & ~0xFF) | i;
|
||||||
u.r2 = PADDR(_start);
|
u.r2 = PADDR(_start);
|
||||||
u.r3 = i;
|
u.r3 = i;
|
||||||
|
@ -134,6 +245,12 @@ mpinit(void)
|
||||||
spllo();
|
spllo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cpuidprint(void)
|
||||||
|
{
|
||||||
|
iprint("cpu%d: %dMHz ARM Cortex A53\n", m->machno, m->cpumhz);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
|
@ -143,6 +260,7 @@ main(void)
|
||||||
fpuinit();
|
fpuinit();
|
||||||
intrinit();
|
intrinit();
|
||||||
clockinit();
|
clockinit();
|
||||||
|
cpuidprint();
|
||||||
synccycles();
|
synccycles();
|
||||||
timersinit();
|
timersinit();
|
||||||
flushtlb();
|
flushtlb();
|
||||||
|
@ -152,6 +270,7 @@ main(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
quotefmtinstall();
|
quotefmtinstall();
|
||||||
|
bootargsinit();
|
||||||
meminit();
|
meminit();
|
||||||
confinit();
|
confinit();
|
||||||
xinit();
|
xinit();
|
||||||
|
@ -162,6 +281,7 @@ main(void)
|
||||||
fpuinit();
|
fpuinit();
|
||||||
intrinit();
|
intrinit();
|
||||||
clockinit();
|
clockinit();
|
||||||
|
cpuidprint();
|
||||||
timersinit();
|
timersinit();
|
||||||
pageinit();
|
pageinit();
|
||||||
procinit0();
|
procinit0();
|
||||||
|
@ -180,35 +300,64 @@ main(void)
|
||||||
void
|
void
|
||||||
exit(int)
|
exit(int)
|
||||||
{
|
{
|
||||||
Ureg u = { .r0 = 0x84000009 };
|
Ureg u = { .r0 = 0x84000002 }; /* CPU_OFF */
|
||||||
|
|
||||||
cpushutdown();
|
cpushutdown();
|
||||||
splfhi();
|
splfhi();
|
||||||
|
|
||||||
/* system reset */
|
if(m->machno == 0)
|
||||||
|
u.r0 = 0x84000009; /* SYSTEM RESET */
|
||||||
smccall(&u);
|
smccall(&u);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static void
|
||||||
isaconfig(char *, int, ISAConf *)
|
rebootjump(void *entry, void *code, ulong size)
|
||||||
{
|
{
|
||||||
return 0;
|
void (*f)(void*, void*, ulong);
|
||||||
}
|
|
||||||
|
|
||||||
char*
|
intrcpushutdown();
|
||||||
getconf(char *)
|
|
||||||
{
|
/* redo identity map */
|
||||||
return nil;
|
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
|
void
|
||||||
writeconf(void)
|
reboot(void*, void *code, ulong size)
|
||||||
{
|
{
|
||||||
}
|
writeconf();
|
||||||
|
while(m->machno != 0){
|
||||||
|
procwired(up, 0);
|
||||||
|
sched();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
cpushutdown();
|
||||||
reboot(void *, void *, ulong)
|
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
|
void
|
||||||
|
|
|
@ -44,9 +44,8 @@
|
||||||
#define UCRAMSIZE (8*MiB)
|
#define UCRAMSIZE (8*MiB)
|
||||||
|
|
||||||
#define VDRAM (0xFFFFFFFFC0000000ULL) /* 0x40000000 - 0x80000000 */
|
#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 VIRTIO (0xFFFFFFFFB0000000ULL) /* 0x30000000 */
|
||||||
|
|
||||||
#define KZERO (0xFFFFFFFF80000000ULL) /* 0x00000000 - kernel address space */
|
#define KZERO (0xFFFFFFFF80000000ULL) /* 0x00000000 - kernel address space */
|
||||||
|
@ -64,6 +63,13 @@
|
||||||
|
|
||||||
#define MACHADDR(n) (KTZERO-((n)+1)*MACHSIZE)
|
#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 UZERO 0ULL /* user segment */
|
||||||
#define UTZERO (UZERO+0x10000) /* user text start */
|
#define UTZERO (UZERO+0x10000) /* user text start */
|
||||||
#define USTKTOP ((EVAMASK>>1)-0xFFFF) /* user segment end +1 */
|
#define USTKTOP ((EVAMASK>>1)-0xFFFF) /* user segment end +1 */
|
||||||
|
|
|
@ -87,8 +87,15 @@ install:V: /$objtype/$p$CONF
|
||||||
<../port/portmkfile
|
<../port/portmkfile
|
||||||
<|../port/mkbootrules $CONF
|
<|../port/mkbootrules $CONF
|
||||||
|
|
||||||
|
main.$O: rebootcode.i
|
||||||
|
|
||||||
|
pciimx.$O: ../port/pci.h
|
||||||
|
|
||||||
initcode.out: init9.$O initcode.$O /$objtype/lib/libc.a
|
initcode.out: init9.$O initcode.$O /$objtype/lib/libc.a
|
||||||
$LD -l -R1 -s -o $target $prereq
|
$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:
|
$CONF.clean:
|
||||||
rm -rf $p$CONF $p$CONF.u errstr.h $CONF.c boot$CONF.c
|
rm -rf $p$CONF $p$CONF.u errstr.h $CONF.c boot$CONF.c
|
||||||
|
|
|
@ -60,6 +60,24 @@ mmu0clear(uintptr *l1)
|
||||||
l1[PTL1X(pa, 3)] = 0;
|
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
|
void
|
||||||
mmu1init(void)
|
mmu1init(void)
|
||||||
{
|
{
|
||||||
|
|
48
sys/src/9/imx8/rebootcode.s
Normal file
48
sys/src/9/imx8/rebootcode.s
Normal 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
|
|
@ -178,11 +178,6 @@ setcolor(ulong p, ulong r, ulong g, ulong b)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
blankscreen(int)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
myscreenputs(char *s, int n)
|
myscreenputs(char *s, int n)
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#define CNTP_TVAL_EL0 SYSREG(3,3,14,2,0)
|
#define CNTP_TVAL_EL0 SYSREG(3,3,14,2,0)
|
||||||
#define CNTP_CTL_EL0 SYSREG(3,3,14,2,1)
|
#define CNTP_CTL_EL0 SYSREG(3,3,14,2,1)
|
||||||
#define CNTP_CVAL_EL0 SYSREG(3,3,14,2,2)
|
#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_EL0 SYSREG(3,3,13,0,2)
|
||||||
#define TPIDR_EL1 SYSREG(3,0,13,0,4)
|
#define TPIDR_EL1 SYSREG(3,0,13,0,4)
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
load ${devtype} ${devnum}:${bootpart} ${kernel_addr_r} ${prefix}9reform.u
|
mw.b 0x40010000 0x0 0x10000
|
||||||
bootm ${kernel_addr_r}
|
load ${devtype} ${devnum}:${bootpart} 0x40010000 ${prefix}plan9.ini
|
||||||
|
load ${devtype} ${devnum}:${bootpart} 0x40100000 ${prefix}9reform.u
|
||||||
|
bootm 0x40100000
|
||||||
|
|
|
@ -10,11 +10,11 @@ binderr(char *new, char *old, int flag)
|
||||||
char dash[4] = { '-' };
|
char dash[4] = { '-' };
|
||||||
|
|
||||||
if(debug){
|
if(debug){
|
||||||
if(flag & MCREATE){
|
if(flag & MCREATE)
|
||||||
dash[2] = 'c';
|
dash[2] = 'c';
|
||||||
flag &= ~MCREATE;
|
|
||||||
}
|
|
||||||
switch(flag){
|
switch(flag){
|
||||||
|
case MCREATE|MREPL:
|
||||||
case MREPL:
|
case MREPL:
|
||||||
dash[0] = ' ';
|
dash[0] = ' ';
|
||||||
if(dash[2] == 'c')
|
if(dash[2] == 'c')
|
||||||
|
@ -133,26 +133,40 @@ skelfs(void)
|
||||||
sysfatal("/mnt/d mount setup: %r");
|
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
|
void
|
||||||
usage(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");
|
exits("usage");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *b;
|
|
||||||
Dir *d;
|
|
||||||
char devs[1024];
|
char devs[1024];
|
||||||
int dfd;
|
int dfd;
|
||||||
char *parts[256];
|
char *path;
|
||||||
int mflags[256];
|
char *a;
|
||||||
int nparts;
|
int sflag;
|
||||||
|
|
||||||
nparts = 0;
|
nparts = 0;
|
||||||
|
path = "/";
|
||||||
memset(devs, 0, sizeof devs);
|
memset(devs, 0, sizeof devs);
|
||||||
|
sflag = 0;
|
||||||
ARGBEGIN{
|
ARGBEGIN{
|
||||||
case 'D':
|
case 'D':
|
||||||
debug++;
|
debug++;
|
||||||
|
@ -160,35 +174,48 @@ main(int argc, char **argv)
|
||||||
debug++;
|
debug++;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
parts[nparts] = EARGF(usage());
|
a = EARGF(usage());
|
||||||
mflags[nparts++] = MREPL;
|
push(a, MREPL);
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
parts[nparts] = EARGF(usage());
|
a = EARGF(usage());
|
||||||
mflags[nparts++] = MCREATE|MREPL;
|
push(a, MREPL|MCREATE);
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
snprint(devs, sizeof devs, "%s%s", devs, EARGF(usage()));
|
snprint(devs, sizeof devs, "%s%s", devs, EARGF(usage()));
|
||||||
break;
|
break;
|
||||||
|
case '.':
|
||||||
|
path = EARGF(usage());
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
sflag = 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
break;
|
break;
|
||||||
}ARGEND
|
}ARGEND
|
||||||
|
|
||||||
if(argc == 0)
|
if(argc == 0)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
b = argv[0];
|
if(sflag){
|
||||||
d = dirstat(b);
|
snprint(devs, sizeof devs, "%s%s", devs, "|d");
|
||||||
if(d == nil){
|
push("/srv", MREPL|MCREATE);
|
||||||
b = smprint("/bin/%s", b);
|
push("/env", MREPL|MCREATE);
|
||||||
d = dirstat(b);
|
push("/rc", MREPL);
|
||||||
if(d == nil)
|
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]);
|
sysfatal("could not stat %s %r", argv[0]);
|
||||||
}
|
}
|
||||||
free(d);
|
push(argv[0], MREPL);
|
||||||
parts[nparts] = b;
|
}
|
||||||
mflags[nparts++] = MREPL;
|
|
||||||
argv[0] = b;
|
|
||||||
|
|
||||||
rfork(RFNAMEG|RFFDG);
|
rfork(RFNAMEG|RFFDG);
|
||||||
skelfs();
|
skelfs();
|
||||||
|
@ -210,5 +237,9 @@ main(int argc, char **argv)
|
||||||
sysfatal("could not write chdev: %r");
|
sysfatal("could not write chdev: %r");
|
||||||
}
|
}
|
||||||
close(dfd);
|
close(dfd);
|
||||||
|
|
||||||
|
if(chdir(path) < 0)
|
||||||
|
sysfatal("can not cd to %s", path);
|
||||||
exec(argv[0], argv);
|
exec(argv[0], argv);
|
||||||
|
sysfatal("exec: %r");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue