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
|
||||
build-stubdom: mini-os-dir build-tools-public-headers
|
||||
$(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
|
||||
$(1)/%: FORCE
|
||||
@@ -149,9 +146,6 @@ install-tools: install-tools-public-headers
|
||||
.PHONY: install-stubdom
|
||||
install-stubdom: mini-os-dir install-tools-public-headers
|
||||
$(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
|
||||
tools/firmware/seabios-dir-force-update:
|
||||
|
||||
@@ -23,9 +23,6 @@ NEWLIB_URL := @NEWLIB_URL@
|
||||
LWIP_VERSION := @LWIP_VERSION@
|
||||
LWIP_URL := @LWIP_URL@
|
||||
|
||||
GRUB_VERSION := @GRUB_VERSION@
|
||||
GRUB_URL := @GRUB_URL@
|
||||
|
||||
GMP_VERSION := @GMP_VERSION@
|
||||
GMP_URL := @GMP_URL@
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
/cross-root-*
|
||||
/gcc-*
|
||||
/gmp-*
|
||||
/grub-*
|
||||
/include
|
||||
/libs-*
|
||||
/libxencall-*
|
||||
|
||||
@@ -361,32 +361,6 @@ vtpmmgr-minios-config.mk: $(CURDIR)/vtpmmgr/minios.cfg
|
||||
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 $@
|
||||
|
||||
######
|
||||
# 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
|
||||
##########
|
||||
@@ -429,17 +403,6 @@ vtpm-stubdom: mini-os-$(XEN_TARGET_ARCH)-vtpm vtpm
|
||||
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"
|
||||
|
||||
.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
|
||||
|
||||
.PHONY: xenstore-stubdom
|
||||
@@ -460,16 +423,6 @@ else
|
||||
install:
|
||||
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_DIR) "$(DESTDIR)$(XENFIRMWAREDIR)"
|
||||
$(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-xenstore/mini-os.gz "$(DESTDIR)$(XENFIRMWAREDIR)/xenstore-stubdom.gz"
|
||||
@@ -500,9 +453,6 @@ else
|
||||
uninstall:
|
||||
endif
|
||||
|
||||
uninstall-grub:
|
||||
rm -f $(DESTDIR)$(XENFIRMWAREDIR)/pv-grub-$(XEN_TARGET_ARCH).gz
|
||||
|
||||
uninstall-xenstore:
|
||||
rm -f $(DESTDIR)$(XENFIRMWAREDIR)/xenstore-stubdom.gz
|
||||
|
||||
@@ -523,14 +473,12 @@ uninstall-vtpmmgr:
|
||||
.PHONY: clean
|
||||
clean: $(foreach lib,$(STUB_LIBS),clean-libxen$(lib))
|
||||
clean:
|
||||
rm -fr mini-os-$(XEN_TARGET_ARCH)-grub
|
||||
rm -fr mini-os-$(XEN_TARGET_ARCH)-xenstore
|
||||
rm -fr mini-os-$(XEN_TARGET_ARCH)-xenstorepvh
|
||||
rm -fr mini-os-$(XEN_TARGET_ARCH)-vtpm
|
||||
rm -fr mini-os-$(XEN_TARGET_ARCH)-vtpmmgr
|
||||
$(MAKE) -C vtpm clean
|
||||
$(MAKE) -C vtpmmgr clean
|
||||
rm -fr grub-$(XEN_TARGET_ARCH)
|
||||
rm -f *-minios-config.mk
|
||||
rm -f *.gen.cfg
|
||||
rm -fr pkg-config
|
||||
@@ -559,7 +507,6 @@ patchclean: crossclean
|
||||
rm -fr polarssl-$(XEN_TARGET_ARCH)
|
||||
rm -fr tpm_emulator-$(XEN_TARGET_ARCH)
|
||||
rm -fr lwip-$(XEN_TARGET_ARCH)
|
||||
rm -fr grub-upstream
|
||||
|
||||
# clean downloads
|
||||
.PHONY: downloadclean
|
||||
@@ -569,7 +516,6 @@ downloadclean: patchclean
|
||||
rm -f gmp-$(GMP_VERSION).tar.bz2
|
||||
rm -f tpm_emulator-$(TPMEMU_VERSION).tar.gz
|
||||
rm -f pciutils-$(LIBPCI_VERSION).tar.bz2
|
||||
rm -f grub-$(GRUB_VERSION).tar.gz
|
||||
rm -f lwip-$(LWIP_VERSION).tar.gz
|
||||
rm -f polarssl-$(POLARSSL_VERSION)-gpl.tgz
|
||||
|
||||
|
||||
Vendored
-65
@@ -630,8 +630,6 @@ POLARSSL_VERSION
|
||||
POLARSSL_URL
|
||||
GMP_VERSION
|
||||
GMP_URL
|
||||
GRUB_VERSION
|
||||
GRUB_URL
|
||||
LWIP_VERSION
|
||||
LWIP_URL
|
||||
NEWLIB_VERSION
|
||||
@@ -660,7 +658,6 @@ extfiles
|
||||
debug
|
||||
xenstorepvh
|
||||
xenstore
|
||||
grub
|
||||
host_os
|
||||
host_vendor
|
||||
host_cpu
|
||||
@@ -711,7 +708,6 @@ SHELL'
|
||||
ac_subst_files=''
|
||||
ac_user_opts='
|
||||
enable_option_checking
|
||||
enable_pv_grub
|
||||
enable_xenstore_stubdom
|
||||
enable_xenstorepvh_stubdom
|
||||
enable_vtpm_stubdom
|
||||
@@ -732,7 +728,6 @@ ZLIB_URL
|
||||
LIBPCI_URL
|
||||
NEWLIB_URL
|
||||
LWIP_URL
|
||||
GRUB_URL
|
||||
GMP_URL
|
||||
POLARSSL_URL
|
||||
TPMEMU_URL'
|
||||
@@ -1358,7 +1353,6 @@ Optional Features:
|
||||
--disable-option-checking ignore unrecognized --enable/--with options
|
||||
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
|
||||
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
||||
--enable-pv-grub Build and install pv-grub (default is DISABLED)
|
||||
--disable-xenstore-stubdom
|
||||
Build and install xenstore-stubdom (default is
|
||||
ENABLED)
|
||||
@@ -1385,7 +1379,6 @@ Some influential environment variables:
|
||||
LIBPCI_URL Download url for libpci
|
||||
NEWLIB_URL Download url for newlib
|
||||
LWIP_URL Download url for lwip
|
||||
GRUB_URL Download url for grub
|
||||
GMP_URL Download url for libgmp
|
||||
POLARSSL_URL
|
||||
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
|
||||
|
||||
# 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.
|
||||
if test ${enable_xenstore_stubdom+y}
|
||||
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"
|
||||
then :
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ m4_include([../m4/depends.m4])
|
||||
m4_include([../m4/fetcher.m4])
|
||||
|
||||
# Enable/disable stub domains
|
||||
AX_STUBDOM_DEFAULT_DISABLE([pv-grub], [grub])
|
||||
AX_STUBDOM_DEFAULT_ENABLE([xenstore-stubdom], [xenstore])
|
||||
AX_STUBDOM_DEFAULT_ENABLE([xenstorepvh-stubdom], [xenstorepvh])
|
||||
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([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([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([POLARSSL], [polarssl], [1.1.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
|
||||