FreeBSD on BochsThis article is a description of my efforts to build a minimal FreeBSD system from scratch and run it under the Bochs emulator. Inspired by "FreeBSD From Scratch" by Jens Schweikhardt, this article extends its ideas by using a file backed virtual disk, as the installation directory and harddisk image under Bochs. Note:The steps described in this article are based on my experiments on a FreeBSD-5.3-RELEASE system, and are generally applicable to all 5.X systems (-CURRENT and -STABLE). As for 4.X systems, you will have to use the vn(4) driver instead of md(4). Links, references and resources pertaining to this article have been listed at the end. IntroductionI have been using FreeBSD for about 2 years now, and as an os development enthusiast I consider it's code base to be very intriguing, but far from being easy to comprehend. I figured that it was much easier to understand the innards of FreeBSD by observing it "at work" and correlate it with the source code rather than perusing all of it. Hacking my existing desktop system was not feasible and since I cannot not afford the luxury of multiple computers for this purpose, the obvious solution was to use Bochs, the IA32 emulator (In simple terms, Bochs is a software program that emulates a computer, enabling you to run multiple operating systems inside another operating system). This article describes how I managed to run FreeBSD on Bochs, and is by no means an authoritative guide, but simply a narration of an amateur FreeBSD geek's weekend experiment. The basic idea of this experiment is to build and install FreeBSD from source into a virtual disk which can be used as a hard disk image under Bochs. So the whole process is essentially in two parts. First, create and initialize the virtual disk (partitions, file system etc), then build and install FreeBSD from source into it. The article assumes that you have some basic knowledge about FreeBSD and Unix commands in general. Some of the steps described require administrator privileges which may require you to use "su" (if you belong to the wheel group) or "sudo" if you are a sudoer. Pre-Requisites
WorkspaceSince this experiment is going to be fairly complex and eventually consist of quite a few files, it's best to create a directory exclusively for this purpose, rather than clutter it up with the rest of your documents. $ mkdir -p /my/home/vfbsd $ cd /my/home/vfbsd Bochs ConfigurationThe Bochs configuration file specifies the location of disk images, details of the emulation layer and its virtual peripheral components (see bochsrc(5)). You will need to create a bochs configuration file local to this project. Fire up an editor to create the file (say) bochs.rc and add the following lines to it - #### my bochs conf #### boot: disk megs: 32 romimage: file=/usr/local/share/bochs/BIOS-bochs-latest, address=0xf0000 vgaromimage: /usr/local/share/bochs/VGABIOS-lgpl-latest Note: The boot parameter specifies the boot device; megs, the amount of memory (in the virtual machine); romimage and vgaromimage point to the image files for virtual rom and vga rom respectively that come as part of the Bochs package and are installed usually in the directory as indicated above. Setup - Virtual Disk + FreeBSD From ScratchCreate a flat, 512MB hard disk image file (say) hd.image, using bximage(1) (an interactive program, part of the bochs package) - $ bximage Although it is possible to create and implement the steps for any size, beware that further descriptions are based on the fact that the disk image size is 512MB. After the program creates the image file, it will spit out details of the disk structure and a line (as shown below) to be added to bochs.rc - ata0-master: type=disk, path="hd.image", mode=flat, cylinders=1040, heads=16, spt=63Append that line to "bochs.rc". The rest of the setup process has been wrapped into a shell script. Download it into your workspace. Open it up and try to understand how it works. Its fairly commented. Set the options correctly and execute it. Note: You must be prepared to work with mergemaster(8). Although simple to use, it is advisable to read the manual. vfbsd_setup.sh
#!/bin/sh -x
#
# vfbsd_setup.sh - http://sig9.com/articles/freebsd-on-bochs
#
# Copyright (c) 2004, Vivek Mohan (http://sig9.com/)
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# !! This shell script file sets up the virtual FreeBSD system from
# !! scratch.
# !! Please set the options correctly.
SETUPDIR=`pwd`
#---------------------------------------------------------------------#
# Option Description
# ====== ===========
#
# HDIMAGE - The harddisk image
# SRCDIR - Location of the freebsd source tree
# KERNCONF - Kernel configuration file
# LABELTMP - The disk label temporary file
# FSTABTMP - The fstab temporary file
# MDUNUM - The memory disk unit number to use
# VDMNT - Mount point for virtual disk
# BUILDDEFINES - Definitions for make buildworld, installworld
#---------------------------------------------------------------------#
HDIMAGE="hd.image"
SRCDIR=/usr/src/
KERNCONF="GENERIC"
MDUNUM=4
LABELTMP="bsdlabel.tmp"
FSTABTMP="fstab.tmp"
VDMNT=${SETUPDIR}/mnt
TEMPROOT="/var/tmp/temproot.vfbsd"
BUILDDEFINES="-DNOCRYPT -DNOMAN -DNOPROFILE -DNOSECURE "\
"-DNOPROFILE -DNOGAMES -DNOINFO -DNOLIBC_R -DNO_FORTRAN "\
"-DNOCLEAN"
#---------------------------------------------------------------------#
# Before the virtual disk can be used, it needs to be sliced and
# partitioned the `BSD' way. This label file is temporarily written
# to ${LABELTMP} for use with bsdlabel(8). This is a prototype file
# which specificies the paritions. As the comments indicate, there are
# 5 partitions /, /var, /tmp, /usr and swap, with sizes indicated in
# the size column. For more details on label prototype files, see
# bsdlabel(8).
#---------------------------------------------------------------------#
cat > ${LABELTMP} << EOLABEL
#--------------------------------BSDLABEL-----------------------------#
8 partitions:
# size offset fstype [fsize bsize bps/cpg] #
# ==== ====== ====== ===================== #
a: 128M 0 4.2BSD # /
b: 20M * swap # swap
c: * * unused 0 0 #
e: 50M * 4.2BSD # /var
f: 50M * 4.2BSD # /tmp
g: * * 4.2BSD # /usr
#---------------------------------------------------------------------#
EOLABEL
cat > ${FSTABTMP} <<EOFSTAB
#--------------------------------FSTAB--------------------------------#
# Device Mountpoint FStype Options Dump Pass
# ========= ========== ====== ======= ==== ====
/dev/ad0a / ufs rw 0 0
/dev/ad0b none swap sw 0 0
/dev/ad0e /var ufs rw 0 2
/dev/ad0f /tmp ufs rw 0 2
/dev/ad0g /usr ufs rw 0 2
pros /proc procfs rw 0 0
#---------------------------------------------------------------------#
EOFSTAB
DESTDIR=${VDMNT}
MD=md${MDUNUM}
MD_SLICE=${MD}
MD_ROOT=${MD_SLICE}a
MD_VAR=${MD_SLICE}e
MD_TMP=${MD_SLICE}f
MD_USR=${MD_SLICE}g
MD_SWAP=${MD_SLICE}b
#---------------------------------------------------------------------#
# do_attach_vdisk() - This will attatch ${HDIMAGE} as a virtual memory
# disk - "/dev/${MD}", ready to be used almost like a hard disk. For
# more information on memory disks see md(4) and mdconfig(8).
#---------------------------------------------------------------------#
do_attach_vdisk() {
# attach virtual disk device
mdconfig -a -t vnode -f ${HDIMAGE} -u ${MDUNUM}
}
#---------------------------------------------------------------------#
# do_deatach_vdisk() - deataches virtual disk.
#---------------------------------------------------------------------#
do_detach_vdisk() {
# detach virtual disk device
mdconfig -d -u ${MDUNUM}
}
#---------------------------------------------------------------------#
# do_setup_vdisk() - configures and initializes virtual disk.
#---------------------------------------------------------------------#
do_setup_vdisk() {
# write labels + bootsector
bsdlabel -B -R /dev/${MD} ${LABELTMP}
# create filesystem
newfs /dev/${MD_ROOT}
newfs /dev/${MD_TMP}
newfs /dev/${MD_VAR}
newfs /dev/${MD_USR}
# enable softupdates
tunefs -n enable /dev/${MD_ROOT}
tunefs -n enable /dev/${MD_TMP}
tunefs -n enable /dev/${MD_VAR}
tunefs -n enable /dev/${MD_USR}
# create mount point for virtual disk device, and mount
mkdir -p ${VDMNT}
mount -o noatime /dev/${MD_ROOT} ${VDMNT}
# create mount points
mkdir -m 0755 -p ${VDMNT}/var
mkdir -m 0755 -p ${VDMNT}/tmp
mkdir -m 0755 -p ${VDMNT}/usr
# unmount and unload virtual disk device
umount /dev/${MD_ROOT}
}
#---------------------------------------------------------------------#
# do_build() - build world + kernel
#---------------------------------------------------------------------#
do_build() {
# make kernel and world
cd ${SRCDIR}
make buildkernel KERNCONF=${KERNCONF}
make buildworld ${BUILDDEFINES}
cd ${SETUPDIR}
}
#---------------------------------------------------------------------#
# do_install() - install world + kernel
#---------------------------------------------------------------------#
do_install() {
# mount
mount -o noatime /dev/${MD_ROOT} ${VDMNT}
mount /dev/${MD_TMP} ${VDMNT}/tmp
mount /dev/${MD_VAR} ${VDMNT}/var
mount /dev/${MD_USR} ${VDMNT}/usr
# make distribution directories
cd ${SRCDIR}/etc
make distrib-dirs DESTDIR=${DESTDIR}
# run merge master
mkdir -p ${TEMPROOT}
mergemaster -i -m ${SRCDIR}/etc -t ${TEMPROOT} -D ${DESTDIR}
# install world
cd ${SRCDIR}
make installworld DESTDIR=${DESTDIR} ${BUILDDEFINES}
# copy system files
cp ${SETUPDIR}/${FSTABTMP} ${DESTDIR}/etc/fstab
cp /etc/localtime ${DESTDIR}/etc/localtime
cp ${SRCDIR}/sys/boot/forth/loader.conf ${DESTDIR}/boot/defaults
cp ${SRCDIR}/sys/i386/conf/GENERIC.hints ${DESTDIR}/boot/device.hints
# copied shamelessly from "FreeBSD From Scratch"
cd ${TEMPROOT}
find . -type f | sed 's,^\./,,' |
while read f; do
if test -r ${DESTDIR}/${f}; then
echo "${DESTDIR}/${f} already exists; not copied"
else
echo "Creating empty ${DESTDIR}/${f}"
cp -p ${f} ${DESTDIR}/${f}
fi
done
chflags -R 0 ${TEMPROOT}
rm -rf ${TEMPROOT}
# install kernel
cd ${SRCDIR}
make installkernel DESTDIR=${DESTDIR} KERNCONF=${KERNCONF}
# unmount and unload virtual disk device
umount /dev/${MD_TMP}
umount /dev/${MD_VAR}
umount /dev/${MD_USR}
umount /dev/${MD_ROOT}
}
#---------------------------------------------------------------------#
# do_clean_up() - clean up after setup
#---------------------------------------------------------------------#
do_clean_up() {
# remove temp files
rm -f ${FSTABTMP}
rm -f ${LABELTMP}
}
#---------------------------------------------------------------------#
# wrapper
#---------------------------------------------------------------------#
vfbsd_setup() {
do_attach_vdisk
do_setup_vdisk
do_build
do_install
do_clean_up
do_detach_vdisk
}
vfbsd_setup 2>&1 | tee vfbsd_setup.log
EmulateAssuming that you have successfuly completed all the above steps, you can proceed to run FreeBSD on Bochs right away - $ bochs -q -f bochs.rc If you see FreeBSD loading, congratulations. If not, post the problem as a comment here. This script has not been extensively tested on many different environments, so glitches can't be ruled out. Copying FilesOnce you start using FreeBSD on Bochs, you might want to transfer files to and from the disk image. To do this, you must attach the image as a virtual memory-disk and mount it as shown below - $ mdconfig -a -t vnode -f hd.image -u 4 $ mount /dev/md4 ./mntand then proceed to do copying or any other file operations. Once done, $ umount /dev/md4 $ mdconfig -d -u 4will unmount and detach the virtual disk. Links, Resources, References
I hope this was as much fun for you as it was for me.
Athlon XP 2000+, 256M etc. Th
Submitted by vivek on Sat, 2004-11-20 03:19.
Athlon XP 2000+, 256M etc. The performace is, ofcourse, poor compared to FreeBSD on real hardware; but good enough for playing around. I have used ee, vi with a few the daemons turned on.
|
TopicsRecent blog posts
|