Merge Mainline

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen 2021-06-17 20:42:27 +08:00
commit 636a2b539b
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
59 changed files with 575 additions and 3104 deletions

View File

@ -136,13 +136,6 @@ menu "Target Images"
help
Create an ext4 filesystem with a journal.
config TARGET_ROOTFS_ISO
bool "iso"
default n
depends on TARGET_x86_generic
help
Create a bootable ISO image.
config TARGET_ROOTFS_JFFS2
bool "jffs2"
depends on USES_JFFS2
@ -207,32 +200,32 @@ menu "Target Images"
config GRUB_IMAGES
bool "Build GRUB images (Linux x86 or x86_64 host only)"
depends on TARGET_x86
depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_ISO || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS
depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS
select PACKAGE_grub2
default y
config EFI_IMAGES
bool "Build EFI GRUB images (Linux x86 or x86_64 host only)"
config GRUB_EFI_IMAGES
bool "Build GRUB EFI images (Linux x86 or x86_64 host only)"
depends on TARGET_x86
depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_ISO || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS
depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS
select PACKAGE_grub2
select PACKAGE_grub2-efi
select PACKAGE_kmod-fs-vfat
default y
config GRUB_CONSOLE
bool "Use Console Terminal (in addition to Serial)"
depends on GRUB_IMAGES || EFI_IMAGES
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
default y
config GRUB_SERIAL
string "Serial port device"
depends on GRUB_IMAGES || EFI_IMAGES
default "hvc0" if TARGET_x86_xen_domu
default "ttyS0" if ! TARGET_x86_xen_domu
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
default "ttyS0"
config GRUB_BAUDRATE
int "Serial port baud rate"
depends on GRUB_IMAGES || EFI_IMAGES
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
default 38400 if TARGET_x86_generic
default 115200
@ -243,65 +236,58 @@ menu "Target Images"
config GRUB_BOOTOPTS
string "Extra kernel boot options"
depends on GRUB_IMAGES || EFI_IMAGES
default "xencons=hvc" if TARGET_x86_xen_domu
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
help
If you don't know, just leave it blank.
config GRUB_TIMEOUT
string "Seconds to wait before booting the default entry"
depends on GRUB_IMAGES || EFI_IMAGES
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
default "0"
help
If you don't know, 5 seconds is a reasonable default.
config GRUB_TITLE
string "Title for the menu entry in GRUB"
depends on GRUB_IMAGES || EFI_IMAGES
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
default "OpenWrt"
help
This is the title of the GRUB menu entry.
If unspecified, it defaults to OpenWrt.
config ISO_IMAGES
bool "Build LiveCD image (ISO)"
depends on TARGET_x86
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
config QCOW2_IMAGES
bool "Build PVE/KVM image files (QCOW2)"
depends on TARGET_x86
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
select PACKAGE_kmod-e1000
config VDI_IMAGES
bool "Build VirtualBox image files (VDI)"
depends on TARGET_x86 || TARGET_x86_64
select GRUB_IMAGES
select TARGET_IMAGES_PAD
depends on TARGET_x86
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
select PACKAGE_kmod-e1000
config VHDX_IMAGES
bool "Build Hyper-V image files (VHDX)"
depends on TARGET_x86
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
select PACKAGE_kmod-tulip
config VMDK_IMAGES
bool "Build VMware image files (VMDK)"
depends on TARGET_x86 || TARGET_x86_64
select GRUB_IMAGES
select TARGET_IMAGES_PAD
depends on TARGET_x86
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
select PACKAGE_kmod-e1000
default y
config VHD_IMAGES
bool "Build Hyper-V image files (VHD)"
depends on TARGET_x86 || TARGET_x86_64
depends on GRUB_IMAGES || EFI_IMAGES
select TARGET_IMAGES_PAD
select PACKAGE_kmod-tulip
default n
config QCOW2_IMAGES
bool "Build PVE/KVM image files (QCOW2)"
depends on TARGET_x86 || TARGET_x86_64
depends on GRUB_IMAGES || EFI_IMAGES
select TARGET_IMAGES_PAD
select PACKAGE_kmod-e1000
default n
config TARGET_IMAGES_PAD
bool "Pad images to filesystem size (for JFFS2)"
depends on GRUB_IMAGES || EFI_IMAGES
default y
config TARGET_IMAGES_GZIP
bool "GZip images"
depends on TARGET_IMAGES_PAD || TARGET_ROOTFS_EXT4FS || TARGET_x86
depends on TARGET_ROOTFS_EXT4FS || TARGET_x86
default y
default n if TARGET_x86
@ -311,21 +297,21 @@ menu "Target Images"
config TARGET_KERNEL_PARTSIZE
int "Kernel partition size (in MB)"
depends on GRUB_IMAGES || EFI_IMAGES || USES_BOOT_PART
depends on USES_BOOT_PART
default 8 if TARGET_apm821xx_sata
default 64 if TARGET_bcm27xx
default 16
config TARGET_ROOTFS_PARTSIZE
int "Root filesystem partition size (in MB)"
depends on GRUB_IMAGES || EFI_IMAGES || USES_ROOTFS_PART || TARGET_ROOTFS_EXT4FS || TARGET_mvebu || TARGET_rb532 || TARGET_sunxi || TARGET_uml
depends on USES_ROOTFS_PART || TARGET_ROOTFS_EXT4FS || TARGET_mvebu || TARGET_rb532 || TARGET_sunxi || TARGET_uml
default 160
help
Select the root filesystem partition size.
config TARGET_ROOTFS_PARTNAME
string "Root partition on target device"
depends on GRUB_IMAGES || EFI_IMAGES
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
help
Override the root partition on the final device. If left empty,
it will be mounted by PARTUUID which makes the kernel find the

View File

@ -466,3 +466,10 @@ define Build/append-metadata
fwtool -S "$@.ucert" "$@" ;\
}
endef
# Convert a raw image into a $1 type image.
# E.g. | qemu-image vdi
define Build/qemu-image
qemu-img convert -f raw -O $1 $@ $@.new
@mv $@.new $@
endef

View File

@ -41,6 +41,7 @@ IMG_PREFIX:=$(VERSION_DIST_SANITIZED)-$(IMG_PREFIX_VERNUM)$(IMG_PREFIX_VERCODE)$
IMG_ROOTFS:=$(IMG_PREFIX)-rootfs
IMG_COMBINED:=$(IMG_PREFIX)-combined
IMG_PART_SIGNATURE:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC) | $(MKHASH) md5 | cut -b1-8)
IMG_PART_DISKGUID:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC) | $(MKHASH) md5 | sed -r 's/(.{8})(.{4})(.{4})(.{4})(.{10})../\1-\2-\3-\4-\500/')
MKFS_DEVTABLE_OPT := -D $(INCLUDE_DIR)/device_table.txt
@ -89,7 +90,6 @@ fs-types-$(CONFIG_TARGET_ROOTFS_SQUASHFS) += squashfs
fs-types-$(CONFIG_TARGET_ROOTFS_JFFS2) += $(addprefix jffs2-,$(JFFS2_BLOCKSIZE))
fs-types-$(CONFIG_TARGET_ROOTFS_JFFS2_NAND) += $(addprefix jffs2-nand-,$(NAND_BLOCKSIZE))
fs-types-$(CONFIG_TARGET_ROOTFS_EXT4FS) += ext4
fs-types-$(CONFIG_TARGET_ROOTFS_ISO) += iso
fs-types-$(CONFIG_TARGET_ROOTFS_UBIFS) += ubifs
fs-subtypes-$(CONFIG_TARGET_ROOTFS_JFFS2) += $(addsuffix -raw,$(addprefix jffs2-,$(JFFS2_BLOCKSIZE)))

View File

@ -90,6 +90,17 @@ get_image() { # <source> [ <command> ]
cat "$from" 2>/dev/null | $cmd
}
get_image_dd() {
local from="$1"; shift
(
exec 3>&2
( exec 3>&2; get_image "$from" 2>&1 1>&3 | grep -v -F ' Broken pipe' ) 2>&1 1>&3 \
| ( exec 3>&2; dd "$@" 2>&1 1>&3 | grep -v -E ' records (in|out)') 2>&1 1>&3
exec 3>&-
)
}
get_magic_word() {
(get_image "$@" | dd bs=2 count=1 | hexdump -v -n 2 -e '1/1 "%02x"') 2>/dev/null
}
@ -98,6 +109,24 @@ get_magic_long() {
(get_image "$@" | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2>/dev/null
}
get_magic_gpt() {
(get_image "$@" | dd bs=8 count=1 skip=64) 2>/dev/null
}
get_magic_vfat() {
(get_image "$@" | dd bs=1 count=3 skip=54) 2>/dev/null
}
part_magic_efi() {
local magic=$(get_magic_gpt "$@")
[ "$magic" = "EFI PART" ]
}
part_magic_fat() {
local magic=$(get_magic_vfat "$@")
[ "$magic" = "FAT" ]
}
export_bootdevice() {
local cmdline uuid disk uevent line
local MAJOR MINOR DEVNAME DEVTYPE
@ -144,6 +173,17 @@ export_bootdevice() {
fi
done
;;
PARTUUID=????????-????-????-????-??????????02)
uuid="${rootpart#PARTUUID=}"
uuid="${uuid%02}00"
for disk in $(find /dev -type b); do
set -- $(dd if=$disk bs=1 skip=568 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"')
if [ "$4$3$2$1-$6$5-$8$7-$9" = "$uuid" ]; then
uevent="/sys/class/block/${disk##*/}/uevent"
break
fi
done
;;
/dev/*)
uevent="/sys/class/block/${disk##*/}/uevent"
;;
@ -203,17 +243,34 @@ get_partitions() { # <device> <filename>
rm -f "/tmp/partmap.$filename"
local part
for part in 1 2 3 4; do
set -- $(hexdump -v -n 12 -s "$((0x1B2 + $part * 16))" -e '3/4 "0x%08X "' "$disk")
part_magic_efi "$disk" && {
#export_partdevice will fail when partition number is greater than 15, as
#the partition major device number is not equal to the disk major device number
for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do
set -- $(hexdump -v -n 48 -s "$((0x380 + $part * 0x80))" -e '4/4 "%08x"" "4/4 "%08x"" "4/4 "0x%08X "' "$disk")
local type="$(( $(hex_le32_to_cpu $1) % 256))"
local lba="$(( $(hex_le32_to_cpu $2) ))"
local num="$(( $(hex_le32_to_cpu $3) ))"
local type="$1"
local lba="$(( $(hex_le32_to_cpu $4) * 0x100000000 + $(hex_le32_to_cpu $3) ))"
local end="$(( $(hex_le32_to_cpu $6) * 0x100000000 + $(hex_le32_to_cpu $5) ))"
local num="$(( $end - $lba ))"
[ $type -gt 0 ] || continue
[ "$type" = "00000000000000000000000000000000" ] && continue
printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename"
done
printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename"
done
} || {
for part in 1 2 3 4; do
set -- $(hexdump -v -n 12 -s "$((0x1B2 + $part * 16))" -e '3/4 "0x%08X "' "$disk")
local type="$(( $(hex_le32_to_cpu $1) % 256))"
local lba="$(( $(hex_le32_to_cpu $2) ))"
local num="$(( $(hex_le32_to_cpu $3) ))"
[ $type -gt 0 ] || continue
printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename"
done
}
fi
}

158
package/boot/grub2/Makefile Normal file
View File

@ -0,0 +1,158 @@
#
# Copyright (C) 2006-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=grub
PKG_CPE_ID:=cpe:/a:gnu:grub2
PKG_VERSION:=2.06~rc1
PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://alpha.gnu.org/gnu/grub
PKG_HASH:=2c87f1f21e2ab50043e6cd9163c08f1b6c3a6171556bf23ff9ed65b074145484
HOST_BUILD_PARALLEL:=1
PKG_BUILD_DEPENDS:=grub2/host
PKG_ASLR_PIE:=0
PKG_SSP:=0
PKG_FLAGS:=nonshared
include $(INCLUDE_DIR)/host-build.mk
include $(INCLUDE_DIR)/package.mk
define Package/grub2/Default
CATEGORY:=Boot Loaders
SECTION:=boot
TITLE:=GRand Unified Bootloader ($(1))
URL:=http://www.gnu.org/software/grub/
DEPENDS:=@TARGET_x86
VARIANT:=$(1)
endef
Package/grub2=$(call Package/grub2/Default,pc)
Package/grub2-efi=$(call Package/grub2/Default,efi)
define Package/grub2-editenv
CATEGORY:=Utilities
SECTION:=utils
SUBMENU:=Boot Loaders
TITLE:=Grub2 Environment editor
URL:=http://www.gnu.org/software/grub/
DEPENDS:=@TARGET_x86
VARIANT:=pc
endef
define Package/grub2-editenv/description
Edit grub2 environment files.
endef
HOST_BUILD_PREFIX := $(STAGING_DIR_HOST)
CONFIGURE_VARS += \
grub_build_mkfont_excuse="don't want fonts"
CONFIGURE_ARGS += \
--target=$(REAL_GNU_TARGET_NAME) \
--disable-werror \
--disable-nls \
--disable-device-mapper \
--disable-libzfs \
--disable-liblzma \
--disable-grub-mkfont \
--with-platform=$(BUILD_VARIANT)
HOST_CONFIGURE_VARS += \
grub_build_mkfont_excuse="don't want fonts"
HOST_CONFIGURE_ARGS += \
--disable-grub-mkfont \
--target=$(REAL_GNU_TARGET_NAME) \
--sbindir="$(STAGING_DIR_HOST)/bin" \
--disable-werror \
--disable-libzfs \
--disable-nls \
--with-platform=none
HOST_MAKE_FLAGS += \
TARGET_RANLIB=$(TARGET_RANLIB) \
LIBLZMA=$(STAGING_DIR_HOST)/lib/liblzma.a
TARGET_CFLAGS := $(filter-out -O2 -O3 -fno-plt,$(TARGET_CFLAGS))
define Host/Configure
$(SED) 's,(RANLIB),(TARGET_RANLIB),' $(HOST_BUILD_DIR)/grub-core/Makefile.in
$(Host/Configure/Default)
endef
define Package/grub2/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/grub-bios-setup $(1)/usr/sbin/
$(INSTALL_DIR) $(STAGING_DIR_IMAGE)/grub2
$(CP) $(PKG_BUILD_DIR)/grub-core/boot.img $(STAGING_DIR_IMAGE)/grub2/
$(CP) $(PKG_BUILD_DIR)/grub-core/cdboot.img $(STAGING_DIR_IMAGE)/grub2/
sed 's#msdos1#gpt1#g' ./files/grub-early.cfg >$(PKG_BUILD_DIR)/grub-early.cfg
$(STAGING_DIR_HOST)/bin/grub-mkimage \
-d $(PKG_BUILD_DIR)/grub-core \
-p /boot/grub \
-O i386-pc \
-c $(PKG_BUILD_DIR)/grub-early.cfg \
-o $(STAGING_DIR_IMAGE)/grub2/gpt-core.img \
at_keyboard biosdisk boot chain configfile fat linux ls part_gpt reboot serial vga
$(STAGING_DIR_HOST)/bin/grub-mkimage \
-d $(PKG_BUILD_DIR)/grub-core \
-p /boot/grub \
-O i386-pc \
-c ./files/grub-early.cfg \
-o $(STAGING_DIR_IMAGE)/grub2/generic-core.img \
at_keyboard biosdisk boot chain configfile ext2 linux ls part_msdos reboot serial vga
$(STAGING_DIR_HOST)/bin/grub-mkimage \
-d $(PKG_BUILD_DIR)/grub-core \
-p /boot/grub \
-O i386-pc \
-c ./files/grub-early.cfg \
-o $(STAGING_DIR_IMAGE)/grub2/eltorito.img \
at_keyboard biosdisk boot chain configfile iso9660 linux ls part_msdos reboot serial test vga
$(STAGING_DIR_HOST)/bin/grub-mkimage \
-d $(PKG_BUILD_DIR)/grub-core \
-p /boot/grub \
-O i386-pc \
-c ./files/grub-early.cfg \
-o $(STAGING_DIR_IMAGE)/grub2/legacy-core.img \
biosdisk boot chain configfile ext2 linux ls part_msdos reboot serial vga
endef
define Package/grub2-efi/install
sed 's#msdos1#gpt1#g' ./files/grub-early.cfg >$(PKG_BUILD_DIR)/grub-early.cfg
$(STAGING_DIR_HOST)/bin/grub-mkimage \
-d $(PKG_BUILD_DIR)/grub-core \
-p /boot/grub \
-O $(CONFIG_ARCH)-efi \
-c $(PKG_BUILD_DIR)/grub-early.cfg \
-o $(STAGING_DIR_IMAGE)/grub2/boot$(if $(CONFIG_x86_64),x64,ia32).efi \
at_keyboard boot chain configfile fat linux ls part_gpt reboot serial efi_gop efi_uga
$(STAGING_DIR_HOST)/bin/grub-mkimage \
-d $(PKG_BUILD_DIR)/grub-core \
-p /boot/grub \
-O $(CONFIG_ARCH)-efi \
-c ./files/grub-early.cfg \
-o $(STAGING_DIR_IMAGE)/grub2/iso-boot$(if $(CONFIG_x86_64),x64,ia32).efi \
at_keyboard boot chain configfile fat iso9660 linux ls part_msdos part_gpt reboot serial test efi_gop efi_uga
endef
define Package/grub2-editenv/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/grub-editenv $(1)/usr/sbin/
endef
$(eval $(call HostBuild))
$(eval $(call BuildPackage,grub2))
$(eval $(call BuildPackage,grub2-efi))
$(eval $(call BuildPackage,grub2-editenv))

View File

@ -1,76 +0,0 @@
#
# Copyright (C) 2006-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_CPE_ID:=cpe:/a:gnu:grub2
PKG_VERSION:=2.06~rc1
PKG_RELEASE:=2
PKG_SOURCE:=grub-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://alpha.gnu.org/gnu/grub
PKG_HASH:=2c87f1f21e2ab50043e6cd9163c08f1b6c3a6171556bf23ff9ed65b074145484
HOST_BUILD_PARALLEL:=1
PKG_ASLR_PIE:=0
PKG_SSP:=0
PKG_FLAGS:=nonshared
PATCH_DIR := ../patches
HOST_PATCH_DIR := ../patches
HOST_BUILD_DIR := $(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_VERSION)
include $(INCLUDE_DIR)/host-build.mk
include $(INCLUDE_DIR)/package.mk
define Package/grub2/Default
CATEGORY:=Boot Loaders
SECTION:=boot
TITLE:=GRand Unified Bootloader
URL:=http://www.gnu.org/software/grub/
DEPENDS:=@TARGET_x86||TARGET_x86_64
endef
HOST_BUILD_PREFIX := $(STAGING_DIR_HOST)
CONFIGURE_VARS += \
grub_build_mkfont_excuse="don't want fonts"
CONFIGURE_ARGS += \
--target=$(REAL_GNU_TARGET_NAME) \
--disable-werror \
--disable-nls \
--disable-device-mapper \
--disable-libzfs \
--disable-liblzma \
--disable-grub-mkfont \
--with-platform=none
HOST_CONFIGURE_VARS += \
grub_build_mkfont_excuse="don't want fonts"
HOST_CONFIGURE_ARGS += \
--disable-grub-mkfont \
--target=$(REAL_GNU_TARGET_NAME) \
--sbindir="$(STAGING_DIR_HOST)/bin" \
--disable-werror \
--disable-libzfs \
--disable-nls
HOST_MAKE_FLAGS += \
TARGET_RANLIB=$(TARGET_RANLIB) \
LIBLZMA=$(STAGING_DIR_HOST)/lib/liblzma.a
TARGET_CFLAGS := $(filter-out -O2 -O3 -fno-plt,$(TARGET_CFLAGS))
define Host/Configure
$(SED) 's,(RANLIB),(TARGET_RANLIB),' $(HOST_BUILD_DIR)/grub-core/Makefile.in
$(Host/Configure/Default)
endef

View File

@ -1,23 +0,0 @@
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=grub-efi
include ../common.mk
TAR_OPTIONS:= --transform 's/grub-${PKG_VERSION}/${PKG_NAME}-${PKG_VERSION}/' $(TAR_OPTIONS)
PKG_BUILD_DEPENDS:=grub2-efi/host
CONFIGURE_ARGS += --with-platform=efi
HOST_CONFIGURE_ARGS += --with-platform=efi --program-suffix=-efi
HOST_BUILD_DIR := $(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_VERSION)
define Package/grub2-efi
$(call Package/grub2/Default)
HIDDEN:=1
TITLE += (with EFI support)
endef
$(eval $(call HostBuild))
$(eval $(call BuildPackage,grub2-efi))

View File

@ -1,33 +0,0 @@
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=grub
include ../common.mk
PKG_BUILD_DEPENDS:=grub2/host
define Package/grub2
$(call Package/grub2/Default)
endef
define Package/grub2-editenv
CATEGORY:=Utilities
SECTION:=utils
TITLE:=Grub2 Environment editor
URL:=http://www.gnu.org/software/grub/
DEPENDS:=@TARGET_x86||TARGET_x86_64
endef
define Package/grub2-editenv/description
Edit grub2 environment files.
endef
define Package/grub2-editenv/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/grub-editenv $(1)/usr/sbin/
endef
$(eval $(call HostBuild))
$(eval $(call BuildPackage,grub2))
$(eval $(call BuildPackage,grub2-editenv))

View File

@ -32,7 +32,7 @@ Signed-off-by: Ismael Ripoll-Ripoll <iripoll@disca.upv.es>
@@ -172,7 +172,7 @@ grub_username_get (char buf[], unsigned
break;
}
- if (key == GRUB_TERM_BACKSPACE)
+ if (key == GRUB_TERM_BACKSPACE && cur_len)
{

View File

@ -20,7 +20,7 @@ sect=63
cyl=$(( (KERNELSIZE + ROOTFSSIZE) * 1024 * 1024 / (head * sect * 512)))
# create partition table
set $(ptgen -o "$OUTPUT" -h $head -s $sect -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 0x$SIGNATURE})
set $(ptgen -o "$OUTPUT" -h $head -s $sect ${GUID:+-g} -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 0x$SIGNATURE} ${GUID:+-G $GUID})
KERNELOFFSET="$(($1 / 512))"
KERNELSIZE="$2"
@ -30,6 +30,12 @@ ROOTFSSIZE="$(($4 / 512))"
[ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc count="$ROOTFSSIZE"
dd if="$ROOTFSIMAGE" of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc
make_ext4fs -J -L kernel -l "$KERNELSIZE" "$OUTPUT.kernel" "$KERNELDIR"
if [ -n "$GUID" ]; then
[ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 seek="$(($ROOTFSOFFSET + $ROOTFSSIZE))" conv=notrunc count="$sect"
mkfs.fat -n kernel -C "$OUTPUT.kernel" -S 512 "$(($KERNELSIZE / 1024))"
mcopy -s -i "$OUTPUT.kernel" "$KERNELDIR"/* ::/
else
make_ext4fs -J -L kernel -l "$KERNELSIZE" "$OUTPUT.kernel" "$KERNELDIR"
fi
dd if="$OUTPUT.kernel" of="$OUTPUT" bs=512 seek="$KERNELOFFSET" conv=notrunc
rm -f "$OUTPUT.kernel"

View File

@ -10,7 +10,7 @@ platform_check_image_sdcard() {
get_partitions "/dev/$diskdev" bootdisk
#extract the boot sector from the image
get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null
get_image_dd "$1" of=/tmp/image.bs count=1 bs=512b
get_partitions /tmp/image.bs image
@ -41,7 +41,7 @@ platform_do_upgrade_sdcard() {
get_partitions "/dev/$diskdev" bootdisk
#extract the boot sector from the image
get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b
get_image_dd "$1" of=/tmp/image.bs count=1 bs=512b
get_partitions /tmp/image.bs image
@ -52,7 +52,7 @@ platform_do_upgrade_sdcard() {
fi
if [ -n "$diff" ]; then
get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync
get_image_dd "$1" of="/dev/$diskdev" bs=4096 conv=fsync
# Separate removal and addtion is necessary; otherwise, partition 1
# will be missing if it overlaps with the old partition 2
@ -60,12 +60,12 @@ platform_do_upgrade_sdcard() {
partx -a - "/dev/$diskdev"
else
#write uboot image
get_image "$@" | dd of="$diskdev" bs=512 skip=1 seek=1 count=2048 conv=fsync
get_image_dd "$1" of="$diskdev" bs=512 skip=1 seek=1 count=2048 conv=fsync
#iterate over each partition from the image and write it to the boot disk
while read part start size; do
if export_partdevice partdev $part; then
echo "Writing image to /dev/$partdev..."
get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
get_image_dd "$1" of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
else
echo "Unable to find partition $part device, skipped."
fi
@ -73,7 +73,7 @@ platform_do_upgrade_sdcard() {
#copy partition uuid
echo "Writing new UUID to /dev/$diskdev..."
get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
get_image_dd "$1" of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
fi
sleep 1

View File

@ -10,7 +10,6 @@ BOARDNAME := NVIDIA Tegra
FEATURES := audio boot-part display ext4 fpu gpio pci pcie rootfs-part rtc squashfs usb
CPU_TYPE := cortex-a9
CPU_SUBTYPE := vfpv3-d16
MAINTAINER := Tomasz Maciej Nowak <tomek_n@o2.pl>
KERNEL_PATCHVER := 5.4
KERNEL_TESTING_PATCHVER := 5.10

View File

@ -3,8 +3,6 @@ REQUIRE_IMAGE_METADATA=1
platform_check_image() {
local diskdev partdev diff
[ "$#" -gt 1 ] && return 1
export_bootdevice && export_partdevice diskdev 0 || {
echo "Unable to determine upgrade device"
return 1
@ -13,7 +11,7 @@ platform_check_image() {
get_partitions "/dev/$diskdev" bootdisk
#extract the boot sector from the image
get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null
get_image_dd "$1" of=/tmp/image.bs count=1 bs=512b
get_partitions /tmp/image.bs image
@ -53,7 +51,7 @@ platform_do_upgrade() {
get_partitions "/dev/$diskdev" bootdisk
#extract the boot sector from the image
get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b
get_image_dd "$1" of=/tmp/image.bs count=1 bs=512b
get_partitions /tmp/image.bs image
@ -64,7 +62,7 @@ platform_do_upgrade() {
fi
if [ -n "$diff" ]; then
get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync
get_image_dd "$1" of="/dev/$diskdev" bs=4096 conv=fsync
# Separate removal and addtion is necessary; otherwise, partition 1
# will be missing if it overlaps with the old partition 2
@ -74,11 +72,13 @@ platform_do_upgrade() {
return 0
fi
echo "Writing bootloader to /dev/$diskdev"
get_image_dd "$1" of="$diskdev" bs=512 skip=1 seek=1 count=4097 conv=fsync,notrunc
#iterate over each partition from the image and write it to the boot disk
while read part start size; do
if export_partdevice partdev $part; then
echo "Writing image to /dev/$partdev..."
get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
get_image_dd "$1" of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
else
echo "Unable to find partition $part device, skipped."
fi
@ -86,5 +86,5 @@ platform_do_upgrade() {
#copy partition uuid
echo "Writing new UUID to /dev/$diskdev..."
get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
get_image_dd "$1" of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
}

View File

@ -43,7 +43,7 @@ define Device/compulab_trimslice
DEVICE_MODEL := TrimSlice
DEVICE_DTS := tegra20-trimslice
DEVICE_PACKAGES := kmod-r8169 kmod-rt2800-usb kmod-rtc-em3027 \
kmod-usb-storage wpad-mini
kmod-usb-storage wpad-basic-wolfssl
UBOOT := trimslice-mmc
endef
TARGET_DEVICES += compulab_trimslice

View File

@ -1,15 +0,0 @@
#
# Copyright (C) 2006-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
define Profile/Generic
NAME:=Generic
endef
define Profile/Generic/Description
Generic Profile
endef
$(eval $(call Profile,Generic))

View File

@ -1,5 +1,5 @@
ARCH:=x86_64
BOARDNAME:=x64 64bit
BOARDNAME:=x64_64
DEFAULT_PACKAGES += kmod-button-hotplug kmod-e1000e kmod-e1000 kmod-igb kmod-bnx2
define Target/Description

View File

@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
ARCH:=i386
BOARD:=x86
BOARDNAME:=x86
FEATURES:=squashfs vdi vmdk pcmcia fpu
FEATURES:=squashfs ext4 vdi vmdk pcmcia targz fpu boot-part rootfs-part
SUBTARGETS:=64 generic zen legacy geode
MAINTAINER:=Felix Fietkau <nbd@nbd.name>
@ -27,6 +27,9 @@ kmod-usb-net kmod-usb-net-asix kmod-usb-net-asix-ax88179 kmod-usb-net-rtl8150 km
$(eval $(call BuildTarget))
$(eval $(call $(if $(CONFIG_TARGET_ROOTFS_ISO),RequireCommand,Ignore),mkisofs, \
Please install mkisofs. \
$(eval $(call $(if $(CONFIG_ISO_IMAGES),SetupHostCommand,Ignore),mkisofs, \
Please install mkisofs. , \
mkisofs -v 2>&1 , \
genisoimage -v 2>&1 | grep genisoimage, \
xorrisofs -v 2>&1 | grep xorriso \
))

View File

@ -1,15 +1,16 @@
# Copyright (C) 2012-2015 OpenWrt.org
move_config() {
local partdev
local partdev parttype=ext4
. /lib/upgrade/common.sh
if export_bootdevice && export_partdevice partdev 1; then
mkdir -p /boot
mount -t ext4 -o rw,noatime "/dev/$partdev" /boot
if [ -f /boot/sysupgrade.tgz ]; then
mv -f /boot/sysupgrade.tgz /
part_magic_fat "/dev/$partdev" && parttype=vfat
mount -t $parttype -o rw,noatime "/dev/$partdev" /boot
if [ -f "/boot/sysupgrade.tgz" ]; then
mv -f "/boot/sysupgrade.tgz" /
fi
mount --bind /boot/boot /boot
fi

View File

@ -0,0 +1,18 @@
upgrade_bootloader() {
local diskdev
. /lib/upgrade/common.sh
if [ ! -f /boot/grub/upgraded ] && export_bootdevice && export_partdevice diskdev 0; then
part_magic_efi "/dev/$diskdev" && return 0
echo "(hd0) /dev/$diskdev" > /tmp/device.map
/usr/sbin/grub-bios-setup \
-m "/tmp/device.map" \
-d "/boot/grub" \
-r "hd0,msdos1" \
"/dev/$diskdev" \
&& touch /boot/grub/upgraded
fi
}
[ "$INITRAMFS" = "1" ] || boot_hook_add preinit_main upgrade_bootloader

View File

@ -1,3 +1,5 @@
RAMFS_COPY_BIN='grub-bios-setup'
platform_check_image() {
local diskdev partdev diff
[ "$#" -gt 1 ] && return 1
@ -17,8 +19,8 @@ platform_check_image() {
get_partitions "/dev/$diskdev" bootdisk
#extract the boot sector from the image
get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null
echo "Extract boot sector from the image"
get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b
get_partitions /tmp/image.bs image
@ -35,15 +37,38 @@ platform_check_image() {
}
platform_copy_config() {
local partdev
local partdev parttype=ext4
if export_partdevice partdev 1; then
mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt
cp -af "$CONF_TAR" /mnt/
part_magic_fat "/dev/$partdev" && parttype=vfat
mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
cp -af "$CONF_TAR" "/mnt/"
umount /mnt
fi
}
platform_do_bootloader_upgrade() {
local bootpart parttable=msdos
local diskdev="$1"
if export_partdevice bootpart 1; then
mkdir -p /tmp/boot
mount -o rw,noatime "/dev/$bootpart" /tmp/boot
echo "(hd0) /dev/$diskdev" > /tmp/device.map
part_magic_efi "/dev/$diskdev" && parttable=gpt
echo "Upgrading bootloader on /dev/$diskdev..."
grub-bios-setup \
-m "/tmp/device.map" \
-d "/tmp/boot/boot/grub" \
-r "hd0,${parttable}1" \
"/dev/$diskdev" \
&& touch /tmp/boot/boot/grub/upgraded
umount /tmp/boot
fi
}
platform_do_upgrade() {
local diskdev partdev diff
@ -54,11 +79,11 @@ platform_do_upgrade() {
sync
if [ "$SAVE_PARTITIONS" = "1" ]; then
if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then
get_partitions "/dev/$diskdev" bootdisk
#extract the boot sector from the image
get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b
echo "Extract boot sector from the image"
get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b
get_partitions /tmp/image.bs image
@ -69,7 +94,7 @@ platform_do_upgrade() {
fi
if [ -n "$diff" ]; then
get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync
get_image_dd "$1" of="/dev/$diskdev" bs=4096 conv=fsync
# Separate removal and addtion is necessary; otherwise, partition 1
# will be missing if it overlaps with the old partition 2
@ -83,13 +108,24 @@ platform_do_upgrade() {
while read part start size; do
if export_partdevice partdev $part; then
echo "Writing image to /dev/$partdev..."
get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
get_image_dd "$1" of="/dev/$partdev" ibs=512 obs=1M skip="$start" count="$size" conv=fsync
else
echo "Unable to find partition $part device, skipped."
fi
done < /tmp/partmap.image
#copy partition uuid
echo "Writing new UUID to /dev/$diskdev..."
get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
get_image_dd "$1" of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
platform_do_bootloader_upgrade "$diskdev"
local parttype=ext4
part_magic_efi "/dev/$diskdev" || return 0
if export_partdevice partdev 1; then
part_magic_fat "/dev/$partdev" && parttype=vfat
mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
set -- $(dd if="/dev/$diskdev" bs=1 skip=1168 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"')
sed -i "s/\(PARTUUID=\)[a-f0-9-]\+/\1$4$3$2$1-$6$5-$8$7-$9/ig" /mnt/boot/grub/grub.cfg
umount /mnt
fi
}

View File

@ -139,6 +139,7 @@ CONFIG_FB_DEFERRED_IO=y
CONFIG_FB_EFI=y
CONFIG_FB_HYPERV=y
# CONFIG_FB_I810 is not set
CONFIG_FB_SIMPLE=y
CONFIG_FB_SYS_COPYAREA=y
CONFIG_FB_SYS_FILLRECT=y
CONFIG_FB_SYS_FOPS=y

View File

@ -1,18 +0,0 @@
#
# Copyright (C) 2006-2009 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
define Profile/Generic
NAME:=Generic
PACKAGES:=kmod-3c59x kmod-e100 kmod-e1000 kmod-natsemi kmod-ne2k-pci \
kmod-pcnet32 kmod-8139too kmod-r8169 kmod-sis900 kmod-tg3 \
kmod-via-rhine kmod-via-velocity
endef
define Profile/Generic/Description
Generic Profile
endef
$(eval $(call Profile,Generic))

View File

@ -1,4 +1,4 @@
BOARDNAME:=x86 32bit
BOARDNAME:=Generic
CPU_TYPE :=pentium4
FEATURES += audio pci pcie usb
DEFAULT_PACKAGES += kmod-button-hotplug

View File

@ -1,20 +0,0 @@
#
# Copyright (C) 2006-2009 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
define Profile/Generic
NAME:=Generic
PACKAGES:= \
soloscli linux-atm br2684ctl ppp-mod-pppoa pppdump pppstats \
hwclock flashrom tc kmod-pppoa kmod-8139cp kmod-mppe \
kmod-usb-ohci-pci kmod-hwmon-lm90 \
kmod-via-rhine
endef
define Profile/Generic/Description
Generic Profile for all Geode boards.
endef
$(eval $(call Profile,Generic))

View File

@ -1,19 +0,0 @@
#
# Copyright (C) 2006-2009 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
define Profile/Geos
NAME:=Geos
PACKAGES:= \
soloscli linux-atm br2684ctl ppp-mod-pppoa pppdump pppstats \
hwclock flashrom tc kmod-pppoa kmod-8139cp kmod-mppe \
kmod-usb-ohci-pci kmod-hwmon-lm90
endef
define Profile/Geos/Description
Traverse Technologies Geos ADSL router
endef
$(eval $(call Profile,Geos))

View File

@ -0,0 +1,7 @@
define Device/generic
DEVICE_TITLE := Generic x86/64
DEVICE_PACKAGES += kmod-amazon-ena kmod-bnx2 kmod-e1000e kmod-e1000 \
kmod-forcedeth kmod-igb kmod-ixgbe kmod-amd-xgbe kmod-r8169
GRUB2_VARIANT := generic
endef
TARGET_DEVICES += generic

View File

@ -5,27 +5,11 @@
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/image.mk
export PATH=$(TARGET_PATH):/sbin
SUPPORTED_DEVICES :=
GRUB2_MODULES = biosdisk boot chain configfile ext2 linux ls part_msdos reboot serial vga
GRUB2_MODULES_LEGACY = $(GRUB2_MODULES)
GRUB2_MODULES_LEGACY += part_gpt search fat exfat
GRUB2_MODULES_EFI = boot chain configfile ext2 linux ls part_msdos reboot serial part_gpt part_msdos search fat exfat ext2 efi_gop efi_uga gfxterm
GRUB2_MODULES_ISO = biosdisk boot chain configfile iso9660 linux ls part_msdos reboot serial vga
GRUB2_VARIANT =
GRUB_TERMINALS =
GRUB_SERIAL_CONFIG =
GRUB_TERMINAL_CONFIG =
GRUB_CONSOLE_CMDLINE =
GRUB_ROOT = hd0,msdos1
USE_ATKBD = generic 64
ifneq ($(strip $(foreach subtarget,$(USE_ATKBD),$(CONFIG_TARGET_x86_$(subtarget)))),)
GRUB2_MODULES += at_keyboard
GRUB2_MODULES_ISO += at_keyboard
endif
ifneq ($(CONFIG_GRUB_CONSOLE),)
GRUB_CONSOLE_CMDLINE += console=tty0
@ -44,313 +28,136 @@ ifneq ($(GRUB_TERMINALS),)
GRUB_TERMINAL_CONFIG := terminal_input $(GRUB_TERMINALS); terminal_output $(GRUB_TERMINALS)
endif
SIGNATURE:=$(shell perl -e 'printf("%08x", rand(0xFFFFFFFF))')
EFI_SIGNATURE:=$(strip $(shell uuidgen | sed "s/[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]$$/0002/" | tr '[a-z]' '[A-Z]'))
ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME))
ROOTPART:=$(if $(ROOTPART),$(ROOTPART),PARTUUID=$(SIGNATURE)-02)
ROOTPART:=$(if $(ROOTPART),$(ROOTPART),PARTUUID=$(IMG_PART_SIGNATURE)-02)
GPT_ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME))
GPT_ROOTPART:=$(if $(GPT_ROOTPART),$(GPT_ROOTPART),PARTUUID=$(shell echo $(IMG_PART_DISKGUID) | sed 's/00$$/02/'))
GRUB_TIMEOUT:=$(call qstrip,$(CONFIG_GRUB_TIMEOUT))
GRUB_TITLE:=$(call qstrip,$(CONFIG_GRUB_TITLE))
ifneq ($(CONFIG_TARGET_x86_xen_domu),)
GRUB_ROOT = xen/xvda,msdos1
endif
BOOTOPTS:=$(call qstrip,$(CONFIG_GRUB_BOOTOPTS))
ifneq ($(CONFIG_GRUB_IMAGES)$(CONFIG_EFI_IMAGES),)
BOOTOPTS:=$(call qstrip,$(CONFIG_GRUB_BOOTOPTS))
define Image/cmdline/ext4
root=$(ROOTPART) rootfstype=ext4 rootwait
endef
define Image/cmdline/squashfs
root=$(ROOTPART) rootfstype=squashfs rootwait
endef
ifneq ($(CONFIG_EFI_IMAGES),)
define Image/cmdline/efi
$(subst $(SIGNATURE)-02,$2,$(call Image/cmdline/$(1)))
endef
define Image/Build/efi
# left here because the image builder doesnt need these
rm -rf $(KDIR)/root.grub/ || true
$(INSTALL_DIR) $(KDIR)/root.grub/boot/grub $(KDIR)/grub2
$(CP) $(KDIR)/bzImage $(KDIR)/root.grub/boot/vmlinuz
echo '(hd0) $(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img' > $(KDIR)/grub2/device.map
sed \
-e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \
-e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \
-e 's#@CMDLINE@#$(strip $(call Image/cmdline/efi,$(1),$(EFI_SIGNATURE)) $(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE))#g' \
-e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \
-e 's#@TITLE@#$(GRUB_TITLE)#g' \
-e 's#set root.*#search --file /boot/grub/$(SIGNATURE).cfg --set=root#g' \
./grub.cfg > $(KDIR)/root.grub/boot/grub/grub.cfg
sed \
-e 's/(hd0,msdos1)/(hd0,gpt1)/' ./grub-early.cfg > \
$(KDIR)/root.grub/boot/grub/grub-early.cfg
$(CP) $(KDIR)/root.grub/boot/grub/grub.cfg $(KDIR)/root.grub/boot/grub/$(SIGNATURE).cfg
grub-mkimage \
-d $(STAGING_DIR_HOST)/lib/grub/i386-pc \
-o $(KDIR)/grub2/core.img \
-O i386-pc \
-p '(hd0,gpt1)/boot/grub' \
-c $(KDIR)/root.grub/boot/grub/grub-early.cfg \
$(GRUB2_MODULES_LEGACY)
$(CP) $(STAGING_DIR_HOST)/lib/grub/i386-pc/*.img $(KDIR)/grub2/
# Build the efi grub version
rm -rf $(KDIR)/grub2.efi/ || true
$(INSTALL_DIR) $(KDIR)/grub2.efi/efi/boot/
# Generate the grub search root config (grub will search for the $(SIGNATURE).cfg file placed on the boot partition as grub does not support search of GPT UUID yet)
echo "search --file /boot/grub/$(SIGNATURE).cfg --set=root" > $(KDIR)/grub2.efi/efi/boot/grub.cfg
echo "configfile /boot/grub/grub.cfg" >> $(KDIR)/grub2.efi/efi/boot/grub.cfg
# Create the EFI grub binary
grub-mkimage-efi \
-d $(STAGING_DIR_HOST)/lib/grub/x86_64-efi \
-o $(KDIR)/grub2.efi/efi/boot/bootx64.efi \
-O x86_64-efi \
-p /efi/boot \
-c $(KDIR)/grub2.efi/efi/boot/grub.cfg \
$(GRUB2_MODULES_EFI)
# Generate the EFI VFAT bootfs
rm $(KDIR)/kernel.efi || true
mkfs.fat -C $(KDIR)/kernel.efi -S 512 1024
mcopy -s -i "$(KDIR)/kernel.efi" $(KDIR)/grub2.efi/* ::/
SIGNATURE="$(SIGNATURE)" PATH="$(TARGET_PATH)" ./gen_image_efi.sh \
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img \
$(CONFIG_TARGET_KERNEL_PARTSIZE) $(KDIR)/root.grub \
1 $(KDIR)/kernel.efi \
1 \
$(CONFIG_TARGET_ROOTFS_PARTSIZE) $(KDIR)/root.$(1) \
define Build/combined
$(CP) $(KDIR)/$(KERNEL_NAME) $@.boot/boot/vmlinuz
-$(CP) $(STAGING_DIR_ROOT)/boot/. $@.boot/boot/
$(CP) $(STAGING_DIR_IMAGE)/grub2/boot.img $@.boot/boot/grub/
$(CP) $(STAGING_DIR_IMAGE)/grub2/$(if $(filter $(1),efi),gpt,$(GRUB2_VARIANT))-core.img \
$@.boot/boot/grub/core.img
$(if $(filter $(1),efi),
$(INSTALL_DIR) $@.boot/efi/boot
$(CP) $(STAGING_DIR_IMAGE)/grub2/boot$(if $(CONFIG_x86_64),x64,ia32).efi $@.boot/efi/boot/
)
PADDING="1" SIGNATURE="$(IMG_PART_SIGNATURE)" \
$(if $(filter $(1),efi),GUID="$(IMG_PART_DISKGUID)") $(SCRIPT_DIR)/gen_image_generic.sh \
$@ \
$(CONFIG_TARGET_KERNEL_PARTSIZE) $@.boot \
$(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) \
256
# Setup legacy bios for hybrid MBR (optional)
grub-bios-setup \
--device-map="$(KDIR)/grub2/device.map" \
-d "$(KDIR)/grub2" \
-r "hd0,msdos1" \
"$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img"
# Convert the MBR partition to GPT and set EFI ROOTFS signature
dd if=/dev/zero of="$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img" bs=512 count=34 conv=notrunc oflag=append
sgdisk -g "$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img"
sgdisk -t 2:EF00 "$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img"
sgdisk -t 3:EF02 "$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img"
sgdisk -u 4:$(EFI_SIGNATURE) "$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img"
sgdisk -h "$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img"
# Setup EFI grub
grub-bios-setup-efi \
--device-map="$(KDIR)/grub2/device.map" \
-d "$(KDIR)/grub2" \
-r "hd0,gpt1" \
"$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img"
endef
endif
ifneq ($(CONFIG_GRUB_IMAGES),)
define Image/Build/grub2
# left here because the image builder doesnt need these
$(INSTALL_DIR) $(KDIR)/root.grub/boot/grub $(KDIR)/grub2
$(CP) $(KDIR)/bzImage $(KDIR)/root.grub/boot/vmlinuz
grub-mkimage \
-p /boot/grub \
-d $(STAGING_DIR_HOST)/lib/grub/i386-pc \
-o $(KDIR)/grub2/core.img \
-O i386-pc \
-c ./grub-early.cfg \
$(GRUB2_MODULES)
$(CP) $(STAGING_DIR_HOST)/lib/grub/i386-pc/*.img $(KDIR)/grub2/
echo '(hd0) $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img' > $(KDIR)/grub2/device.map
sed \
-e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \
-e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \
-e 's#@CMDLINE@#$(strip $(call Image/cmdline/$(1)) $(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE))#g' \
-e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \
-e 's#@ROOT@#$(GRUB_ROOT)#g' \
-e 's#@TITLE@#$(GRUB_TITLE)#g' \
./grub.cfg > $(KDIR)/root.grub/boot/grub/grub.cfg
-$(CP) $(STAGING_DIR_ROOT)/boot/. $(KDIR)/root.grub/boot/
PADDING="$(CONFIG_TARGET_IMAGES_PAD)" SIGNATURE="$(SIGNATURE)" PATH="$(TARGET_PATH)" $(SCRIPT_DIR)/gen_image_generic.sh \
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img \
$(CONFIG_TARGET_KERNEL_PARTSIZE) $(KDIR)/root.grub \
$(CONFIG_TARGET_ROOTFS_PARTSIZE) $(KDIR)/root.$(1) \
256
grub-bios-setup \
--device-map="$(KDIR)/grub2/device.map" \
-d "$(KDIR)/grub2" \
-r "hd0,msdos1" \
"$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img"
endef
endif
endif
define Image/Build/squashfs
dd if=/dev/zero bs=128k count=1 >> $(KDIR)/root.squashfs
endef
define Image/Build/iso
$(INSTALL_DIR) $(KDIR)/root.grub/boot/grub $(KDIR)/grub2
$(CP) $(KDIR)/bzImage $(KDIR)/root.grub/boot/vmlinuz
grub-mkimage \
-p /boot/grub \
-d $(STAGING_DIR_HOST)/lib/grub/i386-pc \
-o $(KDIR)/grub2/eltorito.img \
-O i386-pc \
-c ./grub-early.cfg \
$(GRUB2_MODULES_ISO)
define Build/grub-config
rm -fR $@.boot
$(INSTALL_DIR) $@.boot/boot/grub
sed \
-e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \
-e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \
-e 's#@ROOTPART@#root=$(ROOTPART) rootwait#g' \
-e 's#@GPT_ROOTPART@#root=$(GPT_ROOTPART) rootwait#g' \
-e 's#@CMDLINE@#$(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE)#g' \
-e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \
-e 's#@TITLE@#$(GRUB_TITLE)#g' \
./grub-$(1).cfg > $@.boot/boot/grub/grub.cfg
endef
define Build/grub-install
rm -fR $@.grub2
$(INSTALL_DIR) $@.grub2
$(CP) $(STAGING_DIR_IMAGE)/grub2/boot.img $@.grub2/
$(CP) $(STAGING_DIR_IMAGE)/grub2/$(if $(filter $(1),efi),gpt,$(GRUB2_VARIANT))-core.img $@.grub2/core.img
echo '(hd0) $@' > $@.grub2/device.map
$(STAGING_DIR_HOST)/bin/grub-bios-setup \
-m "$@.grub2/device.map" \
-d "$@.grub2" \
-r "hd0,$(if $(filter $(1),efi),gpt1,msdos1)" \
$@
endef
define Build/iso
$(CP) $(KDIR)/$(KERNEL_NAME) $@.boot/boot/vmlinuz
cat \
$(STAGING_DIR_HOST)/lib/grub/i386-pc/cdboot.img \
$(KDIR)/grub2/eltorito.img \
> $(KDIR)/root.grub/boot/grub/eltorito.img
sed \
-e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \
-e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \
-e 's#@CMDLINE@#root=/dev/sr0 rootfstype=iso9660 rootwait $(strip $(call Image/cmdline/$(1)) $(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE))#g' \
-e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \
-e 's#@TITLE@#$(GRUB_TITLE)#g' \
./grub-iso.cfg > $(KDIR)/root.grub/boot/grub/grub.cfg
-$(CP) $(STAGING_DIR_ROOT)/boot/. $(KDIR)/root.grub/boot/
$(STAGING_DIR_IMAGE)/grub2/cdboot.img \
$(STAGING_DIR_IMAGE)/grub2/eltorito.img \
> $@.boot/boot/grub/eltorito.img
-$(CP) $(STAGING_DIR_ROOT)/boot/. $@.boot/boot/
$(if $(filter $(1),efi),
mkfs.fat -C $@.boot/boot/grub/isoboot.img -S 512 1440
mmd -i $@.boot/boot/grub/isoboot.img ::/efi ::/efi/boot
mcopy -i $@.boot/boot/grub/isoboot.img \
$(STAGING_DIR_IMAGE)/grub2/iso-boot$(if $(CONFIG_x86_64),x64,ia32).efi \
::/efi/boot/boot$(if $(CONFIG_x86_64),x64,ia32).efi
)
mkisofs -R -b boot/grub/eltorito.img -no-emul-boot -boot-info-table \
-o $(KDIR)/root.iso $(KDIR)/root.grub $(TARGET_DIR)
$(if $(filter $(1),efi),-boot-load-size 4 -c boot.cat -eltorito-alt-boot -b boot/grub/isoboot.img -no-emul-boot) \
-o $@ $@.boot $(TARGET_DIR)
endef
ifneq ($(CONFIG_VDI_IMAGES),)
define Image/Build/vdi
rm $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).vdi || true
$(STAGING_DIR_HOST)/bin/qemu-img convert -f raw -O vdi \
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img \
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).vdi
# XXX: VBoxManage insists on setting perms to 0600
chmod 0644 $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).vdi
endef
define Image/Build/vdi_efi
rm $(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).vdi || true
$(STAGING_DIR_HOST)/bin/qemu-img convert -f raw -O vdi \
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img \
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).vdi
# XXX: VBoxManage insists on setting perms to 0600
chmod 0644 $(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).vdi
endef
endif
ifneq ($(CONFIG_VMDK_IMAGES),)
define Image/Build/vmdk
rm $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).vmdk || true
$(STAGING_DIR_HOST)/bin/qemu-img convert -f raw -O vmdk -o adapter_type=lsilogic \
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img \
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).vmdk
#build the ESXI VMDK with
rm $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1)-esxi.vmdk || true
rm $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1)-esxi-flat.vmdk || true
$(STAGING_DIR_HOST)/bin/qemu-img convert -f raw -O vmdk -o adapter_type=lsilogic,subformat=monolithicFlat \
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img \
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1)-esxi.vmdk
endef
define Image/Build/vmdk_efi
rm $(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).vmdk || true
$(STAGING_DIR_HOST)/bin/qemu-img convert -f raw -O vmdk -o adapter_type=lsilogic \
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img \
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).vmdk
endef
endif
ifneq ($(CONFIG_VHD_IMAGES),)
define Image/Build/vhd
rm $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).vhdx || true
$(STAGING_DIR_HOST)/bin/qemu-img convert -O vhdx \
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img \
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).vhdx
endef
define Image/Build/vhd_efi
rm $(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).vhdx || true
$(STAGING_DIR_HOST)/bin/qemu-img convert -O vhdx \
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img \
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).vhdx
endef
endif
ifneq ($(CONFIG_QCOW2_IMAGES),)
define Image/Build/qcow2
rm $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).qcow2 || true
$(STAGING_DIR_HOST)/bin/qemu-img convert -f raw -O qcow2 \
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img \
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).qcow2
endef
define Image/Build/qcow2_efi
rm $(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).qcow2 || true
$(STAGING_DIR_HOST)/bin/qemu-img convert -f raw -O qcow2 \
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img \
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).qcow2
endef
endif
define Image/Build/gzip
gzip -f9n $(BIN_DIR)/$(IMG_PREFIX)-rootfs-$(1).img
ifneq ($(CONFIG_GRUB_IMAGES),)
gzip -f9n $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img
endif
ifneq ($(CONFIG_EFI_IMAGES),)
gzip -f9n $(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img
endif
endef
ifneq ($(CONFIG_TARGET_IMAGES_GZIP),)
define Image/Build/gzip/ext4
$(call Image/Build/gzip,ext4)
endef
define Image/Build/gzip/squashfs
$(call Image/Build/gzip,squashfs)
endef
endif
define Image/BuildKernel
$(CP) $(KDIR)/bzImage $(BIN_DIR)/$(IMG_PREFIX)-vmlinuz
endef
define Image/Prepare
$(call Image/Prepare/grub2)
endef
define Image/Build/Initramfs
$(CP) $(KDIR)/bzImage-initramfs $(BIN_DIR)/$(IMG_PREFIX)-ramfs.bzImage
endef
define Image/Build
$(call Image/Build/$(1))
ifneq ($(1),iso)
$(call Image/Build/grub2,$(1))
$(call Image/Build/efi,$(1))
ifneq ($(CONFIG_GRUB_IMAGES),)
$(call Image/Build/vdi,$(1))
$(call Image/Build/vmdk,$(1))
$(call Image/Build/vhd,$(1))
$(call Image/Build/qcow2,$(1))
endif
ifneq ($(CONFIG_EFI_IMAGES),)
$(call Image/Build/vdi_efi,$(1))
$(call Image/Build/vmdk_efi,$(1))
$(call Image/Build/vhd_efi,$(1))
$(call Image/Build/qcow2_efi,$(1))
endif
$(CP) $(KDIR)/root.$(1) $(BIN_DIR)/$(IMG_PREFIX)-rootfs-$(1).img
DEVICE_VARS += GRUB2_VARIANT
define Device/Default
ARTIFACT/image.iso := grub-config iso | iso
IMAGE/combined.img := grub-config pc | combined | grub-install | append-metadata
IMAGE/combined.img.gz := grub-config pc | combined | grub-install | gzip | append-metadata
IMAGE/combined.qcow2 := grub-config pc | combined | grub-install | qemu-image qcow2
IMAGE/combined.vdi := grub-config pc | combined | grub-install | qemu-image vdi
IMAGE/combined.vhdx := grub-config pc | combined | grub-install | qemu-image vhdx
IMAGE/combined.vmdk := grub-config pc | combined | grub-install | qemu-image vmdk
IMAGE/rootfs.img := append-rootfs | pad-to $(ROOTFS_PARTSIZE)
IMAGE/rootfs.img.gz := append-rootfs | pad-to $(ROOTFS_PARTSIZE) | gzip
ARTIFACT/image-efi.iso := grub-config iso | iso efi
IMAGE/combined-efi.img := grub-config efi | combined efi | grub-install efi | append-metadata
IMAGE/combined-efi.img.gz := grub-config efi | combined efi | grub-install efi | gzip | append-metadata
IMAGE/combined-efi.qcow2 := grub-config efi | combined efi | grub-install efi | qemu-image qcow2
IMAGE/combined-efi.vdi := grub-config efi | combined efi | grub-install efi | qemu-image vdi
IMAGE/combined-efi.vhdx := grub-config efi | combined efi | grub-install efi | qemu-image vhdx
IMAGE/combined-efi.vmdk := grub-config efi | combined efi | grub-install efi | qemu-image vmdk
ifeq ($(CONFIG_TARGET_IMAGES_GZIP),y)
IMAGES-y := rootfs.img.gz
IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.img.gz
IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.img.gz
else
$(CP) $(KDIR)/root.iso $(BIN_DIR)/$(IMG_PREFIX).iso
IMAGES-y := rootfs.img
IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.img
IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.img
endif
$(CP) $(KDIR)/bzImage $(BIN_DIR)/$(IMG_PREFIX)-vmlinuz
$(call Image/Build/gzip/$(1))
ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y)
$(call Image/Build/Initramfs)
endif
KERNEL := kernel-bin
KERNEL_INSTALL := 1
KERNEL_NAME := bzImage
ifeq ($(CONFIG_ISO_IMAGES),y)
ARTIFACTS-$$(CONFIG_GRUB_IMAGES) += image.iso
ARTIFACTS-$$(CONFIG_GRUB_EFI_IMAGES) += image-efi.iso
endif
ifeq ($(CONFIG_QCOW2_IMAGES),y)
IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.qcow2
IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.qcow2
endif
ifeq ($(CONFIG_VDI_IMAGES),y)
IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.vdi
IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.vdi
endif
ifeq ($(CONFIG_VHDX_IMAGES),y)
IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.vhdx
IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.vhdx
endif
ifeq ($(CONFIG_VMDK_IMAGES),y)
IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.vmdk
IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.vmdk
endif
IMAGES := $$(IMAGES-y)
ARTIFACTS := $$(ARTIFACTS-y)
SUPPORTED_DEVICES :=
endef
include $(SUBTARGET).mk
$(eval $(call BuildImage))

View File

@ -1,44 +0,0 @@
#!/usr/bin/env bash
set -x
[ $# == 8 -o $# == 9 ] || {
echo "SYNTAX: $0 <file> <kernel size> <kernel directory> <efi size> <efi image> <efigrubmodule size> <rootfs size> <rootfs image> [<align>]"
exit 1
}
OUTPUT="$1"
KERNELSIZE="$2"
KERNELDIR="$3"
EFISIZE="$4"
EFIIMAGE="$5"
EFIGRUBSIZE="$6"
ROOTFSSIZE="$7"
ROOTFSIMAGE="$8"
ALIGN="$9"
rm -f "$OUTPUT"
head=16
sect=63
cyl=$(( ($KERNELSIZE + $EFISIZE + $EFIGRUBSIZE + $ROOTFSSIZE) * 1024 * 1024 / ($head * $sect * 512) ))
# create partition table
set `ptgen -o "$OUTPUT" -h $head -s $sect -p ${KERNELSIZE}m -p ${EFISIZE}m -p ${EFIGRUBSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 0x$SIGNATURE}`
KERNELOFFSET="$(($1 / 512))"
KERNELSIZE="$2"
EFIOFFSET="$(($3 / 512))"
EFISIZE="$(($4 / 512))"
EFIGRUBOFFSET="$(($5 / 512))"
EFIGRUBSIZE="$(($6 / 512))"
ROOTFSOFFSET="$(($7 / 512))"
ROOTFSSIZE="$(($8 / 512))"
dd if=/dev/zero of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc count="$ROOTFSSIZE"
dd if="$ROOTFSIMAGE" of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc
dd if="$EFIIMAGE" of="$OUTPUT" bs=512 seek="$EFIOFFSET" conv=notrunc
[ -n "$NOGRUB" ] && exit 0
make_ext4fs -J -l "$KERNELSIZE" "$OUTPUT.kernel" "$KERNELDIR"
dd if="$OUTPUT.kernel" of="$OUTPUT" bs=512 seek="$KERNELOFFSET" conv=notrunc
rm -f "$OUTPUT.kernel"

View File

@ -0,0 +1,8 @@
define Device/generic
DEVICE_TITLE := Generic x86
DEVICE_PACKAGES += kmod-3c59x kmod-8139too kmod-e100 kmod-e1000 kmod-natsemi \
kmod-ne2k-pci kmod-pcnet32 kmod-r8169 kmod-sis900 kmod-tg3 \
kmod-via-rhine kmod-via-velocity kmod-forcedeth
GRUB2_VARIANT := generic
endef
TARGET_DEVICES += generic

View File

@ -0,0 +1,14 @@
define Device/generic
DEVICE_TITLE := Generic x86/Geode
DEVICE_PACKAGES += kmod-crypto-cbc kmod-crypto-hw-geode kmod-ledtrig-gpio
GRUB2_VARIANT := legacy
endef
TARGET_DEVICES += generic
define Device/geos
$(call Device/generic)
DEVICE_TITLE := Traverse Technologies Geos
DEVICE_PACKAGES += br2684ctl flashrom kmod-hwmon-lm90 kmod-mppe kmod-pppoa \
kmod-usb-ohci-pci linux-atm ppp-mod-pppoa pppdump pppstats soloscli tc
endef
TARGET_DEVICES += geos

View File

@ -0,0 +1,13 @@
@SERIAL_CONFIG@
@TERMINAL_CONFIG@
set default="0"
set timeout="@TIMEOUT@"
set root='(hd0,gpt1)'
menuentry "@TITLE@" {
linux /boot/vmlinuz @GPT_ROOTPART@ @CMDLINE@ noinitrd
}
menuentry "@TITLE@ (failsafe)" {
linux /boot/vmlinuz failsafe=true @GPT_ROOTPART@ @CMDLINE@ noinitrd
}

View File

@ -3,8 +3,13 @@
set default="0"
set timeout="@TIMEOUT@"
set root='(cd)'
if [ "${grub_platform}" = "efi" ]; then
set root='(cd0)'
else
set root='(cd)'
fi
menuentry "@TITLE@" {
linux /boot/vmlinuz @CMDLINE@ noinitrd
linux /boot/vmlinuz root=/dev/sr0 rootfstype=iso9660 rootwait @CMDLINE@ noinitrd
}

View File

@ -0,0 +1,13 @@
@SERIAL_CONFIG@
@TERMINAL_CONFIG@
set default="0"
set timeout="@TIMEOUT@"
set root='(hd0,msdos1)'
menuentry "@TITLE@" {
linux /boot/vmlinuz @ROOTPART@ @CMDLINE@ noinitrd
}
menuentry "@TITLE@ (failsafe)" {
linux /boot/vmlinuz failsafe=true @ROOTPART@ @CMDLINE@ noinitrd
}

View File

@ -1,13 +0,0 @@
@SERIAL_CONFIG@
@TERMINAL_CONFIG@
set default="0"
set timeout="@TIMEOUT@"
set root='(@ROOT@)'
menuentry "@TITLE@" {
linux /boot/vmlinuz @CMDLINE@ noinitrd
}
menuentry "@TITLE@ (failsafe)" {
linux /boot/vmlinuz failsafe=true @CMDLINE@ noinitrd
}

View File

@ -0,0 +1,8 @@
define Device/generic
DEVICE_TITLE := Generic x86/legacy
DEVICE_PACKAGES += kmod-3c59x kmod-8139too kmod-e100 kmod-e1000 \
kmod-natsemi kmod-ne2k-pci kmod-pcnet32 kmod-r8169 kmod-sis900 \
kmod-tg3 kmod-via-rhine kmod-via-velocity kmod-forcedeth
GRUB2_VARIANT := legacy
endef
TARGET_DEVICES += generic

View File

@ -0,0 +1,5 @@
define Device/generic
DEVICE_TITLE := Generic Zen Architecture
GRUB2_VARIANT := generic
endef
TARGET_DEVICES += generic

View File

@ -1,18 +0,0 @@
#
# Copyright (C) 2006-2009 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
define Profile/Generic
NAME:=Generic
PACKAGES:=kmod-3c59x kmod-e100 kmod-e1000 kmod-natsemi kmod-ne2k-pci \
kmod-pcnet32 kmod-8139too kmod-r8169 kmod-sis900 kmod-tg3 \
kmod-via-rhine kmod-via-velocity
endef
define Profile/Generic/Description
Generic Profile
endef
$(eval $(call Profile,Generic))

View File

@ -1,4 +1,4 @@
BOARDNAME:=Legacy x86 (i586)
BOARDNAME:=Legacy
define Target/Description
Build firmware images for legacy x86 based boards

View File

@ -1,15 +0,0 @@
#
# Copyright (C) 2006-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
define Profile/Generic
NAME:=Generic
endef
define Profile/Generic/Description
Generic Profile
endef
$(eval $(call Profile,Generic))

View File

@ -34,7 +34,6 @@ tools-$(CONFIG_TARGET_ath79) += lzma-old squashfs
tools-$(CONFIG_TARGET_mxs) += elftosb sdimage
tools-$(CONFIG_TARGET_orion_generic) += wrt350nv2-builder upslug2
tools-$(CONFIG_TARGET_tegra) += cbootimage cbootimage-configs
tools-$(CONFIG_TARGET_x86) += qemu
tools-$(CONFIG_USES_MINOR) += kernel2minor
tools-$(CONFIG_USE_SPARSE) += sparse
@ -68,7 +67,6 @@ $(curdir)/mpfr/compile := $(curdir)/gmp/compile
$(curdir)/mtd-utils/compile := $(curdir)/libtool/compile $(curdir)/e2fsprogs/compile $(curdir)/zlib/compile
$(curdir)/padjffs2/compile := $(curdir)/findutils/compile
$(curdir)/patchelf/compile := $(curdir)/libtool/compile
$(curdir)/qemu/compile := $(curdir)/e2fsprogs/compile $(curdir)/zlib/compile
$(curdir)/quilt/compile := $(curdir)/autoconf/compile $(curdir)/findutils/compile
$(curdir)/sdcc/compile := $(curdir)/bison/compile
$(curdir)/squashfs/compile := $(curdir)/lzma-old/compile

View File

@ -7,11 +7,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=bison
PKG_VERSION:=3.7.1
PKG_VERSION:=3.7.4
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
PKG_HASH:=55c215521a13982a9bee68cd42eed51a65713f96c530a739a57de4438ac1bb69
PKG_HASH:=a3b5813f48a11e540ef26f46e4d288c0c25c7907d9879ae50e430ec49f63c010
HOST_BUILD_PARALLEL:=1

View File

@ -1,6 +1,6 @@
--- a/lib/stdio.in.h
+++ b/lib/stdio.in.h
@@ -816,14 +816,6 @@ _GL_WARN_ON_USE (getline, "getline is un
@@ -835,14 +835,6 @@ _GL_WARN_ON_USE (getline, "getline is un
# endif
#endif
@ -12,6 +12,6 @@
-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
-#endif
-
#if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@
struct obstack;
/* Grow an obstack with formatted output. Return the number of
#if defined _WIN32 && !defined __CYGWIN__
# undef getw
# define getw _getw

View File

@ -9,10 +9,10 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=expat
PKG_CPE_ID:=cpe:/a:libexpat:expat
PKG_VERSION:=2.2.9
PKG_VERSION:=2.2.10
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_HASH:=f1063084dc4302a427dabcca499c8312b3a32a29b7d2506653ecc8f950a9a237
PKG_HASH:=b2c160f1b60e92da69de8e12333096aeb0c3bf692d41c60794de278af72135a5
PKG_SOURCE_URL:=https://github.com/libexpat/libexpat/releases/download/R_$(subst .,_,$(PKG_VERSION))
HOST_BUILD_PARALLEL:=1

View File

@ -7,11 +7,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gmp
PKG_VERSION:=6.2.0
PKG_VERSION:=6.2.1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNU/gmp/
PKG_HASH:=258e6cd51b3fbdfc185c716d55f82c08aff57df0c6fbd143cf6ed561267a1526
PKG_HASH:=fd4829912cddd12f84181c3451cc752be224643e87fac497b69edddadc49b4f2
HOST_FIXUP:=autoreconf

View File

@ -7,11 +7,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mpc
PKG_VERSION:=1.2.0
PKG_VERSION:=1.2.1
PKG_SOURCE_URL:=@GNU/mpc/
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_HASH:=e90f2d99553a9c19911abdb4305bf8217106a957e3994436428572c8dfe8fda6
PKG_HASH:=17503d2c395dfcf106b622dc142683c1199431d095367c6aacba6eec30340459
HOST_BUILD_PARALLEL:=1

View File

@ -1,45 +0,0 @@
#
# Copyright (C) 2010-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=qemu
PKG_CPE_ID:=cpe:/a:qemu:qemu
PKG_VERSION:=0.14.1
PKG_RELEASE:=1
PKG_SOURCE_URL:=@SAVANNAH/qemu
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_HASH:=33ceae3fbe516f2cbb151dc98d16c8ccfec74b1056674ad715e75a2f7fed45c3
include $(INCLUDE_DIR)/host-build.mk
HOST_CFLAGS += \
-I$(STAGING_DIR_HOST)/include/e2fsprogs \
-DAES_cbc_encrypt=QEMU_AES_cbc_encrypt \
-DAES_decrypt=QEMU_AES_decrypt \
-DAES_encrypt=QEMU_AES_encrypt \
-DAES_set_decrypt_key=QEMU_AES_set_decrypt_key \
-DAES_set_encrypt_key=QEMU_AES_set_encrypt_key
HOST_CONFIGURE_VARS := \
CFLAGS="$(HOST_CFLAGS)" \
LDFLAGS="$(HOST_LDFLAGS)"
HOST_CONFIGURE_ARGS := \
--extra-cflags="$(HOST_CFLAGS)" \
--enable-uuid
define Host/Compile
$(MAKE) -C $(HOST_BUILD_DIR) qemu-img
endef
define Host/Install
$(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
$(INSTALL_BIN) $(HOST_BUILD_DIR)/qemu-img $(STAGING_DIR_HOST)/bin
endef
$(eval $(call HostBuild))

View File

@ -1,75 +0,0 @@
From 6afca0fc5430db0300fe53f2b9cd7d071a3925bb Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Wed, 25 May 2011 00:46:55 +0200
Subject: [PATCH 01/12] vmdk: fix endianness bugs
The vmdk code is sloppy when handling the header descriptor during
creation of an image. Fix all header accesses in the create path to
either store native endianness or convert it when appropriate.
Reported-by: Yury Tsarev <ytsarev@novell.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -716,11 +716,11 @@ static int vmdk_create(const char *filen
return -errno;
magic = cpu_to_be32(VMDK4_MAGIC);
memset(&header, 0, sizeof(header));
- header.version = cpu_to_le32(1);
- header.flags = cpu_to_le32(3); /* ?? */
- header.capacity = cpu_to_le64(total_size);
- header.granularity = cpu_to_le64(128);
- header.num_gtes_per_gte = cpu_to_le32(512);
+ header.version = 1;
+ header.flags = 3; /* ?? */
+ header.capacity = total_size;
+ header.granularity = 128;
+ header.num_gtes_per_gte = 512;
grains = (total_size + header.granularity - 1) / header.granularity;
gt_size = ((header.num_gtes_per_gte * sizeof(uint32_t)) + 511) >> 9;
@@ -736,6 +736,12 @@ static int vmdk_create(const char *filen
header.granularity - 1) / header.granularity) *
header.granularity;
+ /* swap endianness for all header fields */
+ header.version = cpu_to_le32(header.version);
+ header.flags = cpu_to_le32(header.flags);
+ header.capacity = cpu_to_le64(header.capacity);
+ header.granularity = cpu_to_le64(header.granularity);
+ header.num_gtes_per_gte = cpu_to_le32(header.num_gtes_per_gte);
header.desc_offset = cpu_to_le64(header.desc_offset);
header.desc_size = cpu_to_le64(header.desc_size);
header.rgd_offset = cpu_to_le64(header.rgd_offset);
@@ -759,7 +765,7 @@ static int vmdk_create(const char *filen
goto exit;
}
- ret = ftruncate(fd, header.grain_offset << 9);
+ ret = ftruncate(fd, le64_to_cpu(header.grain_offset) << 9);
if (ret < 0) {
ret = -errno;
goto exit;
@@ -767,7 +773,7 @@ static int vmdk_create(const char *filen
/* write grain directory */
lseek(fd, le64_to_cpu(header.rgd_offset) << 9, SEEK_SET);
- for (i = 0, tmp = header.rgd_offset + gd_size;
+ for (i = 0, tmp = le64_to_cpu(header.rgd_offset) + gd_size;
i < gt_count; i++, tmp += gt_size) {
ret = qemu_write_full(fd, &tmp, sizeof(tmp));
if (ret != sizeof(tmp)) {
@@ -778,7 +784,7 @@ static int vmdk_create(const char *filen
/* write backup grain directory */
lseek(fd, le64_to_cpu(header.gd_offset) << 9, SEEK_SET);
- for (i = 0, tmp = header.gd_offset + gd_size;
+ for (i = 0, tmp = le64_to_cpu(header.gd_offset) + gd_size;
i < gt_count; i++, tmp += gt_size) {
ret = qemu_write_full(fd, &tmp, sizeof(tmp));
if (ret != sizeof(tmp)) {

View File

@ -1,557 +0,0 @@
From fcd9c52d160376184cbd25e04586aa6eef6abd61 Mon Sep 17 00:00:00 2001
From: Fam Zheng <famcool@gmail.com>
Date: Tue, 12 Jul 2011 19:56:28 +0800
Subject: [PATCH 02/12] VMDK: introduce VmdkExtent
Introduced VmdkExtent array into BDRVVmdkState, enable holding multiple
image extents for multiple file image support.
Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 348 +++++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 246 insertions(+), 102 deletions(-)
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -60,7 +60,11 @@ typedef struct {
#define L2_CACHE_SIZE 16
-typedef struct BDRVVmdkState {
+typedef struct VmdkExtent {
+ BlockDriverState *file;
+ bool flat;
+ int64_t sectors;
+ int64_t end_sector;
int64_t l1_table_offset;
int64_t l1_backup_table_offset;
uint32_t *l1_table;
@@ -74,7 +78,13 @@ typedef struct BDRVVmdkState {
uint32_t l2_cache_counts[L2_CACHE_SIZE];
unsigned int cluster_sectors;
+} VmdkExtent;
+
+typedef struct BDRVVmdkState {
uint32_t parent_cid;
+ int num_extents;
+ /* Extent array with num_extents entries, ascend ordered by address */
+ VmdkExtent *extents;
} BDRVVmdkState;
typedef struct VmdkMetaData {
@@ -105,6 +115,19 @@ static int vmdk_probe(const uint8_t *buf
#define DESC_SIZE 20*SECTOR_SIZE // 20 sectors of 512 bytes each
#define HEADER_SIZE 512 // first sector of 512 bytes
+static void vmdk_free_extents(BlockDriverState *bs)
+{
+ int i;
+ BDRVVmdkState *s = bs->opaque;
+
+ for (i = 0; i < s->num_extents; i++) {
+ qemu_free(s->extents[i].l1_table);
+ qemu_free(s->extents[i].l2_cache);
+ qemu_free(s->extents[i].l1_backup_table);
+ }
+ qemu_free(s->extents);
+}
+
static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
{
char desc[DESC_SIZE];
@@ -358,11 +381,50 @@ static int vmdk_parent_open(BlockDriverS
return 0;
}
+/* Create and append extent to the extent array. Return the added VmdkExtent
+ * address. return NULL if allocation failed. */
+static VmdkExtent *vmdk_add_extent(BlockDriverState *bs,
+ BlockDriverState *file, bool flat, int64_t sectors,
+ int64_t l1_offset, int64_t l1_backup_offset,
+ uint32_t l1_size,
+ int l2_size, unsigned int cluster_sectors)
+{
+ VmdkExtent *extent;
+ BDRVVmdkState *s = bs->opaque;
+
+ s->extents = qemu_realloc(s->extents,
+ (s->num_extents + 1) * sizeof(VmdkExtent));
+ extent = &s->extents[s->num_extents];
+ s->num_extents++;
+
+ memset(extent, 0, sizeof(VmdkExtent));
+ extent->file = file;
+ extent->flat = flat;
+ extent->sectors = sectors;
+ extent->l1_table_offset = l1_offset;
+ extent->l1_backup_table_offset = l1_backup_offset;
+ extent->l1_size = l1_size;
+ extent->l1_entry_sectors = l2_size * cluster_sectors;
+ extent->l2_size = l2_size;
+ extent->cluster_sectors = cluster_sectors;
+
+ if (s->num_extents > 1) {
+ extent->end_sector = (*(extent - 1)).end_sector + extent->sectors;
+ } else {
+ extent->end_sector = extent->sectors;
+ }
+ bs->total_sectors = extent->end_sector;
+ return extent;
+}
+
+
static int vmdk_open(BlockDriverState *bs, int flags)
{
BDRVVmdkState *s = bs->opaque;
uint32_t magic;
- int l1_size, i;
+ int i;
+ uint32_t l1_size, l1_entry_sectors;
+ VmdkExtent *extent = NULL;
if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic))
goto fail;
@@ -370,32 +432,34 @@ static int vmdk_open(BlockDriverState *b
magic = be32_to_cpu(magic);
if (magic == VMDK3_MAGIC) {
VMDK3Header header;
-
- if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)) != sizeof(header))
+ if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
+ != sizeof(header)) {
goto fail;
- s->cluster_sectors = le32_to_cpu(header.granularity);
- s->l2_size = 1 << 9;
- s->l1_size = 1 << 6;
- bs->total_sectors = le32_to_cpu(header.disk_sectors);
- s->l1_table_offset = le32_to_cpu(header.l1dir_offset) << 9;
- s->l1_backup_table_offset = 0;
- s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
+ }
+ extent = vmdk_add_extent(bs, bs->file, false,
+ le32_to_cpu(header.disk_sectors),
+ le32_to_cpu(header.l1dir_offset) << 9, 0,
+ 1 << 6, 1 << 9, le32_to_cpu(header.granularity));
} else if (magic == VMDK4_MAGIC) {
VMDK4Header header;
-
- if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)) != sizeof(header))
+ if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
+ != sizeof(header)) {
goto fail;
- bs->total_sectors = le64_to_cpu(header.capacity);
- s->cluster_sectors = le64_to_cpu(header.granularity);
- s->l2_size = le32_to_cpu(header.num_gtes_per_gte);
- s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
- if (s->l1_entry_sectors <= 0)
+ }
+ l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
+ * le64_to_cpu(header.granularity);
+ l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
+ / l1_entry_sectors;
+ extent = vmdk_add_extent(bs, bs->file, false,
+ le64_to_cpu(header.capacity),
+ le64_to_cpu(header.gd_offset) << 9,
+ le64_to_cpu(header.rgd_offset) << 9,
+ l1_size,
+ le32_to_cpu(header.num_gtes_per_gte),
+ le64_to_cpu(header.granularity));
+ if (extent->l1_entry_sectors <= 0) {
goto fail;
- s->l1_size = (bs->total_sectors + s->l1_entry_sectors - 1)
- / s->l1_entry_sectors;
- s->l1_table_offset = le64_to_cpu(header.rgd_offset) << 9;
- s->l1_backup_table_offset = le64_to_cpu(header.gd_offset) << 9;
-
+ }
// try to open parent images, if exist
if (vmdk_parent_open(bs) != 0)
goto fail;
@@ -406,40 +470,49 @@ static int vmdk_open(BlockDriverState *b
}
/* read the L1 table */
- l1_size = s->l1_size * sizeof(uint32_t);
- s->l1_table = qemu_malloc(l1_size);
- if (bdrv_pread(bs->file, s->l1_table_offset, s->l1_table, l1_size) != l1_size)
- goto fail;
- for(i = 0; i < s->l1_size; i++) {
- le32_to_cpus(&s->l1_table[i]);
- }
-
- if (s->l1_backup_table_offset) {
- s->l1_backup_table = qemu_malloc(l1_size);
- if (bdrv_pread(bs->file, s->l1_backup_table_offset, s->l1_backup_table, l1_size) != l1_size)
+ l1_size = extent->l1_size * sizeof(uint32_t);
+ extent->l1_table = qemu_malloc(l1_size);
+ if (bdrv_pread(bs->file,
+ extent->l1_table_offset,
+ extent->l1_table,
+ l1_size)
+ != l1_size) {
+ goto fail;
+ }
+ for (i = 0; i < extent->l1_size; i++) {
+ le32_to_cpus(&extent->l1_table[i]);
+ }
+
+ if (extent->l1_backup_table_offset) {
+ extent->l1_backup_table = qemu_malloc(l1_size);
+ if (bdrv_pread(bs->file,
+ extent->l1_backup_table_offset,
+ extent->l1_backup_table,
+ l1_size)
+ != l1_size) {
goto fail;
- for(i = 0; i < s->l1_size; i++) {
- le32_to_cpus(&s->l1_backup_table[i]);
+ }
+ for (i = 0; i < extent->l1_size; i++) {
+ le32_to_cpus(&extent->l1_backup_table[i]);
}
}
- s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
+ extent->l2_cache =
+ qemu_malloc(extent->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
return 0;
fail:
- qemu_free(s->l1_backup_table);
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
+ vmdk_free_extents(bs);
return -1;
}
-static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
- uint64_t offset, int allocate);
-
-static int get_whole_cluster(BlockDriverState *bs, uint64_t cluster_offset,
- uint64_t offset, int allocate)
+static int get_whole_cluster(BlockDriverState *bs,
+ VmdkExtent *extent,
+ uint64_t cluster_offset,
+ uint64_t offset,
+ bool allocate)
{
- BDRVVmdkState *s = bs->opaque;
- uint8_t whole_grain[s->cluster_sectors*512]; // 128 sectors * 512 bytes each = grain size 64KB
+ /* 128 sectors * 512 bytes each = grain size 64KB */
+ uint8_t whole_grain[extent->cluster_sectors * 512];
// we will be here if it's first write on non-exist grain(cluster).
// try to read from parent image, if exist
@@ -450,14 +523,14 @@ static int get_whole_cluster(BlockDriver
return -1;
ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain,
- s->cluster_sectors);
+ extent->cluster_sectors);
if (ret < 0) {
return -1;
}
//Write grain only into the active image
- ret = bdrv_write(bs->file, cluster_offset, whole_grain,
- s->cluster_sectors);
+ ret = bdrv_write(extent->file, cluster_offset, whole_grain,
+ extent->cluster_sectors);
if (ret < 0) {
return -1;
}
@@ -465,29 +538,39 @@ static int get_whole_cluster(BlockDriver
return 0;
}
-static int vmdk_L2update(BlockDriverState *bs, VmdkMetaData *m_data)
+static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data)
{
- BDRVVmdkState *s = bs->opaque;
-
/* update L2 table */
- if (bdrv_pwrite_sync(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
- &(m_data->offset), sizeof(m_data->offset)) < 0)
+ if (bdrv_pwrite_sync(
+ extent->file,
+ ((int64_t)m_data->l2_offset * 512)
+ + (m_data->l2_index * sizeof(m_data->offset)),
+ &(m_data->offset),
+ sizeof(m_data->offset)
+ ) < 0) {
return -1;
+ }
/* update backup L2 table */
- if (s->l1_backup_table_offset != 0) {
- m_data->l2_offset = s->l1_backup_table[m_data->l1_index];
- if (bdrv_pwrite_sync(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
- &(m_data->offset), sizeof(m_data->offset)) < 0)
+ if (extent->l1_backup_table_offset != 0) {
+ m_data->l2_offset = extent->l1_backup_table[m_data->l1_index];
+ if (bdrv_pwrite_sync(
+ extent->file,
+ ((int64_t)m_data->l2_offset * 512)
+ + (m_data->l2_index * sizeof(m_data->offset)),
+ &(m_data->offset), sizeof(m_data->offset)
+ ) < 0) {
return -1;
+ }
}
return 0;
}
-static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
- uint64_t offset, int allocate)
+static uint64_t get_cluster_offset(BlockDriverState *bs,
+ VmdkExtent *extent,
+ VmdkMetaData *m_data,
+ uint64_t offset, int allocate)
{
- BDRVVmdkState *s = bs->opaque;
unsigned int l1_index, l2_offset, l2_index;
int min_index, i, j;
uint32_t min_count, *l2_table, tmp = 0;
@@ -496,21 +579,23 @@ static uint64_t get_cluster_offset(Block
if (m_data)
m_data->valid = 0;
- l1_index = (offset >> 9) / s->l1_entry_sectors;
- if (l1_index >= s->l1_size)
+ l1_index = (offset >> 9) / extent->l1_entry_sectors;
+ if (l1_index >= extent->l1_size) {
return 0;
- l2_offset = s->l1_table[l1_index];
- if (!l2_offset)
+ }
+ l2_offset = extent->l1_table[l1_index];
+ if (!l2_offset) {
return 0;
+ }
for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (l2_offset == s->l2_cache_offsets[i]) {
+ if (l2_offset == extent->l2_cache_offsets[i]) {
/* increment the hit count */
- if (++s->l2_cache_counts[i] == 0xffffffff) {
+ if (++extent->l2_cache_counts[i] == 0xffffffff) {
for(j = 0; j < L2_CACHE_SIZE; j++) {
- s->l2_cache_counts[j] >>= 1;
+ extent->l2_cache_counts[j] >>= 1;
}
}
- l2_table = s->l2_cache + (i * s->l2_size);
+ l2_table = extent->l2_cache + (i * extent->l2_size);
goto found;
}
}
@@ -518,20 +603,25 @@ static uint64_t get_cluster_offset(Block
min_index = 0;
min_count = 0xffffffff;
for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (s->l2_cache_counts[i] < min_count) {
- min_count = s->l2_cache_counts[i];
+ if (extent->l2_cache_counts[i] < min_count) {
+ min_count = extent->l2_cache_counts[i];
min_index = i;
}
}
- l2_table = s->l2_cache + (min_index * s->l2_size);
- if (bdrv_pread(bs->file, (int64_t)l2_offset * 512, l2_table, s->l2_size * sizeof(uint32_t)) !=
- s->l2_size * sizeof(uint32_t))
+ l2_table = extent->l2_cache + (min_index * extent->l2_size);
+ if (bdrv_pread(
+ extent->file,
+ (int64_t)l2_offset * 512,
+ l2_table,
+ extent->l2_size * sizeof(uint32_t)
+ ) != extent->l2_size * sizeof(uint32_t)) {
return 0;
+ }
- s->l2_cache_offsets[min_index] = l2_offset;
- s->l2_cache_counts[min_index] = 1;
+ extent->l2_cache_offsets[min_index] = l2_offset;
+ extent->l2_cache_counts[min_index] = 1;
found:
- l2_index = ((offset >> 9) / s->cluster_sectors) % s->l2_size;
+ l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;
cluster_offset = le32_to_cpu(l2_table[l2_index]);
if (!cluster_offset) {
@@ -539,8 +629,11 @@ static uint64_t get_cluster_offset(Block
return 0;
// Avoid the L2 tables update for the images that have snapshots.
- cluster_offset = bdrv_getlength(bs->file);
- bdrv_truncate(bs->file, cluster_offset + (s->cluster_sectors << 9));
+ cluster_offset = bdrv_getlength(extent->file);
+ bdrv_truncate(
+ extent->file,
+ cluster_offset + (extent->cluster_sectors << 9)
+ );
cluster_offset >>= 9;
tmp = cpu_to_le32(cluster_offset);
@@ -551,7 +644,8 @@ static uint64_t get_cluster_offset(Block
* This problem may occur because of insufficient space on host disk
* or inappropriate VM shutdown.
*/
- if (get_whole_cluster(bs, cluster_offset, offset, allocate) == -1)
+ if (get_whole_cluster(
+ bs, extent, cluster_offset, offset, allocate) == -1)
return 0;
if (m_data) {
@@ -566,33 +660,69 @@ static uint64_t get_cluster_offset(Block
return cluster_offset;
}
+static VmdkExtent *find_extent(BDRVVmdkState *s,
+ int64_t sector_num, VmdkExtent *start_hint)
+{
+ VmdkExtent *extent = start_hint;
+
+ if (!extent) {
+ extent = &s->extents[0];
+ }
+ while (extent < &s->extents[s->num_extents]) {
+ if (sector_num < extent->end_sector) {
+ return extent;
+ }
+ extent++;
+ }
+ return NULL;
+}
+
static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, int *pnum)
{
BDRVVmdkState *s = bs->opaque;
- int index_in_cluster, n;
- uint64_t cluster_offset;
- cluster_offset = get_cluster_offset(bs, NULL, sector_num << 9, 0);
- index_in_cluster = sector_num % s->cluster_sectors;
- n = s->cluster_sectors - index_in_cluster;
+ int64_t index_in_cluster, n, ret;
+ uint64_t offset;
+ VmdkExtent *extent;
+
+ extent = find_extent(s, sector_num, NULL);
+ if (!extent) {
+ return 0;
+ }
+ if (extent->flat) {
+ n = extent->end_sector - sector_num;
+ ret = 1;
+ } else {
+ offset = get_cluster_offset(bs, extent, NULL, sector_num * 512, 0);
+ index_in_cluster = sector_num % extent->cluster_sectors;
+ n = extent->cluster_sectors - index_in_cluster;
+ ret = offset ? 1 : 0;
+ }
if (n > nb_sectors)
n = nb_sectors;
*pnum = n;
- return (cluster_offset != 0);
+ return ret;
}
static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
BDRVVmdkState *s = bs->opaque;
- int index_in_cluster, n, ret;
+ int ret;
+ uint64_t n, index_in_cluster;
+ VmdkExtent *extent = NULL;
uint64_t cluster_offset;
while (nb_sectors > 0) {
- cluster_offset = get_cluster_offset(bs, NULL, sector_num << 9, 0);
- index_in_cluster = sector_num % s->cluster_sectors;
- n = s->cluster_sectors - index_in_cluster;
+ extent = find_extent(s, sector_num, extent);
+ if (!extent) {
+ return -EIO;
+ }
+ cluster_offset = get_cluster_offset(
+ bs, extent, NULL, sector_num << 9, 0);
+ index_in_cluster = sector_num % extent->cluster_sectors;
+ n = extent->cluster_sectors - index_in_cluster;
if (n > nb_sectors)
n = nb_sectors;
if (!cluster_offset) {
@@ -621,10 +751,12 @@ static int vmdk_write(BlockDriverState *
const uint8_t *buf, int nb_sectors)
{
BDRVVmdkState *s = bs->opaque;
- VmdkMetaData m_data;
- int index_in_cluster, n;
+ VmdkExtent *extent = NULL;
+ int n;
+ int64_t index_in_cluster;
uint64_t cluster_offset;
static int cid_update = 0;
+ VmdkMetaData m_data;
if (sector_num > bs->total_sectors) {
fprintf(stderr,
@@ -635,20 +767,35 @@ static int vmdk_write(BlockDriverState *
}
while (nb_sectors > 0) {
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors)
- n = nb_sectors;
- cluster_offset = get_cluster_offset(bs, &m_data, sector_num << 9, 1);
- if (!cluster_offset)
+ extent = find_extent(s, sector_num, extent);
+ if (!extent) {
+ return -EIO;
+ }
+ cluster_offset = get_cluster_offset(
+ bs,
+ extent,
+ &m_data,
+ sector_num << 9, 1);
+ if (!cluster_offset) {
return -1;
+ }
+ index_in_cluster = sector_num % extent->cluster_sectors;
+ n = extent->cluster_sectors - index_in_cluster;
+ if (n > nb_sectors) {
+ n = nb_sectors;
+ }
- if (bdrv_pwrite(bs->file, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512)
+ if (bdrv_pwrite(bs->file,
+ cluster_offset + index_in_cluster * 512,
+ buf, n * 512)
+ != n * 512) {
return -1;
+ }
if (m_data.valid) {
/* update L2 tables */
- if (vmdk_L2update(bs, &m_data) == -1)
+ if (vmdk_L2update(extent, &m_data) == -1) {
return -1;
+ }
}
nb_sectors -= n;
sector_num += n;
@@ -822,10 +969,7 @@ exit:
static void vmdk_close(BlockDriverState *bs)
{
- BDRVVmdkState *s = bs->opaque;
-
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
+ vmdk_free_extents(bs);
}
static int vmdk_flush(BlockDriverState *bs)

View File

@ -1,46 +0,0 @@
From 66922efc83a670178b208dec2f5123ec85fb6ba3 Mon Sep 17 00:00:00 2001
From: Fam Zheng <famcool@gmail.com>
Date: Tue, 12 Jul 2011 19:56:29 +0800
Subject: [PATCH 03/12] VMDK: bugfix, align offset to cluster in
get_whole_cluster
In get_whole_cluster, the offset is not aligned to cluster when reading
from backing_hd. When the first write to child is not at the cluster
boundary, wrong address data from parent is copied to child.
Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -514,21 +514,23 @@ static int get_whole_cluster(BlockDriver
/* 128 sectors * 512 bytes each = grain size 64KB */
uint8_t whole_grain[extent->cluster_sectors * 512];
- // we will be here if it's first write on non-exist grain(cluster).
- // try to read from parent image, if exist
+ /* we will be here if it's first write on non-exist grain(cluster).
+ * try to read from parent image, if exist */
if (bs->backing_hd) {
int ret;
if (!vmdk_is_cid_valid(bs))
return -1;
+ /* floor offset to cluster */
+ offset -= offset % (extent->cluster_sectors * 512);
ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain,
extent->cluster_sectors);
if (ret < 0) {
return -1;
}
- //Write grain only into the active image
+ /* Write grain only into the active image */
ret = bdrv_write(extent->file, cluster_offset, whole_grain,
extent->cluster_sectors);
if (ret < 0) {

View File

@ -1,74 +0,0 @@
From 930e57ecb64bbab75c2b71d0d1ba07451fec4567 Mon Sep 17 00:00:00 2001
From: Fam Zheng <famcool@gmail.com>
Date: Tue, 12 Jul 2011 19:56:30 +0800
Subject: [PATCH 04/12] VMDK: probe for monolithicFlat images
Probe as the same behavior as VMware does.
Recognize image as monolithicFlat descriptor file when the file is text
and the first effective line (not '#' leaded comment or space line) is
either 'version=1' or 'version=2'. No space or upper case charactors
accepted.
Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 45 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 43 insertions(+), 2 deletions(-)
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -103,10 +103,51 @@ static int vmdk_probe(const uint8_t *buf
return 0;
magic = be32_to_cpu(*(uint32_t *)buf);
if (magic == VMDK3_MAGIC ||
- magic == VMDK4_MAGIC)
+ magic == VMDK4_MAGIC) {
return 100;
- else
+ } else {
+ const char *p = (const char *)buf;
+ const char *end = p + buf_size;
+ while (p < end) {
+ if (*p == '#') {
+ /* skip comment line */
+ while (p < end && *p != '\n') {
+ p++;
+ }
+ p++;
+ continue;
+ }
+ if (*p == ' ') {
+ while (p < end && *p == ' ') {
+ p++;
+ }
+ /* skip '\r' if windows line endings used. */
+ if (p < end && *p == '\r') {
+ p++;
+ }
+ /* only accept blank lines before 'version=' line */
+ if (p == end || *p != '\n') {
+ return 0;
+ }
+ p++;
+ continue;
+ }
+ if (end - p >= strlen("version=X\n")) {
+ if (strncmp("version=1\n", p, strlen("version=1\n")) == 0 ||
+ strncmp("version=2\n", p, strlen("version=2\n")) == 0) {
+ return 100;
+ }
+ }
+ if (end - p >= strlen("version=X\r\n")) {
+ if (strncmp("version=1\r\n", p, strlen("version=1\r\n")) == 0 ||
+ strncmp("version=2\r\n", p, strlen("version=2\r\n")) == 0) {
+ return 100;
+ }
+ }
+ return 0;
+ }
return 0;
+ }
}
#define CHECK_CID 1

View File

@ -1,241 +0,0 @@
From 97cf5df76657bab81d6b8669607f6f13215201c1 Mon Sep 17 00:00:00 2001
From: Fam Zheng <famcool@gmail.com>
Date: Tue, 12 Jul 2011 19:56:31 +0800
Subject: [PATCH 05/12] VMDK: separate vmdk_open by format version
Separate vmdk_open by subformats to:
* vmdk_open_vmdk3
* vmdk_open_vmdk4
Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 178 +++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 112 insertions(+), 66 deletions(-)
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -458,67 +458,20 @@ static VmdkExtent *vmdk_add_extent(Block
return extent;
}
-
-static int vmdk_open(BlockDriverState *bs, int flags)
+static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
{
- BDRVVmdkState *s = bs->opaque;
- uint32_t magic;
- int i;
- uint32_t l1_size, l1_entry_sectors;
- VmdkExtent *extent = NULL;
-
- if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic))
- goto fail;
-
- magic = be32_to_cpu(magic);
- if (magic == VMDK3_MAGIC) {
- VMDK3Header header;
- if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
- != sizeof(header)) {
- goto fail;
- }
- extent = vmdk_add_extent(bs, bs->file, false,
- le32_to_cpu(header.disk_sectors),
- le32_to_cpu(header.l1dir_offset) << 9, 0,
- 1 << 6, 1 << 9, le32_to_cpu(header.granularity));
- } else if (magic == VMDK4_MAGIC) {
- VMDK4Header header;
- if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
- != sizeof(header)) {
- goto fail;
- }
- l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
- * le64_to_cpu(header.granularity);
- l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
- / l1_entry_sectors;
- extent = vmdk_add_extent(bs, bs->file, false,
- le64_to_cpu(header.capacity),
- le64_to_cpu(header.gd_offset) << 9,
- le64_to_cpu(header.rgd_offset) << 9,
- l1_size,
- le32_to_cpu(header.num_gtes_per_gte),
- le64_to_cpu(header.granularity));
- if (extent->l1_entry_sectors <= 0) {
- goto fail;
- }
- // try to open parent images, if exist
- if (vmdk_parent_open(bs) != 0)
- goto fail;
- // write the CID once after the image creation
- s->parent_cid = vmdk_read_cid(bs,1);
- } else {
- goto fail;
- }
+ int ret;
+ int l1_size, i;
/* read the L1 table */
l1_size = extent->l1_size * sizeof(uint32_t);
extent->l1_table = qemu_malloc(l1_size);
- if (bdrv_pread(bs->file,
- extent->l1_table_offset,
- extent->l1_table,
- l1_size)
- != l1_size) {
- goto fail;
+ ret = bdrv_pread(extent->file,
+ extent->l1_table_offset,
+ extent->l1_table,
+ l1_size);
+ if (ret < 0) {
+ goto fail_l1;
}
for (i = 0; i < extent->l1_size; i++) {
le32_to_cpus(&extent->l1_table[i]);
@@ -526,12 +479,12 @@ static int vmdk_open(BlockDriverState *b
if (extent->l1_backup_table_offset) {
extent->l1_backup_table = qemu_malloc(l1_size);
- if (bdrv_pread(bs->file,
- extent->l1_backup_table_offset,
- extent->l1_backup_table,
- l1_size)
- != l1_size) {
- goto fail;
+ ret = bdrv_pread(extent->file,
+ extent->l1_backup_table_offset,
+ extent->l1_backup_table,
+ l1_size);
+ if (ret < 0) {
+ goto fail_l1b;
}
for (i = 0; i < extent->l1_size; i++) {
le32_to_cpus(&extent->l1_backup_table[i]);
@@ -541,9 +494,102 @@ static int vmdk_open(BlockDriverState *b
extent->l2_cache =
qemu_malloc(extent->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
return 0;
+ fail_l1b:
+ qemu_free(extent->l1_backup_table);
+ fail_l1:
+ qemu_free(extent->l1_table);
+ return ret;
+}
+
+static int vmdk_open_vmdk3(BlockDriverState *bs, int flags)
+{
+ int ret;
+ uint32_t magic;
+ VMDK3Header header;
+ VmdkExtent *extent;
+
+ ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
+ if (ret < 0) {
+ goto fail;
+ }
+ extent = vmdk_add_extent(bs,
+ bs->file, false,
+ le32_to_cpu(header.disk_sectors),
+ le32_to_cpu(header.l1dir_offset) << 9,
+ 0, 1 << 6, 1 << 9,
+ le32_to_cpu(header.granularity));
+ ret = vmdk_init_tables(bs, extent);
+ if (ret) {
+ /* vmdk_init_tables cleans up on fail, so only free allocation of
+ * vmdk_add_extent here. */
+ goto fail;
+ }
+ return 0;
fail:
vmdk_free_extents(bs);
- return -1;
+ return ret;
+}
+
+static int vmdk_open_vmdk4(BlockDriverState *bs, int flags)
+{
+ int ret;
+ uint32_t magic;
+ uint32_t l1_size, l1_entry_sectors;
+ VMDK4Header header;
+ BDRVVmdkState *s = bs->opaque;
+ VmdkExtent *extent;
+
+ ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
+ if (ret < 0) {
+ goto fail;
+ }
+ l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
+ * le64_to_cpu(header.granularity);
+ l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
+ / l1_entry_sectors;
+ extent = vmdk_add_extent(bs, bs->file, false,
+ le64_to_cpu(header.capacity),
+ le64_to_cpu(header.gd_offset) << 9,
+ le64_to_cpu(header.rgd_offset) << 9,
+ l1_size,
+ le32_to_cpu(header.num_gtes_per_gte),
+ le64_to_cpu(header.granularity));
+ if (extent->l1_entry_sectors <= 0) {
+ ret = -EINVAL;
+ goto fail;
+ }
+ /* try to open parent images, if exist */
+ ret = vmdk_parent_open(bs);
+ if (ret) {
+ goto fail;
+ }
+ s->parent_cid = vmdk_read_cid(bs, 1);
+ ret = vmdk_init_tables(bs, extent);
+ if (ret) {
+ goto fail;
+ }
+ return 0;
+ fail:
+ vmdk_free_extents(bs);
+ return ret;
+}
+
+static int vmdk_open(BlockDriverState *bs, int flags)
+{
+ uint32_t magic;
+
+ if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic)) {
+ return -EIO;
+ }
+
+ magic = be32_to_cpu(magic);
+ if (magic == VMDK3_MAGIC) {
+ return vmdk_open_vmdk3(bs, flags);
+ } else if (magic == VMDK4_MAGIC) {
+ return vmdk_open_vmdk4(bs, flags);
+ } else {
+ return -EINVAL;
+ }
}
static int get_whole_cluster(BlockDriverState *bs,
@@ -630,11 +676,11 @@ static uint64_t get_cluster_offset(Block
if (!l2_offset) {
return 0;
}
- for(i = 0; i < L2_CACHE_SIZE; i++) {
+ for (i = 0; i < L2_CACHE_SIZE; i++) {
if (l2_offset == extent->l2_cache_offsets[i]) {
/* increment the hit count */
if (++extent->l2_cache_counts[i] == 0xffffffff) {
- for(j = 0; j < L2_CACHE_SIZE; j++) {
+ for (j = 0; j < L2_CACHE_SIZE; j++) {
extent->l2_cache_counts[j] >>= 1;
}
}
@@ -645,7 +691,7 @@ static uint64_t get_cluster_offset(Block
/* not found: load a new entry in the least used one */
min_index = 0;
min_count = 0xffffffff;
- for(i = 0; i < L2_CACHE_SIZE; i++) {
+ for (i = 0; i < L2_CACHE_SIZE; i++) {
if (extent->l2_cache_counts[i] < min_count) {
min_count = extent->l2_cache_counts[i];
min_index = i;

View File

@ -1,102 +0,0 @@
From 1c1781fa1c45a7c012f7b2c4be1be372f19e3cc6 Mon Sep 17 00:00:00 2001
From: Fam Zheng <famcool@gmail.com>
Date: Tue, 12 Jul 2011 19:56:32 +0800
Subject: [PATCH 06/12] VMDK: add field BDRVVmdkState.desc_offset
There are several occurrence of magic number 0x200 as the descriptor
offset within mono sparse image file. This is not the case for images
with separate descriptor file. So a field is added to BDRVVmdkState to
hold the correct value.
Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 27 ++++++++++++++++++---------
1 file changed, 18 insertions(+), 9 deletions(-)
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -81,6 +81,7 @@ typedef struct VmdkExtent {
} VmdkExtent;
typedef struct BDRVVmdkState {
+ int desc_offset;
uint32_t parent_cid;
int num_extents;
/* Extent array with num_extents entries, ascend ordered by address */
@@ -175,10 +176,11 @@ static uint32_t vmdk_read_cid(BlockDrive
uint32_t cid;
const char *p_name, *cid_str;
size_t cid_str_size;
+ BDRVVmdkState *s = bs->opaque;
- /* the descriptor offset = 0x200 */
- if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE)
+ if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
return 0;
+ }
if (parent) {
cid_str = "parentCID";
@@ -200,10 +202,12 @@ static int vmdk_write_cid(BlockDriverSta
{
char desc[DESC_SIZE], tmp_desc[DESC_SIZE];
char *p_name, *tmp_str;
+ BDRVVmdkState *s = bs->opaque;
- /* the descriptor offset = 0x200 */
- if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE)
- return -1;
+ memset(desc, 0, sizeof(desc));
+ if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
+ return -EIO;
+ }
tmp_str = strstr(desc,"parentCID");
pstrcpy(tmp_desc, sizeof(tmp_desc), tmp_str);
@@ -213,8 +217,9 @@ static int vmdk_write_cid(BlockDriverSta
pstrcat(desc, sizeof(desc), tmp_desc);
}
- if (bdrv_pwrite_sync(bs->file, 0x200, desc, DESC_SIZE) < 0)
- return -1;
+ if (bdrv_pwrite_sync(bs->file, s->desc_offset, desc, DESC_SIZE) < 0) {
+ return -EIO;
+ }
return 0;
}
@@ -402,10 +407,11 @@ static int vmdk_parent_open(BlockDriverS
{
char *p_name;
char desc[DESC_SIZE];
+ BDRVVmdkState *s = bs->opaque;
- /* the descriptor offset = 0x200 */
- if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE)
+ if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
return -1;
+ }
if ((p_name = strstr(desc,"parentFileNameHint")) != NULL) {
char *end_name;
@@ -506,8 +512,10 @@ static int vmdk_open_vmdk3(BlockDriverSt
int ret;
uint32_t magic;
VMDK3Header header;
+ BDRVVmdkState *s = bs->opaque;
VmdkExtent *extent;
+ s->desc_offset = 0x200;
ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
if (ret < 0) {
goto fail;
@@ -539,6 +547,7 @@ static int vmdk_open_vmdk4(BlockDriverSt
BDRVVmdkState *s = bs->opaque;
VmdkExtent *extent;
+ s->desc_offset = 0x200;
ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
if (ret < 0) {
goto fail;

View File

@ -1,35 +0,0 @@
From 49885608e66c1e76a2b715fb36fd2f27f73e5202 Mon Sep 17 00:00:00 2001
From: Fam Zheng <famcool@gmail.com>
Date: Tue, 12 Jul 2011 19:56:33 +0800
Subject: [PATCH 07/12] VMDK: flush multiple extents
Flush all the file that referenced by the image.
Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1072,7 +1072,17 @@ static void vmdk_close(BlockDriverState
static int vmdk_flush(BlockDriverState *bs)
{
- return bdrv_flush(bs->file);
+ int i, ret, err;
+ BDRVVmdkState *s = bs->opaque;
+
+ ret = bdrv_flush(bs->file);
+ for (i = 0; i < s->num_extents; i++) {
+ err = bdrv_flush(s->extents[i].file);
+ if (err < 0) {
+ ret = err;
+ }
+ }
+ return ret;
}

View File

@ -1,46 +0,0 @@
From 9d8117f00364c12cbd658de903b1ed26a30584e0 Mon Sep 17 00:00:00 2001
From: Fam Zheng <famcool@gmail.com>
Date: Tue, 12 Jul 2011 19:56:34 +0800
Subject: [PATCH 08/12] VMDK: move 'static' cid_update flag to bs field
Cid_update is the flag for updating CID on first write after opening the
image. This should be per image open rather than per program life cycle,
so change it from static var of vmdk_write to a field in BDRVVmdkState.
Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -82,6 +82,7 @@ typedef struct VmdkExtent {
typedef struct BDRVVmdkState {
int desc_offset;
+ bool cid_updated;
uint32_t parent_cid;
int num_extents;
/* Extent array with num_extents entries, ascend ordered by address */
@@ -853,7 +854,6 @@ static int vmdk_write(BlockDriverState *
int n;
int64_t index_in_cluster;
uint64_t cluster_offset;
- static int cid_update = 0;
VmdkMetaData m_data;
if (sector_num > bs->total_sectors) {
@@ -900,9 +900,9 @@ static int vmdk_write(BlockDriverState *
buf += n * 512;
// update CID on the first write every time the virtual disk is opened
- if (!cid_update) {
+ if (!s->cid_updated) {
vmdk_write_cid(bs, time(NULL));
- cid_update++;
+ s->cid_updated = true;
}
}
return 0;

View File

@ -1,198 +0,0 @@
From 9e1ddc6967e8739f4fa47fa4f6a767ebe319f6ff Mon Sep 17 00:00:00 2001
From: Fam Zheng <famcool@gmail.com>
Date: Tue, 12 Jul 2011 19:56:35 +0800
Subject: [PATCH 09/12] VMDK: change get_cluster_offset return type
The return type of get_cluster_offset was an offset that use 0 to denote
'not allocated', this will be no longer true for flat extents, as we see
flat extent file as a single huge cluster whose offset is 0 and length
is the whole file length.
So now we use int return value, 0 means success and otherwise offset
invalid.
Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 79 ++++++++++++++++++++++++++++++++----------------------------
1 file changed, 42 insertions(+), 37 deletions(-)
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -665,26 +665,31 @@ static int vmdk_L2update(VmdkExtent *ext
return 0;
}
-static uint64_t get_cluster_offset(BlockDriverState *bs,
+static int get_cluster_offset(BlockDriverState *bs,
VmdkExtent *extent,
VmdkMetaData *m_data,
- uint64_t offset, int allocate)
+ uint64_t offset,
+ int allocate,
+ uint64_t *cluster_offset)
{
unsigned int l1_index, l2_offset, l2_index;
int min_index, i, j;
uint32_t min_count, *l2_table, tmp = 0;
- uint64_t cluster_offset;
if (m_data)
m_data->valid = 0;
+ if (extent->flat) {
+ *cluster_offset = 0;
+ return 0;
+ }
l1_index = (offset >> 9) / extent->l1_entry_sectors;
if (l1_index >= extent->l1_size) {
- return 0;
+ return -1;
}
l2_offset = extent->l1_table[l1_index];
if (!l2_offset) {
- return 0;
+ return -1;
}
for (i = 0; i < L2_CACHE_SIZE; i++) {
if (l2_offset == extent->l2_cache_offsets[i]) {
@@ -714,28 +719,29 @@ static uint64_t get_cluster_offset(Block
l2_table,
extent->l2_size * sizeof(uint32_t)
) != extent->l2_size * sizeof(uint32_t)) {
- return 0;
+ return -1;
}
extent->l2_cache_offsets[min_index] = l2_offset;
extent->l2_cache_counts[min_index] = 1;
found:
l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;
- cluster_offset = le32_to_cpu(l2_table[l2_index]);
+ *cluster_offset = le32_to_cpu(l2_table[l2_index]);
- if (!cluster_offset) {
- if (!allocate)
- return 0;
+ if (!*cluster_offset) {
+ if (!allocate) {
+ return -1;
+ }
// Avoid the L2 tables update for the images that have snapshots.
- cluster_offset = bdrv_getlength(extent->file);
+ *cluster_offset = bdrv_getlength(extent->file);
bdrv_truncate(
extent->file,
- cluster_offset + (extent->cluster_sectors << 9)
+ *cluster_offset + (extent->cluster_sectors << 9)
);
- cluster_offset >>= 9;
- tmp = cpu_to_le32(cluster_offset);
+ *cluster_offset >>= 9;
+ tmp = cpu_to_le32(*cluster_offset);
l2_table[l2_index] = tmp;
/* First of all we write grain itself, to avoid race condition
@@ -744,8 +750,8 @@ static uint64_t get_cluster_offset(Block
* or inappropriate VM shutdown.
*/
if (get_whole_cluster(
- bs, extent, cluster_offset, offset, allocate) == -1)
- return 0;
+ bs, extent, *cluster_offset, offset, allocate) == -1)
+ return -1;
if (m_data) {
m_data->offset = tmp;
@@ -755,8 +761,8 @@ static uint64_t get_cluster_offset(Block
m_data->valid = 1;
}
}
- cluster_offset <<= 9;
- return cluster_offset;
+ *cluster_offset <<= 9;
+ return 0;
}
static VmdkExtent *find_extent(BDRVVmdkState *s,
@@ -780,7 +786,6 @@ static int vmdk_is_allocated(BlockDriver
int nb_sectors, int *pnum)
{
BDRVVmdkState *s = bs->opaque;
-
int64_t index_in_cluster, n, ret;
uint64_t offset;
VmdkExtent *extent;
@@ -789,15 +794,13 @@ static int vmdk_is_allocated(BlockDriver
if (!extent) {
return 0;
}
- if (extent->flat) {
- n = extent->end_sector - sector_num;
- ret = 1;
- } else {
- offset = get_cluster_offset(bs, extent, NULL, sector_num * 512, 0);
- index_in_cluster = sector_num % extent->cluster_sectors;
- n = extent->cluster_sectors - index_in_cluster;
- ret = offset ? 1 : 0;
- }
+ ret = get_cluster_offset(bs, extent, NULL,
+ sector_num * 512, 0, &offset);
+ /* get_cluster_offset returning 0 means success */
+ ret = !ret;
+
+ index_in_cluster = sector_num % extent->cluster_sectors;
+ n = extent->cluster_sectors - index_in_cluster;
if (n > nb_sectors)
n = nb_sectors;
*pnum = n;
@@ -818,14 +821,15 @@ static int vmdk_read(BlockDriverState *b
if (!extent) {
return -EIO;
}
- cluster_offset = get_cluster_offset(
- bs, extent, NULL, sector_num << 9, 0);
+ ret = get_cluster_offset(
+ bs, extent, NULL,
+ sector_num << 9, 0, &cluster_offset);
index_in_cluster = sector_num % extent->cluster_sectors;
n = extent->cluster_sectors - index_in_cluster;
if (n > nb_sectors)
n = nb_sectors;
- if (!cluster_offset) {
- // try to read from parent image, if exist
+ if (ret) {
+ /* if not allocated, try to read from parent image, if exist */
if (bs->backing_hd) {
if (!vmdk_is_cid_valid(bs))
return -1;
@@ -851,7 +855,7 @@ static int vmdk_write(BlockDriverState *
{
BDRVVmdkState *s = bs->opaque;
VmdkExtent *extent = NULL;
- int n;
+ int n, ret;
int64_t index_in_cluster;
uint64_t cluster_offset;
VmdkMetaData m_data;
@@ -869,13 +873,14 @@ static int vmdk_write(BlockDriverState *
if (!extent) {
return -EIO;
}
- cluster_offset = get_cluster_offset(
+ ret = get_cluster_offset(
bs,
extent,
&m_data,
- sector_num << 9, 1);
- if (!cluster_offset) {
- return -1;
+ sector_num << 9, 1,
+ &cluster_offset);
+ if (ret) {
+ return -EINVAL;
}
index_in_cluster = sector_num % extent->cluster_sectors;
n = extent->cluster_sectors - index_in_cluster;

View File

@ -1,257 +0,0 @@
From e6b783a12f7ff491a1a2147d9fe55b4535aa046e Mon Sep 17 00:00:00 2001
From: Fam Zheng <famcool@gmail.com>
Date: Tue, 19 Jul 2011 08:38:22 +0800
Subject: [PATCH 10/12] VMDK: open/read/write for monolithicFlat image
Parse vmdk decriptor file and open mono flat image.
Read/write the flat extent.
Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 158 insertions(+), 13 deletions(-)
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -65,6 +65,7 @@ typedef struct VmdkExtent {
bool flat;
int64_t sectors;
int64_t end_sector;
+ int64_t flat_start_offset;
int64_t l1_table_offset;
int64_t l1_backup_table_offset;
uint32_t *l1_table;
@@ -407,9 +408,10 @@ fail:
static int vmdk_parent_open(BlockDriverState *bs)
{
char *p_name;
- char desc[DESC_SIZE];
+ char desc[DESC_SIZE + 1];
BDRVVmdkState *s = bs->opaque;
+ desc[DESC_SIZE] = '\0';
if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
return -1;
}
@@ -584,6 +586,144 @@ static int vmdk_open_vmdk4(BlockDriverSt
return ret;
}
+/* find an option value out of descriptor file */
+static int vmdk_parse_description(const char *desc, const char *opt_name,
+ char *buf, int buf_size)
+{
+ char *opt_pos, *opt_end;
+ const char *end = desc + strlen(desc);
+
+ opt_pos = strstr(desc, opt_name);
+ if (!opt_pos) {
+ return -1;
+ }
+ /* Skip "=\"" following opt_name */
+ opt_pos += strlen(opt_name) + 2;
+ if (opt_pos >= end) {
+ return -1;
+ }
+ opt_end = opt_pos;
+ while (opt_end < end && *opt_end != '"') {
+ opt_end++;
+ }
+ if (opt_end == end || buf_size < opt_end - opt_pos + 1) {
+ return -1;
+ }
+ pstrcpy(buf, opt_end - opt_pos + 1, opt_pos);
+ return 0;
+}
+
+static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
+ const char *desc_file_path)
+{
+ int ret;
+ char access[11];
+ char type[11];
+ char fname[512];
+ const char *p = desc;
+ int64_t sectors = 0;
+ int64_t flat_offset;
+
+ while (*p) {
+ /* parse extent line:
+ * RW [size in sectors] FLAT "file-name.vmdk" OFFSET
+ * or
+ * RW [size in sectors] SPARSE "file-name.vmdk"
+ */
+ flat_offset = -1;
+ ret = sscanf(p, "%10s %" SCNd64 " %10s %511s %" SCNd64,
+ access, &sectors, type, fname, &flat_offset);
+ if (ret < 4 || strcmp(access, "RW")) {
+ goto next_line;
+ } else if (!strcmp(type, "FLAT")) {
+ if (ret != 5 || flat_offset < 0) {
+ return -EINVAL;
+ }
+ } else if (ret != 4) {
+ return -EINVAL;
+ }
+
+ /* trim the quotation marks around */
+ if (fname[0] == '"') {
+ memmove(fname, fname + 1, strlen(fname));
+ if (strlen(fname) <= 1 || fname[strlen(fname) - 1] != '"') {
+ return -EINVAL;
+ }
+ fname[strlen(fname) - 1] = '\0';
+ }
+ if (sectors <= 0 ||
+ (strcmp(type, "FLAT") && strcmp(type, "SPARSE")) ||
+ (strcmp(access, "RW"))) {
+ goto next_line;
+ }
+
+ /* save to extents array */
+ if (!strcmp(type, "FLAT")) {
+ /* FLAT extent */
+ char extent_path[PATH_MAX];
+ BlockDriverState *extent_file;
+ VmdkExtent *extent;
+
+ path_combine(extent_path, sizeof(extent_path),
+ desc_file_path, fname);
+ ret = bdrv_file_open(&extent_file, extent_path, bs->open_flags);
+ if (ret) {
+ return ret;
+ }
+ extent = vmdk_add_extent(bs, extent_file, true, sectors,
+ 0, 0, 0, 0, sectors);
+ extent->flat_start_offset = flat_offset;
+ } else {
+ /* SPARSE extent, not supported for now */
+ fprintf(stderr,
+ "VMDK: Not supported extent type \"%s\""".\n", type);
+ return -ENOTSUP;
+ }
+next_line:
+ /* move to next line */
+ while (*p && *p != '\n') {
+ p++;
+ }
+ p++;
+ }
+ return 0;
+}
+
+static int vmdk_open_desc_file(BlockDriverState *bs, int flags)
+{
+ int ret;
+ char buf[2048];
+ char ct[128];
+ BDRVVmdkState *s = bs->opaque;
+
+ ret = bdrv_pread(bs->file, 0, buf, sizeof(buf));
+ if (ret < 0) {
+ return ret;
+ }
+ buf[2047] = '\0';
+ if (vmdk_parse_description(buf, "createType", ct, sizeof(ct))) {
+ return -EINVAL;
+ }
+ if (strcmp(ct, "monolithicFlat")) {
+ fprintf(stderr,
+ "VMDK: Not supported image type \"%s\""".\n", ct);
+ return -ENOTSUP;
+ }
+ s->desc_offset = 0;
+ ret = vmdk_parse_extents(buf, bs, bs->file->filename);
+ if (ret) {
+ return ret;
+ }
+
+ /* try to open parent images, if exist */
+ if (vmdk_parent_open(bs)) {
+ qemu_free(s->extents);
+ return -EINVAL;
+ }
+ s->parent_cid = vmdk_read_cid(bs, 1);
+ return 0;
+}
+
static int vmdk_open(BlockDriverState *bs, int flags)
{
uint32_t magic;
@@ -598,7 +738,7 @@ static int vmdk_open(BlockDriverState *b
} else if (magic == VMDK4_MAGIC) {
return vmdk_open_vmdk4(bs, flags);
} else {
- return -EINVAL;
+ return vmdk_open_desc_file(bs, flags);
}
}
@@ -679,7 +819,7 @@ static int get_cluster_offset(BlockDrive
if (m_data)
m_data->valid = 0;
if (extent->flat) {
- *cluster_offset = 0;
+ *cluster_offset = extent->flat_start_offset;
return 0;
}
@@ -832,16 +972,20 @@ static int vmdk_read(BlockDriverState *b
/* if not allocated, try to read from parent image, if exist */
if (bs->backing_hd) {
if (!vmdk_is_cid_valid(bs))
- return -1;
+ return -EINVAL;
ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
if (ret < 0)
- return -1;
+ return ret;
} else {
memset(buf, 0, 512 * n);
}
} else {
- if(bdrv_pread(bs->file, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512)
- return -1;
+ ret = bdrv_pread(extent->file,
+ cluster_offset + index_in_cluster * 512,
+ buf, n * 512);
+ if (ret < 0) {
+ return ret;
+ }
}
nb_sectors -= n;
sector_num += n;
@@ -865,7 +1009,7 @@ static int vmdk_write(BlockDriverState *
"(VMDK) Wrong offset: sector_num=0x%" PRIx64
" total_sectors=0x%" PRIx64 "\n",
sector_num, bs->total_sectors);
- return -1;
+ return -EIO;
}
while (nb_sectors > 0) {
@@ -888,16 +1032,17 @@ static int vmdk_write(BlockDriverState *
n = nb_sectors;
}
- if (bdrv_pwrite(bs->file,
+ ret = bdrv_pwrite(extent->file,
cluster_offset + index_in_cluster * 512,
- buf, n * 512)
- != n * 512) {
- return -1;
+ buf,
+ n * 512);
+ if (ret < 0) {
+ return ret;
}
if (m_data.valid) {
/* update L2 tables */
if (vmdk_L2update(extent, &m_data) == -1) {
- return -1;
+ return -EIO;
}
}
nb_sectors -= n;

View File

@ -1,595 +0,0 @@
From 0d0f2ba577bd05491b5954751787f8b969ca1ec3 Mon Sep 17 00:00:00 2001
From: Fam Zheng <famcool@gmail.com>
Date: Tue, 19 Jul 2011 08:45:23 +0800
Subject: [PATCH 11/12] VMDK: create different subformats
Add create option 'format', with enums:
monolithicSparse
monolithicFlat
twoGbMaxExtentSparse
twoGbMaxExtentFlat
Each creates a subformat image file. The default is monolithicSparse.
Signed-off-by: Fam Zheng <famcool@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 503 ++++++++++++++++++++++++++++++++---------------------------
block_int.h | 1 +
2 files changed, 275 insertions(+), 229 deletions(-)
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -156,8 +156,9 @@ static int vmdk_probe(const uint8_t *buf
#define CHECK_CID 1
#define SECTOR_SIZE 512
-#define DESC_SIZE 20*SECTOR_SIZE // 20 sectors of 512 bytes each
-#define HEADER_SIZE 512 // first sector of 512 bytes
+#define DESC_SIZE (20 * SECTOR_SIZE) /* 20 sectors of 512 bytes each */
+#define BUF_SIZE 4096
+#define HEADER_SIZE 512 /* first sector of 512 bytes */
static void vmdk_free_extents(BlockDriverState *bs)
{
@@ -243,168 +244,6 @@ static int vmdk_is_cid_valid(BlockDriver
return 1;
}
-static int vmdk_snapshot_create(const char *filename, const char *backing_file)
-{
- int snp_fd, p_fd;
- int ret;
- uint32_t p_cid;
- char *p_name, *gd_buf, *rgd_buf;
- const char *real_filename, *temp_str;
- VMDK4Header header;
- uint32_t gde_entries, gd_size;
- int64_t gd_offset, rgd_offset, capacity, gt_size;
- char p_desc[DESC_SIZE], s_desc[DESC_SIZE], hdr[HEADER_SIZE];
- static const char desc_template[] =
- "# Disk DescriptorFile\n"
- "version=1\n"
- "CID=%x\n"
- "parentCID=%x\n"
- "createType=\"monolithicSparse\"\n"
- "parentFileNameHint=\"%s\"\n"
- "\n"
- "# Extent description\n"
- "RW %u SPARSE \"%s\"\n"
- "\n"
- "# The Disk Data Base \n"
- "#DDB\n"
- "\n";
-
- snp_fd = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 0644);
- if (snp_fd < 0)
- return -errno;
- p_fd = open(backing_file, O_RDONLY | O_BINARY | O_LARGEFILE);
- if (p_fd < 0) {
- close(snp_fd);
- return -errno;
- }
-
- /* read the header */
- if (lseek(p_fd, 0x0, SEEK_SET) == -1) {
- ret = -errno;
- goto fail;
- }
- if (read(p_fd, hdr, HEADER_SIZE) != HEADER_SIZE) {
- ret = -errno;
- goto fail;
- }
-
- /* write the header */
- if (lseek(snp_fd, 0x0, SEEK_SET) == -1) {
- ret = -errno;
- goto fail;
- }
- if (write(snp_fd, hdr, HEADER_SIZE) == -1) {
- ret = -errno;
- goto fail;
- }
-
- memset(&header, 0, sizeof(header));
- memcpy(&header,&hdr[4], sizeof(header)); // skip the VMDK4_MAGIC
-
- if (ftruncate(snp_fd, header.grain_offset << 9)) {
- ret = -errno;
- goto fail;
- }
- /* the descriptor offset = 0x200 */
- if (lseek(p_fd, 0x200, SEEK_SET) == -1) {
- ret = -errno;
- goto fail;
- }
- if (read(p_fd, p_desc, DESC_SIZE) != DESC_SIZE) {
- ret = -errno;
- goto fail;
- }
-
- if ((p_name = strstr(p_desc,"CID")) != NULL) {
- p_name += sizeof("CID");
- sscanf(p_name,"%x",&p_cid);
- }
-
- real_filename = filename;
- if ((temp_str = strrchr(real_filename, '\\')) != NULL)
- real_filename = temp_str + 1;
- if ((temp_str = strrchr(real_filename, '/')) != NULL)
- real_filename = temp_str + 1;
- if ((temp_str = strrchr(real_filename, ':')) != NULL)
- real_filename = temp_str + 1;
-
- snprintf(s_desc, sizeof(s_desc), desc_template, p_cid, p_cid, backing_file,
- (uint32_t)header.capacity, real_filename);
-
- /* write the descriptor */
- if (lseek(snp_fd, 0x200, SEEK_SET) == -1) {
- ret = -errno;
- goto fail;
- }
- if (write(snp_fd, s_desc, strlen(s_desc)) == -1) {
- ret = -errno;
- goto fail;
- }
-
- gd_offset = header.gd_offset * SECTOR_SIZE; // offset of GD table
- rgd_offset = header.rgd_offset * SECTOR_SIZE; // offset of RGD table
- capacity = header.capacity * SECTOR_SIZE; // Extent size
- /*
- * Each GDE span 32M disk, means:
- * 512 GTE per GT, each GTE points to grain
- */
- gt_size = (int64_t)header.num_gtes_per_gte * header.granularity * SECTOR_SIZE;
- if (!gt_size) {
- ret = -EINVAL;
- goto fail;
- }
- gde_entries = (uint32_t)(capacity / gt_size); // number of gde/rgde
- gd_size = gde_entries * sizeof(uint32_t);
-
- /* write RGD */
- rgd_buf = qemu_malloc(gd_size);
- if (lseek(p_fd, rgd_offset, SEEK_SET) == -1) {
- ret = -errno;
- goto fail_rgd;
- }
- if (read(p_fd, rgd_buf, gd_size) != gd_size) {
- ret = -errno;
- goto fail_rgd;
- }
- if (lseek(snp_fd, rgd_offset, SEEK_SET) == -1) {
- ret = -errno;
- goto fail_rgd;
- }
- if (write(snp_fd, rgd_buf, gd_size) == -1) {
- ret = -errno;
- goto fail_rgd;
- }
-
- /* write GD */
- gd_buf = qemu_malloc(gd_size);
- if (lseek(p_fd, gd_offset, SEEK_SET) == -1) {
- ret = -errno;
- goto fail_gd;
- }
- if (read(p_fd, gd_buf, gd_size) != gd_size) {
- ret = -errno;
- goto fail_gd;
- }
- if (lseek(snp_fd, gd_offset, SEEK_SET) == -1) {
- ret = -errno;
- goto fail_gd;
- }
- if (write(snp_fd, gd_buf, gd_size) == -1) {
- ret = -errno;
- goto fail_gd;
- }
- ret = 0;
-
-fail_gd:
- qemu_free(gd_buf);
-fail_rgd:
- qemu_free(rgd_buf);
-fail:
- close(p_fd);
- close(snp_fd);
- return ret;
-}
-
static int vmdk_parent_open(BlockDriverState *bs)
{
char *p_name;
@@ -1058,68 +897,40 @@ static int vmdk_write(BlockDriverState *
return 0;
}
-static int vmdk_create(const char *filename, QEMUOptionParameter *options)
+
+static int vmdk_create_extent(const char *filename, int64_t filesize, bool flat)
{
- int fd, i;
+ int ret, i;
+ int fd = 0;
VMDK4Header header;
uint32_t tmp, magic, grains, gd_size, gt_size, gt_count;
- static const char desc_template[] =
- "# Disk DescriptorFile\n"
- "version=1\n"
- "CID=%x\n"
- "parentCID=ffffffff\n"
- "createType=\"monolithicSparse\"\n"
- "\n"
- "# Extent description\n"
- "RW %" PRId64 " SPARSE \"%s\"\n"
- "\n"
- "# The Disk Data Base \n"
- "#DDB\n"
- "\n"
- "ddb.virtualHWVersion = \"%d\"\n"
- "ddb.geometry.cylinders = \"%" PRId64 "\"\n"
- "ddb.geometry.heads = \"16\"\n"
- "ddb.geometry.sectors = \"63\"\n"
- "ddb.adapterType = \"ide\"\n";
- char desc[1024];
- const char *real_filename, *temp_str;
- int64_t total_size = 0;
- const char *backing_file = NULL;
- int flags = 0;
- int ret;
- // Read out options
- while (options && options->name) {
- if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
- total_size = options->value.n / 512;
- } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
- backing_file = options->value.s;
- } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) {
- flags |= options->value.n ? BLOCK_FLAG_COMPAT6: 0;
- }
- options++;
+ fd = open(
+ filename,
+ O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
+ 0644);
+ if (fd < 0) {
+ return -errno;
}
-
- /* XXX: add support for backing file */
- if (backing_file) {
- return vmdk_snapshot_create(filename, backing_file);
+ if (flat) {
+ ret = ftruncate(fd, filesize);
+ if (ret < 0) {
+ ret = -errno;
+ }
+ goto exit;
}
-
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
- 0644);
- if (fd < 0)
- return -errno;
magic = cpu_to_be32(VMDK4_MAGIC);
memset(&header, 0, sizeof(header));
header.version = 1;
header.flags = 3; /* ?? */
- header.capacity = total_size;
+ header.capacity = filesize / 512;
header.granularity = 128;
header.num_gtes_per_gte = 512;
- grains = (total_size + header.granularity - 1) / header.granularity;
+ grains = (filesize / 512 + header.granularity - 1) / header.granularity;
gt_size = ((header.num_gtes_per_gte * sizeof(uint32_t)) + 511) >> 9;
- gt_count = (grains + header.num_gtes_per_gte - 1) / header.num_gtes_per_gte;
+ gt_count =
+ (grains + header.num_gtes_per_gte - 1) / header.num_gtes_per_gte;
gd_size = (gt_count * sizeof(uint32_t) + 511) >> 9;
header.desc_offset = 1;
@@ -1130,7 +941,6 @@ static int vmdk_create(const char *filen
((header.gd_offset + gd_size + (gt_size * gt_count) +
header.granularity - 1) / header.granularity) *
header.granularity;
-
/* swap endianness for all header fields */
header.version = cpu_to_le32(header.version);
header.flags = cpu_to_le32(header.flags);
@@ -1188,27 +998,255 @@ static int vmdk_create(const char *filen
}
}
- /* compose the descriptor */
- real_filename = filename;
- if ((temp_str = strrchr(real_filename, '\\')) != NULL)
- real_filename = temp_str + 1;
- if ((temp_str = strrchr(real_filename, '/')) != NULL)
- real_filename = temp_str + 1;
- if ((temp_str = strrchr(real_filename, ':')) != NULL)
- real_filename = temp_str + 1;
- snprintf(desc, sizeof(desc), desc_template, (unsigned int)time(NULL),
- total_size, real_filename,
- (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
- total_size / (int64_t)(63 * 16));
+ ret = 0;
+ exit:
+ close(fd);
+ return ret;
+}
- /* write the descriptor */
- lseek(fd, le64_to_cpu(header.desc_offset) << 9, SEEK_SET);
+static int filename_decompose(const char *filename, char *path, char *prefix,
+ char *postfix, size_t buf_len)
+{
+ const char *p, *q;
+
+ if (filename == NULL || !strlen(filename)) {
+ fprintf(stderr, "Vmdk: no filename provided.\n");
+ return -1;
+ }
+ p = strrchr(filename, '/');
+ if (p == NULL) {
+ p = strrchr(filename, '\\');
+ }
+ if (p == NULL) {
+ p = strrchr(filename, ':');
+ }
+ if (p != NULL) {
+ p++;
+ if (p - filename >= buf_len) {
+ return -1;
+ }
+ pstrcpy(path, p - filename + 1, filename);
+ } else {
+ p = filename;
+ path[0] = '\0';
+ }
+ q = strrchr(p, '.');
+ if (q == NULL) {
+ pstrcpy(prefix, buf_len, p);
+ postfix[0] = '\0';
+ } else {
+ if (q - p >= buf_len) {
+ return -1;
+ }
+ pstrcpy(prefix, q - p + 1, p);
+ pstrcpy(postfix, buf_len, q);
+ }
+ return 0;
+}
+
+static int relative_path(char *dest, int dest_size,
+ const char *base, const char *target)
+{
+ int i = 0;
+ int n = 0;
+ const char *p, *q;
+#ifdef _WIN32
+ const char *sep = "\\";
+#else
+ const char *sep = "/";
+#endif
+
+ if (!(dest && base && target)) {
+ return -1;
+ }
+ if (path_is_absolute(target)) {
+ dest[dest_size - 1] = '\0';
+ strncpy(dest, target, dest_size - 1);
+ return 0;
+ }
+ while (base[i] == target[i]) {
+ i++;
+ }
+ p = &base[i];
+ q = &target[i];
+ while (*p) {
+ if (*p == *sep) {
+ n++;
+ }
+ p++;
+ }
+ dest[0] = '\0';
+ for (; n; n--) {
+ pstrcat(dest, dest_size, "..");
+ pstrcat(dest, dest_size, sep);
+ }
+ pstrcat(dest, dest_size, q);
+ return 0;
+}
+
+static int vmdk_create(const char *filename, QEMUOptionParameter *options)
+{
+ int fd, idx = 0;
+ char desc[BUF_SIZE];
+ int64_t total_size = 0, filesize;
+ const char *backing_file = NULL;
+ const char *fmt = NULL;
+ int flags = 0;
+ int ret = 0;
+ bool flat, split;
+ char ext_desc_lines[BUF_SIZE] = "";
+ char path[PATH_MAX], prefix[PATH_MAX], postfix[PATH_MAX];
+ const int64_t split_size = 0x80000000; /* VMDK has constant split size */
+ const char *desc_extent_line;
+ char parent_desc_line[BUF_SIZE] = "";
+ uint32_t parent_cid = 0xffffffff;
+ const char desc_template[] =
+ "# Disk DescriptorFile\n"
+ "version=1\n"
+ "CID=%x\n"
+ "parentCID=%x\n"
+ "createType=\"%s\"\n"
+ "%s"
+ "\n"
+ "# Extent description\n"
+ "%s"
+ "\n"
+ "# The Disk Data Base\n"
+ "#DDB\n"
+ "\n"
+ "ddb.virtualHWVersion = \"%d\"\n"
+ "ddb.geometry.cylinders = \"%" PRId64 "\"\n"
+ "ddb.geometry.heads = \"16\"\n"
+ "ddb.geometry.sectors = \"63\"\n"
+ "ddb.adapterType = \"ide\"\n";
+
+ if (filename_decompose(filename, path, prefix, postfix, PATH_MAX)) {
+ return -EINVAL;
+ }
+ /* Read out options */
+ while (options && options->name) {
+ if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
+ total_size = options->value.n;
+ } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
+ backing_file = options->value.s;
+ } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) {
+ flags |= options->value.n ? BLOCK_FLAG_COMPAT6 : 0;
+ } else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) {
+ fmt = options->value.s;
+ }
+ options++;
+ }
+ if (!fmt) {
+ /* Default format to monolithicSparse */
+ fmt = "monolithicSparse";
+ } else if (strcmp(fmt, "monolithicFlat") &&
+ strcmp(fmt, "monolithicSparse") &&
+ strcmp(fmt, "twoGbMaxExtentSparse") &&
+ strcmp(fmt, "twoGbMaxExtentFlat")) {
+ fprintf(stderr, "VMDK: Unknown subformat: %s\n", fmt);
+ return -EINVAL;
+ }
+ split = !(strcmp(fmt, "twoGbMaxExtentFlat") &&
+ strcmp(fmt, "twoGbMaxExtentSparse"));
+ flat = !(strcmp(fmt, "monolithicFlat") &&
+ strcmp(fmt, "twoGbMaxExtentFlat"));
+ if (flat) {
+ desc_extent_line = "RW %lld FLAT \"%s\" 0\n";
+ } else {
+ desc_extent_line = "RW %lld SPARSE \"%s\"\n";
+ }
+ if (flat && backing_file) {
+ /* not supporting backing file for flat image */
+ return -ENOTSUP;
+ }
+ if (backing_file) {
+ char parent_filename[PATH_MAX];
+ BlockDriverState *bs = bdrv_new("");
+ ret = bdrv_open(bs, backing_file, 0, NULL);
+ if (ret != 0) {
+ bdrv_delete(bs);
+ return ret;
+ }
+ if (strcmp(bs->drv->format_name, "vmdk")) {
+ bdrv_delete(bs);
+ return -EINVAL;
+ }
+ filesize = bdrv_getlength(bs);
+ parent_cid = vmdk_read_cid(bs, 0);
+ bdrv_delete(bs);
+ relative_path(parent_filename, sizeof(parent_filename),
+ filename, backing_file);
+ snprintf(parent_desc_line, sizeof(parent_desc_line),
+ "parentFileNameHint=\"%s\"", parent_filename);
+ }
+
+ /* Create extents */
+ filesize = total_size;
+ while (filesize > 0) {
+ char desc_line[BUF_SIZE];
+ char ext_filename[PATH_MAX];
+ char desc_filename[PATH_MAX];
+ int64_t size = filesize;
+
+ if (split && size > split_size) {
+ size = split_size;
+ }
+ if (split) {
+ snprintf(desc_filename, sizeof(desc_filename), "%s-%c%03d%s",
+ prefix, flat ? 'f' : 's', ++idx, postfix);
+ } else if (flat) {
+ snprintf(desc_filename, sizeof(desc_filename), "%s-flat%s",
+ prefix, postfix);
+ } else {
+ snprintf(desc_filename, sizeof(desc_filename), "%s%s",
+ prefix, postfix);
+ }
+ snprintf(ext_filename, sizeof(ext_filename), "%s%s",
+ path, desc_filename);
+
+ if (vmdk_create_extent(ext_filename, size, flat)) {
+ return -EINVAL;
+ }
+ filesize -= size;
+
+ /* Format description line */
+ snprintf(desc_line, sizeof(desc_line),
+ desc_extent_line, size / 512, desc_filename);
+ pstrcat(ext_desc_lines, sizeof(ext_desc_lines), desc_line);
+ }
+ /* generate descriptor file */
+ snprintf(desc, sizeof(desc), desc_template,
+ (unsigned int)time(NULL),
+ parent_cid,
+ fmt,
+ parent_desc_line,
+ ext_desc_lines,
+ (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
+ total_size / (int64_t)(63 * 16 * 512));
+ if (split || flat) {
+ fd = open(
+ filename,
+ O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
+ 0644);
+ } else {
+ fd = open(
+ filename,
+ O_WRONLY | O_BINARY | O_LARGEFILE,
+ 0644);
+ }
+ if (fd < 0) {
+ return -errno;
+ }
+ /* the descriptor offset = 0x200 */
+ if (!split && !flat && 0x200 != lseek(fd, 0x200, SEEK_SET)) {
+ ret = -errno;
+ goto exit;
+ }
ret = qemu_write_full(fd, desc, strlen(desc));
if (ret != strlen(desc)) {
ret = -errno;
goto exit;
}
-
ret = 0;
exit:
close(fd);
@@ -1252,6 +1290,13 @@ static QEMUOptionParameter vmdk_create_o
.type = OPT_FLAG,
.help = "VMDK version 6 image"
},
+ {
+ .name = BLOCK_OPT_SUBFMT,
+ .type = OPT_STRING,
+ .help =
+ "VMDK flat extent format, can be one of "
+ "{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat} "
+ },
{ NULL }
};
--- a/block_int.h
+++ b/block_int.h
@@ -39,6 +39,7 @@
#define BLOCK_OPT_CLUSTER_SIZE "cluster_size"
#define BLOCK_OPT_TABLE_SIZE "table_size"
#define BLOCK_OPT_PREALLOC "preallocation"
+#define BLOCK_OPT_SUBFMT "subformat"
typedef struct AIOPool {
void (*cancel)(BlockDriverAIOCB *acb);

View File

@ -1,114 +0,0 @@
From 5483df4df2729a5d1e4888a48039b1cd90438480 Mon Sep 17 00:00:00 2001
From: Othmar Pasteka <pasteka@kabsi.at>
Date: Wed, 30 Jan 2013 00:26:52 +0100
Subject: [PATCH 12/12] vmdk: Allow selecting SCSI adapter in image creation
Introduce a new option "adapter_type" when converting to vmdk images.
It can be one of the following: ide (default), buslogic, lsilogic
or legacyESX (according to the vmdk spec from vmware).
In case of a non-ide adapter, heads is set to 255 instead of the 16.
The latter is used for "ide".
Also see LP#545089
Signed-off-by: Othmar Pasteka <pasteka@kabsi.at>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
block/vmdk.c | 31 ++++++++++++++++++++++++++++---
block_int.h | 1 +
2 files changed, 29 insertions(+), 3 deletions(-)
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1089,6 +1089,7 @@ static int vmdk_create(const char *filen
int fd, idx = 0;
char desc[BUF_SIZE];
int64_t total_size = 0, filesize;
+ const char *adapter_type = NULL;
const char *backing_file = NULL;
const char *fmt = NULL;
int flags = 0;
@@ -1100,6 +1101,7 @@ static int vmdk_create(const char *filen
const char *desc_extent_line;
char parent_desc_line[BUF_SIZE] = "";
uint32_t parent_cid = 0xffffffff;
+ uint32_t number_heads = 16;
const char desc_template[] =
"# Disk DescriptorFile\n"
"version=1\n"
@@ -1116,9 +1118,9 @@ static int vmdk_create(const char *filen
"\n"
"ddb.virtualHWVersion = \"%d\"\n"
"ddb.geometry.cylinders = \"%" PRId64 "\"\n"
- "ddb.geometry.heads = \"16\"\n"
+ "ddb.geometry.heads = \"%d\"\n"
"ddb.geometry.sectors = \"63\"\n"
- "ddb.adapterType = \"ide\"\n";
+ "ddb.adapterType = \"%s\"\n";
if (filename_decompose(filename, path, prefix, postfix, PATH_MAX)) {
return -EINVAL;
@@ -1127,6 +1129,8 @@ static int vmdk_create(const char *filen
while (options && options->name) {
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
total_size = options->value.n;
+ } else if (!strcmp(options->name, BLOCK_OPT_ADAPTER_TYPE)) {
+ adapter_type = options->value.s;
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
backing_file = options->value.s;
} else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) {
@@ -1136,6 +1140,20 @@ static int vmdk_create(const char *filen
}
options++;
}
+ if (!adapter_type) {
+ adapter_type = "ide";
+ } else if (strcmp(adapter_type, "ide") &&
+ strcmp(adapter_type, "buslogic") &&
+ strcmp(adapter_type, "lsilogic") &&
+ strcmp(adapter_type, "legacyESX")) {
+ fprintf(stderr, "VMDK: Unknown adapter type: '%s'.\n", adapter_type);
+ return -EINVAL;
+ }
+ if (strcmp(adapter_type, "ide") != 0) {
+ /* that's the number of heads with which vmware operates when
+ creating, exporting, etc. vmdk files with a non-ide adapter type */
+ number_heads = 255;
+ }
if (!fmt) {
/* Default format to monolithicSparse */
fmt = "monolithicSparse";
@@ -1222,7 +1240,8 @@ static int vmdk_create(const char *filen
parent_desc_line,
ext_desc_lines,
(flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
- total_size / (int64_t)(63 * 16 * 512));
+ total_size / (int64_t)(63 * number_heads * 512), number_heads,
+ adapter_type);
if (split || flat) {
fd = open(
filename,
@@ -1281,6 +1300,12 @@ static QEMUOptionParameter vmdk_create_o
.help = "Virtual disk size"
},
{
+ .name = BLOCK_OPT_ADAPTER_TYPE,
+ .type = OPT_STRING,
+ .help = "Virtual adapter type, can be one of "
+ "ide (default), lsilogic, buslogic or legacyESX"
+ },
+ {
.name = BLOCK_OPT_BACKING_FILE,
.type = OPT_STRING,
.help = "File name of a base image"
--- a/block_int.h
+++ b/block_int.h
@@ -40,6 +40,7 @@
#define BLOCK_OPT_TABLE_SIZE "table_size"
#define BLOCK_OPT_PREALLOC "preallocation"
#define BLOCK_OPT_SUBFMT "subformat"
+#define BLOCK_OPT_ADAPTER_TYPE "adapter_type"
typedef struct AIOPool {
void (*cancel)(BlockDriverAIOCB *acb);