# Running Arm Linux on HTC Magic

Debian linux on HTC Magic

Requirements

  • Basic knowledge about linux kernel
  • Rooted android phone. For instance: HTC Magic (also known as HTC Sapphire)
  • SDcard with at least 1GB memory space
  • Arch Linux ARM binaries
  • ARM EABI Toolchain
  • Android kernel sources
  • Android SDK Tools
  • Fastboot

Goal

We’re going to run Arch Linux (arm version) on android device (HTC Magic) via fastboot directly from sdcard. This is completely non destructive to the android OS. Connectivity with device is provided by adbd. Furthermore we’re going to configure kernel to print boot logs in framebuffer, so we won’t need a serial cable.

Device Specification

Device name: HTC Magic
ROM: yoshimod 1.5 with 32a kernel
Radio: 3.22.20.17
HBOOT: 1.33.2010
Recovery: RA-sapphire-v1.7.0H

Preparing SDcard

Yoshimod rom requires 2 partitions:

  • first: /sdcard (vfat)
  • second contains android apps (ext2)

Now we need third partition designed for Arch Linux. It’s very important to have proper order of the partitions (android wants vfat to be the first partition). This is my configuration:

/dev/block/mmcblk0p1 -> /sdcard
/dev/block/mmcblk0p2 -> Android apps
/dev/block/mmcblk0p3 -> Arch Linux. Ext2 seems to be the best choice. Journaling may be bad for sdcard life.

I’ve prepared partitions using fdisk but you can use gparted as well.

Installing Arch Linux

# Connect with the device
adb shell

# Remount (rootfs is mounted in read only mode by default)
mount -o rw,remount /

# Create archlinux mountpoint directory
mkdir /mnt/arch

# Mount filesystem
mount -t ext2 /dev/block/mmcblk0p3 /mnt/arch

# Download and extract Arch Linux binaries
wget http://archlinuxarm.org/os/ArchLinuxARM-armv5te-latest.tar.gz
tar xzf ArchLinuxARM-armv5te-*.tar.gz
rm ArchLinuxARM-armv5te-*.tar.gz

# Copy adbd
cp /sbin/adbd /mnt/arch/sbin/adbd

# Chroot
mount -o bind /dev/ /mnt/arch/dev
sysctl -w net.ipv4.ip_forward=1
export PATH=/usr/bin:/usr/sbin:/bin:$PATH
export TERM=linux
export HOME=/root

chroot /mnt/arch/ /bin/bash

# Now we are in Arch Linux
mount -t proc proc /proc
mount -t sysfs sysfs /sys

# Update the system
echo "nameserver 8.8.8.8" > /etc/resolv.conf
pacman -Syu

# Reinstall udev (udev gives off many errors, so we're going to install udev-oxnas)
pacman -Rdd udev
pacman -S udev-oxnas

# Configure startup
mkdir -p /system/bin/
ln -s /bin/bash /system/bin/sh

# Configure users
passwd
useradd -m yourusername -s /bin/bash
passwd yourusername

vi /etc/rc.local -> add line "/sbin/adbd &"
vi /etc/rc.conf -> disable eth0 interface and leave syslog-ng, hwclock daemons enabled (disable the rest by adding "!" eg. "!sshd")

# Modify /etc/fstab by adding
/dev/block/mmcblk0p3 / ext2 defaults 1 1
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /media/sdcard vfat defaults 0 0

Building the kernel

New kernel should have:

  • Initrd turned off – system won’t boot with initrd (if you know why please write explanation in comment)
  • Framebuffer turned on – we want to see booting process on the screen
    I’m gonna use the cyanogemod kernel (2.6.35.7-cyanogenmod), so let’s build!
# Debian/Ubuntu required packages
sudo apt-get install git-core gnupg sun-java6-jdk flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl libncurses5-dev zlib1g-dev

# Get ARM EABI Toolchain tool
mkdir ~/Tools && cd ~/Tools
wget https://sourcery.mentor.com/sgpp/lite/arm/portal/package9740/public/arm-none-eabi/arm-2011.09-69-arm-none-eabi-i686-pc-linux-gnu.tar.bz2
tar -xjf arm-*
export CCOMPILER=${HOME}/Tools/arm-2011.09/bin/arm-none-eabi-

# Download kernel Sources
mkdir -p ~/android/kernel
cd ~/android/kernel
git clone git://github.com/CyanogenMod/cm-kernel.git
cd cm-kernel

# Select branch
git checkout android-msm-2.6.35

# Instead of writing kernel configuration from scratch we'll modify existing kernel config. But first we have to download it:
cd ~/kernel/cm-kernel
adb pull /proc/config.gz ~/config.gz
cat config.gz | gunzip > .config

# Enable framebuffer by adding:
CONFIG_FB_MSM=y
CONFIG_FB_MSM_LEGACY_MDP=y
CONFIG_FB_MSM_MDP_PPP=y
CONFIG_FB_MSM_MDDI=y

CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
CONFIG_LOGO=y
CONFIG_LOGO_LINUX_CLUT224=y

# Disable initrd
change CONFIG_BLK_DEV_INITRD to "# CONFIG_BLK_DEV_INITRD is not set"

# The easiest way to enable/disable the kernel options is to use menu config. If above modifications won't work, try to use:
cd ~/android/kernel/cm-kernel/
make ARCH=arm CROSS_COMPILE=$CCOMPILER menuconfig

# Compile!
make ARCH=arm CROSS_COMPILE=$CCOMPILER -jgrep 'processor' /proc/cpuinfo | wc -l

# Did you get some errors? I did:/ if "drivers/media/video/msm/msm_vfe7x.c" fails, you may:
1. Substitute the file with https://github.com/ezterry/kernel-biff-testing/blob/ezgb-2636/drivers/media/video/msm/msm_vfe7x.c
2. Substitute the file/directory with https://github.com/pershoot/kernel-2635">Pershoot kernel file/directory

# Also modify "drivers/video/msm/msm_fb.c" by commenting ("//")
if (msmfb->sleeping != AWAKE)
   DLOG(SUSPEND_RESUME, "pan_update in state(%d)\n", msmfb->sleeping);

# Compile again.
make ARCH=arm CROSS_COMPILE=$CCOMPILER -jgrep 'processor' /proc/cpuinfo | wc -l

# Zip kernel modules
cd ~/android/kernel/cm-kernel
tar -czf modules.tgz find . | grep ko$

# Prepare modules archive
Download 32a kernel.zip http://www.mediafire.com/?cabub1g3y37gj#sv2ozcq27k6e8
Unizp and enter /mod/
Rename "2.6.35.10-cyanogenmod" dir to "2.6.35.7-cyanogenmod" and enter the directory
Unpack modules.tgz to /mod/2.6.35.7-cyanogenmod/kernel

# Create archive
tar -czf "2.6.35.7-cyanogenmod" modules.tgz

# Upload modules
adb push modules.tgz /mnt/arch/lib/modules

# Unpack modules (being in chroot)
cd /lib/modules/
tar -xzf modules.tgz
rm modules.tgz

# Load modules
depmod -a

# Alternatively you can use modprobe to load single modules.

Fastboot

Eventually! We’re going to boot Arch Linux via fastboot

cd ~/android/kernel/cm-kernel/arch/arm/boot/
fastboot -c 'root=/dev/mmcblk0p3 rw rootfs=ext2 init=/sbin/init rootwait noinitrd' boot zImage

It’s working? Yeah!

Summary

We’ve managed to boot Arch Linux on HTC Magic but a lot of things still doesn’t work. I’m gonna work on the most important issues such as wifi, adbd, drivers in my leisure time;] So you can expect continuation of this article soon;]

Demo

Sources: