Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 25 May 1996 00:00:14 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        freebsd-hackers@FreeBSD.org, wpaul@skynet.ctr.columbia.edu
Subject:   Re: three stage boot again
Message-ID:  <199605241400.AAA04777@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>- The program is an OMAGIC binary link edited for address 0. This
>  is necessary because of the real mode/protected mode switching
>  business. When in real mode, we execute at physical memory location
>  0x10000, but with a code segment descriptor that basically maps
>  0x10000 to 0x0. (So the program thinks it's executing at 0x0 but
>  really isn't.) In real mode, we're excuting at 0x1000:0, which again
>  makes the code think it's executing at 0x0. (And this is why we
>  can't make it larger than 64K, since that would cause the program
>  to extend into 0x2000:0, and all the offsets and addresses calculated
>  by the linker would no longer work.)

The 64K restriction could be avoided by linking the real mode parts
separately accessing them through call gates or software interrupts.

>- The program untimately runs at 0x10000, which is the same location
>  as the existing bootstrap (this was so that I could steal the
>  existing global descriptor table values until I understood them
>  well enough to change them). The program is actually loaded into
>  memory at a different location and copies itself to 0x10000.
>  (It could actually go somewhere else, like 0x20000. I'm saving
>  that for later.)

It would probably have been easier to understand it first :-).  You
can't just steal the existing GDT since it will be overwritten.  Extra
care is required to avoid using the old table before the new one is
installed.

>...

>- The existing bootstrap needs to be modified slightly to allow loading
>  of OMAGIC binaries. Currently, it expects to load ZMAGIC binaries,
>  which I think have their sections page aligned. To account for this,
>  the bootstrap skips a chunk of memory between loading the text and
>  data segments; this makes the bootstrap blow up when it tries to load
>  an OMAGIC binary. The code needs to be changed to check the magic
>  value of the binary and only skip the space for ZMAGIC binaries
>  instead of doing it unconditionally.

It should know nothing about binary formats.  It should simply load files
and jump to offset 0 in them.  There should be code at offset 0 that
understands the binary format.

>... Of course, progress was slow even with 
>these books since they don't use gas for their examples. (And will 
>somebody please tell me what the hell 'data32/addr32' mean?)

They are just macros that expand to the address and data operand size
prefix.  Gas doesn't support 16-bit code, so you have to fake it by
using these prefixes and related kludges.

>Now that that's done, there's still one more obstacle to overcome.
>When I went to link the new startup routine with the boot code for
>the first time, I ended up with an unresolved symbol called '_disklabel'.
>It turns out that this symbol is defined in start.S and looks like
>it's meant to just provide a pointer to a particular area of memory.
>I assume that this is supposed to contain the BSD disklabel for the
>disk from which the bootstrap was loaded, but I can't tell how it's
>supposed to know where it is. I also don't quite understand the
>following gas syntax

>ENTRY(disklabel)
>	. = EXT(boot1) + 400
	                 0x400

`.' is the program counter and assigning to it sets it.  The stage 1
bootstrap is known to fit in less than 1 sector or 0x200 bytes.  It
is actually padded to exactly 0x200 bytes.  The _disklabel label
follows the stage 1 boostrap so it is at offset 0x200 from the _boot1
label.  The above assignment to `.' reserves another disk sector's
worth of bytes for the label.

The label _for the boot disk_ is initialized by the stage 1 boot strap
copying the first LOADSZ (= 15) sectors off the disk into memory.  The
label follows the stage 1 bootstrap in memory as it does on the disk.
The above assignment to `.' arranges for the _disklabel label to
point to the initial label.

>... My problem is that the
>third stage will need this disklabel information. I'm not sure if I
>should somehow arrage to save this disklabel info and pass it to the
>third stage or if I should make the third stage read it over again.
>(It should be able to do it by itself, I suppose.)

The third stage can simply read the label into a C array.  So could the
second stage, but this might cost a few bytes of code and would cost
0x200 bytes of data.  The data cost isn't important since the data can
be in the bss.  Even the first stage bootstrap has an infinite amount of
data space (64K is infinite ;-).  Perhaps the cost in code is zero
(there has to be code to read labels off non-boot disk).  Anyway, the
assignment to `.', or perhaps simply `.space 0x200' has to be used to
leave space for the label, since there's a label in the way on the disk.

Bruce



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