mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
stubdom: remove support for grub-pv
The Mini-OS based grub-pv is not being built by default since Xen 4.16. Additionally it can be replaced in most cases by the more modern pvgrub (part of grub upstream), while grub-pv is based on legacy grub 0.97. In case someone is really depending on grub-pv, an old build from a previous Xen version can be used without any problem, as only stable hypercall interfaces are used by it. Remove grub-pv from the build system. Signed-off-by: Juergen Gross <jgross@suse.com> Acked-by: Samuel Thibault <samuel.thibault@ens-lyon.org> Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
58db743e3b
commit
0724c68d85
26 files changed
-11041
No files matched your search
@@ -71,9 +71,6 @@ build-tools-oxenstored: build-tools-public-headers
|
|||||||
.PHONY: build-stubdom
|
.PHONY: build-stubdom
|
||||||
build-stubdom: mini-os-dir build-tools-public-headers
|
build-stubdom: mini-os-dir build-tools-public-headers
|
||||||
$(MAKE) -C stubdom build
|
$(MAKE) -C stubdom build
|
||||||
ifeq (x86_64,$(XEN_TARGET_ARCH))
|
|
||||||
XEN_TARGET_ARCH=x86_32 $(MAKE) -C stubdom pv-grub-if-enabled
|
|
||||||
endif
|
|
||||||
|
|
||||||
define do-subtree
|
define do-subtree
|
||||||
$(1)/%: FORCE
|
$(1)/%: FORCE
|
||||||
@@ -149,9 +146,6 @@ install-tools: install-tools-public-headers
|
|||||||
.PHONY: install-stubdom
|
.PHONY: install-stubdom
|
||||||
install-stubdom: mini-os-dir install-tools-public-headers
|
install-stubdom: mini-os-dir install-tools-public-headers
|
||||||
$(MAKE) -C stubdom install
|
$(MAKE) -C stubdom install
|
||||||
ifeq (x86_64,$(XEN_TARGET_ARCH))
|
|
||||||
XEN_TARGET_ARCH=x86_32 $(MAKE) -C stubdom install-grub-if-enabled
|
|
||||||
endif
|
|
||||||
|
|
||||||
.PHONY: tools/firmware/seabios-dir-force-update
|
.PHONY: tools/firmware/seabios-dir-force-update
|
||||||
tools/firmware/seabios-dir-force-update:
|
tools/firmware/seabios-dir-force-update:
|
||||||
|
|||||||
@@ -23,9 +23,6 @@ NEWLIB_URL := @NEWLIB_URL@
|
|||||||
LWIP_VERSION := @LWIP_VERSION@
|
LWIP_VERSION := @LWIP_VERSION@
|
||||||
LWIP_URL := @LWIP_URL@
|
LWIP_URL := @LWIP_URL@
|
||||||
|
|
||||||
GRUB_VERSION := @GRUB_VERSION@
|
|
||||||
GRUB_URL := @GRUB_URL@
|
|
||||||
|
|
||||||
GMP_VERSION := @GMP_VERSION@
|
GMP_VERSION := @GMP_VERSION@
|
||||||
GMP_URL := @GMP_URL@
|
GMP_URL := @GMP_URL@
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
/cross-root-*
|
/cross-root-*
|
||||||
/gcc-*
|
/gcc-*
|
||||||
/gmp-*
|
/gmp-*
|
||||||
/grub-*
|
|
||||||
/include
|
/include
|
||||||
/libs-*
|
/libs-*
|
||||||
/libxencall-*
|
/libxencall-*
|
||||||
|
|||||||
@@ -361,32 +361,6 @@ vtpmmgr-minios-config.mk: $(CURDIR)/vtpmmgr/minios.cfg
|
|||||||
vtpmmgr: cross-polarssl vtpmmgr-minios-config.mk
|
vtpmmgr: cross-polarssl vtpmmgr-minios-config.mk
|
||||||
XEN_TARGET_ARCH="$(XEN_TARGET_ARCH)" CPPFLAGS="$(TARGET_CPPFLAGS) $(shell cat vtpmmgr-minios-config.mk)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) -C $@
|
XEN_TARGET_ARCH="$(XEN_TARGET_ARCH)" CPPFLAGS="$(TARGET_CPPFLAGS) $(shell cat vtpmmgr-minios-config.mk)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) -C $@
|
||||||
|
|
||||||
######
|
|
||||||
# Grub
|
|
||||||
######
|
|
||||||
|
|
||||||
grub-$(GRUB_VERSION).tar.gz:
|
|
||||||
$(FETCHER) $@ $(GRUB_URL)/$@
|
|
||||||
|
|
||||||
grub-upstream: grub-$(GRUB_VERSION).tar.gz
|
|
||||||
tar xzf $<
|
|
||||||
mv grub-$(GRUB_VERSION) $@
|
|
||||||
for i in grub.patches/* ; do \
|
|
||||||
patch -d $@ -p1 < $$i || exit 1; \
|
|
||||||
done
|
|
||||||
|
|
||||||
grub/minios.gen.cfg: APP_LIBS = guest ctrl toollog
|
|
||||||
grub/minios.gen.cfg: grub/minios.cfg Makefile
|
|
||||||
$(GEN_config) >$@
|
|
||||||
|
|
||||||
grub-$(XEN_TARGET_ARCH)-minios-config.mk: grub/minios.gen.cfg
|
|
||||||
MINIOS_CONFIG="$(CURDIR)/$<" CONFIG_FILE="$(CURDIR)/$@" $(MAKE) DESTDIR= -C $(MINI_OS) config
|
|
||||||
|
|
||||||
.PHONY: grub
|
|
||||||
grub: cross-polarssl grub-upstream $(CROSS_ROOT) grub-$(XEN_TARGET_ARCH)-minios-config.mk
|
|
||||||
mkdir -p grub-$(XEN_TARGET_ARCH)
|
|
||||||
CPPFLAGS="$(TARGET_CPPFLAGS) $(shell cat grub-$(XEN_TARGET_ARCH)-minios-config.mk)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= -C $@ OBJ_DIR=$(CURDIR)/grub-$(XEN_TARGET_ARCH)
|
|
||||||
|
|
||||||
##########
|
##########
|
||||||
# xenstore
|
# xenstore
|
||||||
##########
|
##########
|
||||||
@@ -429,17 +403,6 @@ vtpm-stubdom: mini-os-$(XEN_TARGET_ARCH)-vtpm vtpm
|
|||||||
vtpmmgr-stubdom: mini-os-$(XEN_TARGET_ARCH)-vtpmmgr vtpmmgr
|
vtpmmgr-stubdom: mini-os-$(XEN_TARGET_ARCH)-vtpmmgr vtpmmgr
|
||||||
DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="$(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" MINIOS_CONFIG="$(CURDIR)/vtpmmgr/minios.cfg" $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< APP_OBJS="$(CURDIR)/vtpmmgr/vtpmmgr.a" APP_LDLIBS="-lm -lpolarssl"
|
DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="$(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" MINIOS_CONFIG="$(CURDIR)/vtpmmgr/minios.cfg" $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< APP_OBJS="$(CURDIR)/vtpmmgr/vtpmmgr.a" APP_LDLIBS="-lm -lpolarssl"
|
||||||
|
|
||||||
.PHONY: pv-grub
|
|
||||||
pv-grub: mini-os-$(XEN_TARGET_ARCH)-grub libxenguest grub
|
|
||||||
DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="$(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" MINIOS_CONFIG="$(CURDIR)/grub/minios.gen.cfg" $(MAKE) DESTDIR= -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< APP_OBJS=$(CURDIR)/grub-$(XEN_TARGET_ARCH)/main.a
|
|
||||||
|
|
||||||
.PHONY: pv-grub-if-enabled
|
|
||||||
ifneq ($(filter grub,$(STUBDOM_TARGETS)),)
|
|
||||||
pv-grub-if-enabled: pv-grub
|
|
||||||
else
|
|
||||||
pv-grub-if-enabled:
|
|
||||||
endif
|
|
||||||
|
|
||||||
XENSTORE_DEPS := libxenevtchn libxengnttab libxenmanage
|
XENSTORE_DEPS := libxenevtchn libxengnttab libxenmanage
|
||||||
|
|
||||||
.PHONY: xenstore-stubdom
|
.PHONY: xenstore-stubdom
|
||||||
@@ -460,16 +423,6 @@ else
|
|||||||
install:
|
install:
|
||||||
endif
|
endif
|
||||||
|
|
||||||
install-grub: pv-grub
|
|
||||||
$(INSTALL_DIR) "$(DESTDIR)$(XENFIRMWAREDIR)"
|
|
||||||
$(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-grub/mini-os.gz "$(DESTDIR)$(XENFIRMWAREDIR)/pv-grub-$(XEN_TARGET_ARCH).gz"
|
|
||||||
|
|
||||||
ifneq ($(filter grub,$(STUBDOM_TARGETS)),)
|
|
||||||
install-grub-if-enabled: install-grub
|
|
||||||
else
|
|
||||||
install-grub-if-enabled:
|
|
||||||
endif
|
|
||||||
|
|
||||||
install-xenstore: xenstore-stubdom
|
install-xenstore: xenstore-stubdom
|
||||||
$(INSTALL_DIR) "$(DESTDIR)$(XENFIRMWAREDIR)"
|
$(INSTALL_DIR) "$(DESTDIR)$(XENFIRMWAREDIR)"
|
||||||
$(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-xenstore/mini-os.gz "$(DESTDIR)$(XENFIRMWAREDIR)/xenstore-stubdom.gz"
|
$(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-xenstore/mini-os.gz "$(DESTDIR)$(XENFIRMWAREDIR)/xenstore-stubdom.gz"
|
||||||
@@ -500,9 +453,6 @@ else
|
|||||||
uninstall:
|
uninstall:
|
||||||
endif
|
endif
|
||||||
|
|
||||||
uninstall-grub:
|
|
||||||
rm -f $(DESTDIR)$(XENFIRMWAREDIR)/pv-grub-$(XEN_TARGET_ARCH).gz
|
|
||||||
|
|
||||||
uninstall-xenstore:
|
uninstall-xenstore:
|
||||||
rm -f $(DESTDIR)$(XENFIRMWAREDIR)/xenstore-stubdom.gz
|
rm -f $(DESTDIR)$(XENFIRMWAREDIR)/xenstore-stubdom.gz
|
||||||
|
|
||||||
@@ -523,14 +473,12 @@ uninstall-vtpmmgr:
|
|||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean: $(foreach lib,$(STUB_LIBS),clean-libxen$(lib))
|
clean: $(foreach lib,$(STUB_LIBS),clean-libxen$(lib))
|
||||||
clean:
|
clean:
|
||||||
rm -fr mini-os-$(XEN_TARGET_ARCH)-grub
|
|
||||||
rm -fr mini-os-$(XEN_TARGET_ARCH)-xenstore
|
rm -fr mini-os-$(XEN_TARGET_ARCH)-xenstore
|
||||||
rm -fr mini-os-$(XEN_TARGET_ARCH)-xenstorepvh
|
rm -fr mini-os-$(XEN_TARGET_ARCH)-xenstorepvh
|
||||||
rm -fr mini-os-$(XEN_TARGET_ARCH)-vtpm
|
rm -fr mini-os-$(XEN_TARGET_ARCH)-vtpm
|
||||||
rm -fr mini-os-$(XEN_TARGET_ARCH)-vtpmmgr
|
rm -fr mini-os-$(XEN_TARGET_ARCH)-vtpmmgr
|
||||||
$(MAKE) -C vtpm clean
|
$(MAKE) -C vtpm clean
|
||||||
$(MAKE) -C vtpmmgr clean
|
$(MAKE) -C vtpmmgr clean
|
||||||
rm -fr grub-$(XEN_TARGET_ARCH)
|
|
||||||
rm -f *-minios-config.mk
|
rm -f *-minios-config.mk
|
||||||
rm -f *.gen.cfg
|
rm -f *.gen.cfg
|
||||||
rm -fr pkg-config
|
rm -fr pkg-config
|
||||||
@@ -559,7 +507,6 @@ patchclean: crossclean
|
|||||||
rm -fr polarssl-$(XEN_TARGET_ARCH)
|
rm -fr polarssl-$(XEN_TARGET_ARCH)
|
||||||
rm -fr tpm_emulator-$(XEN_TARGET_ARCH)
|
rm -fr tpm_emulator-$(XEN_TARGET_ARCH)
|
||||||
rm -fr lwip-$(XEN_TARGET_ARCH)
|
rm -fr lwip-$(XEN_TARGET_ARCH)
|
||||||
rm -fr grub-upstream
|
|
||||||
|
|
||||||
# clean downloads
|
# clean downloads
|
||||||
.PHONY: downloadclean
|
.PHONY: downloadclean
|
||||||
@@ -569,7 +516,6 @@ downloadclean: patchclean
|
|||||||
rm -f gmp-$(GMP_VERSION).tar.bz2
|
rm -f gmp-$(GMP_VERSION).tar.bz2
|
||||||
rm -f tpm_emulator-$(TPMEMU_VERSION).tar.gz
|
rm -f tpm_emulator-$(TPMEMU_VERSION).tar.gz
|
||||||
rm -f pciutils-$(LIBPCI_VERSION).tar.bz2
|
rm -f pciutils-$(LIBPCI_VERSION).tar.bz2
|
||||||
rm -f grub-$(GRUB_VERSION).tar.gz
|
|
||||||
rm -f lwip-$(LWIP_VERSION).tar.gz
|
rm -f lwip-$(LWIP_VERSION).tar.gz
|
||||||
rm -f polarssl-$(POLARSSL_VERSION)-gpl.tgz
|
rm -f polarssl-$(POLARSSL_VERSION)-gpl.tgz
|
||||||
|
|
||||||
|
|||||||
Vendored
-65
@@ -630,8 +630,6 @@ POLARSSL_VERSION
|
|||||||
POLARSSL_URL
|
POLARSSL_URL
|
||||||
GMP_VERSION
|
GMP_VERSION
|
||||||
GMP_URL
|
GMP_URL
|
||||||
GRUB_VERSION
|
|
||||||
GRUB_URL
|
|
||||||
LWIP_VERSION
|
LWIP_VERSION
|
||||||
LWIP_URL
|
LWIP_URL
|
||||||
NEWLIB_VERSION
|
NEWLIB_VERSION
|
||||||
@@ -660,7 +658,6 @@ extfiles
|
|||||||
debug
|
debug
|
||||||
xenstorepvh
|
xenstorepvh
|
||||||
xenstore
|
xenstore
|
||||||
grub
|
|
||||||
host_os
|
host_os
|
||||||
host_vendor
|
host_vendor
|
||||||
host_cpu
|
host_cpu
|
||||||
@@ -711,7 +708,6 @@ SHELL'
|
|||||||
ac_subst_files=''
|
ac_subst_files=''
|
||||||
ac_user_opts='
|
ac_user_opts='
|
||||||
enable_option_checking
|
enable_option_checking
|
||||||
enable_pv_grub
|
|
||||||
enable_xenstore_stubdom
|
enable_xenstore_stubdom
|
||||||
enable_xenstorepvh_stubdom
|
enable_xenstorepvh_stubdom
|
||||||
enable_vtpm_stubdom
|
enable_vtpm_stubdom
|
||||||
@@ -732,7 +728,6 @@ ZLIB_URL
|
|||||||
LIBPCI_URL
|
LIBPCI_URL
|
||||||
NEWLIB_URL
|
NEWLIB_URL
|
||||||
LWIP_URL
|
LWIP_URL
|
||||||
GRUB_URL
|
|
||||||
GMP_URL
|
GMP_URL
|
||||||
POLARSSL_URL
|
POLARSSL_URL
|
||||||
TPMEMU_URL'
|
TPMEMU_URL'
|
||||||
@@ -1358,7 +1353,6 @@ Optional Features:
|
|||||||
--disable-option-checking ignore unrecognized --enable/--with options
|
--disable-option-checking ignore unrecognized --enable/--with options
|
||||||
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
|
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
|
||||||
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
||||||
--enable-pv-grub Build and install pv-grub (default is DISABLED)
|
|
||||||
--disable-xenstore-stubdom
|
--disable-xenstore-stubdom
|
||||||
Build and install xenstore-stubdom (default is
|
Build and install xenstore-stubdom (default is
|
||||||
ENABLED)
|
ENABLED)
|
||||||
@@ -1385,7 +1379,6 @@ Some influential environment variables:
|
|||||||
LIBPCI_URL Download url for libpci
|
LIBPCI_URL Download url for libpci
|
||||||
NEWLIB_URL Download url for newlib
|
NEWLIB_URL Download url for newlib
|
||||||
LWIP_URL Download url for lwip
|
LWIP_URL Download url for lwip
|
||||||
GRUB_URL Download url for grub
|
|
||||||
GMP_URL Download url for libgmp
|
GMP_URL Download url for libgmp
|
||||||
POLARSSL_URL
|
POLARSSL_URL
|
||||||
Download url for polarssl
|
Download url for polarssl
|
||||||
@@ -2403,47 +2396,6 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
|
|||||||
|
|
||||||
# Enable/disable stub domains
|
# Enable/disable stub domains
|
||||||
|
|
||||||
# Check whether --enable-pv-grub was given.
|
|
||||||
if test ${enable_pv_grub+y}
|
|
||||||
then :
|
|
||||||
enableval=$enable_pv_grub;
|
|
||||||
|
|
||||||
if test "x$enableval" = "xyes"
|
|
||||||
then :
|
|
||||||
|
|
||||||
|
|
||||||
grub=y
|
|
||||||
STUBDOM_TARGETS="$STUBDOM_TARGETS grub"
|
|
||||||
STUBDOM_BUILD="$STUBDOM_BUILD pv-grub"
|
|
||||||
STUBDOM_INSTALL="$STUBDOM_INSTALL install-grub"
|
|
||||||
STUBDOM_UNINSTALL="$STUBDOM_UNINSTALL install-grub"
|
|
||||||
|
|
||||||
|
|
||||||
else $as_nop
|
|
||||||
|
|
||||||
if test "x$enableval" = "xno"
|
|
||||||
then :
|
|
||||||
|
|
||||||
|
|
||||||
grub=n
|
|
||||||
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
else $as_nop
|
|
||||||
|
|
||||||
|
|
||||||
grub=n
|
|
||||||
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Check whether --enable-xenstore-stubdom was given.
|
# Check whether --enable-xenstore-stubdom was given.
|
||||||
if test ${enable_xenstore_stubdom+y}
|
if test ${enable_xenstore_stubdom+y}
|
||||||
then :
|
then :
|
||||||
@@ -4137,23 +4089,6 @@ LWIP_VERSION="1.3.0"
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
if test "x$GRUB_URL" = "x"
|
|
||||||
then :
|
|
||||||
|
|
||||||
if test "x$extfiles" = "xy"
|
|
||||||
then :
|
|
||||||
GRUB_URL=\$\(XEN_EXTFILES_URL\)
|
|
||||||
else $as_nop
|
|
||||||
GRUB_URL="https://alpha.gnu.org/gnu/grub"
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
GRUB_VERSION="0.97"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if test "x$GMP_URL" = "x"
|
if test "x$GMP_URL" = "x"
|
||||||
then :
|
then :
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ m4_include([../m4/depends.m4])
|
|||||||
m4_include([../m4/fetcher.m4])
|
m4_include([../m4/fetcher.m4])
|
||||||
|
|
||||||
# Enable/disable stub domains
|
# Enable/disable stub domains
|
||||||
AX_STUBDOM_DEFAULT_DISABLE([pv-grub], [grub])
|
|
||||||
AX_STUBDOM_DEFAULT_ENABLE([xenstore-stubdom], [xenstore])
|
AX_STUBDOM_DEFAULT_ENABLE([xenstore-stubdom], [xenstore])
|
||||||
AX_STUBDOM_DEFAULT_ENABLE([xenstorepvh-stubdom], [xenstorepvh])
|
AX_STUBDOM_DEFAULT_ENABLE([xenstorepvh-stubdom], [xenstorepvh])
|
||||||
AX_STUBDOM_CONDITIONAL([vtpm-stubdom], [vtpm])
|
AX_STUBDOM_CONDITIONAL([vtpm-stubdom], [vtpm])
|
||||||
@@ -43,7 +42,6 @@ AX_STUBDOM_LIB([ZLIB], [zlib], [1.2.3])
|
|||||||
AX_STUBDOM_LIB([LIBPCI], [libpci], [2.2.9], [https://mirrors.edge.kernel.org/pub/software/utils/pciutils])
|
AX_STUBDOM_LIB([LIBPCI], [libpci], [2.2.9], [https://mirrors.edge.kernel.org/pub/software/utils/pciutils])
|
||||||
AX_STUBDOM_LIB([NEWLIB], [newlib], [1.16.0], [https://sourceware.org/ftp/newlib])
|
AX_STUBDOM_LIB([NEWLIB], [newlib], [1.16.0], [https://sourceware.org/ftp/newlib])
|
||||||
AX_STUBDOM_LIB([LWIP], [lwip], [1.3.0], [https://download.savannah.gnu.org/releases/lwip])
|
AX_STUBDOM_LIB([LWIP], [lwip], [1.3.0], [https://download.savannah.gnu.org/releases/lwip])
|
||||||
AX_STUBDOM_LIB([GRUB], [grub], [0.97], [https://alpha.gnu.org/gnu/grub])
|
|
||||||
AX_STUBDOM_LIB([GMP], [libgmp], [4.3.2], [https://gmplib.org/download/gmp/archive])
|
AX_STUBDOM_LIB([GMP], [libgmp], [4.3.2], [https://gmplib.org/download/gmp/archive])
|
||||||
AX_STUBDOM_LIB([POLARSSL], [polarssl], [1.1.4])
|
AX_STUBDOM_LIB([POLARSSL], [polarssl], [1.1.4])
|
||||||
AX_STUBDOM_LIB([TPMEMU], [berlios tpm emulator], [0.7.4])
|
AX_STUBDOM_LIB([TPMEMU], [berlios tpm emulator], [0.7.4])
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,13 +0,0 @@
|
|||||||
diff --git a/stage2/stage2.c b/stage2/stage2.c
|
|
||||||
index 9d9fcc3..8353a3b 100644
|
|
||||||
--- a/stage2/stage2.c
|
|
||||||
+++ b/stage2/stage2.c
|
|
||||||
@@ -395,7 +395,7 @@ restart:
|
|
||||||
pressed.
|
|
||||||
This avoids polling (relevant in the grub-shell and later on
|
|
||||||
in grub if interrupt driven I/O is done). */
|
|
||||||
- if (checkkey () >= 0 || grub_timeout < 0)
|
|
||||||
+ if (checkkey () > 0 || grub_timeout < 0)
|
|
||||||
{
|
|
||||||
/* Key was pressed, show which entry is selected before GETKEY,
|
|
||||||
since we're comming in here also on GRUB_TIMEOUT == -1 and
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
2006-01-05 Otavio Salvador <otavio@debian.org>
|
|
||||||
|
|
||||||
* Rediff.
|
|
||||||
|
|
||||||
2005-16-10 Samuel Thibault <samuel.thibault@ens-lyon.org>
|
|
||||||
|
|
||||||
* docs/grub.texi: Added print command description.
|
|
||||||
* stage2/builtins.c(print_func): New function.
|
|
||||||
(builtin_print): New variable.
|
|
||||||
(builtin_table): Added builtin_print in table.
|
|
||||||
|
|
||||||
Debian Status Following:
|
|
||||||
Added by: Otavio Salvador
|
|
||||||
Date: 2006-01-05
|
|
||||||
|
|
||||||
diff -Nur grub-0.97-bkp/stage2/builtins.c grub-0.97/stage2/builtins.c
|
|
||||||
--- grub-0.97-bkp/stage2/builtins.c 2006-01-05 10:59:05.550350040 -0200
|
|
||||||
+++ grub-0.97/stage2/builtins.c 2006-01-05 11:19:28.422445224 -0200
|
|
||||||
@@ -2323,6 +2323,25 @@
|
|
||||||
"Probe I/O ports used for the drive DRIVE."
|
|
||||||
};
|
|
||||||
|
|
||||||
+/* print */
|
|
||||||
+static int
|
|
||||||
+print_func (char *arg, int flags)
|
|
||||||
+{
|
|
||||||
+ printf("%s\n", arg);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct builtin builtin_print =
|
|
||||||
+{
|
|
||||||
+ "print",
|
|
||||||
+ print_func,
|
|
||||||
+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_NO_ECHO,
|
|
||||||
+ "print [MESSAGE ...]",
|
|
||||||
+ "Print MESSAGE."
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+
|
|
||||||
|
|
||||||
/* kernel */
|
|
||||||
static int
|
|
||||||
@@ -4848,6 +4867,7 @@
|
|
||||||
&builtin_parttype,
|
|
||||||
&builtin_password,
|
|
||||||
&builtin_pause,
|
|
||||||
+ &builtin_print,
|
|
||||||
#ifdef GRUB_UTIL
|
|
||||||
&builtin_quit,
|
|
||||||
#endif /* GRUB_UTIL */
|
|
||||||
@@ -1,186 +0,0 @@
|
|||||||
Index: grub/stage2/builtins.c
|
|
||||||
===================================================================
|
|
||||||
--- grub.orig/stage2/builtins.c 2008-06-02 18:06:08.942580000 +0100
|
|
||||||
+++ grub/stage2/builtins.c 2008-06-06 18:35:07.548390000 +0100
|
|
||||||
@@ -86,6 +86,10 @@
|
|
||||||
inside other functions. */
|
|
||||||
static int configfile_func (char *arg, int flags);
|
|
||||||
|
|
||||||
+static int savedefault_helper (char *arg, int flags);
|
|
||||||
+
|
|
||||||
+static int savedefault_shell (char *arg, int flags);
|
|
||||||
+
|
|
||||||
/* Initialize the data for builtins. */
|
|
||||||
void
|
|
||||||
init_builtins (void)
|
|
||||||
@@ -3512,7 +3516,109 @@
|
|
||||||
static int
|
|
||||||
savedefault_func (char *arg, int flags)
|
|
||||||
{
|
|
||||||
-#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
|
|
||||||
+#if !defined(SUPPORT_DISKLESS)
|
|
||||||
+ #if !defined(GRUB_UTIL)
|
|
||||||
+ return savedefault_helper(arg, flags);
|
|
||||||
+ #else
|
|
||||||
+ return savedefault_shell(arg, flags);
|
|
||||||
+ #endif
|
|
||||||
+#else /* !SUPPORT_DISKLESS */
|
|
||||||
+ errnum = ERR_UNRECOGNIZED;
|
|
||||||
+ return 1;
|
|
||||||
+#endif /* !SUPPORT_DISKLESS */
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL)
|
|
||||||
+/* savedefault_shell */
|
|
||||||
+static int
|
|
||||||
+savedefault_shell(char *arg, int flags)
|
|
||||||
+ {
|
|
||||||
+ int once_only = 0;
|
|
||||||
+ int new_default;
|
|
||||||
+ int curr_default = -1;
|
|
||||||
+ int curr_prev_default = -1;
|
|
||||||
+ int new_prev_default = -1;
|
|
||||||
+ FILE *fp;
|
|
||||||
+ size_t bytes = 10;
|
|
||||||
+ char line[bytes];
|
|
||||||
+ char *default_file = (char *) DEFAULT_FILE_BUF;
|
|
||||||
+ char buf[bytes];
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ while (1)
|
|
||||||
+ {
|
|
||||||
+ if (grub_memcmp ("--default=", arg, sizeof ("--default=") - 1) == 0)
|
|
||||||
+ {
|
|
||||||
+ char *p = arg + sizeof ("--default=") - 1;
|
|
||||||
+ if (! safe_parse_maxint (&p, &new_default))
|
|
||||||
+ return 1;
|
|
||||||
+ arg = skip_to (0, arg);
|
|
||||||
+ }
|
|
||||||
+ else if (grub_memcmp ("--once", arg, sizeof ("--once") - 1) == 0)
|
|
||||||
+ {
|
|
||||||
+ once_only = 1;
|
|
||||||
+ arg = skip_to (0, arg);
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ *default_file = 0;
|
|
||||||
+ grub_strncat (default_file, config_file, DEFAULT_FILE_BUFLEN);
|
|
||||||
+ for (i = grub_strlen(default_file); i >= 0; i--)
|
|
||||||
+ if (default_file[i] == '/')
|
|
||||||
+ {
|
|
||||||
+ i++;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ default_file[i] = 0;
|
|
||||||
+ grub_strncat (default_file + i, "default", DEFAULT_FILE_BUFLEN - i);
|
|
||||||
+
|
|
||||||
+ if(!(fp = fopen(default_file,"r")))
|
|
||||||
+ {
|
|
||||||
+ errnum = ERR_READ;
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ fgets(line, bytes, fp);
|
|
||||||
+ fclose(fp);
|
|
||||||
+
|
|
||||||
+ sscanf(line, "%d:%d", &curr_prev_default, &curr_default);
|
|
||||||
+
|
|
||||||
+ if(curr_default != -1)
|
|
||||||
+ new_prev_default = curr_default;
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ if(curr_prev_default != -1)
|
|
||||||
+ new_prev_default = curr_prev_default;
|
|
||||||
+ else
|
|
||||||
+ new_prev_default = 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if(once_only)
|
|
||||||
+ sprintf(buf, "%d:%d", new_prev_default, new_default);
|
|
||||||
+ else
|
|
||||||
+ sprintf(buf, "%d", new_default);
|
|
||||||
+
|
|
||||||
+ if(!(fp = fopen(default_file,"w")))
|
|
||||||
+ {
|
|
||||||
+ errnum = ERR_READ;
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ fprintf(fp, buf);
|
|
||||||
+
|
|
||||||
+fail:
|
|
||||||
+ fclose(fp);
|
|
||||||
+ return errnum;
|
|
||||||
+}
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+/* savedefault_helper */
|
|
||||||
+static int
|
|
||||||
+savedefault_helper (char *arg, int flags)
|
|
||||||
+{
|
|
||||||
+#if !defined(SUPPORT_DISKLESS)
|
|
||||||
unsigned long tmp_drive = saved_drive;
|
|
||||||
unsigned long tmp_partition = saved_partition;
|
|
||||||
char *default_file = (char *) DEFAULT_FILE_BUF;
|
|
||||||
@@ -3588,22 +3694,26 @@
|
|
||||||
|
|
||||||
disk_read_hook = disk_read_savesect_func;
|
|
||||||
len = grub_read (buf, sizeof (buf));
|
|
||||||
+ buf[9]='\0';/* Make sure grub_strstr() below terminates */
|
|
||||||
disk_read_hook = 0;
|
|
||||||
grub_close ();
|
|
||||||
|
|
||||||
- if (len != sizeof (buf))
|
|
||||||
- {
|
|
||||||
- /* This is too small. Do not modify the file manually, please! */
|
|
||||||
- errnum = ERR_READ;
|
|
||||||
- goto fail;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
if (sector_count > 2)
|
|
||||||
{
|
|
||||||
/* Is this possible?! Too fragmented! */
|
|
||||||
errnum = ERR_FSYS_CORRUPT;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ char *tmp;
|
|
||||||
+ if((tmp = grub_strstr(buf, ":")) != NULL)
|
|
||||||
+ {
|
|
||||||
+ int f_len = grub_strlen(buf) - grub_strlen(tmp);
|
|
||||||
+ char *def;
|
|
||||||
+ buf[f_len] = '\0';
|
|
||||||
+ def = buf;
|
|
||||||
+ safe_parse_maxint (&def, &entryno);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/* Set up a string to be written. */
|
|
||||||
grub_memset (buf, '\n', sizeof (buf));
|
|
||||||
Index: grub/stage2/stage2.c
|
|
||||||
===================================================================
|
|
||||||
--- grub.orig/stage2/stage2.c 2008-06-02 18:06:08.858579000 +0100
|
|
||||||
+++ grub/stage2/stage2.c 2008-06-06 18:04:03.585354000 +0100
|
|
||||||
@@ -49,7 +49,8 @@
|
|
||||||
return 0;
|
|
||||||
#endif /* GRUB_UTIL */
|
|
||||||
|
|
||||||
- preset_menu_offset = 0;
|
|
||||||
+ if (preset_menu_offset)
|
|
||||||
+ return 0;
|
|
||||||
return preset_menu != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -934,7 +935,11 @@
|
|
||||||
len = grub_read (buf, sizeof (buf));
|
|
||||||
if (len > 0)
|
|
||||||
{
|
|
||||||
+ char *tmp;
|
|
||||||
buf[sizeof (buf) - 1] = 0;
|
|
||||||
+ if((tmp = grub_strstr(p, ":")) != NULL)
|
|
||||||
+ p = tmp + 1;
|
|
||||||
+
|
|
||||||
safe_parse_maxint (&p, &saved_entryno);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
|
|
||||||
Patch from Red Hat. See #463236, #463123.
|
|
||||||
|
|
||||||
Index: grub/stage2/fsys_ext2fs.c
|
|
||||||
===================================================================
|
|
||||||
--- grub.orig/stage2/fsys_ext2fs.c 2008-05-27 18:47:19.045183000 +0100
|
|
||||||
+++ grub/stage2/fsys_ext2fs.c 2008-05-27 19:09:21.293187000 +0100
|
|
||||||
@@ -79,7 +79,52 @@
|
|
||||||
__u32 s_rev_level; /* Revision level */
|
|
||||||
__u16 s_def_resuid; /* Default uid for reserved blocks */
|
|
||||||
__u16 s_def_resgid; /* Default gid for reserved blocks */
|
|
||||||
- __u32 s_reserved[235]; /* Padding to the end of the block */
|
|
||||||
+ /*
|
|
||||||
+ * These fields are for EXT2_DYNAMIC_REV superblocks only.
|
|
||||||
+ *
|
|
||||||
+ * Note: the difference between the compatible feature set and
|
|
||||||
+ * the incompatible feature set is that if there is a bit set
|
|
||||||
+ * in the incompatible feature set that the kernel doesn't
|
|
||||||
+ * know about, it should refuse to mount the filesystem.
|
|
||||||
+ *
|
|
||||||
+ * e2fsck's requirements are more strict; if it doesn't know
|
|
||||||
+ * about a feature in either the compatible or incompatible
|
|
||||||
+ * feature set, it must abort and not try to meddle with
|
|
||||||
+ * things it doesn't understand...
|
|
||||||
+ */
|
|
||||||
+ __u32 s_first_ino; /* First non-reserved inode */
|
|
||||||
+ __u16 s_inode_size; /* size of inode structure */
|
|
||||||
+ __u16 s_block_group_nr; /* block group # of this superblock */
|
|
||||||
+ __u32 s_feature_compat; /* compatible feature set */
|
|
||||||
+ __u32 s_feature_incompat; /* incompatible feature set */
|
|
||||||
+ __u32 s_feature_ro_compat; /* readonly-compatible feature set */
|
|
||||||
+ __u8 s_uuid[16]; /* 128-bit uuid for volume */
|
|
||||||
+ char s_volume_name[16]; /* volume name */
|
|
||||||
+ char s_last_mounted[64]; /* directory where last mounted */
|
|
||||||
+ __u32 s_algorithm_usage_bitmap; /* For compression */
|
|
||||||
+ /*
|
|
||||||
+ * Performance hints. Directory preallocation should only
|
|
||||||
+ * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on.
|
|
||||||
+ */
|
|
||||||
+ __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/
|
|
||||||
+ __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */
|
|
||||||
+ __u16 s_reserved_gdt_blocks;/* Per group table for online growth */
|
|
||||||
+ /*
|
|
||||||
+ * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set.
|
|
||||||
+ */
|
|
||||||
+ __u8 s_journal_uuid[16]; /* uuid of journal superblock */
|
|
||||||
+ __u32 s_journal_inum; /* inode number of journal file */
|
|
||||||
+ __u32 s_journal_dev; /* device number of journal file */
|
|
||||||
+ __u32 s_last_orphan; /* start of list of inodes to delete */
|
|
||||||
+ __u32 s_hash_seed[4]; /* HTREE hash seed */
|
|
||||||
+ __u8 s_def_hash_version; /* Default hash version to use */
|
|
||||||
+ __u8 s_jnl_backup_type; /* Default type of journal backup */
|
|
||||||
+ __u16 s_reserved_word_pad;
|
|
||||||
+ __u32 s_default_mount_opts;
|
|
||||||
+ __u32 s_first_meta_bg; /* First metablock group */
|
|
||||||
+ __u32 s_mkfs_time; /* When the filesystem was created */
|
|
||||||
+ __u32 s_jnl_blocks[17]; /* Backup of the journal inode */
|
|
||||||
+ __u32 s_reserved[172]; /* Padding to the end of the block */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ext2_group_desc
|
|
||||||
@@ -218,6 +263,9 @@
|
|
||||||
#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
|
|
||||||
#define EXT2_ADDR_PER_BLOCK_BITS(s) (log2(EXT2_ADDR_PER_BLOCK(s)))
|
|
||||||
|
|
||||||
+#define EXT2_INODE_SIZE(s) (SUPERBLOCK->s_inode_size)
|
|
||||||
+#define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
|
|
||||||
+
|
|
||||||
/* linux/ext2_fs.h */
|
|
||||||
#define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10)
|
|
||||||
/* kind of from ext2/super.c */
|
|
||||||
@@ -242,7 +290,14 @@
|
|
||||||
static __inline__ unsigned long
|
|
||||||
ffz (unsigned long word)
|
|
||||||
{
|
|
||||||
- __asm__ ("bsfl %1,%0"
|
|
||||||
+ __asm__ ("bsf"
|
|
||||||
+#ifdef __i386__
|
|
||||||
+ "l"
|
|
||||||
+#endif
|
|
||||||
+#ifdef __x86_64__
|
|
||||||
+ "q"
|
|
||||||
+#endif
|
|
||||||
+ " %1,%0"
|
|
||||||
: "=r" (word)
|
|
||||||
: "r" (~word));
|
|
||||||
return word;
|
|
||||||
@@ -553,7 +608,7 @@
|
|
||||||
gdp = GROUP_DESC;
|
|
||||||
ino_blk = gdp[desc].bg_inode_table +
|
|
||||||
(((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group))
|
|
||||||
- >> log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)));
|
|
||||||
+ >> log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK)));
|
|
||||||
#ifdef E2DEBUG
|
|
||||||
printf ("inode table fsblock=%d\n", ino_blk);
|
|
||||||
#endif /* E2DEBUG */
|
|
||||||
@@ -565,13 +620,12 @@
|
|
||||||
/* reset indirect blocks! */
|
|
||||||
mapblock2 = mapblock1 = -1;
|
|
||||||
|
|
||||||
- raw_inode = INODE +
|
|
||||||
- ((current_ino - 1)
|
|
||||||
- & (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode) - 1));
|
|
||||||
+ raw_inode = (struct ext2_inode *)((char *)INODE +
|
|
||||||
+ ((current_ino - 1) & (EXT2_INODES_PER_BLOCK (SUPERBLOCK) - 1)) *
|
|
||||||
+ EXT2_INODE_SIZE (SUPERBLOCK));
|
|
||||||
#ifdef E2DEBUG
|
|
||||||
printf ("ipb=%d, sizeof(inode)=%d\n",
|
|
||||||
- (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)),
|
|
||||||
- sizeof (struct ext2_inode));
|
|
||||||
+ EXT2_INODES_PER_BLOCK (SUPERBLOCK), EXT2_INODE_SIZE (SUPERBLOCK));
|
|
||||||
printf ("inode=%x, raw_inode=%x\n", INODE, raw_inode);
|
|
||||||
printf ("offset into inode table block=%d\n", (int) raw_inode - (int) INODE);
|
|
||||||
for (i = (unsigned char *) INODE; i <= (unsigned char *) raw_inode;
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
diff -urN grub-0.97.orig/stage2/fsys_ext2fs.c grub-0.97/stage2/fsys_ext2fs.c
|
|
||||||
--- grub-0.97.orig/stage2/fsys_ext2fs.c 2004-08-08 18:19:18.000000000 +0000
|
|
||||||
+++ grub-0.97/stage2/fsys_ext2fs.c 2008-09-16 19:31:15.000000000 +0000
|
|
||||||
@@ -254,7 +254,7 @@
|
|
||||||
{
|
|
||||||
int retval = 1;
|
|
||||||
|
|
||||||
- if ((((current_drive & 0x80) || (current_slice != 0))
|
|
||||||
+ if ((((current_slice != 0))
|
|
||||||
&& (current_slice != PC_SLICE_TYPE_EXT2FS)
|
|
||||||
&& (current_slice != PC_SLICE_TYPE_LINUX_RAID)
|
|
||||||
&& (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_EXT2FS))
|
|
||||||
diff -urN grub-0.97.orig/stage2/fsys_fat.c grub-0.97/stage2/fsys_fat.c
|
|
||||||
--- grub-0.97.orig/stage2/fsys_fat.c 2005-03-15 16:52:00.000000000 +0000
|
|
||||||
+++ grub-0.97/stage2/fsys_fat.c 2008-09-16 19:31:26.000000000 +0000
|
|
||||||
@@ -70,7 +70,7 @@
|
|
||||||
__u32 magic, first_fat;
|
|
||||||
|
|
||||||
/* Check partition type for harddisk */
|
|
||||||
- if (((current_drive & 0x80) || (current_slice != 0))
|
|
||||||
+ if (((current_slice != 0))
|
|
||||||
&& ! IS_PC_SLICE_TYPE_FAT (current_slice)
|
|
||||||
&& (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_MSDOS)))
|
|
||||||
return 0;
|
|
||||||
diff -urN grub-0.97.orig/stage2/fsys_ffs.c grub-0.97/stage2/fsys_ffs.c
|
|
||||||
--- grub-0.97.orig/stage2/fsys_ffs.c 2003-07-09 11:45:52.000000000 +0000
|
|
||||||
+++ grub-0.97/stage2/fsys_ffs.c 2008-09-16 19:31:32.000000000 +0000
|
|
||||||
@@ -82,7 +82,7 @@
|
|
||||||
{
|
|
||||||
int retval = 1;
|
|
||||||
|
|
||||||
- if ((((current_drive & 0x80) || (current_slice != 0))
|
|
||||||
+ if ((((current_slice != 0))
|
|
||||||
&& ! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_BSDFFS))
|
|
||||||
|| part_length < (SBLOCK + (SBSIZE / DEV_BSIZE))
|
|
||||||
|| !devread (SBLOCK, 0, SBSIZE, (char *) SUPERBLOCK)
|
|
||||||
diff -urN grub-0.97.orig/stage2/fsys_minix.c grub-0.97/stage2/fsys_minix.c
|
|
||||||
--- grub-0.97.orig/stage2/fsys_minix.c 2003-07-09 11:45:53.000000000 +0000
|
|
||||||
+++ grub-0.97/stage2/fsys_minix.c 2008-09-16 19:32:01.000000000 +0000
|
|
||||||
@@ -160,7 +160,7 @@
|
|
||||||
int
|
|
||||||
minix_mount (void)
|
|
||||||
{
|
|
||||||
- if (((current_drive & 0x80) || current_slice != 0)
|
|
||||||
+ if ((current_slice != 0)
|
|
||||||
&& ! IS_PC_SLICE_TYPE_MINIX (current_slice)
|
|
||||||
&& ! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_OTHER))
|
|
||||||
return 0; /* The partition is not of MINIX type */
|
|
||||||
diff -urN grub-0.97.orig/stage2/fsys_ufs2.c grub-0.97/stage2/fsys_ufs2.c
|
|
||||||
--- grub-0.97.orig/stage2/fsys_ufs2.c 2004-06-19 12:17:52.000000000 +0000
|
|
||||||
+++ grub-0.97/stage2/fsys_ufs2.c 2008-09-16 19:32:32.000000000 +0000
|
|
||||||
@@ -87,7 +87,7 @@
|
|
||||||
sblockloc = -1;
|
|
||||||
type = 0;
|
|
||||||
|
|
||||||
- if (! (((current_drive & 0x80) || (current_slice != 0))
|
|
||||||
+ if (! (((current_slice != 0))
|
|
||||||
&& ! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_BSDFFS)))
|
|
||||||
{
|
|
||||||
for (i = 0; sblock_try[i] != -1; ++i)
|
|
||||||
diff -urN grub-0.97.orig/stage2/fsys_vstafs.c grub-0.97/stage2/fsys_vstafs.c
|
|
||||||
--- grub-0.97.orig/stage2/fsys_vstafs.c 2003-07-09 11:45:53.000000000 +0000
|
|
||||||
+++ grub-0.97/stage2/fsys_vstafs.c 2008-09-16 19:32:39.000000000 +0000
|
|
||||||
@@ -47,7 +47,7 @@
|
|
||||||
{
|
|
||||||
int retval = 1;
|
|
||||||
|
|
||||||
- if( (((current_drive & 0x80) || (current_slice != 0))
|
|
||||||
+ if( (((current_slice != 0))
|
|
||||||
&& current_slice != PC_SLICE_TYPE_VSTAFS)
|
|
||||||
|| ! devread (0, 0, BLOCK_SIZE, (char *) FSYS_BUF)
|
|
||||||
|| FIRST_SECTOR->fs_magic != 0xDEADFACE)
|
|
||||||
@@ -1,474 +0,0 @@
|
|||||||
Index: grub-0.97/stage2/fsys_ext2fs.c
|
|
||||||
===================================================================
|
|
||||||
--- grub-0.97.orig/stage2/fsys_ext2fs.c
|
|
||||||
+++ grub-0.97/stage2/fsys_ext2fs.c
|
|
||||||
@@ -41,6 +41,7 @@ typedef __signed__ short __s16;
|
|
||||||
typedef unsigned short __u16;
|
|
||||||
typedef __signed__ int __s32;
|
|
||||||
typedef unsigned int __u32;
|
|
||||||
+typedef unsigned long long __u64;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Constants relative to the data blocks, from ext2_fs.h
|
|
||||||
@@ -51,7 +52,7 @@ typedef unsigned int __u32;
|
|
||||||
#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
|
|
||||||
#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
|
|
||||||
|
|
||||||
-/* include/linux/ext2_fs.h */
|
|
||||||
+/* lib/ext2fs/ext2_fs.h from e2fsprogs */
|
|
||||||
struct ext2_super_block
|
|
||||||
{
|
|
||||||
__u32 s_inodes_count; /* Inodes count */
|
|
||||||
@@ -61,9 +62,9 @@ struct ext2_super_block
|
|
||||||
__u32 s_free_inodes_count; /* Free inodes count */
|
|
||||||
__u32 s_first_data_block; /* First Data Block */
|
|
||||||
__u32 s_log_block_size; /* Block size */
|
|
||||||
- __s32 s_log_frag_size; /* Fragment size */
|
|
||||||
+ __s32 s_obso_log_frag_size; /* Obsoleted Fragment size */
|
|
||||||
__u32 s_blocks_per_group; /* # Blocks per group */
|
|
||||||
- __u32 s_frags_per_group; /* # Fragments per group */
|
|
||||||
+ __u32 s_obso_frags_per_group; /* Obsoleted Fragments per group */
|
|
||||||
__u32 s_inodes_per_group; /* # Inodes per group */
|
|
||||||
__u32 s_mtime; /* Mount time */
|
|
||||||
__u32 s_wtime; /* Write time */
|
|
||||||
@@ -72,7 +73,7 @@ struct ext2_super_block
|
|
||||||
__u16 s_magic; /* Magic signature */
|
|
||||||
__u16 s_state; /* File system state */
|
|
||||||
__u16 s_errors; /* Behaviour when detecting errors */
|
|
||||||
- __u16 s_pad;
|
|
||||||
+ __u16 s_minor_rev_level; /* minor revision level */
|
|
||||||
__u32 s_lastcheck; /* time of last check */
|
|
||||||
__u32 s_checkinterval; /* max. time between checks */
|
|
||||||
__u32 s_creator_os; /* OS */
|
|
||||||
@@ -119,15 +120,29 @@ struct ext2_super_block
|
|
||||||
__u32 s_hash_seed[4]; /* HTREE hash seed */
|
|
||||||
__u8 s_def_hash_version; /* Default hash version to use */
|
|
||||||
__u8 s_jnl_backup_type; /* Default type of journal backup */
|
|
||||||
- __u16 s_reserved_word_pad;
|
|
||||||
+ __u16 s_desc_size; /* size of group descriptor */
|
|
||||||
__u32 s_default_mount_opts;
|
|
||||||
__u32 s_first_meta_bg; /* First metablock group */
|
|
||||||
__u32 s_mkfs_time; /* When the filesystem was created */
|
|
||||||
__u32 s_jnl_blocks[17]; /* Backup of the journal inode */
|
|
||||||
- __u32 s_reserved[172]; /* Padding to the end of the block */
|
|
||||||
- };
|
|
||||||
+ /* 64bit desc support valid if EXT4_FEATURE_INCOMPAT_64BIT */
|
|
||||||
+ __u32 s_blocks_count_hi; /* Blocks count */
|
|
||||||
+ __u32 s_r_blocks_count_hi; /* Reserved blocks count */
|
|
||||||
+ __u32 s_free_blocks_count_hi; /* Free blocks count */
|
|
||||||
+ __u16 s_min_extra_isize; /* All inodes have at least # bytes */
|
|
||||||
+ __u16 s_max_extra_isize; /* New inodes should reverve # bytes */
|
|
||||||
+ __u32 s_flags; /* Miscellaneous flags */
|
|
||||||
+ __u16 s_raid_stride; /* Raid stride */
|
|
||||||
+ __u16 s_mmp_interval; /* # seconds to wait MMP checking */
|
|
||||||
+ __u64 s_mmp_block; /* Block for multi-mount protection */
|
|
||||||
+ __u32 s_raid_stripe_width; /* Blocks on all data disks (N*stride)*/
|
|
||||||
+ __u8 s_log_groups_per_flex;/* FLEX_BG group size*/
|
|
||||||
+ __u8 s_reserved_char_pad;
|
|
||||||
+ __u16 s_reserved_pad;
|
|
||||||
+ __u32 s_reserved[162]; /* Padding to the end of the block */
|
|
||||||
+};
|
|
||||||
|
|
||||||
-struct ext2_group_desc
|
|
||||||
+struct ext4_group_desc
|
|
||||||
{
|
|
||||||
__u32 bg_block_bitmap; /* Blocks bitmap block */
|
|
||||||
__u32 bg_inode_bitmap; /* Inodes bitmap block */
|
|
||||||
@@ -135,8 +150,18 @@ struct ext2_group_desc
|
|
||||||
__u16 bg_free_blocks_count; /* Free blocks count */
|
|
||||||
__u16 bg_free_inodes_count; /* Free inodes count */
|
|
||||||
__u16 bg_used_dirs_count; /* Directories count */
|
|
||||||
- __u16 bg_pad;
|
|
||||||
- __u32 bg_reserved[3];
|
|
||||||
+ __u16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */
|
|
||||||
+ __u32 bg_reserved[2]; /* Likely block/inode bitmap checksum */
|
|
||||||
+ __u16 bg_itable_unused; /* Unused inodes count */
|
|
||||||
+ __u16 bg_checksum; /* crc16(sb_uuid+group+desc) */
|
|
||||||
+ __u32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */
|
|
||||||
+ __u32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */
|
|
||||||
+ __u32 bg_inode_table_hi; /* Inodes table block MSB */
|
|
||||||
+ __u16 bg_free_blocks_count_hi;/* Free blocks count MSB */
|
|
||||||
+ __u16 bg_free_inodes_count_hi;/* Free inodes count MSB */
|
|
||||||
+ __u16 bg_used_dirs_count_hi; /* Directories count MSB */
|
|
||||||
+ __u16 bg_itable_unused_hi; /* Unused inodes count MSB */
|
|
||||||
+ __u32 bg_reserved2[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ext2_inode
|
|
||||||
@@ -174,22 +199,22 @@ struct ext2_inode
|
|
||||||
__u32 i_block[EXT2_N_BLOCKS]; /* 40: Pointers to blocks */
|
|
||||||
__u32 i_version; /* File version (for NFS) */
|
|
||||||
__u32 i_file_acl; /* File ACL */
|
|
||||||
- __u32 i_dir_acl; /* Directory ACL */
|
|
||||||
- __u32 i_faddr; /* Fragment address */
|
|
||||||
+ __u32 i_size_high;
|
|
||||||
+ __u32 i_obso_faddr; /* Obsoleted fragment address */
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
- __u8 l_i_frag; /* Fragment number */
|
|
||||||
- __u8 l_i_fsize; /* Fragment size */
|
|
||||||
- __u16 i_pad1;
|
|
||||||
- __u32 l_i_reserved2[2];
|
|
||||||
+ __u16 l_i_blocks_high; /* were l_i_reserved1 */
|
|
||||||
+ __u16 l_i_file_acl_high;
|
|
||||||
+ __u16 l_i_uid_high; /* these 2 fields */
|
|
||||||
+ __u16 l_i_gid_high; /* were reserved2[0] */
|
|
||||||
+ __u32 l_i_reserved2;
|
|
||||||
}
|
|
||||||
linux2;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
- __u8 h_i_frag; /* Fragment number */
|
|
||||||
- __u8 h_i_fsize; /* Fragment size */
|
|
||||||
+ __u16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
|
|
||||||
__u16 h_i_mode_high;
|
|
||||||
__u16 h_i_uid_high;
|
|
||||||
__u16 h_i_gid_high;
|
|
||||||
@@ -198,16 +223,36 @@ struct ext2_inode
|
|
||||||
hurd2;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
- __u8 m_i_frag; /* Fragment number */
|
|
||||||
- __u8 m_i_fsize; /* Fragment size */
|
|
||||||
- __u16 m_pad1;
|
|
||||||
+ __u16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
|
|
||||||
+ __u16 m_i_file_acl_high;
|
|
||||||
__u32 m_i_reserved2[2];
|
|
||||||
}
|
|
||||||
masix2;
|
|
||||||
}
|
|
||||||
osd2; /* OS dependent 2 */
|
|
||||||
+ __u16 i_extra_isize;
|
|
||||||
+ __u16 i_pad1;
|
|
||||||
+ __u32 i_ctime_extra; /* extra Change time (nsec << 2 | epoch) */
|
|
||||||
+ __u32 i_mtime_extra; /* extra Modification time(nsec << 2 | epoch) */
|
|
||||||
+ __u32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */
|
|
||||||
+ __u32 i_crtime; /* File Creation time */
|
|
||||||
+ __u32 i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
|
|
||||||
+ __u32 i_version_hi; /* high 32 bits for 64-bit version */
|
|
||||||
};
|
|
||||||
|
|
||||||
+#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */
|
|
||||||
+#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 /* grub not supported*/
|
|
||||||
+#define EXT4_FEATURE_INCOMPAT_MMP 0x0100
|
|
||||||
+#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
|
|
||||||
+
|
|
||||||
+#define EXT4_HAS_INCOMPAT_FEATURE(sb,mask) \
|
|
||||||
+ ( sb->s_feature_incompat & mask )
|
|
||||||
+
|
|
||||||
+#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
|
|
||||||
+#define EXT4_HUGE_FILE_FL 0x00040000 /* Set to each huge file */
|
|
||||||
+
|
|
||||||
+#define EXT4_MIN_DESC_SIZE 32
|
|
||||||
+
|
|
||||||
/* linux/limits.h */
|
|
||||||
#define NAME_MAX 255 /* # chars in a file name */
|
|
||||||
|
|
||||||
@@ -225,6 +270,57 @@ struct ext2_dir_entry
|
|
||||||
char name[EXT2_NAME_LEN]; /* File name */
|
|
||||||
};
|
|
||||||
|
|
||||||
+/* linux/ext4_fs_extents.h */
|
|
||||||
+/* This is the extent on-disk structure.
|
|
||||||
+ * It's used at the bottom of the tree.
|
|
||||||
+ */
|
|
||||||
+struct ext4_extent
|
|
||||||
+ {
|
|
||||||
+ __u32 ee_block; /* first logical block extent covers */
|
|
||||||
+ __u16 ee_len; /* number of blocks covered by extent */
|
|
||||||
+ __u16 ee_start_hi; /* high 16 bits of physical block */
|
|
||||||
+ __u32 ee_start_lo; /* low 32 bits of physical block */
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * This is index on-disk structure.
|
|
||||||
+ * It's used at all the levels except the bottom.
|
|
||||||
+ */
|
|
||||||
+struct ext4_extent_idx
|
|
||||||
+ {
|
|
||||||
+ __u32 ei_block; /* index covers logical blocks from 'block' */
|
|
||||||
+ __u32 ei_leaf_lo; /* pointer to the physical block of the next *
|
|
||||||
+ * level. leaf or next index could be there */
|
|
||||||
+ __u16 ei_leaf_hi; /* high 16 bits of physical block */
|
|
||||||
+ __u16 ei_unused;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Each block (leaves and indexes), even inode-stored has header.
|
|
||||||
+ */
|
|
||||||
+struct ext4_extent_header
|
|
||||||
+ {
|
|
||||||
+ __u16 eh_magic; /* probably will support different formats */
|
|
||||||
+ __u16 eh_entries; /* number of valid entries */
|
|
||||||
+ __u16 eh_max; /* capacity of store in entries */
|
|
||||||
+ __u16 eh_depth; /* has tree real underlying blocks? */
|
|
||||||
+ __u32 eh_generation; /* generation of the tree */
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+#define EXT4_EXT_MAGIC (0xf30a)
|
|
||||||
+#define EXT_FIRST_EXTENT(__hdr__) \
|
|
||||||
+ ((struct ext4_extent *) (((char *) (__hdr__)) + \
|
|
||||||
+ sizeof(struct ext4_extent_header)))
|
|
||||||
+#define EXT_FIRST_INDEX(__hdr__) \
|
|
||||||
+ ((struct ext4_extent_idx *) (((char *) (__hdr__)) + \
|
|
||||||
+ sizeof(struct ext4_extent_header)))
|
|
||||||
+#define EXT_LAST_EXTENT(__hdr__) \
|
|
||||||
+ (EXT_FIRST_EXTENT((__hdr__)) + (__u16)((__hdr__)->eh_entries) - 1)
|
|
||||||
+#define EXT_LAST_INDEX(__hdr__) \
|
|
||||||
+ (EXT_FIRST_INDEX((__hdr__)) + (__u16)((__hdr__)->eh_entries) - 1)
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+
|
|
||||||
/* linux/ext2fs.h */
|
|
||||||
/*
|
|
||||||
* EXT2_DIR_PAD defines the directory entries boundaries
|
|
||||||
@@ -271,8 +367,17 @@ struct ext2_dir_entry
|
|
||||||
/* kind of from ext2/super.c */
|
|
||||||
#define EXT2_BLOCK_SIZE(s) (1 << EXT2_BLOCK_SIZE_BITS(s))
|
|
||||||
/* linux/ext2fs.h */
|
|
||||||
+/* sizeof(struct ext2_group_desc) is changed in ext4
|
|
||||||
+ * in kernel code, ext2/3 uses sizeof(struct ext2_group_desc) to calculate
|
|
||||||
+ * number of desc per block, while ext4 uses superblock->s_desc_size in stead
|
|
||||||
+ * superblock->s_desc_size is not available in ext2/3
|
|
||||||
+ * */
|
|
||||||
+#define EXT2_DESC_SIZE(s) \
|
|
||||||
+ (EXT4_HAS_INCOMPAT_FEATURE(s,EXT4_FEATURE_INCOMPAT_64BIT)? \
|
|
||||||
+ s->s_desc_size : EXT4_MIN_DESC_SIZE)
|
|
||||||
#define EXT2_DESC_PER_BLOCK(s) \
|
|
||||||
- (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
|
|
||||||
+ (EXT2_BLOCK_SIZE(s) / EXT2_DESC_SIZE(s))
|
|
||||||
+
|
|
||||||
/* linux/stat.h */
|
|
||||||
#define S_IFMT 00170000
|
|
||||||
#define S_IFLNK 0120000
|
|
||||||
@@ -434,6 +539,122 @@ ext2fs_block_map (int logical_block)
|
|
||||||
[logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
|
|
||||||
}
|
|
||||||
|
|
||||||
+/* extent binary search index
|
|
||||||
+ * find closest index in the current level extent tree
|
|
||||||
+ * kind of from ext4_ext_binsearch_idx in ext4/extents.c
|
|
||||||
+ */
|
|
||||||
+static struct ext4_extent_idx*
|
|
||||||
+ext4_ext_binsearch_idx(struct ext4_extent_header* eh, int logical_block)
|
|
||||||
+{
|
|
||||||
+ struct ext4_extent_idx *r, *l, *m;
|
|
||||||
+ l = EXT_FIRST_INDEX(eh) + 1;
|
|
||||||
+ r = EXT_LAST_INDEX(eh);
|
|
||||||
+ while (l <= r)
|
|
||||||
+ {
|
|
||||||
+ m = l + (r - l) / 2;
|
|
||||||
+ if (logical_block < m->ei_block)
|
|
||||||
+ r = m - 1;
|
|
||||||
+ else
|
|
||||||
+ l = m + 1;
|
|
||||||
+ }
|
|
||||||
+ return (struct ext4_extent_idx*)(l - 1);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/* extent binary search
|
|
||||||
+ * find closest extent in the leaf level
|
|
||||||
+ * kind of from ext4_ext_binsearch in ext4/extents.c
|
|
||||||
+ */
|
|
||||||
+static struct ext4_extent*
|
|
||||||
+ext4_ext_binsearch(struct ext4_extent_header* eh, int logical_block)
|
|
||||||
+{
|
|
||||||
+ struct ext4_extent *r, *l, *m;
|
|
||||||
+ l = EXT_FIRST_EXTENT(eh) + 1;
|
|
||||||
+ r = EXT_LAST_EXTENT(eh);
|
|
||||||
+ while (l <= r)
|
|
||||||
+ {
|
|
||||||
+ m = l + (r - l) / 2;
|
|
||||||
+ if (logical_block < m->ee_block)
|
|
||||||
+ r = m - 1;
|
|
||||||
+ else
|
|
||||||
+ l = m + 1;
|
|
||||||
+ }
|
|
||||||
+ return (struct ext4_extent*)(l - 1);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/* Maps extents enabled logical block into physical block via an inode.
|
|
||||||
+ * EXT4_HUGE_FILE_FL should be checked before calling this.
|
|
||||||
+ */
|
|
||||||
+static int
|
|
||||||
+ext4fs_block_map (int logical_block)
|
|
||||||
+{
|
|
||||||
+ struct ext4_extent_header *eh;
|
|
||||||
+ struct ext4_extent *ex, *extent;
|
|
||||||
+ struct ext4_extent_idx *ei, *index;
|
|
||||||
+ int depth;
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+#ifdef E2DEBUG
|
|
||||||
+ unsigned char *i;
|
|
||||||
+ for (i = (unsigned char *) INODE;
|
|
||||||
+ i < ((unsigned char *) INODE + sizeof (struct ext2_inode));
|
|
||||||
+ i++)
|
|
||||||
+ {
|
|
||||||
+ printf ("%c", "0123456789abcdef"[*i >> 4]);
|
|
||||||
+ printf ("%c", "0123456789abcdef"[*i % 16]);
|
|
||||||
+ if (!((i + 1 - (unsigned char *) INODE) % 16))
|
|
||||||
+ {
|
|
||||||
+ printf ("\n");
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ printf (" ");
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ printf ("logical block %d\n", logical_block);
|
|
||||||
+#endif /* E2DEBUG */
|
|
||||||
+ eh = (struct ext4_extent_header*)INODE->i_block;
|
|
||||||
+ if (eh->eh_magic != EXT4_EXT_MAGIC)
|
|
||||||
+ {
|
|
||||||
+ errnum = ERR_FSYS_CORRUPT;
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ while((depth = eh->eh_depth) != 0)
|
|
||||||
+ { /* extent index */
|
|
||||||
+ if (eh->eh_magic != EXT4_EXT_MAGIC)
|
|
||||||
+ {
|
|
||||||
+ errnum = ERR_FSYS_CORRUPT;
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ ei = ext4_ext_binsearch_idx(eh, logical_block);
|
|
||||||
+ if (ei->ei_leaf_hi)
|
|
||||||
+ {/* 64bit physical block number not supported */
|
|
||||||
+ errnum = ERR_FILELENGTH;
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ if (!ext2_rdfsb(ei->ei_leaf_lo, DATABLOCK1))
|
|
||||||
+ {
|
|
||||||
+ errnum = ERR_FSYS_CORRUPT;
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ eh = (struct ext4_extent_header*)DATABLOCK1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* depth==0, we come to the leaf */
|
|
||||||
+ ex = ext4_ext_binsearch(eh, logical_block);
|
|
||||||
+ if (ex->ee_start_hi)
|
|
||||||
+ {/* 64bit physical block number not supported */
|
|
||||||
+ errnum = ERR_FILELENGTH;
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ if ((ex->ee_block + ex->ee_len) < logical_block)
|
|
||||||
+ {
|
|
||||||
+ errnum = ERR_FSYS_CORRUPT;
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ return ex->ee_start_lo + logical_block - ex->ee_block;
|
|
||||||
+
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/* preconditions: all preconds of ext2fs_block_map */
|
|
||||||
int
|
|
||||||
ext2fs_read (char *buf, int len)
|
|
||||||
@@ -468,6 +689,11 @@ ext2fs_read (char *buf, int len)
|
|
||||||
/* find the (logical) block component of our location */
|
|
||||||
logical_block = filepos >> EXT2_BLOCK_SIZE_BITS (SUPERBLOCK);
|
|
||||||
offset = filepos & (EXT2_BLOCK_SIZE (SUPERBLOCK) - 1);
|
|
||||||
+ /* map extents enabled logical block number to physical fs on-disk block number */
|
|
||||||
+ if (EXT4_HAS_INCOMPAT_FEATURE(SUPERBLOCK,EXT4_FEATURE_INCOMPAT_EXTENTS)
|
|
||||||
+ && INODE->i_flags & EXT4_EXTENTS_FL)
|
|
||||||
+ map = ext4fs_block_map (logical_block);
|
|
||||||
+ else
|
|
||||||
map = ext2fs_block_map (logical_block);
|
|
||||||
#ifdef E2DEBUG
|
|
||||||
printf ("map=%d\n", map);
|
|
||||||
@@ -552,7 +778,7 @@ ext2fs_dir (char *dirname)
|
|
||||||
int desc; /* index within that group */
|
|
||||||
int ino_blk; /* fs pointer of the inode's information */
|
|
||||||
int str_chk = 0; /* used to hold the results of a string compare */
|
|
||||||
- struct ext2_group_desc *gdp;
|
|
||||||
+ struct ext4_group_desc *ext4_gdp;
|
|
||||||
struct ext2_inode *raw_inode; /* inode info corresponding to current_ino */
|
|
||||||
|
|
||||||
char linkbuf[PATH_MAX]; /* buffer for following symbolic links */
|
|
||||||
@@ -598,8 +824,15 @@ ext2fs_dir (char *dirname)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
- gdp = GROUP_DESC;
|
|
||||||
- ino_blk = gdp[desc].bg_inode_table +
|
|
||||||
+ ext4_gdp = (struct ext4_group_desc *)( (__u8*)GROUP_DESC +
|
|
||||||
+ desc * EXT2_DESC_SIZE(SUPERBLOCK));
|
|
||||||
+ if (EXT4_HAS_INCOMPAT_FEATURE(SUPERBLOCK, EXT4_FEATURE_INCOMPAT_64BIT)
|
|
||||||
+ && (! ext4_gdp->bg_inode_table_hi))
|
|
||||||
+ {/* 64bit itable not supported */
|
|
||||||
+ errnum = ERR_FILELENGTH;
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ ino_blk = ext4_gdp->bg_inode_table +
|
|
||||||
(((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group))
|
|
||||||
>> log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK)));
|
|
||||||
#ifdef E2DEBUG
|
|
||||||
@@ -676,7 +909,10 @@ ext2fs_dir (char *dirname)
|
|
||||||
}
|
|
||||||
linkbuf[filemax + len] = '\0';
|
|
||||||
|
|
||||||
- /* Read the symlink data. */
|
|
||||||
+ /* Read the symlink data.
|
|
||||||
+ * Slow symlink is extents enabled
|
|
||||||
+ * But since grub_read invokes ext2fs_read, nothing to change here
|
|
||||||
+ */
|
|
||||||
if (! ext2_is_fast_symlink ())
|
|
||||||
{
|
|
||||||
/* Read the necessary blocks, and reset the file pointer. */
|
|
||||||
@@ -687,7 +923,9 @@ ext2fs_dir (char *dirname)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
- /* Copy the data directly from the inode. */
|
|
||||||
+ /* Copy the data directly from the inode.
|
|
||||||
+ * Fast symlink is not extents enabled
|
|
||||||
+ */
|
|
||||||
len = filemax;
|
|
||||||
memmove (linkbuf, (char *) INODE->i_block, len);
|
|
||||||
}
|
|
||||||
@@ -721,6 +959,13 @@ ext2fs_dir (char *dirname)
|
|
||||||
errnum = ERR_BAD_FILETYPE;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
+ /* if file is too large, just stop and report an error*/
|
|
||||||
+ if ( (INODE->i_flags & EXT4_HUGE_FILE_FL) && !(INODE->i_size_high))
|
|
||||||
+ {
|
|
||||||
+ /* file too large, stop reading */
|
|
||||||
+ errnum = ERR_FILELENGTH;
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
filemax = (INODE->i_size);
|
|
||||||
return 1;
|
|
||||||
@@ -775,17 +1020,28 @@ ext2fs_dir (char *dirname)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* else, find the (logical) block component of our location */
|
|
||||||
+ /* ext4 logical block number the same as ext2/3 */
|
|
||||||
blk = loc >> EXT2_BLOCK_SIZE_BITS (SUPERBLOCK);
|
|
||||||
|
|
||||||
/* we know which logical block of the directory entry we are looking
|
|
||||||
for, now we have to translate that to the physical (fs) block on
|
|
||||||
the disk */
|
|
||||||
+ /* map extents enabled logical block number to physical fs on-disk block number */
|
|
||||||
+ if (EXT4_HAS_INCOMPAT_FEATURE(SUPERBLOCK,EXT4_FEATURE_INCOMPAT_EXTENTS)
|
|
||||||
+ && INODE->i_flags & EXT4_EXTENTS_FL)
|
|
||||||
+ map = ext4fs_block_map (blk);
|
|
||||||
+ else
|
|
||||||
map = ext2fs_block_map (blk);
|
|
||||||
#ifdef E2DEBUG
|
|
||||||
printf ("fs block=%d\n", map);
|
|
||||||
#endif /* E2DEBUG */
|
|
||||||
mapblock2 = -1;
|
|
||||||
- if ((map < 0) || !ext2_rdfsb (map, DATABLOCK2))
|
|
||||||
+ if (map < 0)
|
|
||||||
+ {
|
|
||||||
+ *rest = ch;
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ if (!ext2_rdfsb (map, DATABLOCK2))
|
|
||||||
{
|
|
||||||
errnum = ERR_FSYS_CORRUPT;
|
|
||||||
*rest = ch;
|
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -1,45 +0,0 @@
|
|||||||
[ 1436s] ../grub-upstream/netboot/fsys_tftp.c:213: warning: operation on 'block' may be undefined
|
|
||||||
[ 1437s] ../grub-upstream/netboot/main.c:444: warning: operation on 'block' may be undefined
|
|
||||||
|
|
||||||
[ 1234s] E: xen sequence-point ../grub-upstream/netboot/fsys_tftp.c:213
|
|
||||||
[ 1234s] E: xen sequence-point ../grub-upstream/netboot/main.c:444
|
|
||||||
|
|
||||||
---
|
|
||||||
netboot/fsys_tftp.c | 5 ++++-
|
|
||||||
netboot/main.c | 5 ++++-
|
|
||||||
2 files changed, 8 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
Index: grub-0.97/netboot/fsys_tftp.c
|
|
||||||
===================================================================
|
|
||||||
--- grub-0.97.orig/netboot/fsys_tftp.c
|
|
||||||
+++ grub-0.97/netboot/fsys_tftp.c
|
|
||||||
@@ -209,8 +209,11 @@ buf_fill (int abort)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ((block || bcounter) && (block != prevblock + (unsigned short) 1))
|
|
||||||
+ {
|
|
||||||
+ block = prevblock;
|
|
||||||
/* Block order should be continuous */
|
|
||||||
- tp.u.ack.block = htons (block = prevblock);
|
|
||||||
+ tp.u.ack.block = htons (block);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/* Should be continuous. */
|
|
||||||
tp.opcode = abort ? htons (TFTP_ERROR) : htons (TFTP_ACK);
|
|
||||||
Index: grub-0.97/netboot/main.c
|
|
||||||
===================================================================
|
|
||||||
--- grub-0.97.orig/netboot/main.c
|
|
||||||
+++ grub-0.97/netboot/main.c
|
|
||||||
@@ -440,8 +440,11 @@ tftp (const char *name, int (*fnc) (unsi
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ((block || bcounter) && (block != prevblock + 1))
|
|
||||||
+ {
|
|
||||||
+ block = prevblock;
|
|
||||||
/* Block order should be continuous */
|
|
||||||
- tp.u.ack.block = htons (block = prevblock);
|
|
||||||
+ tp.u.ack.block = htons (block);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/* Should be continuous. */
|
|
||||||
tp.opcode = htons (TFTP_ACK);
|
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -1,88 +0,0 @@
|
|||||||
XEN_ROOT = $(CURDIR)/../..
|
|
||||||
|
|
||||||
include $(XEN_ROOT)/Config.mk
|
|
||||||
vpath %.c ../grub-upstream
|
|
||||||
|
|
||||||
BOOT=$(OBJ_DIR)/boot-$(XEN_TARGET_ARCH).o
|
|
||||||
|
|
||||||
DEF_CPPFLAGS += -I$(XEN_ROOT)/tools/libs/toollog/include
|
|
||||||
DEF_CPPFLAGS += -I$(XEN_ROOT)/tools/libs/ctrl/include
|
|
||||||
DEF_CPPFLAGS += -I$(XEN_ROOT)/tools/libs/guest/include
|
|
||||||
DEF_CPPFLAGS += -I$(XEN_ROOT)/tools/include -I.
|
|
||||||
DEF_CPPFLAGS += -I../grub-upstream/stage1
|
|
||||||
DEF_CPPFLAGS += -I../grub-upstream/stage2
|
|
||||||
DEF_CPPFLAGS += -I../grub-upstream/netboot
|
|
||||||
DEF_CPPFLAGS += -I$(XEN_ROOT)/tools/firmware/vgabios
|
|
||||||
DEF_CPPFLAGS += -DWITHOUT_LIBC_STUBS
|
|
||||||
DEF_CPPFLAGS += -DSUPPORT_NETBOOT
|
|
||||||
DEF_CPPFLAGS += -DSUPPORT_GRAPHICS
|
|
||||||
DEF_CPPFLAGS += -DSUPPORT_SERIAL
|
|
||||||
DEF_CPPFLAGS += -DPRESET_MENU_STRING='""'
|
|
||||||
DEF_CPPFLAGS += -DPACKAGE='"grubdom"' -DVERSION='"0.97"'
|
|
||||||
|
|
||||||
all: $(OBJ_DIR)/main.a
|
|
||||||
|
|
||||||
STAGE2_SOURCES=builtins.c char_io.c cmdline.c common.c console.c disk_io.c graphics.c gunzip.c md5.c serial.c stage2.c terminfo.c tparm.c
|
|
||||||
|
|
||||||
NETBOOT_SOURCES=fsys_tftp.c main.c misc.c
|
|
||||||
CPPFLAGS += -DFSYS_TFTP=1
|
|
||||||
|
|
||||||
STAGE2_SOURCES+=fsys_ext2fs.c
|
|
||||||
CPPFLAGS += -DFSYS_EXT2FS=1
|
|
||||||
|
|
||||||
STAGE2_SOURCES+=fsys_fat.c
|
|
||||||
CPPFLAGS += -DFSYS_FAT=1
|
|
||||||
|
|
||||||
STAGE2_SOURCES+=fsys_ffs.c
|
|
||||||
CPPFLAGS += -DFSYS_FFS=1
|
|
||||||
|
|
||||||
STAGE2_SOURCES+=fsys_iso9660.c
|
|
||||||
CPPFLAGS += -DFSYS_ISO9660=1
|
|
||||||
|
|
||||||
STAGE2_SOURCES+=fsys_jfs.c
|
|
||||||
CPPFLAGS += -DFSYS_JFS=1
|
|
||||||
|
|
||||||
STAGE2_SOURCES+=fsys_minix.c
|
|
||||||
CPPFLAGS += -DFSYS_MINIX=1
|
|
||||||
|
|
||||||
STAGE2_SOURCES+=fsys_reiserfs.c
|
|
||||||
CPPFLAGS += -DFSYS_REISERFS=1
|
|
||||||
|
|
||||||
STAGE2_SOURCES+=fsys_ufs2.c
|
|
||||||
CPPFLAGS += -DFSYS_UFS2=1
|
|
||||||
|
|
||||||
STAGE2_SOURCES+=fsys_vstafs.c
|
|
||||||
CPPFLAGS += -DFSYS_VSTAFS=1
|
|
||||||
|
|
||||||
STAGE2_SOURCES+=fsys_xfs.c
|
|
||||||
CPPFLAGS += -DFSYS_XFS=1
|
|
||||||
|
|
||||||
STAGE2_SOURCES:=$(addprefix stage2/,$(STAGE2_SOURCES))
|
|
||||||
NETBOOT_SOURCES:=$(addprefix netboot/,$(NETBOOT_SOURCES))
|
|
||||||
|
|
||||||
$(BOOT): DEF_CPPFLAGS+=-D__ASSEMBLY__
|
|
||||||
|
|
||||||
PV_GRUB_SOURCES = kexec.c mini-os.c
|
|
||||||
PV_GRUB_SOURCES += ../polarssl-$(XEN_TARGET_ARCH)/library/sha1.o
|
|
||||||
|
|
||||||
SOURCES = $(NETBOOT_SOURCES) $(STAGE2_SOURCES) $(PV_GRUB_SOURCES)
|
|
||||||
|
|
||||||
OBJS = $(addprefix $(OBJ_DIR)/,$(SOURCES:.c=.o))
|
|
||||||
|
|
||||||
$(OBJ_DIR)/dirs:
|
|
||||||
mkdir -p $(OBJ_DIR)/netboot $(OBJ_DIR)/stage2
|
|
||||||
touch $@
|
|
||||||
|
|
||||||
$(OBJS): $(OBJ_DIR)/dirs
|
|
||||||
|
|
||||||
$(OBJ_DIR)/main.a: $(BOOT) $(OBJS)
|
|
||||||
$(AR) cr $@ $^
|
|
||||||
|
|
||||||
$(OBJ_DIR)/%.o: %.c
|
|
||||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@
|
|
||||||
|
|
||||||
$(OBJ_DIR)/%.o: %.S
|
|
||||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -fr dirs *.a *.o stage2 netboot
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
#include <os.h>
|
|
||||||
#include <arch_limits.h>
|
|
||||||
#include <xen/arch-x86_32.h>
|
|
||||||
|
|
||||||
/* For simplicity, we keep all of this into just one data page */
|
|
||||||
.data
|
|
||||||
.globl _boot_page
|
|
||||||
_boot_page:
|
|
||||||
.align __PAGE_SIZE
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The following data is initialized from C code
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Pte of this page */
|
|
||||||
.globl _boot_page_entry
|
|
||||||
_boot_page_entry:
|
|
||||||
_boot_page_entry_lo:
|
|
||||||
.long 0
|
|
||||||
_boot_page_entry_hi:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
/* mmuext_op structure */
|
|
||||||
/* Set new page directory */
|
|
||||||
_boot_mmuext:
|
|
||||||
/* Op # */
|
|
||||||
.long MMUEXT_NEW_BASEPTR
|
|
||||||
|
|
||||||
/* MFN of target page table directory */
|
|
||||||
.globl _boot_pdmfn
|
|
||||||
_boot_pdmfn:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
/* Unused */
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
/* Unpin old page directory */
|
|
||||||
/* Op # */
|
|
||||||
.long MMUEXT_UNPIN_TABLE
|
|
||||||
|
|
||||||
/* MFN of old page table directory */
|
|
||||||
.globl _boot_oldpdmfn
|
|
||||||
_boot_oldpdmfn:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
/* Unused */
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
/* Target stack address, also target virtual address of this page */
|
|
||||||
.globl _boot_stack
|
|
||||||
_boot_stack:
|
|
||||||
.long 0
|
|
||||||
.long __KERNEL_SS
|
|
||||||
.globl _boot_target
|
|
||||||
_boot_target:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
/* Target start info */
|
|
||||||
.globl _boot_start_info
|
|
||||||
_boot_start_info:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
/* Target start address */
|
|
||||||
.globl _boot_start
|
|
||||||
_boot_start:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Boot target OS, does not return
|
|
||||||
*/
|
|
||||||
.globl _boot
|
|
||||||
_boot:
|
|
||||||
/* Project ourselves at the target place. */
|
|
||||||
movl _boot_target, %ebx
|
|
||||||
movl %ebx, %ebp /* also keep it in ebp for relative addressing */
|
|
||||||
movl _boot_page_entry_lo, %ecx
|
|
||||||
movl _boot_page_entry_hi, %edx
|
|
||||||
movl $2, %esi /* UVMF_INVLPG */
|
|
||||||
movl $__HYPERVISOR_update_va_mapping, %eax
|
|
||||||
int $0x82
|
|
||||||
testl %eax, %eax
|
|
||||||
jz 0f
|
|
||||||
ud2
|
|
||||||
|
|
||||||
0:
|
|
||||||
/* Go there. */
|
|
||||||
movl $(0f - _boot_page), %eax
|
|
||||||
movl _boot_target, %ebx
|
|
||||||
addl %ebx, %eax
|
|
||||||
jmpl *%eax
|
|
||||||
0:
|
|
||||||
|
|
||||||
/* Load target page table and unpin old page table. */
|
|
||||||
/* We shouldn't have any problem since in the new page table our page is
|
|
||||||
mapped at the same place. */
|
|
||||||
leal (_boot_mmuext-_boot_page)(%ebp), %ebx
|
|
||||||
movl $2, %ecx
|
|
||||||
xorl %edx, %edx
|
|
||||||
movl $0x7FF0, %esi /* DOMID_SELF */
|
|
||||||
movl $__HYPERVISOR_mmuext_op, %eax
|
|
||||||
int $0x82
|
|
||||||
testl %eax, %eax
|
|
||||||
jns 0f
|
|
||||||
ud2
|
|
||||||
|
|
||||||
0:
|
|
||||||
/* Initialize registers. */
|
|
||||||
lss (_boot_stack-_boot_page)(%ebp), %esp
|
|
||||||
movl (_boot_start_info-_boot_page)(%ebp), %esi
|
|
||||||
|
|
||||||
/* Jump! */
|
|
||||||
jmpl *(_boot_start-_boot_page)(%ebp)
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
#include <os.h>
|
|
||||||
#include <arch_limits.h>
|
|
||||||
#include <xen/arch-x86_64.h>
|
|
||||||
|
|
||||||
/* For simplicity, we keep all of this into just one data page */
|
|
||||||
.data
|
|
||||||
.globl _boot_page
|
|
||||||
_boot_page:
|
|
||||||
.align __PAGE_SIZE
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The following data is initialized from C code
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Pte of this page */
|
|
||||||
.globl _boot_page_entry
|
|
||||||
_boot_page_entry:
|
|
||||||
.quad 0
|
|
||||||
|
|
||||||
/* mmuext_op structure */
|
|
||||||
/* Set new page directory */
|
|
||||||
_boot_mmuext:
|
|
||||||
/* Op # */
|
|
||||||
.long MMUEXT_NEW_BASEPTR
|
|
||||||
.long 0 /* pad */
|
|
||||||
|
|
||||||
/* MFN of target page table directory */
|
|
||||||
.globl _boot_pdmfn
|
|
||||||
_boot_pdmfn:
|
|
||||||
.quad 0
|
|
||||||
|
|
||||||
/* Unused */
|
|
||||||
.quad 0
|
|
||||||
|
|
||||||
/* Unpin old page directory */
|
|
||||||
/* Op # */
|
|
||||||
.long MMUEXT_UNPIN_TABLE
|
|
||||||
.long 0 /* pad */
|
|
||||||
|
|
||||||
/* MFN of old page table directory */
|
|
||||||
.globl _boot_oldpdmfn
|
|
||||||
_boot_oldpdmfn:
|
|
||||||
.quad 0
|
|
||||||
|
|
||||||
/* Unused */
|
|
||||||
.quad 0
|
|
||||||
|
|
||||||
/* Target stack address, also target virtual address of this page */
|
|
||||||
.globl _boot_stack
|
|
||||||
_boot_stack:
|
|
||||||
.quad 0
|
|
||||||
.globl _boot_target
|
|
||||||
_boot_target:
|
|
||||||
.quad 0
|
|
||||||
|
|
||||||
/* Target start info */
|
|
||||||
.globl _boot_start_info
|
|
||||||
_boot_start_info:
|
|
||||||
.quad 0
|
|
||||||
|
|
||||||
/* Target start address */
|
|
||||||
.globl _boot_start
|
|
||||||
_boot_start:
|
|
||||||
.quad 0
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Boot target OS, does not return
|
|
||||||
*/
|
|
||||||
.globl _boot
|
|
||||||
_boot:
|
|
||||||
/* Project ourselves at the target place. */
|
|
||||||
movq _boot_target, %rdi
|
|
||||||
movq _boot_page_entry, %rsi
|
|
||||||
movq $2, %rdx /* UVMF_INVLPG */
|
|
||||||
movq $__HYPERVISOR_update_va_mapping, %rax
|
|
||||||
syscall
|
|
||||||
testq %rax, %rax
|
|
||||||
jz 0f
|
|
||||||
ud2
|
|
||||||
|
|
||||||
0:
|
|
||||||
/* Go there. */
|
|
||||||
movq $(0f - _boot_page), %rax
|
|
||||||
movq _boot_target, %rbx
|
|
||||||
addq %rbx, %rax
|
|
||||||
jmpq *%rax
|
|
||||||
0:
|
|
||||||
|
|
||||||
/* Load target page table and unpin old page table. */
|
|
||||||
/* We shouldn't have any problem since in the new page table our page is
|
|
||||||
mapped at the same place. */
|
|
||||||
leaq _boot_mmuext(%rip), %rdi
|
|
||||||
movq $2, %rsi
|
|
||||||
xorq %rdx, %rdx
|
|
||||||
movq $0x7FF0, %r10 /* DOMID_SELF */
|
|
||||||
movq $__HYPERVISOR_mmuext_op, %rax
|
|
||||||
syscall
|
|
||||||
testq %rax, %rax
|
|
||||||
jns 0f
|
|
||||||
ud2
|
|
||||||
|
|
||||||
0:
|
|
||||||
/* Initialize registers. */
|
|
||||||
movq _boot_stack(%rip), %rsp
|
|
||||||
movq _boot_start_info(%rip), %rsi
|
|
||||||
|
|
||||||
/* Jump! */
|
|
||||||
jmpq *_boot_start(%rip)
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#undef putchar
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <kernel.h>
|
|
||||||
#define debug _debug
|
|
||||||
#define grub_halt(a) do_exit()
|
|
||||||
#define printf grub_printf
|
|
||||||
void kexec(void *kernel, long kernel_size, void *module, long module_size, char *cmdline, unsigned long flags);
|
|
||||||
struct fbfront_dev *fb_open(void *fb, int width, int height, int depth);
|
|
||||||
void fb_close(void);
|
|
||||||
void pv_boot (void);
|
|
||||||
@@ -1,434 +0,0 @@
|
|||||||
/*
|
|
||||||
* This supports booting another PV kernel from Mini-OS
|
|
||||||
*
|
|
||||||
* The idea is to setup it using libxc, answer to day0 memory allocation
|
|
||||||
* requests, and using a trampoline boot page to switch to the new page table.
|
|
||||||
*
|
|
||||||
* The procedure of the boot page is:
|
|
||||||
* - map itself at the target position (that may overwrite some C stuff, but we
|
|
||||||
* do not care any more)
|
|
||||||
* - jump there
|
|
||||||
* - switch to the target page table
|
|
||||||
* - unpin the old page table
|
|
||||||
* - jump to the new kernel
|
|
||||||
*
|
|
||||||
* Samuel Thibault <Samuel.Thibault@eu.citrix.com>, May 2008
|
|
||||||
*/
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
#include <xenctrl.h>
|
|
||||||
#include <xenguest.h>
|
|
||||||
|
|
||||||
#include <kernel.h>
|
|
||||||
#include <console.h>
|
|
||||||
#include <os.h>
|
|
||||||
#include <blkfront.h>
|
|
||||||
#include <netfront.h>
|
|
||||||
#include <fbfront.h>
|
|
||||||
#include <tpmfront.h>
|
|
||||||
#include <shared.h>
|
|
||||||
#include <byteswap.h>
|
|
||||||
|
|
||||||
#include "mini-os.h"
|
|
||||||
|
|
||||||
#undef start_info
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#define DEBUG(fmt, ...) printk(fmt, ## __VA_ARGS__)
|
|
||||||
#else
|
|
||||||
#define DEBUG(fmt, ...) (void)0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Assembly boot page from boot.S */
|
|
||||||
extern void _boot_page;
|
|
||||||
extern pgentry_t _boot_page_entry;
|
|
||||||
extern unsigned long _boot_pdmfn;
|
|
||||||
extern unsigned long _boot_stack, _boot_target, _boot_start_info, _boot_start;
|
|
||||||
extern xen_pfn_t _boot_oldpdmfn;
|
|
||||||
extern void _boot(void);
|
|
||||||
|
|
||||||
static unsigned long *pages;
|
|
||||||
static unsigned long *pages_mfns;
|
|
||||||
static xen_pfn_t *pages_moved2pfns;
|
|
||||||
static unsigned long allocated;
|
|
||||||
|
|
||||||
int pin_table(xc_interface *xc_handle, unsigned int type, unsigned long mfn,
|
|
||||||
domid_t dom);
|
|
||||||
|
|
||||||
#define TPM_TAG_RQU_COMMAND 0xC1
|
|
||||||
#define TPM_ORD_Extend 20
|
|
||||||
|
|
||||||
struct pcr_extend_cmd {
|
|
||||||
uint16_t tag;
|
|
||||||
uint32_t size;
|
|
||||||
uint32_t ord;
|
|
||||||
|
|
||||||
uint32_t pcr;
|
|
||||||
unsigned char hash[20];
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct pcr_extend_rsp {
|
|
||||||
uint16_t tag;
|
|
||||||
uint32_t size;
|
|
||||||
uint32_t status;
|
|
||||||
|
|
||||||
unsigned char hash[20];
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
/* Not imported from polarssl's header since the prototype unhelpfully defines
|
|
||||||
* the input as unsigned char, which causes pointer type mismatches */
|
|
||||||
void sha1(const void *input, size_t ilen, unsigned char output[20]);
|
|
||||||
|
|
||||||
/* We need mfn to appear as target_pfn, so exchange with the MFN there */
|
|
||||||
static void do_exchange(struct xc_dom_image *dom, xen_pfn_t target_pfn, xen_pfn_t source_mfn)
|
|
||||||
{
|
|
||||||
xen_pfn_t source_pfn;
|
|
||||||
xen_pfn_t target_mfn;
|
|
||||||
|
|
||||||
for (source_pfn = 0; source_pfn < start_info_ptr->nr_pages; source_pfn++)
|
|
||||||
if (dom->pv_p2m[source_pfn] == source_mfn)
|
|
||||||
break;
|
|
||||||
ASSERT(source_pfn < start_info_ptr->nr_pages);
|
|
||||||
|
|
||||||
target_mfn = dom->pv_p2m[target_pfn];
|
|
||||||
|
|
||||||
/* Put target MFN at source PFN */
|
|
||||||
dom->pv_p2m[source_pfn] = target_mfn;
|
|
||||||
|
|
||||||
/* Put source MFN at target PFN */
|
|
||||||
dom->pv_p2m[target_pfn] = source_mfn;
|
|
||||||
}
|
|
||||||
|
|
||||||
int kexec_allocate(struct xc_dom_image *dom)
|
|
||||||
{
|
|
||||||
unsigned long new_allocated = dom->pfn_alloc_end - dom->rambase_pfn;
|
|
||||||
unsigned long i;
|
|
||||||
|
|
||||||
pages = realloc(pages, new_allocated * sizeof(*pages));
|
|
||||||
pages_mfns = realloc(pages_mfns, new_allocated * sizeof(*pages_mfns));
|
|
||||||
pages_moved2pfns = realloc(pages_moved2pfns, new_allocated * sizeof(*pages_moved2pfns));
|
|
||||||
for (i = allocated; i < new_allocated; i++) {
|
|
||||||
/* Exchange old page of PFN i with a newly allocated page. */
|
|
||||||
xen_pfn_t old_mfn = dom->pv_p2m[i];
|
|
||||||
xen_pfn_t new_pfn;
|
|
||||||
xen_pfn_t new_mfn;
|
|
||||||
|
|
||||||
pages[i] = alloc_page();
|
|
||||||
memset((void*) pages[i], 0, PAGE_SIZE);
|
|
||||||
new_pfn = PHYS_PFN(to_phys(pages[i]));
|
|
||||||
pages_mfns[i] = new_mfn = pfn_to_mfn(new_pfn);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If PFN of newly allocated page (new_pfn) is less then currently
|
|
||||||
* requested PFN (i) then look for relevant PFN/MFN pair. In this
|
|
||||||
* situation dom->pv_p2m[new_pfn] no longer contains proper MFN
|
|
||||||
* because original page with new_pfn was moved earlier
|
|
||||||
* to different location.
|
|
||||||
*/
|
|
||||||
for (; new_pfn < i; new_pfn = pages_moved2pfns[new_pfn]);
|
|
||||||
|
|
||||||
/* Store destination PFN of currently requested page. */
|
|
||||||
pages_moved2pfns[i] = new_pfn;
|
|
||||||
|
|
||||||
/* Put old page at new PFN */
|
|
||||||
dom->pv_p2m[new_pfn] = old_mfn;
|
|
||||||
|
|
||||||
/* Put new page at PFN i */
|
|
||||||
dom->pv_p2m[i] = new_mfn;
|
|
||||||
}
|
|
||||||
|
|
||||||
allocated = new_allocated;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Filled from mini-os command line or left as NULL */
|
|
||||||
char *vtpm_label;
|
|
||||||
|
|
||||||
static void tpm_hash2pcr(struct xc_dom_image *dom, char *cmdline)
|
|
||||||
{
|
|
||||||
struct tpmfront_dev* tpm = init_tpmfront(NULL);
|
|
||||||
struct pcr_extend_rsp *resp;
|
|
||||||
size_t resplen = 0;
|
|
||||||
struct pcr_extend_cmd cmd;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If vtpm_label was specified on the command line, require a vTPM to be
|
|
||||||
* attached and for the domain providing the vTPM to have the given
|
|
||||||
* label.
|
|
||||||
*/
|
|
||||||
if (vtpm_label) {
|
|
||||||
char ctx[128];
|
|
||||||
if (!tpm) {
|
|
||||||
printf("No TPM found and vtpm_label specified, aborting!\n");
|
|
||||||
do_exit();
|
|
||||||
}
|
|
||||||
rv = evtchn_get_peercontext(tpm->evtchn, ctx, sizeof(ctx) - 1);
|
|
||||||
if (rv < 0) {
|
|
||||||
printf("Could not verify vtpm_label: %d\n", rv);
|
|
||||||
do_exit();
|
|
||||||
}
|
|
||||||
ctx[127] = 0;
|
|
||||||
rv = strcmp(ctx, vtpm_label);
|
|
||||||
if (rv && vtpm_label[0] == '*') {
|
|
||||||
int match_len = strlen(vtpm_label) - 1;
|
|
||||||
int offset = strlen(ctx) - match_len;
|
|
||||||
if (offset > 0)
|
|
||||||
rv = strcmp(ctx + offset, vtpm_label + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rv) {
|
|
||||||
printf("Mismatched vtpm_label: '%s' != '%s'\n", ctx, vtpm_label);
|
|
||||||
do_exit();
|
|
||||||
}
|
|
||||||
} else if (!tpm) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.tag = bswap_16(TPM_TAG_RQU_COMMAND);
|
|
||||||
cmd.size = bswap_32(sizeof(cmd));
|
|
||||||
cmd.ord = bswap_32(TPM_ORD_Extend);
|
|
||||||
cmd.pcr = bswap_32(4); // PCR #4 for kernel
|
|
||||||
sha1(dom->kernel_blob, dom->kernel_size, cmd.hash);
|
|
||||||
|
|
||||||
rv = tpmfront_cmd(tpm, (void*)&cmd, sizeof(cmd), (void*)&resp, &resplen);
|
|
||||||
ASSERT(rv == 0 && resp->status == 0);
|
|
||||||
|
|
||||||
cmd.pcr = bswap_32(5); // PCR #5 for cmdline
|
|
||||||
sha1(cmdline, strlen(cmdline), cmd.hash);
|
|
||||||
rv = tpmfront_cmd(tpm, (void*)&cmd, sizeof(cmd), (void*)&resp, &resplen);
|
|
||||||
ASSERT(rv == 0 && resp->status == 0);
|
|
||||||
|
|
||||||
cmd.pcr = bswap_32(5); // PCR #5 for initrd
|
|
||||||
sha1(dom->modules[0].blob, dom->modules[0].size, cmd.hash);
|
|
||||||
rv = tpmfront_cmd(tpm, (void*)&cmd, sizeof(cmd), (void*)&resp, &resplen);
|
|
||||||
ASSERT(rv == 0 && resp->status == 0);
|
|
||||||
|
|
||||||
shutdown_tpmfront(tpm);
|
|
||||||
}
|
|
||||||
|
|
||||||
void kexec(void *kernel, long kernel_size, void *module, long module_size, char *cmdline, unsigned long flags)
|
|
||||||
{
|
|
||||||
struct xc_dom_image *dom;
|
|
||||||
int rc;
|
|
||||||
domid_t domid = DOMID_SELF;
|
|
||||||
xen_pfn_t pfn;
|
|
||||||
xc_interface *xc_handle;
|
|
||||||
unsigned long i;
|
|
||||||
void *seg;
|
|
||||||
xen_pfn_t boot_page_mfn = virt_to_mfn(&_boot_page);
|
|
||||||
char features[] = "";
|
|
||||||
struct mmu_update *m2p_updates;
|
|
||||||
unsigned long nr_m2p_updates;
|
|
||||||
uint64_t virt_base;
|
|
||||||
|
|
||||||
DEBUG("booting with cmdline %s\n", cmdline);
|
|
||||||
xc_handle = xc_interface_open(0,0,0);
|
|
||||||
|
|
||||||
dom = xc_dom_allocate(xc_handle, cmdline, features);
|
|
||||||
dom->allocate = kexec_allocate;
|
|
||||||
|
|
||||||
/* We are using guest owned memory, therefore no limits. */
|
|
||||||
xc_dom_kernel_max_size(dom, 0);
|
|
||||||
xc_dom_module_max_size(dom, 0);
|
|
||||||
|
|
||||||
dom->kernel_blob = kernel;
|
|
||||||
dom->kernel_size = kernel_size;
|
|
||||||
|
|
||||||
xc_dom_module_mem(dom, module, module_size, NULL);
|
|
||||||
|
|
||||||
dom->flags = flags;
|
|
||||||
dom->console_evtchn = start_info_ptr->console.domU.evtchn;
|
|
||||||
dom->xenstore_evtchn = start_info_ptr->store_evtchn;
|
|
||||||
|
|
||||||
tpm_hash2pcr(dom, cmdline);
|
|
||||||
|
|
||||||
if ( (rc = xc_dom_boot_xen_init(dom, xc_handle, domid)) != 0 ) {
|
|
||||||
printk("xc_dom_boot_xen_init returned %d\n", rc);
|
|
||||||
errnum = ERR_BOOT_FAILURE;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if ( (rc = xc_dom_parse_image(dom)) != 0 ) {
|
|
||||||
printk("xc_dom_parse_image returned %d\n", rc);
|
|
||||||
errnum = ERR_BOOT_FAILURE;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __i386__
|
|
||||||
if (strcmp(dom->guest_type, "xen-3.0-x86_32p")) {
|
|
||||||
printk("can only boot x86 32 PAE kernels, not %s\n", dom->guest_type);
|
|
||||||
errnum = ERR_EXEC_FORMAT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef __x86_64__
|
|
||||||
if (strcmp(dom->guest_type, "xen-3.0-x86_64")) {
|
|
||||||
printk("can only boot x86 64 kernels, not %s\n", dom->guest_type);
|
|
||||||
errnum = ERR_EXEC_FORMAT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* equivalent of xc_dom_mem_init */
|
|
||||||
if (xc_dom_set_arch_hooks(dom)) {
|
|
||||||
printk("xc_dom_set_arch_hooks failed\n");
|
|
||||||
errnum = ERR_EXEC_FORMAT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
dom->total_pages = start_info_ptr->nr_pages;
|
|
||||||
|
|
||||||
/* equivalent of arch_setup_meminit */
|
|
||||||
dom->p2m_size = dom->total_pages;
|
|
||||||
|
|
||||||
/* setup initial p2m */
|
|
||||||
dom->pv_p2m = malloc(sizeof(*dom->pv_p2m) * dom->p2m_size);
|
|
||||||
|
|
||||||
/* Start with our current P2M */
|
|
||||||
for (i = 0; i < dom->p2m_size; i++)
|
|
||||||
dom->pv_p2m[i] = pfn_to_mfn(i);
|
|
||||||
|
|
||||||
if ( (rc = xc_dom_build_image(dom)) != 0 ) {
|
|
||||||
printk("xc_dom_build_image returned %d\n", rc);
|
|
||||||
errnum = ERR_BOOT_FAILURE;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
virt_base = xc_dom_virt_base(dom);
|
|
||||||
/* copy hypercall page */
|
|
||||||
/* TODO: domctl instead, but requires privileges */
|
|
||||||
if (xc_dom_virt_hypercall(dom) != -1) {
|
|
||||||
pfn = PHYS_PFN(xc_dom_virt_hypercall(dom) - virt_base);
|
|
||||||
memcpy((void *) pages[pfn], hypercall_page, PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Equivalent of xc_dom_boot_image */
|
|
||||||
dom->shared_info_mfn = PHYS_PFN(start_info_ptr->shared_info);
|
|
||||||
|
|
||||||
if (!xc_dom_compat_check(dom)) {
|
|
||||||
printk("xc_dom_compat_check failed\n");
|
|
||||||
errnum = ERR_EXEC_FORMAT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move current console, xenstore and boot MFNs to the allocated place */
|
|
||||||
do_exchange(dom, dom->console_pfn, start_info_ptr->console.domU.mfn);
|
|
||||||
do_exchange(dom, dom->xenstore_pfn, start_info_ptr->store_mfn);
|
|
||||||
DEBUG("virt base at %llx\n", virt_base);
|
|
||||||
DEBUG("bootstack_pfn %lx\n", dom->bootstack_pfn);
|
|
||||||
_boot_target = virt_base + PFN_PHYS(dom->bootstack_pfn);
|
|
||||||
DEBUG("_boot_target %lx\n", _boot_target);
|
|
||||||
do_exchange(dom, PHYS_PFN(_boot_target - virt_base),
|
|
||||||
virt_to_mfn(&_boot_page));
|
|
||||||
|
|
||||||
if ( dom->arch_hooks->setup_pgtables )
|
|
||||||
if ( (rc = dom->arch_hooks->setup_pgtables(dom))) {
|
|
||||||
printk("setup_pgtables returned %d\n", rc);
|
|
||||||
errnum = ERR_BOOT_FAILURE;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* start info page */
|
|
||||||
if ( dom->arch_hooks->start_info )
|
|
||||||
dom->arch_hooks->start_info(dom);
|
|
||||||
|
|
||||||
xc_dom_log_memory_footprint(dom);
|
|
||||||
|
|
||||||
/* Unmap libxc's projection of the boot page table */
|
|
||||||
seg = xc_dom_seg_to_ptr(dom, &dom->pgtables_seg);
|
|
||||||
munmap(seg, dom->pgtables_seg.vend - dom->pgtables_seg.vstart);
|
|
||||||
seg = xc_dom_seg_to_ptr(dom, &dom->p2m_seg);
|
|
||||||
munmap(seg, dom->p2m_seg.vend - dom->p2m_seg.vstart);
|
|
||||||
|
|
||||||
/* Unmap day0 pages to avoid having a r/w mapping of the future page table */
|
|
||||||
for (pfn = 0; pfn < allocated; pfn++)
|
|
||||||
munmap((void*) pages[pfn], PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Pin the boot page table base */
|
|
||||||
if ( (rc = pin_table(dom->xch,
|
|
||||||
#ifdef __i386__
|
|
||||||
MMUEXT_PIN_L3_TABLE,
|
|
||||||
#endif
|
|
||||||
#ifdef __x86_64__
|
|
||||||
MMUEXT_PIN_L4_TABLE,
|
|
||||||
#endif
|
|
||||||
xc_dom_p2m(dom, dom->pgtables_seg.pfn),
|
|
||||||
dom->guest_domid)) != 0 ) {
|
|
||||||
printk("pin_table(%lx) returned %d\n", xc_dom_p2m(dom,
|
|
||||||
dom->pgtables_seg.pfn), rc);
|
|
||||||
errnum = ERR_BOOT_FAILURE;
|
|
||||||
goto out_remap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We populate the Mini-OS page table here so that boot.S can just call
|
|
||||||
* update_va_mapping to project itself there. */
|
|
||||||
need_pgt(_boot_target);
|
|
||||||
DEBUG("day0 pages %lx\n", allocated);
|
|
||||||
DEBUG("boot target page %lx\n", _boot_target);
|
|
||||||
DEBUG("boot page %p\n", &_boot_page);
|
|
||||||
DEBUG("boot page mfn %lx\n", boot_page_mfn);
|
|
||||||
_boot_page_entry = PFN_PHYS(boot_page_mfn) | L1_PROT;
|
|
||||||
DEBUG("boot page entry %llx\n", _boot_page_entry);
|
|
||||||
_boot_oldpdmfn = virt_to_mfn(start_info_ptr->pt_base);
|
|
||||||
DEBUG("boot old pd mfn %lx\n", _boot_oldpdmfn);
|
|
||||||
DEBUG("boot pd virt %lx\n", dom->pgtables_seg.vstart);
|
|
||||||
_boot_pdmfn = dom->pv_p2m[PHYS_PFN(dom->pgtables_seg.vstart - virt_base)];
|
|
||||||
DEBUG("boot pd mfn %lx\n", _boot_pdmfn);
|
|
||||||
_boot_stack = _boot_target + PAGE_SIZE;
|
|
||||||
DEBUG("boot stack %lx\n", _boot_stack);
|
|
||||||
_boot_start_info = virt_base + PFN_PHYS(dom->start_info_pfn);
|
|
||||||
DEBUG("boot start info %lx\n", _boot_start_info);
|
|
||||||
_boot_start = xc_dom_virt_entry(dom);
|
|
||||||
DEBUG("boot start %lx\n", _boot_start);
|
|
||||||
|
|
||||||
/* Keep only useful entries */
|
|
||||||
for (nr_m2p_updates = pfn = 0; pfn < start_info_ptr->nr_pages; pfn++)
|
|
||||||
if (dom->pv_p2m[pfn] != pfn_to_mfn(pfn))
|
|
||||||
nr_m2p_updates++;
|
|
||||||
|
|
||||||
m2p_updates = malloc(sizeof(*m2p_updates) * nr_m2p_updates);
|
|
||||||
for (i = pfn = 0; pfn < start_info_ptr->nr_pages; pfn++)
|
|
||||||
if (dom->pv_p2m[pfn] != pfn_to_mfn(pfn)) {
|
|
||||||
m2p_updates[i].ptr = PFN_PHYS(dom->pv_p2m[pfn]) | MMU_MACHPHYS_UPDATE;
|
|
||||||
m2p_updates[i].val = pfn;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < blk_nb; i++)
|
|
||||||
shutdown_blkfront(blk_dev[i]);
|
|
||||||
if (net_dev)
|
|
||||||
shutdown_netfront(net_dev);
|
|
||||||
if (kbd_dev)
|
|
||||||
shutdown_kbdfront(kbd_dev);
|
|
||||||
stop_kernel();
|
|
||||||
|
|
||||||
/* Update M2P */
|
|
||||||
if ((rc = HYPERVISOR_mmu_update(m2p_updates, nr_m2p_updates, NULL, DOMID_SELF)) < 0) {
|
|
||||||
xprintk("Could not update M2P\n");
|
|
||||||
ASSERT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
xprintk("go!\n");
|
|
||||||
|
|
||||||
/* Jump to trampoline boot page */
|
|
||||||
_boot();
|
|
||||||
|
|
||||||
ASSERT(0);
|
|
||||||
|
|
||||||
out_remap:
|
|
||||||
for (pfn = 0; pfn < allocated; pfn++)
|
|
||||||
do_map_frames(pages[pfn], &pages_mfns[pfn], 1, 0, 0, DOMID_SELF, 0, L1_PROT);
|
|
||||||
out:
|
|
||||||
xc_dom_release(dom);
|
|
||||||
for (pfn = 0; pfn < allocated; pfn++)
|
|
||||||
free_page((void*)pages[pfn]);
|
|
||||||
free(pages);
|
|
||||||
free(pages_mfns);
|
|
||||||
pages = NULL;
|
|
||||||
pages_mfns = NULL;
|
|
||||||
allocated = 0;
|
|
||||||
xc_interface_close(xc_handle );
|
|
||||||
}
|
|
||||||
@@ -1,771 +0,0 @@
|
|||||||
/*
|
|
||||||
* Mini-OS support for GRUB.
|
|
||||||
*
|
|
||||||
* Samuel Thibault <Samuel.Thibault@eu.citrix.com>, May 2008
|
|
||||||
*/
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <hypervisor.h>
|
|
||||||
#include <blkfront.h>
|
|
||||||
#include <netfront.h>
|
|
||||||
#include <fbfront.h>
|
|
||||||
#include <semaphore.h>
|
|
||||||
|
|
||||||
#include <osdep.h>
|
|
||||||
#include <shared.h>
|
|
||||||
#include <nic.h>
|
|
||||||
#include <etherboot.h>
|
|
||||||
#include <terminfo.h>
|
|
||||||
#include <term.h>
|
|
||||||
|
|
||||||
#include "mini-os.h"
|
|
||||||
|
|
||||||
extern const char *preset_menu;
|
|
||||||
char config_file[DEFAULT_FILE_BUFLEN] = "(hd0,0)/boot/grub/menu.lst";
|
|
||||||
unsigned long boot_drive = NETWORK_DRIVE;
|
|
||||||
unsigned long install_partition = 0xFFFFFF;
|
|
||||||
|
|
||||||
char version_string[] = VERSION;
|
|
||||||
|
|
||||||
/* Variables from asm.S */
|
|
||||||
int saved_entryno;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Disk
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct blkfront_dev **blk_dev;
|
|
||||||
int blk_nb;
|
|
||||||
static struct blkfront_info *blk_info;
|
|
||||||
|
|
||||||
static int vbdcmp(const void *_vbd1, const void *_vbd2) {
|
|
||||||
char *vbd1 = *(char **)_vbd1;
|
|
||||||
char *vbd2 = *(char **)_vbd2;
|
|
||||||
int vbdn1 = atoi(vbd1);
|
|
||||||
int vbdn2 = atoi(vbd2);
|
|
||||||
return vbdn1 - vbdn2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_disk (void)
|
|
||||||
{
|
|
||||||
char **list;
|
|
||||||
char *msg;
|
|
||||||
int i;
|
|
||||||
char *path;
|
|
||||||
|
|
||||||
msg = xenbus_ls(XBT_NIL, "device/vbd", &list);
|
|
||||||
if (msg) {
|
|
||||||
printk("Error %s while reading list of disks\n", msg);
|
|
||||||
free(msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
blk_nb = 0;
|
|
||||||
while (list[blk_nb])
|
|
||||||
blk_nb++;
|
|
||||||
blk_dev = malloc(blk_nb * sizeof(*blk_dev));
|
|
||||||
blk_info = malloc(blk_nb * sizeof(*blk_info));
|
|
||||||
|
|
||||||
qsort(list, blk_nb, sizeof(*list), vbdcmp);
|
|
||||||
|
|
||||||
for (i = 0; i < blk_nb; i++) {
|
|
||||||
printk("vbd %s is hd%d\n", list[i], i);
|
|
||||||
asprintf(&path, "device/vbd/%s", list[i]);
|
|
||||||
blk_dev[i] = init_blkfront(path, &blk_info[i]);
|
|
||||||
free(path);
|
|
||||||
free(list[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the geometry of DRIVE in GEOMETRY. If an error occurs, return
|
|
||||||
non-zero, otherwise zero. */
|
|
||||||
int get_diskinfo (int drive, struct geometry *geometry)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
if (!(drive & 0x80))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
i = drive - 0x80;
|
|
||||||
if (i >= blk_nb)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* Bogus geometry */
|
|
||||||
geometry->cylinders = 65535;
|
|
||||||
geometry->heads = 255;
|
|
||||||
geometry->sectors = 63;
|
|
||||||
|
|
||||||
geometry->total_sectors = blk_info[i].sectors;
|
|
||||||
geometry->sector_size = blk_info[i].sector_size;
|
|
||||||
geometry->flags = BIOSDISK_FLAG_LBA_EXTENSION;
|
|
||||||
if (blk_info[i].info & VDISK_CDROM)
|
|
||||||
geometry->flags |= BIOSDISK_FLAG_CDROM;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read/write NSEC sectors starting from SECTOR in DRIVE disk with GEOMETRY
|
|
||||||
from/into SEGMENT segment. If READ is BIOSDISK_READ, then read it,
|
|
||||||
else if READ is BIOSDISK_WRITE, then write it. If an geometry error
|
|
||||||
occurs, return BIOSDISK_ERROR_GEOMETRY, and if other error occurs, then
|
|
||||||
return the error number. Otherwise, return 0. */
|
|
||||||
int
|
|
||||||
biosdisk (int read, int drive, struct geometry *geometry,
|
|
||||||
unsigned int sector, int nsec, int segment)
|
|
||||||
{
|
|
||||||
void *addr = (void *) ((unsigned long)segment << 4);
|
|
||||||
struct blkfront_aiocb aiocb;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!(drive & 0x80))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
i = drive - 0x80;
|
|
||||||
if (i >= blk_nb)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (sector + nsec > geometry->total_sectors)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
aiocb.aio_dev = blk_dev[i];
|
|
||||||
aiocb.aio_buf = addr;
|
|
||||||
aiocb.aio_nbytes = (size_t)nsec * blk_info[i].sector_size;
|
|
||||||
aiocb.aio_offset = (off_t)sector * blk_info[i].sector_size;
|
|
||||||
aiocb.aio_cb = NULL;
|
|
||||||
|
|
||||||
blkfront_io(&aiocb, read == BIOSDISK_WRITE);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
load_file(char *name, void **ptr, long *size)
|
|
||||||
{
|
|
||||||
char *buf = NULL;
|
|
||||||
int allocated = 1 * 1024 * 1024;
|
|
||||||
int len, filled = 0;
|
|
||||||
|
|
||||||
if (!grub_open (name))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
buf = malloc(allocated);
|
|
||||||
|
|
||||||
errnum = 0;
|
|
||||||
while (1) {
|
|
||||||
len = grub_read (buf + filled, allocated - filled);
|
|
||||||
if (! len) {
|
|
||||||
if (!errnum)
|
|
||||||
break;
|
|
||||||
grub_close ();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
filled += len;
|
|
||||||
if (filled < allocated)
|
|
||||||
break;
|
|
||||||
allocated *= 2;
|
|
||||||
buf = realloc(buf, allocated);
|
|
||||||
}
|
|
||||||
grub_close ();
|
|
||||||
*ptr = buf;
|
|
||||||
*size = filled;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *kernel_image, *module_image;
|
|
||||||
long kernel_size, module_size;
|
|
||||||
char *kernel_arg, *module_arg;
|
|
||||||
void *multiboot_next_module;
|
|
||||||
struct xen_multiboot_mod_list *multiboot_next_module_header;
|
|
||||||
|
|
||||||
kernel_t
|
|
||||||
load_image (char *kernel, char *arg, kernel_t suggested_type,
|
|
||||||
unsigned long load_flags)
|
|
||||||
{
|
|
||||||
arg = skip_to(0, arg);
|
|
||||||
if (kernel_image)
|
|
||||||
free(kernel_image);
|
|
||||||
kernel_image = NULL;
|
|
||||||
if (load_file (kernel, &kernel_image, &kernel_size))
|
|
||||||
return KERNEL_TYPE_NONE;
|
|
||||||
if (kernel_arg)
|
|
||||||
free(kernel_arg);
|
|
||||||
kernel_arg = strdup(arg);
|
|
||||||
return KERNEL_TYPE_PV;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
load_initrd (char *initrd)
|
|
||||||
{
|
|
||||||
if (module_image)
|
|
||||||
free(module_image);
|
|
||||||
module_image = NULL;
|
|
||||||
multiboot_next_module = NULL;
|
|
||||||
multiboot_next_module_header = NULL;
|
|
||||||
load_file (initrd, &module_image, &module_size);
|
|
||||||
return ! errnum;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
load_module (char *module, char *arg)
|
|
||||||
{
|
|
||||||
void *new_module, *new_module_image;
|
|
||||||
long new_module_size, rounded_new_module_size;
|
|
||||||
|
|
||||||
if (load_file (module, &new_module, &new_module_size))
|
|
||||||
return 0;
|
|
||||||
if (strlen(arg) >= PAGE_SIZE) {
|
|
||||||
/* Too big module command line */
|
|
||||||
errnum = ERR_WONT_FIT;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
rounded_new_module_size = (new_module_size + PAGE_SIZE - 1) & PAGE_MASK;
|
|
||||||
|
|
||||||
if (module_image && !multiboot_next_module_header) {
|
|
||||||
/* Initrd already loaded, drop it */
|
|
||||||
free(module_image);
|
|
||||||
if (module_arg)
|
|
||||||
free(module_arg);
|
|
||||||
module_image = NULL;
|
|
||||||
}
|
|
||||||
if (!module_image)
|
|
||||||
/* Reserve one page for the header */
|
|
||||||
multiboot_next_module = (void*) PAGE_SIZE;
|
|
||||||
|
|
||||||
/* Allocate more room for the new module plus its arg */
|
|
||||||
new_module_image = realloc(module_image,
|
|
||||||
(multiboot_next_module - module_image) + rounded_new_module_size + PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Update pointers */
|
|
||||||
multiboot_next_module += new_module_image - module_image;
|
|
||||||
multiboot_next_module_header = (void*) multiboot_next_module_header + (new_module_image - module_image);
|
|
||||||
module_image = new_module_image;
|
|
||||||
|
|
||||||
if ((void*) (multiboot_next_module_header+1) - module_image > PAGE_SIZE) {
|
|
||||||
/* Too many modules */
|
|
||||||
errnum = ERR_WONT_FIT;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy module */
|
|
||||||
memcpy(multiboot_next_module, new_module, new_module_size);
|
|
||||||
multiboot_next_module_header->mod_start = multiboot_next_module - module_image;
|
|
||||||
multiboot_next_module_header->mod_end = multiboot_next_module_header->mod_start + new_module_size - 1;
|
|
||||||
multiboot_next_module += rounded_new_module_size;
|
|
||||||
|
|
||||||
/* Copy cmdline */
|
|
||||||
strcpy(multiboot_next_module, arg);
|
|
||||||
multiboot_next_module_header->cmdline = multiboot_next_module - module_image;
|
|
||||||
multiboot_next_module += PAGE_SIZE;
|
|
||||||
|
|
||||||
/* Pad */
|
|
||||||
multiboot_next_module_header->pad = 0;
|
|
||||||
|
|
||||||
multiboot_next_module_header++;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
pv_boot (void)
|
|
||||||
{
|
|
||||||
unsigned long flags = 0;
|
|
||||||
if (multiboot_next_module_header) {
|
|
||||||
/* Termination entry */
|
|
||||||
multiboot_next_module_header->mod_start = 0;
|
|
||||||
/* Total size */
|
|
||||||
module_size = multiboot_next_module - module_image;
|
|
||||||
/* It's a multiboot module */
|
|
||||||
flags |= SIF_MULTIBOOT_MOD;
|
|
||||||
}
|
|
||||||
kexec(kernel_image, kernel_size, module_image, module_size, kernel_arg, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Network
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct netfront_dev *net_dev;
|
|
||||||
|
|
||||||
int
|
|
||||||
minios_probe (struct nic *nic)
|
|
||||||
{
|
|
||||||
char *ip;
|
|
||||||
|
|
||||||
if (net_dev)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* Clear the ARP table. */
|
|
||||||
grub_memset ((char *) arptable, 0,
|
|
||||||
MAX_ARP * sizeof (struct arptable_t));
|
|
||||||
|
|
||||||
net_dev = init_netfront(NULL, (void*) -1, nic->node_addr, &ip);
|
|
||||||
if (!net_dev)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reset adapter */
|
|
||||||
static void minios_reset(struct nic *nic)
|
|
||||||
{
|
|
||||||
/* TODO? */
|
|
||||||
}
|
|
||||||
|
|
||||||
static void minios_disable(struct nic *nic)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait for a frame */
|
|
||||||
static int minios_poll(struct nic *nic)
|
|
||||||
{
|
|
||||||
return !! (nic->packetlen = netfront_receive(net_dev, (void*) nic->packet, ETH_FRAME_LEN));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Transmit a frame */
|
|
||||||
struct frame {
|
|
||||||
uint8_t dest[ETH_ALEN];
|
|
||||||
uint8_t src[ETH_ALEN];
|
|
||||||
uint16_t type;
|
|
||||||
unsigned char data[];
|
|
||||||
};
|
|
||||||
static void minios_transmit (struct nic *nic, const char *d, unsigned int t,
|
|
||||||
unsigned int s, const char *p)
|
|
||||||
{
|
|
||||||
struct frame *frame = alloca(sizeof(*frame) + s);
|
|
||||||
|
|
||||||
memcpy(frame->dest, d, ETH_ALEN);
|
|
||||||
memcpy(frame->src, nic->node_addr, ETH_ALEN);
|
|
||||||
frame->type = htons(t);
|
|
||||||
memcpy(frame->data, p, s);
|
|
||||||
|
|
||||||
netfront_xmit(net_dev, (void*) frame, sizeof(*frame) + s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char packet[ETH_FRAME_LEN];
|
|
||||||
|
|
||||||
struct nic nic = {
|
|
||||||
.reset = minios_reset,
|
|
||||||
.poll = minios_poll,
|
|
||||||
.transmit = minios_transmit,
|
|
||||||
.disable = minios_disable,
|
|
||||||
.flags = 0,
|
|
||||||
.rom_info = NULL,
|
|
||||||
.node_addr = arptable[ARP_CLIENT].node,
|
|
||||||
.packet = packet,
|
|
||||||
.packetlen = 0,
|
|
||||||
.priv_data = NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
eth_probe (void)
|
|
||||||
{
|
|
||||||
return minios_probe(&nic);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
eth_poll (void)
|
|
||||||
{
|
|
||||||
return minios_poll (&nic);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
eth_disable (void)
|
|
||||||
{
|
|
||||||
minios_disable (&nic);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
eth_transmit (const char *d, unsigned int t,
|
|
||||||
unsigned int s, const void *p)
|
|
||||||
{
|
|
||||||
minios_transmit (&nic, d, t, s, p);
|
|
||||||
if (t == IP)
|
|
||||||
twiddle();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Console
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
serial_hw_put (int _c)
|
|
||||||
{
|
|
||||||
char c = _c;
|
|
||||||
console_print(NULL, &c, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
serial_hw_fetch (void)
|
|
||||||
{
|
|
||||||
char key;
|
|
||||||
|
|
||||||
if (!xencons_ring_avail(NULL))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
read(STDIN_FILENO, &key, 1);
|
|
||||||
switch (key) {
|
|
||||||
case 0x7f: key = '\b'; break;
|
|
||||||
}
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PVFB
|
|
||||||
*/
|
|
||||||
struct kbdfront_dev *kbd_dev;
|
|
||||||
struct fbfront_dev *fb_dev;
|
|
||||||
static union xenkbd_in_event ev;
|
|
||||||
static int has_ev;
|
|
||||||
int console_checkkey (void)
|
|
||||||
{
|
|
||||||
if (has_ev)
|
|
||||||
return 1;
|
|
||||||
has_ev = kbdfront_receive(kbd_dev, &ev, 1);
|
|
||||||
return has_ev;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static QWERTY layout, that's what most PC BIOSes do anyway */
|
|
||||||
static char linux2ascii[] = {
|
|
||||||
[ 1 ] = 27,
|
|
||||||
[ 2 ] = '1',
|
|
||||||
[ 3 ] = '2',
|
|
||||||
[ 4 ] = '3',
|
|
||||||
[ 5 ] = '4',
|
|
||||||
[ 6 ] = '5',
|
|
||||||
[ 7 ] = '6',
|
|
||||||
[ 8 ] = '7',
|
|
||||||
[ 9 ] = '8',
|
|
||||||
[ 10 ] = '9',
|
|
||||||
[ 11 ] = '0',
|
|
||||||
[ 12 ] = '-',
|
|
||||||
[ 13 ] = '=',
|
|
||||||
[ 14 ] = '\b',
|
|
||||||
[ 15 ] = '\t',
|
|
||||||
[ 16 ] = 'q',
|
|
||||||
[ 17 ] = 'w',
|
|
||||||
[ 18 ] = 'e',
|
|
||||||
[ 19 ] = 'r',
|
|
||||||
[ 20 ] = 't',
|
|
||||||
[ 21 ] = 'y',
|
|
||||||
[ 22 ] = 'u',
|
|
||||||
[ 23 ] = 'i',
|
|
||||||
[ 24 ] = 'o',
|
|
||||||
[ 25 ] = 'p',
|
|
||||||
[ 26 ] = '[',
|
|
||||||
[ 27 ] = ']',
|
|
||||||
[ 28 ] = '\n',
|
|
||||||
|
|
||||||
[ 30 ] = 'a',
|
|
||||||
[ 31 ] = 's',
|
|
||||||
[ 32 ] = 'd',
|
|
||||||
[ 33 ] = 'f',
|
|
||||||
[ 34 ] = 'g',
|
|
||||||
[ 35 ] = 'h',
|
|
||||||
[ 36 ] = 'j',
|
|
||||||
[ 37 ] = 'k',
|
|
||||||
[ 38 ] = 'l',
|
|
||||||
[ 39 ] = ';',
|
|
||||||
[ 40 ] = '\'',
|
|
||||||
[ 41 ] = '`',
|
|
||||||
|
|
||||||
[ 43 ] = '\\',
|
|
||||||
[ 44 ] = 'z',
|
|
||||||
[ 45 ] = 'x',
|
|
||||||
[ 46 ] = 'c',
|
|
||||||
[ 47 ] = 'v',
|
|
||||||
[ 48 ] = 'b',
|
|
||||||
[ 49 ] = 'n',
|
|
||||||
[ 50 ] = 'm',
|
|
||||||
[ 51 ] = ',',
|
|
||||||
[ 52 ] = '.',
|
|
||||||
[ 53 ] = '/',
|
|
||||||
|
|
||||||
[ 55 ] = '*',
|
|
||||||
[ 57 ] = ' ',
|
|
||||||
|
|
||||||
[ 71 ] = '7',
|
|
||||||
[ 72 ] = '8',
|
|
||||||
[ 73 ] = '9',
|
|
||||||
[ 74 ] = '-',
|
|
||||||
[ 75 ] = '4',
|
|
||||||
[ 76 ] = '5',
|
|
||||||
[ 77 ] = '6',
|
|
||||||
[ 78 ] = '+',
|
|
||||||
[ 79 ] = '1',
|
|
||||||
[ 80 ] = '2',
|
|
||||||
[ 81 ] = '3',
|
|
||||||
[ 82 ] = '0',
|
|
||||||
[ 83 ] = '.',
|
|
||||||
|
|
||||||
[ 86 ] = '<',
|
|
||||||
|
|
||||||
[ 96 ] = '\n',
|
|
||||||
|
|
||||||
[ 98 ] = '/',
|
|
||||||
|
|
||||||
[ 102 ] = 1, /* home */
|
|
||||||
[ 103 ] = 16, /* up */
|
|
||||||
[ 104 ] = 7, /* page up */
|
|
||||||
[ 105 ] = 2, /* left */
|
|
||||||
[ 106 ] = 6, /* right */
|
|
||||||
[ 107 ] = 5, /* end */
|
|
||||||
[ 108 ] = 14, /* down */
|
|
||||||
[ 109 ] = 3, /* page down */
|
|
||||||
|
|
||||||
[ 111 ] = 4, /* delete */
|
|
||||||
};
|
|
||||||
|
|
||||||
static char linux2ascii_shifted[] = {
|
|
||||||
[ 1 ] = 27,
|
|
||||||
[ 2 ] = '!',
|
|
||||||
[ 3 ] = '@',
|
|
||||||
[ 4 ] = '#',
|
|
||||||
[ 5 ] = '$',
|
|
||||||
[ 6 ] = '%',
|
|
||||||
[ 7 ] = '^',
|
|
||||||
[ 8 ] = '&',
|
|
||||||
[ 9 ] = '*',
|
|
||||||
[ 10 ] = '(',
|
|
||||||
[ 11 ] = ')',
|
|
||||||
[ 12 ] = '_',
|
|
||||||
[ 13 ] = '+',
|
|
||||||
[ 14 ] = '\b',
|
|
||||||
[ 15 ] = '\t',
|
|
||||||
[ 16 ] = 'Q',
|
|
||||||
[ 17 ] = 'W',
|
|
||||||
[ 18 ] = 'E',
|
|
||||||
[ 19 ] = 'R',
|
|
||||||
[ 20 ] = 'T',
|
|
||||||
[ 21 ] = 'Y',
|
|
||||||
[ 22 ] = 'U',
|
|
||||||
[ 23 ] = 'I',
|
|
||||||
[ 24 ] = 'O',
|
|
||||||
[ 25 ] = 'P',
|
|
||||||
[ 26 ] = '{',
|
|
||||||
[ 27 ] = '}',
|
|
||||||
[ 28 ] = '\n',
|
|
||||||
|
|
||||||
[ 30 ] = 'A',
|
|
||||||
[ 31 ] = 'S',
|
|
||||||
[ 32 ] = 'D',
|
|
||||||
[ 33 ] = 'F',
|
|
||||||
[ 34 ] = 'G',
|
|
||||||
[ 35 ] = 'H',
|
|
||||||
[ 36 ] = 'J',
|
|
||||||
[ 37 ] = 'K',
|
|
||||||
[ 38 ] = 'L',
|
|
||||||
[ 39 ] = ':',
|
|
||||||
[ 40 ] = '"',
|
|
||||||
[ 41 ] = '~',
|
|
||||||
|
|
||||||
[ 43 ] = '|',
|
|
||||||
[ 44 ] = 'Z',
|
|
||||||
[ 45 ] = 'X',
|
|
||||||
[ 46 ] = 'C',
|
|
||||||
[ 47 ] = 'V',
|
|
||||||
[ 48 ] = 'B',
|
|
||||||
[ 49 ] = 'N',
|
|
||||||
[ 50 ] = 'M',
|
|
||||||
[ 51 ] = '<',
|
|
||||||
[ 52 ] = '>',
|
|
||||||
[ 53 ] = '?',
|
|
||||||
|
|
||||||
[ 55 ] = '*',
|
|
||||||
[ 57 ] = ' ',
|
|
||||||
|
|
||||||
[ 71 ] = '7',
|
|
||||||
[ 72 ] = '8',
|
|
||||||
[ 73 ] = '9',
|
|
||||||
[ 74 ] = '-',
|
|
||||||
[ 75 ] = '4',
|
|
||||||
[ 76 ] = '5',
|
|
||||||
[ 77 ] = '6',
|
|
||||||
[ 78 ] = '+',
|
|
||||||
[ 79 ] = '1',
|
|
||||||
[ 80 ] = '2',
|
|
||||||
[ 81 ] = '3',
|
|
||||||
[ 82 ] = '0',
|
|
||||||
[ 83 ] = '.',
|
|
||||||
|
|
||||||
[ 86 ] = '>',
|
|
||||||
|
|
||||||
[ 96 ] = '\n',
|
|
||||||
|
|
||||||
[ 98 ] = '/',
|
|
||||||
|
|
||||||
[ 102 ] = 1, /* home */
|
|
||||||
[ 103 ] = 16, /* up */
|
|
||||||
[ 104 ] = 7, /* page up */
|
|
||||||
[ 105 ] = 2, /* left */
|
|
||||||
[ 106 ] = 6, /* right */
|
|
||||||
[ 107 ] = 5, /* end */
|
|
||||||
[ 108 ] = 14, /* down */
|
|
||||||
[ 109 ] = 3, /* page down */
|
|
||||||
|
|
||||||
[ 111 ] = 4, /* delete */
|
|
||||||
};
|
|
||||||
|
|
||||||
int console_getkey (void)
|
|
||||||
{
|
|
||||||
static int shift, control, alt, caps_lock;
|
|
||||||
|
|
||||||
if (!has_ev)
|
|
||||||
has_ev = kbdfront_receive(kbd_dev, &ev, 1);
|
|
||||||
if (!has_ev)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
has_ev = 0;
|
|
||||||
if (ev.type != XENKBD_TYPE_KEY)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (ev.key.keycode == 42 || ev.key.keycode == 54) {
|
|
||||||
caps_lock = 0;
|
|
||||||
shift = ev.key.pressed;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (ev.key.keycode == 58) {
|
|
||||||
caps_lock ^= 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (ev.key.keycode == 29 || ev.key.keycode == 97) {
|
|
||||||
control = ev.key.pressed;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (ev.key.keycode == 56) {
|
|
||||||
alt = ev.key.pressed;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ev.key.pressed)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (ev.key.keycode < sizeof(linux2ascii) / sizeof(*linux2ascii)) {
|
|
||||||
char val;
|
|
||||||
if (shift || caps_lock)
|
|
||||||
val = linux2ascii_shifted[ev.key.keycode];
|
|
||||||
else
|
|
||||||
val = linux2ascii[ev.key.keycode];
|
|
||||||
if (control)
|
|
||||||
val &= ~0x60;
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DECLARE_MUTEX_LOCKED(kbd_sem);
|
|
||||||
static void kbd_thread(void *p)
|
|
||||||
{
|
|
||||||
kbd_dev = init_kbdfront(NULL, 1);
|
|
||||||
up(&kbd_sem);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct fbfront_dev *fb_open(void *fb, int width, int height, int depth)
|
|
||||||
{
|
|
||||||
unsigned long *mfns;
|
|
||||||
int linesize = width * (depth / 8);
|
|
||||||
int memsize = linesize * height;
|
|
||||||
int numpages = (memsize + PAGE_SIZE - 1) / PAGE_SIZE;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
create_thread("kbdfront", kbd_thread, &kbd_sem);
|
|
||||||
|
|
||||||
mfns = malloc(numpages * sizeof(*mfns));
|
|
||||||
for (i = 0; i < numpages; i++) {
|
|
||||||
memset(fb + i * PAGE_SIZE, 0, PAGE_SIZE);
|
|
||||||
mfns[i] = virtual_to_mfn(fb + i * PAGE_SIZE);
|
|
||||||
}
|
|
||||||
fb_dev = init_fbfront(NULL, mfns, width, height, depth, linesize, numpages);
|
|
||||||
free(mfns);
|
|
||||||
|
|
||||||
if (!fb_dev)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
down(&kbd_sem);
|
|
||||||
if (!kbd_dev)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return fb_dev;
|
|
||||||
}
|
|
||||||
|
|
||||||
void kbd_close(void *foo)
|
|
||||||
{
|
|
||||||
shutdown_kbdfront(kbd_dev);
|
|
||||||
kbd_dev = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fb_close(void)
|
|
||||||
{
|
|
||||||
create_thread("kbdfront close", kbd_close, NULL);
|
|
||||||
shutdown_fbfront(fb_dev);
|
|
||||||
fb_dev = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Misc
|
|
||||||
*/
|
|
||||||
|
|
||||||
int getrtsecs (void)
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
return tv.tv_sec % 10 + ((tv.tv_sec / 10) % 6) * 0x10;
|
|
||||||
}
|
|
||||||
|
|
||||||
int currticks (void)
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
return ((tv.tv_sec * 1000000ULL + tv.tv_usec) * TICKS_PER_SEC) / 1000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __attribute__ ((noreturn)) grub_reboot (void)
|
|
||||||
{
|
|
||||||
for ( ;; )
|
|
||||||
{
|
|
||||||
struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_reboot };
|
|
||||||
HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SCRATCH_MEMSIZE (4 * 1024 * 1024)
|
|
||||||
|
|
||||||
/* Note: not allocating it dynamically permits to make sure it lays below 4G
|
|
||||||
* for grub's 32bit pointers to work */
|
|
||||||
char grub_scratch_mem[SCRATCH_MEMSIZE] __attribute__((aligned(PAGE_SIZE)));
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
if (argc > 1 && memcmp(argv[1], "--vtpm-label=", 13) == 0) {
|
|
||||||
vtpm_label = argv[1] + 13;
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc > 1) {
|
|
||||||
strncpy(config_file, argv[1], sizeof(config_file) - 1);
|
|
||||||
config_file[sizeof(config_file) - 1] = 0;
|
|
||||||
if (!strncmp(config_file, "(nd)", 4))
|
|
||||||
preset_menu = "dhcp";
|
|
||||||
} else if (start_info.mod_len)
|
|
||||||
preset_menu = (void*) start_info.mod_start;
|
|
||||||
else
|
|
||||||
preset_menu = "dhcp --with-configfile";
|
|
||||||
|
|
||||||
mbi.drives_addr = BOOTSEC_LOCATION + (60 * 1024);
|
|
||||||
mbi.drives_length = 0;
|
|
||||||
|
|
||||||
mbi.boot_loader_name = (unsigned long) "GNU GRUB " VERSION;
|
|
||||||
mbi.mem_lower = (start_info.nr_pages * PAGE_SIZE) / 1024;
|
|
||||||
mbi.mem_upper = 0;
|
|
||||||
saved_drive = boot_drive;
|
|
||||||
saved_partition = install_partition;
|
|
||||||
|
|
||||||
init_disk();
|
|
||||||
|
|
||||||
/* Try to make sure the client part got launched */
|
|
||||||
sleep(1);
|
|
||||||
cmain();
|
|
||||||
printk("cmain returned!\n");
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
extern int blk_nb;
|
|
||||||
extern struct blkfront_dev **blk_dev;
|
|
||||||
extern struct netfront_dev *net_dev;
|
|
||||||
extern struct kbdfront_dev *kbd_dev;
|
|
||||||
extern struct fbfront_dev *fb_dev;
|
|
||||||
|
|
||||||
extern char* vtpm_label;
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
CONFIG_LIBC=y
|
|
||||||
CONFIG_LWIP=n
|
|
||||||
CONFIG_SPARSE_BSS=n
|
|
||||||
CONFIG_TPMFRONT=y
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#ifndef __OSDEP_H__
|
|
||||||
#define __OSDEP_H__
|
|
||||||
|
|
||||||
#include <byteswap.h>
|
|
||||||
#define swap32(x) bswap_32(x)
|
|
||||||
#define swap16(x) bswap_16(x)
|
|
||||||
|
|
||||||
#include <machine/endian.h>
|
|
||||||
#if BYTE_ORDER == BIG_ENDIAN
|
|
||||||
#define htons(x) (x)
|
|
||||||
#define ntohs(x) (x)
|
|
||||||
#define htonl(x) (x)
|
|
||||||
#define ntohl(x) (x)
|
|
||||||
#else
|
|
||||||
#define htons(x) swap16(x)
|
|
||||||
#define ntohs(x) swap16(x)
|
|
||||||
#define htonl(x) swap32(x)
|
|
||||||
#define ntohl(x) swap32(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef unsigned long Address;
|
|
||||||
|
|
||||||
/* ANSI prototyping macro */
|
|
||||||
#ifdef __STDC__
|
|
||||||
#define P(x) x
|
|
||||||
#else
|
|
||||||
#define P(x) ()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||