Embedded NetBSD Part 2 : A single file unix.

Overview

In the previous article (here), I discussed a technique for creating a bootable NetBSD system, where one floppy contained the kernel and another contained the filesystem. In this article, I will outline the process for creating a NetBSD kernel with a filesystem embedded in the kernel image. This image can then be booted at the boot prompt.

Creating a system wrapped up in one file is a simple way to get started with embedded devices. If you only have one machine at your disposal, you can simply build the embedded system, copy the image to your root directory, and reboot into the new image. When you are done testing, reboot and you are back to your development NetBSD machine.

If you have a second machine at your disposal, and it supports booting over the network, you could place the image on a TFTP server, and have the network adapter boot over the network. This way you don't have to reboot back and forth between your development machine and your test machine. This is the method I like to use.

This simplicity comes with a cost. If you want to make changes to the system, you need to rebuild the image and then reboot the system. One way around this is to have your system mount the filesystem via the Network Filesystem (NFS). This is a bit more complicated and involves setting up a NFS server. However, it allows your to modify the filesystem on the fly and you may be able to simply restart the affected task instead of the whole system. I'll cover this as well.

Building the kernel
You start my modifying a kernel image. The easiest thing to begin with is to get the GENERIC kernel configuration and make the nessecary changes. Basically, you need to enable the memory drive and set aside the space for it. The space is specified as the number of 512 byte blocks. You can force the memory drive to be the root and configure how much space is writeable.
# Enable the hooks used for initializing the root memory-disk.
options 	MEMORY_DISK_HOOKS
options 	MEMORY_DISK_IS_ROOT	# force root on memory disk
options 	MEMORY_DISK_SERVER=0	# no userspace memory disk support
options 	MEMORY_DISK_ROOT_SIZE=32768	# 16M 
#options 	MEMORY_DISK_ROOT_SIZE=8192	# 4M 
#options 	MEMORY_DISK_ROOT_SIZE=2880	# 1.44M, same as a floppy
The filesystem
Once the kernel is built, we can create the filesystem that will be embedded into it. To do this simply create a folder with your filesystem, create the root folders that are needed, and then populate it with the programs that you need. The mandatory files are sbin/init, bin/sh, and the files in /dev. Once the filesystem is populated, then you can bundle it into an image with the makefs command.
mkdir files
mkdir files/sbin
mkdir files/bin
mkdir files/dev
cp /sbin/init files/init
cp /bin/sh files/bin
cp /dev/MAKEDEV files/dev
cd files/DEV 
./MAKEDEV ramdisk
cd ../..
makefs -s 4m -t ffs memdrive.image directory
Putting it all together
Once you have the image, you can embed it into the kernel with the mdsetimage command. Then compress the kernel and place it where you can boot it and give it a whirl.
mdsetimage netbsd memdrive.image
 gzip -c netbsd > netbsd.test.gz

When you boot up, it will start up in single user mode and prompt you for the shell like this...

Enter pathname of shell or RETURN for sh: 
You can eliminate this behavior by rebuilding init with SMALLPROG defined. Although the SMALLPROG version is a little larger, it won't prompt you for the shell and will instead load /bin/sh. If you want to use a different shell, you could simply copy the other shell into /bin/sh or you could redefine the _PATH_BSHELL constant.
#ifdef _PATH_BSHELL
#undef _PATH_BSHELL
#define _PATH_BSHELL "/bin/bash"
#endif
cd /usr/src/sbin/init
make -D SMALLPROG





Contact

Emailbox