I believe I have found a way to boot GoFlex Home/Net devices from USB or SATA devices with or without 1 (or 2) SATA devices installed without an initramfs or having to change UBoot parameters after adding or removing USB or SATA devices. I have seen the topic discussed on a couple of different threads (including these two http://archlinuxarm.org/forum/viewtopic.php?f=18&t=3877 http://archlinuxarm.org/forum/viewtopic.php?f=18&t=3355). There are a couple of different solutions, but I did not come across any that did not involve making an initramfs, or changing UBoot parameters. I spent some time playing around with UBoot and I found a solution that works for me that does not require either.
My plan for one of my GoFlex devices is to use it for trouble shooting, and I would like to be able to add or remove a SATA device and still boot from a USB device. The first time I tried this after installing the latest (davygravy-2012-04-19) UBoot, I had the device booting fine from a USB device, I then powered down added a SATA device and the system did not boot. I checked the serial console, and saw that UBoot was passing the SATA device (not the USB device) to the kernel for the root filesystem. So, I started playing around with UBoot to see if there was a way to detect if SATA devices were present, and if so, adjust what is being passed to the kernel accordingly. I found a way to detect SATA devices and proceeded to update the UBoot environment variables. Here are the steps that have allowed me to boot a GoFlex device with or without SATA devices installed (FOLLOWING THESE STEPS MAY PUT YOUR DEVICE INTO AN UNBOOTABLE STATE, USE AT YOUR OWN RISK):
1. Follow the GoFlex Home/Net install instructions from this thread http://archlinuxarm.org/forum/viewtopic.php?f=18&t=3355, up to and including setting the arcNumber UBoot environment variable
2. Run the following commands:
$this->bbcode_second_pass_code('', '
/usr/sbin/fw_setenv bootcmd 'ide reset; usb start; run get_sata_cnt; run sata_bootcmd; run usb_bootcmd; reset'
/usr/sbin/fw_setenv get_sata_cnt 'n_sata=0; if ide device; then if ide device 0; then n_sata=1; fi; if ide device 1; then if test $n_sata -eq 0; then n_sata=1; else n_sata=2; fi; fi; fi'
/usr/sbin/fw_setenv sata_boot 'if test -n $sata_device; then mw 0x800000 0 1; ext2load ide $sata_device 0x800000 /boot/uImage; if ext2load ide $sata_device 0x1100000 /boot/uInitrd; then bootm 0x800000 0x1100000; else bootm 0x800000; fi; fi'
/usr/sbin/fw_setenv sata_bootcmd 'run sata_scan; run sata_set_bootargs; run sata_boot'
/usr/sbin/fw_setenv sata_scan 'if test $n_sata -ne 0; then sata_scan_done=0; for scan in $sata_scan_list; do run sata_scan_$scan; if test $sata_scan_done -eq 0 && ext2load ide $sata 0x800000 /boot/uImage 1; then sata_scan_done=1; setenv sata_device $sata; if test $n_sata -eq 1; then dev=sda1; fi; setenv sata_root /dev/$dev; echo "Found bootable drive on sata $sata_device"; echo "Passing kernel rootfs device $sata_root"; fi; done; fi'
/usr/sbin/fw_setenv sata_scan_list '1 2'
/usr/sbin/fw_setenv sata_scan_1 'sata=0:1 dev=sda1'
/usr/sbin/fw_setenv sata_scan_2 'sata=1:1 dev=sdb1'
/usr/sbin/fw_setenv sata_rootdelay 10
/usr/sbin/fw_setenv sata_rootfstype ext3
/usr/sbin/fw_setenv sata_set_bootargs 'setenv bootargs console=$console root=$sata_root rootdelay=$sata_rootdelay rootfstype=$sata_rootfstype $mtdparts'
/usr/sbin/fw_setenv usb_boot 'if test -n $usb_device; then mw 0x800000 0 1; ext2load usb $usb_device 0x800000 /boot/uImage; if ext2load usb $usb_device 0x1100000 /boot/uInitrd; then bootm 0x800000 0x1100000; else bootm 0x800000; fi; fi'
/usr/sbin/fw_setenv usb_bootcmd 'run usb_scan; run usb_set_bootargs; run usb_boot'
/usr/sbin/fw_setenv usb_scan 'usb_scan_done=0; for scan in $usb_scan_list; do run usb_scan_$scan; if test $usb_scan_done -eq 0 && ext2load usb $usb 0x800000 /boot/uImage 1; then usb_scan_done=1; setenv usb_device $usb; if test $n_sata -eq 1; then if test sdd1 = $dev; then dev=sde1; elif test sdc1 = $dev; then dev=sdd1; elif test sdb1 = $dev; then dev=sdc1; elif test sda1 = $dev; then dev=sdb1; fi; elif test $n_sata -eq 2; then if test sdd1 = $dev; then dev=sdf1; elif test sdc1 = $dev; then dev=sde1; elif test sdb1 = $dev; then dev=sdd1; elif test sda1 = $dev; then dev=sdc1; fi; fi; setenv usb_root /dev/$dev; echo "Found bootable drive on usb $usb_device"; echo "Passing kernel rootfs device $usb_root"; fi; done'
/usr/sbin/fw_setenv usb_set_bootargs 'setenv bootargs console=$console root=$usb_root rootdelay=$usb_rootdelay rootfstype=$usb_rootfstype $mtdparts'
')
3. If desired, follow the steps (again from this thread http://archlinuxarm.org/forum/viewtopic.php?f=18&t=3355) to activate netconsole (recommended, if you do not have a serial connection setup) and change the I/O scheduler
After following the steps above, on boot up, your GoFlex device will scan the SATA devices then USB devices looking for the first one that has a /boot/uImage file on the first partition (the first partition must also be ext2). It will then load and boot that uImage and set the root file system to the same partition it found the image on.
I have done enough testing to feel confident the solution will work for me. I have not done enough testing to feel confident it will work for you
I have tested on both GoFlex Home and GoFlex Net devices. Here is a list of some of the tests I have run (all the scenarios behaved as expected):
Devices used for testing:
- GoFlex Home
- GoFlex Net
- 4 port USB hub (I only had an older USB v1.1 hub)
- 3 TB SATA (3.5 inch) harddrive
- 80 GB SATA (2.5 inch) harddrive
- 250 GB SATA (2.5 inch) harddrive
- 4 @ USB flash drives (of varying sizes and types)
GoFlex Home Configurations
- 4 USB drives, no SATA drive, uImage on USB drive tested in each port of the USB hub
- 4 USB drives, 3 TB SATA drive, uImage on USB drive tested in each port of the USB hub
- 4 USB drives, 80 GB SATA drive, uImage on USB drive tested in each port of the USB hub
- 4 USB drives, 80 GB SATA drive, uImage on SATA drive
GoFlex Net Configurations
- 1 SATA drive in first slot, no USB drives, uImage on SATA drive (first slot)
- 1 SATA drive in second slot, no USB drives, uImage on SATA drive (second slot)
- 2 SATA drives, no USB drives, uImage on SATA drive (first slot)
- 2 SATA drives, no USB drives, uImage on SATA drive (second slot)
- 1 SATA drive in first slot, 4 USB drives, uImage on SATA drive (first slot)
- 1 SATA drive in second slot, 4 USB drives, uImage on SATA drive (second slot)
- 2 SATA drives, 4 USB drives, uImage on SATA drive (first slot)
- 2 SATA drives, 4 USB drives, uImage on SATA drive (second slot)
- 1 SATA drive in first slot, 4 USB drives, uImage on USB drive tested in each port of the USB hub
- 1 SATA drive in second slot, 4 USB drives, uImage on USB drive tested in each port of the USB hub
- 2 SATA drives, 1 USB drive, uImage on USB drive
- 2 SATA drives, 4 USB drives, uImage on USB drive tested in each port of the USB hub
Thanks to everyone who has contributed to getting Arch Linux to work so well on these devices.