HOWTO_Compile_Kernel_with_ALSA
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:
- Advanced ALSA configuration, e.g. ~/.asoundrc
- Setting up multiple soundcards
- Details of individual soundcards
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 >
Created by NickStallman.net, Luxury Homes Australia
Real estate agents should be using interactive floor plans and real estate agent tools.
