Subject: Re: X11 with ZLXp-E3 framebuffer
To: Michiel Buddingh' <ajuin@stack.nl>
From: Greg A. Woods <woods@weird.com>
List: port-alpha
Date: 03/27/2005 16:57:55
[ On Sunday, March 27, 2005 at 19:53:23 (+0200), Michiel Buddingh' wrote: ]
> Subject: Re: X11 with ZLXp-E3 framebuffer
>
> Dennis Grevenstein <dennis@pcde.inka.de> writes:
> 
> > (WW) checkDevMem: failed to open/mmap /dev/mem (Operation not
> >   permitted) linear framebuffer access unavailable
> 
> You can't read /dev/mem at securelevel 1, and you can't set the
> securelevel to 0 without building a kernel with 'options insecure'.
> 
> If there's another way around this, I'm very much interested as well.

This is still very much a cheap poor hack to /dev/mem, and I don't know
if it'll work the same with XFree 4.x, or on alpha, but the following,
written by Matthieu Herrb and borrowed from OpenBSD, works very well for
me on i386.  ;-)

With the right device file permissions I can run "startx" as an ordinary
user, and my Xserver binary is not setuid root, but normally I run X
from xdm and thus it is run by root and I can keep the device protected.

(you'll see that I did get some of the hacks copied into the alpha
support in the Xserver, but I've never tested them, and I've not yet
even patched the alpha mem(4) driver either, though I do have a PC164
system and some interesting graphics cards to test in it some day when I
get some more spare time :-)

First bit is for your kernel config (note INSECURE is commented out):

# `INSECURE' causes the the kernel security level to be initialised to
# -1, which means when init increments it when multi-user mode is
# started you will be left with kern.securelevel = 0.  This allows
# writing to /dev/mem, loading kernel modules while multi-user, and
# other insecurities good only for development work or running
# stupidly insecure applications such as the XFree86 X11 Window System
# Server.  Do not use this option on a production server!
#
# See also the VGA "aperture" driver option VGA_APERTURE
#
#options 	INSECURE	# disable kernel security levels

# `VGA_APERTURE' allows ordinary users to mmap() the VGA framebuffer
# and BIOS areas via /dev/vga_aperture, iff sysctl machdep.allow_vga_aperture
# is set to 1, and the first megabyte (i.e. the whole ISA addressable
# space) if machdep.allow_vga_aperture is set to 2.  Note
# allow_vga_aperture can only be manipulated when securelevel <= 0,
# hence from /etc/sysctl.conf before the system goes multi-user.
# 
# XFree releases newer than 4.1.0 will attempt to use /dev/vga_aperture if
# their attempt to use /dev/mem fails.
#
options 	VGA_APERTURE	# user can mmap() /dev/vga_aperture


And this is for MAKEDEV but has the line numbers all off.  Note this new
device is just another minor node of /dev/mem:

Index: etc/etc.i386/MAKEDEV
===================================================================
RCS file: /cvs/master/m-NetBSD/main/src/etc/etc.i386/Attic/MAKEDEV,v
retrieving revision 1.175.2.4
diff -u -r1.175.2.4 MAKEDEV
--- etc/etc.i386/MAKEDEV	12 Apr 2004 04:49:40 -0000	1.175.2.4
+++ etc/etc.i386/MAKEDEV	23 Jan 2005 00:21:50 -0000
@@ -232,14 +234,17 @@
 	;;
 
 std)
-	rm -f console drum mem kmem null zero io klog
+	rm -f console drum mem kmem null zero io vga_aperture klog
 	mknod console		c 0 0
 	mknod drum		c 4 0	; chmod 640 drum ; chgrp kmem drum
 	mknod kmem		c 2 1	; chmod 640 kmem ; chgrp kmem kmem
 	mknod mem		c 2 0	; chmod 640 mem	; chgrp kmem mem
 	mknod null		c 2 2	; chmod 666 null
 	mknod zero		c 2 12	; chmod 666 zero
+	# XXX /dev/io is only supported if COMPAT_10 is defined
 	mknod io		c 2 14	; chmod 640 io ; chgrp kmem io
+	# XXX /dev/vga_aperture is only supported if VGA_APERTURE is defined
+	mknod vga_aperture	c 2 16	; chmod 600 vga_aperture
 	mknod klog		c 7 0	; chmod 600 klog
 	if $nofdesc; then
 		rm -f tty stdin stdout stderr

 
Index: share/man/man4/vga_aperture.4
===================================================================
RCS file: share/man/man4/vga_aperture.4
diff -N share/man/man4/vga_aperture.4
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ share/man/man4/vga_aperture.4	23 Jan 2005 00:23:54 -0000
@@ -0,0 +1,108 @@
+.\"	$OpenBSD: xf86.4,v 1.6 2003/06/06 10:29:41 jmc Exp $
+.\"
+.\" Copyright (c) 1998 Matthieu Herrb
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd October 26, 2003
+.Dt VGA_APERTURE 4
+.Os
+.Sh NAME
+.Nm vga_aperture
+.Nd VGA/BIOS aperture driver
+.Sh SYNOPSIS
+.Cd "option VGA_APERTURE"
+.Sh DESCRIPTION
+On
+.Va i386
+the
+.Pa /dev/vga_aperture
+driver provides access to the memory and I/O ports of a VGA board
+and to the PCI configuration registers and BIOS
+for use by the XFree86 X servers,
+even when running with a kernel security level of greater than zero.
+.\"
+.Sh ACCESS CONTROL
+Access to the
+.Pa /dev/vga_aperture
+device is allowed when the sysctl variable
+.Va machdep.allow_vga_aperture
+greater than or equal to 1.
+.Pp
+This variable (which has a default value of 0)
+can only be manipulated when the security level is <= 0, so it should be
+set in
+.Pa /etc/sysctl.conf .
+The possible values for
+.Va machdep.allow_vga_aperture
+are:
+.Bl -tag -width Ds
+.It 0
+the aperture driver is disabled.
+Opening it returns
+.Dv EPERM .
+.It 1
+the aperture driver allows access to standard VGA framebuffer and BIOS.
+Access to
+.Xr pci 4
+configuration registers is also allowed.
+.It 2
+in addition to allowing access to
+.Xr pci 4
+configuration registers,
+the aperture driver allows access to the whole 1st megabyte of physical
+memory, permitting use of the int10 emulation in XFree86 4.0.x.
+Note that this can cause some security problems, since the process that
+has access to the aperture driver can also access part of the kernel
+memory.
+.\" This mode is not supported on alpha or sparc64.
+.El
+.Sh SEE ALSO
+.Xr XF86_Accel 1 ,
+.Xr XF86_SVGA 1 ,
+.Xr options 4 ,
+.Xr pci 4 ,
+.Xr sysctl.conf 5 ,
+.Xr config 8 ,
+.Xr sysctl 8
+.Sh HISTORY
+.Pa /dev/vga_aperture
+was introduced as a loadable kernel module for
+.Nx 0.9 c
+with XFree86 3.1.
+It was integrated as an in-kernel device on
+.Ox 2.3 .
+It is required in order to allow access to I/O ports for all X servers since
+.Ox 2.4 .
+It has been integrated into the Planix release of
+.Nx 1.6.x
+by
+.An "Greg A. Woods" Aq woods@planix.com
+.Sh AUTHORS
+The aperture driver was written by Matthieu Herrb.
+.Sh BUGS
+This driver allows access to all addresses above
+.Va physmem .
+It should be restricted to the actual address range of the video
+memory.


Index: sys/arch/i386/include/cpu.h
===================================================================
RCS file: /cvs/master/m-NetBSD/main/src/sys/arch/i386/include/cpu.h,v
retrieving revision 1.80.4.1
diff -u -r1.80.4.1 cpu.h
--- sys/arch/i386/include/cpu.h	7 Sep 2003 13:09:54 -0000	1.80.4.1
+++ sys/arch/i386/include/cpu.h	27 Mar 2005 21:40:24 -0000
@@ -279,7 +279,8 @@
 #define CPU_TMLR_FREQUENCY	12 	/* int: current frequency */
 #define CPU_TMLR_VOLTAGE	13 	/* int: curret voltage */
 #define CPU_TMLR_PERCENTAGE	14	/* int: current clock percentage */
-#define	CPU_MAXID		15	/* number of valid machdep ids */
+#define	CPU_ALLOW_VGA_APERTURE	15	/* int: allow mmap() of /dev/vga_aperture */
+#define	CPU_MAXID		16	/* number of valid machdep ids */
 
 #define	CTL_MACHDEP_NAMES { \
 	{ 0, 0 }, \
@@ -297,6 +298,7 @@
 	{ "tm_longrun_frequency", CTLTYPE_INT }, \
 	{ "tm_longrun_voltage", CTLTYPE_INT }, \
 	{ "tm_longrun_percentage", CTLTYPE_INT }, \
+	{ "allow_vga_aperture", CTLTYPE_INT }, \
 }
 
 
Index: sys/arch/i386/include/conf.h
===================================================================
RCS file: /cvs/master/m-NetBSD/main/src/sys/arch/i386/include/Attic/conf.h,v
retrieving revision 1.10
diff -u -r1.10 conf.h
--- sys/arch/i386/include/conf.h	18 Apr 2002 12:54:15 -0000	1.10
+++ sys/arch/i386/include/conf.h	26 Oct 2003 23:45:14 -0000
@@ -37,6 +37,7 @@
  */
 
 #define	DEV_IO		14	/* iopl for compat_10 */
