]> git.lizzy.rs Git - plan9front.git/commitdiff
pc, pc64: support for multiboot framebuffer, common bootargs and multiboot code
authorcinap_lenrek <cinap_lenrek@felloff.net>
Sun, 25 Jun 2017 20:22:58 +0000 (22:22 +0200)
committercinap_lenrek <cinap_lenrek@felloff.net>
Sun, 25 Jun 2017 20:22:58 +0000 (22:22 +0200)
14 files changed:
sys/src/9/pc/bootargs.c [new file with mode: 0644]
sys/src/9/pc/fns.h
sys/src/9/pc/l.s
sys/src/9/pc/main.c
sys/src/9/pc/mem.h
sys/src/9/pc/mkfile
sys/src/9/pc/screen.c
sys/src/9/pc/screen.h
sys/src/9/pc/vgavesa.c
sys/src/9/pc64/fns.h
sys/src/9/pc64/l.s
sys/src/9/pc64/main.c
sys/src/9/pc64/mem.h
sys/src/9/pc64/mkfile

diff --git a/sys/src/9/pc/bootargs.c b/sys/src/9/pc/bootargs.c
new file mode 100644 (file)
index 0000000..ece6f8e
--- /dev/null
@@ -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<<p[1])-1 << p[0],
+                               (1UL<<p[3])-1 << p[2],
+                               (1UL<<p[5])-1 << p[4]);
+                       }
+                       cp = seprint(cp, ep, "*bootscreen=%dx%dx%d %s %#lux\n",
+                               (int)multiboot[24]*8 / depth,
+                               (int)multiboot[26],
+                               depth,
+                               chan,
+                               multiboot[22]);
+               }
+       } else
+       if((multiboot[0] & (1<<11)) != 0 && multiboot[19] != 0)         /* vbe mode info */
+               cp = vesabootscreenconf(cp, ep, KADDR(multiboot[19]));
+
+       /* 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;
+}
+
+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);
+}
index 594d2f553a5d4b1fee5568d2beed496bc6c8609d..3710d92913d4ea819b755a68d91b978d077230e1 100644 (file)
@@ -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);
index c2c2837937cc2f23319c109bbc0a1a3b3aa62177..e28ef9e959ea1caeb3333621ff7283f6e8f5cf7f 100644 (file)
@@ -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    $                             /* 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
 
 /*
index 1e9ec8bb6e92d1618eca0508827f9b7816f0a784..c69fb976948b6dda63df0fb9f4d68919e1f5a7ac 100644 (file)
 #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<argc; i++)
+               ((char**)sp)[i] = UA(argv[i]);
+       ((char**)sp)[i] = nil;
+
+       sp = UA(sp);
+#undef UA
+       sp -= BY2WD;
+}
+
 void
 userinit(void)
 {
@@ -294,7 +222,7 @@ userinit(void)
        v = tmpmap(pg);
        memset(v, 0, BY2PG);
        segpage(s, pg);
-       bootargs(v);
+       userbootargs(v);
        tmpunmap(v);
 
        /*
@@ -314,82 +242,6 @@ userinit(void)
        ready(p);
 }
 
-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;
-       }
-
-       /* 4 byte word align stack */
-       sp = (char*)((uintptr)sp & ~3);
-
-       /* build argv on stack */
-       sp -= (argc+1)*BY2WD;
-       for(i=0; i<argc; i++)
-               ((char**)sp)[i] = UA(argv[i]);
-       ((char**)sp)[i] = nil;
-
-       sp = UA(sp);
-#undef UA
-       sp -= BY2WD;
-}
-
-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)
 {
index 7f5b09a163955843b1bfb23cc187abbb98056c2a..6de469cb37644f18a53132dfd1b5404214223cd0 100644 (file)
  * 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
  */
index c6e683e22906f5f7b06d36c7a64d37e7ef28609f..62e622b21aa6f877ef73b8b407a3988104605aac 100644 (file)
@@ -53,6 +53,7 @@ OBJ=\
        memory.$O\
        mmu.$O\
        trap.$O\
+       bootargs.$O\
        $CONF.root.$O\
        $CONF.rootc.$O\
        $DEVS\
index 69018c4fe2bfe98931e5cca2daf43a6a560e6385..20df768fd437bb95d64c9318196181eaa4822b29 100644 (file)
@@ -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<<depth-1;
+       dm |= dm-1;
+
+       m[0] = rm & dm;
+       m[1] = gm & dm;
+       m[2] = bm & dm;
+       m[3] = (~(m[0] | m[1] | m[2])) & dm;
+
+       buf[0] = 0;
+Next:
+       for(c=0; c<4; c++){
+               for(n = 0; m[c] & (1<<n); n++)
+                       ;
+               if(n){
+                       m[0] >>= 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);
 }
index 646edd6e2a58da266aadaa2eb884d78355944acd..401d056a3f3e21c56faf00e112774af0ffa82e43 100644 (file)
@@ -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*);
index ceca04406d965759f4823fc392b2bb7432a4f04b..dbe4d0024b3bec8e5c5413adb30e8f0e0eed9627 100644 (file)
@@ -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<<p[31])-1 << p[32],
+                       (1UL<<p[33])-1 << p[34],
+                       (1UL<<p[35])-1 << p[36]);
+       return nil;
+}
+
 static void
 vesalinear(VGAscr *scr, int, int)
 {
        int i, mode, size, havesize;
-       ulong paddr;
        Pcidev *pci;
-       uchar *p;
+       char *err;
+       Vmode m;
 
        vbecheck();
        mode = vbegetmode();
@@ -111,14 +146,10 @@ vesalinear(VGAscr *scr, int, int)
                error("not in linear graphics mode");
         */
        mode &= 0x3FFF;
-       p = vbemodeinfo(mode);
-       if(!(WORD(p+0) & (1<<4)))
-               error("not in VESA graphics mode");
-       if(!(WORD(p+0) & (1<<7)))
-               error("not in linear graphics mode");
+       if((err = vmode(&m, vbemodeinfo(mode))) != nil)
+               error(err);
 
-       paddr = LONG(p+40);
-       size = WORD(p+20)*WORD(p+16);
+       size = m.dy * m.bpl;
 
        /*
         * figure out max size of memory so that we have
@@ -136,8 +167,8 @@ vesalinear(VGAscr *scr, int, int)
                                continue;
                        a = pci->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);
+}
index f51d21fe6a6bbb491608afaca002aad69be6002e..481572a3a096708aa54034d72b10b3ee0617bc7e 100644 (file)
@@ -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);
index 715e5f432f0fa4e4699c1e712a8827a6edcebd78..a1cc976f34e485057bab0253f8d9048c9e1ab9b5 100644 (file)
@@ -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    $                             /* depth */
+       LONG    $32                             /* depth */
 
 /* 
  * the kernel expects the data segment to be page-aligned
index 24d99eea6d5d0d4286edf79d6b59c1795790892c..179c9e6d0d59caba074392e61440c348bde48fe7 100644 (file)
 #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; i<argc; i++)
-               ((char**)sp)[i] = UA(argv[i]);
-       ((char**)sp)[i] = nil;
-
-       sp = UA(sp);
-#undef UA
-       sp -= BY2WD;
-}
-
 void
 init0(void)
 {
-       int i;
        char buf[2*KNAMELEN];
 
        up->nerrlab = 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<argc; i++)
+               ((char**)sp)[i] = UA(argv[i]);
+       ((char**)sp)[i] = nil;
+
+       sp = UA(sp);
+#undef UA
+       sp -= BY2WD;
+}
+
 void
 userinit(void)
 {
@@ -452,7 +302,7 @@ userinit(void)
        v = kmap(pg);
        memset(v, 0, BY2PG);
        segpage(s, pg);
-       bootargs(v);
+       userbootargs(v);
        kunmap(v);
 
        /*
@@ -480,7 +330,7 @@ void
 main()
 {
        mach0init();
-       options();
+       bootargsinit();
        ioinit();
        i8250console();
        quotefmtinstall();
index a5d1aa368f19c859c41a3127a55088aa85374eb5..4c07bf99b2448786b4e6d11d5c23d9fa51c10430 100644 (file)
 
 #define        MACHSIZE        (2*KSTACK)
 
+/*
+ * 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
  */
index 8214614a9567b84f2ac78de68cd4451fc4b24155..bf298306b695420df2cf07c0b874fd8da967b71f 100644 (file)
@@ -50,6 +50,7 @@ OBJ=\
        memory.$O\
        mmu.$O\
        trap.$O\
+       bootargs.$O\
        $CONF.root.$O\
        $CONF.rootc.$O\
        $DEVS\