Oracle Solaris HCL Portal

Feature Article

Adding Device Drivers to the New Boot Install Image in the Solaris 10 OS for x86 Platforms

James C. Liu and Brian Dowdy, June 2006

Contents:

Abstract: This engineering reference explains how to add new device driver binaries to an install image for the Solaris Operating System (OS) so that a system with a new device will be able to install and support this device during, and after, the installation process. This document is intended for systems administrators and developers with a working background in UNIX. The target operating system is the Solaris 10 01/06 release for x86 platforms (also known as Update 1) with the new boot architecture and also OpenSolaris (also known as Nevada). This how-to is not applicable to prior versions of the Solaris 10 OS for x86 platforms (GA release 03/05) or any versions of the Solaris OS for SPARC platforms.

Introduction

As more users have begun adopting the Solaris 10 OS for x86 and x64 platforms, there has also been an increase in driver development and testing. Some drivers can be added post-install usage by means of a floppy disk or USB mass storage device. This is true of most network drivers. If the system has an optical drive, you can install the Solaris OS first, then add the new driver later after the system bootstraps itself up.

However, as users have tried the Solaris OS on more systems, some with no optical drive or floppy or USB port, or systems that have a new type of storage controller, a problem arises: How do you install the Solaris OS onto a system that requires a device that does not have a driver binary already in the Solaris installation media? In the case of a storage controller, unless the installer media has the driver a priori, there will be no way to persist the installation packages to disk storage. And in the case of a blade-type computer with primarily a network interface and little other I/O, it becomes impossible to perform a network install of the Solaris OS onto that system if the initial Solaris instance that boots the system over the network does not have a driver for the network interface.

This how-to document therefore provides a concise set of directions to insert new device driver binaries into the installation media. It covers two primary installation methods:


The document applies only to the Solaris 10 1/06 (also known as Update 1) and OpenSolaris (Nevada) versions that use the new Solaris boot architecture. (See Resources section for more information.)

Network PXE-Boot Installation

Perhaps the fastest and most convenient way to install the Solaris OS has been over the network from a Solaris JumpStart server. Many administrators who use the Solaris Enterprise System may already know about JumpStart technology for Oracle servers and workstations based on SPARC technology, which have network-aware Open Boot PROM firmware. Oracle popularized this install methodology nearly two decades ago. The basic process follows these simple steps:

  1. The netinstall client is configured to boot over the network.
  2. Just after powering up, the client uses BOOTP to broadcast for network information.
  3. The BOOTP server replies with network, bootstrap, and installation information.
  4. The client configures its network and retrieves bootstrap and installation files.

In recent years, the Ethernet interface has also become a standard on virtually all PCs, and many come enabled with Intel's Pre-boot Execution Environment (PXE) firmware that extends the PC BIOS with a similar ability to perform network bootstraps and installations. The process for PCs is essentially identical, the only difference being that PXE boot leverages DHCP to retrieve network, bootstrap, and installation information in steps (2) and (3). What many Solaris system administrators may not know, however, is that Solaris JumpStart servers can also boot PCs with the addition of DHCP server support for the PXE boot clients. All the required server software components come bundled into the Solaris OS already and this is just a matter of configuration.

Setting Up a JumpStart PXE Boot Server

The Solaris install media usually includes a utility to install the basic JumpStart server. Inserting optical media into a running Solaris system will usually prompt the volume manager to mount the media at /cdrom. When you change the directory to the following you should see the JumpStart installation script setup_install_server(1m).

   # cd /cdrom/sol_10_106_x86/Solaris_10/Tools

Usage is straightforward. Just specify the command and a target installation directory:

   # ./setup_install_server /export/install

The user can change the target directory, /export/install, to another location as needed. Running this command requires about 3 or more Gbytes of disk space on the slice that holds the target directory. The command may also take an hour or more as all the components are copied to the target directory from optical media. The time depends on the speed of the optical drive, and the speed of the main system.

Users who only have a CD-ROM drive and no support for DVDs will be installing from multiple disks. The initial installation is the same for CD1 as for the DVD. After the initial setup_install_server, you can exit out of the current directory back to the /root directory, and then eject the first CD from the file manager window, and then insert additional CDs. On each CD, change directories back into the /cdrom/sol_10_106_*/Solaris10/Tools/ directory and run the add_to_install_server(1M) command with the same target directory you started with.

When the install server setup completes, it is important to export the installation file system to the network. To do this, edit the /etc/dfs/dfstab file and insert a line that looks like the following:

   # share -F nfs -o ro,anon=0 -d "jumpstart dir" /export/install

You can edit /export/install to wherever you unpacked the install server. After saving and exiting the editor, you should then enable or restart the NFS server by running the following:

   # svcadm enable svc:/network/nfs/server ; shareall

For completeness, you can create a directory:

   # mkdir /export/install/jumpstart

Then copy the sample jumpstart_sample files to that directory:

   # cp -r /export/install/Solaris_10/Misc/jumpstart_sample/* \
    /export/install/jumpstart

Setting Up a DHCP Server for PXE Boot

In the previous section, you completed most of the tasks required to transfer JumpStart installation packages to the server, and make these packages accessible over the network through NFS. However, before a PC boot client can access those packages, it must boot over the network and obtain initial network and boot files to begin the installation. For most network install environments, the same JumpStart host also runs DHCP and PXE boot server processes for the boot clients.

When a PXE boot client starts, it broadcasts for network information and boot files. The network information is provided through DHCP. Then the Solaris network boot program (nbp) and other initialization files such as the Solaris x86.miniroot are transferred using TFTP, and finally, once the Solaris installer has started, the JumpStart installation packages are transferred through NFS.

Configuring the Solaris DHCP requires the following:


If a DHCP server is already configured, you can unconfigure it using the dhcpconfig(1M) command with the unconfigure flag, for example:

   # dhcpconfig -Ux

The server you configure here will answer promiscuously for all PXE boot requests for the Solaris OS on x86 platforms and works well on an isolated subnet where it is the only install service. However, if this DHCP service must coexist with others, or requires specific configurations, customizations are available to answer requests only from specific MAC addresses or for specific networks. Please see the Solaris DHCP Administration Guide for more information.

The following is a script that should simplify most generic DHCP configurations for PXE:

 #!/bin/sh
dhcpconfig -D -r SUNWbinfiles -p /var/dhcp
dhcpconfig -N <network> -m <netmask> -t <routerip>
dhtadm -A -s SrootOpt -d 'Vendor=SUNW.i86pc,1,ASCII,1,0'
dhtadm -A -s SrootIP4 -d 'Vendor=SUNW.i86pc,2,IP,1,1'
dhtadm -A -s SrootNM -d 'Vendor=SUNW.i86pc,3,ASCII,1,0'
dhtadm -A -s SrootPTH -d 'Vendor=SUNW.i86pc,4,ASCII,1,0'
dhtadm -A -s SswapIP4 -d 'Vendor=SUNW.i86pc,5,IP,1,0'
dhtadm -A -s SswapPTH -d 'Vendor=SUNW.i86pc,6,ASCII,1,0'
dhtadm -A -s SbootFIL -d 'Vendor=SUNW.i86pc,7,ASCII,1,0'
dhtadm -A -s Stz -d 'Vendor=SUNW.i86pc,8,ASCII,1,0'
dhtadm -A -s SbootRS -d 'Vendor=SUNW.i86pc,9,NUMBER,2,1'
dhtadm -A -s SinstIP4 -d 'Vendor=SUNW.i86pc,10,IP,1,1'
dhtadm -A -s SinstNM -d 'Vendor=SUNW.i86pc,11,ASCII,1,0'
dhtadm -A -s SinstPTH -d 'Vendor=SUNW.i86pc,12,ASCII,1,0'
dhtadm -A -s SsysidCF -d 'Vendor=SUNW.i86pc,13,ASCII,1,0'
dhtadm -A -s SjumpsCF -d 'Vendor=SUNW.i86pc,14,ASCII,1,0'
dhtadm -A -s Sterm -d 'Vendor=SUNW.i86pc,15,ASCII,1,0'
dhtadm -A -s SbootURI -d 'Vendor=SUNW.i86pc,16,ASCII,1,0'
dhtadm -A -m PXEClient:Arch:00000:UNDI:002001 -d ':BootFile="nbp.SUNW.i86pc":BootSrvA=<serverip>:'
dhtadm -A -m SUNW.i86pc -d \ 
   ':SinstNM="<server>":SinstIP4=<serverip>:\
SinstPTH="/export/install":SrootNM="<server>":\
SrootIP4=<serverip>:\
SrootPTH="/export/install/Solaris_10/Tools/Boot":\
SjumpsCF="<server>:/export/install/jumpstart":\
SsysidCF="<server>:/export/install/jumpstart":'

