2.6-udev hint

Ryan Reich ryanr at uchicago.edu
Sat Feb 21 00:29:12 PST 2004


Hi!  This is a totally unsolicited hint guiding the unsuspecting user through
the 2.6 installation process and the configuration of udev to manage a dynamic
/dev directory.

Ryan Reich
-------------- next part --------------
AUTHOR: Ryan Reich <ryanr at uchicago.edu>
DATE: 2004-02-21 (2 February 2004)
LICENSE: GPL

SYNOPSIS: Installing the 2.6 kernel version on an already-configured LFS
system, and getting dynamic /dev working without devfs.

DESCRIPTION: In this hint, I will explain how to turn your plain ol' LFS
system into a shiny new Linux-2.6 LFS system, without doing a whole lot of
recompiling.  There are, of course, downsides to this, but I haven't noticed
any with ordinary desktop use.  The main reason I wrote this, though, was to
describe how to use udev/sysfs as a replacement for devfsd/devfs, since I
find the documentation available to be a little lacking.

PREREQUISITES: You need to get the following:
	Linux-2.6.*:
		The current 2.6 kernel, located at
		http://www.kernel.org/pub/linux/kernel/v2.6/
		Grab the newest one.

	Module-init-tools:
		This package replaces modutils since the module format changed in
		2.6.  Find it at:
		http://www.kernel.org/pub/linux/utils/kernel/module-init-tools/
		Grab the latest stable version.  You're living enough on the edge
		using 2.6 without getting beta software as well.

	Udev:
		The userspace daemon which handles /dev dynamically, which devfs
		also did once upon a time, before it was deprecated.  It's at:
		http://www.kernel.org/pub/linux/utils/kernel/hotplug/
		This thing is still under development, but the recent versions
		work fine and if something doesn't work, it's probably a sysfs
		problem.  Just get the latest release.

	Hotplug scripts:
		Located in the same directory as udev.  Udev relies upon hotplug
		to do its work, so you need these.

HINT: Here goes.  The first thing you need to do is upgrade your module
utilities.  In particular, you want to be really careful that you don't
overwrite your old ones so that, in the very likely event you need to boot
back into 2.4 because something in 2.6 doesn't work right the first time, you
can still actually do this.  Hence the somewhat extended build process:

tar xjvf module-init-tools-*.tar.bz2 [ Or xzvf, if you prefer .tar.gz ]
cd module-init-tools-*/
./configure --prefix=/
make moveold
make
make install
./generate-modprobe.conf /etc/modprobe.conf

Command explanations:
./configure --prefix=/
	Unlike almost everything else in LFS, this is a system utility required
	at boot and must reside in /sbin.

make moveold
	This copies modprobe, insmod, rmmod, and depmod to *.old (it also does
	this for the man pages).  This way, the new modprobe will check first
	to see your kernel version; if you are using 2.4, it calls the .old
	modprobe instead of proceeding itself.  Hence no hassle.

./generate-modprobe.conf /etc/modprobe.conf
	module-init-tools has a much different system for the modules
	configuration file than did modutils, and correspondingly it is kind
	enough to give you a new file.  It will even incorporate definitions
	you made in your old modules.conf, which it will of course leave where
	it was so that modprobe.old can find it if necessary.

Configuration: Reading the man page for modprobe and modprobe.conf is
recommended, but the gist of the changes is that all those confusing and
complicated aboves and belows and whatnot that went in modules.conf have been
replaced with but two commands: install and remove.  alias still exists, of
course.  The following are thus equivalent (for example):
	below snd-intel8x0 snd-pcm-oss (modules.conf)
	install snd-intel8x0 /sbin/modprobe snd-pcm-oss; /sbin/modprobe \
		--ignore-install snd-intel8x0 (modprobe.conf)
This means that if you execute `modprobe snd-intel8x0` in 2.6, modprobe will
literally run the sequence `modprobe snd-pcm-oss; modprobe snd-intel8x0`.
The --ignore-install means to ignore the line in the config file when running
the second modprobe, for of course to do otherwise would result in an endless
loop.  remove works similarly; in general, this syntax is infinitely
extensible.

Now to compile a new kernel.  The developers really spent a lot of time
improving even the build procedure in 2.6, so that numerous conveniences have
been introduced.  For one, it will try to interpret the .config of your
current kernel, if it's located in /boot/config-`uname -r` (i.e.
/boot/config-2.4.22 if you are running linux-2.4.22).  For two, there are now
two GUI config interfaces, xconfig and gconfig, using qt and gtk,
respectively.  You should do:

tar xjvf linux-2.6.*.tar.bz2 [ or z, as above ]
cd linux-2.6.*/
make mrproper
make *config
make
make modules_install
cp arch/$(ARCH)/boot/bzImage /boot/<whatever>
cp System.map /boot/<whatever else>

Command Explanations:
make mrproper:
	Always make mrproper the first time you use a tree.  You never know
	what might have snuck in.

make *config:
	I like xconfig, personally, but then, I use KDE also.  Draw your own
	conclusions.  When configuring, do a very careful run-through because
	the options have changed dramatically from 2.4.  The CPU selection is
	different, for example, and you really don't want the kernel compiled
	for the wrong CPU.

	Another thing to watch out for is CONFIG_HOTPLUG.  It's in Bus options,
	near the top of the base config menu.  If you don't have this, the
	hotplug scripts are useless and you can't use udev.

	Finally, read the post-halloween docs at
	http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt
	to get incredibly detailed information on what changed from 2.4.
	Really.  Do this.

make:
	What?  Did you say I forgot make dep?  No, I didn't; it got cut.  You
	don't have to specify bzImage either, since presumably zImage is going
	the way of the dodo soon.  Just `make` will do.  Oh, and they recommend
	you use gcc-2.95.3 to compile; the instructions for this are in the
	BLFS book, so if you want to use this compiler, just specify
	`make CC=/opt/gcc2/bin/gcc` (path is as given in BLFS).

cp <stuff> <places>
	Call the image and System.map whatever you like, so long as System.map
	is called System.map-2.6.*.  Yes, now the kernel supports VERSIONED map
	files, so that you don't have to switch stuff around every time you
	boot into a different-version kernel.  Just append the version to which
	System.map corresponds to the name and the kernel will find it at boot.

	There is also a `make install` target that will call
	/sbin/installkernel or ~/bin/installkernel if they exist; however, I
	have not used this option so you're on your own here.

You could do the rest in 2.4, but since udev won't work without sysfs, you
may as well reboot.  If you are following strict LFS, you may not have a
script to update your modules.dep file on boot, in which case the kernel will
complain mightily when you boot.  Therefore you should run

depmod -Ae -F /boot/System.map-2.6.* 2.6.*

substituting of course the correct numbers in for whichever 2.6 kernel you
just compiled.

You may also wish to update your init scripts to mount sysfs.  Since it's
similar to proc, it's easy enough to append it to the mountproc script: just
stick

mount -t sysfs sysfs /sys
evaluate_retval

in there.  Make sure /sys exists, of course.  If you are worried about
getting error messages on booting into 2.4 and trying to mount the
there-nonexistent sysfs, you can put a check

if ! grep 'sysfs' /proc/filesystems; then exit 0; fi

before the above lines.  Of course, then you have to put all this AFTER you
mount /proc.

The /sys filesystem exports various device-related data; in fact, it exports
so much it's impossible to figure out what to do with it all.  Some of it is
useful for configuring udev to correctly identify unusual or transient
devices, like USB thingies.  It's new, though, so I am not sure if anything
else uses it aside from udev.

Anyway, now you're running 2.6.  The hotplug scripts are easy to install:

make install

