Saturday, November 26, 2011

A PandaBoard Desktop with Fedora 13

A serial port console, while nice and simple to work on, is a little lacking for eye candy, so today I installed X Windows and Xfce to run a desktop on my PandaBoard.

The installation was the easy part:
yum -y groupinstall Base 'X Window System' 'XFCE' 'GNOME Desktop Environment'

And then it was hurry-up-and-wait while it installed 421 packages.

When it finished, I rebooted it and found a few problems that I had to fix.  The default resolution for the display is a safe 640x480, so I had to add a kernel command line option to make it 1280x1024: omapfb.mode=dvi:1280x1024MR-24@60.  I also added another console=tty0 option so both the serial port and the display could be consoles.  The last console parameter is the primary console and for now I kept the serial port as primary for easier debugging.

[root@fedora-arm ~]# mount /dev/mmcblk0p1 /mnt/boot
[root@fedora-arm ~]# cd /mnt/boot
[root@fedora-arm boot]# vim boot.cmd
[root@fedora-arm boot]# cat boot.cmd
setenv mpurate 800
setenv bootargs 'console=tty0 console=ttyO2,115200n8 ro rootwait root=/dev/sda1 mpurate=${mpurate} init=/sbin/init earlyprintk rd_NO_PLYMOUTH selinux=0 omapfb.mode=dvi:1280x1024MR-24@60'
setenv bootcmd 'mmc rescan 0; mmc init; fatload mmc 0:1 0x80300000 uImage; fatload mmc 0:1 0x81600000 uInitrd; bootm 0x80300000 0x81600000'
[root@fedora-arm boot]# mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n 'Pandaboard Boot Script' -d boot.cmd boot.scr
Image Name: Pandaboard Boot Script
Created: Sat Nov 26 14:22:00 2011
Image Type: ARM Linux Script (uncompressed)
Data Size: 359 Bytes = 0.35 kB = 0.00 MB
Load Address: 00000000
Entry Point: 00000000
Image 0: 351 Bytes = 0.34 kB = 0.00 MB
[root@fedora-arm boot]# cd
[root@fedora-arm ~]# umount /mnt/boot

I then updated /etc/inittab to make runlevel 5 the default and rebooted the PandaBoard again.

I noticed ntpdate was failing to set the clock.  I tried running it manually and noticed it couldn't resolve the hostname  A quick peek at /etc/resolv.conf showed that NetworkManager had re-written the file with nothing but comments because I have /etc/sysconfig/network-scripts/ifcfg-eth0 set up for a static IP address for now.  So I disabled NetworkManager with chkconfig and cleaned up resolv.conf and rebooted once more.

This time it almost worked.  It went through all the boot scripts cleanly, but it got stuck when it should have started X11 and gdm.  Fortunately the serial console still worked, so I logged in and discovered that the /etc/rc.d/rc script was still running and starting up runlevel 5, but it didn't seem to be doing anything.  I then found it was waiting for /etc/rc.d/rc5.d/S99local to finish (aka /etc/rc.d/rc.local).  I looked at this script and remembered the "ugly hack" I had to set up back in April to run agetty on the serial port.  It was running in a never-ending loop which means it will never finish and the init scripts will never start X11.

The Fedora ARM page no longer mentions this ugly hack, so I guess the bug has been fixed and I can use a normal upstart job to manage agetty on the serial port.  I commented out the hack in the rc.local script and created a new /etc/init/serial-ttyO2.conf job:

[root@fedora-arm ~]# cat /etc/rc.d/rc.local
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.

touch /var/lock/subsys/local

# horrible hack to respawn serial console
###while true
###    /sbin/agetty -L 115200 console vt100

[root@fedora-arm ~]# cat /etc/init/serial-ttyO2.conf
start on stopped rc RUNLEVEL=[2345]
stop on runlevel [016]

pre-start exec /sbin/securetty ttyO2
exec /sbin/agetty /dev/ttyO2 115200 vt100-nav

[root@fedora-arm ~]# initctl start serial-ttyO2
serial-ttyO2 start/running, process 20245

One final reboot and ... Hooray!  It ran through the firstboot setup and then launched X11 and gdm.  I logged in to Xfce and launched Firefox and a Terminal.  I now have a completely silent desktop!

Monday, November 14, 2011

System Clock on the PandaBoard

A quick way to find the physical device backing a filesystem is to use the 'df' command.  (LVM, software-RAID, LUKS, and other layers can make this more complicated.)  I did this on my PandaBoard and was a little surprised at the answer:

[root@fedora-arm ~]# df -Th /
Filesystem    Type    Size  Used Avail Use% Mounted on
/dev/root      nfs    7.4G  1.8G  5.3G  25% /

Why is it NFS-mounting a USB flash drive?  And /dev/root doesn't tell me what the device name is.  I was expecting to see something like sda1 or mmcblk0p1.

I thought that was weird, so I edited /etc/fstab and changed the device and filesystem type:
[root@fedora-arm ~]# diff -u /etc/fstab.ORIG /etc/fstab
--- /etc/fstab.ORIG        2011-11-14 10:09:40.000000000 -0600
+++ /etc/fstab  2011-11-14 12:48:58.000000000 -0600
@@ -1,4 +1,4 @@
-/dev/root               /                       nfs     defaults        1 1
+/dev/sda1               /                       ext3    defaults        1 1

And then I rebooted my PandaBoard and quickly learned why it's set to NFS:
                Welcome to Fedora
                Press 'I' to enter interactive startup.
Starting udev: [  OK  ]
Setting hostname fedora-arm:  [  OK  ]
Setting up Logical Volume Management:   No volume groups found
[  OK  ]
Checking filesystems
Checking all file systems.
[/sbin/fsck.ext3 (1) -- /] fsck.ext3 -a /dev/sda1
fedoraroot: Superblock last mount time (Mon Nov 14 11:19:35 2011,
        now = Sat Jan  1 00:00:01 2000) is in the future.

        (i.e., without -a or -p options)

There's no battery-backed clock on the PandaBoard so the clock gets reset to 2000-01-01 00:00:00 every time it's power-cycled, and this causes the Fedora boot scripts to get confused and force a filesystem check.

Apparently mounting the root filesystem as NFS is one way to workaround  this problem.

I mentioned this in #fedora-arm on freenode and Chris Tyler suggested modifying the boot scripts to set the clock to 1 minute past the previous write time of the root filesystem.

Here's what I came up with:
--- /etc/rc.d/rc.sysinit.ORIG    2011-03-08 15:51:46.000000000 -0600
+++ /etc/rc.d/rc.sysinit    2011-11-14 12:44:28.441405990 -0600
@@ -577,6 +577,15 @@
 if [ -z "$fastboot" -a "$READONLY" != "yes" ]; then

+        # set the clock on the PandaBoard to 1 minute after last write
+        # time of root filesystem to avoid "last mount is in the future"
+        echo "Current system clock is $(date)"
+        rootdev=$(egrep '\s/\s' /etc/fstab | awk '{print $1}')
+        lastwrite=$(dumpe2fs -h $rootdev 2>/dev/null | \
+                    grep "Last write time" | sed -e 's/^[^:]*:\s*//')
+        echo "Setting system clock to 1 minute after $lastwrite"
+        date -s "$lastwrite + 1 minute"
         STRING=$"Checking filesystems"
         echo $STRING
         fsck -T -t noopts=_netdev -A $fsckoptions

Notice the new messages (red text) during boot:
                Welcome to Fedora
                Press 'I' to enter interactive startup.
Starting udev: [  OK  ]
Setting hostname fedora-arm:  [  OK  ]
Setting up Logical Volume Management:   No volume groups found
[  OK  ]
Current system clock is Sat Jan  1 00:00:01 CST 2000
Setting system clock to 1 minute after Mon Nov 14 12:45:36 2011
Mon Nov 14 12:46:36 CST 2011
Checking filesystems
Checking all file systems.
[/sbin/fsck.ext3 (1) -- /] fsck.ext3 -a /dev/sda1
fedoraroot: clean, 69076/489600 files, 487736/1957605 blocks
[  OK  ]

And the root filesystem and device look correct now!
[root@fedora-arm ~]# df -Th /
Filesystem    Type    Size  Used Avail Use% Mounted on
/dev/sda1     ext3    7.4G  1.8G  5.3G  25% /

Note that I do have ntpd start later in the boot process which sets the actual correct time.