Altering the Kernel with config(8)

While sysctl lets you tweak the kernel, it won’t let you change values that are hard-coded into the kernel binary. Some of these values are used to initialize kernel data structures, and they can’t be changed once the kernel is running. Others relate to device drivers. Once the kernel has finished probing devices, it won’t go back and reprobe just because you change where a device driver checks for its hardware. To change hard-coded values like these, you must edit the existing kernel file and reboot, allowing the system to set things as you like from initialization. That’s where config(8) comes in.

The config command has two completely separate functions. The first creates a kernel compilation directory from a text configuration file, as discussed in Chapter 19. The function we’re most interested in now is editing an existing kernel binary, which lets you tweak a kernel to better suit your needs.

Note

The modern OpenBSD kernel is largely dynamic. If you call for additional virtual interfaces, the kernel creates them. If you need to change the amount of memory for the buffer cache, use a sysctl. Editing the kernel is rarely necessary.

Making a Backup of the Default Kernel

Before making any changes to a working kernel, no matter how minor, back up the original kernel! If your minor changes make your machine unbootable, you want to be able to easily fall back to a working kernel.

The kernel is just a file, /bsd. To back it up, copy it to another file. I recommend naming your backup of the default kernel /bsd.GENERIC, for reasons that will become apparent in Chapter 19.

Always keep a known-good kernel on your system. A bad kernel can prevent a computer from booting, and if you don’t have a reliable kernel that’s easily bootable, you will need to boot from installation media. (Boot your backup kernel using the instructions in Chapter 5.) And remember that subtle kernel bugs can take weeks or months to show up, so plan to keep your backup kernel forever.

Device Drivers and the Kernel

Much of the hard-coded information in the kernel relates to device drivers, especially drivers for ancient ISA cards.

Some of you may remember manually configuring the interrupt request (IRQ) and memory port addresses on a network or SCSI card. The kernel uses the IRQ to identify cards. Essentially, it consults an internal list of IRQs and port numbers, compares it to what it finds on the hardware probe, and assigns the drivers appropriately. “This card answers at IRQ 10 and memory port 0x300? It must be a NE2000-compatible network card. I will assign that driver to it.” The process is more complicated than this, of course, but this probe is a vital part of the process. If you want OpenBSD to recognize such a card, and the card is set to an IRQ and memory port other than what OpenBSD expects, you must tell the kernel the IRQ and memory port the card is using.

Realistically, the best way to deal with ISA cards is to feed them to the recycling plant. Running OpenBSD on a 25-year-old VAX is interesting and educational. Running OpenBSD on 15-year-old Sparc hardware is realistic for very specific applications, and can also be educational and interesting. Running OpenBSD on 10-year-old consumer-grade i386 hardware is either a waste of time or an exercise in masochism—probably both.

Note

Modern PCI-descended hardware includes hooks for the kernel to identify the hardware and assign the proper device driver. You shouldn’t need to edit the kernel to support hardware.

Enabling Drivers

Rather than changing driver IRQs, more realistically, you might need to enable a device driver that’s disabled by default or disable a device that’s on by default.

The kernel includes some device drivers that are disabled because they react badly with certain hardware, such as the IPMI driver. The ipmi(4) driver is known to be buggy, and as I write this, it is badly broken in some use cases. It’s included in the default kernel, but disabled by default.

You can choose to enable ipmi(4). If it works for you, great. If it doesn’t, feel free to submit bug reports, preferably with patches, or at least proper dmesg output and crash dumps.

Editing the Kernel with config

When using config as a kernel editor, use the command-line options -e and -o. The -e flag tells config you’re editing a kernel binary. The -o flag lets you specify a new file for the edited version of the kernel.

Give the original kernel file path as an argument. For example, here’s how to edit /bsd and write the result to the file /bsd.test:

# config -e -o /bsd.test /bsd

You could use the -f flag instead of -o and a filename. The -f flag tells config to edit the kernel file in place, not to create a new file.

Note

If you’re editing /bsd and you specified the -f option, your changes are written directly to /bsd. I recommend not doing this. (Unless, of course, you’re absolutely certain you know what you’re doing. You get to keep all the parts.)

Running config will open the kernel editor, which should look much like this:

OpenBSD 5.2-current (GENERIC) #287: Tue Aug 21 18:15:00 MDT 2013
    [email protected]:/usr/src/sys/arch/i386/compile/GENERIC
Enter 'help' for information
ukc>

At this point, you need to use kernel editor commands to make changes.

Using the help and list Commands

Start with the two editor commands help and list. The help command shows all the commands available within config and comes in particularly handy at stupid-o’clock AM to remind you of the necessary syntax.

The list command displays a complete list of all the devices the kernel supports, one screen at a time.

ukc> list
  0 video* at uvideo* flags 0x0
  1 audio* at uaudio*|sb0|sb*|gus0|gus*|pas0|ess*|wss0|wss*|ym*|eap*|envy*|
eso*|sv*|neo*|cmpci*|clcs*|clct*|auacer*|auglx*|auich*|auixp*|autri*|auvia*|
azalia*|fms*|maestro*|esa*|yds*|emu* flags 0x0
  2 midi* at umidi*|sb0|sb*|ym*|mpu*|mpu*|autri*|eap*|envy* flags 0x0
…

On an OpenBSD 5.2 system, the default kernel has 538 entries, most for hardware that isn’t on any particular system but that OpenBSD supports out of the box. Let’s take a closer look at the devices shown.

Line 0 says that this kernel supports the video device. The kernel will look for a video device attached to the uvideo device. The uvideo(4) man page tells us that uvideo is USB video, mainly for webcams and the like, and video(4) says that the video driver is a device-independent video driver. The flags statement gives settings to feed to this device driver. (This kernel supports webcams.)

Line 1 says that this kernel supports an audio device, and it can be attached to any of a long list of device drivers. The online manual says that uaudio, sb0, gus0, and so on are sound cards. We get sound with our video? Truly we live in an age of wonders.

Entries for older ISA gear are more complex.

278 ne0 at isa0 port 0x240 size 0 iomem -1 iosiz 0 irq 9 drq -1 drq2 -1 flags 0x0

This entry for supporting the old-fashioned NE2000 ISA network card includes an IRQ, DRQ, memory port, and a few other settings that I’ve (thankfully) forgotten about. The kernel will check ISA bus number 0 at the stated port and IRQ, in the hope of finding such a device.

504 pflog count 1 (pseudo device)

This is a pseudo-device—a software creation that acts much like an actual device but has no underlying hardware. The pflog(4) pseudo-device is where the packet filter dumps its logs. This kernel creates one instance of the pflog device at boot, but thanks to OpenBSD’s cloneable interfaces, the kernel can create more pflog interfaces as needed.

Finally, notice that several lines declare themselves “free.” You can copy an existing device and add it to the kernel. For example, if you wanted a kernel that supported 10 NE2000 cards, and needed 10 instances of the device driver in the kernel, you could copy and add the devices here. The kernel will autoconfigure any number of device driver instances for modern hardware; it will find 10 PCI Express network cards and give them their own instances of the device without any prodding from you.

Finding and Enabling Devices

One of the disadvantages to the list command is that it shows everything in the kernel. You can’t interrupt it; you must scroll through to the end. It’s also difficult to search through several hundred devices by eye. If you know the device you want, use find to search for it. Here, we’ll use ipmi as an example.

ukc> find ipmi
493 ipmi0 at mainbus0 disable bus -1 flags 0x0

The IPMI device is device number 493, and it is attached to the device mainbus0. But note the word disable in the device entry. The ipmi device is disabled. Let’s turn it on.

ukc> enable ipmi
493 ipmi0 enabled

The kernel now has an active IPMI driver. Yippee!

Changing Kernel Constants

In addition to the device drivers, the kernel has a few hard-coded values for internal data structures. If you run help in the kernel editor, you’ll see these values as options.

ukc> help
…
        bufcachepercent [number]            Show/change BUFCACHEPERCENT
        nkmempg         [number]            Show/change NKMEMPAGES

As you can see there are only two values: BUFCACHEPERCENT and NKMEMPAGES. Unless you have a compelling reason to touch these values, leave them alone.

NKMEMPAGES is the number of pages of memory dedicated to the kernel.If your machine starts panicking with error messages of out of space in kmem_map, you can increase this value. If the system boots successfully, however, you’re better off setting the vm.nkmempages sysctl rather than editing the kernel.

BUFCACHEPERCENT is the percentage of physical memory dedicated to the buffer cache. In some fairly rare circumstances, increasing the size of the buffer cache can improve filesystem performance. You could set the sysctl kern.bufcachepercent instead of editing this kernel value, however.

To view a current value, enter its name.

ukc> bufcachepercent
bufcachepercent = 20

To change the value, enter its name and the desired value.

ukc> bufcachepercent 50
bufcachepercent = 50

Again, don’t muck with these numbers arbitrarily. The OpenBSD developers set them to the default values for very good reasons.

Completing Configuration

Once you’ve made all of your changes, enter quit to save your changes and write them to a kernel file. The exit command discards all changes and leaves the editor, making it easy to start over. Do not mix quit and exit unless you like being annoyed and confused.

Installing Your Edited Kernel

Your edited kernel is just a file. Verify that you have a backup of your working kernel, copy your new kernel to /bsd, and reboot.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.157.6