Skip to contentSkip to conversation

boot-directdisk: mount root by MBR disk signature for Linux 3.8+

PATCH Superseded Jonathan Liu 2 participants 5 messages May 23, 2013 – Jul 9, 2013

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 boot-directdisk: mount root by MBR disk signature for Linux 3.8+

---
 meta/classes/boot-directdisk.bbclass | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)
meta/classes/boot-directdisk.bbclass +18 -3
index 3169043..736bee0 100644
@@ -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,22 @@ 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 or later, mount root by MBR disk signature
+	if [[ $KERNEL_VERSION -eq 3 && $KERNEL_PATCHLEVEL -ge 8 ]] || [ $KERNEL_VERSION -gt 3 ]; then
+		# The disk signature generated by GNU Parted isn't really random, so regenerate it
+		echo -ne "$(uuidgen | sed 's/-//g;s/\(..\)/\\x&/g')" | dd of=$IMAGE bs=1 seek=440 count=4 conv=notrunc
+
+		DISK_SIGNATURE=$(hexdump -s 440 -n 4 -e '4 1 "%02x\n" "\n"' $IMAGE | tac | paste -sd '')
+		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 +88,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 
Signature · 1 line
1.8.2.3
#1 lore raw

Hi Jon,

Please include a complete commit message. For specifics on contributing patches, please see:

https://wiki.yoctoproject.org/wiki/Contribution_Guidelines

What is the problem? What is the cause? How are you addressing it? How was it tested?

Is this 3.8 feature you are referring to something must be configured into the kernel? Or is it always present?

There is also the concern with dual kernel systems (but that perhaps can wait until that is commonplace and the infrastructure is in place).

See inline for additional comments:

Quoted 20 lines · Jonathan Liu
---
 meta/classes/boot-directdisk.bbclass | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)
meta/classes/boot-directdisk.bbclass +2 -1
index 3169043..736bee0 100644
@@ -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"

meta/classes/boot-directdisk.bbclass build_boot_dd() { · line 63

Quoted 5 lines
meta/classes/boot-directdisk.bbclass +2 -0
@@ -58,6 +59,22 @@ 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]*$')

Could you use LINUX_VERSION here and void delving into the Linux sources directly?

meta/classes/boot-directdisk.bbclass build_boot_dd() { · line 70

Quoted 7 lines
meta/classes/boot-directdisk.bbclass +7 -0
+
+	rm -rf $IMAGE
+	dd if=/dev/zero of=$IMAGE bs=512 seek=1 count=0
+	parted $IMAGE mklabel msdos
+
+	# If using Linux 3.8 or later, mount root by MBR disk signature
+	if [[ $KERNEL_VERSION -eq 3 && $KERNEL_PATCHLEVEL -ge 8 ]] || [ $KERNEL_VERSION -gt 3 ]; then

[[ is a bashism, use portable tests please, for example:

if ([ $KERNEL_VERSION -eq 3 ] && [$KERNEL_PATCHLEVEL -ge 8 ]) || [ $KERNEL_VERSION -gt 3 ]; then

This is easily tested by writing test.sh and executing with bash and dash and ensuring consistent behavior.

Is the version sufficient? No CONFIG_ value to test for?

meta/classes/boot-directdisk.bbclass build_boot_dd() { · line 74

Quoted 4 lines
meta/classes/boot-directdisk.bbclass +4 -0
+		# The disk signature generated by GNU Parted isn't really random, so regenerate it
+		echo -ne "$(uuidgen | sed 's/-//g;s/\(..\)/\\x&/g')" | dd of=$IMAGE bs=1 seek=440 count=4 conv=notrunc
+
+		DISK_SIGNATURE=$(hexdump -s 440 -n 4 -e '4 1 "%02x\n" "\n"' $IMAGE | tac | paste -sd '')

Seems like it would be more efficient to just store this in a variable initially
rather than opening, seeking, and dumping the value that you just wrote in...

meta/classes/boot-directdisk.bbclass build_boot_dd() { · line 75

Quoted 1 line
meta/classes/boot-directdisk.bbclass +1 -0
+		sed -i "s|\broot=[^ ]*|root=PARTUUID=$DISK_SIGNATURE-02|" $HDDDIR/syslinux.cfg

In bootimg.bbclass I have been abstracting out the boot loader so it is not explicitly referenced. Something like that is in order here. For example, an EFI boot-directdisk (which admittedly doesn't exist yet) would not have a syslinux.cfg but would still need the change. Consider using the syslinux class to abstract this necessary change. Then I can add the gummiboot change when EFI support is added.

--
Darren

Quoted 17 lines
meta/classes/boot-directdisk.bbclass +2 -2
+	fi
+
 	mkdosfs -n ${BOOTDD_VOLUME_ID} -S 512 -C $HDDIMG $BLOCKS 
 	mcopy -i $HDDIMG -s $HDDDIR/* ::/
 
@@ -71,10 +88,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 
Signature · 3 lines
Darren Hart
Intel Open Source Technology Center
Yocto Project - Technical Lead - Linux Kernel
#2 lore raw

Hi Darren,

Quoted 7 lines · Darren Hart

Hi Jon,

Please include a complete commit message. For specifics on contributing patches, please see:

https://wiki.yoctoproject.org/wiki/Contribution_Guidelines

Quoted 8 lines

What is the problem? What is the cause? How are you addressing it? How was it tested?

Is this 3.8 feature you are referring to something must be configured into the kernel? Or is it always present?

There is also the concern with dual kernel systems (but that perhaps can wait until that is commonplace and the infrastructure is in place).

Ok.

Quoted 26 lines

See inline for additional comments:

Quoted 23 lines · Jonathan Liu
---
  meta/classes/boot-directdisk.bbclass | 21 ++++++++++++++++++---
  1 file changed, 18 insertions(+), 3 deletions(-)
meta/classes/boot-directdisk.bbclass +2 -1
index 3169043..736bee0 100644
@@ -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,22 @@ build_boot_dd() {
  	# done in blocks, thus the mod by 16 instead of 32.
  	BLOCKS=$(expr $BLOCKS + $(expr 16 - $(expr $BLOCKS % 16)))
 
Quoted 4 lines

meta/classes/boot-directdisk.bbclass build_boot_dd() { · line 63

Quoted 2 lines
meta/classes/boot-directdisk.bbclass +2 -0
+	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]*$')

Could you use LINUX_VERSION here and void delving into the Linux sources directly?

It's not available in the context of the image recipe if I do bitbake -e core-image-minimal.

Quoted 9 lines

meta/classes/boot-directdisk.bbclass build_boot_dd() { · line 70

Quoted 7 lines
meta/classes/boot-directdisk.bbclass +7 -0
+
+	rm -rf $IMAGE
+	dd if=/dev/zero of=$IMAGE bs=512 seek=1 count=0
+	parted $IMAGE mklabel msdos
+
+	# If using Linux 3.8 or later, mount root by MBR disk signature
+	if [[ $KERNEL_VERSION -eq 3 && $KERNEL_PATCHLEVEL -ge 8 ]] || [ $KERNEL_VERSION -gt 3 ]; then

[[ is a bashism, use portable tests please, for example:

Quoted 5 lines

if ([ $KERNEL_VERSION -eq 3 ] && [$KERNEL_PATCHLEVEL -ge 8 ]) || [ $KERNEL_VERSION -gt 3 ]; then

This is easily tested by writing test.sh and executing with bash and dash and ensuring consistent behavior.

Ok.

Quoted 1 line

Is the version sufficient? No CONFIG_ value to test for?

It needs CONFIG_BLOCK so I will test for that.

Quoted 8 lines

meta/classes/boot-directdisk.bbclass build_boot_dd() { · line 74

Quoted 4 lines
meta/classes/boot-directdisk.bbclass +4 -0
+		# The disk signature generated by GNU Parted isn't really random, so regenerate it
+		echo -ne "$(uuidgen | sed 's/-//g;s/\(..\)/\\x&/g')" | dd of=$IMAGE bs=1 seek=440 count=4 conv=notrunc
+
+		DISK_SIGNATURE=$(hexdump -s 440 -n 4 -e '4 1 "%02x\n" "\n"' $IMAGE | tac | paste -sd '')

Seems like it would be more efficient to just store this in a variable initially
rather than opening, seeking, and dumping the value that you just wrote in...

Ok.

Quoted 7 lines

meta/classes/boot-directdisk.bbclass build_boot_dd() { · line 75

Quoted 1 line
meta/classes/boot-directdisk.bbclass +1 -0
+		sed -i "s|\broot=[^ ]*|root=PARTUUID=$DISK_SIGNATURE-02|" $HDDDIR/syslinux.cfg

In bootimg.bbclass I have been abstracting out the boot loader so it is not explicitly referenced. Something like that is in order here. For example, an EFI boot-directdisk (which admittedly doesn't exist yet) would not have a syslinux.cfg but would still need the change. Consider using the syslinux class to abstract this necessary change. Then I can add the gummiboot change when EFI support is added.

Do you mean adding a function to the syslinux class which updates root= in syslinux.cfg previously created by build_syslinux_cfg()?

Quoted 15 lines

--
Darren

Quoted 12 lines
meta/classes/boot-directdisk.bbclass +2 -1
+	fi
+
  	mkdosfs -n ${BOOTDD_VOLUME_ID} -S 512 -C $HDDIMG $BLOCKS
  	mcopy -i $HDDIMG -s $HDDDIR/* ::/
 
@@ -71,10 +88,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
 
Quoted 5 lines

meta/classes/boot-directdisk.bbclass build_boot_dd() { · line 95

Quoted 5 lines
meta/classes/boot-directdisk.bbclass +0 -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

Regards,
Jonathan

#3 lore raw
Quoted 10 lines · Jonathan Liu

Hi Darren,

Quoted 7 lines

meta/classes/boot-directdisk.bbclass build_boot_dd() { · line 75

Quoted 1 line
meta/classes/boot-directdisk.bbclass +1 -0
+		sed -i "s|\broot=[^ ]*|root=PARTUUID=$DISK_SIGNATURE-02|" $HDDDIR/syslinux.cfg

In bootimg.bbclass I have been abstracting out the boot loader so it is not explicitly referenced. Something like that is in order here. For example, an EFI boot-directdisk (which admittedly doesn't exist yet) would not have a syslinux.cfg but would still need the change. Consider using the syslinux class to abstract this necessary change. Then I can add the gummiboot change when EFI support is added.

Quoted 2 lines

Do you mean adding a function to the syslinux class which updates root= in syslinux.cfg previously created by build_syslinux_cfg()?

In the words of a wise director at a large technology company, "I meant whatever is the most intelligent." :-)

This could be a new function in syslinux.bbclass. It could also be a parameter to build_syslinux_cfg which would allow it to be used from either bootimg.bbclass, boot-directdisk.bbclass, with or without EFI, with various kernel versions, etc. I suspect some parameterization will result in the cleanest, most maintainable approach, but investigation is required.

Thanks!

Darren

Quoted 24 lines
Quoted 16 lines

--
Darren

Quoted 12 lines
meta/classes/boot-directdisk.bbclass +2 -1
+	fi
+
  	mkdosfs -n ${BOOTDD_VOLUME_ID} -S 512 -C $HDDIMG $BLOCKS
  	mcopy -i $HDDIMG -s $HDDDIR/* ::/
@@ -71,10 +88,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
 
Quoted 5 lines

meta/classes/boot-directdisk.bbclass build_boot_dd() { · line 95

Quoted 5 lines
meta/classes/boot-directdisk.bbclass +0 -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

Regards,
Jonathan

Signature · 3 lines
Darren Hart
Intel Open Source Technology Center
Yocto Project - Technical Lead - Linux Kernel
#4 lore raw
Quoted 23 lines · Darren Hart
Quoted 11 lines · Jonathan Liu

Hi Darren,

Quoted 7 lines

meta/classes/boot-directdisk.bbclass build_boot_dd() { · line 75

Quoted 1 line
meta/classes/boot-directdisk.bbclass +1 -0
+		sed -i "s|\broot=[^ ]*|root=PARTUUID=$DISK_SIGNATURE-02|" $HDDDIR/syslinux.cfg

In bootimg.bbclass I have been abstracting out the boot loader so it is not explicitly referenced. Something like that is in order here. For example, an EFI boot-directdisk (which admittedly doesn't exist yet) would not have a syslinux.cfg but would still need the change. Consider using the syslinux class to abstract this necessary change. Then I can add the gummiboot change when EFI support is added.

Do you mean adding a function to the syslinux class which updates root= in syslinux.cfg previously created by build_syslinux_cfg()?

In the words of a wise director at a large technology company, "I meant whatever is the most intelligent." :-)

This could be a new function in syslinux.bbclass. It could also be a parameter to build_syslinux_cfg which would allow it to be used from either bootimg.bbclass, boot-directdisk.bbclass, with or without EFI, with various kernel versions, etc. I suspect some parameterization will result in the cleanest, most maintainable approach, but investigation is required.

Quoted 3 lines

Thanks!

Darren

Submitted V3 patch which sets SYSLINUX_ROOT appropriately instead of modifying syslinux.cfg directly.

Regards,
Jonathan

Quoted 24 lines
Quoted 24 lines
Quoted 16 lines

--
Darren

Quoted 12 lines
meta/classes/boot-directdisk.bbclass +2 -1
+	fi
+
   	mkdosfs -n ${BOOTDD_VOLUME_ID} -S 512 -C $HDDIMG $BLOCKS
   	mcopy -i $HDDIMG -s $HDDDIR/* ::/
@@ -71,10 +88,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
 
Quoted 5 lines

meta/classes/boot-directdisk.bbclass build_boot_dd() { · line 95

Quoted 5 lines
meta/classes/boot-directdisk.bbclass +0 -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

Regards,
Jonathan