Tuesday, January 13, 2015

Installing Debian on Odroid C1

After my adventure of installing Debian on Pogo, I decided to ditch the Pogo and go for Odroid C1 which has gigabit ethernet and a quad core armv7 running at 1.5GHz. My objective again is to install Debian from scratch using the installer over serial console, without using a flash image that somebody else prepared.
Warning: The ethernet driver for Odroid C1 is buggy and may have auto-negotiation problems which prevent the Gigabit ethernet from achieving line speed.
Here is my shopping list:
The USB UART Module Kit contains three pieces: the USB cable, a small board with FTDI chip, and a Molex cable. I mostly bought the kit just for the Molex cable because Odroid C1 serial console has a Molex socket. I kind of wished that Hardkernel could just sell the Molex cable separately so I could use the USB-TTL adapter I already had for Raspberry Pi.

The Molex cable could be mated to a commodity USB-TTL adapter by inserting the short-end of the break-away headers to the Molex connector, and the long end to the TTL.

Beware: I found out that you could (accidentally) power the Odroid C1 through the serial port if you connect the red wire, but the Ethernet chip would not receive enough power to work reliably. In my case, packets are transmitted but no packets are received. If you ping host X from the Odroid and run tcpdump on host X, you'd see the ICMP echo and reply, but Odroid C1 never sees the reply.

You will have to disconnect the serial console's power even if you plug in the DC power, or the Odroid will continue to draw power from the serial port.

First I need to flash the eMMC from Odroid's image to ensure the proper bootloader and the partition layout. It would be nice in the future if they could provide a tool to format the eMMC.
  • From: http://odroid.com/dokuwiki/doku.php?id=en:c1_release_linux_ubuntu
  • unxz --keep ubuntu-14.04.1lts-lubuntu-odroid-c1-20150102.img.xz
  • On Mac OS X:
    • Use "diskutil list" to find the eMMC device.
    • Use "diskutil umount" to unmount whichever volume is currently mounted, prior to flashing with the dd command.
    • Use "diskutil eject" to eject the device after the flashing is done.
  • dd if=ubuntu-14.04.1lts-lubuntu-odroid-c1-20150102.img of=/dev/rdisk2 bs=1M
This will result in an eMMC with two partitions. Mac OS X or Windows will see only the boot (FAT32) partition. While you're at it, edit boot.ini and change bootargs from:
setenv bootargs "console=ttyS0,115200n8 root=UUID=e139ce78-9841-40fe-8823-96a304a09859 rootwait ro no_console_suspend vdaccfg=0xa000 logo=osd1,loaded,0x7900000,720p,full dmfc=3 cvbsmode=576cvbs hdmimode=${m} m_bpp=${m_bpp} vout=${vout_mode} ${disableuhs}"
setenv bootargs "console=ttyS0,115200n8 root=/dev/mmcblk0p2 rootwait ro no_console_suspend vdaccfg=0xa000 logo=osd1,loaded,0x7900000,720p,full dmfc=3 cvbsmode=576cvbs hdmimode=${m} m_bpp=${m_bpp} vout=${vout_mode} ${disableuhs}"
That's because we will reformat the filesystem which results in a different UUID. It is also fixable later.

We will now install Debian using Odroid's uImage with the uInitrd of the Debian network installer for efikamx, which you could download from here. I don't know if other installers under armhf work or not; maybe I just got lucky. You can either put the uInitrd under a different name (say uInitrd-deb) into the boot partition (the FAT32 partition that has boot.ini) or TFTP it in later. But we will first boot into Odroid's Xubuntu to resize the root filesystem since Debian installer can't repartition it.

Don't plug in the Ethernet cable the first time, until you change the password for 'root' and 'odroid' over the serial console. Also, while you're at it, change /etc/ssh/sshd_config to disallow root login.
# passwd -d root
# passwd odroid
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
# sed -i 's/\(PermitRootLogin\) .*/\1 no/' /etc/ssh/sshd_config
# service ssh reload
This ensures that nobody could login as root and replace our kernel before we're ready to install Debian. We will be keeping the same kernel for now. Run odroid-utility.sh now to resize the root filesystem to fill the eMMC.

Reboot the Odroid, and press the enter key immediately to abort U-Boot. You will see the "odroidc#" prompt. Now it is safe to plug in the Ethernet cable.
* Welcome to Hardkernel's ODROID-C... (Built at 19:33:00 Dec  8 2014) *
PU : AMLogic S805
MEM : 1024MB (DDR3@792MHz)
BID : HKC13C0001
S/N : HKC1CC0349B9915D
Loading U-boot...success.

U-boot-00000-g9f5aee4(odroidc@odroidc-v2011.03) (Jan 02 2015 - 17:56:06)

DRAM:  1 GiB
relocation Offset is: 2ff0c000
MMC:   eMMC: 0, SDCARD: 1
IR init is done!
vpu clk_level = 3
set vpu clk: 182150000Hz, readback: 182150000Hz(0x701)
mode = 6  vic = 4
set HDMI vic: 4
mode is: 6
viu chan = 1
config HPLL
config HPLL done
reconfig packet setting done
MMC read: dev # 0, block # 33984, count 12288 ... 12288 blocks read: OK
There is no valid bmp file at the given address
Vendor: Man 450100 Snr 01281340 Rev: 4.7 Prod: SDW32
            Type: Removable Hard Disk
            Capacity: 29820.0 MB = 29.1 GB (61071360 x 512)
Partition     Start Sector     Num Sectors     Type
    1                 3072          263168       6
    2               266240         9363456      83
Net:   Meson_Ethernet
init suspend firmware done. (ret:0)
Hit Enter key to stop autoboot -- :  1 tstc enter

exit abortboot: 1
Here we will load the original uImage and boot into uInitrd-deb of the Debian installer. You could just TFTP in the Debian installer uInitrd using the tftpload command (not shown).
odroidc#fatload mmc 0:1 0x21000000 uImage
reading uImage

5434708 bytes read
odroidc#fatload mmc 0:1 0x22000000 uInitrd-deb
reading uInitrd-deb

5473116 bytes read
odroidc#fatload mmc 0:1 0x21800000 meson8b_odroidc.dtb
reading meson8b_odroidc.dtb

17748 bytes read
odroidc#setenv bootargs "console=ttyS0,115200n8 rootwait ro no_console_suspend vdaccfg=0xa000 logo=osd1,loaded,0x7900000,720p,full dmfc=3 cvbsmode=576cvbs hdmimode=720p m_bpp=32 vout=hdmi disableuhs"
odroidc#bootm 0x21000000 0x22000000 0x21800000
The bootargs contain some magic incantation that tells the board how to activate the frame buffer. Without them you'd get a kernel panic. The bootargs and other load commands all come from /boot/boot.ini on the eMMC card. After you boot, you should be able to continue with the usual Debian Installer. Make sure that you use /dev/mmcblk0p2 as your root.

If you forgot to fix boot.ini to use root=/dev/mmcblk0p2 instead of the UUID earlier, initramfs will drop to an "(initramfs)" prompt after failing to find root. The following commands fix it by assigning the new root filesystem the same UUID as before:
mount /dev/mmcblk0p2 /root
mount /dev /root/dev
chroot /root
tune2fs -U e139ce78-9841-40fe-8823-96a304a09859 /dev/mmcblk0p2
The resulting system won't have any kernel modules, but the builtin kernel is functional enough without additional modules. You will be able to install the modules over the network after the system boots normally. See my next post on how to compile a kernel for Odroid C1.

No comments: