How to build a tiny Linux MP3 Player System using Buildroot


How to build a tiny Linux MP3 Player System using Buildroot

Do you have an old spare computer that is rotting somewhere in your attic/cellar? Why not recycle it into a MP3 jukebox! 🙂

An old rig (Pentium 1/2/3-class) with 64Megs of RAM and USB connector will do!

No Harddisk required, a CDROM drive is optional in case that booting from USB doesn’t work.

We will design our (minimalistic but fully automated) Linux system so that a screen and a network interface aren’t even required.

Our very simple MP3 player system will be designed according to the following lines :

USB flash drive, with 2 partitions :

  • One SYSTEM partition, EXT2 formatted.
  • One data partition, labelled MYMUSIC, FAT or EXT2 formatted (preferably FAT if you want to copy files from window$ computers). The mp3 files will be stored in this partition.

We want to be able to boot directly from the USB flash drive (or with a CD if the computer can’t)

Ou Linux system will automatically mount the MYMUSIC partition (in READ ONLY mode for safety!)

The Playlist will be generated by searching mp3 files on the whole partition.

The soundcard is initialized

Playback starts.

Basically, just turn on the computer with the USB flash drive plugged in/Boot CD inserted, wait a few seconds, and enjoy your music!

Requirement for the buildroot host system

In order to create ou tiny Linux system, we need the Buildroot development suite. In this tutorial, Buildroot 2011.02 was used, on a Debian Squeeze 6.0 system.

You may want to have a look at my other how to in order to get started.

You’ll also need :

– a full development system. On Ubuntu/Debian this means the following packages : build-essential, ncurses-dev, bison, flex
– BusyBox
– syslinux/extlinux
– qemu (optional)

If you already have Buildroot installed on your host system, it is strongly advised to delete your old output directory.

PART I – Creating our tiny Linux kernel

Configuration of Buildroot before compilation/system generation :
# cd <your buildroot home> && make menuconfig

Toolchain —>
[X] Enable large file (files > 2 GB) support
[X] Enable WCHAR support

Package Selection for the target —>
Audio and video libraries and applications —>
[*] alsa-utils
ALSA utils selection —>
check everything
[*] mpg123

Hardware handling —>
[*] udev

(Without udev, soundcard support didn’t work for me)

Kernel —>
[X] Linux Kernel
Defconfig name : i386

Target filesystem options —>
[X] iso image (optional, only if you want to burn on a CD)
[X] initramfs for initial ramdisk of linux kernel
uncheck others

Linux Kernel configuration
# make linux-menuconfig

Include all the sound drivers for maximum compatibility (kernel size won’t suffer much!)

Device drivers —>

Sound card support —>
Advanced Linux Sound Architecture —>
PCI sound devices —>

<*> …
<*> Intel/SiS/nVidia/AMD/ALi AC97 Controller

<*>

(check all)

Next, we need to configure BusyBox for our embedded system, but Buildroot currently has a limitation : you must first compile the whole thing, so :

# make

then configure BusyBox
# make busybox-menuconfig

Linux System Utilities —>
[X] Support specifying devices by label or UUID

Miscellaneous Utilities —>
[X] Beep

We also need to adapt our root filesystem (the rootfs that will be included in our kernel, via initramfs) :

# cd <your buildroot home>/output/target

Create mnt/music (the mount point we will use to mount our MYMUSIC partition to)

# mkdir mnt/music

Accordingly, modify the etc/fstab file by issuing the command :

# echo "LABEL=MYMUSIC /mnt/music auto ro,noauto 0 0" >>etc/fstab

“auto” tells that the filesystem will be automatically recognized.
the “noauto” value, tells that the entry is not mounted by the mount -a command

(optional) Generate a keymap for our system (ex. for our French readers 🙂

# sudo busybox dumpkmap >etc/fr.kmap

And add the following lines to the  etc/init.d/rcS (our own startup code) :

# MYMUSIC volume label
MYMUSIC="MYMUSIC"
# Mount point
MYMUSIC_MNT="/mnt/music"
# load your keymap (optional)
loadkmap </etc/fr.kmap
clear
echo -e -n "\nInitializing soundcard : "
# a beep will be played if alsactl init fails
# TODO : add better error handling
alsactl init || beep
echo -e "\nMounting Music folder... "
# dirty trick here :
# trying to mount the MYMUSIC partition
# we have to add a delay (10 secs max should be enough) for the usb device to be available!
i=1
while [ $i -le 10 ]
do
# if mount failed, wait 1 sec, else get out of loop (break)
mount LABEL=$MYMUSIC && break
echo "Waiting..."
sleep 1;
i=$(( $i + 1 ))
done
# check if partition successfully mounted
if grep -qs $MYMUSIC_MNT /proc/mounts
then
echo -e -n "\nMusic folder mounted (Read-only)!\nGenerating playlist : "
# scan all folders for *.mp3 files on the volume and sort them alphabetically
find $MYMUSIC_MNT -iname "*.mp3" | sort >/tmp/playlist.txt
echo -e "OK"
cd $MYMUSIC_MNT
# endless loop (you may want to remove it)
while true
do
echo -e "Starting music player (press h for help)\n"
mpg123 -v -C -@ /tmp/playlist.txt
clear
done
# never reached!
echo -e "\nEnd of playlist!"
else
# no music partition found/mounted
# play 3 beeps here to signal the failure
beep
beep
beep
echo -e "\nCouldn't mount your music folder!"
echo -e "\nPlease make sure that your music partition : "
echo -e " - is a valid formatted volume and is labelled $MYMUSIC"
echo -e " - doesn't contain filesystem errors"
echo -e "\nYou can shut down the system now or manually login and check your device."
fi
# to reset your system: you can use the SysRq keys : Alt+PrintScreen+b

(Optional) When generating an iso as well, you’ll have to modify the grub bootloader menu.lst file (because it would boot the first harddisk by default, not the CD!) :

# nano <buildroot>/fs/iso9660/menu.lst

default         1
timeout         3
color yellow/green white/blue
title           Hard Drive (first partition)
rootnoverify    (hd0)
chainloader     +1
title           Fredo's TinyLinuxMP3Player (plug your USB drive & boot CD!)
kernel          /kernel
initrd          /initrd

Ok, now it’s time to generate our tiny Linux kernel :
# cd <your buildroot home> && make

The generated kernel file (named bzImage) is well under 10Megs! And the iso is about ~14Megs.

It’s possible to test our system right away, using qemu
# qemu -kernel output/images/bzImage -soundhw all

(or with the iso)
# qemu -cdrom output/images/rootfs.iso9660 -soundhw all

Part II – Creating our bootable USB flash drive

Display all the drives to see which device is our USB drive :

# fdisk -l

Partition the drive :

WARNING! EVERYTHING ON YOUR DRIVE WILL BE LOST! AND PLEASE SELECT THE CORRECT DEVICE!

Adapt “/dev/sdX” to your own case.

# fdisk /dev/sdX
o
n
p
1
<first cylinder><enter>
<last cylinder>+16M    # 16Megs should be enough, increase it if needed.
t
1
83 <Linux>
n
p
2
<first cylinder><enter>
<last cylinder><enter>
t
2
6 <FAT16> or 83 <Linux> depending on what you prefer
a
1
w

(You may unplug and plug the drive again)

Next, we format the partitions / create the filesystems with the correct volume labels :

For the SYSTEM partition
# mkfs -t ext2 -L SYSTEM /dev/sdX1

For the MYMUSIC partition
# mkfs -t vfat -n MYMUSIC /dev/sdX2

or, if you’d rather use EXT2
# mkfs -t ext2 -L MYMUSIC /dev/sdX2

Finally, let’s make the drive bootable, by installing the EXTLINUX (part of the SYSLINUX package) bootloader :

# cat /usr/lib/syslinux/mbr.bin >/dev/sdX

# mkdir /mnt/usb

# mount /dev/sdX1 /mnt/usb/
# extlinux --install /mnt/usb
# cat >/mnt/usb/extlinux.conf <<EOF
> DEFAULT linux
> PROMPT 0
> LABEL linux
>   SAY TINY LINUX JUKEBOX NOW BOOTING!
>   KERNEL bzImage
>   APPEND quiet # comment this line for debug
> EOF

TIP :
More kernel boot options (for the APPEND line)
http://www.kernel.org/doc/Documentation/kernel-parameters.txt

Last thing, we need to copy our kernel on the drive!
# cp <your buildroot home>/output/images/bzImage /mnt/usb/

(Optional) As for the iso file (output/images/rootfs.iso9660) just burn it to a blank cdrom

Now, let’s unmount the drive :

# cd && umount /mnt/usb

PART III – Playback time!

Copy some mp3 files on the MYMUSIC partition, and boot 🙂

Press the ‘h’ key for MPG123’s help screen.

END.

IDEAS FOR IMPROVEMENTS :

– change video mode  for better display (vga=xxx )
– optimize kernel size by removing unused features

PROBLEMS ENCOUNTERED :

– BusyBox’s beep command does not produce any sound

Solution : TODO

– Certain mp3 files can’t be played
Solution : your usb flash drive might be corrupted! Re-format/try another one.

– Only mp3 files are played! No OGG, no WMV, no ….

Solution : in this version, we use the MPG123 player. You’ll need to adapt the system to use another one (hint: MPLAYER).

Send me remarks, thoughts, flames, ideas for improvements! Thanks!

12 thoughts on “How to build a tiny Linux MP3 Player System using Buildroot

  1. Hi
    nice but i do not see the step what i should do with my genereted rootfs.tar
    Just untar it on the boot partition ?

    • In this howto, the rootfs is included in the initramfs (which itself is embedded into the kernel), so you only need one file : the linux kernel (bzImage) on your boot partition!

  2. nice work with buildroot.
    I use it on the kindles. appreciate teh in depth aritcles even if they don;t completely apply.

  3. I build the rootfs.iso9660 image, when i will test with virtualbox i am getting into grub prompt. Please help me

  4. Hi,

    I confirm this. Just tried with Buildroot 2013.11, booting the rootfs.iso9660 (with grub bootloader) with qemu, hangs at “Loading stage2 …”

    I don’t know why. Maybe try with isolinux…

  5. Hi,
    Great tutorial, it helps me a loot, with a school project i’m doing.

    I’m just having some problems, i don’t know if you could help me:
    when i use qemu, i put: “qemu -hda /dev/sdb1 -hdb /dev/sdb2” cause rootfs is in the second partition, and it works fine. But when i boot the computer from the usb it only uses the first partition, right?, so i got “kernel panic” message. How could i solve this problem?

    One more time, thank you for this tutorial,
    Miguel

    • @Miguel, you should use “-hda /dev/sdb” because you want the whole drive. The booted system will handle the partitions.

  6. i only am trying to make an old mp3 player flash a puppy install. But every iso and boot partition manager doesnt seem to work. I tried unetbootin from lubuntu, but this rca mp3 player wont be reconized…On my other flashdrives i never had trouble, im just wondering why some usb drived wont boot and ISO…

Leave a reply to thiyagu Cancel reply