From aab4e32ce05a26bff7386bb86ffc24589cbe601c Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 25 Jun 2017 22:22:58 +0200 Subject: pc, pc64: support for multiboot framebuffer, common bootargs and multiboot code --- sys/src/9/pc/bootargs.c | 189 +++++++++++++++++++++++++++++++++++++++ sys/src/9/pc/fns.h | 4 +- sys/src/9/pc/l.s | 13 ++- sys/src/9/pc/main.c | 232 +++++++++--------------------------------------- sys/src/9/pc/mem.h | 11 +++ sys/src/9/pc/mkfile | 1 + sys/src/9/pc/screen.c | 33 ++++++- sys/src/9/pc/screen.h | 1 + sys/src/9/pc/vgavesa.c | 71 ++++++++++++--- sys/src/9/pc64/fns.h | 4 +- sys/src/9/pc64/l.s | 6 +- sys/src/9/pc64/main.c | 228 ++++++++--------------------------------------- sys/src/9/pc64/mem.h | 11 +++ sys/src/9/pc64/mkfile | 1 + 14 files changed, 400 insertions(+), 405 deletions(-) create mode 100644 sys/src/9/pc/bootargs.c (limited to 'sys/src') diff --git a/sys/src/9/pc/bootargs.c b/sys/src/9/pc/bootargs.c new file mode 100644 index 000000000..ece6f8e33 --- /dev/null +++ b/sys/src/9/pc/bootargs.c @@ -0,0 +1,189 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" + +#define MAXCONF 64 +static char *confname[MAXCONF]; +static char *confval[MAXCONF]; +static int nconf; + +/* screen.c */ +extern char* rgbmask2chan(char *buf, int depth, u32int rm, u32int gm, u32int bm); + +/* vgavesa.c */ +extern char* vesabootscreenconf(char*, char*, uchar*); + +static void +multibootargs(void) +{ + extern ulong multibootptr; + ulong *multiboot; + char *cp, *ep; + ulong *m, l; + + if(multibootptr == 0) + return; + + multiboot = (ulong*)KADDR(multibootptr); + + /* command line */ + if((multiboot[0] & (1<<2)) != 0) + strncpy(BOOTLINE, KADDR(multiboot[4]), BOOTLINELEN-1); + + cp = BOOTARGS; + ep = cp + BOOTARGSLEN-1; + + /* memory map */ + if((multiboot[0] & (1<<6)) != 0 && (l = multiboot[11]) >= 24){ + cp = seprint(cp, ep, "*e820="); + m = KADDR(multiboot[12]); + while(m[0] >= 20 && m[0]+4 <= l){ + uvlong base, size; + m++; + base = ((uvlong)m[0] | (uvlong)m[1]<<32); + size = ((uvlong)m[2] | (uvlong)m[3]<<32); + cp = seprint(cp, ep, "%.1lux %.16llux %.16llux ", + m[4] & 0xF, base, base+size); + l -= m[-1]+4; + m = (ulong*)((uintptr)m + m[-1]); + } + cp[-1] = '\n'; + } + + if((multiboot[0] & (1<<12)) != 0 && multiboot[22] != 0){ /* framebuffer */ + uchar *p = (uchar*)multiboot + 112; + int depth = multiboot[27] & 0xFF; + char chan[32]; + + switch((multiboot[27]>>8) & 0xFF){ + case 0: + snprint(chan, sizeof chan, "m%d", depth); + if(0){ + case 1: + rgbmask2chan(chan, depth, + (1UL< 0){ + m = KADDR(multiboot[6]); + l = m[1] - m[0]; + m = KADDR(m[0]); + if(cp+l > ep) + l = ep - cp; + memmove(cp, m, l); + cp += l; + } + *cp = 0; +} + +void +bootargsinit(void) +{ + int i, j, n; + char *cp, *line[MAXCONF], *p, *q; + + multibootargs(); + + /* + * 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 == '\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 0; +} + +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"); + memset(BOOTLINE, 0, BOOTLINELEN); + memmove(BOOTARGS, p, n); + poperror(); + free(p); +} diff --git a/sys/src/9/pc/fns.h b/sys/src/9/pc/fns.h index 594d2f553..3710d9291 100644 --- a/sys/src/9/pc/fns.h +++ b/sys/src/9/pc/fns.h @@ -8,7 +8,7 @@ int bios32call(BIOS32ci*, u16int[3]); int bios32ci(BIOS32si*, BIOS32ci*); void bios32close(BIOS32si*); BIOS32si* bios32open(char*); -void bootargs(void*); +void bootargsinit(void); ulong cankaddr(ulong); int checksum(void *, int); void clockintr(Ureg*, void*); @@ -176,6 +176,7 @@ int rdmsr(int, vlong*); void realmode(Ureg*); void screeninit(void); void (*screenputs)(char*, int); +void setconfenv(void); void* sigsearch(char*); void syncclock(void); void* tmpmap(Page*); @@ -198,6 +199,7 @@ void* vmap(ulong, int); int vmapsync(ulong); void vunmap(void*, int); void wbinvd(void); +void writeconf(void); int wrmsr(int, vlong); int xchgw(ushort*, int); void rdrandbuf(void*, ulong); diff --git a/sys/src/9/pc/l.s b/sys/src/9/pc/l.s index c2c283793..e28ef9e95 100644 --- a/sys/src/9/pc/l.s +++ b/sys/src/9/pc/l.s @@ -42,8 +42,8 @@ TEXT _startKADDR(SB), $0 */ TEXT _multibootheader(SB), $0 LONG $0x1BADB002 /* magic */ - LONG $0x00010003 /* flags */ - LONG $-(0x1BADB002 + 0x00010003) /* checksum */ + LONG $0x00010007 /* flags */ + LONG $-(0x1BADB002 + 0x00010007) /* checksum */ LONG $_multibootheader-KZERO(SB) /* header_addr */ LONG $_startKADDR-KZERO(SB) /* load_addr */ LONG $edata-KZERO(SB) /* load_end_addr */ @@ -52,7 +52,7 @@ TEXT _multibootheader(SB), $0 LONG $0 /* mode_type */ LONG $0 /* width */ LONG $0 /* height */ - LONG $0 /* depth */ + LONG $32 /* depth */ /* * the kernel expects the data segment to be page-aligned @@ -70,14 +70,13 @@ TEXT _multibootentry(SB), $0 INCL CX /* one more for post decrement */ STD REP; MOVSB - ADDL $KZERO, BX - MOVL BX, multiboot-KZERO(SB) + MOVL BX, multibootptr-KZERO(SB) MOVL $_startPADDR(SB), AX ANDL $~KZERO, AX JMP* AX -/* multiboot structure pointer */ -TEXT multiboot(SB), $0 +/* multiboot structure pointer (physical address) */ +TEXT multibootptr(SB), $0 LONG $0 /* diff --git a/sys/src/9/pc/main.c b/sys/src/9/pc/main.c index 1e9ec8bb6..c69fb9769 100644 --- a/sys/src/9/pc/main.c +++ b/sys/src/9/pc/main.c @@ -11,131 +11,28 @@ #include "reboot.h" Mach *m; - -/* - * Where configuration info is left for the loaded programme. - * This will turn into a structure as more is done by the boot loader - * (e.g. why parse the .ini file twice?). - * There are 3584 bytes available at CONFADDR. - */ -#define BOOTLINE ((char*)CONFADDR) -#define BOOTLINELEN 64 -#define BOOTARGS ((char*)(CONFADDR+BOOTLINELEN)) -#define BOOTARGSLEN (4096-0x200-BOOTLINELEN) -#define MAXCONF 64 - Conf conf; -char *confname[MAXCONF]; -char *confval[MAXCONF]; -int nconf; + char *sp; /* user stack of init proc */ int delaylink; int idle_spin; -static void -multibootargs(void) -{ - char *cp, *ep; - ulong *m, l; - - extern ulong *multiboot; - - if(multiboot == nil) - return; - - /* command line */ - if((multiboot[0] & (1<<2)) != 0) - strncpy(BOOTLINE, KADDR(multiboot[4]), BOOTLINELEN-1); - - cp = BOOTARGS; - ep = cp + BOOTARGSLEN-1; - - /* memory map */ - if((multiboot[0] & (1<<6)) != 0 && (l = multiboot[11]) >= 24){ - cp = seprint(cp, ep, "*e820="); - m = KADDR(multiboot[12]); - while(m[0] >= 20 && m[0]+4 <= l){ - uvlong base, size; - m++; - base = ((uvlong)m[0] | (uvlong)m[1]<<32); - size = ((uvlong)m[2] | (uvlong)m[3]<<32); - cp = seprint(cp, ep, "%.1lux %.16llux %.16llux ", - m[4] & 0xF, base, base+size); - l -= m[-1]+4; - m = (ulong*)((ulong)m + m[-1]); - } - cp[-1] = '\n'; - } - - /* plan9.ini passed as the first module */ - if((multiboot[0] & (1<<3)) != 0 && multiboot[5] > 0){ - m = KADDR(multiboot[6]); - l = m[1] - m[0]; - m = KADDR(m[0]); - if(cp+l > ep) - l = ep - cp; - memmove(cp, m, l); - cp += l; - } - *cp = 0; -} - -static void -options(void) -{ - long i, n; - char *cp, *line[MAXCONF], *p, *q; - - multibootargs(); - - /* - * 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 == '\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'; - confname[nconf] = line[i]; - confval[nconf] = cp; - nconf++; - } -} - extern void (*i8237alloc)(void); extern void bootscreeninit(void); +extern void multibootdebug(void); void main(void) { mach0init(); - options(); + bootargsinit(); ioinit(); i8250console(); quotefmtinstall(); screeninit(); print("\nPlan 9\n"); - + trapinit0(); i8253init(); cpuidentify(); @@ -213,7 +110,6 @@ machinit(void) void init0(void) { - int i; char buf[2*KNAMELEN]; up->nerrlab = 0; @@ -239,17 +135,49 @@ init0(void) ksetenv("service", "cpu", 0); else ksetenv("service", "terminal", 0); - for(i = 0; i < nconf; i++){ - if(confname[i][0] != '*') - ksetenv(confname[i], confval[i], 0); - ksetenv(confname[i], confval[i], 1); - } + setconfenv(); poperror(); } kproc("alarm", alarmkproc, 0); touser(sp); } +void +userbootargs(void *base) +{ + char *argv[8]; + int i, argc; + +#define UA(ka) ((char*)(ka) + ((uintptr)(USTKTOP - BY2PG) - (uintptr)base)) + sp = (char*)base + BY2PG - sizeof(Tos); + + /* push boot command line onto the stack */ + sp -= BOOTLINELEN; + sp[BOOTLINELEN-1] = '\0'; + memmove(sp, BOOTLINE, BOOTLINELEN-1); + + /* parse boot command line */ + argc = tokenize(sp, argv, nelem(argv)); + if(argc < 1){ + strcpy(sp, "boot"); + argc = 0; + argv[argc++] = sp; + } + + /* 4 byte word align stack */ + sp = (char*)((uintptr)sp & ~3); + + /* build argv on stack */ + sp -= (argc+1)*BY2WD; + for(i=0; i= BOOTARGSLEN) - error("kernel configuration too large"); - memset(BOOTLINE, 0, BOOTLINELEN); - memmove(BOOTARGS, p, n); - poperror(); - free(p); -} - void confinit(void) { diff --git a/sys/src/9/pc/mem.h b/sys/src/9/pc/mem.h index 7f5b09a16..6de469cb3 100644 --- a/sys/src/9/pc/mem.h +++ b/sys/src/9/pc/mem.h @@ -77,6 +77,17 @@ * and that there are 6 of them. */ +/* + * Where configuration info is left for the loaded programme. + * This will turn into a structure as more is done by the boot loader + * (e.g. why parse the .ini file twice?). + * There are 3584 bytes available at CONFADDR. + */ +#define BOOTLINE ((char*)CONFADDR) +#define BOOTLINELEN 64 +#define BOOTARGS ((char*)(CONFADDR+BOOTLINELEN)) +#define BOOTARGSLEN (4096-0x200-BOOTLINELEN) + /* * known x86 segments (in GDT) and their selectors */ diff --git a/sys/src/9/pc/mkfile b/sys/src/9/pc/mkfile index c6e683e22..62e622b21 100644 --- a/sys/src/9/pc/mkfile +++ b/sys/src/9/pc/mkfile @@ -53,6 +53,7 @@ OBJ=\ memory.$O\ mmu.$O\ trap.$O\ + bootargs.$O\ $CONF.root.$O\ $CONF.rootc.$O\ $DEVS\ diff --git a/sys/src/9/pc/screen.c b/sys/src/9/pc/screen.c index 69018c4fe..20df768fd 100644 --- a/sys/src/9/pc/screen.c +++ b/sys/src/9/pc/screen.c @@ -587,6 +587,36 @@ bootmapfb(VGAscr *scr, ulong pa, ulong sz) return vgalinearaddr0(scr, pa, sz); } +char* +rgbmask2chan(char *buf, int depth, u32int rm, u32int gm, u32int bm) +{ + u32int m[4], dm; /* r,g,b,x */ + char tmp[32]; + int c, n; + + dm = 1<>= n, m[1] >>= n, m[2] >>= n, m[3] >>= n; + snprint(tmp, sizeof tmp, "%c%d%s", "rgbx"[c], n, buf); + strcpy(buf, tmp); + goto Next; + } + } + return buf; +} + /* * called early on boot to attach to framebuffer * setup by bootloader/firmware or plan9. @@ -682,11 +712,10 @@ bootscreenconf(VGAscr *scr) char conf[100], chan[30]; conf[0] = '\0'; - if(scr != nil && scr->paddr != 0) + if(scr != nil && scr->paddr != 0 && scr->gscreen != nil) snprint(conf, sizeof(conf), "%dx%dx%d %s %#p %d\n", scr->gscreen->r.max.x, scr->gscreen->r.max.y, scr->gscreen->depth, chantostr(chan, scr->gscreen->chan), scr->paddr, scr->apsize); - ksetenv("*bootscreen", conf, 1); } diff --git a/sys/src/9/pc/screen.h b/sys/src/9/pc/screen.h index 646edd6e2..401d056a3 100644 --- a/sys/src/9/pc/screen.h +++ b/sys/src/9/pc/screen.h @@ -147,6 +147,7 @@ extern int screensize(int, int, int, ulong); extern int screenaperture(int, int); extern Rectangle physgscreenr; /* actual monitor size */ extern void blankscreen(int); +extern char* rgbmask2chan(char *buf, int depth, u32int rm, u32int gm, u32int bm); extern void bootscreeninit(void); extern void bootscreenconf(VGAscr*); diff --git a/sys/src/9/pc/vgavesa.c b/sys/src/9/pc/vgavesa.c index ceca04406..dbe4d0024 100644 --- a/sys/src/9/pc/vgavesa.c +++ b/sys/src/9/pc/vgavesa.c @@ -31,6 +31,17 @@ static Chan *creg, *cmem; #define PWORD(p, v) (p)[0] = (v); (p)[1] = (v)>>8 #define PLONG(p, v) (p)[0] = (v); (p)[1] = (v)>>8; (p)[2] = (v)>>16; (p)[3] = (v)>>24 +typedef struct Vmode Vmode; +struct Vmode +{ + char chan[32]; + int attr; /* flags */ + int bpl; + int dx, dy; + int depth; + ulong paddr; +}; + static uchar* vbesetup(Ureg386 *u, int ax) { @@ -95,13 +106,37 @@ vbemodeinfo(int mode) return p; } +static char* +vmode(Vmode *m, uchar *p) +{ + m->attr = WORD(p); + if(!(m->attr & (1<<4))) + return "not in VESA graphics mode"; + if(!(m->attr & (1<<7))) + return "not in linear graphics mode"; + m->bpl = WORD(p+16); + m->dx = WORD(p+18); + m->dy = WORD(p+20); + m->depth = p[25]; + m->paddr = LONG(p+40); + if(m->depth <= 8) + snprint(m->chan, sizeof m->chan, "%c%d", + (m->attr & (1<<3)) ? 'm' : 'k', m->depth); + else + rgbmask2chan(m->chan, m->depth, + (1UL<mem[i].bar & ~0xF; e = a + pci->mem[i].size; - if(paddr >= a && (paddr+size) <= e){ - size = e - paddr; + if(m.paddr >= a && (m.paddr+size) <= e){ + size = e - m.paddr; havesize = 1; break; } @@ -151,7 +182,7 @@ vesalinear(VGAscr *scr, int, int) else size = ROUND(size, 1024*1024); - vgalinearaddr(scr, paddr, size); + vgalinearaddr(scr, m.paddr, size); if(scr->apsize) addvgaseg("vesascreen", scr->paddr, scr->apsize); @@ -222,3 +253,19 @@ VGAdev vgavesadev = { vesalinear, vesadrawinit, }; + +/* + * called from multibootargs() to convert + * vbe mode info (passed from bootloader) + * to *bootscreen= parameter + */ +char* +vesabootscreenconf(char *s, char *e, uchar *p) +{ + Vmode m; + + if(vmode(&m, p) != nil) + return s; + return seprint(s, e, "*bootscreen=%dx%dx%d %s %#lux\n", + m.bpl * 8 / m.depth, m.dy, m.depth, m.chan, m.paddr); +} diff --git a/sys/src/9/pc64/fns.h b/sys/src/9/pc64/fns.h index f51d21fe6..481572a3a 100644 --- a/sys/src/9/pc64/fns.h +++ b/sys/src/9/pc64/fns.h @@ -8,7 +8,7 @@ int bios32call(BIOS32ci*, u16int[3]); int bios32ci(BIOS32si*, BIOS32ci*); void bios32close(BIOS32si*); BIOS32si* bios32open(char*); -void bootargs(void*); +void bootargsinit(void); uintptr cankaddr(uintptr); int checksum(void *, int); void clockintr(Ureg*, void*); @@ -171,6 +171,7 @@ int rdmsr(int, vlong*); void realmode(Ureg*); void screeninit(void); void (*screenputs)(char*, int); +void setconfenv(void); void* sigsearch(char*); void syncclock(void); void syscallentry(void); @@ -191,6 +192,7 @@ void vectortable(void); void* vmap(uintptr, int); void vunmap(void*, int); void wbinvd(void); +void writeconf(void); int wrmsr(int, vlong); int xchgw(ushort*, int); void rdrandbuf(void*, ulong); diff --git a/sys/src/9/pc64/l.s b/sys/src/9/pc64/l.s index 715e5f432..a1cc976f3 100644 --- a/sys/src/9/pc64/l.s +++ b/sys/src/9/pc64/l.s @@ -37,8 +37,8 @@ TEXT _protected<>(SB), 1, $-4 */ TEXT _multibootheader<>(SB), 1, $-4 LONG $0x1BADB002 /* magic */ - LONG $0x00010003 /* flags */ - LONG $-(0x1BADB002 + 0x00010003) /* checksum */ + LONG $0x00010007 /* flags */ + LONG $-(0x1BADB002 + 0x00010007) /* checksum */ LONG $_multibootheader<>-KZERO(SB) /* header_addr */ LONG $_protected<>-KZERO(SB) /* load_addr */ LONG $edata-KZERO(SB) /* load_end_addr */ @@ -47,7 +47,7 @@ TEXT _multibootheader<>(SB), 1, $-4 LONG $0 /* mode_type */ LONG $0 /* width */ LONG $0 /* height */ - LONG $0 /* depth */ + LONG $32 /* depth */ /* * the kernel expects the data segment to be page-aligned diff --git a/sys/src/9/pc64/main.c b/sys/src/9/pc64/main.c index 24d99eea6..179c9e6d0 100644 --- a/sys/src/9/pc64/main.c +++ b/sys/src/9/pc64/main.c @@ -10,22 +10,7 @@ #include "pool.h" #include "reboot.h" -/* - * Where configuration info is left for the loaded programme. - * This will turn into a structure as more is done by the boot loader - * (e.g. why parse the .ini file twice?). - * There are 3584 bytes available at CONFADDR. - */ -#define BOOTLINE ((char*)CONFADDR) -#define BOOTLINELEN 64 -#define BOOTARGS ((char*)(CONFADDR+BOOTLINELEN)) -#define BOOTARGSLEN (4096-0x200-BOOTLINELEN) -#define MAXCONF 64 - Conf conf; -char *confname[MAXCONF]; -char *confval[MAXCONF]; -int nconf; int delaylink; int idle_spin; @@ -34,136 +19,6 @@ char *sp; /* user stack of init proc */ extern void (*i8237alloc)(void); extern void bootscreeninit(void); -static void -multibootargs(void) -{ - extern ulong multibootptr; - ulong *multiboot; - char *cp, *ep; - ulong *m, l; - - if(multibootptr == 0) - return; - - multiboot = (ulong*)KADDR(multibootptr); - /* command line */ - if((multiboot[0] & (1<<2)) != 0) - strncpy(BOOTLINE, KADDR(multiboot[4]), BOOTLINELEN-1); - - cp = BOOTARGS; - ep = cp + BOOTARGSLEN-1; - - /* memory map */ - if((multiboot[0] & (1<<6)) != 0 && (l = multiboot[11]) >= 24){ - cp = seprint(cp, ep, "*e820="); - m = KADDR(multiboot[12]); - while(m[0] >= 20 && m[0]+4 <= l){ - uvlong base, size; - m++; - base = ((uvlong)m[0] | (uvlong)m[1]<<32); - size = ((uvlong)m[2] | (uvlong)m[3]<<32); - cp = seprint(cp, ep, "%.1lux %.16llux %.16llux ", - m[4] & 0xF, base, base+size); - l -= m[-1]+4; - m = (ulong*)((uintptr)m + m[-1]); - } - cp[-1] = '\n'; - } - - /* plan9.ini passed as the first module */ - if((multiboot[0] & (1<<3)) != 0 && multiboot[5] > 0){ - m = KADDR(multiboot[6]); - l = m[1] - m[0]; - m = KADDR(m[0]); - if(cp+l > ep) - l = ep - cp; - memmove(cp, m, l); - cp += l; - } - *cp = 0; -} - -static void -options(void) -{ - long i, n; - char *cp, *line[MAXCONF], *p, *q; - - multibootargs(); - - /* - * 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 == '\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'; - confname[nconf] = line[i]; - confval[nconf] = cp; - nconf++; - } -} - -char* -getconf(char *name) -{ - int i; - - for(i = 0; i < nconf; i++) - if(cistrcmp(confname[i], name) == 0) - return confval[i]; - return 0; -} - -static 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"); - memset(BOOTLINE, 0, BOOTLINELEN); - memmove(BOOTARGS, p, n); - poperror(); - free(p); -} - void confinit(void) { @@ -331,46 +186,9 @@ mach0init(void) active.exiting = 0; } -void -bootargs(void *base) -{ - char *argv[8]; - int i, argc; - -#define UA(ka) ((char*)(ka) + ((uintptr)(USTKTOP - BY2PG) - (uintptr)base)) - sp = (char*)base + BY2PG - sizeof(Tos); - - /* push boot command line onto the stack */ - sp -= BOOTLINELEN; - sp[BOOTLINELEN-1] = '\0'; - memmove(sp, BOOTLINE, BOOTLINELEN-1); - - /* parse boot command line */ - argc = tokenize(sp, argv, nelem(argv)); - if(argc < 1){ - strcpy(sp, "boot"); - argc = 0; - argv[argc++] = sp; - } - - /* 8 byte word align stack */ - sp = (char*)((uintptr)sp & ~7); - - /* build argv on stack */ - sp -= (argc+1)*BY2WD; - for(i=0; inerrlab = 0; @@ -396,11 +214,7 @@ init0(void) ksetenv("service", "cpu", 0); else ksetenv("service", "terminal", 0); - for(i = 0; i < nconf; i++){ - if(confname[i][0] != '*') - ksetenv(confname[i], confval[i], 0); - ksetenv(confname[i], confval[i], 1); - } + setconfenv(); poperror(); } kproc("alarm", alarmkproc, 0); @@ -408,6 +222,42 @@ init0(void) touser(sp); } +void +userbootargs(void *base) +{ + char *argv[8]; + int i, argc; + +#define UA(ka) ((char*)(ka) + ((uintptr)(USTKTOP - BY2PG) - (uintptr)base)) + sp = (char*)base + BY2PG - sizeof(Tos); + + /* push boot command line onto the stack */ + sp -= BOOTLINELEN; + sp[BOOTLINELEN-1] = '\0'; + memmove(sp, BOOTLINE, BOOTLINELEN-1); + + /* parse boot command line */ + argc = tokenize(sp, argv, nelem(argv)); + if(argc < 1){ + strcpy(sp, "boot"); + argc = 0; + argv[argc++] = sp; + } + + /* 8 byte word align stack */ + sp = (char*)((uintptr)sp & ~7); + + /* build argv on stack */ + sp -= (argc+1)*BY2WD; + for(i=0; i