Tuesday, December 23, 2014

pcDuino3 Nano–Problems with the NAND Root File System

This is another in the series documenting my setup of a new home server with the Linksprite pcDuino3 Nano.  A listing for the entire series can be found here.  More information on the pcDuino3 Nano can be found at Linksprite’s website and the pcDuino website.

After connecting the SATA drive I had hoped to move on to setting up the system to recognize the drive and then to use it for the root file system.  However, I ran into a snag…

Some where along the way the root file system in nand had become corrupted.  I subsequently found out that it appeared the corruption occurred when I used apt-get to install the latest updates.  This was a problem because I planned to boot from nand and then copy the root file system from the sd card on to the SATA disk.

Initially I didn’t realize that the problem was with the apt-get so I re-installed the 20141205 kernel and the 20140807 root file system.  Once this was complete I used apt-get to install the latest updates and when the process was complete rebooted and found out I again had a corrupted file system.

At this point I decided to create an image of the root file system on the sd card which was current as of 20141222 and try and reinstall the 20141205 kernel with my 20141222 root file system.  This worked.

Below is the process I used for creating an image of the root file system on the sd card.

Creating an Root File System Image

I did this using a laptop that was running Ubuntu.  The process goes like this:

1. Copy the root file system from the sd card to disk.  First, determine the device for your sd card.  Once you have the device copy the second partition to disk.

ubuntu@ubuntu:~$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 232.9G  0 disk
├─sda1   8:1    0  14.7G  0 part
├─sda2   8:2    0 118.2G  0 part
├─sda3   8:3    0  97.1G  0 part /
├─sda4   8:4    0     1K  0 part
└─sda5   8:5    0     3G  0 part
sr0     11:0    1  1024M  0 rom
sdb      8:16   1   7.4G  0 disk
├─sdb1   8:17   1    16M  0 part
└─sdb2   8:18   1   7.4G  0 part
ubuntu@ubuntu:~$ sudo dd if=/dev/sdb2 of=file.img
15529984+0 records in
15529984+0 records out
7951351808 bytes (8.0 GB) copied, 505.368 s, 15.7 MB/s

The lsblk command will report all the block structured devices.  In this case we can see that there are two disks sda and sdb and that sda has a partition sda3 that is the root mount point.  Based on this we want sdb2 as sdb1 is the boot partition.

2. Mount and check the image copy.  Using losetup mount the image file and run fsck to make sure it is in good order.  losetup is a nice utility to know about as it allows you to add image files as loopback devices and operate on them.

ubuntu@ubuntu:~$ sudo losetup -f --show file.img
/dev/loop0 ubuntu@ubuntu:~$ sudo e2fsck -fy /dev/loop0
e2fsck 1.42 (29-Nov-2011)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/loop0: 70827/473280 files (1.3% non-contiguous), 416578/1941248 blocks

3. Resize the file system and the image file.  I was using an 8GB sd card and had expanded the file system to use the whole card.  To speed the update process I wanted to reduce the size of my root file system and the sd image.  To resize the file system I used the resize2fs command and then using dd created a copy of the image file.  As I was done with the loopback device I deleted it.

For the dd command I used a 1K block size and a count that was the same as the K size I had used with resize2fs.

ubutntu@ubuntu:~$ sudo resize2fs -p /dev/loop0 1677721K
resize2fs 1.42 (29-Nov-2011)
Resizing the filesystem on /dev/loop0 to 419430 (4k) blocks.
Begin pass 2 (max = 42302)
Relocating blocks             XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 3 (max = 60)
Scanning inode table          XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 4 (max = 6053)
Updating inode references     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The filesystem on /dev/loop0 is now 419430 blocks long.
ubuntu@ubuntu:~$ sudo losetup -d /dev/loop0
ubuntu@ubuntu:~$ dd if=file.img of=file2.img bs=1024 count=1677721
1677721+0 records in
1677721+0 records out
1717986304 bytes (1.7 GB) copied, 86.4562 s, 19.9 MB/s

4. Replace the Image on the Update SD Card.  Insert the second sd card you created in the pcDuino3 Nano – Kernel Upgrade at step 7 that has the 20140807 root file system and update.sh on it.  You will need to delete the old image file pcduino3_ubuntu_20140807.img and replace it with the image you created above.

You could also use a blank vfat formatted sd card with slightly different steps.  As the sd card is blank you would just copy the image file created above to the sd card.

ubuntu@ubuntu:~$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 232.9G  0 disk
├─sda1   8:1    0  14.7G  0 part
├─sda2   8:2    0 118.2G  0 part
├─sda3   8:3    0  97.1G  0 part /
├─sda4   8:4    0     1K  0 part
└─sda5   8:5    0     3G  0 part
sr0     11:0    1  1024M  0 rom
sdb      8:16   1   1.9G  0 disk
└─sdb1   8:17   1   1.9G  0 part /media/C311-0715
ubuntu@ubuntu:~$ ls -l /media/C311-0715
total 1677760
-rw-r--r-- 1 gjdonaldson gjdonaldson 1717986304 Aug  7 02:58 pcduino3_ubuntu_20140807.img
-rw-r--r-- 1 gjdonaldson gjdonaldson        618 Aug  7 02:58 update.sh
ubuntu@ubuntu:~$ rm /media/C311-0715/pcduino3_ubuntu_20140807.img
ubuntu@ubuntu~$ cp file2.img /media/C311-0715/pcduino3_ubuntu_20141223.img

5. Update the copy of update.sh on the sd card replacing the image file name on line 3 with the name of the image you just copied to the sd card and save the file back to the sd card.

pcduino3_ubuntu_20140807.img –> pcduino3_ubuntu_20141223.img

If you are using the alternative method that started with the blank vfat sd card.  You will need to create a file on it update.sh that contains the lines below with the name of the image file above on line 3 after IMG=.

#!/bin/sh
cd `dirname $0`
IMG=pcduino3_ubuntu_20140807.img

IMG_SIZE=`du -s $IMG  | cut -f1`
BURN_TIME=`expr $IMG_SIZE / 1024 / 3 / 60`
echo -e "\twriting $IMG to nand flash\n"
echo -e "\tit will take about $BURN_TIME minutes to finish..."

time dd if=$IMG of=/dev/nandd bs=4M && sync
if [ $? -eq 0 ]; then
    echo "update finished"
    killall blink_led.sh
    /blink_led.sh 18 1000000 &
    /blink_led.sh 19 1000000 &
else
    echo "write ubuntu to nand failed"
    killall blink_led.sh
    /blink_led.sh 18 100000 &
    /blink_led.sh 19 100000 &
    exit 1
fi

6) Power off your pcDuino3 Nano and put the sd card with the 20141205 kernel update on it into the pcDuino3 Nano’s sd slot and apply power to the pcDuino3 Nano.  If you don’t have an sd card with this on it you can follow the steps in pcDuino3 Nano – Kernel Upgrade to generate the card.

While the kernel is loading LED 4 will flash.  Once the load is complete it will turn off.  When it does turn off the pcDuino3 Nano and remove the sd card.

7) Put it in the sd card we updated in the steps above into the sd card slot of the pcDuino3 Nano and power up the system.  While the Ubuntu files are loading LED 3 will be on and LED 4 will flash.  When the load is finished both LED 3 and LED 4 will blink in unison.

8) Turn off the pcDuino3 Nano, remove the sd card and turn it back on.  It should boot into the updated root file system.

No comments: