[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: The lilo problem



On 2000-05-21 at 03:38 -0400, David Butts wrote:

> Thanks for the fast response.

Well, now you're getting a slower one!

> On Sat, 20 May 2000, Mike Bilow wrote:
> 
> > I think what you are missing is that the kernel you were using previously
> > was compressed in bzImage form, while your new kernel is not.  This is
> > Lilo behaving essentially as documented.  There would be effectively no
> > limitation on kernel size using bzImage, since this involves a multipart
> > loader (which is the whole point of bzImage).
> 
> I've poked around through the docs (both for lilo and the kernel source)
> and haven't found any explanation of what the bzImage does.  I had assumed
> that it just used bzip to compress the kernel instead of gzip, but that
> apparently isn't the case.  What exactly is the bzImage doing that allows
> a larger kernel image to be loaded, if it's the uncompressed size that
> matters?

>From <kernel-source>/Documentation/kbuild/commands.txt:

	Note: the difference between 'zImage' files and 'bzImage' files is
	that 'bzImage' uses a different layout and a different loading
	algorithm, and thus has a larger capacity.  Both files use gzip
	compression. The 'bz' in 'bzImage' stands for 'big zImage', not
	for 'bzip'!

If you are interested in the extremely gory details, look at bootsect.S
and setup.S in <kernel-source>/arch/i386/boot and see what happens when
"_BIG_KERNEL_" is defined.  Without getting into these details here, the
basic problem is that a zImage kernel assumes that it will be uncompressed
at 0x001000, which limits the kernel size because it must fit into
conventional memory accessible from real mode.  Remember the 640 KB limit
from DOS?  This is because of the memory hole from 0x0A0000 to 0x0FFFFF.

Fortunately, part of the original BIOS specification provided for a way to
access extended memory above the 1 MB boundary.  Since the CPU -- even a
Pentium III -- must switch into protected mode to do this, the BIOS must
do a protected mode switch in the course of its Int 15h handler.  Nearly
all machines are capable of this, so the Linux kernel can be built to
assume the kernel is uncompressed at the bottom of extended memory,
0x100000, which means that the only restriction on kernel size is that it
has to fit into the machine RAM size less 1 MB.  That is, if you boot a
bzImage kernel on a machine with 4 MB, then your kernel must have an
uncompressed size less than 3 MB -- well satisfied by any possible kernel.

The downside to the bzImage kernel is that some oddball machines either
did not implement the Int 15h protected mode BIOS interface or have
serious bugs, since DOS never used it for anything.  Such machines are
fairly rare, since all of the big name BIOS makers, including Phoenix and
Award, have been doing this properly at least since OS/2 became an issue
about ten years ago.  Machines which have a broken BIOS are usually
laptops, such as the Toshiba Tecra.  (OS/2 uses a different boot system
based upon the filesystem type.  If OS/2 is booting from FAT, then it does
something similar to Linux Loadlin/zImage.  If OS/2 is booting from HPFS,
then it does something closer to Linux Lilo/bzImage.)

Realizing that hardly any machines which are theoretically built for this
DOS architecture actually ever do run DOS -- and don't bother flaming me
about Windows 95/98 which has similar limitations -- some manufacuters
have been taking advantage of the high end of the 640 KB area to store
private BIOS information.  If you actually boot such a machine under DOS,
you would only have 639 KB (for example) of conventional memory.  This is
common in machines from certain manufacturers, particularly Compaq, and
also when certain features, such as SMP or hardware RAID controllers, are
present.  This special area is known as the "Extended BIOS Data Area," or
EBDA.  Lilo has always been configured to avoid trashing the EBDA, but
lately some machines, such as the IBM Netfinity servers, have been coming
through with large EBDA reserved areas.  This is hardly surprising, since
obviously no one buys the IBM Netfinity ServeRAID to run DOS.

In order to avoid trashing the new, larger EBDA, Lilo has a compile-time
switch now that simply reserves more space at the end of the conventional
memory arena when loading a zImage kernel that would be uncompressed into
conventional memory.  Since a bzImage kernel is not uncompressed into
conventional memory, the EBDA size is irrelevant to it.  However, Lilo
also cannot be permitted to trash the EBDA area as scratch space, such as
a disk buffer, or even a bzImage kernel will not boot.  So the protection
for large EBDA in the new Lilo is essentially a safety feature.

> > Also, even on a 16 MHz 386SX, kernel decompression time should be minimal.  
> > If you are doing an initrd load, however, this can be very slow since it
> > goes through ROM BIOS disk access calls rather than Linux.  Since I used a
> > 16 MHz 386SX when working on the SCSI stack in Linux back around v0.95, I
> > can assure you that decompressing the kernel on boot is a LOT less time
> > consuming than, say, recompiling the kernel on that platform.
> 
> This is true.  It took ~18 hours to compile the kernel and modules, but
> I figured that, since I was trying to keep the kernel small to save
> memory, I could get away with an uncompressed kernel and save a few
> seconds at boot (FWIW, it loads the image substantially faster than it
> decompresses it).  In retrospect, the fact that other architectures can
> get away with it wasn't applicable to lilo, but live and learn, right?

Other architectures have no brain-dead concepts of "conventional memory,"
"upper memory," "high memory," "extended memory," or "enhanced memory."  
Other architectures have no idiotic things such as memory holes nor
critical information stuck arbitrarily next to a memory hole.  Unless you
have a rare machine with a broken BIOS, always use bzImage for i386.

> Out of curiosity, how long has it been since a full kernel fit in 512Kb?

I really have no idea.  It's probably quite possible to build a modern
kernel to fit into 512 KB, especially if modules are used extensively.

-- Mike




Reply to: