Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 14 May 1996 12:08:57 -0400 (EDT)
From:      Bill Paul <wpaul@skynet.ctr.columbia.edu>
To:        msmith@atrad.adelaide.edu.au (Michael Smith)
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: Making a three-stage boot
Message-ID:  <199605141608.MAA02641@skynet.ctr.columbia.edu>
In-Reply-To: <199605141446.AAA23535@genesis.atrad.adelaide.edu.au> from "Michael Smith" at May 15, 96 00:16:40 am

next in thread | previous in thread | raw e-mail | index | archive | help
Of all the gin joints in all the world, Michael Smith had to walk into 
mine and say:
 
> Bill Paul stands accused of saying:
> > 
> > Lately I've been experimenting with creating a three-sgate bootstrap
> > program. (No, I don't know why. It isn't as if I don't have enough to
> > do already.) Unfortunately, much as I expected, I've hit a wall.
> 
> That's OK; I've been thinking about this too 8)
> 
> > - There is a standalong program called /boot. This program should run
> >   in protected mode, but have the same ability to perform real mode
> >   BIOS operations as the existing second-stage bootstrap. I believe it
> 
> Hmm.  I'm not convinced that it should run in protected mode.  Why not run
> in real mode and avoid having to switch back and forth until the time comes
> to load the kernel?

Well, for a couple of reasons. First, generating real mode executables
is hard (we have assembly that starts off in real mode and changes to
protected mode now). Second, the kernel is loaded above 1MB, and you
have to be in protected mode to do that. The second stage bootstrap
accomplishes this by running in protected mode and then switching to
real mode to do BIOS stuff, which is in itself a third reason, namely
don't re-invent the wheel if you can avoid it. :)
 
> >   has to be limited to having at most 64K of text and data, though I
> >   may be mistaken about this. This is the program which will ultimately
> >   read the kernel image from the filesystem and run it.
> 
> The issue here is which compiler is used to generate the 'boot' program.
> If we stick with gcc (a wise idea), and use the same approach as the
> current second-stage bootstrap, then yes, I believe we're limited to 
> 64K in real mode.  If 'boot' were running in protected mode, we could go
> larger without any trouble.

Okay. No problem then.

> > - The /boot program is loaded by a second stage bootstrap, which is
> >   by design very dumb and limited in function. It has a compiled-in
> >   array of disk blocks which tell it where the the /boot program resides
> >   on disk. It also has a compiled-in value for the filesystem blocksize,
> >   and possibly some other magic values. In essence, this second stage
> 
> I think this hardcoding is a Very Bad Idea.

Well, SunOS has used this scheme successfully for a long time. I happen
to like the idea.

>  The code to find and read
> filesystems is already in the second-stage bootstrap, so it fits already.
> You should search all possible FreeBSD partitions, not just the first one.

But I don't want the code that groks the filesystem in the second
stage bootstrap. The second stage can't be made big enough to have any
fun, which is why we need the third stage. If we're making a third
stage anyway, then it should be the one with all the brains. Also,
ripping out as much non-essential code as possible leaves more room for
the block number array: the more block numbers you can cram in, the
larger a third stage bootstrap you can load.

The installboot program can patch in block numbers for /boot no matter
where it's located (well, unless it's past the 1024th cylinder, of
course). Also, I seem to recall people clamoring for a way to stamp disks 
in such a way as to be able to relate the DOS/BIOS drive ID to FreeBSD's 
notion of drive IDs (controller/unit). You could use installboot to patch 
this info into the bootstrap.

Yes you have to change it if you change your machine configuration.
Well, hey: life is tough.

> Alternatively, put the block information in the first part of the 'boot'
> program.  If you were to use the first 512 bytes, and allow 32 bits per
> physical block, you could map a 64K file.  This means that any bootstrap
> can use the boot program, not just one written to explicitly know where
> it is.  (Think using a second-stage bootstrap off a floppy).

In my current prototype, I have an array of 768 unsigned ints reserved
for block numbers. With a blocksize of 4K, this allows me to reference
something like 3 MB of data, which is more than you could fit on a
floppy anyway. With an 8K blocksize (the default for disk partitions)
this goes up to 6 MB.

> >   need any code to grok a UFS filesystem; it doesn't need any keyboard or 
> >   serial port I/O code since it doesn't have to interact with the user.
> 
> It should be able to report on its progress searching for a 'boot' program.

I plan to leave the 'twiddle' function in so that you can see it
trying to load sectors. The only errors it can signal are disk read
failures: remember that it isn't searching for anything -- it knows
exactly where /boot is.
 
> > to load it. Also, by patching values into the bootstrap, we can save
> > other information, such as the proper disk geometry of the boot drive,
> > or anything else that it would be useful to save. The one restriction
> > here is that /boot must remain where it is. If it is moved, the installboot
> > program must be run again in order to install a new second stage boot
> > with a new set of physical block numbers.
> 
> Better still, never mind about all these other parameters.  Because 'boot'
> is using the BIOS and is much larger, it can nut these out itself.  It
> can also read and maybe write UFS filesystems, so it can maintain a 
> seperate configuration file.  

No. We're trudging ever closer to '/etc/system' as it is now. I'm not
going to contribute to such an abomination if I can help it. Installboot
should have access to all sorts of information about the disk configuration,
and it takes a trivial amount of effort to just jam it into the executable.

> Obviously then we move userconfig() into 'boot', and have it be able to
> read configurations out of kernels.

Argh. No. Please. One catastrophe at a time, okay? Next you'll be telling
me to add devfs support to it, and then I'll be forced to shoot you.
 
> > - The standalone image obviously needs some sort of assembly language
> >   startup routine, only I'm not adept enough at 386 protected-mode
> >   assembly language to write it myself. (What would really help is if
> >   we had some sort of 'libsa' standalone library. 4.4BSD-Lite had one
> >   for the i386 architecture, but it relied on special protected-mode
> >   drivers. It would be terrific if we had one that used the BIOS
> >   instead.)
> 
> Stick to real mode.  Calling the BIOS out of real mode is Relatively Easy.

But generating real mode code is Relatively Hard. At least with our
existing compiler tools.

Again, we already have the bits that do this. I'm trying to pull this
off using existing tools rather than rewriting everything from scratch.

> In real mode, about all you'll have to do is setup ds and ss.

See, now you're already over my head. :)

> If
> you're determined to do the protected-mode thing, have a look at how 
> the DJGPP stuff works.  (The go32 DOS extender etc.)  Note that this is
> serious overkill for this application. 8)

Yeah, no kidding.
 
> > - Assuming I had a startup routine (and the right code to do the real-mode
> >   BIOS operations), how exactly do I link the image?
> >
> > 	o Should it be a ZMAGIC binary like the kernel? Or should it
> >           be OMAGIC like the existing bootstrap?
> 
> It probably wants to be PIC or possibly loaded somewhere lowish like
> 2000:0.  You'll want to consider whether 'boot' will be loaded by the
> 'fbsdboot.exe' program, or whether 'boot's functionality will be 
> incorporated into it.  Also consider those that use the Linix 'lilo'
> tool.

PIC? Hm... the existing bootstrap isn't compiled PIC. That would
imply runtime relocation hackery, no?

To have it loaded by fbsdboot.exe, it would have to be similar to a
stripped down kernel. This is not a bad idea, but again I haven't
the slightest idea how to do it.

As for LILO, if I'm not mistaken, it should continue to work, since
I think it just loads the primary bootstrap anyway. From there, LILO
is out of the picture.

> > - How do I hand off control to the standalone image from the second
> >   stage bootstrap? Can I use the same startprog() routine that the
> >   existing bootstrap uses to kick off the kernel? If not, what do I
> >   use instead?
> 
> If it's in real mode, you just do a far jump to it.  You'll need to work
> out who's responsible for ss and ds, and get this clear with the compiler
> too.

But it isn't going to be in real mode.
 
> > Basically, this is deep magic, and I'm not yet a clever enough magician
> > to make it all work. I _want_ to learn how to do this, but I'm not making
> > much progress. If anyone can shed some light on this subject, either
> > by pointing me at some in-depth documentation (that preferably doesn't
> > need to be viewed with a stinking web browser) or answering some of the 
> > above questions, I'd greatly appreciate it.
> 
> Hmm.  I'm not all that much of a magician either 8(  If any of the above is
> helpful, great!  There are lots of wonderful things that could be done 
> with such an approach.

To quote Marge Simpson: "Hrrmmmmmmmmmmm."

-Bill

-- 
=============================================================================
-Bill Paul            (212) 854-6020 | System Manager
Work:         wpaul@ctr.columbia.edu | Center for Telecommunications Research
Home:  wpaul@skynet.ctr.columbia.edu | Columbia University, New York City
=============================================================================
License error: The license for this .sig file has expired. You must obtain
a new license key before any more witty phrases will appear in this space.
=============================================================================



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199605141608.MAA02641>