The root device is currently set as /dev/hda2. However, this is
only correct if it's the first IDE drive. If booting off the first SATA
drive instead, it would be /dev/sda2. It's not the first drive, neither
/dev/hda2 or /dev/sda2 would be correct.

The solution to this has typically been to use the filesystem UUID to
specify the root device but this requires extra support in the initrd.
Linux 3.8 introduces the ability to specify the root device using the
MBR disk signature and the partition number which is much simpler to
use and avoids the extra overhead of an initrd.

This change uses the MBR disk signature to specify the root device when
using Linux 3.8+ and CONFIG_BLOCK (required for root=PARTUUID=)
is enabled in the kernel.

This has been tested with QEMU x86 and Intel Desktop Board D2500HN using
an image recipe inheriting boot-directdisk and core-image.

Signed-off-by: Jonathan Liu <net...@gmail.com>
---
 meta/classes/boot-directdisk.bbclass | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/meta/classes/boot-directdisk.bbclass 
b/meta/classes/boot-directdisk.bbclass
index 3169043..efeadab 100644
--- a/meta/classes/boot-directdisk.bbclass
+++ b/meta/classes/boot-directdisk.bbclass
@@ -23,7 +23,8 @@ do_bootdirectdisk[depends] += 
"dosfstools-native:do_populate_sysroot \
                                syslinux:do_populate_sysroot \
                                syslinux-native:do_populate_sysroot \
                                parted-native:do_populate_sysroot \
-                               mtools-native:do_populate_sysroot "
+                               mtools-native:do_populate_sysroot \
+                               util-linux-native:do_populate_sysroot "
 
 PACKAGES = " "
 EXCLUDE_FROM_WORLD = "1"
@@ -58,6 +59,25 @@ build_boot_dd() {
        # done in blocks, thus the mod by 16 instead of 32.
        BLOCKS=$(expr $BLOCKS + $(expr 16 - $(expr $BLOCKS % 16)))
 
+       KERNEL_VERSION=$(grep '^VERSION\s*=' ${STAGING_KERNEL_DIR}/Makefile | 
grep -o '[0-9]*$')
+       KERNEL_PATCHLEVEL=$(grep '^PATCHLEVEL\s*=' 
${STAGING_KERNEL_DIR}/Makefile | grep -o '[0-9]*$')
+
+       rm -rf $IMAGE
+       dd if=/dev/zero of=$IMAGE bs=512 seek=1 count=0
+       parted $IMAGE mklabel msdos
+
+       # If using Linux 3.8+ and CONFIG_BLOCK is enabled, use MBR disk 
signature to specify root device
+       if (([ $KERNEL_VERSION -eq 3 ] && [ $KERNEL_PATCHLEVEL -ge 8 ]) || [ 
$KERNEL_VERSION -gt 3 ]) &&
+          grep '^CONFIG_BLOCK=y$' ${STAGING_KERNEL_DIR}/.config >/dev/null; 
then
+               # Disk signature generated by parted isn't really random, so 
regenerate it
+               DISK_SIGNATURE=$(uuidgen | sed 's/-//g' | cut -b -8)
+               echo -ne "$(echo $DISK_SIGNATURE | fold -w 2 | tac | paste -sd 
'' | sed 's/\(..\)/\\x&/g')" | \
+                       dd of=$IMAGE bs=1 seek=440 conv=notrunc
+
+               # Use MBR disk signature to specify root device
+               sed -i "s|\broot=[^ ]*|root=PARTUUID=$DISK_SIGNATURE-02|" 
$HDDDIR/syslinux.cfg
+       fi
+
        mkdosfs -n ${BOOTDD_VOLUME_ID} -S 512 -C $HDDIMG $BLOCKS 
        mcopy -i $HDDIMG -s $HDDDIR/* ::/
 
@@ -71,10 +91,8 @@ build_boot_dd() {
        END3=`expr \( $ROOTFSBLOCKS \* 1024 \) + $END1`
 
        echo $ROOTFSBLOCKS $TOTALSIZE $END1 $END2 $END3
-       rm -rf $IMAGE
        dd if=/dev/zero of=$IMAGE bs=1024 seek=$TOTALSIZE count=1
 
-       parted $IMAGE mklabel msdos
        parted $IMAGE mkpart primary fat16 0 ${END1}B
        parted $IMAGE unit B mkpart primary ext2 ${END2}B ${END3}B
        parted $IMAGE set 1 boot on 
-- 
1.8.2.3

_______________________________________________
Openembedded-core mailing list
Openembedded-core@lists.openembedded.org
http://lists.openembedded.org/mailman/listinfo/openembedded-core

Reply via email to