Self-Hosting Movies with MoviX
The exploitation of Linux potentialities on x86 platforms increased quite a lot in the last few years, but an entire field of applications seems to me to be extremely underdeveloped. I am referring to dedicated CD mini-distributions, namely Linux distributions that live on a CD, contain exactly the software needed to run some particular application and automatically start that application at the boot. That is, they use Linux only to provide us a background from which to run some application directly from CD.
Let me provide a concrete example. Suppose you keep your favorite audio/video files on CD in several formats, such as DivX, XviD, MP3, OggVorbis and so on. Typically, when you try to play your files on a PC different from your own, one of the following happens: the machine has no HD; no player on that machine is able to play your audio/video format; the codec you need is not installed; or everything is there, but the playback quality is poor even though you know with the hardware playback should be pretty decent.
Now, suppose that together with your files you also burned on the CD a minimal Linux system that is able to boot directly from CD. It would start automatically and play all of the CD files. This way the CD would be “self-sufficient”, you wouldn't have to worry about any codec hassle, and you could be pretty sure that all PC resources are devoted only to the playback. Actually, you even would be able to play your files on a diskless PC. And, of course, you could still play all CD files from your favorite OS when you want to do so.
As you might imagine, such a philosophy is not limited to audio/video playback. You can create dedicated Linux mini-distributions for basically any application, including gaming, text processing, multimedia editing, network broadcasting and so on.
Let me point out the main advantages of such mini-distributions:
No wasted HD space.
Ready to run every time you need it.
Runs even on a diskless PC.
Runs even where Linux is not present, helping Linux diffusion.
This idea of “live” CD distributions is not new. Many good examples of both big (DemoLinux, Knoppix) and small (LNX-BBC, Devil-Linux) distributions are available, especially those that are routering and firewalling oriented. But, I could find very few examples of such dedicated ones (see Resources).
In particular, a few months ago I looked on the Net for a Linux CD mini-distribution that is able to boot and play automatically all audio/video files on the CD. I was very surprised to find none. Therefore, my only chance to get one was to develop it myself, and so I started working on MoviX. Now, I am not a Linux guru and I know close to zero about multimedia playback, but the beauty of open source is you can put together tools developed by people who know much more than you and still create something new and useful. I put together my knowledge of Slackware management (I've been fond of Slackware since 1994) and the MPlayer (“the” multimedia player) and IsoLinux (an easy-to-use Linux CD bootloader) package I had recently found out on the Net and began building my distribution.
Initially MoviX consisted in a single Linux CD micro-distribution, but after a lot of feedback and requests from MoviX users, the project split into three different packages, as follows:
eMoviX: a CD Linux micro-distribution (~7MB) meant to be embedded in a CD together with audio/video files that is able to boot and play automatically all CD files.
MoviX: a CD Linux mini-distribution (~15MB) able to boot and launch a console interface to MPlayer.
MoviX2: a Linux mini-distribution (~30MB) containing a full installation of XFree86 4.2.0 and able to boot and launch gmplayer, the MPlayer GUI.
If you use MoviX or MoviX2, after the boot you can get rid of the boot CD and use the interface to play most audio/video CD/DVDs. In short, while eMoviX makes your CD self-sufficient, MoviX and MoviX2 are some kind of “Swiss Army Knife of multimedia”, able to make any PC a powerful multimedia station. And because MPlayer is such a good piece of software, you can achieve good playback even on a P200MMX.
The point I want to make in this article is that developing this kind of dedicated mini-distributions is not hard once you have a few guidelines. I hope to encourage the development of more such distributions by describing below the main steps I followed to build the MoviX packages. The only thing I assume is you are accustomed to kernel/modules configuration and compilation.
First of all, make sure your kernel is compiled with support for the RAM disk and loopback device, because you are going to use these features. It is cleaner to keep your PC kernel tree separated from the one used for the distribution. So get the latest stable kernel (2.4.20 at the time of this writing), and unpack it in a directory different from your main kernel directory.
The kernel configuration defaults are close to the ones we need. Once you are in the distribution kernel directory, run make menuconfig and add support for the following items:
Code maturity level options ---> Prompt for development and/or incomplete code/drivers
Processor type and features ---> Processor family: [choose Pentium-MMX]
Block device ---> Loopback device support
Block device ---> RAM disk support
Block device ---> Initial RAM disk (initrd) support
File systems ---> /dev file system support [select the “Automatically mount at boot” option]
Then run make bzImage to produce the kernel binary.
The initrd file (init Ram Disc) contains the root filesystem of the distribution. Our first initrd should contain only the system files; therefore, 5MB will be enough. To create it, we make use of the RAM discs:
dd if=/dev/zero of=/dev/ram0 bs=1k count=5000 mke2fs -m0 /dev/ram0 5000 mount /dev/ram0 /distro
The de facto standard for small distributions is the Busybox binary (the “Swiss Army Knife of Embedded Linux”) in place of the scores of small binaries we need.
Compilation instructions are pretty easy and well documented, but you also may want to take a look at Bruce Perens' Busybox articles in Embedded Linux Journal (see Resources). I suggest you compile it with support for all possible commands because, eventually, you are going to need most of them. Remember to install Busybox with ./install.sh /distro, so all links for all commands supported by your copy of Busybox automatically are created in /distro.
Binaries usually are linked dynamically to system libraries. It is possible to compile Busybox statically to save space. But, we are going to add more complex binaries to the distribution, so eventually we'll have to add dynamical libraries anyway. To add the libraries for a binary, say Busybox, the rule is always the same:
get the list of libraries linked to it:
root# ldd busybox libc.so.6 => /lib/libc.so.6 (0x40028000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
copy all of them ton /distro/lib/.
A trick to minimize libraries size is getting rid of all the debug stuff they contain:
objcopy --strip-debug /lib/libc.so.6 /distro/lib/libc.so.6
To complete the work we need to add a few configuration scripts: /distro/etc/inittab, /distro/etc/rc.d/rc.S, /distro/etc/fstab, /distro/etc/shells and /distro/etc/profile. We also need to create a few directories: /distro/dev, /distro/mnt, distro/proc, /distro/root and /distro/tmp. We don't need to create any device node in /distro/dev, because the devfs dæmon automatically creates all devices at boot time.
Finally we can create the initrd file:
umount /dev/ram0 dd if=/dev/ram0 of=initrd bs=1k count=5000
To check that everything is okay, you can mount the initrd file and take a look inside:
mount initrd /distro -o loop ls -lR /distro
Then remember to umount it and gzip it.
Before burning a CD, it is a good idea to test the initrd image by booting it from LILO. Create an /initrd directory in your system, put bzImage and initrd.gz there, rename bzImage as vmlinuz and add the lines in Listing 1 to lilo.conf.
At this point run LILO, reboot and choose the “Distro” label at the LILO prompt to boot with your new distribution.
To create a bootable CD containing the kernel and filesystem created above, you need a boot image. The most convenient choice you can make is the IsoLinux boot image, called isolinux.bin and part of the SysLinux package, so your system is able to load the initrd.gz no matter what its size.
Begin by creating a new directory, say /cdrom. Then, create a /cdrom/isolinux/kernel directory; put the initrd.gz and isolinux.bin files in /isolinux and the kernel in isolinux/kernel. Finally, inside /isolinux edit a isolinux.cfg file to tell the boot loader the boot options you want to use (see Listing 2).
The format of this file is similar to the lilo.conf format; consult the SysLinux web site for detailed information. A nice improvement is the possibility of calling up to 10 text files from the boot prompt, using the F1-F10 keys. That is, there is a way to make the user able to access documentation about boot parameters right at boot time, directly from the CD. For the type of distribution we are talking about, this is a useful feature. Another nice feature is the capability to visualize pictures rather than text, for example, making it possible to add a “splash” boot logo to the distribution (16 colors at most; otherwise, try the BootScriptor package).
To produce a bootable CD image, run mkisofs with the following options:
mkisofs -o /tmp/distro.iso -r -V "My distro" -v -no-emul-boot \ -boot-load-size 4 -boot-info-table -b isolinux/isolinux.bin \ -c isolinux/isolinux.boot /cdrom
Then, burn the image:
cdrecord dev=0,0 -v -eject /tmp/distro.iso
Now you can reboot the system to be sure the burning was successful and the CD is really bootable.
As is, this CD already is a pretty good hardware checking tool, and it easily can be turned into a good recovery tool. Indeed, simply by booting from it, you can find out the brand and model of most PC hardware (everything except ISA cards) by looking at /proc/pci and /proc/cpuinfo. By taking a look at the kernel boot log with dmesg, you also may find information on the P&P ISA cards. Adding to it binaries such as e2fsck, you have all the tools necessary to recovery a Linux system experiencing problems.
On the other hand, no card is supported by the system at this point—no NIC, no audio card, no SCSI card, nothing. Although this probably is okay for a rescue CD, it most likely is not okay for our mini-distribution.
The standard way of activating kernel hardware support is to use kernel modules, but simply loading all possible modules is not a good idea. You need some autodetection tool. Several autodetection tools have been developed by big Linux distributions: kudzu (Red Hat), libdetect (Mandrake, but now they use kudzu too), discover (Progeny). But these seem much too complex for the kind of small distribution we are building.
Luckily, you can base a simple autodetection procedure on the devfs. Indeed, its automatic creation of device nodes can be used as an effective way of checking whether some device has been recognized by the kernel. For example, the device node /dev/sound/dsp automatically is created only when you load the right module for your audio card. So, you can easily write a script that loads, one by one, every single audio module and verifies every time whether the audio device appeared. If it did, then you successfully loaded the driver and can stop the loop; otherwise, you can unload the module and go on. See Listing 3 for a simple Perl example.
Hence, our method of autodetecting some kind of card, say the audio one, follows this path:
go back to the distribution kernel directory and activate the support for all possible audio cards as modules;
compile all modules with make modules
install the modules on your system with make modules_install (to avoid overwriting the “true” modules directory, make sure you rename it before installing the distribution's);
re-mount the initrd.gz file on /distro (remember to gunzip it before mounting it or it won't work);
copy the newly created directory /lib/modules/2.4.20 to /distro/lib/modules/; if the space left is smaller than ~.5MB, build a new initrd, as explained above, and assign to it more space;
add some script to load all possible modules and add a line to call it in rc.S
I don't have enough data to tell you whether this method is always reliable, but I've been using it in all MoviX packages for four months. Thus far, I have received no negative feedback, so at least I can tell you it is not totally unreliable.
Repeating this procedure for every kind of driver you need, you can easily build a script able to autodetect all hardware supported by Linux on any PC. You can find working examples of such scripts in each MoviX package.
Once all necessary hardware drivers are loaded, any application making use only of the console can be installed easily in the distribution. Both eMoviX and MoviX are based exactly on this principle, because the package MPlayer is able to play audio and video files without X.
If we assume, as it happens in most of cases, the package we want to include in our distribution makes use of the autoconf/automake mechanism, then the easiest way to add the package is to do something like the following:
./configure --prefix=/usr/local/mplayer [further options] make make install
In this case, to transfer the installation to the distribution it is enough to do as follows:
re-mount the inird in /distro
copy the package in /distro: cp -a /usr/local/mplayer/ /distro/usr/local/
add to /distro/lib/ all missing libraries linked to all binaries in /usr/local/mplayer/bin/;
add the /usr/local/mplayer/bin/ path to the PATH variable in profile: PATH=$PATH:/usr/local/mplayer/bin/
add a line to rc.S to create a software link in the distro /lib to all libraries in /usr/local/mplayer/lib/ with ln -s /usr/local/mplayer/lib/* /distro/lib/
unmount and gzip back the initrd.
Following these directions for the application mp3blaster, you easily could produce a mini-distribution able to boot and play automatically every MP3 or Ogg Vorbis audio file—a distribution endowed with a nice console interface (the native mp3blaster one). This would ensure that users are able to play their favorite Vorbis files on any PC (at least as long as its audio card is supported by Linux), regardless of which OS is installed and without having to install any plugin.
A lot of applications need X in order to work. Unfortunately, the XFree package tends to be pretty big (~80MB), which is bad when you need to load everything in RAM to make the CD/DVD drive back available.
Several projects are available whose goal or byproduct is small-sized versions of X, including DirectFB or smallX, but none of them gets close to the hardware support level offered by the latest XFree86 full versions. If you plan to make use of such capabilities for the largest number of cards possible, the best solution is to use the full XFree86 package after removing as many unnecessary component as possible.
Luckily enough, almost half of the XFree86 package is occupied by fonts. As the distribution you are building is going to run only a few applications, you easily can reduce the package size to around 40MB once you identify the few fonts actually used. Getting rid of unnecessary binaries and libraries can bring the package size down to around 30MB.
Of course, you also need to produce a working XF86Config file “on the fly”, either generating it from X itself—using the X -configure command and tweaking it a little (you need at least to set the number of colors and your favorite screen resolution)--or creating a sort of template. In the template method, you would write a script that is able to detect the video card and then set the right parameters corresponding to it.
In both cases it is a good idea to have a tool able to detect the most important data of the monitor, namely the horizontal sync and the vertical refresh frequencies ranges. It is especially helpful if it warn us when the monitor is not able to provide this data, so we can provide standard frequencies instead. A good tool for this is the program ddcxinfo, part of the kudzu package, that returns the ranges we need with ddcxinfo -hsync and ddcxinfo -vsync, respectively. When the information is not available, it simply returns 0-0.
Finally, let me point out that you most likely won't need a window manager, because you are going to run only one application. This is the case for MoviX2. In case you need one, you should try a tiny manager, such as Matchbox.
I hope this article helps increase the number of such dedicated distributions. Their development does not require highly technical skills, only a good acquaintance with the management of a Linux system. Moreover, it is an effective way to increase significantly your knowledge of Linux and the application you're including, thanks to the users feedback.
Let me conclude by thanking all developers whose projects I used for making them open source, because the MoviX project would not have been possible otherwise. Thank you also to all the people whose feedback significantly increased my knowledge of Linux and MPlayer.
Kernel Docs: www.tldp.org/HOWTO/Kernel-HOWTO.html
Bruce Perens first ELJ BusyBox article: linuxjournal.com/article/4335
Live CD distributions
Dedicated CD Distributions
Byzantine OS: byzgl.sf.net
Roberto De Leo received a PhD in Physics from the University of Cagliari and one in Math from UMD. He teaches at Alberti High School, where in 1994, he built the first italian school web site using a Slackware box. When he's not doing research, teaching or taking care of Alberti's Linux boxes, he likes to hack with his own Linux box.