A Virtual Linux Environment on a Windows System
Imagine this: a flexible embedded Linux development environment
running under Windows.Now it's a reality. David created a virtual
Linux environment on a Windows system usingcoLinux. This is your
platform for embedded cross development.
The development environment for my first system consisted of LEDs
and switches. Today, embedded developers expect capable tools for
the systems they work with.
Embedded systems are getting smaller,more powerful, cheaper, and
faster. They are becoming a more ubiquitous part of everyday life.
They exist in single-purpose devices manufactured in the
millions,where fractions of a cent are critical to success. And
they are increasingly appearing in larger and more complex products
with tight schedules where time to market is more critical.
High-end embedded systems with orders of magnitude more resources
and performance than the Heathkit H8 personal computer I started
with in college are a natural fit for Linux. Incorporating Linux as
part of an embedded project creates new demands and compels
embedded developers to broaden their skills. Embedded Linux
projects still require talented developers who work in the dark
region between hardware and software that intimidates applications
developers used to the world of Visual Basic, Java, and .NET. But
it increases the requirements for familiarity and sometimes
intimacy with general-purpose operating systems and applications
development. Linux has established a commanding place in the field
of embedded systems. There is a presumption that the developer will
be running Linux and is familiar with Linux development tools and
commands. But for the majority of embedded developers,this is not
true.
I have been fortunate. My experiences have taken me into virtually
every facet of software development from writing payroll systems to
disk controllers and programming PALs through web applications. I
have been working with Linux and open-source for most of a decade.
I returned to embedded development in the past few years. Like most
software developers, I live primarily in a Windows world. I port
Linux to embedded systems. I use Linux file, mail, and web servers.
But my primary development system is a laptop running Windows XP.
Embedded products from Pico Computing,which constitute most of my
work today, run Linux, GreenHills Software,μCosII, and often no OS.
Pico provides development environments for Linux,OpenBSD, and
Windows. But the overwhelming majority of clients use Windows. This
creates unique challenges,such as how to effectively perform
embedded Linux development in a Windows environment.
Whatever the merits of Linux over Windows, requiring Windows
developers to become Linux experts is a hard road. This article
reflects my efforts to synthesize from existing resources a
friendly,powerful, flexible, and extensible embedded Linux
development environment for embedded engineers running Windows.
DEVELOPMENT TOOLS
There are two major facets to this:the general tools for embedded
Linux software development and providing a friendly means for using
them from Windows. This article focuses on installing coLinux-a
light-weight real version of Linux that runs as a process under
Windows. Much of the task of setting up coLinux is nearly the same
as setting up Linux on an embedded device. Editing colinux.conf and
running the Windows installer is unique,but most every other task
builds knowledge and skills that will be needed to set up an
embedded Linux device.
The tools for embedded Linux development are primarily Unix/Linux
tools. To use them, you need a Unix/Linux-like environment. There
are numerous choices. An option under Windows is Microsoft Services
for Unix (SFU)。 SFU is available as a free download and includes a
fairly complete set of Unix/Linux development tools and resources.
A second option is Cygwin, as well as permutations such as Xilinx
xygwin. Cygwin attempts to map the Unix/Linux system to Windows
through a .dll that translates Unix/Linux systems calls to Windows
equivalents with a fairly high degree of conformance to the
expectations of Unix/Linux programs. A significant percentage of
open-source software,including embedded development tools, have
been "ported" to Cygwin. From the perspective of software built for
Cygwin, Windows/Cygwin is just another *nix.
A third option is Mingw32, which is very similar to Cygwin, except
it builds native Windows applications without a dependence on an
external Unix/Windows .dll. Mingw32 is better described as a
Windows port of the GNU compiler collection. There is a lot of
overlap between Mingw32 and Cygwin, but they have differing goals
and approaches.
SFU, Cygwin, and, to a lesser extent, MingW32 are all attempts to
make Windows look like Linux. It is possible to perform almost
every embedded Linux development task,including the particularly
challenging task of building a Linux kernel under Cygwin. The
primary difficulty of developing under these involves learning a
large set of workarounds unique to trying to develop for Linux
under Windows. Numerous frequently used *nix features-such as
case-sensitive file systems, incredibly long path lengths, and hard
and symbolic links that are poorly supported-work differently or do
not work at all under Windows. Acquiring proficiency with these
workarounds does not contribute to knowledge of either Windows or
Linux.
The next major class of alternatives is to actually run Linux. You
have several alternatives for accomplishing this. You can run a
Linux server/workstation for software development on another
computer and work remotely using a tool such as Putty/SSH,
XWindows, or VNC. This is the primary way that I perform embedded
Linux software development. The downside is that it requires two
machines, and more understanding of Linux.
Another alternative is using virtualization to run Linux on the
same machine as Windows. Microsoft Virtual PC, XEN, and VMWare are
notable examples of hardware virtualization. There are numerous
strong points for hardware virtualization solutions; however,they
add a significant additional layer of complexity. They also require
a deeper understanding of Linux and knowledge of the virtualization
software. They also make significant resource demands on the host
hardware. If there are independent reasons for developing
proficiency with hardware virtualization,this may be a good choice.
A less explored alternative is operating system virtualization.
Open-source projects such as User Mode Linux, Linux VServers, Open-
VZ, and Virtuozzo lay a foundation for running Linux under Linux
with near zero additional overhead. The coLinux project, which
borrows heavily from these, implements Linux as a process running
under Windows.
WHY coLinux?Please note that coLinux is an active open-source project. I
deliberately used a development version for this article. Numerous
advances have occurred recently and many fixes and features have
been added. Everything within this article should work as described
with the suggested downloads. However, I encourage you to use more
current versions despite minor discrepancies with this article.
Unlike Cygwin, SFU, and others,coLinux runs a real version of Linux
concurrently as a process under Windows. To Windows, coLinux looks
exactly like any other Windows program. Because coLinux is real
Linux(it uses a small collection of custom Linux-to-Windows device
drivers to provide Linux with access to Windows resources), it does
not suffer from any of the problems inherent to emulators. Like
hardware virtualization solutions, there are two operating systems
running concurrently on the same hardware. Unlike hardware
virtualizers, there is minimal impact on the host OS. The
installation of coLinux is much like the installation of any other
Windows program. The end result is Linux running as a process on a
Windows system. I keep a copy of coLinux installed on my Windows
workstation. Whenever I need to travel, I copy my current Linux
work from the Linux workstation I normally use for embedded
development and continue exactly as I was before. There are some
limitations,caveats, and idiosyncrasies of coLinux, but overall, it
is still the easiest, fastest, and friendliest way to get a Linux
development environment on a Windows machine. It is also an
excellent way for an embedded developer to become familiar with
Linux without demanding immediate proficiency with Linux, or
virtualization, or the idiosyncrasies of a simulated development
environment. coLinux has the added appeal that for an embedded
Linux developer it is not much different from an embedded system
running Linux inside their Windows machine.
GETTING STARTED
The first step in my approach to embedded Linux development under
Windows is installing coLinux. The coLinux project is hosted by
Source- Forge (www.colinux.org)。 You can download the current
coLinux installer. (When I wrote this article, it was
colinux-0.7.1-20070101.exe.) This is run like almost any Windows
installer (see Photo 1)。

Expanding the coLinux tab shows a number of options that are
enabled by default. TAP-WIN32, SLiRP, and WinPcap are all
networking options. Although not mutually exclusive,you need only
one (see Photo 2)。I prefer WinPcap bridged networking because it is
the easiest to set up and getting the coLinux network working is
usually the most difficult aspect of installing coLinux. Also,
WinPcap is an essential component of Ethereal,WireShark, and many
other Ethernet sniffers, which many embedded developers may already
have installed. WinPcap can be found at www.winpcap.org. The Linux
consoles,virtual serial device, and debugging are not essential.

However, at least one Linux console is typically needed to set up
networking. The typical impression of a file system is as structure
implementing files and directories on top of the sectors on a hard
disk. But there is no reason why a file system can not exist inside
any type of storage (e.g., RAM,ROM, flash memory, or even a file on
another file system)。 Neither Linux nor Windows require the file
system to be stored directly to a hard disk. In Linux in
particular, most file systems are independent of a specific type of
store. In Windows, there are many tools like WinImage or various CD
burning tools that store disk images as files. coLinux takes
advantage of this and implements virtual disk drives as files under
Windows.
Unless you are extremely ambitious(and intend to build your own
Linux environment) or you already have an existing coLinux root
file system, you will want to download a root file system(see Photo
3)。 You may choose from any of the listed Linux distributions for
the root file system. Each has its advantages. Debian is extremely
common among embedded developers,and it is my distribution of
choice and the basis of many other popular distributions such as
Ubuntu and Linspire. However, I recommend selecting"none" and
separately downloading Debian-20040605.ext3.1610mb.bz2.

Linux distributions tend to differ substantially less than
different releases of Windows, so moving from one to another is
fairly easy. The choice of distribution affects the installation
more than the operation of Linux. The coLinux root file system
images are preinstalled Linux images, substantially eliminating
installation differences. The remainder of this article will use
the Debian root file system image. Recent versions of coLinux use
either command-line options or a text-configuration file to specify
coLinux options.
By convention, Linux devices with names starting with "co" are
coLinux devices to access Windows resources. cobd# is coLinux block
device #. These are Linux block devices that access Windows files
as Linux disk images. cobd0 is normally the block device
corresponding to the Linux root file system (the rough Windows
equivalent of drive c:)。 Other block devices are used to access
other virtual file systems or a swap file (much like pagefile.sys)。
If you downloaded the Debian root file system image, you need to
decompress it and rename it root_fs:
bunzip2 Debian-20040605.ext3. 1610mb.bz2.
bzip2/bunzip2 for Windows are available at www.bzip.org/downloads.
html or as part of the GNUwin32 tools for Windows (http://gnuwin32.
sourceforge.net), which will make moving back and forth from Linux
to Windows less painful. A collection of different sized coLinux
swap files is available at http://gniarf.nerim.net/ colinux/swap.
You can download the coLinux tools from the main coLinux site and
build any size yourself. The default Debian file system does not
have sufficient free space to build the cross-platform development
tools. It is possible to expand the file system, but the simplest
solution is to download and mount an empty file system for
additional workspace. A collection of empty coLinux file systems of
various sizes is at http://gniarf.nerim.net /colinux/fs. I
recommend at least 2 GB. Like the swap file, coLinux tools can be
used to build one to any size. If the empty file system is created
as a Windows sparse file, the actual size will only be the space
used. cofs# is a file system driver that maps Windows directory
trees to coLinux directory trees.
As an example, you can assign cofs1=c:\ and mount cofs1 as /windows
under coLinux and then access the whole Windows file system from
coLinux. This is extremely useful for trivially moving files
between Windows and coLinux. It also has many other uses. However,
Windows file system capabilities and attributes are a subset of
those of Linux. This is a fundamental reason why SFU and Cygwin can
not easily perform difficult Linux tasks, such as building a
kernel. Windows files accessed through cofs are constrained by the
same limitations. conet# maps Linux network device names to
coLinux/ Windows network resources.
The coLinux configuration file is where you map virtual disk
images,such as the root image downloaded by the installer to cobd#
devices,Windows paths to cofs# devices(optional), and Windows
network resources to conet# devices. A sample configuration is
provided. It is critical that cobd0 is configured for a valid root
file system image. Configuring a swap device is also important
because coLinux can not use virtual memory without one. Otherwise,
the defaults should work well enough to get started. Getting
network functionality is important because the Debian package
manager-kind of like Windows update on steroids-is extremely
difficult to use without Internet access. The additional steps
needed to configure WinPcap networking are creating an eth# entry
in the config file configuring eth# as pcap-bridge and assigning
eth# to a Windows network adapter and assigning it a MAC address.
The network adapter name is the name that is displayed in view
networks, and must match exactly. Alternately, you can start
coLinux from a DOS box and review the messages as it attempts to
match the adapter name(see Photo 4)。

The MAC address is 12 hexadecimal nibbles. It must be unique on
your network, and it must be a valid MAC address. It must not
contain all 0s or all fs and the first byte should be even. In
addition to establishing a connection through your normal wired
network adapter (WinPcap has difficulty with some wireless
adapters), I suggest installing the Microsoft Loopback driver and
creating a coLinux networked bridged connection through it. If you
set the address to 192.168.0.1, it will be accessible from coLinux
on the initial boot. Networking through the Loopback adapter will
allow coLinux-to- Windows connections even when a wired network is
unavailable-as in an airport lounge. It also allows you to use an
ssh client such as putty (www.chiark.
greenend.org.uk/~sgtatham/putty) rather than either colinux console
(http://geod soft.com/howto/ssh/putty.htm) (see Photo 5)。

A minimal colinux.conf file would be:
kernel=vmlinux
root=/dev/cobd0
initrd=initrd.gz
cobd0=root_fs
cobd1=homefs
cobd3=swap
cofs1=c:\
eth0=pcap-bridge,"Microsoft
LoopBack",12:48:de:ad:be:af
Additional help is available on the coLinux wiki
(http://colinux.wikia.com /wiki/Network#WinPcap)。 After creating a
coLinux config file, you can start coLinux from the command line:
colinuxdaemon. exe @colinux.conf. This should boot coLinux and
start the coLinux console. Log in as root with a password of root.
"passwd" is the command to change passwords. "man passwd" provides
detailed help, but the prompts should be sufficient. After the root
password has been changed, you should be able to putty to coLinux
at 192.168.0.40 or putty to coLinux if you add 192.168.0.40 coLinux
to c:\windows\ system32\drivers\etc\hosts. That has the side effect
of making putty connections faster. Once you have a single putty
connection working, you can open multiple concurrent putty
connections and dispense with the coLinux consoles altogether.
Putty provides a much more capable terminal. Further,you have the
basics of coLinux networking working, so adding other network
interfaces should be simple.
The next step is to configure coLinux as needed to reflect your
config file. Linux configuration is almost exclusively text-based.
Regardless of religious preferences for text editors, anyone using
Linux/Unix should have minimal competence with vi. It is
ubiquitous. Like it or not, it will always be there, and it is
substantially more capable than Notepad or Edlin. Many other Linux
programs have vilike commands. For a minimal Vi in a Nutshell,
refer to www.petefreitag.com /item/504.cfm. Vim is the most popular
vi variant and has a following that includes Jim Allchin at
Microsoft.
The Linux equivalent of the Windows registry is the /etc directory
tree of text files. Any cofs# or cobd# entries in your config file
probably should have corresponding entries in the Linux /etc/fstab.
Aside from the root and swap partitions, this is optional, but it
is convenient and easier to set up /etc/fstab than to manually
mount file systems. Linux does not have a concept of drive letters.
There is always a root file system, which always starts at "/." If
you are constantly moving between Windows and Linux, be prepared to
be constantly typing the wrong directory separator. You may
eventually note that the "/"
is supported under Windows in many instances-but not from a command
prompt. To access files that are not on the root file system, you
must mount them to a mount point-any empty directory of the root
file system. Many ubiquitous Linux/Unix features (such as mounting,
hard links, and symbolic links) exist in some form under
Windows,but most are infrequently used and tend to confuse a lot of
Windows applications. Another important Linux tool to learn early
is man. /etc/fstab controls what file systems are mounted on boot
(see Photo 6)。

Generally "#" in a Linux text file marks the start of a comment.
The /dev/cobd0 and proc entries or an equivalent must have been
present to boot coLinux. The /dev/cobd3 entry mounts the swap file.
The sys entry is optional. The /dev/cofs1 entry maps the Windows
file system to coLinux. In conjunction with the cofs1 entry in the
colinux.conf file maps,Linux references to /windows to Windows
accesses to c:\. You will also have to mkdir /windows to create the
/windows mount point. "man fstab"
will bring up the Linux man pages describing the structure of the
fstab file. The basic loopback network should already be working.
But network access beyond the Windows machine requires additional
changes to the colinx.conf as well as /etc/network/ interfaces
under coLinux. It is possible to configure the network by issuing
commands, but it is more convenient to edit /etc/network/interfaces
and permanently set the correct configuration. With few
exceptions,changes to a running Linux system do not require
rebooting. Linux zealots take great pride and quote multiyear
system uptimes. But Windows habits die hard, and unless you have a
compelling need to establish 1,000-day uptime scores, it is
frequently easier on the user to just reboot after a configuration
change than figure out exactly what (if anything) is needed to make
it take effect. The configuration of /etc/network/interfaces should
be understandable by inspection. If not from a command prompt, you
can type man interfaces and get more than you wanted to know about
interfaces. The Debian disk image does not have a dhcp client
installed yet, so eth1 needs to be set to a fixed IP temporarily by
adding something like /etc/network/interfaces (see Photo 7)。
Under Windows, you can find the gateway using ipconfig. It also may
be necessary to replace 127.0.0.1 with the IP address of your DNS
server in /etc/resolv.conf or disable the coLinux DNS server if you
have DNS problems. At this point, you should have coLinux installed
and configured and all the desired file systems automatically
mounting and network interfaces assigned and configured (see Photo
7)。

Set your hostname in /etc/hostname and /etc/hosts. You can now make
sure that your Linux install is completely up-to-date by executing:
swapon /dev/cobd3
apt-get update
apt-get install dhcp3-client
-o APT::Force-LoopBreak=true
apt is advanced package tool. It is the Debian equivalent of
Windows update on steroids. If you prefer a text/GUI tool, dselect
is a GUI wrapper arround apt. After you have installed a DHCP
client, the typical additions to /etc/network/interfaces for the
common DHCP client are:
auto eth1
iface th1 inet dhcp
/etc/resolv.conf should be managed by the DHCP client.
THE NEXT STEP
Using tools like apt is optional. It is quite possible to install,
build, and maintain Linux systems, including coLinux, entirely from
scratch with few tools beyond vi and GCC. Gentoo Linux, while
providing its own package manager, eschews binary packages and
builds everything from source. If you are interested in that degree
of knowledge and control, refer to www.linuxfrom scratch.org and
www.gentoo.org.
At this point, you should have a Linux environment running under
Windows, networked through Windows to the world. Next month, you
will create a platform for embedded cross development.
David Lynch (dhlii@dlasys.net) is a partner at Pico Computing
(www.pico computing.com), the owner of DLA Systems (www.dlasys.net)
software consulting, and an architect, with projects ranging from
automated warehouses to embedded OS ports. When he is not working
(playing)with computers, he is busy attempting to automate his home
and coerce his two children away from screens and into the outdoors
to help build their home.