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>