conradus@iname.com
This is a build guide for a custom MP3 box, which has no harddrive, floppy, or video card and boots from the network. It also fetches the songs from the network. It is intended as template, quick reference, and a template to building a custom MP3 box. Frequently asked questions related to MP3 box building, its usage, problems, and references are given.
Much of this information came from authors private ideas and source files covered under GNU licenses. Huge thanks goes to Tom Jones (for helping me design the box), Ryan Defelic (for his MP3 box being a alpha-prototype), Steve Maroney (for asking me many questions), the LRP project, and of course The Penguin (which sits on his shrine next to my network closet :=) )
Copyright (c) 2001 by Konrad Rzeszutek
Please freely copy and distribute (sell or give away) this document in any format. It's requested that corrections and/or comments be forwarded to the document maintainer. You may create a derivative work and distribute it provided that you:
If you're considering making a derived work other than a translation, it's requested that you discuss your plans with the current maintainer.
I rely on you, the reader, to make this HOWTO useful. If you have any questions, corrections, or comments, please send them to me, conradus@iname.com, and I will try to incorporate them in the next revision.
The sole and only reason why you, the reader, is engulfing yourself in reading this material along with a nice warm container full with java, is so that you:
Its important to keep certain things in mind:
The idea behind this box is to separate tasks - the MP3-box can only play the mp3's from a server, while you, the reader, can freely add more files to your big-end server. Thus, the MPEG-box wouldn't need a harddrive, nor floppy drive. It would boot the operating system from the network (from the same server where the mp3 files are located).
The software running the decoding process (mpg123) can happily work on a 486DX/66 or higher without any constraints. 16MB of RAM ought to do fine as well. Any sound card that is supported under Linux should work. The following list includes all the hardware I used:
Before you proceed with installing the server-software, it would be beneficial to review the following HOWTO's (in the listed order):
Particularly, the Diskless-HOWTO contains a wealth of information useful for this project.
The required software are mostly already installed on a stock Linux distribution, but some might be missing. The ones that are usually not found (dhcpd, pxe, etc) are included in the mpeg-box-project.tgz file.
I presume you have read the NFS-HOWTO . If you haven't, do yourself a favor and pick it up. Most of these information are straight from that HOWTO.
Before you start setting NFS, make sure you have nfs-utils or nfs-server package installed. If you don't have them, the dhcpd-2.0pl2 source code is included in the mpeg-box-project.tgz file.
tar -zxvf mpeg-box-project.tgz
cd "1st Step - configuring server/01 - dhcp"
./configure make make install
Setting up the server will be done in two steps: Setting up the configuration files for NFS, and then starting the NFS services.
There are three main configuration files you will need to edit to set up an NFS server: /etc/exports, /etc/hosts.allow, and /etc/hosts.deny. Strictly speaking, you only need to edit /etc/exports to get NFS to work, but you would be left with an extremely insecure setup. You may also need to edit your startup scripts.
This file contains a list of entries; each entry indicates a volume that is shared and how it is shared. Check the man pages (man exports) for a complete description of all the setup options for the file, although the description here will probably satisfy most people's needs.
An entry in /etc/exports will typically look like this:
directory machine1(option11,option12) machine2(option21,option22)
where
the directory that you want to share. It may be an entire volume though it need not be. If you share a directory, then all directories under it within the same file system will be shared as well. For example it might be: /exports
client machines that will have access to the directory. The machines may be listed by their IP address or their DNS address (e.g., machine.company.com or 192.168.0.8). Using IP addresses is more reliable and more secure.
the option listing for each machine will describe what kind of access that machine will have. Important options are:
For our MP3-box, we just need to read-only access to the directory with mp3's. Suppose the MP3-box IP will be 10.0.0.8 and the directory with our music files is /exports/media. The /etc/exports would look like this:
/exports/media 10.0.0.8(ro)
These two files specify which computers on the network can use services on your machine. Each line of the file is an entry listing a service and a set of machines. When the server gets a request from a machine, it does the following:
In general, it is a good idea with NFS (as with most internet services) to explicitly deny access to hosts that you don't need to allow access to.
The first step in doing this is to add the following entry to /etc/hosts.deny:
portmap:ALL
Next, we need to add an entry to hosts.allow to give any hosts access that we want to have access. (If we just leave the above lines in hosts.deny then nobody will have access to NFS.) Entries in hosts.allow follow the format:
service: host [or network/netmask] , host [or network/netmask]
Here, host is IP address of a potential client; it may be possible in some
versions to use the DNS name of the host, but it is strongly deprecated.
Suppose we have the setup above and we just want to allow access to huh.com and arakis.dune.com, and suppose that the IP addresses of these machines are 10.0.0.8 and.10.0.0.1, respectively. We could add the following entry to /etc/hosts.allow:
portmap: 10.0.0.8, 10.0.0.1
For recent nfs-utils versions, we would also add the following (again, these
entries are harmless even if they are not supported):
lockd: 10.0.0.8, 10.0.0.1
rquotad: 10.0.0.8, 10.0.0.1
mountd: 10.0.0.8, 10.0.0.1
statd: 10.0.0.8, 10.0.0.1
The shell scripts which start the NFS server are usually in /etc/init.d or /etc/rc.d. Depending on your Linux distribution, you either need to run: netconfig, setup (RedHat) ; YaSt2(SuSe); turbo-config (TurboLinux); or you are stuck editing /etc/init.d/nfs-server files manually. If you run those programs, look for options that list NFS or nfs-serveR and start those services.
DHCP (Dynamic Host Configuration Protocol) is a protocol for computers to find out their IP address, gateway settings, netmask, and a lot more. Its a quite nice off-load for the system administrator. The reason why you want to use it is because when the MP3-box comes up, as said before, it doesn't have a harddrive, nor floppy drive - therefore it can't boot an operating system. But with a card that supports PXE, the following happens:
Setting up the DHCP daemon is a two stage process - installing the binaries, and setting up the configuration file for DHCP.
The version of DHCP I'm using comes from Internet Software Consortium, the version is 2.0. You might already have the binaries installed, if that's the case - skip this section.
The source code is 1st Step - configuring server/01 - dhcpd/dhcp-2.0pl2, go into that directory and issue the following commands:
./configure make make install
The shell scripts which start the DHCP server are usually in /etc/init.d or /etc/rc.d. Depending on your Linux distribution, you either need to run: netconfig, setup (RedHat) ; YaSt2(SuSe); turbo-config (TurboLinux); or you are stuck editing /etc/init.d/dhcpd files manually.
The most important part of the /etc/dhcpd.conf file are the option fields and the host field. For the v2.0 of ISC-dhcpd its necessary to specify
option dhcp-class-identifier "PXEClient";
option vendor-encapsulated-options ff;
This will enable the DHCP server to recognize the network cards with PXE as valid. Make sure you also have the host section filled out. For example, for the MP3-box called swallow.eoh the host entry would look like:
host swallow {
hardware ethernet 00:90:27:c1:dc:db;
fixed-address swallow.eoh;
}
This is allow the DHCP server to give the box with that MAC address (which the network card displays during boot-up), the IP address associated with the host swallow. How is the host associated with 10.0.0.8 - that's the job of DNS server (which you hopefully have installed). If you don't have DNS, you can use flat-host resolution and add into /etc/hosts the following line (replace the 00:90:27. .. with your MAC address):
10.0.0.8 swallow.eoh swallow
Back to the program ...
Following is my /etc/dhcpd.conf file:
option domain-name "eoh";
option dhcp-class-identifier "PXEClient";
option vendor-encapsulated-options ff;
option subnet-mask 255.255.255.0;
default-lease-time 600;
max-lease-time 7200;
subnet 10.0.0.0 netmask 255.255.255.0 {
range 10.0.0.20 10.0.0.40;
}
host swallow {
hardware ethernet 00:90:27:c1:dc:db;
fixed-address swallow.eoh;
}
You can check your DHCP server by booting up a Windows workstation, and change its IP address to Obtain an IP address automatically.
PXE is standard for remote booting. The following information is taken from 1st Step - configuring server/02 - pxe/pxe-README:
PXE is an extension to DHCP and also method of remotely booting. The specs for PXE can be found at ftp://download.intel.com/ial/wfm/pxespec.pdf. The PXE daemon provides two capabilities: proxyDHCP and PXE Bootserver. The PXE daemon can be set up to provide either or obth of the capabilities. Both capabilities are required.
proxyDHCP works in parallel with DHCP and provides the booting client with a remote boot configuration options. ProxyDHCP provides the PXE client(s) with the following information: remote boot prompt with optional timeout, remote boot menu and PXE Bootserver discovery options.
The PXE Bootserver is a capability provided by the PXE daemon. The PXE Bootserver is the capability that provides the booting client with boot images for a particular boot environment.
PXE Bootserver serves up requested NBPs (Network Boot Programs) to PXE clients. PXE Clients locate PXE Bootservers using discovery information provided to the client by proxyDHCP. The discovery method used by the PXE client (multicast, broadcast or unicast) and the list of available bootserver types is controlled by proxyDHCP. PXE Bootservers always listen for all three types of discovery requests and will respond to all valid requests.
If you have RedHat or SuSE, pxe is available as an RPM - download it and install it. Unfortunately, you are still going to need the sources - you will have to recompile the NBP (Network Boot Program).
All the paths mentioned below refer to the contents of the mpeg-box-project.tgz file, which has all the source files and configuration files listed below.
The source file for PXE server are located in
1st Step - configuring server/02 - pxe/pxe/pxe-linux/server.
If you don't have PXE installed, just run: make and make install. The files will be installed in /usr/local. After that you should copy the 1st Step - configuring server/02 - pxe/pxe/pxe.init file to /etc/rc.d or /etc/init.d. After that go into your /etc/rc2.d and link /etc/init.d/pxe.init file to S99pxe. The command is:
ln -s ../init.d/pxe.init S99pxeIf you have no clue what I'm talking about, just enter
pxethat will start the PXE daemon (but do that after you have read the next section)
To get the PXE daemon completely working, its necessary to setup a couple of configuration files/directories.
mtftp dgram udp wait root /usr/sbin/tcpd in.mtftpd /tftpboot
tftp dgram udp wait nobody /usr/sbin/tcpd in.tftpd
mtftp 1759/udp
pxe 67/udp
pxe 4011/udp
This will your life a little simpler when you are going to debug network problems.
mkdir -p /tftpboot/X86PC/UNDI/BStrap
mkdir -p /tftpboot/X86PC/UNDI/linux-install
The copy the bstrap.0 file (which is located in
1st Step - configuring server/02 - pxe/pxe/pxe-linux/server/services into /tftpboot/X86PC/UNDI/BStrap. Do the same thing for linux.0, but copy it into /tftpboot/X86PC/UNDI/linux-install. If you don't like any of these patchs, modify the /etc/pxe.conf, /etc/mtftpd.conf accordingly.After all these steps, make sure you have a DHCP daemon running and working (look in the section about DHCP to find out how). Start the pxe daemon by typing
pxeThe debug information for PXE is piped into /PxeServiceLog.txt. To turn this debug-feature off, edit the /etc/pxe.conf - search for DebugOutToFile.
Turn on your system with a network card that supports PXE. You should see the card getting an IP from the DHCP server, and then showing up a menu. If that's the case, you have successfully configured the server system, and its time to get configure the Linux kernel and initrd file for the MP3-box in the next section.
The name of this section is rather misleading - since we are booting the system remotly, all the software is not located on the client, but rather on the server. The software, which includes the Linux kernel and a small Linux distribution is under 2MB of space. It could probably be squished into 1.44MB (so that it would fit onto a floppy) but its more fun to remotly boot the MP3-box, and not use floppies. The Linux kernel used was 2.2.16. Any versions can be used. The mini-distribution used is LRP - it normally fits on a 1.44 floppy compressed. The only thing that was left from the original mini-distribution is the binaries - the rest was changed by me.
Making a new kernel for the MP3-box is a necessity. Your sound card will inevitable different than mine, and you might have a different network card.
The Linux kernel tree that I used is supplied. Look in:
2nd Step - configuring client/01 - linux kernel/linux-2.2.16
and type:
cd "2nd Step - configuring client/01 - linux kernel/linux-2.2.16" make menuconfigand choose the right drivers. If you want to use my startup scripts for the mini-linux distribution, make all the drivers modularized (network, filesystem, sound card).
After successfully choosing your drivers, make the kernel. Copy your new kernel 2nd Step - configuring client/01 - linux kernel/linux-2.2.16/arch/i386/boot/bzImage into your tftpboot directory as linux.1 (not as linux.0!)
cd "2nd Step - configuring client/01 - linux kernel/linux-2.2.16" make bzImage cp arch/i386/boot/bzImage /tftpboot/X86PC/UNDI/linux-install
Presumably, you configured your network, sound drivers as modules. It will be necessary to compile them and put them in temporary directory (until you get the mini-distribution setup). To compile and install in temporary directory do:
export INSTALL_MOD_PATH=/tmp make modules;make modules_installThe modules for the kernel will be located in /tmp/lib/modules/2.2.16. Remember that path.
We need to make a filesystem that the Network Boot Program can download from the server, and pass to the kernel. The maximum size of such filesystem is limited to the amount of memory in the machine, but generally it shouldn't be bigger than 4MB.
Since we want to boot the MP3-box from the network, and have no media storage device on the MP3-box, the filesystem cannot be on a harddrive, floppy drive, nor ZIP drive. Linux provides a facility for that called Initial RAM Disk (initrd) - its a file, which actually is a ext2 filesystem embedded in a file.
To understand why we need to create a INITial Ram Disk filesystem, its necessary to understand how Linux boots up.
For more info, man initrd.
The initrd - is a initial ram disk embedded inside a file. Creation of such a file is quite straightforward (you have to be root to use losetup).
dd if=/dev/zero of=/root/initrd count=4096 bs=1024
losetup /dev/loop0 /root/initrd
mke2fs /dev/loop0
losetup -d /dev/loop0
file /root/initrd
This creates a initrd file 4MB big. The last command should say: Linux/i386 ext2 filesystem. This is the file that we eventually use to boot the Linux OS on the MP3-box.
To use the initrd for something its necessary to make a mount-point a mount the initrd file:
mkdir /data
mount /root/initrd /data -o loop
Now you freely copy files back and forth onto the 4MB initrd file, which is mounted under /data.
Its time to put something meaningful on the 4MB initrd. We need to copy a small linux distribution onto the initrd, otherwise we can't use it boot the MP3-box.
cd "2nd Step - configuring client/02 - the filesystem"
tar -cf - * | (cd /data; tar -xvf - )
Do you remember the modules that we compiled in the previous section?
cp -Rf /tmp/lib/modules/2.2.16/* ./data/lib/modules/2.2.16
sync
df -h
df -h serves only to show you how much space you have left on the filesystem.
Using the initrd file generally means we have to unmount the file, gzip it and copy it into the tftpboot directory.
umount /data
sync
gzip -c9 /root/initrd > /tftpboot/X86PC/UNDI/linux-install/linux.2
This will unmount the initrd, and compress it into linux.2 file (which is what the NBP will look for and download).
That's basicly the method of designing and using an initrd filesystem. One thing to keep in mind - the initrd should always be compressed when deployed.
After you have copied your initrd file and tried to boot up the workstation, you found out that the kernel complains about not being able to mount the root partition. The problem lies in the NBP that is supplied with PXE - it was compiled for RedHat type initrd images, and therefore does some changes to the kernel.
1st Step - configuring server/02 - pxe/pxe/pxe-linux/nbp.linux/prepare.c. Line 212 lists the hexadecimal address. Change it to 0x0100 - that way the kernel will mount /dev/ram0 and actually find a initrd filesystem.
When the kernel completes loading the initrd into memory and mounts it as a filesystem, then /sbin/init is executed, which handles the rest of starting the operating system.
The scripts were made as simple as possible. The files you ought to look into and alter are:
The Logitech Remote I obtained was quite easy to get working with Linux. The software used in Linux was ARCaMP (AST Remote control MP3 Player). The software basicly listens at the serial port for some predefined characters, and based on them, launches mpg123.
The source code is included in 2nd Step - configuring client/99 - the sources/ARCaMP. It differs from the original code - the key mappings are different and the default playlist has been altered. If you find out that the program works with your remote, but the buttons -> action mappings are screwed up, then edit the defs.h to match your scan-codes with your remote. Getting the scan-codes is quite easy:
cat /dev/ttyS1 | od -t x2
0000000 2000 7f10 7f10 7f10 7f10 7f10 7f10 7f10
0000020 7f10 7f10 202a 7f10 7f10 7f10 7f10 7f10
0000040 7f10 7f10 7f10 7f10 7f10 7f10 202a 7f10
0000060 7f10 7f10 7f10 7f10 7f10 7f10 7f10 202a
0000100 0f0f 0f0f 0f0f 0f0f 0f0f 2a0f 0f20 0f0f
0000120 0f0f 0f0f 0f0f 2a0f 0f20 0f0f 0f0f 0f0f
0000140 0f0f 0f0f 202a 1212 1212 1212 1212 2a12
0000160 1220 1212 1212 1212 1212 2a12 1220 1212
0000200 1212 1212 1212 1212 1212 202a 1212 1212
/dev/ttyS1 is the serial port for my infrared receiver, yours might be different. od -t x2 converts the output to hexadecimal.
The first eight bytes are just offset locations - ignore them. If you look closely at the strings it becomes clear that whenever you hit a the same button on the remote, you get similar looking strings of numbers. The first three rows are actually the fastforward button being hit three times. The repetition of ox20, ox2A, 0x7F, and 0x10 suggest that 0x20 and/or 9x2A are remote-id number, while 0x7F or 0x10 are codes for fastforward.
The next three rows are for the play button (the scancode is 0x0F). And as you can see, the repetition of 0x20, 0x2A suggest remote-id again.
The last three rows are for the stop button - 0x12.
Just run make and copy the arcamp file into /data/bin directory - assuming you still have the initrd filesystem mounted under /data.
If you have different remote, and the scancode-match procedure doesn't work, then you won't be able to use ARCaMP. Instead you will have to search for some software under Linux that will support your remote. Look at the Remote control programs section at the end of the document for some URLs.
Just keep in mind, that you will have to modify /etc/rc.d/rc.audio (on the initrd fs) so that it will spawn a different program then ARCaMP.
The program is staticly compiled and put in /bin (on the initrd) directory. If you find it necessary to get a more recent version , recompile it with -static flag and put in /bin.
The box can be made of wood, metal or anything else. But the most simplest way of building ones box is to use plexiglass. Plexiglass under heat - from a torch, kitchen stove - will warm up and is susceptible to bending. The disadvantage of plexiglass is that its can carry electric charge - thus its unadvisable to put electronic components on the plastic - use those small plastic pegs for motherboards - glue them on the plexiglass.
The design of the box depends on your parts. If you have a small motherboard, low-profile sound card and network card, you can make the box 4"-5" tall. The placement of motherboard, power supply, and the infrared serial receiver all depends on your imagination.
In the case of my box, the minimum I could get was 6" height (the motherboard + plastic pegs + ISA Sound card). Therefore I decided on building a wide box to compensate for the height. The shape of the box is semi-pyramid.
During the design, heat and air circulation has to be taken into account. If you wish to make your system noise-less (without fans), make the box big, and drill holes on sides, and on the top so that hot air can raise and escape. You also might consider downclocking the CPU - that way you can use a heatsink instead of CPU fan. Another alternative is to drill holes one side of the box, and put a fan on other side, and have the CPU in the middle of the air-flow. Take also in consideration your power supply. The small power supplies (83W, 40W) don't exhaust too much heat and can be safely left without a fan. Unfortunately, the bigger they get the more heat they exhaust - and the heat has to be drawn out.
In my case I decided to use one fan to cool down the power supply and CPU. The fan is mounted on top of the power supply. The power supply has exhaust vents on top, from which heat escapes. The CPU is located 20cm away from the fan, under 45" angle - also not that far away from the CPU I drilled some holes to suck in fresh air. What essentially happens is that outside air is sucked in thru the holes, passes over the CPU and then combined with the air from the power supply is sucked out by a fan. For pictures: check mpeg-box pictures.
Move the whole linux-2.2.16 directory somewhere else where the directory-name doesn't have spaces in itself.
Tough! :P
You will have to look for some other software that will support your remote control. Look in the Remote programs URL section.
Look in Configuring - NBP Network Boot Program
Get a torch and heat the opposite side of the plexiglass that you are going to bend. You should move the torch back and forth, not to fast, and not too slow. One minute - two minutes should be fine, if you warm up it too much, bubbles will appear. After you have heated the material, put in on table and slowly bend it. Keep it under the desired angle up to a minute.
Go into the BIOS settings and change the Video Mode (it might be called something else on your system) and change from CGA/EGA or VGA to None.