Subject: Kernel config file caveat
To: None <port-sun3@NetBSD.ORG>
From: Geoff Adams <gadams@avernus.com>
List: port-sun3
Date: 04/20/1995 02:52:34
I've just determined that it's dangerous not to set the option GENERIC
if you do 'config netbsd swap generic' in your kernel config file.
This seems broken by my set of assumptions, which are that for generic
kernels you specify 'options GENERIC,' and for a kernel for a machine
named, say, spatula, you specify 'options SPATULA.'

Here's why it happens, though.  (I know Gordon knows all this.  He
wrote it.)

The sun3 autoconf.c is dependent on GENERIC in a way which seems to
cause trouble.  Specifically, if GENERIC is not defined, and the
kernel config file specifies generic swapping, then the root, swap,
and dump devices are never selected.  Here's the relevent function:

void configure()
{
    ... some other stuff ...

#ifdef  GENERIC
    /* Choose root and swap devices. */
    swapgeneric();
#endif
    swapconf();
    dumpconf();
}

Swapgeneric() only gets compiled in if the kernel config file contains
a line like:

config          netbsd  root on sd0 swap on sd0

Swapgeneric() sets rootdev, the first element of the array swdevt, and
dumpdev.  Additionally, it selects a mountroot(), depending on the boot
device, and if it's NFS, sets nfsbootdev.

swdevt is initialized as follows:

struct  swdevt swdevt[] = {
        { NODEV,        0,      0 },
        { NODEV,        0,      0 },
};

So, without swapgeneric() doing its thing, swdevt contains zeroes, so
the for loop in swapconf() will happily fall through without doing
anything.  This leads to an MMU fault very shortly later.

I noticed that amiga uses:

struct  swdevt swdevt[] = {
        { NODEV,        1,      0 },
        { NODEV,        0,      0 },
};

Does this default to partition b of no device?  Hmmm...

If, on the other hand, you specify a config line such as:

config          netbsd  root on sd0 swap on sd0

then a swapnetbsd.c file gets created for you in your compile directory
which sets rootdev, dumpdev, and swdevt appropriately.  It does this
via variable initialization, not through procedural setting.  For
instance:

dev_t   dumpdev = makedev(7, 1);        /* sd0b */

And everything works out nicely.  As long as you haven't included
'options GENERIC' in your config file, because then I imagine you'd
get a link error.


So, the problem, as I understand it, is that if we use swapgeneric.c,
instead of a created swap%s.c, we need to call the function
swapgeneric() within it.  How can we know at comnpile time whether to
call that function?  At the moment, the solution seems to be to use
#ifdef GENERIC, and make the requirement that the user specify

options         GENERIC

if and only if swap is set up like

config          netbsd swap generic


Thinking about it some more, I've come up with the question:  What
happens if you've set your root/swap/dump device to be sd0 in the
kernel config file, and you then boot from what ends up at autoconf
time to be, say, sd2?  And, of course, the PROM can hand us off a
boot device name that doesn't match our concept of the world,
because we might map SCSI IDs to sd#s differently.

Is there any way that makes sense to move the code in swapgeneric(),
which grabs the root/swap/dump devices from the PROM or from user
input, into the autoconf.c?  That could solve some of these problems.

Ponderously,
- Geoff