Installing MythFrontend on Apple TV using Gentoo

From MythTV Official Wiki
Revision as of 08:06, 16 January 2011 by Wagnerrp (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Important.png Note: These instructions are for the original Apple TV. Not the second generation unit released at the end of 2010.

Warning.png Warning: The Apple TV is built using a 1GHz Pentium M, a GeForce 7300, and 256MB of memory. The limited processor, and graphics only capable of XvMC, mean this unit will only have enough power for standard definition content. Lower bitrate HD MPEG2 may be possible, but not advised. Further, the limited amount of memory may result in UI responsiveness issues.

Purpose

The purpose of this guide will be to instruct you on how to install Myth Frontend onto an Apple TV using Gentoo Linux without having to crack open your Apple TV and voiding your warranty. We will also back up your Apple TV drive so you can restore it if you need to RMA it for any reason.

Portions of this guide can be used as a basis for installing other Linux distro's as well as instruct on what modifications may be needed to resolve certain issues.

Creating the USB patchstick

I recommend a 1GB USB thumb drive that you can store someplace safe afterwards. The extra space is to allow us to store the stage and portage tar.bz2’s durring the install process. You can however use a 512MB drive

For this we will be using atv-bootloader. It can be located here.

You will need a machine with linux already installed. Your Kernel must either have HFS built into it or modular.

1. Install the patched parted version. Instructions are here.

2. Obtain a copy of boot.efi. Follow this guide here.

3. This guide assumes the device at "/dev/sdb" is the pen drive so remember to adjust this to match your device setup or very bad things will happen.

# zero the initial sectors
sudo dd if=/dev/zero of=/dev/sdb bs=4096 count=1M

# sync the system disk partition tables
sudo partprobe /dev/sdb

# create the GPT format
sudo parted -s /dev/sdb mklabel gpt

# create just a recovery partition
sudo parted -s /dev/sdb mkpart primary HFS 40s 69671s
sudo parted -s /dev/sdb set 1 atvrecv on

# sync the system disk partition tables
sudo partprobe /dev/sdb

# Verify that it looks fine and the atvrecv flag is set 
sudo parted -s /dev/sdg unit s print
Model: CBM Flash Disk (scsi)
Disk /dev/sdb: 2015744s
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start    End       Size      File system  Name     Flags
 1      40s      69671s    69632s                 primary  atvrecv
Format this partition hfsplus 
# format it
sudo mkfs.hfsplus -v Recovery /dev/sdb1

# mount it
mkdir penboot
sudo mount /dev/sdb1 penboot

# download atv-bootloader (recovery.tar.gz) and install it
wget http://atv-bootloader.googlecode.com/files/recovery-0.6.tar.gz
sudo tar -xzf recovery-0.6.tar.gz
sudo cp -arp recovery/* penboot/
Remember to copy boot.efi to penboot/ 
sudo cp -ap boot.efi penboot/

Override the normal auto boot sequence as we need to get into a command-line enviroment and get telnetd started. Edit "penboot/com.apple.Boot.plist" on the recovery partition and change the atv-boot parameter from "auto"

<string>atv-boot=auto video=vesafb</string>

to "none"

<string>atv-boot=none video=vesafb</string>

Unmount the disk and we are done building atv-bootloader on a USB pen disk.

sudo umount penboot

4. Now that we have the atv-bootloader installed let’s make a partition to backup the apple tv drive to.

sudo parted -s /dev/sdb mkpart primary ext3 69672s 501725s

# check it
sudo parted -s /dev/sdg unit s print
Model: CBM Flash Disk (scsi)
Disk /dev/sdb: 2015744s
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start    End       Size      File system  Name     Flags
 1      40s      69671s    69632s    hfs+         primary  atvrecv
 2      69672s   501725s   432054s                primary

# sync the system disk partition tables
sudo partprobe /dev/sdb
# format this partition ext3
sudo mkfs.ext3 /dev/sdb2

5. Lets format the rest of the drive to store the install tar.bz2

sudo parted -s /dev/sdb mkpart primary ext3 501726s 2015710s

sudo parted -s /dev/sdg unit s print
Model: CBM Flash Disk (scsi)
Disk /dev/sdb: 2015744s
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start    End       Size      File system  Name     Flags
 1      40s      69671s    69632s    hfs+         primary  atvrecv
 2      69672s   501725s   432054s   ext3         primary
 3      501726s  2015710s  1513985s               primary 

# sync the system disk partition tables
sudo partprobe /dev/sdb

# format this partition ext3
sudo mkfs.ext3 /dev/sdb3
# mount the drive and copy the Stage file and Portage snapshot to it.
mount /dev/sdb3 /mnt/usb
wget ftp://distro.ibiblio.org/pub/linux/distributions/gentoo/releases/x86/current/stages/stage3-x86-2007.0.tar.bz2
wget ftp://distro.ibiblio.org/pub/linux/distributions/gentoo/snapshots/portage-latest.tar.bz2
# also you will need your resolv.conf file from a working machine as I would not trust the one from the patchstick at the moment.
cp /etc/resolv.conf ./

DNS is broken on the atv-bootloader, v0.6, at the moment. This will be fixed in a future release. once you chroot into your stage however this point is moot.

# copy the boot.efi and recovery-0.6.tar.gz to as well.
cp /path to/boot.efi ./
cp /path to/recovery-0.6.tar.gz ./
# download the MBR which will be needed later to make the dist bootable.
wget http://atv-bootloader.googlecode.com/files/mbr_fast-1.0.bin

Backing up your Apple TV

Boot the AppleTV using the USB pen disk. You have to force a "Recovery Boot" by holding "menu" and "-" buttons down on the Apple IR remote either during power-up or when the AppleTV OS is running.

You should see the kernel boot messages, the ifconfig dump and then a login prompt. Either login (user=root, password=root) using a USB keyboard or telnet in using the listed IP addresses. vi, nano, and tar are present as well as the parted and hfs tools for creating AppleTV GPT format partitions.

Nothing is mounted so make two mount points and mount the second partition of the USB flash drive on one and the "Recovery" partition on the internal PATA disk on the other. Clone the contents of "Recovery" to our backup partition. You don't have to copy the contents of "EFI" as there is nothing to copy. That correct, "EFI" is empty. Note that we fsck.hfsplus the "Recovery" partition even though it will be mounted read only.

mkdir src dst
# mount the destination, we don't need to fsck as this is an ext3 partition
mount /dev/sdb2 dst
# mount the source
fsck.hfsplus /dev/sda2
mount -t hfsplus /dev/sda2 src
cp -arp src/* dst/
# force a disk buffer flush
sync
umount src dst
# clean up by removing the mount points
rmdir src dst

Run "parted" and make a copy of the original partitioning for the internal PATA disk. If we alter the original partitioning, the internal PATA disk can be re-partitioned back to the original later using this copy as a guide. Copy this to the first partition of the USB flash drive for safe keeping.

mkdir tmp
# mount fsck.hfsplus /dev/sdb1
mount /dev/sdb1 tmp
parted -s /dev/sda unit s print > tmp/org_gtp.txt

Check the file using "cat tmp/org_gtp.txt", for a 40GB disk it should look something like this.

Model: FUJITSU  K00FT7125M1W (scsi)
Disk /dev/sda: 78140160s
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Number  Start     End        Size       File system  Name      Flags  
 1      40s       69671s     69632s     fat32        EFI       boot   
 2      69672s    888823s    819152s    hfs+         Recovery  atvrecv
 3      888824s   2732015s   1843192s   hfs+         OSBoot           
 4      2732016s  77878015s  75146000s  hfs+         Media            
umount tmp
# clean up by removing the mount points
rmdir tmp

When we are finished you should lable this thumb drive and store it somewhere safe/ So you dont lose it or overwrite this inforamtion. You may need it to RMA the Apple TV at some point. I'm not saying to expect to have to, but just in case. If you want, you can also tar and gzip the contents of the "backup" partition on the USB flash drive to another location. That was quick and painless.

If you ever need to restore this inforamtion to your internal drive follow the guide here.

Installing Gentoo

Partitioning

Zero the hard disk first (well, at least the first 8GB) and be sure you get the device path right!:

dd if=/dev/zero of=/dev/sda bs=4096 count=2M

Set the partition type

parted -s /dev/sda mklabel gpt

Now create the partitions themselves, and their attributes.

parted -s /dev/sda mkpart primary fat32 40s 25M
parted -s /dev/sda set 1 boot on
parted -s /dev/sda mkpart primary HFS 25M 50M
parted -s /dev/sda set 2 atvrecv on
parted -s /dev/sda mkpart primary HFS 50M 75M
parted -s /dev/sda mkpart primary ext3 75M 158.9GB
parted -s /dev/sda mkpart primary linux-swap 158.9GB 160.0GB

If you like, you can now check the partitioning:

parted /dev/sda print

Check that the partition sizes look sane, and that the first two partitions have the right flags. On my system, the output looks like this:

Model: SAMSUNG HM160JC (scsi)
Disk /dev/sdb: 160GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Number  Start   End     Size    File system  Name     Flags
 1      20.5kB  25.0MB  25.0MB               primary  boot
 2      25.0MB  50.0MB  25.0MB               primary  atvrecv
 3      50.0MB  75.0MB  25.0MB               primary 
 4      75.0MB  159GB   159GB                primary 
 5      159GB   160GB   1142MB               primary

Filesystems

Now we format each partition appropriately:

mkfs.msdos -F 32 -n EFI /dev/sda1
mkfs.hfsplus -v Recovery /dev/sda2
mkfs.hfsplus -v OSBoot /dev/sda3
mkfs.ext3 -L gentoo /dev/sda4
mkswap /dev/sda5

Now we mount the partitions and install the bootloader files.

mkdir tmp
mount /dev/sdb3 tmp
mkdir OSBoot
mount /dev/sda3 OSBoot
mkdir Recovery
mount /dev/sda2 Recovery
tar -xzf tmp/recovery-0.6.tar.gz
cp -arp recovery/* /mnt/OSBoot/
cp -arp recovery/* /mnt/Recovery/
cp -ap tmp/boot.efi /mnt/OSBoot
cp -ap tmp/boot.efi /mnt/Recovery
umount /dev/sda2 /dev/sda3

Mount and create your Gentoo system

mkdir gentoo
mount /dev/sda4 gentoo
cd gentoo
tar -xjf ../tmp/stage3-x86-2007.0.tar.bz2
tar -xjf ../tmp/portage-latest.tar.bz2 -C ./usr/

Set up DNS as well as mount points, and then enter our new environment:

cp -L ../tmp/resolv.conf etc/resolv.conf
cd ..
mount -t proc none gentoo/proc
mount -o bind /dev gentoo/dev
swapon /dev/sda5
chroot gentoo /bin/bash
env-update
source /etc/profile
emerge --sync --quiet

Using nano, edit "/etc/make.conf" to look like this, but take note to suit the mirror settings to suit your own situation:

CFLAGS="-march=pentium-m -O2 -pipe -fomit-frame-pointer"
CXXFLAGS="${CFLAGS}"
CHOST="i686-pc-linux-gnu"
USE="bluetooth"
GENTOO_MIRRORS="ftp://mirror.internode.on.net/pub/gentoo"
SYNC="rsync://mirror.internode.on.net/gentoo-portage"
MAKEOPTS="-j2"
VIDEO_CARDS="nvidia"
LIRC_DEVICES="macmini"


Edit "/etc/conf.d/clock" to have the correct settings for CLOCK and TIMEZONE. And then set up a symlink for your timezone:

cd /etc
ln -s /usr/share/zoneinfo/YourCountry/YourCity localtime

Building your Kernel

Personally I am running on gentoo-sources-2.6.24-r8. There may be newer kernels out there by the time someone uses this guide.

wget http://users.net1plus.com/bonkote/MythTV/config-2.6.24.3.zip
cd /usr/src
unzip config-2.6.24.3
emerge -v =gentoo-sources-2.6.24-r8 genkernel
genkernel --kernel-config=/usr/src/config-2.6.24.3 all
cd /boot
ln -s System.map-genkernel-x86-2.6.24-gentoo-r8 System.map
ln -s initramfs-genkernel-x86-2.6.24-gentoo-r8 initramfs
ln -s kernel-genkernel-x86-2.6.24-gentoo-r8 kernel

Update the system

At this point, it is recommended that you refer to http://www.gentoo.org/doc/en/change-chost.xml to fix anything that might be confused by the change in CHOST. In short, this is what I did (note that this take a long time):

emerge -v1 binutils gcc glibc
etc-update
env-update && source /etc/profile

Then, update the rest of the system, note that we're now building things with the toolchain optimised for our architecture:

emerge -v -D --update system
etc-update
emerge -v -D --update world
etc-update

Tweaking

Configure some other aspects of the system:

passwd
emerge syslog-ng vixie-cron slocate dhcp
rc-update add syslog-ng default
rc-update add vixie-cron default

Using nano, edit /etc/fstab so that the 'guts' looks like this:

/dev/sda4               /               ext3            noatime         0 1
/dev/sda5               swap            swap            defaults        0 0
shm                     /dev/shm        tmpfs           nodev,nosuid,noexec     0 0

If you plan to use sound, edit "/etc/modules.autoload.d/kernel-2.6" and add these three lines:

snd-hda-intel
snd-mixer-oss
snd-pcm-oss

Make sure that networking is enabled on bootup:

emerge dhcp
rc-update add net.eth0 default

Install the bootloader (Grub):

emerge -v grub

Edit "/boot/grub/grub.conf" to look like this:

default 0
timeout 30
splashimage=(hd0,3)/boot/grub/splash.xpm.gz

title Gentoo Linux 2.6.24-r8
root (hd0,3)
kernel /boot/kernel root=/dev/ram0 init=/linuxrc ramdisk=8192 real_root=/dev/sda4 udev
initrd /boot/initramfs

Exit the chroot environment:

exit
cd
umount gentoo/proc
umount -l gentoo/dev
umount gentoo 

MBR

Now we update the boot disk MBR:

dd if=tmp/mbr_fast-1.0.bin of=/dev/sda bs=512 count=1

Booting

Remove the USB connection from the HDD, and then insert the HDD into the IDE bus of the target Apple TV. Turn on the Apple TV, and it should boot successfully into Gentoo Linux. (First you'll see the ATV Bootloader graphic, and then the bootloader should load, and then it will load "our" kernel.)

Once the system has booted, you should be able to login to it as normal.

If you like, you can log in as root and do these cleanups:

rm /*.bz2
emerge -v -D --newuse world
emerge gentoolkit
emerge -v --depclean

Installing MythTV

Here is what I recommend to emerge

emerge alsa-utils evilwm kdm lirc mythtv mythmusic mythvideo mythweather ntp nvidia-drivers nvidia-settings vnc xset xorg-x11

Setup a VNC password so that we can remote in and set things up without needing a mouse and keyboard connected to the system

vncpasswd .vnc/passwd

Here is my xorg.conf it outputs through my HDMI connection and configures the monitor based on the EDID information.

# nvidia-xconfig: X configuration file generated by nvidia-xconfig
# nvidia-xconfig:  version 1.0  (buildmeister@builder3)  Thu Feb 14 18:20:37 PST 2008

Section "ServerLayout"
    Identifier     "X.org Configured"
    Screen      0  "Screen0" 0 0
    InputDevice    "Mouse0" "CorePointer"
    InputDevice    "Keyboard0" "CoreKeyboard"
EndSection

Section "Files"
    RgbPath         "/usr/share/X11/rgb"
    ModulePath      "/usr/lib/xorg/modules"
    FontPath        "/usr/share/fonts/misc/"
    FontPath        "/usr/share/fonts/TTF/"
    FontPath        "/usr/share/fonts/OTF"
    FontPath        "/usr/share/fonts/Type1/"
    FontPath        "/usr/share/fonts/100dpi/"
    FontPath        "/usr/share/fonts/75dpi/"
EndSection

Section "Module"
    Load           "vnc"
    Load           "dbe"
    Load           "extmod"
    Load           "glx"
    Load           "xtrap"
    Load           "record"
    Load           "type1"
    Load           "freetype"
EndSection

Section "InputDevice"
    Identifier     "Keyboard0"
    Driver         "kbd"
EndSection

Section "InputDevice"
    Identifier     "Mouse0"
    Driver         "mouse"
    Option         "Protocol" "auto"
    Option         "Device" "/dev/input/mice"
    Option         "ZAxisMapping" "4 5 6 7"
EndSection

Section "Monitor"
    Identifier     "Monitor0"
    VendorName     "Monitor Vendor"
    ModelName      "Monitor Model"
EndSection

Section "Device"
    Identifier     "Card0"
    Driver         "nvidia"
    VendorName     "nVidia Corporation"
    BoardName      "Quadro NVS 110M / GeForce Go 7300"
EndSection

Section "Screen"
    Identifier     "Screen0"
    Device         "Card0"
    Monitor        "Monitor0"
    Option         "PasswordFile" "/root/.vnc/passwd"
    Option         "UseEdidDpi" "FALSE"
    Option         "DPI" "96 x 96"
    Option         "XvmcUsesTextures" "false"
    Option         "NVAGP" "1"
    Option         "UseEvents" "True"
    Option         "NoLogo" "True"
    Option         "Coolbits" "1"
    SubSection     "Display"
        Viewport    0 0
    EndSubSection
    SubSection     "Display"
        Viewport    0 0
        Depth       4
    EndSubSection
    SubSection     "Display"
        Viewport    0 0
        Depth       8
    EndSubSection
    SubSection     "Display"
        Viewport    0 0
        Depth       15
    EndSubSection
    SubSection     "Display"
        Viewport    0 0
        Depth       16
    EndSubSection
    SubSection     "Display"
        Viewport    0 0
        Depth       24
    EndSubSection
EndSection

Section "Extensions"
    Option         "Composite" "Disable"
EndSection

I did have to disable EDID DPI detection as my TV sends erronious data for this. You may need to undo this

I did not setup the built in IR receiver as I am using streamzap so you will have to look else where for instructions.

Lets setup kdm and make it start evilWM and mythfrontend.

Set kdm as your xdm by editing /etc/conf.d/xdm (in old versions it was in /etc/rc.conf) File: /etc/conf.d/xdm

...
DISPLAYMANAGER="kdm"
...

If you run evilWM, set the session type for mythuser to custom. You can do this within KDM or by creating ~/.dmrc. File: ~/.dmrc

[Desktop]
Session=custom

This will cause KDM to execute your .xsession file at logon, for this to work .xsession must be executable!. File: ~/.xsession

# Sample .xinitrc for starting evilwm
# Merge X resources from ~/.Xdefaults
[ -f $HOME/.Xdefaults ] && xrdb $HOME/.Xdefaults

# Set the background and root cursor shape (requires xsetroot)
xsetroot -solid \#400040
xsetroot -cursor_name left_ptr

# Start evilwm - snap to borders within 10 pixels
/usr/bin/evilwm -snap 10 &

sudo nvidia-settings -a GPUOverclockingState=1
# nVidia drivers 177 and up lowered the max ClockFreq to 720. Older versions can use 800.
sudo nvidia-settings -a GPU2DClockFreqs=200,720

#irexec &
#/usr/bin/xset -dpms
#/usr/bin/xset s off
#/usr/bin/mythfrontend &
#/usr/bin/mythfrontend -v playback &

/usr/local/bin/myth-load.sh

# Transfer control to xclock - killing xclock (with Ctrl+Alt+Escape, say)
# will exit our session
#exec xclock -digital -padding 2 -g -0+0
# Or, if you want to be able to exit X with Ctrl-Alt-Backspace only, use this
# dummy line as the last line:
exec sleep infinity

I have a myth-load.sh file setup. If you do not want to use this just uncomment the same lines from xsession. File: /usr/local/bin/myth-load.sh

#!/bin/bash

# Only do this stuff if we're on the main display
# (i.e., don't do this in a vnc session)
if [ `echo $DISPLAY | grep -c ":0"` -ge 1 ]
then
    # Restore audio settings
#    /usr/sbin/alsactl restore
    # Launch irexec for myth power button stop/start
    irexec &
    # Launch myth frontend
    mythfrontend &
    # Disable dynamic power management (screen blanking)
    /usr/bin/xset -dpms
    # Disable screen saver
    /usr/bin/xset s off
fi
exit

XvMC

Add the following to /etc/X11/XvMCConfig

/usr/lib/libXvMCNVIDIA.so

The edit playback settings and follow these instructions

Configuring Digital Audio

Set your .asoundrc or /etc/asound.conf to the following.

pcm.!default {
        type plug
        slave {
                pcm "spdif"
                rate 48000
                format S16_LE
        }
}

Then go into the Audio config in myth and set the following.

Audio output device: ALSA:default
Passthrough output device: default
Max Audio Channels: 5.1
Upmix: Passive
Enable AC3 and DTS passthrough and turn off buffering and internal volume controls.

Wireless

I have not set this up yet. There are instructions on how to do this here, which is where alot of this guide started. I just rewrote sections based on using the patchstick as opposed to gutting the machine and connecting the HDD to another machine. Also some of the issues that the original writer ran into have been fixed in this writeup.