Friday, December 30, 2011

Fedora 14 ARM on Pandaboard

Jon Masters has provided a Pandaboard Fedora 13 image which mostly works great (the MLO appears to not work on the new ES model, but you can strip the MLO from the Pandaboard validation image and use it instead).

However, if you have the desire to stay current, you might want to try a little newer version of Fedora.  I expect the floodgates to open shortly as the Fedora ARM team is working on bootstrapping Fedora 15, but in the meantime, Peter Robinson has provided a Fedora 14 ARM image.  No, it's not specific to the Pandaboard, but we can get it working anyway with a little elbow grease.  And if we leverage the work of others, we won't even have to do any compiling!

Partitioning & formatting your SD card

This is perhaps the most critical step - and one with many nuances and folklore.  The image provided by Peter is "generic" in the fact that it doesn't have Pandaboard specific files or image layout.  What this means is that we'll have to provide an additional partition: the MLO/uboot partition for Pandaboard.

There have been some reported problems with specific SD cards, so I would suggest using a high quality SD card (I have used both Micro Center "generic" card and a PNY professional card without issues).  If there is any doubt about the card, try the validation image first.

Once you have the card in hand, you can insert it into your computer and examine /var/log/messages to determine which device is assigned by the kernel.  In my case, this is what was reported:

sd 4:0:0:2: [sde] 15644672 512-byte logical blocks: (8.01 GB/7.45 GiB)

Also, it's worth noting that if there are mountable filesystems, they are probably mounted.  That's not what we want, so be sure to unmount any mounted filesystems from this card.

Now I use fdisk to create two partitions:
  1. The uboot/MLO partition sized at about 64 MB.
  2. The rest of the card for the system.
There is two things worth mentioning here.  Most people also create a separate swap, boot, and root partitions.  I'm not going to do that here.  I'm going to instead create a 2nd partitions to use as a PV (Physical Volume) for LVM.  I will then later create Logical Volumes for swap and root filesystems.  I will not be creating a separate /boot filesystem.  The reason that this is many times distinct from the root filesystem is because it makes recovery easier if you can mount up root and make changes.  Since the /uboot partition/filesystem will be copies of files from /boot, I won't make it separate - the /uboot filesystem will contain the important files.

Now create the two partitions:

# fdisk /dev/sde

Command (m for help): c
DOS Compatibility flag is set (DEPRECATED!)

Command (m for help): o
Building a new DOS disklabel with disk identifier 0xaa802e39.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (with command 'c').
Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1): 1
First sector (62-15644671, default 62): 63
Last sector, +sectors or +size{K,M,G} (63-15644671, default 15644671): +64M

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 6
Changed system type of partition 1 to 6 (FAT16)

Command (m for help): a
Partition number (1-4): 1

Command (m for help): p

Disk /dev/sde: 8010 MB, 8010072064 bytes
247 heads, 62 sectors/track, 1021 cylinders, total 15644672 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xaa802e39

   Device Boot      Start         End      Blocks   Id  System
/dev/sde1   *          63      131135       65536+   6  FAT16
Partition 1 does not end on cylinder boundary.

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
Partition number (1-4, default 2): 2
First sector (62-15644671, default 62): 131136
Last sector, +sectors or +size{K,M,G} (131136-15644671, default 15644671):
Using default value 15644671

Command (m for help): t
Partition number (1-4): 2
Hex code (type L to list codes): 8e
Changed system type of partition 2 to 8e (Linux LVM)

Command (m for help): p

Disk /dev/sde: 8010 MB, 8010072064 bytes
247 heads, 62 sectors/track, 1021 cylinders, total 15644672 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xaa802e39

   Device Boot      Start         End      Blocks   Id  System
/dev/sde1   *          63      131135       65536+   6  FAT16
Partition 1 does not end on cylinder boundary.
/dev/sde2          131136    15644671     7756768   8e  Linux LVM
Partition 2 does not end on cylinder boundary.

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: If you have created or modified any DOS 6.x
partitions, please see the fdisk manual page for additional
information.
Syncing disks.
#
You'll notice that I forced the 1st partition to start at sector 63 even though this was listed as no longer a requirement.  For whatever reason, I was unable to get a starting sector of 2048 (the default when not using DOS-compatability mode) to work.  Your mileage may vary.

We'll want to format that first partition too:

# mkfs -t vfat -F 16 -n uboot /dev/sde1
mkfs.vfat 3.0.12 (29 Oct 2011)
#
Installing the boot files

Now to save some time creating the boot partition, we're going to borrow MLO and uboot binaries from the Pandaboard validation image and a previous Fedora-13 Pandaboard image.  Download this image and copy the binaries to your local directory.  Now let's discover how the image is laid out:

# fdisk -l validation-19102011.img

Disk validation-19102011.img: 83 MB, 83886080 bytes
255 heads, 63 sectors/track, 10 cylinders, total 163840 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

                  Device Boot      Start         End      Blocks   Id  System
validation-19102011.img1   *          63       80324       40131    c  W95 FAT32 (LBA)
validation-19102011.img2           80325      144584       32130   83  Linux
#
From this, we can know that the uboot filesystem is located at 512 bytes per sector x 63 sectors = 32256 bytes.  Let's mount it and copy out the files we need.  All we really need is MLO and u-boot.bin, but we'll go ahead and grab the uImage for some quick testing too.

# mkdir tmp
# losetup --offset 32256 --show --find ./validation-19102011.img
/dev/loop0
# mount /dev/loop0 ./tmp
# ls tmp
MLO  u-boot.bin  uImage
# cp tmp/MLO tmp/u-boot.bin tmp/uImage .
# umount ./tmp
# losetup -d /dev/loop0
# rmdir tmp
#


Now, let's copy the MLO, u-boot.bin, and uImage files to the flash.  The MLO must be the first file written, and never be re-written, so we have to take special precautions to make sure that this happens correctly with no other writes.

# mount /dev/sde1 /mnt/tmp
# cp MLO /mnt/tmp/
# sync
# umount /mnt/tmp
# mount /dev/sde1 /mnt/tmp
# cp u-boot.bin uImage /mnt/tmp/
# umount /mnt/tmp
So this should be enough to at least test and make sure we laid it out right.  Let's eject the media and try booting it on the Pandaboard.

# eject /dev/sde
#
 A quick test

Welcome to minicom 2.5

OPTIONS: I18n
Compiled on Apr  6 2011, 07:59:07.
Port /dev/ttyUSB0

Press CTRL-A Z for help on special keys



Texas Instruments X-Loader 1.41 (Sep 29 2011 - 10:43:53)
OMAP4460: 1.2 GHz capable SOM
Starting OS Bootloader from MMC/SD1 ...


U-Boot 1.1.4-gc1cd80bc-dirty (Oct 12 2011 - 17:56:27)

Load address: 0x80e80000
DRAM:  1024 MB
Flash:  0 kB
Using default environment

In:    serial                                                                  
Out:   serial                                                                  
Err:   serial                                                                  
Hit any key to stop autoboot:  0                                               
mmc read: Invalid size                                                         
                                                                               
4020344 bytes read                                                             
## Booting image at 82000000 ...                                               
   Image Name:   Linux-3.0.4+                                                  
   Image Type:   ARM Linux Kernel Image (uncompressed)                         
   Data Size:    4020280 Bytes =  3.8 MB                                       
   Load Address: 80008000                                                      
   Entry Point:  80008000                                                      
   Verifying Checksum ... OK                                                   
OK                                                                             
                                                                               
Starting kernel ...                                                            
                                                                               
Uncompressing Linux... done, booting the kernel.                               
[    0.000000] Linux version 3.0.4+ (danders@ccd-dev) (gcc version 4.3.3 (Sourc1
[    0.000000] CPU: ARMv7 Processor [412fc09a] revision 10 (ARMv7), cr=10c5387f
...
[    8.663208] Waiting 3sec before mounting root device...                     
[   12.223846]   b301           65536 mmcblk0p1 00000000-0000-0000-0000-00000001
[   12.233856]   b302         7756768 mmcblk0p2 00000000-0000-0000-0000-00000002
[   12.242279] No filesystem could mount root, tried:  ext3                    
[   12.242279] Kernel panic - not syncing: VFS: Unable to mount root fs on unkn)
...

If you saw your board get at least to the point of trying to mount the root and failing, this is a good sign.  This means that the MLO, u-boot.bin, and uImage files are all functional.

Next step is to get it booting a Fedora image - that's the next post.

Thursday, February 3, 2011

GuruPlug Plus Gets a New OS - Redux, part 3 (Fedora ARM on microSDHC)

Booting a Fedora ARM Root Filesystem from microSDHC
(this continues from the previous post)

Now we have a fabulous new kernel and shiny new uboot.  Time to get Fedora ARM working.

Although Fedora 12 is quite old at this point, I'm going to use it since the ARM packages for both Fedora 13, 14, and rawhide are incomplete.

My first thought was to partition the SD card with 3 partitions:  1) a partition to support /boot (about 512 MB), 2) an ext3 partition (about 2 GB) for the root filesystem (since you'll soon see that booting a logical volume is going to be too much work), and 3) a partition to be a physical volume for LVM for anything that I might want to mount later.

In the end I decided that I really didn't need /boot separate unless I was going to also be using LVM for the root filesystem.  The problem is that the Linux kernel by itself can not boot a filesystem on a logical volume.  You have to boot Linux with an initrd which loads the LVM modules, then boots from the root filesystem.  That's just too much effort at this point so I'm going to make the root filesystem ext3.  And that means that I won't need a separate /boot to hold the kernels.

This is what my microSDHC looks like:

# fdisk -l /dev/sde



Disk /dev/sde: 7973 MB, 7973371904 bytes

246 heads, 62 sectors/track, 1021 cylinders, total 15572992 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk identifier: 0x5e8436c8



   Device Boot      Start         End      Blocks   Id  System

/dev/sde1              62     2120027     1059983   83  Linux

/dev/sde2         2120028    15572291     6726132   8e  Linux LVM

#

You can get a copy of the root filesystem here:  https://fedoraproject.org/wiki/Architectures/ARM/Using#Latest_Release:_Fedora_12

Assuming you've mounted your root filesystem (sde1 in my example) under /media/sdhc, you'll need to copy the contents of the pre-built root filesystem onto your SDHC card

# tar -jxf rootfs-f12.tar.bz2
# cp -ar rootfs-f12/* /media/sdhc/

Now we're going to need the major/minor numbers of the root filesystem to feed to the kernel through uboot.  But don't fret, it can be found quite easily if you don't know.  Go ahead and test boot the kernel and let it tell you what the available major/minors are:

Marvell>> nand read.e 0x6400000 0x100000 0x400000                              
                                                                               
NAND read: device 0 offset 0x100000, size 0x400000                             
 4194304 bytes read: OK                                                        
Marvell>> setenv bootargs console=ttyS0,115200 rootdelay=10                    
Marvell>> bootm 0x6400000                                                      
## Booting kernel from Legacy Image at 06400000 ...                            
   Image Name:   Linux-2.6.36                                                  
   Image Type:   ARM Linux Kernel Image (uncompressed)                         
   Data Size:    2947644 Bytes =  2.8 MB                                       
   Load Address: 00008000                                                      
   Entry Point:  00008000                                                      
   Verifying Checksum ... OK                                                   
   Loading Kernel Image ... OK                                                 
OK                                                                             
                                                                               
Starting kernel ...                                                            
                                                                               
Uncompressing Linux... done, booting the kernel.                               
Linux version 2.6.36 (kelly@speedy) (gcc version 4.4.3 (Sourcery G++ Lite er) )0
...
VFS: Cannot open root device "(null)" or unknown-block(2,0)                    
Please append a correct "root=" boot option; here are the available partitions:
1f00            1024 mtdblock0 (driver?)                                       
1f01            4096 mtdblock1 (driver?)                                       
1f02          519168 mtdblock2 (driver?)                                       
0810         7786496 sdb driver: sd                                            
  0811         1059983 sdb1                                                    
  0812         6726132 sdb2                                                    
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2,0)


From this boot attempt, we can see that our SDHC card is sdb and the root partition that I created is sdb1 which has a major/minor of 0811.


With this info, we can now setup the uboot environment to boot this filesystem:

Marvell>> editenv x_bootargs_root                                              
edit: ubi.mtd=2 root=0811 rootdelay=10                                         
Marvell>> saveenv                                                              
Saving Environment to NAND...                                                  
Erasing Nand...                                                                
Erasing at 0x40000 -- 100% complete.                                           
Writing to Nand... done                                                        
Marvell>> reset                                                                
resetting ...


With a little luck, you'll now now a login prompt to your new Fedora 12 ARM system (default root password: "fedoraarm").

Fedora release 12 (Constantine)                                                
Kernel 2.6.36 on an armv5tel (/dev/ttyS0) 


There was probably a lot of complaints about modules, which you can fix by installing the kernel modules that you got from the same place as your kernel.  These should be untarred to the / directory (which installs them in /lib/modules).

Note: The pre-built rootfs you just booted has a guest user with no password.  Consider the security implications of this for your use case and take appropriate action.

Additional packages I needed to install to meet my goals:
  • cryptsetup-luks
  • device-mapper
  • lvm2
  • nfs-utils
  • rpcbind
Also, if you're trying to use the plug as a NFS server like I am, the kernel that is installed has the sunrpc functionality built in whereas Fedora assumes that it's a module to be loaded.  This will cause the startup scripts to emit an error.  This can be worked around by adding the following line to /etc/fstab:

rpc_pipefs              /var/lib/nfs/rpc_pipefs rpc_pipefs defaults     0 0