Near the top, <network> should be replaced with the network address for your subnet (for example, 192.168.100.0). The <netmask> is your netmask (for example, 255.255.255.0), and the <routerip> is the IP address of your router (for example, 192.168.100.1). On the last line of the script, replace <server> with the host name of the install server, which also is the name of the dhtadm macro you name on the last line previously, and also replace <serverip> with the IP address of the install server. Cut and paste the script into a file and run it as the super-user.

Also, edit the /etc/hosts file and add one or more client entries with an IP address. For two clients, do the following:

   192.168.100.101 pxeclient1
   192.168.100.102 pxeclient2

Now add those to the DHCP server client table using the pntadm(1M) command:

   # pntadm -A 192.168.100.101 -m <server> -h pxeclient1 <network> 
   # pntadm -A 192.168.100.102 -m <server> -h pxeclient2 <network>

Note that <server> and <network> have the same meaning for the server and network macros specified by the last line of the PXE configuration script above. Then send a -HUP signal to the in.dhcp process by issuing the following command:

   #  pkill -HUP in.dhcpd 

This signal will force the DHCP server to reread its configuration files. This should take care of the first step of DHCP server configuration.

To configure the boot files for TFTP, the Solaris OS provides a command to simplify the creation and copying of all the files to the /tftpboot directory. Simply run the command from the /export/install/images/Solaris_10/Tools directory:

   # ./add_install_client -d SUNW.i86pc i86pc

You should now be able to test your PC client and boot PXE on the Solaris OS.

Adding More Drivers

There are two steps to adding drivers for PXE boot clients. Most critical to add are usually the storage controller and network interface drivers as explained previously. The first step is to insert these drivers into the x86.miniroot that loads through TFTP.

The file, if you follow the aforementioned directions, would be located at the following:

   /export/install/boot/x86.miniroot

But the file could be located at /export/<solaris_root_install_dir>/boot/x86.miniroot , where <solaris_root_install_dir> is the top-level directory name under /export where you unpacked the install media. To do the first step, unpacking the miniroot, you can run the root_archive(1M) command on the install server. This is only available on the Solaris 10 1/06 release for x86 platforms and later. Change directories to the /export/install/boot or wherever the install server setup put the packages, and then unpack the miniroot using the following command:

   # /boot/solaris/bin/root_archive unpack ./x86.miniroot ./unpacked

Once the miniroot is unpacked, copy the 32-bit driver binary and driver.conf file to the /unpacked/kernel/drv directory, and then run the /usr/sbin/add_drv command with the right PCI IDs and the right permissions against the unpacked miniroot directory. For example:

  # add_drv -b <fullpath-to-unpacked> -n -v -m '* 0600 root sys' -i "<device ids>" <mydrivername>

Note that <mydrivername> is the name of the binary just copied to the ./unpacked/kernel/drv directory, and the <device ids> is a string list of PCI device IDs that might look like the following:

   '"pci1a44,9043" "pci1a44,9065" "pci1a44,9106" "pci1a44,9053"'

Also, the -b flag allows you to set the root path where you apply the driver add operation, which is pointing to the unpacked miniroot. Note that x86.miniroot is 32-bit and only supports 32-bit drivers.

The last step is to repack the miniroot using the same command, but specifying pack as the keyword. Before you do that, you can, and probably should, make a copy of the original x86.miniroot in the same boot directory. For example:

   # cp ./x86.miniroot ./x86.miniroot.orig

Then run the root_archive(1M) command:

   # /boot/solaris/bin/root_archive pack ./x86.miniroot ./unpacked

If the PXE boot server was working before, the client should be able to boot and load the x86.miniroot and complete a normal installation of the Solaris 10 1/06 release for x86 platforms. The installation will bring up a menu of install choices; the default is to perform an interactive install. When doing an interactive install, the installer offers a choice of auto-reboot or manual reboot. Choose the manual reboot, because while the previous steps get the driver into the miniroot, they do not do anything to install the missing network driver onto the final client system. Select manual reboot so you have a chance to copy over the drivers and run the add_drv command on the final client disk image before rebooting. Otherwise, the newly installed system still will not have a network driver.

Now where do you put the driver binaries so the install client can copy them over?

You could copy the one from the miniroot's /kernel/drv that is already there. This works if the system is only 32-bit and will only run in this mode. However, if the system is x64 capable, you did not copy the 64-bit driver binary into the miniroot's /kernel/drv/amd64 directory and that is because the miniroot is only 32-bit and does not have a ./kernel/drv/amd64 directory. You could have created that directory in earlier steps, but that is not necessary. During the Solaris PXE boot installation, the client mounts the install server directories through NFS. Thus it is easy enough, before rebooting, to simply put the driver files in the install server's exported PXE boot directory, especially inside the jumpstart directory where the client already mounts them during the install. You can just put a ./jumpstart/drv subdirectory inside the server's exported directories. This will be usually mounted on the install client as /tmp/install_config. If you cannot find it, use the df(1M) command to see a list of file systems and their mount points.

CD/DVD-ROM Media Installation

Making bootable CD or DVD install media with additional drivers is similar in process to altering the x86.miniroot for network installation. Most of the additional work is in mounting the CD or DVD, copying over the entire disk image contents to another directory, performing the same driver insertion operations on the copy of the install image, and then repackaging the files and creating a bootable ISO image that can be burned onto CD or DVD media.

Using CD/DVD-ROM Media

If DVD or CD-ROM media are present already, then it should be straightforward to copy the files over. Simply insert the disk into the drive, and then at the command line do the following:

   # cd /cdrom/sol_10_106/x86; find . -depth -print|cpio -vpdm <targetdir>

Note that the <targetdir> is the full path to the target-working directory. Once copied over, the miniroot is usually located in <targetdir>/boot/x86.miniroot. Repeat the previous steps in the section titled "Adding More Drivers."

When done, use the mkisofs(8) command to repackage the files into a bootable ISO image to be burned. Specifically:

   # mkisofs -o <outfilename.iso> -b boot/grub/stage2_eltorito \
     -c .catalog -no-emul-boot -boot-load-size 4 \
     -boot-info-table -relaxed-filenames -N -L -l -r -J \
     -d -D -V <volname> <targetdir> 

Replace the <outfilename.iso> with the file name you want output, and <volname> with a volume name (for example, MYS10VOL). <targetdir> is the same as from where the original files were copied.

Using CD/DVD ISO Files

If you do not have media, but have downloaded an ISO file, you do not need to burn the media first and then mount it. The Solaris OS offers a loopback file system mounting command, lofiadm(1M), that allows users to mount ISO images. Simply use the following command:

 # /usr/sbin/lofiadm -a <isoimagepath>

Note that <isoimagepath> is the full path to the downloaded installation ISO image. Often, the lofiadm(1M) command will return the block device location as /dev/lofi/1 or /dev/lofi/2 or /dev/lofi/ depending on the number of loopback file systems already mounted. To mount this as a readable file system, use the mount(1M) command:

   # mount -F hsfs /dev/lofi/1 /mnt

The files are now available just as in the section titled "Using CD/DVD-ROM Media," except at the /mnt mount point. Repeat the same process for inserting drivers into the install image as in "Adding More Drivers" and repackage as a burnable and bootable ISO image using the same command in the section titled "Using CD/DVD-ROM Media."

When complete with the loopback file system mount, simply run the umount(1M) and lofiadm(1M) commands to umount:

   # umount /mnt; lofiadm -d /dev/lofi/1

Replace the /mnt and /dev/lofi/1 with your mount points in the previous command.

Resources

For more information, here are a number of useful links: