Subject: Re: Driver hierarchy
To: Chris G. Demetriou <>
From: Eduardo E. Horvath <>
List: tech-kern
Date: 03/20/2000 09:41:50
> Simon Burge <> writes:

> > 	ARCHDIRS.sparc= sparc   sparc64
> > 	ARCHDIRS.sparc64=${ARCHDIRS.sparc}
> similarly here.  i don't think sparc should include sparc64.  maybe
> sparc64 including sparc is OK -- i dunno, but even that doesn't seem
> to make much sense to me.  the only thing that should be included
> multiple times are the basic CPU support dirs which support multiple
> endiannesses (e.g. mips).
> (as an aside, i've kinda wondered: why can't sparc and sparc64 be put
> in the same MACHINE_ARCH, in the same way that all of the various MIPS
> flavors are.  there's similar variation between mips32 and mip64,
> right?  I'd expect the same ABI issues to show up in each place, and
> i'd expect a consistent solution, but my expectations aren't often in
> sync with reality.  8-)

O.K.  I'll answer that.  

Thre really are two MACHINE_ARCHes.  MACHINE_ARCH=sparc is for 32-bit
SPARC v8- binaries that run on sun4, sun4c, sun4m, sun4d, and sun4e
machines.  MACHINE_ARCH=sparc64 is for 64-bit SPARC v9+ binaries that
will only run on sun4u machines.

Binaries are different.  Toolchains are different.  Stack frames are
different.  Even the code to set up the execution environment is
different.  If you took an EM_SPARC binary and changed the ELF type to
EM_SPARC64 it would immediately fault due to stackframe

You can compile the sparc64 kernel two different ways using two
different toolchains.  Using the 32-bit toolchain (and the proper
makefile tweaks[1]) you get a 32-bit kernel that MACHINE_ARCH=sparc.  It
runs most all NetBSD/sparc binaries with little problem.  It is
limited to a 32-bit (4GB) address space.  It will not run SPARC v9
binaries and can not run MACHINE_ARCH=sparc64 userland.  It requires a
32-bit MACHINE_ARCH=sparc /sbin/init or it will not boot.

Using the 64-bit toolchain (and makefile tweaks) you get a 64-bit
kernel.  It will run NetBSD/sparc64 binaries.  It has a 64-bit address
space, 64-bit registers, etc.  It requires a 64-bit
MACHINE_ARCH=sparc64 /sbin/init or it will not boot[2].

The 64-bit kernel can be compiled with COMPAT_NETBSD32.  This allows
the running of some 32-bit MACHINE_ARCH=sparc binaries.  These
binaries cannot use libkvm or they will get complete garbage.  A
32-bit binary cannot expect to extract sensible information from a
64-bit binary.  Pointers are different sizes, structure members and
alignments are different.  They cannot use sysctl.  You cannot run a
32-bit NFS server.  32-bit *_mount does not work.  It just doesn't
seem to be worth the effort to create a complete emulation environment
at this time.  The binary incompatibilities are to great.  Most of
these things cannot be easily fixed.

Then there's the conflict between 32-bit and 64-bit shared libraries
which is equivalent to the a.out/ELF issue but both use the same
binary format and identically named ld.so_elf.

The difference between MACHINE_ARCH=sparc and MACHINE_ARCH=sparc64 is
equivalent to the difference between MACHINE_ARCH=mipeb and

> > in <> doesn't seem too bad.  Then things like sys/arch/Makefile
> > just have
> > 
> yah.
> > > 	* for the /usr/include/machine symlink, point to the _generic
> > > 	  cpu_ headers, and see what breaks.  everything that breaks
> > > 	  is either:
> > > 
> > > 		* something that is but doesn't need to be MACHINE
> > > 		  dependent, or,
> > > 
> > > 		* something that needs to have code written, so it
> > > 		  will be properly decided at run-time based on the
> > > 		  MACHINE value.
> > 
> > Almost sounds like a case for domain-os like symlinks :-)
> *chuckle*  see PR 1781.  no, i don't think it's a good idea.
> i don't think it's a particularly good idea here, either, if you're
> (jokingly) suggesting the 'machine' automatically repoint itself.
> there's too much ability to accidentally make binaries
> MACHINE-dependent that way.

Ugh.  This gets really ugly.  When mucking with libkvm I found a need
to include both sparc and sparc64 headers in the same file.  But
headers include other headers which include other headers that blindly
use <machine/foo.h> which results in really strange things happenning.

> > > by decided at run-time, i mean use sysctl (or whatever) to find our
> > > the current MACHINE type, then pick from separately-compiled
> > > machine-specific versions of code, and do the right thing with a
> > > function switch or whatever.
> > 
> > I can see programs like disklabel becoming a bit of a nightmare with
> > .../disklabel/arch/m68k/machdep.c having large case statements.  It
> > would however probably be a Big Step In The Right Direction...
> right, except, you can't really have a single large case statement and
> just do everything in one file per MACHINE_ARCH, because, at least
> right now, the constant names conflict.  now, you could certaily fix
> that...

Constant names, structure names, lots of things.  

[1] Some assembly code depends on the architecture model which depends
on the toolchain being used.  Some kernel options are valid only on
certain toolchains.  (COMPAT_NETBSD32 does not work well on a 32-bit
kernel.)  It would be nice if the build could detect the toolchain and
enable/disable the appropriate tweaks.

[2] I have experimented with using a 32-bit init on a 64-bit kernel.
Some parts of it can be made to work.  But eventually it bombs when
trying to issue sysctl()s.  

Eduardo Horvath
	"I need to find a pithy new quote." -- me