They're just shell scripts, after all.  The README has other suggestions that
are not strictly necessary.  One of the scripts installed is a boot script,
placed in /etc/rc.d/init.d/hotplug, which you may wish to run at boot.
Sadly, their script is not LFS-style and is quite hard to make LFS-style, so
you won't get any nice colored notifications when it runs.  Put it somewhere
at the beginning of the runlevel queue.

And finally, we have udev.  There's no configure script, so make takes a few
extra variables.  Strictly speaking, this could also be done by editing the
makefile in the appropriate places.

tar xjvf udev-*.tar.bz2
cd udev-*/
mv etc/init.d/udev etc/init.d/udev.default
mv etc/init.d/udev.init.lfs etc/init.d/udev
make USE_LOG=false DEBUG=false USE_KLIBC=true initdir=/etc/rc.d/init.d \
	udevdir=/dev
make install

Command Explanations:
mv <stuff> <places>
	udev comes with three init scripts; one of them is LFS-style, since
	some saintly soul provided them with one.  However, it's not installed
	by default, so we just shuffle things around so that it is.

make ...
	These options are up to you.  If USE_LOG is true you get a syslog
	message for every single device udev creates, which is tedious.  Only
	use DEBUG if you are, well, debugging.  USE_KLIBC controls whether udev
	is linked against the C library included in the package or glibc; it is
	recommended to use klibc because it's optimized for size and kernel
	work.  initdir directs make to install the init script in the right
	place, and udevdir is where udev puts its devices.

Configuration:
	This is the fun part.  Configuring udev itself is an exercise best left
	to the reader; the man page is actually pretty helpful.  Configuration
	in this case means telling udev what to name which devices and what
	permissions to give them; the work is figuring out which device you are
	trying to name.  The information you use is drawn from sysfs; in
	addition, pciutils and usbutils are quite helpful (they aren't given in
	the BLFS book, however).

	However, you do not want the devices in /dev to disappear entirely on
	boot, since they are necessary in the interval before udev runs.  And,
	of course, you might go back to 2.4 sometime.  Therefore we are going
	to mount a RAM-based filesystem on /dev in a manner similar to devfs so
	that the old files are hidden rather than deleted (obviously this is
	unsatisfactory for people worried about space, but a full /dev takes up
	maybe 100k, tops, so you aren't one of these people if you aren't
	running an embedded system).  The ramfs will get mounted at boot,
	populated by the udev init script, and then vanish on reboot.

	To make things work properly, you want the udev boot script to run
	early, but not too early.  I suggest right after mountfs runs, becuase
	the script uses utilities located on /usr, which may be a separate
	partition.  To get the ramfs thing going, you need only add the
	following five lines to the script:

		mount -t ramfs /dev/ram0 /dev
		ACTION=add DEVPATH=/class/mem/null $bin mem/null
		mkdir /dev/{pts,shm}
		mount /dev/pts
		mount /dev/shm

	The first one is really all you need, technically.  However, you will
	run into extremely annoying messages about the absence of /dev/null if
	you try to run the rest of the script with only that, so we create that
	file specially.  You could also use mknod, but it is a udev script.
	The last three lines take care of the devpts and shm filesystems, which
	are absolutely necessary (they are included in LFS-5.0).

Finally, in the continuing spirit of backwards-compatibility, if you
currently use devfs you have more work.  Obviously you can't mount both devfs
and ramfs on /dev and expect both to work, and anyway, udev replaces devfs.
I suggest, therefore, that in configuring the kernel way back above, you make
sure to disable devfs entirely.  Then, modify your devfs boot script:

mount -t devfs devfs /dev || exit 0

Thus, if devfs is not supported by the kernel (like it is not in your 2.6
kernel), the script will quit without mounting it and without giving an
error.

That's it!  Hopefully your system boots without too much complaining.

CHANGELOG:
[2004-02-21]
* Created the hint.


More information about the hints mailing list