+#define DEV_VGA		16	/* minor device 16 is VGA & BIOS aperture */
 
 #include <sys/conf.h>
 
Index: sys/arch/i386/i386/sys_machdep.c
===================================================================
RCS file: /cvs/master/m-NetBSD/main/src/sys/arch/i386/i386/sys_machdep.c,v
retrieving revision 1.62.4.2
diff -u -r1.62.4.2 sys_machdep.c
--- sys/arch/i386/i386/sys_machdep.c	7 Aug 2002 04:34:25 -0000	1.62.4.2
+++ sys/arch/i386/i386/sys_machdep.c	26 Oct 2003 22:57:38 -0000
@@ -328,6 +328,10 @@
 }
 #endif	/* USER_LDT */
 
+#ifdef VGA_APERTURE
+extern int allow_vga_aperture;
+#endif
+
 int
 i386_iopl(p, args, retval)
 	struct proc *p;
@@ -338,8 +342,13 @@
 	struct trapframe *tf = p->p_md.md_regs;
 	struct i386_iopl_args ua;
 
-	if (securelevel > 1)
+#ifdef VGA_APERTURE
+	if (allow_vga_aperture == 0 && securelevel > 1)
 		return EPERM;
+#else
+	if (securelevel > 1)	/* XXX OpenBSD tests against 0! */
+		return EPERM;
+#endif
 
 	if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
 		return error;
Index: sys/arch/i386/i386/mem.c
===================================================================
RCS file: /cvs/master/m-NetBSD/main/src/sys/arch/i386/i386/mem.c,v
retrieving revision 1.51
diff -u -r1.51 mem.c
--- sys/arch/i386/i386/mem.c	27 Feb 2002 01:20:53 -0000	1.51
+++ sys/arch/i386/i386/mem.c	27 Mar 2005 21:40:48 -0000
@@ -62,6 +62,16 @@
 
 #include <uvm/uvm_extern.h>
 
+#ifdef VGA_APERTURE
+/* open counter for aperture */
+static int ap_open_count = 0;
+extern int allow_vga_aperture;	/* sysctl machdep.allow_vga_aperture */
+
+# define VGA_START	0xA0000		/* 640 KB */
+# define VGA_END	0xBFFFF		/*  */
+# define BIOS_END	0xFFFFF		/* 1 MB */
+#endif
+                                                                                                                    
 extern char *vmmap;            /* poor name! */
 caddr_t zeropage;
 
@@ -77,14 +87,28 @@
 #ifdef COMPAT_10
 	/* This is done by i386_iopl(3) now. */
 	case DEV_IO:
-		if (flag & FWRITE) {
+		if (securelevel <= 0 && (flag & FWRITE)) {
 			struct trapframe *fp;
+
 			fp = curproc->p_md.md_regs;
 			fp->tf_eflags |= PSL_IOPL;
 		}
 		break;
 #endif
 
+#ifdef VGA_APERTURE
+       case DEV_VGA:
+	       if (suser(p->p_ucred, &p->p_acflag) != 0)
+		       return (EPERM);
+	       if (allow_vga_aperture == 0)
+		       return (EPERM);
+	       /* authorize only one simultaneous open() */
+	       if (ap_open_count > 0)
+		       return (EBUSY);
+               ap_open_count++;
+	       break;
+#endif
+
 	default:
 		break;
 	}
@@ -98,6 +122,10 @@
 	int flag, mode;
 	struct proc *p;
 {
+#ifdef VGA_APERTURE
+	if (minor(dev) == DEV_VGA)
+		ap_open_count--;
+#endif
 
 	return (0);
 }
@@ -200,18 +228,47 @@
 {
 	struct proc *p = curproc;	/* XXX */
 
+	switch (minor(dev)) {
+#ifdef VGA_APERTURE
+	case DEV_VGA:
+		switch (allow_vga_aperture) {
+		case 1:
+			/*
+			 * Allow mapping of the VGA framebuffer & BIOS only
+			 * or space above physical memory.... (AGP?)
+			 */
+			if (off < VGA_START)
+				return (-1);
+			/* FALLTHRU */
+		case 2:
+			/*
+			 * Allow mapping of the whole 1st megabyte for x86emu
+			 * or space above physical memory.... (AGP?)
+			 */
+			if (off > BIOS_END && (u_int) off <= ctob(physmem))
+				return (-1);
+			return (i386_btop((u_int) off));
+		}
+		return (-1);
+#endif
+	case DEV_MEM:
+		if ((u_int) off > ctob(physmem) && suser(p->p_ucred, &p->p_acflag) != 0)
+			return (-1);
+		return (i386_btop((u_int)off));
+	}
+
 	/*
-	 * /dev/mem is the only one that makes sense through this
-	 * interface.  For /dev/kmem any physaddr we return here
-	 * could be transient and hence incorrect or invalid at
-	 * a later time.  /dev/null just doesn't make any sense
-	 * and /dev/zero is a hack that is handled via the default
-	 * pager in mmap().
+	 * /dev/mem and /dev/vga_aperture are the only minor nodes it makes
+	 * sense to support through this interface.
+	 *
+	 * For /dev/kmem any physaddr returned would likely be transient and
+	 * hence incorrect or invalid at any later time.
+	 *
+	 * mmap() of /dev/null just doesn't make any sense
+	 *
+	 * mmap() of /dev/zero is a hack that is handled via the default pager
+	 * in sys_mmap().
 	 */
-	if (minor(dev) != DEV_MEM)
-		return (-1);
 
-	if ((u_int)off > ctob(physmem) && suser(p->p_ucred, &p->p_acflag) != 0)
-		return (-1);
-	return (i386_btop((u_int)off));
+	return (-1);
 }
Index: sys/arch/i386/i386/machdep.c
===================================================================
RCS file: /cvs/master/m-NetBSD/main/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.471.4.4
diff -u -r1.471.4.4 machdep.c
--- sys/arch/i386/i386/machdep.c	16 Aug 2003 16:17:11 -0000	1.471.4.4
+++ sys/arch/i386/i386/machdep.c	27 Jan 2005 23:00:09 -0000
@@ -247,6 +247,14 @@
 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX];
 int	mem_cluster_cnt;
 
+#ifdef VGA_APERTURE
+# ifdef INSECURE
+int allow_vga_aperture = 1;
+# else
+int allow_vga_aperture = 0;
+# endif
+#endif
+
 /*
  * The number of CPU cycles in one second.
  */
@@ -1993,6 +2001,15 @@
 			return (EOPNOTSUPP);
 		tmx86_get_longrun_status_all();
 		return (sysctl_rdint(oldp, oldlenp, newp, crusoe_percentage));
+	case CPU_ALLOW_VGA_APERTURE:
+#ifdef VGA_APERTURE
+		if (securelevel > 0)
+			return (sysctl_rdint(oldp, oldlenp, newp, allow_vga_aperture));
+		else
+			return (sysctl_int(oldp, oldlenp, newp, newlen, &allow_vga_aperture));
+#else
+		return (sysctl_rdint(oldp, oldlenp, newp, 0));
+#endif
 	default:
 		return (EOPNOTSUPP);
 	}
@@ -2224,6 +2241,10 @@
 	}
 
 	boothowto = howto;
+	/*
+	 * XXX this bit, except for the "cold" check above, should be MI --
+	 * i.e. back in kern/kern_xxx.c:sys_reboot()
+	 */
 	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
 		waittime = 0;
 		vfs_shutdown();


Index: xfree/xc/programs/Xserver/hw/xfree86/common/xf86Privstr.h
===================================================================
RCS file: /cvs/master/m-NetBSD/main/xsrc/xfree/xc/programs/Xserver/hw/xfree86/common/xf86Privstr.h,v
retrieving revision 1.1.1.6
diff -u -r1.1.1.6 xf86Privstr.h
--- xfree/xc/programs/Xserver/hw/xfree86/common/xf86Privstr.h	5 Mar 2004 14:28:27 -0000	1.1.1.6
+++ xfree/xc/programs/Xserver/hw/xfree86/common/xf86Privstr.h	14 Jun 2004 18:28:25 -0000
@@ -143,6 +143,7 @@
 #ifdef CSRG_BASED
     int			screenFd;	/* fd for memory mapped access to
 					 * vga card */
+    char *              screenName;	/* name opened for screenFd */
     int			consType;	/* Which console driver? */
 #endif
 
Index: xfree/xc/programs/Xserver/hw/xfree86/os-support/bsd/alpha_video.c
===================================================================
RCS file: /cvs/master/m-NetBSD/main/xsrc/xfree/xc/programs/Xserver/hw/xfree86/os-support/bsd/alpha_video.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 alpha_video.c
--- xfree/xc/programs/Xserver/hw/xfree86/os-support/bsd/alpha_video.c	5 Mar 2004 14:29:16 -0000	1.1.1.3
+++ xfree/xc/programs/Xserver/hw/xfree86/os-support/bsd/alpha_video.c	23 Jan 2005 00:24:26 -0000
@@ -184,15 +184,25 @@
                   "\tin /etc/sysctl.conf and reboot your machine\n" \
                   "\trefer to xf86(4) for details"
 #endif
