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.
# 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
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
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