The Wind River Linux Guest OS documentation provides step-by-step instructions to build a Linux image that is capable of booting on top of their hypervisor. If you follow the instructions you will end up with a Guest OS that uses a RAM disk for its file system. While this may be a desirable setup for embedded devices as they head to market, during the design/debugging phases it may be convenient to have a file system that doesn't lose all changes on every reboot.
To address this issue, let’s take a look at how we can use a USB thumb drive to hold the file system for our Guest OS. Setup is as follows:
- Intel Xeon 5500 Series Platform with Intel VT-x and VT-d Enabled
- Wind River Hypervisor 1.3
- Wind River Linux 4.1
- 16GB USB Flash Drive (A smaller drive will work, but the larger the better)
Since we are going to use a USB thumb drive to hold the file system for the Guest OS, we need to pass through the host USB controller to the Guest OS's Virtual Board (VB). The easiest way to do this is:
- Grab the pre-built system image provided by Wind River for your target
- Boot the target and drop to the hypervisor debug shell via serial port
- Prebuilt images are located in the hypervisor BSP directory, for example
<install_dir>/wrhv-1.3/bsp/x86_hanlan_creek_nehalem/obj_x86_hanlan_creek_nehalem/ as system.elf. Follow the instructions Booting an IA-32 Target from USB Storage in the Wind River Hypervisor Users Guide to get up and running quickly.
- When partitioning the USB drive I typically make the boot partition 512MB or less and use the remaining space on the drive for the file system. This way I only need 1 USB drive to boot the platform and serve as the file system for the Guest OS.
- Prebuilt images are located in the hypervisor BSP directory, for example
- At the hypervisor debug shell, issue a 'lspci -x' to get a print out of all the devices in the system. This is also good time to build/update your PhysicalBoard.xml for your target and identify the host USB controller(s) that needs to be passed through to the Virtual Board.
As you can see below, my platform has 4 USB controllers and I will pass all of them through to the VB:
wrhv> lspci -x
<Location Bus="0" Device="26" Function="0" /> <!-- Set Attribute WriteEnable="1" in the Guest Device -->
<RegSet Address="0x000020c0" Length="0x20"/>
<Location Bus="0" Device="26" Function="1" /> <!-- Set Attribute WriteEnable="1" in the Guest Device -->
<RegSet Address="0x000020a0" Length="0x20"/>
<Location Bus="0" Device="26" Function="2" /> <!-- Set Attribute WriteEnable="1" in the Guest Device -->
<RegSet Address="0x00002080" Length="0x20"/>
<Location Bus="0" Device="26" Function="7" /> <!-- Set Attribute WriteEnable="1" in the Guest Device -->
<RegSet Address="0xb1a21000" Length="0x400"/>
For a more detailed look at how to configure a device for passthrough to a Virtual Board, reference the Wind River Hypervisor Users Guide and also my previous blog post Device Passthrough with Wind River Hypervisor.
Assuming you have correctly configured the USB controller(s) for passthrough, now it is time to build your Guest OS image. The steps are very similar as those described in the Configuring and Building the Linux Guest OS section of the Wind River Linux Guest OS for Hypervisor Programmer's Guide, with a few small modifications.
Start by setting up the environment and configuring the project:
$ cd <install_dir>
$ ./wrenv.linux -p wrlinux-4
If you already have a workspace setup, change to that directory now. Or proceed with creating one...
$ mkdir workspace; mkdir workspace/wrlpp-gos-usbfs_prj
(abbreviation: Wind River Linux Platform Project – Guest OS – USB file system)
$ cd workspace/wrlpp-gos-usbfs_prj
$ $WIND_LINUX_CONFIGURE --enable-kernel=standard \
--enable-kernel=standard: Select the standard linux kernel.
--enable-board=intel_xeon_5520_ioh: The target board. For a list of available options, look in
--enable-rootfs=glibc_std: The file system type to use. The documentation often specifies glibc_small which produces a much smaller image but often at the cost of functionality. If you want a full featured shell for less headaches and ease of use, stay with glibc_std. This option is what may cause you to need a larger flash drive.
--with-layer=wrll-multicore,wrll-userspace/compiler,wrll-linux-2.6.34: wrll-multicore specifies this will be an image intended to run on top of the hypervisor, wrll-userspace/compiler and wrll-linux-2.6.34 are included for compiler support. If you don't need to compile anything, these may be left off to decrease the image size. Make sure to keep the wrll-multicore in either case.
Note: Depending on your version of Wind River Linux, you may need to change the 2.6.34 parameter to match
your kernel version.
--with-template=feature/mipc,feature/hyp,target/tools-extended: These are the recommended options. If you
removed the compiler support in the previous parameter, then you may also remove target/tools-extended.
Once the project is created, it's time to build:
$ make -j 16 all
Note: The -j 16 parameter should be adjusted to be equal to the number of cores in the system, or the number of cores that you would like to use to build packages in parallel.
Now it's time to prepare the USB drive with the file system. Use your favorite partitioning tool (I like gparted) to create and format an ext3 partition on the USB drive.
The 'make all' command will have produced a file system in tar.bz2 format, which we will now extract to the USB drive:
$ cd /media/wrlinux #This is the location where I mounted the drive
$ sudo tar xjf ~/workspace/wrlpp-gos-usbfs_prj/export/intel_xeon_5520_ioh-standard-glibc_std-dist.tar.bz2
Note: It is important to run the extraction with super user privileges, otherwise it will fail.
At this point your file system is ready to go, and we only require two small changes to the Guest OS XML file.
The BootLine parameter of the Guest might currently look something like this:
BootLine=”console=ttyS0,115200 rw root=/dev/ram ramdisk_size=32768”
This means we are using the ramdisk as the root file system, and we need to change that. This is where it gets tricky, and might require some trial and error. The root= parameter needs to point to the USB partition which holds the root file system, but it may not be completely obvious where that is going to be. One option is to boot the Guest OS (with the USB controllers passthrough and the USB drive plugged into the system) and look at the output as the kernel begins initializing devices. It should tell you where it placed the USB drive. In my case, it happened to be /dev/sdb2, so my new BootLine looks like this:
BootLine=”console=ttyS0,115200 rw root=/dev/sdb2 rootwait”
The addition of the rootwait parameter is extremely important! It tells the kernel to wait for /dev/sdb2 to become available, which happens sometime after the kernel begins looking for its root file system. Without this parameter, you will see a kernel panic early on in the Guest OS boot process.
You have now done all the necessary steps for building a Guest OS that uses a USB drive for its file system. Continue to provide the kernel image to the hypervisor project as you normally would.
If you built a 64-bit Linux Guest OS, then you need to provide ~/workspace/wrlpp-gos-usbfs_prj/build/linux-intel_xeon_5520_ioh-standard-build/arch/x86/boot/compressed/vmlinux to the hypervisor.
If you built a 32-bit Linux Guest OS, then you need to provide ~/workspace/wrlpp-gos-usbfs_prj/export/intel_xeon_5520_ioh-vmlinux-stripped-* to the hypervisor.
Failure to provide the correct kernel image will result in the Guest OS failing to boot.