-
-static Bool useDevMem = FALSE;
-static int  devMemFd = -1;
+#ifdef __NetBSD__
+# define SYSCTL_MSG "\tCheck that you have set 'machdep.allow_vga_aperture=1'\n"\
+		    "\tin /etc/sysctl.conf and run '/etc/rc.d/sysctl start'\n" \
+		    "\tRefer to vga_aperture(4) for details.\n"
+#endif
 
 #ifdef HAS_APERTURE_DRV
-#define DEV_APERTURE "/dev/xf86"
+# ifdef __OpenBSD__
+#  define DEV_APERTURE "/dev/xf86"
+# else
+#  define DEV_APERTURE "/dev/vga_aperture"
+# endif
 #endif
 #define DEV_MEM "/dev/mem"
 
+static Bool useDevMem = FALSE;
+static int  devMemFd = -1;
+static char *devMemName = "dev_mem";
+
 static pointer mapVidMem(int, unsigned long, unsigned long, int);
 static void unmapVidMem(int, pointer, unsigned long);
 static pointer mapVidMemSparse(int, unsigned long, unsigned long, int);
@@ -243,6 +253,7 @@
 	    if (base != MAP_FAILED) {
 		munmap((caddr_t)base, 4096);
 		devMemFd = fd;
+		devMemName = DEV_MEM;
 		useDevMem = TRUE;
 		return;
 	    } else {
@@ -257,14 +268,15 @@
            xf86Msg(X_WARNING, "checkDevMem: failed to open/mmap %s (%s)\n",
                    DEV_MEM, strerror(errno));
 #else
-#ifndef __OpenBSD__
-           xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n"
-               "\t(%s)\n", DEV_APERTURE, DEV_MEM, strerror(errno));
-#else /* __OpenBSD__ */
+# if defined(SYSCTL_MSG)
            xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n"
                    "\t(%s)\n%s", DEV_APERTURE, DEV_MEM, strerror(errno),
                    SYSCTL_MSG);
-#endif /* __OpenBSD__ */
+# else
+           xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n"
+               "\t(%s)\n", DEV_APERTURE, DEV_MEM, strerror(errno));
+# endif
+	   
 #endif
            xf86ErrorF("\tlinear framebuffer access unavailable\n");
 	}
@@ -310,7 +322,7 @@
 	    if (devMemFd < 0) 
 	    {
 		FatalError("xf86MapVidMem: failed to open %s (%s)\n",
-			   DEV_MEM, strerror(errno));
+			   devMemName, strerror(errno));
 	    }
 	    base = mmap((caddr_t)0, Size,
 			(flags & VIDMEM_READONLY) ?
@@ -318,14 +330,14 @@
 			 MAP_FLAGS, devMemFd, (off_t)Base + BUS_BASE_BWX);
 	    if (base == MAP_FAILED)
 	    {
-		FatalError("%s: could not mmap %s [s=%lx,a=%lx] (%s)\n",
-			   "xf86MapVidMem", DEV_MEM, Size, Base, 
+		FatalError("%s: could not mmap %s [s=%x,a=%lx] (%s)\n",
+			   "xf86MapVidMem", devMemName, Size, Base, 
 			   strerror(errno));
 	    }
 	    return(base);
 	}
 		
-	/* else, mmap /dev/vga */
+	/* else, mmap the screenFd */
 	if ((unsigned long)Base < 0xA0000 || (unsigned long)Base >= 0xC0000)
 	{
 		FatalError("%s: Address 0x%lx outside allowable range\n",
@@ -338,8 +350,8 @@
 		    (unsigned long)Base + BUS_BASE);
 	if (base == MAP_FAILED)
 	{
-	    FatalError("xf86MapVidMem: Could not mmap /dev/vga (%s)\n",
-		       strerror(errno));
+	    FatalError("xf86MapVidMem: Could not mmap screen file %s (%s)\n",
+		       xf86Info.screenName, strerror(errno));
 	}
 	return(base);
 }
@@ -377,7 +389,7 @@
 	{
 		xf86Msg(X_WARNING, 
 			"xf86ReadBIOS: %s mmap[s=%x,a=%lx,o=%lx] failed (%s)\n",
-			DEV_MEM, Len, Base, Offset, strerror(errno));
+			devMemName, Len, Base, Offset, strerror(errno));
 		return(-1);
 	}
 #ifdef DEBUG
Index: xfree/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_init.c
===================================================================
RCS file: /cvs/master/m-NetBSD/main/xsrc/xfree/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_init.c,v
retrieving revision 1.2
diff -u -r1.2 bsd_init.c
--- xfree/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_init.c	26 Jan 2005 22:19:04 -0000	1.2
+++ xfree/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_init.c	28 Jan 2005 21:50:59 -0000
@@ -36,6 +36,7 @@
 #include <sys/param.h>
 #include <sys/utsname.h>
 #include <stdlib.h>
