PXE boot an XIP image?

Don whY Don.whY at gmx.com
Sat Jun 13 19:28:25 UTC 2015


On 6/13/2015 6:10 AM, Julian Elischer wrote:
> On 6/13/15 6:34 PM, Don whY wrote:
>
>> I'd like to PXE boot a kernel then fetch (any choice of protocol)
>> a *single* image to load into RAM thereafter not requiring any
>> access to external media to operate.  I.e., as if the image
>> had resided in the device all along.
>
> what do you mean by "single"? any PXE boot is by definition a number of
> transactions.

Load kernel, load *an* executable, CUT NETWORK CORD.  Thereafter, behave
as if the device was operating from built-in FLASH.

> The regular PXE boot code from FreeBSD is capable of loading a kernel and a
> matching ram filesystem, which when executed, will boot up as a running
> system and not touch any medium. I haven't done it for a while but at
> one stage there used to be a suitable memory filesystem on one fo the boot media.
> (that may no longer be true)

A memory filesystem is not the same as XIP.  You'd have *two* copies of
anything that is executing in RAM at any given time:  the one stored
in the filesystem and the one that is executing in process memory.

I want to omit the "filesystem" aspect.  E.g., load *everything*
into process memory so the remaining "RAM" is available for use
*by* those processes.  Then, shrink the amount of RAM installed
(think "appliance" -- hence the -embedded reference in my OP)
to just that which is required to store the RUNNING code and
it's data requirements.

> you can also boot a completely NFS system as well, and that will not touch
> media either.

It touches the remote NFS mount ("external media").  I.e., once "loaded",
the network should be not required for fetching other binaries.  "Cut
network cord".

> Finally, if having the network boot loader load TWO modules (kernel and FS) is
> too much,
> you could make a kernel that has the filesystem statically linked into it.
> But that's more work.

I'm looking for a step beyond that:  have a "process image"
loaded directly alongside the kernel.

>> A crude approach *might* be something like crunchgen'ing init
>> with all of the (static linked) binaries that are required
>> and letting the loaded kernel NFS read (load) that init(1).
>> Obviously, I'd trim the kernel and other binaries down to the
>> bare essentials to minimize RAM requirements (as there would be no
>> swap, etc.)
>>
>> [I.e., creating a tiny filesystem that simply links every executable
>> back to this *one* image]
>>
>> In practice, this won't (?) really work as hoped.  Any pointers on
>> a proven technique to achieve these results?
> I don't know why that wouldn't work, but what you put in your memory filesystem
> is up to you.

The point is to get rid of the "memory filesystem".

E.g., load kernel.  Let kernel read init(1) via an NFS mount.
Now, init resides in "process memory" -- we haven't built a
filesystem with anything *in* it!  Then, "cut network cord".

I.e., as long as init doesn't exit, it remains in process
memory.  As init was crunchgen'd with all the other binaries,
*they* also remain in memory.

The fluke is requiring a nominal filesystem simply to point to
the "other" entry points in that crunchgen'd image -- yet NOT
require a second instance of it (i.e., init) to be loaded
when one of those other entry points is invoked.

E.g., imagine you use some set of "commands".  Together, they
create a crunchgen'd image that is ~1MB (arbitrary number chosen solely
for discussion).  Assume there are 200 of them (another arbitrary
number).  One of those components is "init".

Kernel loads init (via NFS) and, with it, come ALL of these commands.

You then invoke *all* of those commands, simultaneously.  Each,
of course, has some process-specific state.  The goal is to
only require 1MB of RAM (in addition to the kernel), *plus* that
per-process state.  Regardless of how many "commands" (processes)
are running from that ONE crunchgen'd "init".

The lower limit in the presence of an external store (for the
individual, non-crunchgen'd executables) would be the sum of
all their text segments and data segments.  There would be
some overlap in those text segments due to common library uses.
And, some heap-related costs (ideally, tailored to each executable).

Get to *this* point while eliminating the "external store"
(i.e., allowing only "ONE" access to it at boot) -- without keeping
a copy of that external store in a "memory filesystem".

> You dont say what your limits are.   How much RAM is on the machine?

Again, think appliance.  I have lots of machines to play with that include
gobs of RAM.  What I want is to trim that RAM requirement down to an
affordable bill of materials, power budget, etc.  Having a copy of
the executables appear *twice* is just wasteful:  "here's a copy that
I use to load the *working* copy..."

> All this is documented on many blogs, man pages, etc. so spend a while on
> google and you should be able to patch it together.

What's missing is how to do this without having a filesystem (duplicate
copy of executables) on the target device!

FOR EXAMPLE, look at the resources present in standalone X Terminals.
Count the bytes of (EP)ROM.  Count the bytes of RAM.  How would you approach
that level of resource utilization with the existing codebase?

I can easily elide portions of the kernel that aren't important to that
particular functionality (in this example, an X Terminal).  And, I can
omit all the executables that aren't pertinent to "the implementation of
an X Terminal".  But, the UN*X model doesn't easily lend itself to
"load a composite image into memory and start the processes represented
*in* that image" -- while the OS in an X Terminal can do this easily
(because it was designed with that XIP capability).

> remember:
> the bootblocks/loader used for Regular PXE booting can load using NFS or tftp.
> teh loader can link a file with the kernel that is just a filesystem image..
> (I forget the exact 'type' is needs to use.. I'm sure the man pages would have it)
> teh filesystem image is just that.. you make it bu making a memory based drive,
> and formatting and filling it just as you would a regular drive.
>
> We DID at one stage have the ability to have the filesystem loaded be compressed.
> (in fact at one stag the kernel could also be compressed. I presume we cna stil
> do that
> but as I said, I haven't done this for some time.
>
> finally you can load the filesystem image and kernel from GRUB too, so if you
> get the net lodaing capable version of grub going you should be able to do
> exactly the same thing. it's just a case of giving the right 'type' and name
> for the image, and giving the right "mountfrom" value (ufs:md0 would be an
> expected value for example).



More information about the freebsd-hackers mailing list