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:
Juergen Gross authored and Jan Beulich committed 2026-08-13 15:11:20 +02:00
1 parent 58db743e3b
commit 0724c68d85
26 files changed
-11041

No files matched your search

-6
View File
@@ -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:
-3
View File
@@ -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@
-1
View File
@@ -9,7 +9,6 @@
/cross-root-* /cross-root-*
/gcc-* /gcc-*
/gmp-* /gmp-*
/grub-*
/include /include
/libs-* /libs-*
/libxencall-* /libxencall-*
-54
View File
@@ -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
-65
View File
@@ -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 :
-2
View File
@@ -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
-52
View File
@@ -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 */
-186
View File
@@ -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;
-72
View File
@@ -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)
-474
View File
@@ -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
-88
View File
@@ -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
-112
View File
@@ -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)
-108
View File
@@ -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)
-12
View File
@@ -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);
-434
View File
@@ -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 );
}
-771
View File
@@ -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");
}
-7
View File
@@ -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;
-4
View File
@@ -1,4 +0,0 @@
CONFIG_LIBC=y
CONFIG_LWIP=n
CONFIG_SPARSE_BSS=n
CONFIG_TPMFRONT=y
-30
View File
@@ -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
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.