Search:  
Gentoo Wiki

HOWTO_Compile_Kernel_with_ALSA

It has been suggested that this article or section be merged into ALSA/Install. (Discuss)

Contents

Introduction

The purpose of this article is to provide a reasonably foolproof method of compiling the kernel and including the in-kernel ALSA modules for sound (instead of emerging alsa-driver). It was written because there are many potential errors to make, for people unfamiliar with kernel modules.

For simplicity, this article describes the simplest reasonable way of getting things working. Topics which are out-of-scope for this article (and which should be in separate wiki articles) are:

The reason for keeping this article so simple is to prevent the confusion of newbies who are simply trying to get basic sound working. It is already difficult enough to get newbies to read this article fully, and provide the debugging information. To reduce its length, it does not duplicate important information, so read all of it.

Background

Kernel Modules

Modules live in /lib/modules/<kernel version>/. They can be listed with:

find /lib/modules/ -name \*.ko

The kernel version of the currently-running kernel can be viewed with:

uname -r

The full kernel details, including date & time of compilation, can be viewed with:

uname -a

Steps

Identify the soundcard

Use the ALSA soundcard list and Google to discover the appropriate kernel module for the soundcard - search for the model name, along with keywords such as "linux module". This will probably show the soundcard model:

update-pciids
lspci | grep -i audio

The purpose of update-pciids is to update the lookup database that lspci uses.

Choose appropriate kernel

Different versions of the kernel may include different versions of ALSA, and ALSA can occasionally break itself partly (e.g. missing channels) or wholly (e.g. no sound) for various soundcards, so an obvious trick is to try a newer (but older is possible also) kernel, or a different kernel. There are custom kernels available on the Gentoo forums which may contain recent ALSA patches, e.g. the popular zen-sources. The aim is simply to find a kernel containing an ALSA version that works with your particular hardware combination.

If in doubt, it is recommended to try a kernel patched with the latest ALSA version (e.g. zen-sources) first, especially with new-ish hardware models, or the often-problematic Intel HDA variations.

Set kernel symlink

First run:

cd /usr/src
ls -l

/usr/src/linux should be a symlink to the directory containing the desired kernel. If not, create/change the symlink with e.g.:

ln -sfn linux-2.6.23.1 linux

Patch kernel with live ALSA (optional)

An advanced option is to patch the kernel with the latest ALSA code, from a git checkout, overwriting the ALSA code currently in the kernel - e.g. see ebuild on bugzilla.

The ALSA project now uses git instead of mercurial, so the out-of-date instructions have been removed.

Clean out old modules

First, delete any existing sound-related modules. This immediately fixes some extremely common mistakes regarding old modules which are inadvertently loaded.

Code: Deletes existing sound-related modules
emerge --unmerge alsa-driver
find /lib/modules -name alsa-driver -print0 | xargs -0 rm -rf
find /lib/modules -name snd\*.ko -delete
find /lib/modules -name sound\*.ko -delete

Guard against alsa-driver being emerged. It is not needed, because the in-kernel ALSA replaces it.

echo "media-sound/alsa-driver" >> /etc/portage/package.mask

Configure kernel with ALSA modules

Manually copy your kernel configuration to /usr/src/linux/.config - a useful tip for copying the configuration of the currently-running kernel, as a starting point, is:

zcat /proc/config.gz > /usr/src/linux/.config

Then enter the kernel configuration menus:

cd /usr/src/linux
make menuconfig

Select the ALSA kernel modules, including the module for your soundcard (press / to perform a keyword search, when within the kernel menus). Example:

$ grep SND /usr/src/linux/.config | grep =m
CONFIG_SND=m
CONFIG_SND_TIMER=m
CONFIG_SND_PCM=m
CONFIG_SND_HWDEP=m
CONFIG_SND_RAWMIDI=m
CONFIG_SND_SEQUENCER=m
CONFIG_SND_MIXER_OSS=m
CONFIG_SND_PCM_OSS=m
CONFIG_SND_RTCTIMER=m
CONFIG_SND_AC97_CODEC=m
CONFIG_SND_EMU10K1=m
$ grep SND /usr/src/linux/.config | grep =y
CONFIG_SND_OSSEMUL=y
CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_SEQUENCER_OSS=y
CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
CONFIG_SND_DYNAMIC_MINORS=y
CONFIG_SND_SUPPORT_OLD_API=y
CONFIG_SND_VERBOSE_PROCFS=y
$ grep SOUND /usr/src/linux/.config
CONFIG_SOUND=m
# CONFIG_SOUND_PRIME is not set

The difference between =m and =y is very important. =y is only used for options. All the modules are selected as external modules, to be placed within /lib/modules, so that they can be loaded by /etc/init.d/alsasound, so that the alsasound script can do its job of checking that the correct modules are set up, and using /etc/modprobe.conf to configure them.

Do not enable VIRMIDI, because it may become the first soundcard, thus overriding the intended soundcard (see index=0 option for multiple soundcards).

$ grep -i virmidi /usr/src/linux/.config
# CONFIG_SND_VIRMIDI is not set

Note that ALSA's support for OSS is included, for backwards-compatibility and choice.

Configure module options

Refer to the ALSA soundcard list to find the lines with which to populate /etc/modprobe.d/alsa - example for a Soundblaster card which uses the EMU10K1 module:

alias char-major-116 snd
alias char-major-14 soundcore
alias snd-card-0 snd-emu10k1
alias sound-slot-0 snd-card-0
alias sound-service-0-0 snd-mixer-oss
alias sound-service-0-1 snd-seq-oss
alias sound-service-0-3 snd-pcm-oss
alias sound-service-0-8 snd-seq-oss
alias sound-service-0-12 snd-pcm-oss
alias /dev/mixer snd-mixer-oss
alias /dev/dsp snd-pcm-oss
alias /dev/midi snd-seq-oss
options snd cards_limit=1

Then run, to recreate /etc/modprobe.conf from the files in /etc/modprobe.d/

update-modules

Note that it is not necessary to run alsaconf to set up /etc/modprobe.d/alsa

Compile kernel and modules

To compile the kernel, run:

cd /usr/src/linux
make clean bzImage modules modules_install

The purpose of those parameters is to ensure that the whole kernel and all of its modules are recompiled, even if they already exist in /lib/modules/ - for further information, read the output of:

cd /usr/src/linux
make help

Do not blindly run make && make install, because that takes shortcuts which may not be appropriate, leading to "invalid module" errors.

Next, re-emerge any packages which provide kernel modules in /lib/modules/, e.g.:

rm -f /lib/modules/*/{video/nvidia,fs/fuse,misc/{cdemu,ndiswrapper,vm{mon,net}}}.ko
emerge -1 nvidia-drivers ndiswrapper

The rm command is run first, to prevent Portage from moaning about file collisions with already-existing files when FEATURES="collision-protect" is in /etc/make.conf, and also to ensure that the modules do get recompiled. This can interfere with other kernels.

It is worth mentioning module-rebuild as a utility to aid in recompiling kernel modules which were installed by ebuilds.

Note that a minority of packages providing kernel modules require a reboot into the new kernel, before being recompiled.

Copy kernel into /boot

The first step in turning the newly-compiled kernel into the next kernel after a reboot, is to copy it to a convenient place for GRUB to load it. This place is within /boot. For an x86 (32-bit) installation, the commands can be e.g.:

Code: Copy kernel into /boot
cd /usr/src/linux
[[ -d /boot/grub ]] || mount /boot
cp arch/i386/boot/bzImage /boot/kernel
cp System.map /boot/System.map
cp .config /boot/config

Note that /boot must be mounted before being used, if it has its own partition. This is a very common mistake.

Configure GRUB

The second part of making the kernel live, is to check that GRUB will boot into the newly-compiled kernel. Edit /boot/grub/menu.lst and check that it contains e.g.:

title Gentoo
root (hd0,0)
kernel /boot/kernel root=/dev/sda1

The filename /boot/kernel must match the filename of the kernel that was copied into /boot.

Emerge ALSA ebuilds

Install the ALSA headers, libraries and programs:

emerge -n alsa-headers alsa-lib alsa-utils alsa-tools

Configure alsasound service

Ensure that the alsasound service will start, in the correct runlevel:

rc-update del alsasound
rc-update add alsasound boot

Put in /etc/conf.d/alsasound

ENABLE_OSS_EMUL="yes"
RESTORE_ON_START="yes"
SAVE_ON_STOP="no"

Configure groups

Your Linux username should be in the audio group.

groups yourusername

So add it:

gpasswd -a yourusername audio

Delete old ALSA state configuration

If installing a different soundcard, then delete the old asound.state, otherwise ALSA can get confused about the mixer controls. For simplicity, delete the file from its two common locations:

rm -f /etc/asound.state /var/lib/alsa/asound.state

Check module configuration

Check that /etc/modules.autoload.d/kernel-2.6 does not contain any sound-related modules, because they are automatically loaded by /etc/init.d/alsasound

Reboot into new kernel

First, unmount /boot if it was mounted:

umount /boot

Reboot the PC, to boot into the new kernel:

reboot

Check new kernel

First check that the newly-compiled kernel is the current kernel:

uname -a

Check the exact time and date shown by uname -a, against the time and date of:

ls -l /usr/src/linux/System.map

If the times do not match exactly, then fix it. Check that /boot was mounted if it has its own partition. Check the GRUB configuration. Reboot again, and check the times again.

Check for warning/error messages:

tail -n 200 /var/log/messages
dmesg

Check that /dev/dsp exists (which is for ALSA's emulation of OSS):

$ ls -l /dev/dsp
/dev/dsp -> sound/dsp

Check that there is exactly one sound card:

cat /proc/asound/cards

Compile special modules

A minority of packages which provide kernel modules can only be compiled when the desired kernel is the currently-running kernel. Example script for /etc/init.d/local.start

if ! modprobe fuse ; then
    emerge -1 sys-fs/fuse
fi

If a new module cannot be found by modprobe after being compiled, then check that /lib/modules/`uname -r`/modules.alias has been updated, by running:

depmod -e -F /usr/src/linux/System.map

Configure volume levels

The volume levels by default will usually be muted. This is a safety feature to prevent damage to hardware from having volume levels too loud. First start some music playing:

emerge -n audacious
audacious &

The music will be silent. Configure the volume levels:

emerge -n alsa-utils
alsamixer

Press the m key to toggle mute for the volume levels that show "MM" at the bottom. Then use the up and down arrow keys to change the volume.

It is best to mute any unused channels (e.g. the microphone), to reduce the possibility of them causing interference.

To save the volume levels so that they are restored after a reboot, run as root:

alsactl -f /var/lib/alsa/asound.state store

Note that /etc/init.d/alsasound ignores /etc/asound.state

Troubleshooting

Error loading modules

"Unknown symbol", "duplicate symbol", and "invalid module format" errors usually indicate that the kernel has not been compiled properly, or is not the currently-running kernel, or the modules have not been recompiled for the current kernel. Refer to "Clean out old modules" and "Compile kernel and modules" above.

Failed to load necessary drivers

This error message is shown by the /etc/init.d/alsasound script when its initialization fails. Check for missing sound-related modules in the kernel configuration.

Could not detect custom ALSA settings

This error message is shown by the /etc/init.d/alsasound script when modprobe -c does not show any alias snd-card-* lines. Read section "Configure module options".

Nodes in /dev not created

Udev should be enabled. Check for this line in /etc/conf.d/rc

RC_DEVICES="auto"

If it needed to be changed from "static", then reboot.

/dev/mixer or /dev/dsp missing

OSS support was not included. Read sections "Configure kernel with ALSA modules" and "Configure module options".

Mixer controls are missing

If alsamixer is not showing all the expected mixer controls, then see sections "Delete old ALSA state configuration" and "ALSA module parameters".

No sound

If the soundcard seems to be set up correctly except for it remaining silent, then try toggling every option in alsamixer, especially External Amplifier and Analog/Digital Output Jack if present (these tend to be on the far right of the mixer list). Also see section "ALSA module parameters".

Check that the correct modules are being used, e.g. for Intel HDA cards:

grep HDA /usr/src/linux/.config

Sound works in one distro but not another

If sound works in only one distro (usually Ubuntu), then see what that distro does differently. The usual changes are in the ALSA sourcecode, and the options lines for sound modules (which vary in file location by distro, e.g. /etc/modprobe.conf, /etc/modules.d/alsa, /etc/modprobe.d/alsa-base).

ALSA module parameters

Some ALSA modules have options with which to tweak the configuration, which can be essential to get the soundcard properly working (example). The main documentation for this is in /usr/src/linux/Documentation/sound/alsa/ALSA-Configuration.txt, and the options can also be seen by running modinfo, e.g.:

modinfo snd-hda-intel

An example is to put in /etc/modprobe.d/alsa

options snd-hda-intel model=macbook index=0

index=0 ensures that it is the first soundcard, if there is more than one.

Then repopulate /etc/modprobe.conf and restart ALSA:

update-modules
/etc/init.d/alsasound restart

ALSA version

The version of ALSA in the currently-running kernel can be shown with:

cat /proc/asound/version

Or for the kernel in /usr/src/linux

cat /usr/src/linux/include/sound/version.h

Check that the different ALSA versions match reasonably, between the in-kernel ALSA, alsa-headers, alsa-lib, alsa-utils, and alsa-tools (if installed).

emerge -pv alsa-headers alsa-lib alsa-utils alsa-tools

Further help

First look at the Gentoo ALSA guide.

Secondly, help yourself. Do not assume that you are the first person ever to have a problem with ALSA, or that your problem is unique. Use Google to search for how other people have gotten the same hardware to work, using search terms such as "alsa", and the model/name of the motherboard, laptop, or soundcard. Re-read this article. Search on the ALSA Bugzilla. Try a more recent kernel.

Refer to the Gentoo forums in the "Multimedia" or "Kernel & Hardware" forums. Browse the many existing threads, and Google. Search the Gentoo forums using Google, by entering forums.gentoo.org into the Domain box.

If you really must post a forum message, be sure that you have tried everything in this article first. The number of useless ALSA-related threads in Linux forums is astounding, because people are too lazy to try to solve their own problems. To prevent the forum thread from being useless, use a pastebin site such as pastebin.ca for long lists of technical information, and include the output of alsa-info.log, after running this extremely useful script as root:

echo -e "\n-------------------BEGIN--------------------\n" >alsa-info.log
echo -e "\n--------------------  /boot/grub/menu.lst --------------------\n">>alsa-info.log
cat /boot/grub/menu.lst >> alsa-info.log 2>&1
echo -e "\n------------------- ls -l /boot/  -------------------\n">>alsa-info.log
ls -l /boot/ >>alsa-info.log 2>&1
echo -e "\n------------------- ls -l /usr/src -------------------\n">>alsa-info.log
ls -l /usr/src >>alsa-info.log 2>&1
echo -e "\n---------------- find /lib/modules/ -type f | xargs ls -l -------------------\n">>alsa-info.log
find /lib/modules/ -type f | xargs ls -l >>alsa-info.log 2>&1
echo -e "\n----------------- grep SND /usr/src/linux/.config | grep "=" -------------------\n">>alsa-info.log
grep SND /usr/src/linux/.config | grep "=" >>alsa-info.log 2>&1
echo -e "\n------------------- grep SOUND /usr/src/linux/.config | grep "=" ----------------\n">>alsa-info.log
grep SOUND /usr/src/linux/.config | grep "=" >>alsa-info.log 2>&1
echo -e "\n------------------- uname -a -------------------\n">>alsa-info.log
uname -a >>alsa-info.log 2>&1
echo -e "\n------------------- emerge -pv alsa-driver -------------------\n">>alsa-info.log
emerge -pv alsa-driver >>alsa-info.log 2>&1
echo -e "\n------------------- cat /etc/modprobe.d/alsa -------------------\n">>alsa-info.log
cat /etc/modprobe.d/alsa >>alsa-info.log 2>&1
echo -e "\n------------------- cat /proc/asound/cards -------------------\n">>alsa-info.log
cat /proc/asound/cards >>alsa-info.log 2>&1
echo -e "\n------------------- cat /proc/interrupts -------------------\n">>alsa-info.log
cat /proc/interrupts >>alsa-info.log 2>&1
echo -e "\n------ amixer    # emerge media-sound/alsa-utils if command not found ------\n">>alsa-info.log
amixer     >>alsa-info.log 2>&1
echo -e "\n-------- lspci -v  # emerge sys-apps/pciutils if command not found --------\n">>alsa-info.log
lspci -v   >>alsa-info.log 2>&1
echo -e "\n-------------------END---------------------\n" >>alsa-info.log

Also provide manufacturer and model names for the motherboard, PC/laptop and sound card.

Alternatives

Open Sound System

If your soundcard has problems in ALSA (often SND_HDA_INTEL), then try Open Sound System ("OSS") - install ebuild using howto guide, and see forum.

Note that OSS is also not guaranteed to work perfectly.

Completely remove sound from the kernel, first:

$ grep SND /usr/src/linux/.config | grep =
< Absolutely nothing matches >
Retrieved from "http://www.gentoo-wiki.info/HOWTO_Compile_Kernel_with_ALSA"

Last modified: Tue, 26 Aug 2008 03:32:00 +0000 Hits: 29,868