Showing posts with label Linux. Show all posts
Showing posts with label Linux. Show all posts

2012-06-29

Securely erasing a drive in Linux

Now ain't that useful. From time to time you have to part with an old disk, but of course, you're rather make sure it is properly erased of all its data before handing it off.

Well, what do you know, since 2001, nearly every HDD under the sun comes with a Secure Erase feature, as it is part of the ATA standard.

The even better news is that hdparm fully supports it (is there anything hdparm can't do?), thus, if you're on Linux and you need to securely erase all the data from a drive, all you need to do, say, if your disk is /dev/sdb, is:
# hdparm --user-master u --security-set-pass p /dev/sdb
security_password="p"

/dev/sdb:
 Issuing SECURITY_SET_PASS command, password="p", user=user, mode=high

# hdparm --user-master u --security-erase p /dev/sdb
security_password="p"

/dev/sdb:
 Issuing SECURITY_ERASE command, password="p", user=user
After a while, you should find that your drive has been securely erased. Neat!

VERY IMPORTANT NOTE: If you want to reuse the drive after the secure erase is complete, you MUST issue the following command to remove the lock.
# hdparm --security-disable p /dev/sdb
security_password="p"

/dev/sdb:
 Issuing SECURITY_DISABLE command, password="p", user=user
This is because, if you don't disable security, the drive will be kept locked, which will produce ATA/SATA interface errors and prevent any write access!


Note that if you want to find out whether the security erase/enhanced erase feature is supported at all, as well as how long that erasing is going to take, you probably want to issue the following beforehand:
~# hdparm -I /dev/sdb

/dev/sdb:

ATA device, with non-removable media
        Model Number:       SAMSUNG HD322GJ
        Serial Number:      XXXXXXXXXXXXXX
        Firmware Revision:  XXXXXXXX
        Transport:          Serial, ATA8-AST, SATA 1.0a, SATA II Extensions, SATA Rev 2.5, SATA Rev 2.6
(...)
Security:
        Master password revision code = 65534
                supported
        not     enabled
        not     locked
        not     frozen
        not     expired: security count
                supported: enhanced erase
        48min for SECURITY ERASE UNIT. 48min for ENHANCED SECURITY ERASE UNIT.

2012-06-26

Setting passwords /etc/shadow

If you ever need to edit /etc/shadow to add an MD5 password manually (yes, this can happen for very legitimate reasons):
# openssl passwd -1 -salt abcd1234
Password: hunter1
$1$abcd1234$97fq4hZr.GzmcDQ5upZAX1
Also of reference: here and here


2012-01-10

Help, my RAID array does not complete synchronization!

Let us suppose the following situation: You have a Linux server with a software RAID1 array (md) and, for one reason or another (mostly because your are a lazy admin, admit it!), both disks are reporting unreadable sectors, either through SMART or through actual failed readout attempts.

So you installed a 3rd good disk, set it as a spare, then failed one of the 2 bad ones to initiate synchronisation onto the good new disk. However, all hell breaks lose as you find out your synchronisation doesn't complete (/proc/mdstat reports U_ or _U) and instead of ignoring the unreadable sectors as it should, md decides that it cannot continue.

Worse, if you look at your dmesg, you find out that it is being polluted by a continuous stream of:
RAID1 conf printout:
--- wd:1 rd:2
disk 0, wo:0, o:1, dev:sda1
disk 1, wo:1, o:1, dev:sdb1
Help!!!!

OK, first of all, since this information is quite hard to find, especially if you are in a hurry, here are what the abbreviations above mean:
  • wd: working disks
  • rd: raid disks
  • wo: write-only (if set to 1, this usually indicates a problem, and that data duplication doe not occur for this device)
  • o: online
Obviously, wd:1 as well as wo:1 for the second disk is not something we want to see. Why can't our good spare disk be added as R/W to the gorram array? Heck, if the problematic disk fails, that single-handedly contains our up-to-date data now, we will be in big trouble. What's the point of providing redundancy, really, if md fails to synchronize as soon as there's one measly sector it cannot read!

It's a bird! It's a plane! No, it's hdparm!

Well, the sad truth of md on Linux (which may have improved with newer versions) is that it isn't resilient at all when it comes to unreadable sectors during sync. I guess the developers decided that, since the point of redundancy is to always have at least one good set of data, they didn't need to focus on situation where the "good" set of data may also have some corruption, and therefore never planned for anything but try and re-read an unreadable sector forever, until the disk magically repairs itself (right... fat chance!).

Now (and for the rest of this post I will mostly be following the excellent information provided by Bas on his blog) to compensate for that oversight, the trick is to have md read the problematic sectors one way or another, so that the synchronisation can complete. May sound easier said than done but most of the time it shouldn't be an issue, as recent disks with SMART are engineered with a set of spare sectors, to be allocated in replacement of unreadable or unwritable ones for exactly this kind of situation. The issue however is that reallocation of sectors only occurs on write access.

What this means then is that, while the disk has the technology to "fix" itself, as long as you are only attempting to read the problematic sectors, reallocation will not be triggered and you will continue to get read errors. Thus, you must manually issue a write to the problematic sector(s) to trigger the "recovery" mechanism (NB: I'm using "fix" and "recovery" loosely, as you can of course not recover data from these sectors if they are reallocated, therefore will end up with some corrupted data).

This can be confirmed by checking the Offline_Uncorrectable (#198) and Reallocated_Sector_Ct (#5) reports from SMART:
# smartctl -A /dev/sda
smartctl version 5.38 [x86_64-redhat-linux-gnu] Copyright (C) 2002-8 Bruce Allen
Home page is http://smartmontools.sourceforge.net/

=== START OF READ SMART DATA SECTION ===
SMART Attributes Data Structure revision number: 16
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x002f   100   100   051    Pre-fail  Always       -       105
  2 Throughput_Performance  0x0026   054   054   000    Old_age   Always       -       2759
  3 Spin_Up_Time            0x0023   084   084   025    Pre-fail  Always       -       4989
  4 Start_Stop_Count        0x0032   100   100   000    Old_age   Always       -       10
  5 Reallocated_Sector_Ct   0x0033   252   252   010    Pre-fail  Always       -       0
  7 Seek_Error_Rate         0x002e   252   252   051    Old_age   Always       -       0
  8 Seek_Time_Performance   0x0024   252   252   015    Old_age   Offline      -       0
  9 Power_On_Hours          0x0032   100   100   000    Old_age   Always       -       11496
 10 Spin_Retry_Count        0x0032   252   252   051    Old_age   Always       -       0
 11 Calibration_Retry_Count 0x0032   252   252   000    Old_age   Always       -       0
 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       10
191 G-Sense_Error_Rate      0x0022   252   252   000    Old_age   Always       -       0
192 Power-Off_Retract_Count 0x0022   252   252   000    Old_age   Always       -       0
194 Temperature_Celsius     0x0002   064   060   000    Old_age   Always       -       32 (Lifetime Min/Max 20/40)
195 Hardware_ECC_Recovered  0x003a   100   100   000    Old_age   Always       -       0
196 Reallocated_Event_Count 0x0032   252   252   000    Old_age   Always       -       0
197 Current_Pending_Sector  0x0032   252   100   000    Old_age   Always       -       0
198 Offline_Uncorrectable   0x0030   252   100   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x0036   200   200   000    Old_age   Always       -       0
200 Multi_Zone_Error_Rate   0x002a   100   100   000    Old_age   Always       -       2
223 Load_Retry_Count        0x0032   252   252   000    Old_age   Always       -       0
225 Load_Cycle_Count        0x0032   100   100   000    Old_age   Always       -       10
If you see a zero at the end of these attributes but the disk still reports that it has trouble reading sectors, it indicates that the sector reallocation process hasn't kicked in yet, and needs to be triggered manually.

The first order of the day then is to find the address of the sector(s) we should trigger a write to. This is fairly easy, as all you need to do is run a SMART test, with something like smartctl -t long /dev/sda and write down the first sector address where a read error is reported:
# smartctl -a /dev/sda
(...)
SMART Self-test log structure revision number 1
Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
# 1  Extended offline    Completed: read failure       60%     10864         293039329
(...)
Once we have that address, we could of course use dd, but an even simpler approach is to use a recent version of hdparm, as it adds easy support for reading/writing a single sector.

First thing to try with hdparm then, is confirm that we have a problem accessing that sector:
# hdparm --read-sector 293039329 /dev/sda

/dev/sda: Input/Output error
This confirms what the SMART test reported. You can try a few more read attempts, to validate that the sector is busted, and then, you can issue a write so that the disk finally realizes it should reallocate that sector. Note that, because the operation obviously means destroying existing data, hdparm requires you to add a --yes-i-know-what-i-am-doing flag to issue the write, hence:
# hdparm --yes-i-know-what-i-am-doing --write-sector 293039329 /dev/sda

/dev/sda: re-writing sector 293039329: succeeded
You can then issue a read again, which will confirm that the sector has been reallocated:
# hdparm --read-sector 293039329 /dev/sda

/dev/sda:
reading sector 293039329: succeeded
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
If you issue smartctl -A again, you should also see that the sector has been reallocated:
198 Offline_Uncorrectable   0x0030   100   100   000    Old_age   Offline      -        1
It's usually a good idea to use hdparm to read adjacent sectors as well, and correct them as needed, then repeat the operations above until the SMART self test completes without error and you have smoked out all the problematic sectors. At this stage, if you issue a resync of the array with the new disk, it should complete successfully and redundancy will be restored. Time to order another replacement and check your data for corruption. But at least, you are redundant again.

Addons
  • To get details of your md array, you can use mdadm --detail. Eg.
    # mdadm --detail /dev/md2
    /dev/md2:
            Version : 0.90
      Creation Time : Tue May  6 18:43:16 2008
         Raid Level : raid1
         Array Size : 130030016 (124.01 GiB 133.15 GB)
      Used Dev Size : 130030016 (124.01 GiB 133.15 GB)
       Raid Devices : 2
      Total Devices : 3
    Preferred Minor : 2
        Persistence : Superblock is persistent
    
        Update Time : Tue Jan 10 13:42:29 2012
              State : clean
     Active Devices : 2
    Working Devices : 3
     Failed Devices : 0
      Spare Devices : 1
    
               UUID : 0be47c81:ede086ae:0c460403:d81de298
             Events : 0.3658859
    
        Number   Major   Minor   RaidDevice State
           0       8        3        0      active sync   /dev/sda3
           1       8       19        1      active sync   /dev/sdb3
    
           2       8       35        -      spare   /dev/sdc3
  • You are strongly encouraged to check your syslog or messages for reports of I/O issues, especially if you want to locate the data that may have been affected.
  • This method is not guaranteed to work! Sometimes a SMART test will report a read error but a readout of the sector using hdparam will work fine, so you won't be able to get the disk to reallocate it. However, tis shouldn't matter too much for md resync which is what we are interested in here.
  • If your disk has a lot of unreadable sectors, it is possible that you may run out of spare sectors for reallocation. It's hard to say how many spare sectors are made available by hard drive manufacturers, but I assume it isn't that many.
  • You may have a problem recompiling a recent version of hdparm on some older Linux systems:
    fallocate.c: In function ‘do_fallocate_syscall’:
    fallocate.c:39: error: ‘__NR_fallocate’ undeclared (first use in this function)
    fallocate.c:39: error: (Each undeclared identifier is reported only once
    fallocate.c:39: error: for each function it appears in.)
    make: *** [fallocate.o] Error 1
    If that is the case, just add:
    #define __NR_fallocate 285
    in fallocate.c
  • Some disks seem to be smart enough (no pun intended) to do further correction, once they have registered Offline_Uncorrectable sectors, so you may actually find out that, after a few hours, the value of Offline_Uncorrectable falls back to zero, and still the sectors can be read or written with extended SMART tests not reporting any issue. Pretty neat, but I still wouldn't entirely trust the disk...

2012-01-04

Using LILO to boot disks by UUID

If you're plugging USB drives in an out and using LILO to boot a Linux distro (eg. Slackware) you may have ended up with a kernel panic because your /dev/sd# were shuffled around and the kernel was no longer able to find its root partition on the expected device. Of course, having Linux failing to boot just because you happened to plug an extra drive sucks big time, so we want to fix that.

The well known solution of course it to use UUIDs or labels, since these are fixed. However, while recent versions of LILO are supposed to support root partitions that are identified by UUID/Label, in practice, this doesn't work UNLESS you are using an initrd disk. I'm not sure who of LILO or the kernel is responsible for this new layer of "suck" (I'd assume the kernel, since the expectation is that LILO is using the dev mappings that are being fed by the kernel), but I can only say that there really are some areas of Linux that could still benefit from long awaited improvements...

Thus, to be able to use UUIDs or labels for your root partition in LILO, you must boot using an initrd. Worse, as previously documented, you will most likely need to compile a new kernel that embeds the initrd, lest you want to run into the following issue while running LILO:
Warning: The initial RAM disk is too big to fit between
the kernel and the 15M-16M memory hole.

In practice (as also illustrated by this post), this means you will need to:
  1. Create an initrd cpio image that can be embedded into a kernel with:
    cd /boot
    mkinitrd -c
    cd initrd-tree
    find . | cpio -H newc -o > ../initrd.cpio
  2. Recompile a kernel, while making sure that you have the General Setup → Initial RAM filesystem and RAM disk (initramfd/initrd) support selected, and then set General Setup → Initramfs source file(s) to /boot/initrd.cpio

  3. Edit your /etc/lilo.conf and add an append = "root=UUID=<YOUR-DISK-GUID>" to your Linux boot entry. An example of a working lilo.conf is provided below. Note that you probably also want to use a fixed IDs for boot=, so that running LILO is also not dependent on the current /dev/sd# organization.. 

  4. Run LILO, plug drives around and watch in amazement as your system still boots the Linux partition regardless of how the drives are assigned
Example lilo.conf:
# Start LILO global section
boot = /dev/disk/by-id/ata-ST3320620AS_ABCD1234
compact
lba32
# LILO doesn't like same volume IDs of RAID 1
disk = /dev/sdb inaccessible
default = Windows
bitmap = /boot/slack.bmp
bmp-colors = 255,0,255,0,255,0
bmp-table = 60,6,1,16
bmp-timer = 65,27,0,255
# Append any additional kernel parameters:
append=" vt.default_utf8=1"
prompt
timeout = 35
# End LILO global section

image = /boot/vmlinuz
  append = "root=UUID=2cc11aaf-f838-4474-9d9a-f3881569f97c"
  label = Linux
  read-only
image = /boot/vmlinuz.rescue
  append = "root=UUID=2cc11aaf-f838-4474-9d9a-f3881569f97c"
  label = Rescue
  read-only
other = /dev/sda
  # Windows doesn't go to S3 sleep and has issues with backup,
  # unless it sees its disk as first in BIOS...
  boot-as = 0x80
  label = Windows
other = /dev/disk/by-id/ata-ST3320620AS_ABCD1234-part4
  label = OSX
Oh, and of course, don't forget to edit your /etc/fstab as required, if you still use /dev/sdX# entries there.

2011-08-31

Enabling serial console on Linux Slackware

I'm doing this frequently enough to warrant a post.
  1. Make sure you use a kernel with console enabled

  2. Confirm that your serial tty's are detected with dmesg | grep tty:
    [    0.000000] console [tty0] enabled
    [ 1.323949] serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
    [ 1.568561] serial8250: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
    [ 1.592267] 00:0c: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
    [ 1.614293] 00:10: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A

  3. Edit /etc/securetty and uncomment the lines matching the ttyS you got from dmesg. Else you won't be able to logon as root.

  4. Edit your /etc/inittab and uncomment the lines:
    s1:12345:respawn:/sbin/agetty -L ttyS0 9600 vt100
    s2:12345:respawn:/sbin/agetty -L ttyS1 9600 vt100
    While you're at it, you probably want to change the 9600 vt100 to 115200 linux, if you use putty in serial mode to connect for instance.

  5. If you want the boot messages on serial as well (recommended!), make sure you append a console= line to your kernel. For instance, if using LILO and for 115200 bauds, you would add a line:
    append = "console=ttyS0,115200"

2011-05-23

Installing OSX (Snow Leopard) + Linux (Slackware 13.37 x86_64) on a GUID/GPT disk, with Software RAID enabled (ICH8R) - Part 1

Now that's quite a mouthful of a title. And considering that there is much to discuss, I will break this whole thing into a multipart post, so here is the first part of our series.

Introduction & Requirements

First of all, I gotta start with the disappointing news that, despite what you might anticipate from the title, this is not a guide to setup motherboard RAID (a.k.a. fakeRAID) support in either OSX or Linux (though the later is no biggie - see previous posts here for various options). The mention of RAID here is to indicate that we want to do an OSX and Linux that coexists nicely with a previous fakeRAID installation, by NOT requiring you to disable RAID settings in BIOS if they are already enabled.

In practice here, the goal is to add OSX and Linux on a separate non-RAID disk to an existing Windows 7 installation that was set to use fakeRAID (RAID 1 from ICH8R), without touching the BIOS settings.

Basically, what happened is that I recently upgraded my good old Asus P5B Deluxe based rig to a dual Samsung F3 1TB, installed Windows 7 ontop of the ICH8R RAID 1 array which I created in BIOS as a result, and since that left me with a bunch of unused SATA drives, I thought I would put one of these to good use by installing both OSX and Slackware on it (that Slackware 13.37 sure IS nice!), and use it to boot the whole lot. Sounds easy, but it actually presents a nice set of challenges, some of which include:
  • Adding extra drivers to a vanilla OSX installation media, so that it recognizes our AHCI controller even in RAID mode
  • Allow LILO (or GRUB) to boot OSes other than the main Linux system on a GPT/GUID partitioned disk (with a BIOS that is NOT EFI)
  • Installing OSX Snow Leopard from scratch, including updates and necessary drivers for your rig, but WITHOUT having to spend one's life endlessly browsing the OSX86 forums. Yes, the effort is much appreciated guys, but I have better things to do then become an expert on kexts, Chameleon, DSDT, iBoot and whatnot.
My specs:
  • Asus P5B Deluxe with 2x 1TB SATA HDDs in RAID mode (ICH8R) and 1x 320GB HDD (non RAID)
  • nVidia GPU (7950GT)
  • PS/2 keyboard, USB mouse + IDE DVD (the DVD is only going to be used for iBoot, so SATA or IDE won't matter one bit)
Requirements:
  • OSX Snow Leopard official installation DVD or .dmg image (build 10A421A)
  • One 8 GB (or bigger) USB key
  • An existing Snow Leopard installation. Yeah, I know it sucks, but hey.
That last item means either you need to create a VMWare image from the DVD media, or borrow a friend's Mac, but we want to create a USB OSX installation medium, which we can customize so there's little way to bypass that requirement. If you really don't have access to a preexisting OSX system, it's probably possible to create an USB key from Linux from the OSX installation DVD, but I haven't tried it so I can't comment on that. Besides, a VMWare image with Snow Leopard shouldn't be that hard to find.

My kingdom for AHCI? Surely you are jesting!

Question: What do all the hackintosh installation guides you find on the internet have in common?
Answer: They all begin with "You MUST change your BIOS settings and set your SATA controller to AHCI before you begin the installation"

Of course, this is utter nonsense. If a guide begins with "You MUST change your BIOS settings to something potentially incompatible with what you want, and risk destroying existing data as a result" (by disabling RAID mode from ICHR), then it's a lousy guide and you should stop right there. For having been a fakeRAID/motherboard RAID user for some years now, with both Intel and nVidia solutions, I'll tell you frankly: all those who say "Don't use fakeRAID: buy a dedicated RAID controller instead" are idiots. First of all, money to buy a separate controller doesn't grow on tree and secondly, with all these cores lying around, the idea that one should spend extra, when all they want is add fault tolerance to consumer grade hardware is ludicrous. We're not building an enterprise grade server here dammit! Besides, most of these solutions are rather well supported in Linux now, which means that if you screw up your fakeRAID array, you may just be able to do something about it. With a hardware proprietary non reverse engineered RAID solution on the other hand, you might not be so lucky...

Therefore, the hell with changing your BIOS settings to AHCI! If Linux doesn't bat an eyelid about accessing SATA HDDs with an ICH controller in RAID mode, why should OSX be the exception? Therefore, we'll keep our ICH BIOS settings to RAID, thank you very much, and ignore all this AHCI brainwashing.

Now, since the OSX installation media has not been designed to support ICH8 in RAID mode, if you try something like iBoot and an unmodified OSX installation media, then unless your HD is plugged on a JMicron SATA controller (which is an actual possibility on the P5B Deluxe), the OSX installer will not see it. This basically means we're gonna have to modify the OSX installation system so that it sees our ICH8R controller as AHCI ICH8 and that's also where doing the install from an 8GB (or more) USB key, that we can modify on the fly, will come real handy.

But first, we gotta create the base vanilla installer on our key.

Creating a vanilla OSX installation USB key

To do that, you need to be in your existing OSX system (VMWare, soon-to-be-ex-friend's machine, etc.). I'm going to assume that you have the vanilla OSX disk as a .dmg. The steps to create the key then are as follow:
  1. Plug in your USB key. Don't worry if it automounts.
  2. Open the OSX disk utility (Applications -> Utilities ->Disk Utilities). You should see something like "8.02 GB Generic STORAGE DEVICE Media" or something, as your USB volume
  3. Click on the "Partition" button on the left, to access the partition tab, then click on the "Current" Volume Scheme button so that you get a dropdown, and select 1 partition
  4. In options, under the partition diagram, make sure you select "GUID Partition Table". For the Format, you select "Mac OS Extended" (though it shouldn't matter)
  5. Click Apply to partition & format the USB key
  6. Once formatting is complete, select the Restore button
  7. Now double click on your OSX .dmg image to mount it (or insert your OSX DVD). A "Mac OS X Install DVD" icon should appear on your desktop
  8. Drag that icon onto the Source field of the Restore parameters in Disk Utility until a green '+' sign appears, and then drop it there
  9. For the Destination field, just drag and drop the "Untitled 1" partition, or whatever you called it, from your newly formatted USB stick
  10. Click the "Restore" button. You will be prompted for the system's administrative password.
For those who want to see it for themselves, the whole process of creating an OSX installation USB key is demonstrated by the first part of the video below (credits go to stellarola - you can ignore the Stella Magic part that comes afterwards):



The restore process will take a few minutes (15-30 mins), but, once completed, will give you the ability to install OSX from USB using iBoot.

Installing a text editor

Because we're going to do it the hard way, a must have for our USB key is a text editor, so that we can tune the USB key to our needs during the installation process (more about this in the next post). As a UNIX veteran, I swear by vi, but I do understand that not everybody is confortable with vi sequences, so to alleviate the editing process, we'll go with the more intuitive GNU nano.

One might wonder why there is no default editor on the vanilla OSX installation media, but the answer is that Apple obviously considered an installer to be read-only affair, so it made little sense adding vi or nano to the installation utilities. On the other hand, we will very much require the ability to edit files on USB, so we need a text editor for OSX. Of course, since GNU nano is GPL and therefore, anybody can legally publish a nano OSX binary to copy onto an USB key, I'm not going think twice about putting the one I conveniently recompiled from source (using Xcode 3.2) and that I am putting online here.

Once downloaded, just drag and drop the "nano" file onto your USB stick folder (where you'll see the OSX installation paraphernalia). As long as it's on the key, we're good - no need to worry about placing it into bin/ or usr/bin/ just yet. Once it's copied, you can eject the USB, as at this stage, we won't need to access another OSX system: we'll just do everything we need from USB.

iBoot

Finally, the last piece we need for the installation is the latest iBoot CD (bugmenot). And while on the iBoot download page, you might as well download MultiBeast, as it will come handy to finalize our installation.

The iBoot zip basically contains an ISO which you should burn to a CD. Note that if you can't use a CD, you should be able to use that ISO image to produce an alternate iBoot loader (eg use a second USB key or TFTP), but I'm not going to detail that.

2010-08-13

Formatting a PSP Memory Stick for use with a Pandora battery in Linux

Always a pain to do, and nobody seems to provide the files I want, so I'll just provide my own files (using ipl_ms.bin => no frills, just normal boot) and a short script.

Once extracted, just run something like:
root@sheeva:~/pandora# ./format_ms.sh /dev/sda
+ dd if=/dev/zero of=/dev/sda bs=512 count=32
32+0 records in
32+0 records out
16384 bytes (16 kB) copied, 0.00699201 s, 2.3 MB/s
+ parted /dev/sda
GNU Parted 1.8.8
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) mklabel msdos
(parted) mkpartfs primary fat16 32s -1s
(parted) set 1 boot on
(parted) set 1 lba off
(parted) u s
(parted) p
Model: Generic STORAGE DEVICE (scsi)
Disk /dev/sda: 3995648s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number Start End Size Type File system Flags
1 32s 3995647s 3995616s primary fat16 boot

(parted) q
Information: You may need to update /etc/fstab.

+ dd if=ipl_ms.bin of=/dev/sda bs=512 seek=16
4+1 records in
4+1 records out
2288 bytes (2.3 kB) copied, 0.00179176 s, 1.3 MB/s
+ mount /dev/sda1 tmp_mnt
+ tar -C tmp_mnt -xvf ms.tar
ISO/
ISO/VIDEO/
MEMSTICK.IND
MP_ROOT/
MP_ROOT/100MNV01/
MP_ROOT/101ANV01/
MSTK_PRO.IND
MUSIC/
PICTURE/
PSP/
PSP/GAME150/
PSP/GAME5XX/
PSP/GAME/
PSP/SAVEDATA/
PSP/COMMON/
PSP/SYSTEM/
PSP/THEME/
PSP/RSSCH/
PSP/RSSCH/IMPORT/
VIDEO/
seplugins/
+ umount tmp_mnt
+ sync

2009-10-09

Installing Slackware on the SheevaPlug

And so, finally, we come to the final part of our series regarding the setting up of our SheevaPlug with Linux. Thanks to the good guys at armedslack, we will have the best Linux distro ever, running on one of the coolest little devices around.

For this setup, we will install Slackware on an 8 GB High speed SDIO MMC card, and leave the NAND flash untouched with its updated Ubuntu version. This will also suppose that you have a working kernel that supports ext4 and all the features you want already installed on the flash (if not, refer to this post to to set it up). Now, we are going to deviate a little bit from the "official" armedslack intallation guide for the SheevaPlug, as we are not going to use TFTP for our packages but instead read them directly from an USB device.

And so, without further ado:
  1. Download the packages from armedslack.org. The only directories you really need are the "slackware", "isolinux" and "kernels" directory from ftp://ftp.armedslack.org/armedslack/armedslack-current/. If you're downloading from a Linux system, one way to do it, as advertised in the armedslack installation readme is:
    rsync --exclude '*/source/*' --delete -Pavv ftp.armedslack.org::armedslack/armedslack-current .
    (NB: If you use Filezilla to download from FTP, please note that it seems to default to ASCII mode instead of binary, so don't be surprised if your files are corrupted!)
    This amounts to about 2 GB of files, so it will take a while, but the filesystem used for the target shouldn't matter much, as long as it is accessible from the default armedslack kernel. So if you have a FAT formatted USB stick lying around, with more than 3 GB space available, you should probably use that.
    I also have to point out that we are downloading slackware-current, which contains an up-to-date version of the packages, but is different from a dot release, so you might see some versioning differences between current and what you get on the official x86 dot releases.
    For the remainder of this guide, I will assume that you have the directories (slackware/, isolinux/ and kernels/) in an "armedslack/" directory at the root of a FAT formatted USB device. Note that if you're not using a FAT formatted device, you will need to copy the kernel and initrd image on a separate device that can be read from U-boot

  2. Alright, time to reboot the system, with your USB and MMC card plugged in and enter the Marvell>> U-boot prompt through the serial console. There, you need to issue the following:
    Marvell>> usb start
    
    (Re)start USB...
    USB: scanning bus for devices... 2 USB Device(s) found
    scanning bus for storage devices... 1 Storage Device(s) found
    Marvell>> fatload usb 0 0x00800000 armedslack/kernels/kirkwood/uImage-kirkwood
    reading armedslack/kernels/kirkwood/uImage-kirkwood
    ...
    ................................................................................

    1887248 bytes read
    Marvell>> fatload usb 0 0x01100000 armedslack/isolinux/uinitrd-kirkwood.img
    reading armedslack/isolinux/uinitrd-kirkwood.img
    ...
    ................................................................................

    10985095 bytes read
    Marvell>> setenv bootargs console=ttyS0,115200 nodhcp kbd=uk root=/dev/ram rw;bootm 0x00800000 0x01100000
    If all is well, you should be seeing your usual Slackware installation screen.
    Please note that because of the "kbd=uk" line above, your keyboard will be automatically set to uk, so change it accordingly.
    Also, if you want to use a network session rather than the serial console, you should issue:
    dhcpcd eth0
    
    /etc/rc.d/rc.dropbear start
    Then you can find your IP address through ifconfig and ssh to it.

  3. If needed, you should use fdisk to partition your MMC device:
    fdisk /dev/mmcblk0
    On my system, I created a 512MB /dev/mmcblk0p1 partition for Swap (type 0x82) and left the rest as /dev/mmcblk0p2 for Linux (type 0x83)

  4. If you had a look at dmesg, you should see that your USB device has been detected by the kernel (normally as /dev/sda). Since we have our Slackware package on that device, this is what we are going to use for the source. I have found out however that:
    - If you attempt to mount the directory manually and chose the Install from a pre-mounted directory option in SOURCE MEDIA SELECTION, MAKE SURE that your path ends with the slackware/ directory where the a/, ap/, d/... packages reside and NOT the one where extra/, isolinux/, kernels/... reside. If you don't, setup will happily list the packages but fail to install them and produce a completely irrelevant error!
    - If you select "Install from a hard drive partition" but haven't previously mounted the partition, it will fail to mount the directory properly.
    For now, we will use the "Install from a hard drive partition" option, but we first need to mount that partition manually.
    And remember that the Slackware setup process uses /mnt for its own purpose, so you should not use that location as a mountpoint. So:
    mkdir /usb
    
    mount /dev/sda1 /usb
    echo "mmc0" > /sys/class/leds/plug\:green\:health/trigger
    setup
    The "echo mmc0" line in there is a trick to get the blue LED act as an MMC card access indicator, as, if you're like me, you want to see some indication of r/w access to your root device.

  5. Setup should be smart enough to detect your Swap & Linux mmc partitions, and format them (the default ext4 is a good choice for a filesystem). With regards to the SOURCE MEDIA SELECTION screen, you should now select "2 Install from a hard drive partition" then enter "/dev/sda1" as the device and "/armedslack" as the path (or whatever you called your directory on the USB). If you did mount your partition beforehand, this will work and you will then be able to select the packages straight off the USB.

  6. From there, it's your run-of-the-mill package selection and installation. On my 8 GB SD Card, I found that selecting everything but GNU Emacs, TeX, KDEI and the Kernel sources resulted in a 3.7 GB installation, thus leaving about 2.9 GB free space, which is fine. Of course, if you want more space, you can fine tune your package selection or use a bigger SD card.

  7. After you've gone through the rest of the configuration (network, etc) you can reboot the system and get back to the Marvell>> U-Boot prompt. There we will want to test that the custom kernel we've been using to boot Ubuntu can also boot our Slackware installation. Again, this supposes that you followed the steps from my earlier post regarding custom kernel installation and flashing. If not, now is probably a good time to follow this post to to flash the uImage-kirkwood kernel that you used for setup.

    To test that your current NAND kernel can boot Slackware:
    # Preliminary check to see if your bootargs_console variable is
    
    # properly defined. if not, make sure you set it up
    Marvell>> printenv bootargs_console
    bootargs_console=console=ttyS0,115200
    # This defines our root device. Make sure that use the right device, and that you mount it "ro"
    Marvell>> setenv bootargs_root root=/dev/mmcblk0p2 rootfs=ext4 ro
    Marvell>> setenv bootargs $(bootargs_console) $(bootargs_root)
    Marvell>> printenv bootcmd
    bootcmd=nand read.e 0x800000 0x100000 0x400000; bootm 0x800000
    # Your bootcmd should only read the kernel and boot from it.
    # If not, just issue the 2 commands above instead of what follows
    Marvell>> run bootcmd
    You should then be able to boot into your newly installed Slackware Linux. If not, you might want to check your parameters and install & flash a kernel that works.
    Now, while we have confirmed that your system can indeed boot, we haven't yet saved anything on the flash to make it the default, so you need to reboot into the Marvell prompt once more, and this time:
    # First, we start by saving the current working bootargs so that if you ever want
    
    # to get back to Ubuntu, you can issue a "setenv bootargs $(bootargs_rescue)"
    Marvell>> setenv bootargs_rescue $(bootargs)
    Marvell>> setenv bootargs_root root=/dev/mmcblk0p2 rootfs=ext4 rootwait ro
    Marvell>> setenv bootargs $(bootargs_console) $(bootargs_root)
    Marvell>> saveenv
    Saving Environment to NAND...
    Erasing Nand...Writing to Nand... done
    Marvell>> reset
  8. After this last command, the plug should automatically boot into Slackware and you can finalize your installation.

    IMPORTANT: You VERY MUCH want to add a rootwait parameter to your bootargs, which ensures that the SD is ready before the kernel attempts to mount it as rootfs. Otherwise, you may end up with maddening kernel panics when mounting rootfs, especially after a power failure, that are really due to the SD card not being ready yet.
    Another alternative would be to add rootdelay=## but if you read here, you'll see that rootwait is the smarter option.

    One thing you might want to do, as we did during the install, is set the blue LED as an MMC access indicator.
    On my system, I did that by editing /etc/rc.d/rc.S and adding the line:
    # Set the blue LED as SD access indicator
    
    echo "mmc0" > /sys/class/leds/plug\:green\:health/trigger
    just before the section
    # Enable swapping:
    
    /sbin/swapon -a



Using the SheevaPlug as an iSCSI target for Vista or Windows 7

(Updated 2010.08.08)

Well, since I played with this iScsi stuff just for the sake of it, I might as well post a quick guide.

For this setup, I will be using the SheevaPlug running Slackware 13.0 (armedslack) on an SDIO card, a 100 GB HDD connected to the plug through USB (/dev/sda, but you could use a partition or even an image file) and a version of Windows that supports iSCSI (Vista or later). The SheevaPlug server has been creatively named "sheeva".

Compiling

The de-facto iSCSI target server tool for Linux is the Linux SCSI target framework (tgt) project (NB: you know you need to come up with better designation when your URL is actually shorter than your project name), so off we go and download the latest version (Important note: at the time of this post update, version 1.0.7 doesn't appear to work for the SheevaPlug, but 1.0.5 does).
We're pretty much going to follow the "./doc/README.iscsi" from the archive, so you might want to keep that file open for reference.
Once extracted on the SheevaPlug, cd to the usr/ directory and issue a "make ISCSI=1; make install". This package is not that big, so we can compile it on the Plug directly. Remember to add ISCSI=1, as default make will not have iSCSI.

Starting the target server daemon

After that, as root, you need to launch the daemon with
tgtd
The syslog should tell you that everything's rolling with a line like
Oct  9 12:46:23 sheeva tgtd: Target daemon logger with pid=1897 started!

Setting up the iSCSI target

This is where the bulk of our configuration occurs. What we're going to set below is an iSCSI drive named "sheeva:hd100" that maps to our /dev/sda HDD.

  1. First we need to create that device:
    root@sheeva:~# tgtadm --lld iscsi --mode target --op new --tid 1 --target sheeva:hd100
    root@sheeva:~# tgtadm --lld iscsi --mode target --op show
    Target 1: sheeva:hd100
    System information:
    Driver: iscsi
    State: ready
    I_T nexus information:
    LUN information:
    LUN: 0
    Type: controller
    SCSI ID: IET 00010000
    SCSI SN: beaf10
    Size: 0 MB
    Online: Yes
    Removable media: No
    Backing store type: rdwr
    Backing store path: None
    Account information:
    ACL information:
    root@sheeva:~#
  2. Now, despite the fact that a device with LUN0 was created as shown above, this is just a virtual controller device, not a physical target, and we still need to create a LUN for our device:
    root@sheeva:~# tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 1 --backing-store /dev/sda
    root@sheeva:~# tgtadm --lld iscsi --mode target --op show
    Target 1: sheeva:hd100
    System information:
    Driver: iscsi
    State: ready
    I_T nexus information:
    LUN information:
    LUN: 0
    Type: controller
    SCSI ID: IET 00010000
    SCSI SN: beaf10
    Size: 0 MB
    Online: Yes
    Removable media: No
    Backing store type: rdwr
    Backing store path: None
    LUN: 1
    Type: disk
    SCSI ID: IET 00010001
    SCSI SN: beaf11
    Size: 100030 MB
    Online: Yes
    Removable media: No
    Backing store type: rdwr
    Backing store path: /dev/sda
    Account information:
    ACL information:
    root@sheeva:~#
    This time, we have our physical device listed. Note that you could also mount a partition instead of a whole device, and make it appear as a device through iSCSI

  3. At this stage, we have a target, but it doesn't accept inbound connections ("ACL information" is empty), so:
    root@sheeva:~# tgtadm --lld iscsi --mode target --op bind --tid 1 --initiator-address ALL
    root@sheeva:~# tgtadm --lld iscsi --mode target --op show
    Target 1: sheeva:hd100
    System information:
    Driver: iscsi
    State: ready
    I_T nexus information:
    LUN information:
    LUN: 0
    Type: controller
    SCSI ID: IET 00010000
    SCSI SN: beaf10
    Size: 0 MB
    Online: Yes
    Removable media: No
    Backing store type: rdwr
    Backing store path: None
    LUN: 1
    Type: disk
    SCSI ID: IET 00010001
    SCSI SN: beaf11
    Size: 100030 MB
    Online: Yes
    Removable media: No
    Backing store type: rdwr
    Backing store path: /dev/sda
    Account information:
    ACL information:
    ALL
    root@sheeva:~#
  4. Here you might want to find out if Windows is able to see our target, so you can fire up the iSCSI Initiator (in Control Panel -> Administrative Tools). If you are prompted to enable the iSCSI service on startup and modify the firewall rules, accept it.
    Now, if you go to the "Targets" tab and press Refresh, you'll probably see that your target is not yet detected.
    To make it appear in the target list, you want to go to the "Discovery" tab and click "Add/Discover Portal". Then provide the IP/DNS of your server. Port 3260 should be fine as it's used by the Target daemon on the Linux server.
    After doing this, if you go to the "Targets" tab again, you should see something like this listed:
    sheeva:hd100              Inactive
    If not, you might want to check your daemon, firewall, etc. as you should be able to detect the target at this stage.

  5. If you're fine with anybody being able to connect to our iSCSI target on your network, then you can just try to press "Log On" in the Targets tab, and you should be able to connect. You can then go to Computer Management, and you should be able to see the disk!
    You should also see who is connect to your target in the "I_T nexus information" section from tgtadm in Linux:
    root@sheeva:~# tgtadm --lld iscsi --mode target --op show
    Target 1: sheeva:hd100
    System information:
    Driver: iscsi
    State: ready
    I_T nexus information:
    I_T nexus: 4
    Initiator: iqn.1991-05.com.microsoft:dusk
    Connection: 1
    IP Address: 192.168.1.184
    LUN information:
    LUN: 0
    Type: controller
    SCSI ID: IET 00010000
    SCSI SN: beaf10
    Size: 0 MB
    Online: Yes
    Removable media: No
    Backing store type: rdwr
    Backing store path: None
    LUN: 1
    Type: disk
    SCSI ID: IET 00010001
    SCSI SN: beaf11
    Size: 100030 MB
    Online: Yes
    Removable media: No
    Backing store type: rdwr
    Backing store path: /dev/sda
    Account information:
    ACL information:
    ALL
    root@sheeva:~#
    Pretty cool, heh?
    If you do want to restrict access, you should of course follow the README.iscsi and add iSCSI target accounts. Then you can provide these credentials to the CHAP logon parameters in Windows (which can be accessed by clicking "Advanced" in the "Log On to Target" dialog. Be warned however that Windows will return a "CHAP secret given does not conform to the standard" error if your password is too short, so you need to make it at least 10 characters or more.
    To disconnect from a target, on Vista, simply click on "Details", select its Identifier and click "Log off...". For Windows 7, Microsoft did the wise thing and added a "Disconnect" button.

    IMPORTANT NOTE: Because we used LUN 1, and not LUN 0, if you attempt to boot from this newly created iSCSI disk, you MUST fill in the LUN parameter in the iSCSI root path syntax (the sequence of 4 columns that most guides will leave blank). In our case, if we wanted to use the device above for booting with gpxe/dnsmasq, we would add the following in dnsmasq.conf:
    dhcp-option=net:gpxe,17,"iscsi:192.168.1.3:::1:sheeva:hd1"
    Notice that there is a "1" for the LUN before "sheeva:hd1" and that we used :::1: instead of ::::. Likewise if you use a nonstandard port (different than 3260), you would use something like ::<custom port>:<LUN>:<target name>. This is detailed in RFC 4173, or you can find more information here.

2009-10-07

Checking removable media for badblocks on Linux

This comes handy when you are flashing firmwares from USB and don't want to take any risk with data corruptions (most firmwares images have checksums or CRCs, but who knows...)

Linux provides a badblock command to do just that. Obviously, this is a DESTRUCTIVE test (all data on your media will be erased without warning), and you'll need to reformat your media afterwards. Oh, and of course the badblocks command is available on the SheevaPlug.
badblocks -t random -svw <your_device>

2009-10-06

Using the blue LED on the SheevaPlug

As mentioned here, it is possible to control the blue LED on the Plug and use it for notification.
The LED itself is accessible as /sys/class/leds/plug\:green\:health, and as mentioned in the Linux LED Documentation, it is possible to find out the available LED functions (triggers) through:
~# cat /sys/class/leds/plug\:green\:health/trigger
none nand-disk mmc0 timer heartbeat [default-on]
Thus, if you want a heartbeat effect, you would issue the command:
echo "heartbeat" > /sys/class/leds/plug\:green\:health/trigger
Now, on the more useful side, with a default Linux image running on the NAND flash, you might want to enable "nand-disk" to monitor said flash activity. Please be aware however that the LED behaviour in this case is quite different from your run-of-the-mill HDD access activity (which is a good thing - the less actual access to the NAND, the less wear and tear). In short, UBIFS does its job and reduces NAND accesses to the bare minimum, which in turn results in little NAND activity actually going on. A couple of well placed "sync" should suffice to convince you that "nand-disk" works as expected though.

If you're using the default Ubuntu running on the NAND Flash, you probably want to add the following to your /etc/rc.local then:
echo "nand-disk" > /sys/class/leds/plug\:green\:health/trigger

Recompiling a new kernel for the SheevaPlug

There are many reasons why you would want to use a custom kernel on the plug. As far as I am concerned, the lack of ext4 and ntfs support in the kernel provided with the otherwise excellent SheevaPlug installer 1.0 system make a clear case for a custom kernel. After all, you might wanna mount external HDDs that are NTFS formatted, or, more important, you might want to install/access a Linux system running with ext4 (which I hear is nicer on flash based media devices than ext3), as we will do when we install armedslack on an SDIO card.


Setting up a cross-compiler for the SheevaPlug on Linux x86_64

While it is definitely possible to recompile a kernel on the SheevaPlug itself, let us just consider the raw compilation times observed when compiling a 2.6.31.2 kernel (exact same .config) on the Sheeva and on a more up to date PC:
- Quad Core PC (Slackware 13.0 x86_64 w/ ext4 fs on a RAID5 array) - 3:03 mins (183 secs)
- SheevaPlug (Ubuntu 9.04 w/ ext4 fs on a high speed SDIO card) - 57:42 mins (3462 secs)

That's one full order of magnitude right there (or about 20x slower)! And if you need a further case for cross-compilation, remember that extracting the kernel source takes ALOT of space. You will run out of space if you try to extract it on the internal flash NAND - it's just too big for what's left of the 512 MB space, and even on external media, you might want to think twice about using the limited space you have there.

If you're familiar with this blog, you know that there's no way we'll want to use any of the old, likely outdated, tools that came with the SheevaPlug SDK CD or internet binaries got compiled by people we don't know (and therefore don't trust!). Besides, the Cross compiler tgz I got on the CD has a big fat CRC error to start with, and it's 32 bit while our cross compiling rig is running Linux x86_64. If what we've seen with the 32 bit openocd binaries is any indication of what's in store for 64 bit users, we might as well cut to the chase and ignore anything that's not 64 bit.
What we do want, and always will want, is the most cutting edge and up to date technology we can lay our hands on. Therefore, we will of course recompile our own cross compiler for the SheevaPlug using the latest gcc, glibc and binutils.

Now, we could of course dive in straight ahead, and recompile, by hand, the whole cross-compiling shebang, but let's face it: your time is precious, so is mine, and if you just dive in head first in trying to produce a cross compiler from the GNU vanilla tarballs, whilst having no previous experience in the matter, you'll find soon enough that:
  1. Compiling a cross compiler manually is absolute hell!
  2. glibc and gcc have to be the worst offenders for breaking things that worked perfectly fine before with newer versions. All those rumours you've heard about needing to apply a massive amount of patches to gcc and gblic before you can compile them as cross-compilers? They're true!
Fact of the matter is I wasted more than one afternoon yesterday on the "Heck, I'm smarter than that - I'll go manual!" approach, and, while I now have a clearer idea of how one might get a cross-compiler actually compiled from scratch, I'll just say this: Do yourself a favour - if you value your time, don't waste it in trying to create a cross-compiling toolchain by hand.
Now, if you really, really, insist on compiling a whole toolchain manually, then my advice is to try to stick as close as possible to this guide (trust me!), but don't come whining that I didn't warn you you were about to step through the gates of hell beforehand...


Using CrossTool-NG

The MUCH better approach, to automate the cross compilation setup process is to use Yann E. Morin's most excellent Crosstool-NG. And, yes, despite being an automated tool, it will not compromise on our using the latest versions of gcc, glibc, binutils, etc.

So off we go:
cd /usr/src
mkdir sheeva
cd sheeva
wget http://ymorin.is-a-geek.org/download/crosstool-ng/crosstool-ng-1.4.2.tar.bz2
tar -xjvf crosstool-ng-1.4.2.tar.bz2
cd crosstool-ng-1.4.2
./configure
make
make install
cd ..
ct-ng menuconfig
Well, isn't that nice - a kernel like configuration menu. Alrighty then, here are the options you want to change for the SheevaPlug:
  • Paths and misc options
    • Try features marked as EXPERIMENTAL: check
    • Prefix directory: "/usr/local/${CT_TARGET}" (this will result in all the tools residing in /usr/local/arm-unknown-linux-gnueabi) or, preferred: "/usr/local/sheeva". One important note though: DO NOT USE /usr/local or any directory containing data you plan to keep. THIS DIRECTORY WILL BE ERASED. You have been warned.
    • Use LAN mirror: Let's try to use a mirror there, so - check
      • Prefer the mirror: check
      • Base URL: ftp://ftp.heanet.ie/mirrors/ftp.gnu.org/gnu/ (this is an Irish mirror - not entirely sure it works, as the downloads didn't seem much faster, but worth a try)
    • Stop after extracting tarballs: check (we'll need to patch glibc!)
    • Number of parallel jobs: 2x the number of cores you have. In my case that would be 8 (quad core)
    • Maximum log level to see: change from "INFO" to "EXTRA"
  • Target Options
    • Target Architecture: arm
    • Use EABI: check
    • Emit assembly for CPU: arm926ej-s
    • Floating point: change from "hardware (FPU)" to "software"
  • Toolchain options: don't change anything
  • Operating System:
    • Target OS: change from "bare-metal" to "linux"
    • Get kernel headers from: change from "kernel's 'headers_install'" to "Use custom headers"
    • Path to custom headers directory/tarball: "/usr/src/sheeva"
  • GMP and MPFR:
    • GMP and MPFR: check
    • GMP version: 4.2.4 (latest)
    • MPFR version: 2.4.1 (latest)
  • binutils
    • binutils version: 2.19.51.0.2
  • C compiler:
    • gcc version: 4.3.3
    • C++: check
  • C-library:
    • C library: glibc
    • glibc version: 2.9
    • Threading implementation to use: make sure "ntpl" is set.
The rest should be left untouched. For your reference, I am providing the Crosstool-NG .config file I used. Please note that if you use a recent version of glibc, you MUST have a threading implementation set, but you can NOT use linuxthreads, as it's been deprecated (you WILL get errors if you do select it), so the only option to use in nptl.


Kernel headers & glibc 2.9 patch

Before you can run the build, we still need to setup our kernel headers.
At the time of this writing, the most recent kernel is linux-2.6.31.2, so just download and extract it somewhere. Then, within the linux-2.6.31.2/ directory, run the command:
make headers_install ARCH=arm INSTALL_HDR_PATH=/usr/src/sheeva
The INSTALL_HDR_PATH should match exactly what you used for "Path to custom headers directory/tarball" in the menuconfig of Crosstool-NG.
You should now find that you have an "include" directory containing the relevant kernel headers in /usr/src/sheeva

Once you have everything setup, you need to go back to the sheeva directory (because this is where the ct-ng config resides) and launch the build with:
cd /usr/src/sheeva
ct-ng build
If you followed what we did above, you will note that we checked the "Stop after extracting tarballs" option, and indeed the build process stops after "Extracting and patching toolchain components". The reason we did that is because glibc 2.9 needs to be manually patched to prevent the following error (undefined reference to `_begin') from occurring:
[ALL  ]    /usr/src/sheeva/targets/arm-unknown-linux-gnueabi/build/build-libc/elf/librtld.os: In function `_dl_start_final':
[ALL ] raise.c:(.text+0x54c): undefined reference to `_begin'
[ALL ] /usr/src/sheeva/targets/arm-unknown-linux-gnueabi/build/gcc-core-shared/lib/gcc/arm-unknown-linux-gnueabi/4.3.3/../../../../arm-unknown-linux-gnueabi/bin/ld: /usr/src/sheeva/targets/arm-unknown-linux-gnueabi/build/build-libc/elf/ld.so: hidden symbol `_begin' isn't defined
[ALL ] /usr/src/sheeva/targets/arm-unknown-linux-gnueabi/build/gcc-core-shared/lib/gcc/arm-unknown-linux-gnueabi/4.3.3/../../../../arm-unknown-linux-gnueabi/bin/ld: final link failed: Nonrepresentable section on output
[ALL ] collect2: ld returned 1 exit status
(...)
[ERROR] Build failed in step 'Installing C library'
This known problem is documented here and if you have a look at the diff file, you'll see that we can easily manually patch this problem by editing "targets/src/glibc-cvs-2.9/elf/Makefile" and replace, on line 314:
-e 's/\. = 0 + SIZEOF_HEADERS;/& _begin = . - SIZEOF_HEADERS;/' \
with
-e 's/\. = .* + SIZEOF_HEADERS;/& _begin = . - SIZEOF_HEADERS;/' \

Building the cross-compiler


Once you have made this change, just launch ct-ng menuconfig again (from the /usr/src/sheeva directory, as this is where the config file resides) and remove the checkmark on "Stop after extracting tarballs" (in the "Paths and misc options" menu)

Now, you can launch the actual build of the tools with
ct-ng build
This will take a little while (about 15 mins on my machine) but should complete successfully. If you have a multiple core system, hopefully you didn't forget to change the "Number of parallel jobs" option (which is equivalent to the -j option of make, i.e. number of concurrent jobs to run at once), as this dramatically reduces the time it takes to compile the toolchain. The -j option should always be your friend when compiling a large source, like a Linux kernel for instance.

Time for a tea or coffee break!

Note that, near the end of the compilation, you might get the error "[ERROR] libtool.m4: error: problem compiling FC test program". From what I gather however, FC is a test for the Fortran 90 compiler, which we couldn't care less about, so, unless you got another error, I will consider this build process of success, and you should now have the whole set of cross compiler tools in /usr/local/sheeva/bin. Time to compile ourselves a new kernel!


Installing U-boot mkimage


While we now have the tools to create arm binaries, we're still missing the last piece of the puzzle to boot a kernel, and that is the mkimage utility (which is called at the end of a successful kernel compilation), which turns a newly crafted kernel into something U-Boot can actually launch.

You guessed it, no way in hell we're gonna use the Marvell provided mkimage tool - we're gonna recompile our own from source of course!
And once more, the good guys at Debian (never underestimate a Debianer!) provide us with what we need:
cd /usr/src/sheeva
wget http://ftp.de.debian.org/debian/pool/main/u/uboot-mkimage/uboot-mkimage_0.4.tar.gz
tar -xzvf uboot-mkimage_0.4.tar.gz
make
make install
Easy as a pie!


Cross-Compiling a new kernel for the SheevaPlug


At long last, we're ready to compile us some custom kernel!
At this stage, we can more or less follow the Compiling Linux Kernel for the Plug Computer tutorial from openplug.org . Henceforth:
cd /usr/src/sheeva/linux-2.6.31.2
make ARCH=arm kirkwood_defconfig
make ARCH=arm menuconfig
There, change the options that you want. If you plan to keep using UBIFS (which you should have switched to during the SheevaPlug Installer 1.0 upgrade), then make sure that you enable BOTH:
  • Device Drivers ---> Memory Technology Device (MTD) support ---> UBI - Unsorted block images ---> Enable UBI
  • File systems ---> Miscellaneous filesystems ---> UBIFS file system support
  • Device Drivers ---> Generic Driver Options, and make sure that both "Create a kernel maintained /dev tmpfs (EXPERIMENTAL)" and "Automount devtmpfs at /dev" are enabled. Without those, you won't see init messages on the serial console after the root filesystem is mounted.
With this set, and the other default options from kirkwood_defconfig, you should be able to produce a usable kernel. Now is obviously a good time to add ext4 & NTFS suppot, and remove features (802.11 stack) that you do not want. Finally, we're ready to compile, and the kernel makes cross compilation very easy for us, as its CROSS_COMPILE feature enables us to specify exactly which tools it should use instead of the default ones. Thus, because we have an arm-unknown-linux-gnueabi-gcc, arm-unknown-linux-gnueabi-ld, etc. in /usr/local/sheeva/bin, we will use the line:
make -j8 ARCH=arm CROSS_COMPILE=/usr/local/sheeva/bin/arm-unknown-linux-gnueabi- uImage
and in about 3 minutes (vs. one hour if done on the SheevaPlug) you should end up with something like
Image Name:   Linux-2.6.31.2
Created: Tue Oct 6 14:50:51 2009
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 3151992 Bytes = 3078.12 kB = 3.01 MB
Load Address: 0x00008000
Entry Point: 0x00008000
Image arch/arm/boot/uImage is ready

Building the modules


You probably still have a few modules to compile as well, which you can do as follows
make -j8 ARCH=arm CROSS_COMPILE=/usr/local/sheeva/bin/arm-unknown-linux-gnueabi- modules
make -j8 ARCH=arm CROSS_COMPILE=/usr/local/sheeva/bin/arm-unknown-linux-gnueabi- INSTALL_MOD_PATH=./modules modules_install
Just don't forget that you'll need to copy the content of the ./modules directory to your Ubuntu image to keep the kernel happy


Testing the new kernel on the plug

In a next post, we'll see how to actually flash that kernel on the plug. Before we do that though, we want to ensure that it can boot our current system, so we'll try to launch it from an USB stick.
Off we go then to copy your shiny new kernel to an USB stick with
mount /dev/sde1 /mnt/usb
cp arch/arm/boot/uImage /mnt/usb/
sync
umount /mnt/usb
For the test part, we'll need the serial console ("screen /dev/ttyUSB0 115200,-crtscts" or similar), with which we first reboot our system, and interrupt the autoboot to get to the Marvel >> prompt. From there, the following set of commands should boot the existing system with our new kernel:
usb start
fatload usb 0 0x00800000 uImage
bootm 0x00800000
Success? Then my work here is done.

2009-10-03

OpenOCD and the SheevaPlug on Linux x86_64

This is a tutorial for people like me who want to start with JTAG and OpenOCD access on the SheevaPlug. Most of this stuff regarding the installation of OpenOCD on Linux x86_64 is of course generic and can be used for other FTDI based JTAG devices like.

First of all, if you're running a 64 bit OS (Vista, Win7), a word of advice: Don't waste your time trying to get OpenOCD to work on a 64 bit Windows - there's no ready-made package that works (the 32 bit version just don't), so the only way is to recompile the whole shebang yourself, and it's a complete mess, as you will also need a 64 bit gcc-like compiler, and figure out how to get a 64 bit version of a the FTDI GPL library talk to the 64 bit libUSB drivers.
If I ever manage to get a Windows version going, you'll be the first to hear about it, but for the time being, if you value your time, stick with Linux.

Now, the distro I am using is Slackware x86_64. There are of course tutorials on how to compile OpenOCD for Linux here and there, but things are slightly different for 64 bit version, which is why I'm posting my own version.
  1. Before anything else, you want to have the serial console to the SheevaPlug through the USB FTDI device. For that you need to compile the kernel driver for the "USB FTDI Single Port Serial Driver" either as a module, or directly in your kernel. You will find that option, in the kernel, under: "Device Drivers ---> USB support ---> USB Serial Converter support ---> USB FTDI Single Port Serial Driver"
    Once you have the driver loaded, with the USB cable connected to the sheevaplug, you should get a /dev/ttyUSB0 device, which you can use as a regular serial port.
    The best way to connect to the SheevaPlug in Linux (or to any serial terminal for that matter) has to be to use screen, with a command like:
    screen /dev/ttyUSB0 115200,-crtscts
    Once you have confirmed that you can connect to the plug using the FTDI USB Serial converter driver, you can move to building OpenOCD, as it's a good indication that Linux should have no trouble accessing the rest of the FTDI chip functionalities

    • OPTION 1: Using the proprietary libftd2xx library from FTDI, provided for completion. Note that using this option will kill any opened serial console whenever you launch openocd, whereas this does not occur with OPTION 2 below, which I strongly advise you to use.
      On an x86_64 MUST pick up the 64 bit version of the Linux drivers from the FTDI website. At the time of this post, that means you must download libftd2xx0.4.16_x86_64.tar.gz, NOT libftd2xx0.4.16.tar.gz. What's more, when you install the library, it has to go into lib64, NOT lib else you will get the ominous
      checking whether ftd2xx library works...
      configure: error: Cannot build & run test program using ftd2xx.lib
      Thus:
      cd /usr/src
      wget http://www.ftdichip.com/Drivers/D2XX/Linux/libftd2xx0.4.16_x86_64.tar.gz
      tar -xzvf libftd2xx0.4.16_x86_64.tar.gz
      cp libftd2xx0.4.16_x86_64/libftd2xx.so.0.4.16 /usr/local/lib64
      ln -s /usr/local/lib64/libftd2xx.so.0.4.16 /usr/local/lib64/libftd2xx.so
      # even if you specify --libdir=/usr/local/lib64 on openocd compilation
      # it requires libftd2xx.so.0 in /usr/lib64!
      ln -s /usr/local/lib64/libftd2xx.so.0.4.16 /usr/lib64/libftd2xx.so.0
    • OPTION 2 (PREFERRED): Using the GPL/Open source version of the FTDI library
      cd /usr/src
      wget http://www.intra2net.com/en/developer/libftdi/download/libftdi-0.16.tar.gz
      tar -xzvf libftdi-0.16.tar.gz
      cd libftdi-0.16
      # by default, libftdi will go in /usr/local/lib, whereas, on x86_64, it should go to lib64, thus
      ./configure --with--libdir=/usr/local/lib64
      make
      make install
      # openocd looks in /usr/lib64
      ln -s /usr/local/lib64/libftdi.so.1.16.0 /usr/lib64/libftdi.so.1
  2. Now it's time to get OpenOCD compiled. For that:
    svn checkout svn://svn.berlios.de/openocd/trunk openocd
    cd openocd
    ./bootstrap
    # OPTION 1 - PROPRIETARY LIB FROM FTDI
    ./configure --libdir=/usr/local/lib64 --enable-maintainer-mode --enable-ft2232_ftd2xx
    # OPTION 2 - GPL FTDI LIBRARY
    ./configure --libdir=/usr/local/lib64 --enable-maintainer-mode --enable-ft2232_libftdi
    make
    make install
    Note that if you don't use the "--enable-maintainer-mode" option, you will get an error when make reaches the creation of the documentation, which is not a problem per se, but will prevent the openocd configuration scripts to be copied over on make install

  3. If the above completed successfully, then you have openOCD ready to run. To connect to the SheevPlug then, issue a:
    openocd -f /usr/local/share/openocd/scripts/board/sheevaplug.cfg
    At this stage, if you are getting the following, then you need to reboot the plug and launch openOCD in the early stages of reboot:
    Error: JTAG scan chain interrogation failed: all zeroes
    Error: Check JTAG interface, timings, target power, etc.
    Error: Trying to use configured scan chain anyway...
    Error: feroceon.cpu: IR capture error; saw 0x00 not 0x..1
    Warn : Errors during IR capture, continuing anyway...
    Error: unexpected Feroceon EICE version signature
    What you really want to see when launching openOCD is:
    root@stella:/usr/src/openocd# openocd -f /usr/local/share/openocd/scripts/board/sheevaplug.cfg
    Open On-Chip Debugger 0.3.0-in-development (2009-10-07-01:35) svn:2808
    $URL: svn://svn.berlios.de/openocd/trunk/src/openocd.c $
    For bug reports, read http://svn.berlios.de/svnroot/repos/openocd/trunk/BUGS
    2000 kHz
    jtag_nsrst_delay: 200
    jtag_ntrst_delay: 200
    dcc downloads are enabled
    Warn : use 'feroceon.cpu' as target identifier, not '0'
    Info : clock speed 2000 kHz
    Info : JTAG tap: feroceon.cpu tap/device found: 0x20a023d3 (mfg: 0x1e9, part: 0x0a02, ver: 0x2)
  4. OpenOCD is a client server software, so when you launch openOCD, you are really only launching the server part. To actually send JTAG commands and all that Jazz, you need to open a client session with:
    telnet localhost 4444
    This should then provide you with the On-Chip Debugger prompt.

  5. Now, JTAG operations are a bit tricky (there are various JTAG states involved) so you can't really send any JTAG command you want (eg. NAND ID) any time you like and expect a meaningful reply. If you looked in the cfg file for the SheevaPlug, you'll see that before any NAND access operation is performed, a "sheevaplug_init" command is being called, so this is what we'll do. Once it's run, you will get a whole lot of interesting commands working, as illustrated with the session below:
    > sheevaplug_init
    target state: halted
    target halted in ARM state due to debug-request, current mode: Supervisor
    cpsr: 0x000000d3 pc: 0xffff0000
    MMU: disabled, D-Cache: disabled, I-Cache: disabled
    0 0 1 0: 00052078
    > scan_chain
    TapName | Enabled | IdCode Expected IrLen IrCap IrMask Instr
    ---|--------------------|---------|------------|------------|------|------|------|---------
    0 | feroceon.cpu | Y | 0x20a023d3 | 0x20a023d3 | 0x04 | 0x01 | 0x0f | 0x0c
    > nand probe 0
    NAND flash device 'NAND 512MiB 3,3V 8-bit' found
    > nand list
    #0: NAND 512MiB 3,3V 8-bit (Hynix) pagesize: 2048, buswidth: 8,
    blocksize: 131072, blocks: 4096
    > nand info 0
    #0: NAND 512MiB 3,3V 8-bit (Hynix) pagesize: 2048, buswidth: 8, erasesize: 131072
    #0: 0x00000000 (128kB) erase state unknown (block condition unknown)
    #1: 0x00020000 (128kB) erase state unknown (block condition unknown)
    (...)
    #4094: 0x1ffc0000 (128kB) erase state unknown (block condition unknown)
    #4095: 0x1ffe0000 (128kB) erase state unknown (block condition unknown)

2009-10-02

SheevaPlug - Let's get cracking!

Alright, now that we have our new shiny SheevaPlug, let's get started.

  1. Of course, first thing we want is a serial console to the Linux OS, so we'll plug the mini <-> std USB cable provided to one of our USB ports and find out if Vista (x64) is able to figure out the FT2232D driver itself... which it can't (surprise, surprise). No big deal. The PDF readme from the DevKit CD tells you that you can find the TeraTerm Windows drivers in the SheevaPlug_Host_SWsupportPackageWindowsHost.zip or, for a more up to date version, at http://www.ftdichip.com/Drivers/D2XX.htm. Installing the drivers with Vista autodetect is still a pain, as you don't get the option to browse to the driver directory (yes, Microsoft, all your users are complete tools - that's why they use your products in the first place!), but with the device manager, you're good to go. Yay, another COM port! Yay a set of USB Serial converters!

  2. Alrighty, if we have our COM port, so we're good to go with the ever versatile putty. The FIRST thing you want to know is that the serial console is set to 115200 bauds, and the SECOND thing is that the default logon is root/nosoup4u (Globalscale: even their passwords are cool!). And we're in... Niiiiiice! dmesg, df -h, top, they're all waiting for you, but first you might as well wanna change the date & time, as mine was set to Apr 22 1953. That's like, way old! Also, since you're gonna wanna try a reboot to see what the console spills out, I'll just mention that there's a very loooong pause during boot after the line "eth0: link up, full duplex, speed 1 Gbps", so just be patient, you will get your logon prompt. Oh and you'll see warnings here and there as well, but what do you expect.

  3. What do we have here? Ubuntu? Huh, well, at least it's Debian based and we have a good chunk of space left. We could have fared much much worse (read anything that's based on Red Hat). We'll install armedslack soon enough but let's get cracking then. Of course, we'll want to recompile stuff on the device itself (something that can't be done on a WRT!). Let's start by compiling the very handy memtester to do a little bit of torture test, and see how much the baby heats up when using RAM.

  4. According to google, installing gcc on the SheevaPlug ios as easy as running: "apt-get install build-essential"... Except that you are missing the cache directory so the command fails. You need to issue a
    mkdir -p /var/cache/apt/archives/partial
    before you can use apt-get (and you might want to add this line to your /etc/rc.local as well). But we're still not out of the woods yet, as the package upgrade seems to start up fine, but after a while, you get errors like:
    Failed to fetch http://ports.ubuntu.com/pool/main/b/binutils/binutils_2.19.0.20090110-0ubuntu1_armel.deb  404 Not Found
    Checking that URL confirms that the package is no longer hosted there.
    Drats!

  5. The easiest solution at this stage is to update your system as a whole with "apt-get update". This might take a while, but it seemed to get the problem sorted, as the subsequent "apt-get install build-essential" completed hapilly. You might also want to run an "apt-get autoremove" after that, to free up some space. Good, now we can compile natively on the plug.

  6. "-bash: wget: command not found"? Who on earth delivers a system without wget? "apt-get install wget" then, but sheesh! But then...
    root@debian:/usr/src# wget http://pyropus.ca/software/memtester/old-versions/memtester-4.1.2.tar.gz
    --2009-10-02 14:05:28-- http://pyropus.ca/software/memtester/old-versions/memtester-4.1.2.tar.gz
    Resolving pyropus.ca... failed: Name or service not known.
    wget: unable to resolve host address `pyropus.ca'
    Indeed, DNS resolution doesn't seem to work out of the box and the default /etc/resolv.conf goes something like:
    domain lan
    search lan
    nameserver 127.0.0.1
    It's clear that with only these 3 lines, you're not gonna get very far (it's a wonder apt-get still managed to find its way - must be using direct IPs). Let's just comment the domain & search lines and add our ISP's nameservers before the 127.0.0.1 to get some resolution going. Now, please be aware that any changes you make here won't hold on reboot, so for more details on how to fix the default annoyance, you might as well have a look at the New Plugger Howto from openplug.org.

  7. Good, now we can wget memtester, compile it and run it (and it looks like our RAM is good). Maybe I'll try mprime later on as well... But to complete the setup of a half decent Linux system, let's issue an "apt-get install screen.
Next, we'll try to play with JTAG and OpenOCD...

SheevaPlug - first impressions

At last, my SheevaPlug Development Kit has arrived!

For those who don't know yet what the SheevaPlug is, you can have a look at this short CNET article or Marvell's slightly longer blurb about this wonderful little device.
I ordered mine (UK version) from Globalscale about 2-3 weeks ago, to basically replace my long trusted WRT54G running openWRT with something that has a little more punch and I/O capabilities. The truth of the matter is, I almost never use the WRT for WiFi, but having an always on & completely customizable Linux low power "server" has proved invaluable (Samba share for easy data interchange between any machine, DHCP server, bootp/tftp server, nmap & other networking tools provider, etc.), and I had been waiting for some time to see something like Marvell's plug computer come out, as it's basically a glorified hacked WRT54G, without the unneeded Wifi/network hub features.

For those who can't be bothered to read the whole post (and who can blame them!), I'll jump right into the main points of my first impressions:

The not so good:
  • Globascale's delays in shipment, and total lack of response when asked for updates. Granted delays are likely unavoidable (I doubt they're shipping Sheevaplugs by the truckload right now), but that doesn't explain why it took about 2 weeks of repeated e-mails to sales to get a simple status update on the order.
  • No choice but to use Fedex for shipping if you're not in the US. Granted, once it's shipped, the delivery is fast indeed, but considering the shipping delay, you might as well want to use regular post and spare a few bucks.
    Also, since Fedex are really happy to help with the obnoxious EU VAT & Customs Duty extortion scheme, you will be hit by 46% retroactive VAT on import (€31.20 - I really wish I was making this up), meaning that, as usual, no matter what you do, amount in $ = amount in €, and you still have to pay €99 for a bloody $99 item. Better believe this is the last time I import anything with Fedex.
    HEED MY ADVICE - DO NOT IMPORT ANYTHING WITH FEDEX, EVER!!!

  • Unlike the most excellent US removable plug (see below), the UK plug is just a common adapter to fit over the US socket, so it's not as sleekly designed. Not that big a deal, but it adds to the overall height of the device when used in plug mode. It would have been nice to see an integrated UK plug in the way the US one is. Also, the Globalscale UK devkit photos don't make that as clear as they could.
  • The mainboard is now rev. 1.3 and very different from the reference mainboard you see in the documentation (see below). For starters, there is no longer a separate mainboard for JTAG and SDIO, and the solder-able port for an ARM JTAG connector is gone. Gone as well is the generic GPIO connector. There still seems to be a small JTAG port, but with only 8 connectors and a non-standard smaller socket too be fitted in, it will be a pain to interface with. Not sure if many people would put single board vs 2 separate boards design as a disadvantage, but I was kind of planning on using the standalone expansion board as a cheap JTAG device (it has the very well known FT2232 JTAG IC on it) but now using the SheevaPlug hardware as a JTAG interface to other boards, or as a general purpose IO device, is going to be less of a possibility for your regular electronics hobbyist.
    UPDATE: for some of the new ports pinouts (still no JTAG desc), have a look here
  • Even idle, the device seems to run a bit hotter than I anticipated (It's certainly running hotter than my WRT54G). Definitely not that hot (akin to one of the numerous power bricks you have in your house), and most likely the heat is due to the PSU rather than the chip themselves, but still, I've seen power bricks run cooler than that (the 12V DC WRT brick being one of those). Of course, anybody who hears "heat" automatically thinks "increased power consumption", so I don't know how that translates into wasted wattage. My guess is this might be due to using a 110V/220V compatible PSU. Using a localized source voltage PSU for 220V -> 5V delivery would probably reduce the heat.
    [UPDATE 2009.10.08] The Plug does run scaringly hot when running at full load for a prolonged period of time, as I just found out through a rogue process.
    The metal parts on both USB and network sockets are almost burning when running for a long time at 100% of the CPU, and you wouldn't want to leave something in contact with them then. Still probably not hot enough to light up paper or plastic that would be in contact, yet quite scary... And it looks like the PSU unit does play some part in raising the whole temperature of the plug on full load. I also found that I had to enlarge some of the vents on my plug with a knife because they had been pourly moulded and were not entirely open. Still, I don't think Even then, there are too few vents on the current Plug and I don't think it is designed for adequate cooling! Something that definitely needs some improvement for later models.
    My advice: make sure you leave ample space around the plug, and check that all your vents are fully open.
The good:
  • Brilliant design from Globalscale. As somebody else said, whoever designed that removable socket for corded/plugged needs to have both a raise and a corner office. And despite the point I made above, the single mainboard layout is very well done (and rumour has it there is even an eSata port in there). Those guys have sharp engineers! The whole device itself feels both sturdy, inconspicuous, yet elegant. Even the cardboard packaging the plug is shipped in is very good design, so much so that I almost felt like taking pictures of the packaging. But then I thought, only Apple fanboys ever do something like that...
  • Does exactly what it says on the tin. The layout design might have changed, but you still get 2 USB ports (1 for debug), 1 SDIO port, 1 Gb Ethernet port and a computer with 512 MB RAM, 512 MB Flash, a most excellent 1.2 GHz ARM CPU, plus a JTAG device that's compatible with OpenOCD. Who could ask for more?
  • Can power a 2.5" USB HDD (tested with both a 5400 rpm 100 GB and a 7200 rpm 320 GB HDD). Impressive!
  • Loads of free space on the flash with the default Ubuntu installation
Alright, now it's time for opening the device and posting some pictures! Wait, are you telling me that the first thing you do when receiving a cool new toy is NOT tearing it apart to see what's inside? What on earth are you doing with your life?

Some pictures
  • That very well done removable socket/cord plug concealer
From SheevaPlug
  • Opening the plug (just remove the rubber pads to find the screws)
From SheevaPlug
  • Mainboard - top
From SheevaPlug
  • Mainboard - underside, with heatsink
From SheevaPlug
  • Mainboard - underside, without heatsink
From SheevaPlug
  • The device in action
From SheevaPlug

2009-03-12

redhat/centos services and mdadm quicknotes

Always seem to forget stuff there. The command I'm looking for to manage services/change runlevel on redhat/centos is chkconfig (chkconfig --list).

Also, to re-add a partition to an existing (failed) RAID array:
mdadm /dev/md0 --manage --add /dev/sdb1

2009-02-05

And here we go again - RAID5 fakeraid + Linux

It's that time of the decade where I get a new machine, this time an nVidia MCP79 (a.k.a. GeForce 9400) based motherboard from Gigabyte. Oh, and yes, the MCP79 is the same all-inclusive nForce chipset nVidia uses in the new MacBook Pros, as well as their Atom "can of whoop-ass" for set top HDTV boxes.

As most people, I'm pleasantly surprised by the features of the chipset. My goal was to build an HTPC, and with one good durable mobo (with both HDMI and optical SPDIF), the adding of a 45 nm quad core and 4 GB dirt cheap DDR2 RAM, I should have a solution that will last for some time. Oh, and of course, since we're hopefully going to store a lot of media data there, we can't forget the 3x 1 TB Samsung SpinPoint HDDs in a RAID5 array, which is what brings us here today.

Yep, as you guessed from the title, it's ye olde getting Linux to work with fakeraid. And the first thing I gotta say is I'm sick and tired of all the posts you see on the net where people asking how to make Linux work with their fakeraid are met with a "why don't you use Linux's md instead".
Well, I'm sorry, but there are still people out there who want to dual boot with Vista and trust nVidia RAID5 driver (MediaShield) enough not to want to make a complete mess of their Windows installation. Hell, I'd rather spend time figuring out how to make my RAID5 work in Linux than have to spend time doing the same thing in Windows. Plus, I like the convenience of having my BIOS handle things like RAID.

Here we are then, with Vista installed and painfully updated at last (see below) and a blank partition on the nVidia RAID5 MediaShield array that's just dying to get Linux installed.

OK, it's not that I mind a challenge here, but I've got a blank HDD lying around, so this time, what we're going to do is install Linux on that standalone drive, conf it so that it sees the RAID5 partition, and then move over our system rather than have to create our own custom RAID5 installation CD.

As usual, I'm gonna use the latest Slackware (12.2) so ymmv.

1. Slackware install with ALL the options you really want in the end (we'll be using that partition as the source) and LILO booting the single HDD = piece of cake. Just make sure that you don't install LILO on anything else BUT the HDD that's not part of the array
2. First bad surprise - if you keep your 2.6 kernel as is, no matter what you try, dmraid will return:
ERROR: device-mapper target type "raid45" not in kernel
Don't waste your time changing the raid45 to raid456 identifiers in dmraid either - you'll still get the same error. The kernel actually needs to be patched for dmraid to be happy.

[UPDATED]One year later, and still a mess. As of 2.6.35, the dm-raid45 module still hadn't been integrated to the kernel, plus the evil people at Red Hat who were supposed to maintain that module have completely dropped the ball, the Gentoo people also have dropped the ball (after 2.6.31) and the last set of dm-raid45 patches I could only go to 2.6.33 (and don't work against 2.6.35). So I guess we're stuck with 2.6.33 then. This last set of dmraid patch can be found from Mandriva. Can't help but find it strange that, while the dm-raid45 module is commonly used in Ubuntu (except that dmraid itself is useless with large disks as it doesn't support GPT), nobody seems to care about trying to merge it with the official kernel tree. Oh well...
root@stella# cd /usr/src/linux-2.6.33/
root@stella# wget http://tmb.mine.nu/Mandriva/Cooker/dm-raid/dm-raid45_2.6.33-rc1-20091126.patch
root@stella# patch -p1 < dm-raid45_2.6.33-rc1-20091126.patch
root@stella# wget http://tmb.mine.nu/Mandriva/Cooker/dm-raid/dm-raid45-buildfix-for-2.6.33.patch
root@stella# patch -p1 < dm-raid45-buildfix-for-2.6.33.patch
OK, so you just go through your usual kernel recompile. Now, a couple of things I wanna point out:
- You do want to reduce the size of your kernel if you're planning to remove the standalone HD and still boot your RAID5 array Linux partition with a decent solution
- Of course you want to add Device mapper support (Device drivers -> Multiple devices driver support (RAID and LVM)) and the new experimental "RAID 4/5 target" that was added by the kernel patch
- Despite being a Gb adpater, the nForce Ethernet driver (forcedeth) is to be found in: Ethernet (10 or 100Mbit) -> EISA, VLB, PCI and on board controllers -> nForce Ethernet support
- if you're using ext4 for root, don't forget to include ext2 support as well, as your root partition cannot be mounted without it.

Once you have a kernel that boots, you can move on to the dmraid install. This time, no need for devmapper. Just download the current dmraid source from http://people.redhat.com/~heinzm/sw/dmraid/src/:
root@stella# cd /usr/src
root@stella# wget http://people.redhat.com/~heinzm/sw/dmraid/src/dmraid-current.tar.bz2
root@stella# tar -xjvf dmraid-current.tar.bz2
root@stella# cd dmraid/1.0.0.rc15
root@stella# ./configure; make; make install
root@stella# dmraid -ay
RAID set "nvidia_aeejfdbe" was activated
RAID set "nvidia_aeejfdbep1" was activated
RAID set "nvidia_aeejfdbep2" was activated
RAID set "nvidia_aeejfdbep3" was activated
Yay! it works!

If you only see see the RAW disk (nvidia_aeejfdbe) but not the partitions, that's probably because you're using a GPT disk. In that case, you need to also run kpartx as follows:
root@stella# kpartx -a -v /dev/mapper/nvidia_aeejfdbe
add map nvidia_aeejfdbe1 (252:1): 0 262144 linear /dev/mapper/nvidia_aeejfdbe 34
add map nvidia_aeejfdbe2 (252:2): 0 209715200 linear /dev/mapper/nvidia_aeejfdbe 264192
add map nvidia_aeejfdbe3 (252:3): 0 186478592 linear /dev/mapper/nvidia_aeejfdbe 209979392
add map nvidia_aeejfdbe4 (252:4): 0 11324626944 linear /dev/mapper/nvidia_aeejfdbe 396457984
kpartx itself can be obtained from the multipath-tools.

OK, so now we can get going. Be sure you format the RELEVANT partition. In my case, I'll be using nvidia_aeejfdbep2, the second partition on the RAID5 array for the GNU/Linux system.
root@stella# mkfs.ext4 /dev/mapper/nvidia_aeejfdbep2
root@stella# mount /dev/mapper/nvidia_aeejfdbep2 /mnt/hd
root@stella# mkdir /mnt/hd/proc
root@stella# mkdir /mnt/hd/sys
root@stella# cp -ax / /mnt/hd
This could take a while...
Note that the -x option ensures that we stay on a single file system

OK, in the next post we'll see the grub way to (kinda) boot this whole mess