+#include <paths.h>
 
 static Bool KeepTty = FALSE;
 static int devConsoleFd = -1;
@@ -73,7 +74,7 @@
 #endif
 
 #if defined(WSCONS_SUPPORT) && defined(__NetBSD__)
-/* NetBSD's new console driver */
+/* NetBSD's new console driver, in PCVT compatability mode, "options WSDISPLAY_COMPAT_PCVT" */
 #define WSCONS_PCVT_COMPAT_CONSOLE_DEV "/dev/ttyE0"
 #endif
 
@@ -163,7 +164,7 @@
 	/* check if we are run with euid==0 */
 	if (geteuid() != 0)
 	{
-	    FatalError("xf86OpenConsole: Server must be suid root");
+	    FatalError("xf86OpenConsole: Server must be run as root");
 	}
 
 	if (!KeepTty)
@@ -224,11 +225,11 @@
 	     * Hack to prevent keyboard hanging when syslogd closes
 	     * /dev/console
 	     */
-	    if ((devConsoleFd = open("/dev/console", O_WRONLY,0)) < 0)
+	    if ((devConsoleFd = open(_PATH_CONSOLE, O_WRONLY,0)) < 0)
 	    {
 		xf86Msg(X_WARNING,
-			"xf86OpenConsole: couldn't open /dev/console (%s)\n",
-			strerror(errno));
+			"xf86OpenConsole: couldn't open %s (%s)\n",
+			_PATH_CONSOLE, strerror(errno));
 	    }
 	    break;
 #endif
@@ -336,6 +337,7 @@
 {
     int fd = -1;
 
+    xf86Msg(X_INFO, "xf86OpenPccons: trying %s or %s\n", PCCONS_CONSOLE_DEV1, PCCONS_CONSOLE_DEV1);
     if ((fd = open(PCCONS_CONSOLE_DEV1, PCCONS_CONSOLE_MODE, 0))
 	>= 0 ||
 	(fd = open(PCCONS_CONSOLE_DEV2, PCCONS_CONSOLE_MODE, 0))
@@ -370,6 +372,7 @@
     long syscons_version;
     MessageType from;
 
+    xf86Msg(X_INFO, "xf86OpenSyscons: trying %s\n", SYSCONS_CONSOLE_DEV);
     /* Check for syscons */
     if ((fd = open(SYSCONS_CONSOLE_DEV1, SYSCONS_CONSOLE_MODE, 0)) >= 0
 	|| (fd = open(SYSCONS_CONSOLE_DEV2, SYSCONS_CONSOLE_MODE, 0)) >= 0)
@@ -465,7 +468,8 @@
 		FatalError("xf86OpenSyscons: VT_GETMODE failed");
 	    }
 	    xf86Info.consType = SYSCONS;
-	    xf86Msg(X_PROBED, "Using syscons driver with X support");
+	    xf86Info.screenName = strdup(vtname);
+	    xf86Msg(X_PROBED, "Using syscons driver via %s with X support", vtname);
 	    if (syscons_version >= 0x100)
 	    {
 		xf86ErrorF(" (version %ld.%ld)\n", syscons_version >> 8,
@@ -508,10 +512,12 @@
     vtprefix = "/dev/ttyC";
 #endif
 
+    xf86Msg(X_INFO, "xf86OpenPcvt: trying %s\n", PCVT_CONSOLE_DEV);
     fd = open(PCVT_CONSOLE_DEV, PCVT_CONSOLE_MODE, 0);
 #ifdef WSCONS_PCVT_COMPAT_CONSOLE_DEV
     if (fd < 0)
     {
+	xf86Msg(X_INFO, "xf86OpenPcvt: (WSCONS_PCVT_COMPAT) trying %s\n", WSCONS_PCVT_COMPAT_CONSOLE_DEV);
 	fd = open(WSCONS_PCVT_COMPAT_CONSOLE_DEV, PCVT_CONSOLE_MODE, 0);
 	vtprefix = "/dev/ttyE";
     }
@@ -574,6 +580,7 @@
 		FatalError("xf86OpenPcvt: Cannot open %s (%s)",
 			   vtname, strerror(errno));
 	    }
+	    xf86Info.screenName = strdup(vtname);
 	    if (ioctl(fd, VT_GETMODE, &vtmode) < 0)
 	    {
 		FatalError("xf86OpenPcvt: VT_GETMODE failed");
@@ -581,12 +588,13 @@
 	    xf86Info.consType = PCVT;
 #ifdef WSCONS_SUPPORT
 	    xf86Msg(X_PROBED,
-		    "Using wscons driver in pcvt compatibility mode "
+		    "Using wscons driver via %s in pcvt compatibility mode "
 		    "(version %d.%d)\n",
+		    vtname,
 		    pcvt_version.rmajor, pcvt_version.rminor);
 #else
-	    xf86Msg(X_PROBED, "Using pcvt driver (version %d.%d)\n",
-		    pcvt_version.rmajor, pcvt_version.rminor);
+	    xf86Msg(X_PROBED, "Using pcvt driver via %s (version %d.%d)\n",
+		    vtname, pcvt_version.rmajor, pcvt_version.rminor);
 #endif
 	}
 	else
@@ -617,18 +625,24 @@
 	sprintf(ttyname, "/dev/ttyE%d", i);
 #elif defined(__OpenBSD__)
 	sprintf(ttyname, "/dev/ttyC%d", i);
+#else
+# include "ERROR: WSCONS_SUPPORT is currently only available for NetBSD and OpenBSD"
 #endif
-	if ((fd = open(ttyname, 2)) != -1)
+	xf86Msg(X_INFO, "xf86OpenWScons: trying %s\n", ttyname);
+	if ((fd = open(ttyname, O_RDWR, 0)) != -1) {
+	    xf86Msg(X_WARNING, "xf86OpenWScons: open(%s) failed: %s\n", ttyname, strerror(errno));
 	    break;
+	}
     }
     if (fd != -1) {
 	if (ioctl(fd, WSDISPLAYIO_SMODE, &mode) < 0) {
-	    FatalError("%s: WSDISPLAYIO_MODE_MAPPED failed (%s)\n%s",
-		       "xf86OpenConsole", strerror(errno),
+	    FatalError("%s: WSDISPLAYIO_MODE_MAPPED failed on %s (%s)\n%s", 
+		       ttyname, "xf86OpenConsole", strerror(errno),
 		       CHECK_DRIVER_MSG);
 	}
+	xf86Info.screenName = strdup(ttyname);
 	xf86Info.consType = WSCONS;
-	xf86Msg(X_PROBED, "Using wscons driver\n");
+	xf86Msg(X_PROBED, "Using wscons driver on %s\n", ttyname);
     }
     return fd;
 }
@@ -683,10 +697,14 @@
     {
 	close(xf86Info.screenFd);
 	close(xf86Info.consoleFd);
-	if ((xf86Info.consoleFd = open("/dev/console",O_RDONLY,0)) <0)
+	/* XXX Why the hell bother doing this just to close it again immediately!?!?!?!? */
+	if ((xf86Info.consoleFd = open(_PATH_CONSOLE, O_RDONLY, 0)) <0)
 	{
-	    xf86FatalError("xf86CloseConsole: Cannot open /dev/console (%s)",
-			   strerror(errno));
+	    char *fmsg;
+
+	    asprintf(&fmsg, "%s: %s", _PATH_CONSOLE, strerror(errno));
+	    xf86FatalError("xf86CloseConsole: Cannot open console read-only (%s)", fmsg);
+	    free(fmsg);
 	}
     }
     close(xf86Info.consoleFd);
Index: xfree/xc/programs/Xserver/hw/xfree86/os-support/bsd/i386_video.c
===================================================================
RCS file: /cvs/master/m-NetBSD/main/xsrc/xfree/xc/programs/Xserver/hw/xfree86/os-support/bsd/i386_video.c,v
retrieving revision 1.3
diff -u -r1.3 i386_video.c
--- xfree/xc/programs/Xserver/hw/xfree86/os-support/bsd/i386_video.c	5 Mar 2004 16:33:06 -0000	1.3
+++ xfree/xc/programs/Xserver/hw/xfree86/os-support/bsd/i386_video.c	23 Jan 2005 00:24:31 -0000
@@ -73,19 +73,33 @@
 		"\tin /etc/sysctl.conf and reboot your machine\n" \
 		"\trefer to xf86(4) for details"
 #endif
+#ifdef __NetBSD__
+#define SYSCTL_MSG "\tCheck that you have set 'machdep.allow_vga_aperture=1'\n"\
+		   "\tin /etc/sysctl.conf and run '/etc/rc.d/sysctl start'\n" \
+		   "\tRefer to vga_aperture(4) for details.\n"
+#define SYSCTL_MSG2 \
+		"Check that you have set 'machdep.allow_vga_aperture=2'\n" \
+		"\tin /etc/sysctl.conf and run '/etc/rc.d/sysctl start'\n" \
+		"\tRefer to vga_aperture(4) for details.\n"
+#endif
 
 /***************************************************************************/
 /* Video Memory Mapping section                                            */
 /***************************************************************************/
 
-static Bool useDevMem = FALSE;
-static int  devMemFd = -1;
-
 #ifdef HAS_APERTURE_DRV
-#define DEV_APERTURE "/dev/xf86"
+# ifdef __OpenBSD__
+#  define DEV_APERTURE "/dev/xf86"
+# else
+#  define DEV_APERTURE "/dev/vga_aperture"
+# endif
 #endif
 #define DEV_MEM "/dev/mem"
 
+static Bool useDevMem = FALSE;
+static int  devMemFd = -1;
+static char *devMemName = "dev_mem";
+
 static pointer mapVidMem(int, unsigned long, unsigned long, int);
 static void unmapVidMem(int, pointer, unsigned long);
 
@@ -126,6 +140,7 @@
 	    {
 		munmap((caddr_t)base, 4096);
 		devMemFd = fd;
+		devMemName = DEV_MEM;
 		useDevMem = TRUE;
 		return;
 	    } else {
@@ -159,6 +174,7 @@
 	    {
 		munmap((caddr_t)base, 4096);
 		devMemFd = fd;
+		devMemName = DEV_APERTURE;
 		useDevMem = TRUE;
 		xf86Msg(X_INFO, "checkDevMem: using aperture driver %s\n",
 		        DEV_APERTURE);
@@ -174,14 +190,14 @@
 	} else {
 	    if (warn)
 	    {
-#ifndef __OpenBSD__
-		xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n"
-			"\t(%s)\n", DEV_MEM, DEV_APERTURE, strerror(errno));
-#else /* __OpenBSD__ */
+#if defined(SYSCTL_MSG)
 		xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n"
 			"\t(%s)\n%s", DEV_MEM, DEV_APERTURE, strerror(errno),
 			SYSCTL_MSG);
-#endif /* __OpenBSD__ */
+#else
+		xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n"
+			"\t(%s)\n", DEV_MEM, DEV_APERTURE, strerror(errno));
+#endif
 	    }
 	}
 	
@@ -226,7 +242,7 @@
 	    if (devMemFd < 0) 
 	    {
 		FatalError("xf86MapVidMem: failed to open %s (%s)",
-			   DEV_MEM, strerror(errno));
+			   devMemName, strerror(errno));
 	    }
 	    base = mmap((caddr_t)0, Size,
 			(flags & VIDMEM_READONLY) ?
@@ -235,7 +251,7 @@
 	    if (base == MAP_FAILED)
 	    {
 		FatalError("%s: could not mmap %s [s=%lx,a=%lx] (%s)",
-			   "xf86MapVidMem", DEV_MEM, Size, Base, 
+			   "xf86MapVidMem", devMemName, Size, Base, 
 			   strerror(errno));
 	    }
 	    return(base);
@@ -255,8 +271,8 @@
 	    );
 	if (base == MAP_FAILED)
 	{
-	    FatalError("xf86MapVidMem: Could not mmap /dev/vga (%s)",
-		       strerror(errno));
+	    FatalError("xf86MapVidMem: Could not mmap screen file %s (%s)",
+		       xf86Info.screenName, strerror(errno));
 	}
 	return(base);
 }
@@ -293,9 +309,9 @@
 	if ((long)ptr == -1)
 	{
 		xf86Msg(X_WARNING, 
-			"xf86ReadBIOS: %s mmap[s=%x,a=%lx,o=%lx] failed (%s)\n",
-			DEV_MEM, Len, Base, Offset, strerror(errno));
-#ifdef __OpenBSD__
+			"xf86ReadBIOS: %s mmap[s=%x,a=%lx,o=%lx] failed (%s)",
+			devMemName, Len, Base, Offset, strerror(errno));
+#if defined(SYSCTL_MSG2) && (defined(__OpenBSD__) || defined(__NetBSD__))
 		if (Base < 0xa0000) {
 		    xf86Msg(X_WARNING, SYSCTL_MSG2);
 		} 
@@ -332,12 +348,12 @@
 
 	if (i386_iopl(TRUE) < 0)
 	{
-#ifndef __OpenBSD__
-		FatalError("%s: Failed to set IOPL for extended I/O",
-			   "xf86EnableIO");
-#else
+#if defined(SYSCTL_MSG)
 		FatalError("%s: Failed to set IOPL for extended I/O\n%s",
 			   "xf86EnableIO", SYSCTL_MSG);
+#else
+		FatalError("%s: Failed to set IOPL for extended I/O",
+			   "xf86EnableIO");
 #endif
 	}
 	ExtendedEnabled = TRUE;


-- 
						Greg A. Woods

H:+1 416 218-0098  W:+1 416 489-5852 x122  VE3TCP  RoboHack <woods@robohack.ca>
Planix, Inc. <woods@planix.com>          Secrets of the Weird <woods@weird.com>