Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Sep 1996 06:46:59 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        cvs-all@freefall.freebsd.org, CVS-committers@freefall.freebsd.org, cvs-sys@freefall.freebsd.org, julian@freefall.freebsd.org
Subject:   Re: cvs commit:  src/sys/i386/boot/biosboot Makefile boot.c boot2.S
Message-ID:  <199609042046.GAA16994@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>  Modified:    sys/i386/boot/biosboot  Makefile boot.c boot2.S
>  Log:
>  3 changes:
>  1/ Makefile:  the maximum size for boot2 is 7.5K not 7K,
>  so don't complain until it reaches THAT size..
>  newfs leaves 8K and boot 1 is 512k. leaving 7.5K becasue the disklabel
>  is considered to part of the boot2 file.

Wrong.  The limit is the size of a track on the boot media.  It's 18
sectors for 1440K floppies, 15 sectors for 1200K floppies, and 9 sectors
for 360K floppies (not supported).  start.S always loads LOADSZ = 15,
so a larger size currently won't even work on 1440K floppies.  To load
more, the i/o needs to be split up into track-size pieces.  This requires
knowing the track size.  The track size can be obtained using the BIOS
call in get_diskinfo(), unless the BIOS call fails...

>  3/ boot.c:
>  Move the parsing of the command line into the
>  place it's called for clarity.. alsoi comment it a bit and clean it
>  up a bit.. for some reason this seems ot have made it a little
>  larger, but I can't work out why.. maybe bruce might have ideas?
>  compensated for by shrinkage elsewhere..

getbootdev() was one of the few places in boot/*/* that was already
clean (except boothowto is poorly named).

I once tried inlining it too :-).  This made it larger so I didn't
commit it.  gcc turns out to generate fairly space-efficient code for
all the indirections (*howto) and extremely space-inefficient code
for changing the loadflags global directly.  (Space-inefficent code
is also time-inefficient unless the instruction fetcher can keep up.)

In the old generated code, howto is kept in a register and flags are
ORed directly to memory.  This takes only 3 bytes per OR for flags
<= 0x80 (using an 8 bit constant).  It should take only 3 bytes for
all (single) flags (using an 8 bit constant at an offset), but gcc
generates poor code for this case (it generates a 32 but constant
and 6 bytes per OR).  Also, the initialization of loadflags should
have been smaller:

	/*
	 * New code takes 10 bytes: 2 for the opcode, 4 for the target
	 * address, 4 for the source constant.
	 */
	loadflags = RB_SERIAL;
	/*
	 * Old code also takes 10 bytes for the same things, but should
	 * have used a 1 byte constant at an offset to save 3 bytes.
	 */
	loadflags |= RB_SERIAL;
	/*
	 * Even smaller code could be obtained by keeping a pointer to
	 * loadflags in a register and loading the pointer only once.
	 * The main point of the separate _extern_ function getbootdev()
	 * was to hide the fact that boothowto == &loadflags from gcc.
	 * If getbootdev() is changed to a static inline function and
	 * moved earlier so that it gets inlined, then gcc will notice
	 * that boothowto == &loadflags and generate space-inefficent
	 * code to access loadflags directly!
	 */

Compile with CFLAGS+= -Wa,-al to see the instruction sizes.

Bruce



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