5. Advanced topics
5.1 Resource allocation for PCMCIA devices
In theory, it should not really matter which interrupt is allocated to which device, as long as two devices are not configured to use the same interrupt. In /etc/pcmcia/config.opts you'll find a place for excluding interrupts that are used by non-PCMCIA devices.
Similarly, there is no way to directly specify the I/O addresses for a card to use. The /etc/pcmcia/config.opts file allows you to specify ranges of ports available for use by any card, or to exclude ranges that conflict with other devices.
After modifying /etc/pcmcia/config.opts, you can reinitialize cardmgr with ``kill -HUP''.
The interrupt used to monitor card status changes is chosen by the low-level socket driver module (i82365 or tcic) before cardmgr parses /etc/pcmcia/config, so it is not affected by changes to this file. To set this interrupt, use the cs_irq= option when the socket driver is loaded, by setting the PCIC_OPTS variable in /etc/rc.d/rc.pcmcia.
All the client card drivers have a parameter called irq_list for specifying which interrupts they may try to allocate. These driver options should be set in your /etc/pcmcia/config file. For example:
module "serial_cs" opts "irq_list=8,12"
would specify that the serial driver should only use irq 8 or irq 12. Regardless of irq_list settings, Card Services will never allocate an interrupt that is already in use by another device, or an interrupt that is excluded in the config file.
5.2 How can I have separate device setups for home and work?
This is fairly easy using ``scheme'' support. Use two configuration schemes, called ``home'' and ``work''. Here is an example of a network.opts script with scheme-specific settings:
case "$ADDRESS" in
# definitions for network card in work scheme
# definitions for network card in home scheme
The first part of a device address is always the configuration scheme. In this example, the second ``case'' clause will select for both the ``home'' and ``default'' schemes. So, if the scheme is unset for any reason, it will default to the ``home'' setup.
Now, to select between the two sets of settings, run either:
cardctl scheme home
cardctl scheme work
The cardctl command does the equivalent of shutting down all your cards and restarting them. The command can be safely executed whether or not the PCMCIA system is loaded, but the command may fail if you are using other PCMCIA devices at the time (even if their configurations are not explicitly dependant on the scheme setting).
To find out the current scheme setting, run:
By default, the scheme setting is persistent across boots. This can have undesirable effects if networking is initialized for the wrong environment. Optionally, you can set the initial scheme value with the SCHEME startup option (see Startup options for details). It is also possible to set the scheme from the lilo boot prompt. Since lilo passes unrecognized options to init as environment variables, a value for SCHEME (or any other PCMCIA startup option) at the boot prompt will be propagated into the PCMCIA startup script.
To save even more keystrokes, schemes can be specified in lilo's configuration file. For instance, you could have:
root = /dev/hda1
image = /boot/vmlinuz
label = home
append = "SCHEME=home"
image = /boot/vmlinuz
label = work
append = "SCHEME=work"
Typing ``home'' or ``work'' at the boot prompt would then boot into the appropriate scheme.
5.3 Booting from a PCMCIA device
Having the root filesystem on a PCMCIA device is tricky because the Linux PCMCIA system is not designed to be linked into the kernel. Its core components, the loadable kernel modules and the user mode cardmgr daemon, depend on an already running system. The kernel's ``initrd'' facility works around this requirement by allowing Linux to boot using a temporary ram disk as a minimal root image, load drivers, and then re-mount a different root filesystem. The temporary root can configure PCMCIA devices and then re-mount a PCMCIA device as root.
The initrd image absolutely must reside on a bootable device: this generally cannot be put on a PCMCIA device. This is a BIOS limitation, not a kernel limitation. It is useful here to distinguish between ``boot-able'' devices (i.e., devices that can be booted), and ``root-able'' devices (i.e., devices that can be mounted as root). ``Boot-able'' devices are determined by the BIOS, and are generally limited to internal floppy and hard disk drives. ``Root-able'' devices are any block devices that the kernel supports once it has been loaded. The initrd facility makes more devices ``root-able'', not ``boot-able''.
Some Linux distributions will allow installation to a device connected to a PCMCIA SCSI adapter, as an unintended side-effect of their support for installs from PCMCIA SCSI CD-ROM devices. However, at present, no Linux installation tools support configuring an appropriate ``initrd'' to boot Linux with a PCMCIA root filesystem. Setting up a system with a PCMCIA root thus requires that you use another Linux system to create the ``initrd'' image. If another Linux system is not available, another option would be to temporarily install a minimal Linux setup on a non-PCMCIA drive, create an initrd image, and then reinstall to the PCMCIA target.
The Linux Bootdisk-HOWTO has some general information about setting up boot disks but nothing specific to initrd. The main initrd document is included with recent kernel source code distributions, in linux/Documentation/initrd.txt. Before beginning, you should read this document. A familiarity with lilo is also helpful. Using initrd also requires that you have a kernel compiled with CONFIG_BLK_DEV_RAM and CONFIG_BLK_DEV_INITRD enabled.
This is an advanced configuration technique, and requires a high level of familiarity with Linux and the PCMCIA system. Be sure to read all the relevant documentation before starting. The following cookbook instructions should work, but deviations from the examples will quickly put you in uncharted and ``unsupported'' territory, and you will be on your own.
This method absolutely requires that you use a PCMCIA driver release of 2.9.5 or later. Older PCMCIA packages or individual components will not work in the initrd context. Do not mix components from different releases.
The pcinitrd helper script
The pcinitrd script creates a basic initrd image for booting with a PCMCIA root partition. The image includes a minimal directory heirarchy, a handful of device files, a few binaries, shared libraries, and a set of PCMCIA driver modules. When invoking pcinitrd, you specify the driver modules that you want to be included in the image. The core PCMCIA components, pcmcia_core and ds, are automatically included.
As an example, say that your laptop uses an i82365-compatible host controller, and you want to boot Linux with the root filesystem on a hard drive attached to an Adaptec SlimSCSI adapter. You could create an appropriate initrd image with:
pcinitrd -v initrd pcmcia/i82365.o pcmcia/aha152x_cs.o
To customize the initrd startup sequence, you could mount the image using the ``loopback'' device with a command like:
mount -o loop -t ext2 initrd /mnt
and then edit the linuxrc script. The configuration files will be installed under /etc in the image, and can also be customized. See the man page for pcinitrd for more information.
Creating an initrd boot floppy
After creating an image with pcinitrd, you can create a boot floppy by copying the kernel, the compressed initrd image, and a few support files for lilo to a clean floppy. In the following example, we assume that the desired PCMCIA root device is /dev/sda1:
mount /dev/fd0 /mnt
mkdir /mnt/etc /mnt/boot /mnt/dev
cp -a /dev/fd0 /dev/sda1 /mnt/dev
cp [kernel-image] /mnt/vmlinuz
cp /boot/boot.b /mnt/boot/boot.b
gzip < [initrd-image] > /mnt/initrd
Create /mnt/etc/lilo.conf with the contents:
Finally, invoke lilo with:
lilo -r /mnt
When lilo is invoked with -r, it performs all actions relative to the specified alternate root directory. The reason for creating the device files under /mnt/dev was that lilo will not be able to use the files in /dev when it is running in this alternate-root mode.
Installing an initrd image on a non-Linux drive
One common use of the initrd facility would be on systems where the internal hard drive is dedicated to another operating system. The Linux kernel and initrd image can be placed in a non-Linux partition, and lilo or LOADLIN can be set up to boot Linux from these images.
Assuming that you have a kernel has been configured for the appropriate root device, and an initrd image created on another system, the easiest way to get started is to boot Linux using LOADLIN, as:
LOADLIN <kernel> initrd=<initrd-image>
Once you can boot Linux on your target machine, you could then install lilo to allow booting Linux directly. For example, say that /dev/hda1 is the non-Linux target partition and /mnt can be used as a mount point. First, create a subdirectory on the target for the Linux files:
mount /dev/hda1 /mnt
cp [kernel-image] /mnt/linux/vmlinuz
cp [initrd-image] /mnt/linux/initrd
In this example, say that /dev/sda1 is the desired Linux root partition, a SCSI hard drive mounted via a PCMCIA SCSI adapter. To install lilo, create a lilo.conf file with the contents:
The boot= line says to install the boot loader in the master boot record of the specified device. The root= line identifies the desired root filesystem to be used after loading the initrd image, and may be unnecessary if the kernel image is already configured this way. The other= section is used to describe the other operating system installed on /dev/hda1.
To install lilo in this case, use:
lilo -C lilo.conf
Note that in this case, the lilo.conf file uses absolute paths that include /mnt. I did this in the example because the target filesystem may not support the creation of Linux device files for the boot= and root= options.