Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 Apr 2009 23:34:22 -0700 (PDT)
From:      Travis Daygale <anti_spamsys@yahoo.com>
To:        David Naylor <naylor.b.david@gmail.com>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: compiling root filesystem into kernel (preferably tmpfs root filesystem)
Message-ID:  <104771.62272.qm@web37103.mail.mud.yahoo.com>

next in thread | raw e-mail | index | archive | help
David, thank you for the great information! =A0Yes, I would appreciate seei=
ng the scripts and hearing about the other method you outline. =A0
Yes, you understand what I want to achieve exactly.
I see what you're saying about not needing to put it in the kernel file, th=
ough for a variety of reasons, I do prefer a single file in the end.
And I did find this after posting (didn't see it on previous searches, thou=
gh I invested a lot of time looking before I posted):http://lists.freebsd.o=
rg/pipermail/freebsd-hackers/2006-November/018662.html
I have built a root image that I put in the kernel as described in the Nov =
2006 post. =A0My UFS root image consists of /sbin/init, where init is a sta=
tically compiled C program that just spits out "Hello world" and sleeps, th=
is binary runs fine under FBSD. =A0At this point, I have the kernel booting=
 but it panics because it says it can't find init.... =A0Hmmm... =A0I belie=
ve (haven't had time to test) that it is finding root? =A0Not sure though w=
hat loader args I might need to be providing? =A0Could it be a /dev issue (=
though I'm not needing sh, etc., since my init is not a real init)? =A0Stil=
l figuring this out.

Trever

--- On Sun, 4/5/09, David Naylor <naylor.b.david@gmail.com> wrote:

From: David Naylor <naylor.b.david@gmail.com>
Subject: Re: compiling root filesystem into kernel (preferably tmpfs root f=
ilesystem)
To: "Travis Daygale" <anti_spamsys@yahoo.com>
Cc: freebsd-hackers@freebsd.org
Date: Sunday, April 5, 2009, 1:14 PM

On Saturday 04 April 2009 21:52:14 Travis Daygale wrote:
> In both the loader and kernel compiling doc, I see snippets of informatio=
n
> like this: #Make space in the kernel for a root filesystem on a md
> device.options MD_ROOT_SIZE=3D10 boot_dfltrootInstructs the kernel to mou=
nt
> the statically compiled-in root file system.

Yes, you can compile a fs image into the kernel.=A0 This however will be st=
atic=20
and if you want editing then will need to use unionfs with mdmfs.=A0 tmpfs=
=20
cannot be used for this as it does not yet (to my knowledge) support unionf=
s.=A0=20

> My question is, how does one compile a root filesystem into the FreeBSD
> kernel? =A0

Personally I wouldn't recommend taking the approach you want to do.=A0 Ther=
e is=20
simply an easier way.=A0 Just load the fs image as a kernel module (sort of=
).=A0=20
You get the same effect with more flexibility.=A0 (I'll explain below).

> When mounted, I want this root filesystem to run entirely in=20
> memory with no other backing store (not even a readonly flash disc nor
> other backing media such as DVD/CD).=20

This is do-able.=A0 I've created a CD that ejects it self when loaded=20
completely.=A0 (I thought it was cool :-))

> The standard FreeBSD DVD install disc=20
> uses just such a root? =A0(Though seems to rely heavily on the rescue
> binaries being on a read only filesystem backed by the install DVD?)=20

Can't comment, haven't used the FreeBSD CD/DVD's for years (since 6.0)

> I'm=20
> still trying to reverse engineer how that was done, without much luck. Is
> there a place/documentation I should be finding? =A0PicoBSD, NanoBSD, NFS
> root diskless systems... all tantalizing close, but not the same thing
> (read only roots backed by media other than memory). The root filesystem
> I'm wanting would presumably be in some conceptual sense similar to
> initramfs in Linux land, if that helps explain what I'm trying to achieve=
.=A0=20

I'll give you a quick tutorial below (if you need further help please let m=
e=20
know).

> =A0In fact I have a Linux distribution which consists of a single giant
> kernel image and when boot, runs entirely in memory, the kernel in fact
> can't read filesystems other than tmpfs because no filesystems are compil=
ed
> in. =A0

I think you are getting some concepts confused here.=A0=20

> It appears all of this won't be possible in FreeBSD (looks like ufs is=20
> required) but it appears I can get close to this. Indeed, I'd love a way
> for the root filesystem in FreeBSD to be of type tmpfs, again similar to
> what is possible on the Linux side, though I'm much less concerned with t=
he
> type of filesystem (it just needs to be compiled into the FreeBSD kernel
> and needs to be a memory backed filesystem when it mounts, no other backi=
ng
> store). Thanks in advance!

Ok, onto my explanation: my understanding is that you want to have some typ=
e=20
of FreeBSD based system that is loaded completely into RAM.=A0 Once loaded =
(at=20
boot time) this system should have no reliance on any medium (other than=20
RAM).=A0 This system, once loaded, should behave the same as if it were bac=
ked=20
by a hard drive (except the statefullness after reboots).=A0 i.e. the=20
filesystem should be editable.=A0=20

This is of course very possible.=A0=20


STAGE 1: The filesystem

In order to have the system in memory one needs a delivery method.=A0 As=20
mentioned before this is achieved using a MD device.=A0=20

MD's can have three types of backing, a vnode (aka file, on a CD/DVD or har=
d=20
drive), or memory (purely in memory, AFAIK no swapping out) and swap (same =
as=20
memory except my get swapped out).=A0 Ignoring the subtle difference betwee=
n=20
memory and swap, swap is better.=A0 Technically the forth is preload but th=
is=20
is the same as memory but done by the loader.=A0 See md(4) for further deta=
ils.=A0=20

Now, MD just imitates a hard drive, one still needs the data to put there.=
=A0=20
Any filesystem will suite this purpose.=A0 My preference is UFS but ISO9660=
=20
works just as easily (other options are not so easy but still do-able).=A0=
=20

Now, to create the filesystem, just install your system into a folder.=A0 e=
.g.
# su -
# mkdir /tmp/world
# cd src; make world kernel distribution DESTDIR=3D/tmp/world
# cp /path/to/packages /tmp/world/tmp
# chroot /tmp/world sh -c 'cd=A0 /tmp ; pkg_add *'
# rm -rf /tmp/world/tmp/*
# cat > /tmp/world/etc/fstab < _EOF
proc=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /proc=A0 =A0 =A0 =A0 =A0=A0=A0p=
rocfs=A0 rw=A0 =A0 =A0 =A0 =A0 =A0 =A0 0=A0 =A0 =A0=A0=A00
tmpfs=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=A0=A0/tmp=A0 =A0 =A0 =A0 =A0 =A0 t=
mpfs=A0=A0=A0rw=A0 =A0 =A0 =A0 =A0 =A0 =A0 0=A0 =A0 =A0=A0=A00
_EOF
* Now, edit /tmp/world as you require to make it work as you want (the easi=
est=20
way is to create a Flash stick [as per my script], edit the system live and=
=20
then copy all changes across).=A0 *


STAGE 2: The filesystem image

*** For UFS ***
# makefs /tmp/world.ufs /tmp/world
# MDDEV=3D$(mdconfig -a -t vnode /tmp/world.ufs)
# tunefs -L ROOTFS /dev/$MDDEV
# mdconfig -d -u $MDDEV

*** For CD9660 ***
# mkisofs -quiet -sysid=20
FREEBSD -rock -untranslated-filenames -max-iso9660-filenames -iso-level=20
4 -volid DragonBSD -o $WORKDIR/DragonBSD.iso -volid=20
DragonBSD -o /tmp/world.iso /tmp/world

Now, since these images are often much larger then required I prefer to=20
compress them.=A0 This allows more programs to be added to the image and it=
=20
takes up less memory during runtime (not to mention faster load times).=A0=
=20
[I assume UFS option, do the appropriate for CD9660 option]

# mkuzip -s 8192 -o /tmp/world.uzip /tmp/world.ufs


STAGE 3: Loading the filesystem image

Now you have an image that can be loaded on boot, to do so add the followin=
g=20
to loader.conf
# cd /path/to/boot/system/image
# cat >> boot/loader.conf < _EOF
rootfs_load=3D"YES"
rootfs_type=3D"mfs_root"
rootfs_name=3D"/boot/world.uzip"
_EOF
# cp /tmp/world.uzip boot/

Now, to inform the system that you want it to boot off the memory system
# cat >> boot/loader.conf < _EOF
vfs.root.mountfrom=3D"ufs:/dev/ufs/ROOTFS"
_EOF


STAGE 4: Making the Live System editable
Now, to make the whole system editable (everything) is quite the challenge =
and=20
requires a change in the way the previous stages are done.=A0 The concept i=
s=20
simple though.=A0 First:

Because the filesystem was compressed (using mkuzip), it cannot be written =
to.=A0=20
If the system were not compressed and extra space was allocated to the UFS=
=20
image then it can be editable.=A0 Even the extra size at load time can be=
=20
compensated for (since loader supports compressed modules [both gzip and=20
bzip2] however you will be running the full image uncompressed in memory.=
=A0 It=20
is faster but much more expensive.=A0 Just to give you an idea, I have gott=
en a=20
700MB system to boot and run off a mini CD (210MB) and a system with 512MB =
of=20
RAM, using the compressed approach with everything editable :-).=A0=20

To do this approach requires some changes to stage 2.=A0 Basically, after=
=20
completing the approach for UFS image do the following
# EXTRA_SIZE=3D32
# SIZE=3D$(($(du -m /tmp/world.ufs) + EXTRA_SIZE))
# dd if=3D/dev/zero of=3D/tmp/world.ufs count=3D$SIZE bs=3D1m=A0 # NB, use =
zero to allow=20
for compression
# MDDEV=3D$(mdconfig -a -t vnode /tmp/world.ufs)
# newfs -L ROOTFS -o space /dev/$MDDEV
# mkdir /tmp/btstrp
# mount /dev/$MDDEV /tmp/btstrp
# (cd /tmp/world; tar -cf - .) | (cd /tmp/btstrp; tar -xf -)
# umount /tmp/btstrp
# mdconfig -d -u $MDDEV

Next, DO NOT compress the image with mkuzip, instead do:
# gzip -9 /tmp/world.ufs

This requires either geom_uzip loaded or compiled into the kernel.

and, instead of the first part of stage 3 do
# cd /path/to/boot/system/image
# cat >> boot/loader.conf < _EOF
rootfs_load=3D"YES"
rootfs_type=3D"mfs_root"
rootfs_name=3D"/boot/world.ufs"
_EOF
# cp /tmp/world.ufs.gz boot/

NOTE: this approach cannot be done using cd9660.

The second approach, the one I prefer requires a double boot image (one ins=
ide=20
the other), where the one acts as a boot strap, mdconfig and mount's the=20
embedded second image, creates a editable fs using mdmfs and unionfs it ove=
r=20
the second image.=A0=20

This is done through using
# cat >> boot/loader.conf < _EOF
init_script=3D"/chroot.sh"
init_chroot=3D"/base"

where /chroot.sh basically does:
mount -o ro /dev/$(mdconfig -a -t vnode -o readonly -f /world.uzip).uzip /b=
ase
mdmfs -s 32m md /tmp
mount -t unionfs -o noatime -o copymode=3Dtransparent /tmp/base

It would be very nice to add unionfs support to tmpfs but not yet :-(.=A0 T=
he=20
second approach I have not described fully, it is quite a bit more involved=
=20
than the first but has great benefits, memory wise.=A0 If you want more det=
ails=20
about this approach please let me know.=A0=20

I've created a set of scripts that are designed to create LiveCD/DVD/Flash =
of=20
FreeBSD.=A0 There are three cd9660 images that it produces:
1) CD backed live system (using compressed ufs image)
2) Memory backed live system (using compressed ufs image)
3) CD backed live system (no compression).
And one Flash memory based image:
1) Flash based memory (using compressed ufs image and perpetual state overl=
ay)=20
[similar to option 1 above except the changes are permanent).=A0=20

If you would like access to these scripts please let me know and I will gla=
dly=20
forward them to you.=A0 Also if you have any questions or want further=20
clarification please ask.=A0=20

Regards,

David

Disclaimer: The commands may be incorrect but the procedure has been tried =
and=20
tested.=A0=20
=0A=0A=0A      



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