rename ./busybox to xzcat\r
\r
\r
+======== How to build ash/hexdump/xzcat for mips64el ======== \r
+#download mips64el-musl cross toolchain from https://github.com/ventoy/musl-cross-make/releases/download/latest/\r
+#How to get ash.config/hexdump.cofig/xzcat.config\r
+#ARCH=mips CROSS_COMPILE=mips64el-linux-musl- make allnoconfig "CFLAGS+=-mips64r2 -mabi=64 -Os" "LDFLAGS+=-mips64r2 -mabi=64 -Os"\r
+#ARCH=mips CROSS_COMPILE=mips64el-linux-musl- make menuconfig "CFLAGS+=-mips64r2 -mabi=64 -Os" "LDFLAGS+=-mips64r2 -mabi=64 -Os"\r
+#----> enable static build\r
+#----> enable xzcat\r
+#get mips64el_xzcat.config\r
+\r
+tar xf busybox-1.32.0.tar.bz2\r
+cd busybox-1.32.0\r
+copy mips64el_xzcat.config as .config\r
+ARCH=mips CROSS_COMPILE=mips64el-linux-musl- make "CFLAGS+=-mips64r2 -mabi=64 -Os" "LDFLAGS+=-mips64r2 -mabi=64 -Os"\r
+rename ./busybox to xzcat\r
+\r
+\r
+======== How to build full busybox =========\r
+#make defconfig\r
+#make menuconfig select static build\r
\r
======== How to build ash/hexdump/xzcat for x86_64 ==========\r
#How to get ash.config/hexdump.cofig/xzcat.config\r
DSTDIR=../../IMG/cpio/ventoy/busybox
rm -f vtchmod32 vtchmod64 vtchmod64_musl vtchmodaa64
-rm -f $DSTDIR/vtchmod32 $DSTDIR/vtchmod64 $DSTDIR/vtchmodaa64
+rm -f $DSTDIR/vtchmod32 $DSTDIR/vtchmod64 $DSTDIR/vtchmodaa64 $DSTDIR/vtchmodm64e
/opt/diet32/bin/diet gcc -Os -m32 vtchmod.c -o vtchmod32
/opt/diet64/bin/diet gcc -Os vtchmod.c -o vtchmod64
aarch64-linux-gcc -Os -static vtchmod.c -o vtchmodaa64
aarch64-linux-strip --strip-all vtchmodaa64
+mips64el-linux-musl-gcc -mips64r2 -mabi=64 -Os -static vtchmod.c -o vtchmodm64e
+mips64el-linux-musl-strip --strip-all vtchmodm64e
+
+
gcc -specs "/usr/local/musl/lib/musl-gcc.specs" -Os -static vtchmod.c -o vtchmod64_musl
strip --strip-all vtchmod64_musl
chmod 777 vtchmod64
chmod 777 vtchmodaa64
chmod 777 vtchmod64_musl
+chmod 777 vtchmodm64e
cp -a vtchmod32 $DSTDIR/
cp -a vtchmod64 $DSTDIR/
cp -a vtchmodaa64 $DSTDIR/
cp -a vtchmod64_musl $DSTDIR/
+cp -a vtchmodm64e $DSTDIR/
--- /dev/null
+#
+# Automatically generated make config: don't edit
+# Busybox version: 1.32.0
+# Thu Mar 4 12:59:59 2021
+#
+CONFIG_HAVE_DOT_CONFIG=y
+
+#
+# Settings
+#
+# CONFIG_DESKTOP is not set
+# CONFIG_EXTRA_COMPAT is not set
+# CONFIG_FEDORA_COMPAT is not set
+# CONFIG_INCLUDE_SUSv2 is not set
+# CONFIG_LONG_OPTS is not set
+# CONFIG_SHOW_USAGE is not set
+# CONFIG_FEATURE_VERBOSE_USAGE is not set
+# CONFIG_FEATURE_COMPRESS_USAGE is not set
+# CONFIG_LFS is not set
+# CONFIG_PAM is not set
+# CONFIG_FEATURE_DEVPTS is not set
+# CONFIG_FEATURE_UTMP is not set
+# CONFIG_FEATURE_WTMP is not set
+# CONFIG_FEATURE_PIDFILE is not set
+CONFIG_PID_FILE_PATH=""
+# CONFIG_BUSYBOX is not set
+# CONFIG_FEATURE_SHOW_SCRIPT is not set
+# CONFIG_FEATURE_INSTALLER is not set
+# CONFIG_INSTALL_NO_USR is not set
+# CONFIG_FEATURE_SUID is not set
+# CONFIG_FEATURE_SUID_CONFIG is not set
+# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set
+# CONFIG_FEATURE_PREFER_APPLETS is not set
+CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe"
+# CONFIG_SELINUX is not set
+# CONFIG_FEATURE_CLEAN_UP is not set
+# CONFIG_FEATURE_SYSLOG_INFO is not set
+# CONFIG_FEATURE_SYSLOG is not set
+# CONFIG_PLATFORM_LINUX is not set
+
+#
+# Build Options
+#
+CONFIG_STATIC=y
+# CONFIG_PIE is not set
+# CONFIG_NOMMU is not set
+# CONFIG_BUILD_LIBBUSYBOX is not set
+# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set
+# CONFIG_FEATURE_INDIVIDUAL is not set
+# CONFIG_FEATURE_SHARED_BUSYBOX is not set
+CONFIG_CROSS_COMPILER_PREFIX=""
+CONFIG_SYSROOT=""
+CONFIG_EXTRA_CFLAGS=""
+CONFIG_EXTRA_LDFLAGS=""
+CONFIG_EXTRA_LDLIBS=""
+# CONFIG_USE_PORTABLE_CODE is not set
+# CONFIG_STACK_OPTIMIZATION_386 is not set
+
+#
+# Installation Options ("make install" behavior)
+#
+CONFIG_INSTALL_APPLET_SYMLINKS=y
+# CONFIG_INSTALL_APPLET_HARDLINKS is not set
+# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set
+# CONFIG_INSTALL_APPLET_DONT is not set
+# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set
+# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set
+# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set
+CONFIG_PREFIX="./_install"
+
+#
+# Debugging Options
+#
+# CONFIG_DEBUG is not set
+# CONFIG_DEBUG_PESSIMIZE is not set
+# CONFIG_DEBUG_SANITIZE is not set
+# CONFIG_UNIT_TEST is not set
+# CONFIG_WERROR is not set
+# CONFIG_WARN_SIMPLE_MSG is not set
+CONFIG_NO_DEBUG_LIB=y
+# CONFIG_DMALLOC is not set
+# CONFIG_EFENCE is not set
+
+#
+# Library Tuning
+#
+# CONFIG_FEATURE_USE_BSS_TAIL is not set
+# CONFIG_FLOAT_DURATION is not set
+# CONFIG_FEATURE_RTMINMAX is not set
+# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set
+CONFIG_FEATURE_BUFFERS_USE_MALLOC=y
+# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set
+# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set
+CONFIG_PASSWORD_MINLEN=6
+CONFIG_MD5_SMALL=1
+CONFIG_SHA3_SMALL=1
+# CONFIG_FEATURE_FAST_TOP is not set
+# CONFIG_FEATURE_ETC_NETWORKS is not set
+# CONFIG_FEATURE_ETC_SERVICES is not set
+# CONFIG_FEATURE_EDITING is not set
+CONFIG_FEATURE_EDITING_MAX_LEN=0
+# CONFIG_FEATURE_EDITING_VI is not set
+CONFIG_FEATURE_EDITING_HISTORY=0
+# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set
+# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set
+# CONFIG_FEATURE_REVERSE_SEARCH is not set
+# CONFIG_FEATURE_TAB_COMPLETION is not set
+# CONFIG_FEATURE_USERNAME_COMPLETION is not set
+# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set
+# CONFIG_FEATURE_EDITING_WINCH is not set
+# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set
+# CONFIG_LOCALE_SUPPORT is not set
+# CONFIG_UNICODE_SUPPORT is not set
+# CONFIG_UNICODE_USING_LOCALE is not set
+# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set
+CONFIG_SUBST_WCHAR=0
+CONFIG_LAST_SUPPORTED_WCHAR=0
+# CONFIG_UNICODE_COMBINING_WCHARS is not set
+# CONFIG_UNICODE_WIDE_WCHARS is not set
+# CONFIG_UNICODE_BIDI_SUPPORT is not set
+# CONFIG_UNICODE_NEUTRAL_TABLE is not set
+# CONFIG_UNICODE_PRESERVE_BROKEN is not set
+# CONFIG_FEATURE_NON_POSIX_CP is not set
+# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set
+# CONFIG_FEATURE_USE_SENDFILE is not set
+CONFIG_FEATURE_COPYBUF_KB=4
+# CONFIG_FEATURE_SKIP_ROOTFS is not set
+# CONFIG_MONOTONIC_SYSCALL is not set
+# CONFIG_IOCTL_HEX2STR_ERROR is not set
+# CONFIG_FEATURE_HWIB is not set
+
+#
+# Applets
+#
+
+#
+# Archival Utilities
+#
+# CONFIG_FEATURE_SEAMLESS_XZ is not set
+# CONFIG_FEATURE_SEAMLESS_LZMA is not set
+# CONFIG_FEATURE_SEAMLESS_BZ2 is not set
+# CONFIG_FEATURE_SEAMLESS_GZ is not set
+# CONFIG_FEATURE_SEAMLESS_Z is not set
+# CONFIG_AR is not set
+# CONFIG_FEATURE_AR_LONG_FILENAMES is not set
+# CONFIG_FEATURE_AR_CREATE is not set
+# CONFIG_UNCOMPRESS is not set
+# CONFIG_GUNZIP is not set
+# CONFIG_ZCAT is not set
+# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set
+# CONFIG_BUNZIP2 is not set
+# CONFIG_BZCAT is not set
+# CONFIG_UNLZMA is not set
+# CONFIG_LZCAT is not set
+# CONFIG_LZMA is not set
+# CONFIG_UNXZ is not set
+# CONFIG_XZCAT is not set
+# CONFIG_XZ is not set
+# CONFIG_BZIP2 is not set
+CONFIG_BZIP2_SMALL=0
+# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set
+# CONFIG_CPIO is not set
+# CONFIG_FEATURE_CPIO_O is not set
+# CONFIG_FEATURE_CPIO_P is not set
+# CONFIG_DPKG is not set
+# CONFIG_DPKG_DEB is not set
+# CONFIG_GZIP is not set
+# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set
+CONFIG_GZIP_FAST=0
+# CONFIG_FEATURE_GZIP_LEVELS is not set
+# CONFIG_FEATURE_GZIP_DECOMPRESS is not set
+# CONFIG_LZOP is not set
+# CONFIG_UNLZOP is not set
+# CONFIG_LZOPCAT is not set
+# CONFIG_LZOP_COMPR_HIGH is not set
+# CONFIG_RPM is not set
+# CONFIG_RPM2CPIO is not set
+# CONFIG_TAR is not set
+# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set
+# CONFIG_FEATURE_TAR_CREATE is not set
+# CONFIG_FEATURE_TAR_AUTODETECT is not set
+# CONFIG_FEATURE_TAR_FROM is not set
+# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set
+# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set
+# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set
+# CONFIG_FEATURE_TAR_TO_COMMAND is not set
+# CONFIG_FEATURE_TAR_UNAME_GNAME is not set
+# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set
+# CONFIG_FEATURE_TAR_SELINUX is not set
+# CONFIG_UNZIP is not set
+# CONFIG_FEATURE_UNZIP_CDF is not set
+# CONFIG_FEATURE_UNZIP_BZIP2 is not set
+# CONFIG_FEATURE_UNZIP_LZMA is not set
+# CONFIG_FEATURE_UNZIP_XZ is not set
+# CONFIG_FEATURE_LZMA_FAST is not set
+
+#
+# Coreutils
+#
+# CONFIG_BASENAME is not set
+# CONFIG_CAT is not set
+# CONFIG_FEATURE_CATN is not set
+# CONFIG_FEATURE_CATV is not set
+# CONFIG_CHGRP is not set
+# CONFIG_CHMOD is not set
+# CONFIG_CHOWN is not set
+# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set
+# CONFIG_CHROOT is not set
+# CONFIG_CKSUM is not set
+# CONFIG_COMM is not set
+# CONFIG_CP is not set
+# CONFIG_FEATURE_CP_LONG_OPTIONS is not set
+# CONFIG_FEATURE_CP_REFLINK is not set
+# CONFIG_CUT is not set
+# CONFIG_DATE is not set
+# CONFIG_FEATURE_DATE_ISOFMT is not set
+# CONFIG_FEATURE_DATE_NANO is not set
+# CONFIG_FEATURE_DATE_COMPAT is not set
+# CONFIG_DD is not set
+# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set
+# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set
+# CONFIG_FEATURE_DD_IBS_OBS is not set
+# CONFIG_FEATURE_DD_STATUS is not set
+# CONFIG_DF is not set
+# CONFIG_FEATURE_DF_FANCY is not set
+# CONFIG_DIRNAME is not set
+# CONFIG_DOS2UNIX is not set
+# CONFIG_UNIX2DOS is not set
+# CONFIG_DU is not set
+# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set
+# CONFIG_ECHO is not set
+# CONFIG_FEATURE_FANCY_ECHO is not set
+# CONFIG_ENV is not set
+# CONFIG_EXPAND is not set
+# CONFIG_UNEXPAND is not set
+# CONFIG_EXPR is not set
+# CONFIG_EXPR_MATH_SUPPORT_64 is not set
+# CONFIG_FACTOR is not set
+# CONFIG_FALSE is not set
+# CONFIG_FOLD is not set
+# CONFIG_HEAD is not set
+# CONFIG_FEATURE_FANCY_HEAD is not set
+# CONFIG_HOSTID is not set
+# CONFIG_ID is not set
+# CONFIG_GROUPS is not set
+# CONFIG_INSTALL is not set
+# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set
+# CONFIG_LINK is not set
+# CONFIG_LN is not set
+# CONFIG_LOGNAME is not set
+# CONFIG_LS is not set
+# CONFIG_FEATURE_LS_FILETYPES is not set
+# CONFIG_FEATURE_LS_FOLLOWLINKS is not set
+# CONFIG_FEATURE_LS_RECURSIVE is not set
+# CONFIG_FEATURE_LS_WIDTH is not set
+# CONFIG_FEATURE_LS_SORTFILES is not set
+# CONFIG_FEATURE_LS_TIMESTAMPS is not set
+# CONFIG_FEATURE_LS_USERNAME is not set
+# CONFIG_FEATURE_LS_COLOR is not set
+# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set
+# CONFIG_MD5SUM is not set
+# CONFIG_SHA1SUM is not set
+# CONFIG_SHA256SUM is not set
+# CONFIG_SHA512SUM is not set
+# CONFIG_SHA3SUM is not set
+# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set
+# CONFIG_MKDIR is not set
+# CONFIG_MKFIFO is not set
+# CONFIG_MKNOD is not set
+# CONFIG_MKTEMP is not set
+# CONFIG_MV is not set
+# CONFIG_NICE is not set
+# CONFIG_NL is not set
+# CONFIG_NOHUP is not set
+# CONFIG_NPROC is not set
+# CONFIG_OD is not set
+# CONFIG_PASTE is not set
+# CONFIG_PRINTENV is not set
+# CONFIG_PRINTF is not set
+# CONFIG_PWD is not set
+# CONFIG_READLINK is not set
+# CONFIG_FEATURE_READLINK_FOLLOW is not set
+# CONFIG_REALPATH is not set
+# CONFIG_RM is not set
+# CONFIG_RMDIR is not set
+# CONFIG_SEQ is not set
+# CONFIG_SHRED is not set
+# CONFIG_SHUF is not set
+# CONFIG_SLEEP is not set
+# CONFIG_FEATURE_FANCY_SLEEP is not set
+# CONFIG_SORT is not set
+# CONFIG_FEATURE_SORT_BIG is not set
+# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set
+# CONFIG_SPLIT is not set
+# CONFIG_FEATURE_SPLIT_FANCY is not set
+# CONFIG_STAT is not set
+# CONFIG_FEATURE_STAT_FORMAT is not set
+# CONFIG_FEATURE_STAT_FILESYSTEM is not set
+# CONFIG_STTY is not set
+# CONFIG_SUM is not set
+# CONFIG_SYNC is not set
+# CONFIG_FEATURE_SYNC_FANCY is not set
+# CONFIG_FSYNC is not set
+# CONFIG_TAC is not set
+# CONFIG_TAIL is not set
+# CONFIG_FEATURE_FANCY_TAIL is not set
+# CONFIG_TEE is not set
+# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set
+# CONFIG_TEST is not set
+# CONFIG_TEST1 is not set
+# CONFIG_TEST2 is not set
+# CONFIG_FEATURE_TEST_64 is not set
+# CONFIG_TIMEOUT is not set
+# CONFIG_TOUCH is not set
+# CONFIG_FEATURE_TOUCH_NODEREF is not set
+# CONFIG_FEATURE_TOUCH_SUSV3 is not set
+# CONFIG_TR is not set
+# CONFIG_FEATURE_TR_CLASSES is not set
+# CONFIG_FEATURE_TR_EQUIV is not set
+# CONFIG_TRUE is not set
+# CONFIG_TRUNCATE is not set
+# CONFIG_TTY is not set
+# CONFIG_UNAME is not set
+CONFIG_UNAME_OSNAME=""
+# CONFIG_BB_ARCH is not set
+# CONFIG_UNIQ is not set
+# CONFIG_UNLINK is not set
+# CONFIG_USLEEP is not set
+# CONFIG_UUDECODE is not set
+# CONFIG_BASE64 is not set
+# CONFIG_UUENCODE is not set
+# CONFIG_WC is not set
+# CONFIG_FEATURE_WC_LARGE is not set
+# CONFIG_WHOAMI is not set
+# CONFIG_WHO is not set
+# CONFIG_W is not set
+# CONFIG_USERS is not set
+# CONFIG_YES is not set
+
+#
+# Common options
+#
+# CONFIG_FEATURE_VERBOSE is not set
+# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set
+# CONFIG_FEATURE_HUMAN_READABLE is not set
+
+#
+# Console Utilities
+#
+# CONFIG_CHVT is not set
+# CONFIG_CLEAR is not set
+# CONFIG_DEALLOCVT is not set
+# CONFIG_DUMPKMAP is not set
+# CONFIG_FGCONSOLE is not set
+# CONFIG_KBD_MODE is not set
+# CONFIG_LOADFONT is not set
+# CONFIG_SETFONT is not set
+# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set
+CONFIG_DEFAULT_SETFONT_DIR=""
+# CONFIG_FEATURE_LOADFONT_PSF2 is not set
+# CONFIG_FEATURE_LOADFONT_RAW is not set
+# CONFIG_LOADKMAP is not set
+# CONFIG_OPENVT is not set
+# CONFIG_RESET is not set
+# CONFIG_RESIZE is not set
+# CONFIG_FEATURE_RESIZE_PRINT is not set
+# CONFIG_SETCONSOLE is not set
+# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set
+# CONFIG_SETKEYCODES is not set
+# CONFIG_SETLOGCONS is not set
+# CONFIG_SHOWKEY is not set
+
+#
+# Debian Utilities
+#
+# CONFIG_PIPE_PROGRESS is not set
+# CONFIG_RUN_PARTS is not set
+# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set
+# CONFIG_FEATURE_RUN_PARTS_FANCY is not set
+# CONFIG_START_STOP_DAEMON is not set
+# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set
+# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set
+# CONFIG_WHICH is not set
+
+#
+# klibc-utils
+#
+# CONFIG_MINIPS is not set
+# CONFIG_NUKE is not set
+# CONFIG_RESUME is not set
+# CONFIG_RUN_INIT is not set
+
+#
+# Editors
+#
+# CONFIG_AWK is not set
+# CONFIG_FEATURE_AWK_LIBM is not set
+# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set
+# CONFIG_CMP is not set
+# CONFIG_DIFF is not set
+# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set
+# CONFIG_FEATURE_DIFF_DIR is not set
+# CONFIG_ED is not set
+# CONFIG_PATCH is not set
+# CONFIG_SED is not set
+# CONFIG_VI is not set
+CONFIG_FEATURE_VI_MAX_LEN=0
+# CONFIG_FEATURE_VI_8BIT is not set
+# CONFIG_FEATURE_VI_COLON is not set
+# CONFIG_FEATURE_VI_YANKMARK is not set
+# CONFIG_FEATURE_VI_SEARCH is not set
+# CONFIG_FEATURE_VI_REGEX_SEARCH is not set
+# CONFIG_FEATURE_VI_USE_SIGNALS is not set
+# CONFIG_FEATURE_VI_DOT_CMD is not set
+# CONFIG_FEATURE_VI_READONLY is not set
+# CONFIG_FEATURE_VI_SETOPTS is not set
+# CONFIG_FEATURE_VI_SET is not set
+# CONFIG_FEATURE_VI_WIN_RESIZE is not set
+# CONFIG_FEATURE_VI_ASK_TERMINAL is not set
+# CONFIG_FEATURE_VI_UNDO is not set
+# CONFIG_FEATURE_VI_UNDO_QUEUE is not set
+CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0
+# CONFIG_FEATURE_ALLOW_EXEC is not set
+
+#
+# Finding Utilities
+#
+# CONFIG_FIND is not set
+# CONFIG_FEATURE_FIND_PRINT0 is not set
+# CONFIG_FEATURE_FIND_MTIME is not set
+# CONFIG_FEATURE_FIND_MMIN is not set
+# CONFIG_FEATURE_FIND_PERM is not set
+# CONFIG_FEATURE_FIND_TYPE is not set
+# CONFIG_FEATURE_FIND_EXECUTABLE is not set
+# CONFIG_FEATURE_FIND_XDEV is not set
+# CONFIG_FEATURE_FIND_MAXDEPTH is not set
+# CONFIG_FEATURE_FIND_NEWER is not set
+# CONFIG_FEATURE_FIND_INUM is not set
+# CONFIG_FEATURE_FIND_EXEC is not set
+# CONFIG_FEATURE_FIND_EXEC_PLUS is not set
+# CONFIG_FEATURE_FIND_USER is not set
+# CONFIG_FEATURE_FIND_GROUP is not set
+# CONFIG_FEATURE_FIND_NOT is not set
+# CONFIG_FEATURE_FIND_DEPTH is not set
+# CONFIG_FEATURE_FIND_PAREN is not set
+# CONFIG_FEATURE_FIND_SIZE is not set
+# CONFIG_FEATURE_FIND_PRUNE is not set
+# CONFIG_FEATURE_FIND_QUIT is not set
+# CONFIG_FEATURE_FIND_DELETE is not set
+# CONFIG_FEATURE_FIND_EMPTY is not set
+# CONFIG_FEATURE_FIND_PATH is not set
+# CONFIG_FEATURE_FIND_REGEX is not set
+# CONFIG_FEATURE_FIND_CONTEXT is not set
+# CONFIG_FEATURE_FIND_LINKS is not set
+# CONFIG_GREP is not set
+# CONFIG_EGREP is not set
+# CONFIG_FGREP is not set
+# CONFIG_FEATURE_GREP_CONTEXT is not set
+# CONFIG_XARGS is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set
+
+#
+# Init Utilities
+#
+# CONFIG_BOOTCHARTD is not set
+# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set
+# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set
+# CONFIG_HALT is not set
+# CONFIG_POWEROFF is not set
+# CONFIG_REBOOT is not set
+# CONFIG_FEATURE_WAIT_FOR_INIT is not set
+# CONFIG_FEATURE_CALL_TELINIT is not set
+CONFIG_TELINIT_PATH=""
+# CONFIG_INIT is not set
+# CONFIG_LINUXRC is not set
+# CONFIG_FEATURE_USE_INITTAB is not set
+# CONFIG_FEATURE_KILL_REMOVED is not set
+CONFIG_FEATURE_KILL_DELAY=0
+# CONFIG_FEATURE_INIT_SCTTY is not set
+# CONFIG_FEATURE_INIT_SYSLOG is not set
+# CONFIG_FEATURE_INIT_QUIET is not set
+# CONFIG_FEATURE_INIT_COREDUMPS is not set
+CONFIG_INIT_TERMINAL_TYPE=""
+# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set
+
+#
+# Login/Password Management Utilities
+#
+# CONFIG_FEATURE_SHADOWPASSWDS is not set
+# CONFIG_USE_BB_PWD_GRP is not set
+# CONFIG_USE_BB_SHADOW is not set
+# CONFIG_USE_BB_CRYPT is not set
+# CONFIG_USE_BB_CRYPT_SHA is not set
+# CONFIG_ADDGROUP is not set
+# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set
+# CONFIG_ADD_SHELL is not set
+# CONFIG_REMOVE_SHELL is not set
+# CONFIG_ADDUSER is not set
+# CONFIG_FEATURE_CHECK_NAMES is not set
+CONFIG_LAST_ID=0
+CONFIG_FIRST_SYSTEM_ID=0
+CONFIG_LAST_SYSTEM_ID=0
+# CONFIG_CHPASSWD is not set
+CONFIG_FEATURE_DEFAULT_PASSWD_ALGO=""
+# CONFIG_CRYPTPW is not set
+# CONFIG_MKPASSWD is not set
+# CONFIG_DELUSER is not set
+# CONFIG_DELGROUP is not set
+# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set
+# CONFIG_GETTY is not set
+# CONFIG_LOGIN is not set
+# CONFIG_LOGIN_SESSION_AS_CHILD is not set
+# CONFIG_LOGIN_SCRIPTS is not set
+# CONFIG_FEATURE_NOLOGIN is not set
+# CONFIG_FEATURE_SECURETTY is not set
+# CONFIG_PASSWD is not set
+# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set
+# CONFIG_SU is not set
+# CONFIG_FEATURE_SU_SYSLOG is not set
+# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set
+# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set
+# CONFIG_SULOGIN is not set
+# CONFIG_VLOCK is not set
+
+#
+# Linux Ext2 FS Progs
+#
+# CONFIG_CHATTR is not set
+# CONFIG_FSCK is not set
+# CONFIG_LSATTR is not set
+# CONFIG_TUNE2FS is not set
+
+#
+# Linux Module Utilities
+#
+# CONFIG_MODPROBE_SMALL is not set
+# CONFIG_DEPMOD is not set
+# CONFIG_INSMOD is not set
+# CONFIG_LSMOD is not set
+# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set
+# CONFIG_MODINFO is not set
+# CONFIG_MODPROBE is not set
+# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set
+# CONFIG_RMMOD is not set
+
+#
+# Options common to multiple modutils
+#
+# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set
+# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set
+# CONFIG_FEATURE_2_4_MODULES is not set
+# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set
+# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set
+# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set
+# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set
+# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set
+# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set
+# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set
+# CONFIG_FEATURE_MODUTILS_ALIAS is not set
+# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set
+CONFIG_DEFAULT_MODULES_DIR=""
+CONFIG_DEFAULT_DEPMOD_FILE=""
+
+#
+# Linux System Utilities
+#
+# CONFIG_ACPID is not set
+# CONFIG_FEATURE_ACPID_COMPAT is not set
+# CONFIG_BLKDISCARD is not set
+# CONFIG_BLKID is not set
+# CONFIG_FEATURE_BLKID_TYPE is not set
+# CONFIG_BLOCKDEV is not set
+# CONFIG_CAL is not set
+# CONFIG_CHRT is not set
+# CONFIG_DMESG is not set
+# CONFIG_FEATURE_DMESG_PRETTY is not set
+# CONFIG_EJECT is not set
+# CONFIG_FEATURE_EJECT_SCSI is not set
+# CONFIG_FALLOCATE is not set
+# CONFIG_FATATTR is not set
+# CONFIG_FBSET is not set
+# CONFIG_FEATURE_FBSET_FANCY is not set
+# CONFIG_FEATURE_FBSET_READMODE is not set
+# CONFIG_FDFORMAT is not set
+# CONFIG_FDISK is not set
+# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set
+# CONFIG_FEATURE_FDISK_WRITABLE is not set
+# CONFIG_FEATURE_AIX_LABEL is not set
+# CONFIG_FEATURE_SGI_LABEL is not set
+# CONFIG_FEATURE_SUN_LABEL is not set
+# CONFIG_FEATURE_OSF_LABEL is not set
+# CONFIG_FEATURE_GPT_LABEL is not set
+# CONFIG_FEATURE_FDISK_ADVANCED is not set
+# CONFIG_FINDFS is not set
+# CONFIG_FLOCK is not set
+# CONFIG_FDFLUSH is not set
+# CONFIG_FREERAMDISK is not set
+# CONFIG_FSCK_MINIX is not set
+# CONFIG_FSFREEZE is not set
+# CONFIG_FSTRIM is not set
+# CONFIG_GETOPT is not set
+# CONFIG_FEATURE_GETOPT_LONG is not set
+# CONFIG_HEXDUMP is not set
+# CONFIG_FEATURE_HEXDUMP_REVERSE is not set
+# CONFIG_HD is not set
+# CONFIG_XXD is not set
+# CONFIG_HWCLOCK is not set
+# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set
+# CONFIG_IONICE is not set
+# CONFIG_IPCRM is not set
+# CONFIG_IPCS is not set
+# CONFIG_LAST is not set
+# CONFIG_FEATURE_LAST_FANCY is not set
+# CONFIG_LOSETUP is not set
+# CONFIG_LSPCI is not set
+# CONFIG_LSUSB is not set
+# CONFIG_MDEV is not set
+# CONFIG_FEATURE_MDEV_CONF is not set
+# CONFIG_FEATURE_MDEV_RENAME is not set
+# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set
+# CONFIG_FEATURE_MDEV_EXEC is not set
+# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set
+# CONFIG_FEATURE_MDEV_DAEMON is not set
+# CONFIG_MESG is not set
+# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set
+# CONFIG_MKE2FS is not set
+# CONFIG_MKFS_EXT2 is not set
+# CONFIG_MKFS_MINIX is not set
+# CONFIG_FEATURE_MINIX2 is not set
+# CONFIG_MKFS_REISER is not set
+# CONFIG_MKDOSFS is not set
+# CONFIG_MKFS_VFAT is not set
+# CONFIG_MKSWAP is not set
+# CONFIG_FEATURE_MKSWAP_UUID is not set
+# CONFIG_MORE is not set
+# CONFIG_MOUNT is not set
+# CONFIG_FEATURE_MOUNT_FAKE is not set
+# CONFIG_FEATURE_MOUNT_VERBOSE is not set
+# CONFIG_FEATURE_MOUNT_HELPERS is not set
+# CONFIG_FEATURE_MOUNT_LABEL is not set
+# CONFIG_FEATURE_MOUNT_NFS is not set
+# CONFIG_FEATURE_MOUNT_CIFS is not set
+# CONFIG_FEATURE_MOUNT_FLAGS is not set
+# CONFIG_FEATURE_MOUNT_FSTAB is not set
+# CONFIG_FEATURE_MOUNT_OTHERTAB is not set
+# CONFIG_MOUNTPOINT is not set
+# CONFIG_NOLOGIN is not set
+# CONFIG_NOLOGIN_DEPENDENCIES is not set
+# CONFIG_NSENTER is not set
+# CONFIG_PIVOT_ROOT is not set
+# CONFIG_RDATE is not set
+# CONFIG_RDEV is not set
+# CONFIG_READPROFILE is not set
+# CONFIG_RENICE is not set
+# CONFIG_REV is not set
+# CONFIG_RTCWAKE is not set
+# CONFIG_SCRIPT is not set
+# CONFIG_SCRIPTREPLAY is not set
+# CONFIG_SETARCH is not set
+# CONFIG_LINUX32 is not set
+# CONFIG_LINUX64 is not set
+# CONFIG_SETPRIV is not set
+# CONFIG_FEATURE_SETPRIV_DUMP is not set
+# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set
+# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set
+# CONFIG_SETSID is not set
+# CONFIG_SWAPON is not set
+# CONFIG_FEATURE_SWAPON_DISCARD is not set
+# CONFIG_FEATURE_SWAPON_PRI is not set
+# CONFIG_SWAPOFF is not set
+# CONFIG_FEATURE_SWAPONOFF_LABEL is not set
+# CONFIG_SWITCH_ROOT is not set
+# CONFIG_TASKSET is not set
+# CONFIG_FEATURE_TASKSET_FANCY is not set
+# CONFIG_FEATURE_TASKSET_CPULIST is not set
+# CONFIG_UEVENT is not set
+# CONFIG_UMOUNT is not set
+# CONFIG_FEATURE_UMOUNT_ALL is not set
+# CONFIG_UNSHARE is not set
+# CONFIG_WALL is not set
+# CONFIG_FEATURE_MOUNT_LOOP is not set
+# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set
+# CONFIG_FEATURE_MTAB_SUPPORT is not set
+# CONFIG_VOLUMEID is not set
+# CONFIG_FEATURE_VOLUMEID_BCACHE is not set
+# CONFIG_FEATURE_VOLUMEID_BTRFS is not set
+# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set
+# CONFIG_FEATURE_VOLUMEID_EXFAT is not set
+# CONFIG_FEATURE_VOLUMEID_EXT is not set
+# CONFIG_FEATURE_VOLUMEID_F2FS is not set
+# CONFIG_FEATURE_VOLUMEID_FAT is not set
+# CONFIG_FEATURE_VOLUMEID_HFS is not set
+# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set
+# CONFIG_FEATURE_VOLUMEID_JFS is not set
+# CONFIG_FEATURE_VOLUMEID_LFS is not set
+# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set
+# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set
+# CONFIG_FEATURE_VOLUMEID_LUKS is not set
+# CONFIG_FEATURE_VOLUMEID_MINIX is not set
+# CONFIG_FEATURE_VOLUMEID_NILFS is not set
+# CONFIG_FEATURE_VOLUMEID_NTFS is not set
+# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set
+# CONFIG_FEATURE_VOLUMEID_REISERFS is not set
+# CONFIG_FEATURE_VOLUMEID_ROMFS is not set
+# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set
+# CONFIG_FEATURE_VOLUMEID_SYSV is not set
+# CONFIG_FEATURE_VOLUMEID_UBIFS is not set
+# CONFIG_FEATURE_VOLUMEID_UDF is not set
+# CONFIG_FEATURE_VOLUMEID_XFS is not set
+
+#
+# Miscellaneous Utilities
+#
+# CONFIG_ADJTIMEX is not set
+# CONFIG_BBCONFIG is not set
+# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set
+# CONFIG_BC is not set
+# CONFIG_DC is not set
+# CONFIG_FEATURE_DC_BIG is not set
+# CONFIG_FEATURE_DC_LIBM is not set
+# CONFIG_FEATURE_BC_INTERACTIVE is not set
+# CONFIG_FEATURE_BC_LONG_OPTIONS is not set
+# CONFIG_BEEP is not set
+CONFIG_FEATURE_BEEP_FREQ=0
+CONFIG_FEATURE_BEEP_LENGTH_MS=0
+# CONFIG_CHAT is not set
+# CONFIG_FEATURE_CHAT_NOFAIL is not set
+# CONFIG_FEATURE_CHAT_TTY_HIFI is not set
+# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set
+# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set
+# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set
+# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set
+# CONFIG_FEATURE_CHAT_CLR_ABORT is not set
+# CONFIG_CONSPY is not set
+# CONFIG_CROND is not set
+# CONFIG_FEATURE_CROND_D is not set
+# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set
+# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set
+CONFIG_FEATURE_CROND_DIR=""
+# CONFIG_CRONTAB is not set
+# CONFIG_DEVFSD is not set
+# CONFIG_DEVFSD_MODLOAD is not set
+# CONFIG_DEVFSD_FG_NP is not set
+# CONFIG_DEVFSD_VERBOSE is not set
+# CONFIG_FEATURE_DEVFS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_FBSPLASH is not set
+# CONFIG_FLASHCP is not set
+# CONFIG_FLASH_ERASEALL is not set
+# CONFIG_FLASH_LOCK is not set
+# CONFIG_FLASH_UNLOCK is not set
+# CONFIG_HDPARM is not set
+# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set
+# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set
+# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set
+# CONFIG_HEXEDIT is not set
+# CONFIG_I2CGET is not set
+# CONFIG_I2CSET is not set
+# CONFIG_I2CDUMP is not set
+# CONFIG_I2CDETECT is not set
+# CONFIG_I2CTRANSFER is not set
+# CONFIG_INOTIFYD is not set
+# CONFIG_LESS is not set
+CONFIG_FEATURE_LESS_MAXLINES=0
+# CONFIG_FEATURE_LESS_BRACKETS is not set
+# CONFIG_FEATURE_LESS_FLAGS is not set
+# CONFIG_FEATURE_LESS_TRUNCATE is not set
+# CONFIG_FEATURE_LESS_MARKS is not set
+# CONFIG_FEATURE_LESS_REGEXP is not set
+# CONFIG_FEATURE_LESS_WINCH is not set
+# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set
+# CONFIG_FEATURE_LESS_DASHCMD is not set
+# CONFIG_FEATURE_LESS_LINENUMS is not set
+# CONFIG_FEATURE_LESS_RAW is not set
+# CONFIG_FEATURE_LESS_ENV is not set
+# CONFIG_LSSCSI is not set
+# CONFIG_MAKEDEVS is not set
+# CONFIG_FEATURE_MAKEDEVS_LEAF is not set
+# CONFIG_FEATURE_MAKEDEVS_TABLE is not set
+# CONFIG_MAN is not set
+# CONFIG_MICROCOM is not set
+# CONFIG_MIM is not set
+# CONFIG_MT is not set
+# CONFIG_NANDWRITE is not set
+# CONFIG_NANDDUMP is not set
+# CONFIG_PARTPROBE is not set
+# CONFIG_RAIDAUTORUN is not set
+# CONFIG_READAHEAD is not set
+# CONFIG_RFKILL is not set
+# CONFIG_RUNLEVEL is not set
+# CONFIG_RX is not set
+# CONFIG_SETFATTR is not set
+# CONFIG_SETSERIAL is not set
+# CONFIG_STRINGS is not set
+# CONFIG_TIME is not set
+# CONFIG_TS is not set
+# CONFIG_TTYSIZE is not set
+# CONFIG_UBIRENAME is not set
+# CONFIG_UBIATTACH is not set
+# CONFIG_UBIDETACH is not set
+# CONFIG_UBIMKVOL is not set
+# CONFIG_UBIRMVOL is not set
+# CONFIG_UBIRSVOL is not set
+# CONFIG_UBIUPDATEVOL is not set
+# CONFIG_VOLNAME is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Networking Utilities
+#
+# CONFIG_FEATURE_IPV6 is not set
+# CONFIG_FEATURE_UNIX_LOCAL is not set
+# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set
+# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set
+# CONFIG_FEATURE_TLS_SHA1 is not set
+# CONFIG_ARP is not set
+# CONFIG_ARPING is not set
+# CONFIG_BRCTL is not set
+# CONFIG_FEATURE_BRCTL_FANCY is not set
+# CONFIG_FEATURE_BRCTL_SHOW is not set
+# CONFIG_DNSD is not set
+# CONFIG_ETHER_WAKE is not set
+# CONFIG_FTPD is not set
+# CONFIG_FEATURE_FTPD_WRITE is not set
+# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set
+# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set
+# CONFIG_FTPGET is not set
+# CONFIG_FTPPUT is not set
+# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set
+# CONFIG_HOSTNAME is not set
+# CONFIG_DNSDOMAINNAME is not set
+# CONFIG_HTTPD is not set
+# CONFIG_FEATURE_HTTPD_RANGES is not set
+# CONFIG_FEATURE_HTTPD_SETUID is not set
+# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set
+# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set
+# CONFIG_FEATURE_HTTPD_CGI is not set
+# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set
+# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set
+# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set
+# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set
+# CONFIG_FEATURE_HTTPD_PROXY is not set
+# CONFIG_FEATURE_HTTPD_GZIP is not set
+# CONFIG_IFCONFIG is not set
+# CONFIG_FEATURE_IFCONFIG_STATUS is not set
+# CONFIG_FEATURE_IFCONFIG_SLIP is not set
+# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set
+# CONFIG_FEATURE_IFCONFIG_HW is not set
+# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set
+# CONFIG_IFENSLAVE is not set
+# CONFIG_IFPLUGD is not set
+# CONFIG_IFUP is not set
+# CONFIG_IFDOWN is not set
+CONFIG_IFUPDOWN_IFSTATE_PATH=""
+# CONFIG_FEATURE_IFUPDOWN_IP is not set
+# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set
+# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set
+# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set
+# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set
+# CONFIG_INETD is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set
+# CONFIG_FEATURE_INETD_RPC is not set
+# CONFIG_IP is not set
+# CONFIG_IPADDR is not set
+# CONFIG_IPLINK is not set
+# CONFIG_IPROUTE is not set
+# CONFIG_IPTUNNEL is not set
+# CONFIG_IPRULE is not set
+# CONFIG_IPNEIGH is not set
+# CONFIG_FEATURE_IP_ADDRESS is not set
+# CONFIG_FEATURE_IP_LINK is not set
+# CONFIG_FEATURE_IP_ROUTE is not set
+CONFIG_FEATURE_IP_ROUTE_DIR=""
+# CONFIG_FEATURE_IP_TUNNEL is not set
+# CONFIG_FEATURE_IP_RULE is not set
+# CONFIG_FEATURE_IP_NEIGH is not set
+# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set
+# CONFIG_IPCALC is not set
+# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set
+# CONFIG_FEATURE_IPCALC_FANCY is not set
+# CONFIG_FAKEIDENTD is not set
+# CONFIG_NAMEIF is not set
+# CONFIG_FEATURE_NAMEIF_EXTENDED is not set
+# CONFIG_NBDCLIENT is not set
+# CONFIG_NC is not set
+# CONFIG_NETCAT is not set
+# CONFIG_NC_SERVER is not set
+# CONFIG_NC_EXTRA is not set
+# CONFIG_NC_110_COMPAT is not set
+# CONFIG_NETSTAT is not set
+# CONFIG_FEATURE_NETSTAT_WIDE is not set
+# CONFIG_FEATURE_NETSTAT_PRG is not set
+# CONFIG_NSLOOKUP is not set
+# CONFIG_FEATURE_NSLOOKUP_BIG is not set
+# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set
+# CONFIG_NTPD is not set
+# CONFIG_FEATURE_NTPD_SERVER is not set
+# CONFIG_FEATURE_NTPD_CONF is not set
+# CONFIG_FEATURE_NTP_AUTH is not set
+# CONFIG_PING is not set
+# CONFIG_PING6 is not set
+# CONFIG_FEATURE_FANCY_PING is not set
+# CONFIG_PSCAN is not set
+# CONFIG_ROUTE is not set
+# CONFIG_SLATTACH is not set
+# CONFIG_SSL_CLIENT is not set
+# CONFIG_TC is not set
+# CONFIG_FEATURE_TC_INGRESS is not set
+# CONFIG_TCPSVD is not set
+# CONFIG_UDPSVD is not set
+# CONFIG_TELNET is not set
+# CONFIG_FEATURE_TELNET_TTYPE is not set
+# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set
+# CONFIG_FEATURE_TELNET_WIDTH is not set
+# CONFIG_TELNETD is not set
+# CONFIG_FEATURE_TELNETD_STANDALONE is not set
+# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set
+# CONFIG_TFTP is not set
+# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set
+# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set
+# CONFIG_TFTPD is not set
+# CONFIG_FEATURE_TFTP_GET is not set
+# CONFIG_FEATURE_TFTP_PUT is not set
+# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set
+# CONFIG_TFTP_DEBUG is not set
+# CONFIG_TLS is not set
+# CONFIG_TRACEROUTE is not set
+# CONFIG_TRACEROUTE6 is not set
+# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
+# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
+# CONFIG_TUNCTL is not set
+# CONFIG_FEATURE_TUNCTL_UG is not set
+# CONFIG_VCONFIG is not set
+# CONFIG_WGET is not set
+# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set
+# CONFIG_FEATURE_WGET_STATUSBAR is not set
+# CONFIG_FEATURE_WGET_AUTHENTICATION is not set
+# CONFIG_FEATURE_WGET_TIMEOUT is not set
+# CONFIG_FEATURE_WGET_HTTPS is not set
+# CONFIG_FEATURE_WGET_OPENSSL is not set
+# CONFIG_WHOIS is not set
+# CONFIG_ZCIP is not set
+# CONFIG_UDHCPD is not set
+# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set
+# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set
+CONFIG_DHCPD_LEASES_FILE=""
+# CONFIG_DUMPLEASES is not set
+# CONFIG_DHCPRELAY is not set
+# CONFIG_UDHCPC is not set
+# CONFIG_FEATURE_UDHCPC_ARPING is not set
+# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set
+CONFIG_UDHCPC_DEFAULT_SCRIPT=""
+# CONFIG_UDHCPC6 is not set
+# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set
+# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set
+# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set
+# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set
+# CONFIG_FEATURE_UDHCP_PORT is not set
+CONFIG_UDHCP_DEBUG=0
+CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0
+# CONFIG_FEATURE_UDHCP_RFC3397 is not set
+# CONFIG_FEATURE_UDHCP_8021Q is not set
+CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS=""
+
+#
+# Print Utilities
+#
+# CONFIG_LPD is not set
+# CONFIG_LPR is not set
+# CONFIG_LPQ is not set
+
+#
+# Mail Utilities
+#
+# CONFIG_MAKEMIME is not set
+# CONFIG_POPMAILDIR is not set
+# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set
+# CONFIG_REFORMIME is not set
+# CONFIG_FEATURE_REFORMIME_COMPAT is not set
+# CONFIG_SENDMAIL is not set
+CONFIG_FEATURE_MIME_CHARSET=""
+
+#
+# Process Utilities
+#
+# CONFIG_FREE is not set
+# CONFIG_FUSER is not set
+# CONFIG_IOSTAT is not set
+# CONFIG_KILL is not set
+# CONFIG_KILLALL is not set
+# CONFIG_KILLALL5 is not set
+# CONFIG_LSOF is not set
+# CONFIG_MPSTAT is not set
+# CONFIG_NMETER is not set
+# CONFIG_PGREP is not set
+# CONFIG_PKILL is not set
+# CONFIG_PIDOF is not set
+# CONFIG_FEATURE_PIDOF_SINGLE is not set
+# CONFIG_FEATURE_PIDOF_OMIT is not set
+# CONFIG_PMAP is not set
+# CONFIG_POWERTOP is not set
+# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set
+# CONFIG_PS is not set
+# CONFIG_FEATURE_PS_WIDE is not set
+# CONFIG_FEATURE_PS_LONG is not set
+# CONFIG_FEATURE_PS_TIME is not set
+# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set
+# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set
+# CONFIG_PSTREE is not set
+# CONFIG_PWDX is not set
+# CONFIG_SMEMCAP is not set
+# CONFIG_BB_SYSCTL is not set
+# CONFIG_TOP is not set
+# CONFIG_FEATURE_TOP_INTERACTIVE is not set
+# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set
+# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set
+# CONFIG_FEATURE_TOP_SMP_CPU is not set
+# CONFIG_FEATURE_TOP_DECIMALS is not set
+# CONFIG_FEATURE_TOP_SMP_PROCESS is not set
+# CONFIG_FEATURE_TOPMEM is not set
+# CONFIG_UPTIME is not set
+# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set
+# CONFIG_WATCH is not set
+# CONFIG_FEATURE_SHOW_THREADS is not set
+
+#
+# Runit Utilities
+#
+# CONFIG_CHPST is not set
+# CONFIG_SETUIDGID is not set
+# CONFIG_ENVUIDGID is not set
+# CONFIG_ENVDIR is not set
+# CONFIG_SOFTLIMIT is not set
+# CONFIG_RUNSV is not set
+# CONFIG_RUNSVDIR is not set
+# CONFIG_FEATURE_RUNSVDIR_LOG is not set
+# CONFIG_SV is not set
+CONFIG_SV_DEFAULT_SERVICE_DIR=""
+# CONFIG_SVC is not set
+# CONFIG_SVOK is not set
+# CONFIG_SVLOGD is not set
+# CONFIG_CHCON is not set
+# CONFIG_GETENFORCE is not set
+# CONFIG_GETSEBOOL is not set
+# CONFIG_LOAD_POLICY is not set
+# CONFIG_MATCHPATHCON is not set
+# CONFIG_RUNCON is not set
+# CONFIG_SELINUXENABLED is not set
+# CONFIG_SESTATUS is not set
+# CONFIG_SETENFORCE is not set
+# CONFIG_SETFILES is not set
+# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set
+# CONFIG_RESTORECON is not set
+# CONFIG_SETSEBOOL is not set
+
+#
+# Shells
+#
+CONFIG_SH_IS_ASH=y
+# CONFIG_SH_IS_HUSH is not set
+# CONFIG_SH_IS_NONE is not set
+# CONFIG_BASH_IS_ASH is not set
+# CONFIG_BASH_IS_HUSH is not set
+CONFIG_BASH_IS_NONE=y
+CONFIG_SHELL_ASH=y
+CONFIG_ASH=y
+# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set
+# CONFIG_ASH_INTERNAL_GLOB is not set
+# CONFIG_ASH_BASH_COMPAT is not set
+# CONFIG_ASH_BASH_SOURCE_CURDIR is not set
+# CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set
+# CONFIG_ASH_JOB_CONTROL is not set
+# CONFIG_ASH_ALIAS is not set
+# CONFIG_ASH_RANDOM_SUPPORT is not set
+# CONFIG_ASH_EXPAND_PRMT is not set
+# CONFIG_ASH_IDLE_TIMEOUT is not set
+# CONFIG_ASH_MAIL is not set
+# CONFIG_ASH_ECHO is not set
+# CONFIG_ASH_PRINTF is not set
+# CONFIG_ASH_TEST is not set
+# CONFIG_ASH_HELP is not set
+# CONFIG_ASH_GETOPTS is not set
+# CONFIG_ASH_CMDCMD is not set
+# CONFIG_CTTYHACK is not set
+# CONFIG_HUSH is not set
+# CONFIG_SHELL_HUSH is not set
+# CONFIG_HUSH_BASH_COMPAT is not set
+# CONFIG_HUSH_BRACE_EXPANSION is not set
+# CONFIG_HUSH_LINENO_VAR is not set
+# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set
+# CONFIG_HUSH_INTERACTIVE is not set
+# CONFIG_HUSH_SAVEHISTORY is not set
+# CONFIG_HUSH_JOB is not set
+# CONFIG_HUSH_TICK is not set
+# CONFIG_HUSH_IF is not set
+# CONFIG_HUSH_LOOPS is not set
+# CONFIG_HUSH_CASE is not set
+# CONFIG_HUSH_FUNCTIONS is not set
+# CONFIG_HUSH_LOCAL is not set
+# CONFIG_HUSH_RANDOM_SUPPORT is not set
+# CONFIG_HUSH_MODE_X is not set
+# CONFIG_HUSH_ECHO is not set
+# CONFIG_HUSH_PRINTF is not set
+# CONFIG_HUSH_TEST is not set
+# CONFIG_HUSH_HELP is not set
+# CONFIG_HUSH_EXPORT is not set
+# CONFIG_HUSH_EXPORT_N is not set
+# CONFIG_HUSH_READONLY is not set
+# CONFIG_HUSH_KILL is not set
+# CONFIG_HUSH_WAIT is not set
+# CONFIG_HUSH_COMMAND is not set
+# CONFIG_HUSH_TRAP is not set
+# CONFIG_HUSH_TYPE is not set
+# CONFIG_HUSH_TIMES is not set
+# CONFIG_HUSH_READ is not set
+# CONFIG_HUSH_SET is not set
+# CONFIG_HUSH_UNSET is not set
+# CONFIG_HUSH_ULIMIT is not set
+# CONFIG_HUSH_UMASK is not set
+# CONFIG_HUSH_GETOPTS is not set
+# CONFIG_HUSH_MEMLEAK is not set
+
+#
+# Options common to all shells
+#
+# CONFIG_FEATURE_SH_MATH is not set
+# CONFIG_FEATURE_SH_MATH_64 is not set
+# CONFIG_FEATURE_SH_MATH_BASE is not set
+# CONFIG_FEATURE_SH_EXTRA_QUIET is not set
+# CONFIG_FEATURE_SH_STANDALONE is not set
+# CONFIG_FEATURE_SH_NOFORK is not set
+# CONFIG_FEATURE_SH_READ_FRAC is not set
+# CONFIG_FEATURE_SH_HISTFILESIZE is not set
+# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set
+
+#
+# System Logging Utilities
+#
+# CONFIG_KLOGD is not set
+# CONFIG_FEATURE_KLOGD_KLOGCTL is not set
+# CONFIG_LOGGER is not set
+# CONFIG_LOGREAD is not set
+# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set
+# CONFIG_SYSLOGD is not set
+# CONFIG_FEATURE_ROTATE_LOGFILE is not set
+# CONFIG_FEATURE_REMOTE_LOG is not set
+# CONFIG_FEATURE_SYSLOGD_DUP is not set
+# CONFIG_FEATURE_SYSLOGD_CFG is not set
+# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set
+CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0
+# CONFIG_FEATURE_IPC_SYSLOG is not set
+CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0
+# CONFIG_FEATURE_KMSG_SYSLOG is not set
--- /dev/null
+#
+# Automatically generated make config: don't edit
+# Busybox version: 1.32.0
+# Thu Mar 4 13:08:09 2021
+#
+CONFIG_HAVE_DOT_CONFIG=y
+
+#
+# Settings
+#
+# CONFIG_DESKTOP is not set
+# CONFIG_EXTRA_COMPAT is not set
+# CONFIG_FEDORA_COMPAT is not set
+# CONFIG_INCLUDE_SUSv2 is not set
+# CONFIG_LONG_OPTS is not set
+# CONFIG_SHOW_USAGE is not set
+# CONFIG_FEATURE_VERBOSE_USAGE is not set
+# CONFIG_FEATURE_COMPRESS_USAGE is not set
+# CONFIG_LFS is not set
+# CONFIG_PAM is not set
+# CONFIG_FEATURE_DEVPTS is not set
+# CONFIG_FEATURE_UTMP is not set
+# CONFIG_FEATURE_WTMP is not set
+# CONFIG_FEATURE_PIDFILE is not set
+CONFIG_PID_FILE_PATH=""
+# CONFIG_BUSYBOX is not set
+# CONFIG_FEATURE_SHOW_SCRIPT is not set
+# CONFIG_FEATURE_INSTALLER is not set
+# CONFIG_INSTALL_NO_USR is not set
+# CONFIG_FEATURE_SUID is not set
+# CONFIG_FEATURE_SUID_CONFIG is not set
+# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set
+# CONFIG_FEATURE_PREFER_APPLETS is not set
+CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe"
+# CONFIG_SELINUX is not set
+# CONFIG_FEATURE_CLEAN_UP is not set
+# CONFIG_FEATURE_SYSLOG_INFO is not set
+# CONFIG_FEATURE_SYSLOG is not set
+# CONFIG_PLATFORM_LINUX is not set
+
+#
+# Build Options
+#
+CONFIG_STATIC=y
+# CONFIG_PIE is not set
+# CONFIG_NOMMU is not set
+# CONFIG_BUILD_LIBBUSYBOX is not set
+# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set
+# CONFIG_FEATURE_INDIVIDUAL is not set
+# CONFIG_FEATURE_SHARED_BUSYBOX is not set
+CONFIG_CROSS_COMPILER_PREFIX=""
+CONFIG_SYSROOT=""
+CONFIG_EXTRA_CFLAGS=""
+CONFIG_EXTRA_LDFLAGS=""
+CONFIG_EXTRA_LDLIBS=""
+# CONFIG_USE_PORTABLE_CODE is not set
+# CONFIG_STACK_OPTIMIZATION_386 is not set
+
+#
+# Installation Options ("make install" behavior)
+#
+CONFIG_INSTALL_APPLET_SYMLINKS=y
+# CONFIG_INSTALL_APPLET_HARDLINKS is not set
+# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set
+# CONFIG_INSTALL_APPLET_DONT is not set
+# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set
+# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set
+# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set
+CONFIG_PREFIX="./_install"
+
+#
+# Debugging Options
+#
+# CONFIG_DEBUG is not set
+# CONFIG_DEBUG_PESSIMIZE is not set
+# CONFIG_DEBUG_SANITIZE is not set
+# CONFIG_UNIT_TEST is not set
+# CONFIG_WERROR is not set
+# CONFIG_WARN_SIMPLE_MSG is not set
+CONFIG_NO_DEBUG_LIB=y
+# CONFIG_DMALLOC is not set
+# CONFIG_EFENCE is not set
+
+#
+# Library Tuning
+#
+# CONFIG_FEATURE_USE_BSS_TAIL is not set
+# CONFIG_FLOAT_DURATION is not set
+# CONFIG_FEATURE_RTMINMAX is not set
+# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set
+CONFIG_FEATURE_BUFFERS_USE_MALLOC=y
+# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set
+# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set
+CONFIG_PASSWORD_MINLEN=6
+CONFIG_MD5_SMALL=1
+CONFIG_SHA3_SMALL=1
+# CONFIG_FEATURE_FAST_TOP is not set
+# CONFIG_FEATURE_ETC_NETWORKS is not set
+# CONFIG_FEATURE_ETC_SERVICES is not set
+# CONFIG_FEATURE_EDITING is not set
+CONFIG_FEATURE_EDITING_MAX_LEN=0
+# CONFIG_FEATURE_EDITING_VI is not set
+CONFIG_FEATURE_EDITING_HISTORY=0
+# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set
+# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set
+# CONFIG_FEATURE_REVERSE_SEARCH is not set
+# CONFIG_FEATURE_TAB_COMPLETION is not set
+# CONFIG_FEATURE_USERNAME_COMPLETION is not set
+# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set
+# CONFIG_FEATURE_EDITING_WINCH is not set
+# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set
+# CONFIG_LOCALE_SUPPORT is not set
+# CONFIG_UNICODE_SUPPORT is not set
+# CONFIG_UNICODE_USING_LOCALE is not set
+# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set
+CONFIG_SUBST_WCHAR=0
+CONFIG_LAST_SUPPORTED_WCHAR=0
+# CONFIG_UNICODE_COMBINING_WCHARS is not set
+# CONFIG_UNICODE_WIDE_WCHARS is not set
+# CONFIG_UNICODE_BIDI_SUPPORT is not set
+# CONFIG_UNICODE_NEUTRAL_TABLE is not set
+# CONFIG_UNICODE_PRESERVE_BROKEN is not set
+# CONFIG_FEATURE_NON_POSIX_CP is not set
+# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set
+# CONFIG_FEATURE_USE_SENDFILE is not set
+CONFIG_FEATURE_COPYBUF_KB=4
+# CONFIG_FEATURE_SKIP_ROOTFS is not set
+# CONFIG_MONOTONIC_SYSCALL is not set
+# CONFIG_IOCTL_HEX2STR_ERROR is not set
+# CONFIG_FEATURE_HWIB is not set
+
+#
+# Applets
+#
+
+#
+# Archival Utilities
+#
+# CONFIG_FEATURE_SEAMLESS_XZ is not set
+# CONFIG_FEATURE_SEAMLESS_LZMA is not set
+# CONFIG_FEATURE_SEAMLESS_BZ2 is not set
+# CONFIG_FEATURE_SEAMLESS_GZ is not set
+# CONFIG_FEATURE_SEAMLESS_Z is not set
+# CONFIG_AR is not set
+# CONFIG_FEATURE_AR_LONG_FILENAMES is not set
+# CONFIG_FEATURE_AR_CREATE is not set
+# CONFIG_UNCOMPRESS is not set
+# CONFIG_GUNZIP is not set
+# CONFIG_ZCAT is not set
+# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set
+# CONFIG_BUNZIP2 is not set
+# CONFIG_BZCAT is not set
+# CONFIG_UNLZMA is not set
+# CONFIG_LZCAT is not set
+# CONFIG_LZMA is not set
+# CONFIG_UNXZ is not set
+# CONFIG_XZCAT is not set
+# CONFIG_XZ is not set
+# CONFIG_BZIP2 is not set
+CONFIG_BZIP2_SMALL=0
+# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set
+# CONFIG_CPIO is not set
+# CONFIG_FEATURE_CPIO_O is not set
+# CONFIG_FEATURE_CPIO_P is not set
+# CONFIG_DPKG is not set
+# CONFIG_DPKG_DEB is not set
+# CONFIG_GZIP is not set
+# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set
+CONFIG_GZIP_FAST=0
+# CONFIG_FEATURE_GZIP_LEVELS is not set
+# CONFIG_FEATURE_GZIP_DECOMPRESS is not set
+# CONFIG_LZOP is not set
+# CONFIG_UNLZOP is not set
+# CONFIG_LZOPCAT is not set
+# CONFIG_LZOP_COMPR_HIGH is not set
+# CONFIG_RPM is not set
+# CONFIG_RPM2CPIO is not set
+# CONFIG_TAR is not set
+# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set
+# CONFIG_FEATURE_TAR_CREATE is not set
+# CONFIG_FEATURE_TAR_AUTODETECT is not set
+# CONFIG_FEATURE_TAR_FROM is not set
+# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set
+# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set
+# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set
+# CONFIG_FEATURE_TAR_TO_COMMAND is not set
+# CONFIG_FEATURE_TAR_UNAME_GNAME is not set
+# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set
+# CONFIG_FEATURE_TAR_SELINUX is not set
+# CONFIG_UNZIP is not set
+# CONFIG_FEATURE_UNZIP_CDF is not set
+# CONFIG_FEATURE_UNZIP_BZIP2 is not set
+# CONFIG_FEATURE_UNZIP_LZMA is not set
+# CONFIG_FEATURE_UNZIP_XZ is not set
+# CONFIG_FEATURE_LZMA_FAST is not set
+
+#
+# Coreutils
+#
+# CONFIG_BASENAME is not set
+# CONFIG_CAT is not set
+# CONFIG_FEATURE_CATN is not set
+# CONFIG_FEATURE_CATV is not set
+# CONFIG_CHGRP is not set
+# CONFIG_CHMOD is not set
+# CONFIG_CHOWN is not set
+# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set
+# CONFIG_CHROOT is not set
+# CONFIG_CKSUM is not set
+# CONFIG_COMM is not set
+# CONFIG_CP is not set
+# CONFIG_FEATURE_CP_LONG_OPTIONS is not set
+# CONFIG_FEATURE_CP_REFLINK is not set
+# CONFIG_CUT is not set
+# CONFIG_DATE is not set
+# CONFIG_FEATURE_DATE_ISOFMT is not set
+# CONFIG_FEATURE_DATE_NANO is not set
+# CONFIG_FEATURE_DATE_COMPAT is not set
+# CONFIG_DD is not set
+# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set
+# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set
+# CONFIG_FEATURE_DD_IBS_OBS is not set
+# CONFIG_FEATURE_DD_STATUS is not set
+# CONFIG_DF is not set
+# CONFIG_FEATURE_DF_FANCY is not set
+# CONFIG_DIRNAME is not set
+# CONFIG_DOS2UNIX is not set
+# CONFIG_UNIX2DOS is not set
+# CONFIG_DU is not set
+# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set
+# CONFIG_ECHO is not set
+# CONFIG_FEATURE_FANCY_ECHO is not set
+# CONFIG_ENV is not set
+# CONFIG_EXPAND is not set
+# CONFIG_UNEXPAND is not set
+# CONFIG_EXPR is not set
+# CONFIG_EXPR_MATH_SUPPORT_64 is not set
+# CONFIG_FACTOR is not set
+# CONFIG_FALSE is not set
+# CONFIG_FOLD is not set
+# CONFIG_HEAD is not set
+# CONFIG_FEATURE_FANCY_HEAD is not set
+# CONFIG_HOSTID is not set
+# CONFIG_ID is not set
+# CONFIG_GROUPS is not set
+# CONFIG_INSTALL is not set
+# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set
+# CONFIG_LINK is not set
+# CONFIG_LN is not set
+# CONFIG_LOGNAME is not set
+# CONFIG_LS is not set
+# CONFIG_FEATURE_LS_FILETYPES is not set
+# CONFIG_FEATURE_LS_FOLLOWLINKS is not set
+# CONFIG_FEATURE_LS_RECURSIVE is not set
+# CONFIG_FEATURE_LS_WIDTH is not set
+# CONFIG_FEATURE_LS_SORTFILES is not set
+# CONFIG_FEATURE_LS_TIMESTAMPS is not set
+# CONFIG_FEATURE_LS_USERNAME is not set
+# CONFIG_FEATURE_LS_COLOR is not set
+# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set
+# CONFIG_MD5SUM is not set
+# CONFIG_SHA1SUM is not set
+# CONFIG_SHA256SUM is not set
+# CONFIG_SHA512SUM is not set
+# CONFIG_SHA3SUM is not set
+# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set
+# CONFIG_MKDIR is not set
+# CONFIG_MKFIFO is not set
+# CONFIG_MKNOD is not set
+# CONFIG_MKTEMP is not set
+# CONFIG_MV is not set
+# CONFIG_NICE is not set
+# CONFIG_NL is not set
+# CONFIG_NOHUP is not set
+# CONFIG_NPROC is not set
+# CONFIG_OD is not set
+# CONFIG_PASTE is not set
+# CONFIG_PRINTENV is not set
+# CONFIG_PRINTF is not set
+# CONFIG_PWD is not set
+# CONFIG_READLINK is not set
+# CONFIG_FEATURE_READLINK_FOLLOW is not set
+# CONFIG_REALPATH is not set
+# CONFIG_RM is not set
+# CONFIG_RMDIR is not set
+# CONFIG_SEQ is not set
+# CONFIG_SHRED is not set
+# CONFIG_SHUF is not set
+# CONFIG_SLEEP is not set
+# CONFIG_FEATURE_FANCY_SLEEP is not set
+# CONFIG_SORT is not set
+# CONFIG_FEATURE_SORT_BIG is not set
+# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set
+# CONFIG_SPLIT is not set
+# CONFIG_FEATURE_SPLIT_FANCY is not set
+# CONFIG_STAT is not set
+# CONFIG_FEATURE_STAT_FORMAT is not set
+# CONFIG_FEATURE_STAT_FILESYSTEM is not set
+# CONFIG_STTY is not set
+# CONFIG_SUM is not set
+# CONFIG_SYNC is not set
+# CONFIG_FEATURE_SYNC_FANCY is not set
+# CONFIG_FSYNC is not set
+# CONFIG_TAC is not set
+# CONFIG_TAIL is not set
+# CONFIG_FEATURE_FANCY_TAIL is not set
+# CONFIG_TEE is not set
+# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set
+# CONFIG_TEST is not set
+# CONFIG_TEST1 is not set
+# CONFIG_TEST2 is not set
+# CONFIG_FEATURE_TEST_64 is not set
+# CONFIG_TIMEOUT is not set
+# CONFIG_TOUCH is not set
+# CONFIG_FEATURE_TOUCH_NODEREF is not set
+# CONFIG_FEATURE_TOUCH_SUSV3 is not set
+# CONFIG_TR is not set
+# CONFIG_FEATURE_TR_CLASSES is not set
+# CONFIG_FEATURE_TR_EQUIV is not set
+# CONFIG_TRUE is not set
+# CONFIG_TRUNCATE is not set
+# CONFIG_TTY is not set
+# CONFIG_UNAME is not set
+CONFIG_UNAME_OSNAME=""
+# CONFIG_BB_ARCH is not set
+# CONFIG_UNIQ is not set
+# CONFIG_UNLINK is not set
+# CONFIG_USLEEP is not set
+# CONFIG_UUDECODE is not set
+# CONFIG_BASE64 is not set
+# CONFIG_UUENCODE is not set
+# CONFIG_WC is not set
+# CONFIG_FEATURE_WC_LARGE is not set
+# CONFIG_WHOAMI is not set
+# CONFIG_WHO is not set
+# CONFIG_W is not set
+# CONFIG_USERS is not set
+# CONFIG_YES is not set
+
+#
+# Common options
+#
+# CONFIG_FEATURE_VERBOSE is not set
+# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set
+# CONFIG_FEATURE_HUMAN_READABLE is not set
+
+#
+# Console Utilities
+#
+# CONFIG_CHVT is not set
+# CONFIG_CLEAR is not set
+# CONFIG_DEALLOCVT is not set
+# CONFIG_DUMPKMAP is not set
+# CONFIG_FGCONSOLE is not set
+# CONFIG_KBD_MODE is not set
+# CONFIG_LOADFONT is not set
+# CONFIG_SETFONT is not set
+# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set
+CONFIG_DEFAULT_SETFONT_DIR=""
+# CONFIG_FEATURE_LOADFONT_PSF2 is not set
+# CONFIG_FEATURE_LOADFONT_RAW is not set
+# CONFIG_LOADKMAP is not set
+# CONFIG_OPENVT is not set
+# CONFIG_RESET is not set
+# CONFIG_RESIZE is not set
+# CONFIG_FEATURE_RESIZE_PRINT is not set
+# CONFIG_SETCONSOLE is not set
+# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set
+# CONFIG_SETKEYCODES is not set
+# CONFIG_SETLOGCONS is not set
+# CONFIG_SHOWKEY is not set
+
+#
+# Debian Utilities
+#
+# CONFIG_PIPE_PROGRESS is not set
+# CONFIG_RUN_PARTS is not set
+# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set
+# CONFIG_FEATURE_RUN_PARTS_FANCY is not set
+# CONFIG_START_STOP_DAEMON is not set
+# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set
+# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set
+# CONFIG_WHICH is not set
+
+#
+# klibc-utils
+#
+# CONFIG_MINIPS is not set
+# CONFIG_NUKE is not set
+# CONFIG_RESUME is not set
+# CONFIG_RUN_INIT is not set
+
+#
+# Editors
+#
+# CONFIG_AWK is not set
+# CONFIG_FEATURE_AWK_LIBM is not set
+# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set
+# CONFIG_CMP is not set
+# CONFIG_DIFF is not set
+# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set
+# CONFIG_FEATURE_DIFF_DIR is not set
+# CONFIG_ED is not set
+# CONFIG_PATCH is not set
+# CONFIG_SED is not set
+# CONFIG_VI is not set
+CONFIG_FEATURE_VI_MAX_LEN=0
+# CONFIG_FEATURE_VI_8BIT is not set
+# CONFIG_FEATURE_VI_COLON is not set
+# CONFIG_FEATURE_VI_YANKMARK is not set
+# CONFIG_FEATURE_VI_SEARCH is not set
+# CONFIG_FEATURE_VI_REGEX_SEARCH is not set
+# CONFIG_FEATURE_VI_USE_SIGNALS is not set
+# CONFIG_FEATURE_VI_DOT_CMD is not set
+# CONFIG_FEATURE_VI_READONLY is not set
+# CONFIG_FEATURE_VI_SETOPTS is not set
+# CONFIG_FEATURE_VI_SET is not set
+# CONFIG_FEATURE_VI_WIN_RESIZE is not set
+# CONFIG_FEATURE_VI_ASK_TERMINAL is not set
+# CONFIG_FEATURE_VI_UNDO is not set
+# CONFIG_FEATURE_VI_UNDO_QUEUE is not set
+CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0
+# CONFIG_FEATURE_ALLOW_EXEC is not set
+
+#
+# Finding Utilities
+#
+# CONFIG_FIND is not set
+# CONFIG_FEATURE_FIND_PRINT0 is not set
+# CONFIG_FEATURE_FIND_MTIME is not set
+# CONFIG_FEATURE_FIND_MMIN is not set
+# CONFIG_FEATURE_FIND_PERM is not set
+# CONFIG_FEATURE_FIND_TYPE is not set
+# CONFIG_FEATURE_FIND_EXECUTABLE is not set
+# CONFIG_FEATURE_FIND_XDEV is not set
+# CONFIG_FEATURE_FIND_MAXDEPTH is not set
+# CONFIG_FEATURE_FIND_NEWER is not set
+# CONFIG_FEATURE_FIND_INUM is not set
+# CONFIG_FEATURE_FIND_EXEC is not set
+# CONFIG_FEATURE_FIND_EXEC_PLUS is not set
+# CONFIG_FEATURE_FIND_USER is not set
+# CONFIG_FEATURE_FIND_GROUP is not set
+# CONFIG_FEATURE_FIND_NOT is not set
+# CONFIG_FEATURE_FIND_DEPTH is not set
+# CONFIG_FEATURE_FIND_PAREN is not set
+# CONFIG_FEATURE_FIND_SIZE is not set
+# CONFIG_FEATURE_FIND_PRUNE is not set
+# CONFIG_FEATURE_FIND_QUIT is not set
+# CONFIG_FEATURE_FIND_DELETE is not set
+# CONFIG_FEATURE_FIND_EMPTY is not set
+# CONFIG_FEATURE_FIND_PATH is not set
+# CONFIG_FEATURE_FIND_REGEX is not set
+# CONFIG_FEATURE_FIND_CONTEXT is not set
+# CONFIG_FEATURE_FIND_LINKS is not set
+# CONFIG_GREP is not set
+# CONFIG_EGREP is not set
+# CONFIG_FGREP is not set
+# CONFIG_FEATURE_GREP_CONTEXT is not set
+# CONFIG_XARGS is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set
+
+#
+# Init Utilities
+#
+# CONFIG_BOOTCHARTD is not set
+# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set
+# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set
+# CONFIG_HALT is not set
+# CONFIG_POWEROFF is not set
+# CONFIG_REBOOT is not set
+# CONFIG_FEATURE_WAIT_FOR_INIT is not set
+# CONFIG_FEATURE_CALL_TELINIT is not set
+CONFIG_TELINIT_PATH=""
+# CONFIG_INIT is not set
+# CONFIG_LINUXRC is not set
+# CONFIG_FEATURE_USE_INITTAB is not set
+# CONFIG_FEATURE_KILL_REMOVED is not set
+CONFIG_FEATURE_KILL_DELAY=0
+# CONFIG_FEATURE_INIT_SCTTY is not set
+# CONFIG_FEATURE_INIT_SYSLOG is not set
+# CONFIG_FEATURE_INIT_QUIET is not set
+# CONFIG_FEATURE_INIT_COREDUMPS is not set
+CONFIG_INIT_TERMINAL_TYPE=""
+# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set
+
+#
+# Login/Password Management Utilities
+#
+# CONFIG_FEATURE_SHADOWPASSWDS is not set
+# CONFIG_USE_BB_PWD_GRP is not set
+# CONFIG_USE_BB_SHADOW is not set
+# CONFIG_USE_BB_CRYPT is not set
+# CONFIG_USE_BB_CRYPT_SHA is not set
+# CONFIG_ADDGROUP is not set
+# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set
+# CONFIG_ADD_SHELL is not set
+# CONFIG_REMOVE_SHELL is not set
+# CONFIG_ADDUSER is not set
+# CONFIG_FEATURE_CHECK_NAMES is not set
+CONFIG_LAST_ID=0
+CONFIG_FIRST_SYSTEM_ID=0
+CONFIG_LAST_SYSTEM_ID=0
+# CONFIG_CHPASSWD is not set
+CONFIG_FEATURE_DEFAULT_PASSWD_ALGO=""
+# CONFIG_CRYPTPW is not set
+# CONFIG_MKPASSWD is not set
+# CONFIG_DELUSER is not set
+# CONFIG_DELGROUP is not set
+# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set
+# CONFIG_GETTY is not set
+# CONFIG_LOGIN is not set
+# CONFIG_LOGIN_SESSION_AS_CHILD is not set
+# CONFIG_LOGIN_SCRIPTS is not set
+# CONFIG_FEATURE_NOLOGIN is not set
+# CONFIG_FEATURE_SECURETTY is not set
+# CONFIG_PASSWD is not set
+# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set
+# CONFIG_SU is not set
+# CONFIG_FEATURE_SU_SYSLOG is not set
+# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set
+# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set
+# CONFIG_SULOGIN is not set
+# CONFIG_VLOCK is not set
+
+#
+# Linux Ext2 FS Progs
+#
+# CONFIG_CHATTR is not set
+# CONFIG_FSCK is not set
+# CONFIG_LSATTR is not set
+# CONFIG_TUNE2FS is not set
+
+#
+# Linux Module Utilities
+#
+# CONFIG_MODPROBE_SMALL is not set
+# CONFIG_DEPMOD is not set
+# CONFIG_INSMOD is not set
+# CONFIG_LSMOD is not set
+# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set
+# CONFIG_MODINFO is not set
+# CONFIG_MODPROBE is not set
+# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set
+# CONFIG_RMMOD is not set
+
+#
+# Options common to multiple modutils
+#
+# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set
+# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set
+# CONFIG_FEATURE_2_4_MODULES is not set
+# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set
+# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set
+# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set
+# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set
+# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set
+# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set
+# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set
+# CONFIG_FEATURE_MODUTILS_ALIAS is not set
+# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set
+CONFIG_DEFAULT_MODULES_DIR=""
+CONFIG_DEFAULT_DEPMOD_FILE=""
+
+#
+# Linux System Utilities
+#
+# CONFIG_ACPID is not set
+# CONFIG_FEATURE_ACPID_COMPAT is not set
+# CONFIG_BLKDISCARD is not set
+# CONFIG_BLKID is not set
+# CONFIG_FEATURE_BLKID_TYPE is not set
+# CONFIG_BLOCKDEV is not set
+# CONFIG_CAL is not set
+# CONFIG_CHRT is not set
+# CONFIG_DMESG is not set
+# CONFIG_FEATURE_DMESG_PRETTY is not set
+# CONFIG_EJECT is not set
+# CONFIG_FEATURE_EJECT_SCSI is not set
+# CONFIG_FALLOCATE is not set
+# CONFIG_FATATTR is not set
+# CONFIG_FBSET is not set
+# CONFIG_FEATURE_FBSET_FANCY is not set
+# CONFIG_FEATURE_FBSET_READMODE is not set
+# CONFIG_FDFORMAT is not set
+# CONFIG_FDISK is not set
+# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set
+# CONFIG_FEATURE_FDISK_WRITABLE is not set
+# CONFIG_FEATURE_AIX_LABEL is not set
+# CONFIG_FEATURE_SGI_LABEL is not set
+# CONFIG_FEATURE_SUN_LABEL is not set
+# CONFIG_FEATURE_OSF_LABEL is not set
+# CONFIG_FEATURE_GPT_LABEL is not set
+# CONFIG_FEATURE_FDISK_ADVANCED is not set
+# CONFIG_FINDFS is not set
+# CONFIG_FLOCK is not set
+# CONFIG_FDFLUSH is not set
+# CONFIG_FREERAMDISK is not set
+# CONFIG_FSCK_MINIX is not set
+# CONFIG_FSFREEZE is not set
+# CONFIG_FSTRIM is not set
+# CONFIG_GETOPT is not set
+# CONFIG_FEATURE_GETOPT_LONG is not set
+CONFIG_HEXDUMP=y
+CONFIG_FEATURE_HEXDUMP_REVERSE=y
+# CONFIG_HD is not set
+# CONFIG_XXD is not set
+# CONFIG_HWCLOCK is not set
+# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set
+# CONFIG_IONICE is not set
+# CONFIG_IPCRM is not set
+# CONFIG_IPCS is not set
+# CONFIG_LAST is not set
+# CONFIG_FEATURE_LAST_FANCY is not set
+# CONFIG_LOSETUP is not set
+# CONFIG_LSPCI is not set
+# CONFIG_LSUSB is not set
+# CONFIG_MDEV is not set
+# CONFIG_FEATURE_MDEV_CONF is not set
+# CONFIG_FEATURE_MDEV_RENAME is not set
+# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set
+# CONFIG_FEATURE_MDEV_EXEC is not set
+# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set
+# CONFIG_FEATURE_MDEV_DAEMON is not set
+# CONFIG_MESG is not set
+# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set
+# CONFIG_MKE2FS is not set
+# CONFIG_MKFS_EXT2 is not set
+# CONFIG_MKFS_MINIX is not set
+# CONFIG_FEATURE_MINIX2 is not set
+# CONFIG_MKFS_REISER is not set
+# CONFIG_MKDOSFS is not set
+# CONFIG_MKFS_VFAT is not set
+# CONFIG_MKSWAP is not set
+# CONFIG_FEATURE_MKSWAP_UUID is not set
+# CONFIG_MORE is not set
+# CONFIG_MOUNT is not set
+# CONFIG_FEATURE_MOUNT_FAKE is not set
+# CONFIG_FEATURE_MOUNT_VERBOSE is not set
+# CONFIG_FEATURE_MOUNT_HELPERS is not set
+# CONFIG_FEATURE_MOUNT_LABEL is not set
+# CONFIG_FEATURE_MOUNT_NFS is not set
+# CONFIG_FEATURE_MOUNT_CIFS is not set
+# CONFIG_FEATURE_MOUNT_FLAGS is not set
+# CONFIG_FEATURE_MOUNT_FSTAB is not set
+# CONFIG_FEATURE_MOUNT_OTHERTAB is not set
+# CONFIG_MOUNTPOINT is not set
+# CONFIG_NOLOGIN is not set
+# CONFIG_NOLOGIN_DEPENDENCIES is not set
+# CONFIG_NSENTER is not set
+# CONFIG_PIVOT_ROOT is not set
+# CONFIG_RDATE is not set
+# CONFIG_RDEV is not set
+# CONFIG_READPROFILE is not set
+# CONFIG_RENICE is not set
+# CONFIG_REV is not set
+# CONFIG_RTCWAKE is not set
+# CONFIG_SCRIPT is not set
+# CONFIG_SCRIPTREPLAY is not set
+# CONFIG_SETARCH is not set
+# CONFIG_LINUX32 is not set
+# CONFIG_LINUX64 is not set
+# CONFIG_SETPRIV is not set
+# CONFIG_FEATURE_SETPRIV_DUMP is not set
+# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set
+# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set
+# CONFIG_SETSID is not set
+# CONFIG_SWAPON is not set
+# CONFIG_FEATURE_SWAPON_DISCARD is not set
+# CONFIG_FEATURE_SWAPON_PRI is not set
+# CONFIG_SWAPOFF is not set
+# CONFIG_FEATURE_SWAPONOFF_LABEL is not set
+# CONFIG_SWITCH_ROOT is not set
+# CONFIG_TASKSET is not set
+# CONFIG_FEATURE_TASKSET_FANCY is not set
+# CONFIG_FEATURE_TASKSET_CPULIST is not set
+# CONFIG_UEVENT is not set
+# CONFIG_UMOUNT is not set
+# CONFIG_FEATURE_UMOUNT_ALL is not set
+# CONFIG_UNSHARE is not set
+# CONFIG_WALL is not set
+# CONFIG_FEATURE_MOUNT_LOOP is not set
+# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set
+# CONFIG_FEATURE_MTAB_SUPPORT is not set
+# CONFIG_VOLUMEID is not set
+# CONFIG_FEATURE_VOLUMEID_BCACHE is not set
+# CONFIG_FEATURE_VOLUMEID_BTRFS is not set
+# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set
+# CONFIG_FEATURE_VOLUMEID_EXFAT is not set
+# CONFIG_FEATURE_VOLUMEID_EXT is not set
+# CONFIG_FEATURE_VOLUMEID_F2FS is not set
+# CONFIG_FEATURE_VOLUMEID_FAT is not set
+# CONFIG_FEATURE_VOLUMEID_HFS is not set
+# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set
+# CONFIG_FEATURE_VOLUMEID_JFS is not set
+# CONFIG_FEATURE_VOLUMEID_LFS is not set
+# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set
+# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set
+# CONFIG_FEATURE_VOLUMEID_LUKS is not set
+# CONFIG_FEATURE_VOLUMEID_MINIX is not set
+# CONFIG_FEATURE_VOLUMEID_NILFS is not set
+# CONFIG_FEATURE_VOLUMEID_NTFS is not set
+# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set
+# CONFIG_FEATURE_VOLUMEID_REISERFS is not set
+# CONFIG_FEATURE_VOLUMEID_ROMFS is not set
+# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set
+# CONFIG_FEATURE_VOLUMEID_SYSV is not set
+# CONFIG_FEATURE_VOLUMEID_UBIFS is not set
+# CONFIG_FEATURE_VOLUMEID_UDF is not set
+# CONFIG_FEATURE_VOLUMEID_XFS is not set
+
+#
+# Miscellaneous Utilities
+#
+# CONFIG_ADJTIMEX is not set
+# CONFIG_BBCONFIG is not set
+# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set
+# CONFIG_BC is not set
+# CONFIG_DC is not set
+# CONFIG_FEATURE_DC_BIG is not set
+# CONFIG_FEATURE_DC_LIBM is not set
+# CONFIG_FEATURE_BC_INTERACTIVE is not set
+# CONFIG_FEATURE_BC_LONG_OPTIONS is not set
+# CONFIG_BEEP is not set
+CONFIG_FEATURE_BEEP_FREQ=0
+CONFIG_FEATURE_BEEP_LENGTH_MS=0
+# CONFIG_CHAT is not set
+# CONFIG_FEATURE_CHAT_NOFAIL is not set
+# CONFIG_FEATURE_CHAT_TTY_HIFI is not set
+# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set
+# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set
+# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set
+# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set
+# CONFIG_FEATURE_CHAT_CLR_ABORT is not set
+# CONFIG_CONSPY is not set
+# CONFIG_CROND is not set
+# CONFIG_FEATURE_CROND_D is not set
+# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set
+# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set
+CONFIG_FEATURE_CROND_DIR=""
+# CONFIG_CRONTAB is not set
+# CONFIG_DEVFSD is not set
+# CONFIG_DEVFSD_MODLOAD is not set
+# CONFIG_DEVFSD_FG_NP is not set
+# CONFIG_DEVFSD_VERBOSE is not set
+# CONFIG_FEATURE_DEVFS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_FBSPLASH is not set
+# CONFIG_FLASHCP is not set
+# CONFIG_FLASH_ERASEALL is not set
+# CONFIG_FLASH_LOCK is not set
+# CONFIG_FLASH_UNLOCK is not set
+# CONFIG_HDPARM is not set
+# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set
+# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set
+# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set
+# CONFIG_HEXEDIT is not set
+# CONFIG_I2CGET is not set
+# CONFIG_I2CSET is not set
+# CONFIG_I2CDUMP is not set
+# CONFIG_I2CDETECT is not set
+# CONFIG_I2CTRANSFER is not set
+# CONFIG_INOTIFYD is not set
+# CONFIG_LESS is not set
+CONFIG_FEATURE_LESS_MAXLINES=0
+# CONFIG_FEATURE_LESS_BRACKETS is not set
+# CONFIG_FEATURE_LESS_FLAGS is not set
+# CONFIG_FEATURE_LESS_TRUNCATE is not set
+# CONFIG_FEATURE_LESS_MARKS is not set
+# CONFIG_FEATURE_LESS_REGEXP is not set
+# CONFIG_FEATURE_LESS_WINCH is not set
+# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set
+# CONFIG_FEATURE_LESS_DASHCMD is not set
+# CONFIG_FEATURE_LESS_LINENUMS is not set
+# CONFIG_FEATURE_LESS_RAW is not set
+# CONFIG_FEATURE_LESS_ENV is not set
+# CONFIG_LSSCSI is not set
+# CONFIG_MAKEDEVS is not set
+# CONFIG_FEATURE_MAKEDEVS_LEAF is not set
+# CONFIG_FEATURE_MAKEDEVS_TABLE is not set
+# CONFIG_MAN is not set
+# CONFIG_MICROCOM is not set
+# CONFIG_MIM is not set
+# CONFIG_MT is not set
+# CONFIG_NANDWRITE is not set
+# CONFIG_NANDDUMP is not set
+# CONFIG_PARTPROBE is not set
+# CONFIG_RAIDAUTORUN is not set
+# CONFIG_READAHEAD is not set
+# CONFIG_RFKILL is not set
+# CONFIG_RUNLEVEL is not set
+# CONFIG_RX is not set
+# CONFIG_SETFATTR is not set
+# CONFIG_SETSERIAL is not set
+# CONFIG_STRINGS is not set
+# CONFIG_TIME is not set
+# CONFIG_TS is not set
+# CONFIG_TTYSIZE is not set
+# CONFIG_UBIRENAME is not set
+# CONFIG_UBIATTACH is not set
+# CONFIG_UBIDETACH is not set
+# CONFIG_UBIMKVOL is not set
+# CONFIG_UBIRMVOL is not set
+# CONFIG_UBIRSVOL is not set
+# CONFIG_UBIUPDATEVOL is not set
+# CONFIG_VOLNAME is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Networking Utilities
+#
+# CONFIG_FEATURE_IPV6 is not set
+# CONFIG_FEATURE_UNIX_LOCAL is not set
+# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set
+# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set
+# CONFIG_FEATURE_TLS_SHA1 is not set
+# CONFIG_ARP is not set
+# CONFIG_ARPING is not set
+# CONFIG_BRCTL is not set
+# CONFIG_FEATURE_BRCTL_FANCY is not set
+# CONFIG_FEATURE_BRCTL_SHOW is not set
+# CONFIG_DNSD is not set
+# CONFIG_ETHER_WAKE is not set
+# CONFIG_FTPD is not set
+# CONFIG_FEATURE_FTPD_WRITE is not set
+# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set
+# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set
+# CONFIG_FTPGET is not set
+# CONFIG_FTPPUT is not set
+# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set
+# CONFIG_HOSTNAME is not set
+# CONFIG_DNSDOMAINNAME is not set
+# CONFIG_HTTPD is not set
+# CONFIG_FEATURE_HTTPD_RANGES is not set
+# CONFIG_FEATURE_HTTPD_SETUID is not set
+# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set
+# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set
+# CONFIG_FEATURE_HTTPD_CGI is not set
+# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set
+# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set
+# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set
+# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set
+# CONFIG_FEATURE_HTTPD_PROXY is not set
+# CONFIG_FEATURE_HTTPD_GZIP is not set
+# CONFIG_IFCONFIG is not set
+# CONFIG_FEATURE_IFCONFIG_STATUS is not set
+# CONFIG_FEATURE_IFCONFIG_SLIP is not set
+# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set
+# CONFIG_FEATURE_IFCONFIG_HW is not set
+# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set
+# CONFIG_IFENSLAVE is not set
+# CONFIG_IFPLUGD is not set
+# CONFIG_IFUP is not set
+# CONFIG_IFDOWN is not set
+CONFIG_IFUPDOWN_IFSTATE_PATH=""
+# CONFIG_FEATURE_IFUPDOWN_IP is not set
+# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set
+# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set
+# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set
+# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set
+# CONFIG_INETD is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set
+# CONFIG_FEATURE_INETD_RPC is not set
+# CONFIG_IP is not set
+# CONFIG_IPADDR is not set
+# CONFIG_IPLINK is not set
+# CONFIG_IPROUTE is not set
+# CONFIG_IPTUNNEL is not set
+# CONFIG_IPRULE is not set
+# CONFIG_IPNEIGH is not set
+# CONFIG_FEATURE_IP_ADDRESS is not set
+# CONFIG_FEATURE_IP_LINK is not set
+# CONFIG_FEATURE_IP_ROUTE is not set
+CONFIG_FEATURE_IP_ROUTE_DIR=""
+# CONFIG_FEATURE_IP_TUNNEL is not set
+# CONFIG_FEATURE_IP_RULE is not set
+# CONFIG_FEATURE_IP_NEIGH is not set
+# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set
+# CONFIG_IPCALC is not set
+# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set
+# CONFIG_FEATURE_IPCALC_FANCY is not set
+# CONFIG_FAKEIDENTD is not set
+# CONFIG_NAMEIF is not set
+# CONFIG_FEATURE_NAMEIF_EXTENDED is not set
+# CONFIG_NBDCLIENT is not set
+# CONFIG_NC is not set
+# CONFIG_NETCAT is not set
+# CONFIG_NC_SERVER is not set
+# CONFIG_NC_EXTRA is not set
+# CONFIG_NC_110_COMPAT is not set
+# CONFIG_NETSTAT is not set
+# CONFIG_FEATURE_NETSTAT_WIDE is not set
+# CONFIG_FEATURE_NETSTAT_PRG is not set
+# CONFIG_NSLOOKUP is not set
+# CONFIG_FEATURE_NSLOOKUP_BIG is not set
+# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set
+# CONFIG_NTPD is not set
+# CONFIG_FEATURE_NTPD_SERVER is not set
+# CONFIG_FEATURE_NTPD_CONF is not set
+# CONFIG_FEATURE_NTP_AUTH is not set
+# CONFIG_PING is not set
+# CONFIG_PING6 is not set
+# CONFIG_FEATURE_FANCY_PING is not set
+# CONFIG_PSCAN is not set
+# CONFIG_ROUTE is not set
+# CONFIG_SLATTACH is not set
+# CONFIG_SSL_CLIENT is not set
+# CONFIG_TC is not set
+# CONFIG_FEATURE_TC_INGRESS is not set
+# CONFIG_TCPSVD is not set
+# CONFIG_UDPSVD is not set
+# CONFIG_TELNET is not set
+# CONFIG_FEATURE_TELNET_TTYPE is not set
+# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set
+# CONFIG_FEATURE_TELNET_WIDTH is not set
+# CONFIG_TELNETD is not set
+# CONFIG_FEATURE_TELNETD_STANDALONE is not set
+# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set
+# CONFIG_TFTP is not set
+# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set
+# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set
+# CONFIG_TFTPD is not set
+# CONFIG_FEATURE_TFTP_GET is not set
+# CONFIG_FEATURE_TFTP_PUT is not set
+# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set
+# CONFIG_TFTP_DEBUG is not set
+# CONFIG_TLS is not set
+# CONFIG_TRACEROUTE is not set
+# CONFIG_TRACEROUTE6 is not set
+# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
+# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
+# CONFIG_TUNCTL is not set
+# CONFIG_FEATURE_TUNCTL_UG is not set
+# CONFIG_VCONFIG is not set
+# CONFIG_WGET is not set
+# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set
+# CONFIG_FEATURE_WGET_STATUSBAR is not set
+# CONFIG_FEATURE_WGET_AUTHENTICATION is not set
+# CONFIG_FEATURE_WGET_TIMEOUT is not set
+# CONFIG_FEATURE_WGET_HTTPS is not set
+# CONFIG_FEATURE_WGET_OPENSSL is not set
+# CONFIG_WHOIS is not set
+# CONFIG_ZCIP is not set
+# CONFIG_UDHCPD is not set
+# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set
+# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set
+CONFIG_DHCPD_LEASES_FILE=""
+# CONFIG_DUMPLEASES is not set
+# CONFIG_DHCPRELAY is not set
+# CONFIG_UDHCPC is not set
+# CONFIG_FEATURE_UDHCPC_ARPING is not set
+# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set
+CONFIG_UDHCPC_DEFAULT_SCRIPT=""
+# CONFIG_UDHCPC6 is not set
+# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set
+# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set
+# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set
+# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set
+# CONFIG_FEATURE_UDHCP_PORT is not set
+CONFIG_UDHCP_DEBUG=0
+CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0
+# CONFIG_FEATURE_UDHCP_RFC3397 is not set
+# CONFIG_FEATURE_UDHCP_8021Q is not set
+CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS=""
+
+#
+# Print Utilities
+#
+# CONFIG_LPD is not set
+# CONFIG_LPR is not set
+# CONFIG_LPQ is not set
+
+#
+# Mail Utilities
+#
+# CONFIG_MAKEMIME is not set
+# CONFIG_POPMAILDIR is not set
+# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set
+# CONFIG_REFORMIME is not set
+# CONFIG_FEATURE_REFORMIME_COMPAT is not set
+# CONFIG_SENDMAIL is not set
+CONFIG_FEATURE_MIME_CHARSET=""
+
+#
+# Process Utilities
+#
+# CONFIG_FREE is not set
+# CONFIG_FUSER is not set
+# CONFIG_IOSTAT is not set
+# CONFIG_KILL is not set
+# CONFIG_KILLALL is not set
+# CONFIG_KILLALL5 is not set
+# CONFIG_LSOF is not set
+# CONFIG_MPSTAT is not set
+# CONFIG_NMETER is not set
+# CONFIG_PGREP is not set
+# CONFIG_PKILL is not set
+# CONFIG_PIDOF is not set
+# CONFIG_FEATURE_PIDOF_SINGLE is not set
+# CONFIG_FEATURE_PIDOF_OMIT is not set
+# CONFIG_PMAP is not set
+# CONFIG_POWERTOP is not set
+# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set
+# CONFIG_PS is not set
+# CONFIG_FEATURE_PS_WIDE is not set
+# CONFIG_FEATURE_PS_LONG is not set
+# CONFIG_FEATURE_PS_TIME is not set
+# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set
+# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set
+# CONFIG_PSTREE is not set
+# CONFIG_PWDX is not set
+# CONFIG_SMEMCAP is not set
+# CONFIG_BB_SYSCTL is not set
+# CONFIG_TOP is not set
+# CONFIG_FEATURE_TOP_INTERACTIVE is not set
+# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set
+# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set
+# CONFIG_FEATURE_TOP_SMP_CPU is not set
+# CONFIG_FEATURE_TOP_DECIMALS is not set
+# CONFIG_FEATURE_TOP_SMP_PROCESS is not set
+# CONFIG_FEATURE_TOPMEM is not set
+# CONFIG_UPTIME is not set
+# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set
+# CONFIG_WATCH is not set
+# CONFIG_FEATURE_SHOW_THREADS is not set
+
+#
+# Runit Utilities
+#
+# CONFIG_CHPST is not set
+# CONFIG_SETUIDGID is not set
+# CONFIG_ENVUIDGID is not set
+# CONFIG_ENVDIR is not set
+# CONFIG_SOFTLIMIT is not set
+# CONFIG_RUNSV is not set
+# CONFIG_RUNSVDIR is not set
+# CONFIG_FEATURE_RUNSVDIR_LOG is not set
+# CONFIG_SV is not set
+CONFIG_SV_DEFAULT_SERVICE_DIR=""
+# CONFIG_SVC is not set
+# CONFIG_SVOK is not set
+# CONFIG_SVLOGD is not set
+# CONFIG_CHCON is not set
+# CONFIG_GETENFORCE is not set
+# CONFIG_GETSEBOOL is not set
+# CONFIG_LOAD_POLICY is not set
+# CONFIG_MATCHPATHCON is not set
+# CONFIG_RUNCON is not set
+# CONFIG_SELINUXENABLED is not set
+# CONFIG_SESTATUS is not set
+# CONFIG_SETENFORCE is not set
+# CONFIG_SETFILES is not set
+# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set
+# CONFIG_RESTORECON is not set
+# CONFIG_SETSEBOOL is not set
+
+#
+# Shells
+#
+CONFIG_SH_IS_ASH=y
+# CONFIG_SH_IS_HUSH is not set
+# CONFIG_SH_IS_NONE is not set
+# CONFIG_BASH_IS_ASH is not set
+# CONFIG_BASH_IS_HUSH is not set
+CONFIG_BASH_IS_NONE=y
+CONFIG_SHELL_ASH=y
+# CONFIG_ASH is not set
+# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set
+# CONFIG_ASH_INTERNAL_GLOB is not set
+# CONFIG_ASH_BASH_COMPAT is not set
+# CONFIG_ASH_BASH_SOURCE_CURDIR is not set
+# CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set
+# CONFIG_ASH_JOB_CONTROL is not set
+# CONFIG_ASH_ALIAS is not set
+# CONFIG_ASH_RANDOM_SUPPORT is not set
+# CONFIG_ASH_EXPAND_PRMT is not set
+# CONFIG_ASH_IDLE_TIMEOUT is not set
+# CONFIG_ASH_MAIL is not set
+# CONFIG_ASH_ECHO is not set
+# CONFIG_ASH_PRINTF is not set
+# CONFIG_ASH_TEST is not set
+# CONFIG_ASH_HELP is not set
+# CONFIG_ASH_GETOPTS is not set
+# CONFIG_ASH_CMDCMD is not set
+# CONFIG_CTTYHACK is not set
+# CONFIG_HUSH is not set
+# CONFIG_SHELL_HUSH is not set
+# CONFIG_HUSH_BASH_COMPAT is not set
+# CONFIG_HUSH_BRACE_EXPANSION is not set
+# CONFIG_HUSH_LINENO_VAR is not set
+# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set
+# CONFIG_HUSH_INTERACTIVE is not set
+# CONFIG_HUSH_SAVEHISTORY is not set
+# CONFIG_HUSH_JOB is not set
+# CONFIG_HUSH_TICK is not set
+# CONFIG_HUSH_IF is not set
+# CONFIG_HUSH_LOOPS is not set
+# CONFIG_HUSH_CASE is not set
+# CONFIG_HUSH_FUNCTIONS is not set
+# CONFIG_HUSH_LOCAL is not set
+# CONFIG_HUSH_RANDOM_SUPPORT is not set
+# CONFIG_HUSH_MODE_X is not set
+# CONFIG_HUSH_ECHO is not set
+# CONFIG_HUSH_PRINTF is not set
+# CONFIG_HUSH_TEST is not set
+# CONFIG_HUSH_HELP is not set
+# CONFIG_HUSH_EXPORT is not set
+# CONFIG_HUSH_EXPORT_N is not set
+# CONFIG_HUSH_READONLY is not set
+# CONFIG_HUSH_KILL is not set
+# CONFIG_HUSH_WAIT is not set
+# CONFIG_HUSH_COMMAND is not set
+# CONFIG_HUSH_TRAP is not set
+# CONFIG_HUSH_TYPE is not set
+# CONFIG_HUSH_TIMES is not set
+# CONFIG_HUSH_READ is not set
+# CONFIG_HUSH_SET is not set
+# CONFIG_HUSH_UNSET is not set
+# CONFIG_HUSH_ULIMIT is not set
+# CONFIG_HUSH_UMASK is not set
+# CONFIG_HUSH_GETOPTS is not set
+# CONFIG_HUSH_MEMLEAK is not set
+
+#
+# Options common to all shells
+#
+# CONFIG_FEATURE_SH_MATH is not set
+# CONFIG_FEATURE_SH_MATH_64 is not set
+# CONFIG_FEATURE_SH_MATH_BASE is not set
+# CONFIG_FEATURE_SH_EXTRA_QUIET is not set
+# CONFIG_FEATURE_SH_STANDALONE is not set
+# CONFIG_FEATURE_SH_NOFORK is not set
+# CONFIG_FEATURE_SH_READ_FRAC is not set
+# CONFIG_FEATURE_SH_HISTFILESIZE is not set
+# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set
+
+#
+# System Logging Utilities
+#
+# CONFIG_KLOGD is not set
+# CONFIG_FEATURE_KLOGD_KLOGCTL is not set
+# CONFIG_LOGGER is not set
+# CONFIG_LOGREAD is not set
+# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set
+# CONFIG_SYSLOGD is not set
+# CONFIG_FEATURE_ROTATE_LOGFILE is not set
+# CONFIG_FEATURE_REMOTE_LOG is not set
+# CONFIG_FEATURE_SYSLOGD_DUP is not set
+# CONFIG_FEATURE_SYSLOGD_CFG is not set
+# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set
+CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0
+# CONFIG_FEATURE_IPC_SYSLOG is not set
+CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0
+# CONFIG_FEATURE_KMSG_SYSLOG is not set
--- /dev/null
+#
+# Automatically generated make config: don't edit
+# Busybox version: 1.32.0
+# Thu Mar 4 13:03:19 2021
+#
+CONFIG_HAVE_DOT_CONFIG=y
+
+#
+# Settings
+#
+# CONFIG_DESKTOP is not set
+# CONFIG_EXTRA_COMPAT is not set
+# CONFIG_FEDORA_COMPAT is not set
+# CONFIG_INCLUDE_SUSv2 is not set
+# CONFIG_LONG_OPTS is not set
+# CONFIG_SHOW_USAGE is not set
+# CONFIG_FEATURE_VERBOSE_USAGE is not set
+# CONFIG_FEATURE_COMPRESS_USAGE is not set
+# CONFIG_LFS is not set
+# CONFIG_PAM is not set
+# CONFIG_FEATURE_DEVPTS is not set
+# CONFIG_FEATURE_UTMP is not set
+# CONFIG_FEATURE_WTMP is not set
+# CONFIG_FEATURE_PIDFILE is not set
+CONFIG_PID_FILE_PATH=""
+# CONFIG_BUSYBOX is not set
+# CONFIG_FEATURE_SHOW_SCRIPT is not set
+# CONFIG_FEATURE_INSTALLER is not set
+# CONFIG_INSTALL_NO_USR is not set
+# CONFIG_FEATURE_SUID is not set
+# CONFIG_FEATURE_SUID_CONFIG is not set
+# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set
+# CONFIG_FEATURE_PREFER_APPLETS is not set
+CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe"
+# CONFIG_SELINUX is not set
+# CONFIG_FEATURE_CLEAN_UP is not set
+# CONFIG_FEATURE_SYSLOG_INFO is not set
+# CONFIG_FEATURE_SYSLOG is not set
+# CONFIG_PLATFORM_LINUX is not set
+
+#
+# Build Options
+#
+CONFIG_STATIC=y
+# CONFIG_PIE is not set
+# CONFIG_NOMMU is not set
+# CONFIG_BUILD_LIBBUSYBOX is not set
+# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set
+# CONFIG_FEATURE_INDIVIDUAL is not set
+# CONFIG_FEATURE_SHARED_BUSYBOX is not set
+CONFIG_CROSS_COMPILER_PREFIX=""
+CONFIG_SYSROOT=""
+CONFIG_EXTRA_CFLAGS=""
+CONFIG_EXTRA_LDFLAGS=""
+CONFIG_EXTRA_LDLIBS=""
+# CONFIG_USE_PORTABLE_CODE is not set
+# CONFIG_STACK_OPTIMIZATION_386 is not set
+
+#
+# Installation Options ("make install" behavior)
+#
+CONFIG_INSTALL_APPLET_SYMLINKS=y
+# CONFIG_INSTALL_APPLET_HARDLINKS is not set
+# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set
+# CONFIG_INSTALL_APPLET_DONT is not set
+# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set
+# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set
+# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set
+CONFIG_PREFIX="./_install"
+
+#
+# Debugging Options
+#
+# CONFIG_DEBUG is not set
+# CONFIG_DEBUG_PESSIMIZE is not set
+# CONFIG_DEBUG_SANITIZE is not set
+# CONFIG_UNIT_TEST is not set
+# CONFIG_WERROR is not set
+# CONFIG_WARN_SIMPLE_MSG is not set
+CONFIG_NO_DEBUG_LIB=y
+# CONFIG_DMALLOC is not set
+# CONFIG_EFENCE is not set
+
+#
+# Library Tuning
+#
+# CONFIG_FEATURE_USE_BSS_TAIL is not set
+# CONFIG_FLOAT_DURATION is not set
+# CONFIG_FEATURE_RTMINMAX is not set
+# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set
+CONFIG_FEATURE_BUFFERS_USE_MALLOC=y
+# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set
+# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set
+CONFIG_PASSWORD_MINLEN=6
+CONFIG_MD5_SMALL=1
+CONFIG_SHA3_SMALL=1
+# CONFIG_FEATURE_FAST_TOP is not set
+# CONFIG_FEATURE_ETC_NETWORKS is not set
+# CONFIG_FEATURE_ETC_SERVICES is not set
+# CONFIG_FEATURE_EDITING is not set
+CONFIG_FEATURE_EDITING_MAX_LEN=0
+# CONFIG_FEATURE_EDITING_VI is not set
+CONFIG_FEATURE_EDITING_HISTORY=0
+# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set
+# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set
+# CONFIG_FEATURE_REVERSE_SEARCH is not set
+# CONFIG_FEATURE_TAB_COMPLETION is not set
+# CONFIG_FEATURE_USERNAME_COMPLETION is not set
+# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set
+# CONFIG_FEATURE_EDITING_WINCH is not set
+# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set
+# CONFIG_LOCALE_SUPPORT is not set
+# CONFIG_UNICODE_SUPPORT is not set
+# CONFIG_UNICODE_USING_LOCALE is not set
+# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set
+CONFIG_SUBST_WCHAR=0
+CONFIG_LAST_SUPPORTED_WCHAR=0
+# CONFIG_UNICODE_COMBINING_WCHARS is not set
+# CONFIG_UNICODE_WIDE_WCHARS is not set
+# CONFIG_UNICODE_BIDI_SUPPORT is not set
+# CONFIG_UNICODE_NEUTRAL_TABLE is not set
+# CONFIG_UNICODE_PRESERVE_BROKEN is not set
+# CONFIG_FEATURE_NON_POSIX_CP is not set
+# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set
+# CONFIG_FEATURE_USE_SENDFILE is not set
+CONFIG_FEATURE_COPYBUF_KB=4
+# CONFIG_FEATURE_SKIP_ROOTFS is not set
+# CONFIG_MONOTONIC_SYSCALL is not set
+# CONFIG_IOCTL_HEX2STR_ERROR is not set
+# CONFIG_FEATURE_HWIB is not set
+
+#
+# Applets
+#
+
+#
+# Archival Utilities
+#
+# CONFIG_FEATURE_SEAMLESS_XZ is not set
+# CONFIG_FEATURE_SEAMLESS_LZMA is not set
+# CONFIG_FEATURE_SEAMLESS_BZ2 is not set
+# CONFIG_FEATURE_SEAMLESS_GZ is not set
+# CONFIG_FEATURE_SEAMLESS_Z is not set
+# CONFIG_AR is not set
+# CONFIG_FEATURE_AR_LONG_FILENAMES is not set
+# CONFIG_FEATURE_AR_CREATE is not set
+# CONFIG_UNCOMPRESS is not set
+# CONFIG_GUNZIP is not set
+# CONFIG_ZCAT is not set
+# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set
+# CONFIG_BUNZIP2 is not set
+# CONFIG_BZCAT is not set
+# CONFIG_UNLZMA is not set
+# CONFIG_LZCAT is not set
+# CONFIG_LZMA is not set
+# CONFIG_UNXZ is not set
+CONFIG_XZCAT=y
+# CONFIG_XZ is not set
+# CONFIG_BZIP2 is not set
+CONFIG_BZIP2_SMALL=0
+# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set
+# CONFIG_CPIO is not set
+# CONFIG_FEATURE_CPIO_O is not set
+# CONFIG_FEATURE_CPIO_P is not set
+# CONFIG_DPKG is not set
+# CONFIG_DPKG_DEB is not set
+# CONFIG_GZIP is not set
+# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set
+CONFIG_GZIP_FAST=0
+# CONFIG_FEATURE_GZIP_LEVELS is not set
+# CONFIG_FEATURE_GZIP_DECOMPRESS is not set
+# CONFIG_LZOP is not set
+# CONFIG_UNLZOP is not set
+# CONFIG_LZOPCAT is not set
+# CONFIG_LZOP_COMPR_HIGH is not set
+# CONFIG_RPM is not set
+# CONFIG_RPM2CPIO is not set
+# CONFIG_TAR is not set
+# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set
+# CONFIG_FEATURE_TAR_CREATE is not set
+# CONFIG_FEATURE_TAR_AUTODETECT is not set
+# CONFIG_FEATURE_TAR_FROM is not set
+# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set
+# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set
+# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set
+# CONFIG_FEATURE_TAR_TO_COMMAND is not set
+# CONFIG_FEATURE_TAR_UNAME_GNAME is not set
+# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set
+# CONFIG_FEATURE_TAR_SELINUX is not set
+# CONFIG_UNZIP is not set
+# CONFIG_FEATURE_UNZIP_CDF is not set
+# CONFIG_FEATURE_UNZIP_BZIP2 is not set
+# CONFIG_FEATURE_UNZIP_LZMA is not set
+# CONFIG_FEATURE_UNZIP_XZ is not set
+# CONFIG_FEATURE_LZMA_FAST is not set
+
+#
+# Coreutils
+#
+# CONFIG_BASENAME is not set
+# CONFIG_CAT is not set
+# CONFIG_FEATURE_CATN is not set
+# CONFIG_FEATURE_CATV is not set
+# CONFIG_CHGRP is not set
+# CONFIG_CHMOD is not set
+# CONFIG_CHOWN is not set
+# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set
+# CONFIG_CHROOT is not set
+# CONFIG_CKSUM is not set
+# CONFIG_COMM is not set
+# CONFIG_CP is not set
+# CONFIG_FEATURE_CP_LONG_OPTIONS is not set
+# CONFIG_FEATURE_CP_REFLINK is not set
+# CONFIG_CUT is not set
+# CONFIG_DATE is not set
+# CONFIG_FEATURE_DATE_ISOFMT is not set
+# CONFIG_FEATURE_DATE_NANO is not set
+# CONFIG_FEATURE_DATE_COMPAT is not set
+# CONFIG_DD is not set
+# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set
+# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set
+# CONFIG_FEATURE_DD_IBS_OBS is not set
+# CONFIG_FEATURE_DD_STATUS is not set
+# CONFIG_DF is not set
+# CONFIG_FEATURE_DF_FANCY is not set
+# CONFIG_DIRNAME is not set
+# CONFIG_DOS2UNIX is not set
+# CONFIG_UNIX2DOS is not set
+# CONFIG_DU is not set
+# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set
+# CONFIG_ECHO is not set
+# CONFIG_FEATURE_FANCY_ECHO is not set
+# CONFIG_ENV is not set
+# CONFIG_EXPAND is not set
+# CONFIG_UNEXPAND is not set
+# CONFIG_EXPR is not set
+# CONFIG_EXPR_MATH_SUPPORT_64 is not set
+# CONFIG_FACTOR is not set
+# CONFIG_FALSE is not set
+# CONFIG_FOLD is not set
+# CONFIG_HEAD is not set
+# CONFIG_FEATURE_FANCY_HEAD is not set
+# CONFIG_HOSTID is not set
+# CONFIG_ID is not set
+# CONFIG_GROUPS is not set
+# CONFIG_INSTALL is not set
+# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set
+# CONFIG_LINK is not set
+# CONFIG_LN is not set
+# CONFIG_LOGNAME is not set
+# CONFIG_LS is not set
+# CONFIG_FEATURE_LS_FILETYPES is not set
+# CONFIG_FEATURE_LS_FOLLOWLINKS is not set
+# CONFIG_FEATURE_LS_RECURSIVE is not set
+# CONFIG_FEATURE_LS_WIDTH is not set
+# CONFIG_FEATURE_LS_SORTFILES is not set
+# CONFIG_FEATURE_LS_TIMESTAMPS is not set
+# CONFIG_FEATURE_LS_USERNAME is not set
+# CONFIG_FEATURE_LS_COLOR is not set
+# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set
+# CONFIG_MD5SUM is not set
+# CONFIG_SHA1SUM is not set
+# CONFIG_SHA256SUM is not set
+# CONFIG_SHA512SUM is not set
+# CONFIG_SHA3SUM is not set
+# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set
+# CONFIG_MKDIR is not set
+# CONFIG_MKFIFO is not set
+# CONFIG_MKNOD is not set
+# CONFIG_MKTEMP is not set
+# CONFIG_MV is not set
+# CONFIG_NICE is not set
+# CONFIG_NL is not set
+# CONFIG_NOHUP is not set
+# CONFIG_NPROC is not set
+# CONFIG_OD is not set
+# CONFIG_PASTE is not set
+# CONFIG_PRINTENV is not set
+# CONFIG_PRINTF is not set
+# CONFIG_PWD is not set
+# CONFIG_READLINK is not set
+# CONFIG_FEATURE_READLINK_FOLLOW is not set
+# CONFIG_REALPATH is not set
+# CONFIG_RM is not set
+# CONFIG_RMDIR is not set
+# CONFIG_SEQ is not set
+# CONFIG_SHRED is not set
+# CONFIG_SHUF is not set
+# CONFIG_SLEEP is not set
+# CONFIG_FEATURE_FANCY_SLEEP is not set
+# CONFIG_SORT is not set
+# CONFIG_FEATURE_SORT_BIG is not set
+# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set
+# CONFIG_SPLIT is not set
+# CONFIG_FEATURE_SPLIT_FANCY is not set
+# CONFIG_STAT is not set
+# CONFIG_FEATURE_STAT_FORMAT is not set
+# CONFIG_FEATURE_STAT_FILESYSTEM is not set
+# CONFIG_STTY is not set
+# CONFIG_SUM is not set
+# CONFIG_SYNC is not set
+# CONFIG_FEATURE_SYNC_FANCY is not set
+# CONFIG_FSYNC is not set
+# CONFIG_TAC is not set
+# CONFIG_TAIL is not set
+# CONFIG_FEATURE_FANCY_TAIL is not set
+# CONFIG_TEE is not set
+# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set
+# CONFIG_TEST is not set
+# CONFIG_TEST1 is not set
+# CONFIG_TEST2 is not set
+# CONFIG_FEATURE_TEST_64 is not set
+# CONFIG_TIMEOUT is not set
+# CONFIG_TOUCH is not set
+# CONFIG_FEATURE_TOUCH_NODEREF is not set
+# CONFIG_FEATURE_TOUCH_SUSV3 is not set
+# CONFIG_TR is not set
+# CONFIG_FEATURE_TR_CLASSES is not set
+# CONFIG_FEATURE_TR_EQUIV is not set
+# CONFIG_TRUE is not set
+# CONFIG_TRUNCATE is not set
+# CONFIG_TTY is not set
+# CONFIG_UNAME is not set
+CONFIG_UNAME_OSNAME=""
+# CONFIG_BB_ARCH is not set
+# CONFIG_UNIQ is not set
+# CONFIG_UNLINK is not set
+# CONFIG_USLEEP is not set
+# CONFIG_UUDECODE is not set
+# CONFIG_BASE64 is not set
+# CONFIG_UUENCODE is not set
+# CONFIG_WC is not set
+# CONFIG_FEATURE_WC_LARGE is not set
+# CONFIG_WHOAMI is not set
+# CONFIG_WHO is not set
+# CONFIG_W is not set
+# CONFIG_USERS is not set
+# CONFIG_YES is not set
+
+#
+# Common options
+#
+# CONFIG_FEATURE_VERBOSE is not set
+# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set
+# CONFIG_FEATURE_HUMAN_READABLE is not set
+
+#
+# Console Utilities
+#
+# CONFIG_CHVT is not set
+# CONFIG_CLEAR is not set
+# CONFIG_DEALLOCVT is not set
+# CONFIG_DUMPKMAP is not set
+# CONFIG_FGCONSOLE is not set
+# CONFIG_KBD_MODE is not set
+# CONFIG_LOADFONT is not set
+# CONFIG_SETFONT is not set
+# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set
+CONFIG_DEFAULT_SETFONT_DIR=""
+# CONFIG_FEATURE_LOADFONT_PSF2 is not set
+# CONFIG_FEATURE_LOADFONT_RAW is not set
+# CONFIG_LOADKMAP is not set
+# CONFIG_OPENVT is not set
+# CONFIG_RESET is not set
+# CONFIG_RESIZE is not set
+# CONFIG_FEATURE_RESIZE_PRINT is not set
+# CONFIG_SETCONSOLE is not set
+# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set
+# CONFIG_SETKEYCODES is not set
+# CONFIG_SETLOGCONS is not set
+# CONFIG_SHOWKEY is not set
+
+#
+# Debian Utilities
+#
+# CONFIG_PIPE_PROGRESS is not set
+# CONFIG_RUN_PARTS is not set
+# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set
+# CONFIG_FEATURE_RUN_PARTS_FANCY is not set
+# CONFIG_START_STOP_DAEMON is not set
+# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set
+# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set
+# CONFIG_WHICH is not set
+
+#
+# klibc-utils
+#
+# CONFIG_MINIPS is not set
+# CONFIG_NUKE is not set
+# CONFIG_RESUME is not set
+# CONFIG_RUN_INIT is not set
+
+#
+# Editors
+#
+# CONFIG_AWK is not set
+# CONFIG_FEATURE_AWK_LIBM is not set
+# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set
+# CONFIG_CMP is not set
+# CONFIG_DIFF is not set
+# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set
+# CONFIG_FEATURE_DIFF_DIR is not set
+# CONFIG_ED is not set
+# CONFIG_PATCH is not set
+# CONFIG_SED is not set
+# CONFIG_VI is not set
+CONFIG_FEATURE_VI_MAX_LEN=0
+# CONFIG_FEATURE_VI_8BIT is not set
+# CONFIG_FEATURE_VI_COLON is not set
+# CONFIG_FEATURE_VI_YANKMARK is not set
+# CONFIG_FEATURE_VI_SEARCH is not set
+# CONFIG_FEATURE_VI_REGEX_SEARCH is not set
+# CONFIG_FEATURE_VI_USE_SIGNALS is not set
+# CONFIG_FEATURE_VI_DOT_CMD is not set
+# CONFIG_FEATURE_VI_READONLY is not set
+# CONFIG_FEATURE_VI_SETOPTS is not set
+# CONFIG_FEATURE_VI_SET is not set
+# CONFIG_FEATURE_VI_WIN_RESIZE is not set
+# CONFIG_FEATURE_VI_ASK_TERMINAL is not set
+# CONFIG_FEATURE_VI_UNDO is not set
+# CONFIG_FEATURE_VI_UNDO_QUEUE is not set
+CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0
+# CONFIG_FEATURE_ALLOW_EXEC is not set
+
+#
+# Finding Utilities
+#
+# CONFIG_FIND is not set
+# CONFIG_FEATURE_FIND_PRINT0 is not set
+# CONFIG_FEATURE_FIND_MTIME is not set
+# CONFIG_FEATURE_FIND_MMIN is not set
+# CONFIG_FEATURE_FIND_PERM is not set
+# CONFIG_FEATURE_FIND_TYPE is not set
+# CONFIG_FEATURE_FIND_EXECUTABLE is not set
+# CONFIG_FEATURE_FIND_XDEV is not set
+# CONFIG_FEATURE_FIND_MAXDEPTH is not set
+# CONFIG_FEATURE_FIND_NEWER is not set
+# CONFIG_FEATURE_FIND_INUM is not set
+# CONFIG_FEATURE_FIND_EXEC is not set
+# CONFIG_FEATURE_FIND_EXEC_PLUS is not set
+# CONFIG_FEATURE_FIND_USER is not set
+# CONFIG_FEATURE_FIND_GROUP is not set
+# CONFIG_FEATURE_FIND_NOT is not set
+# CONFIG_FEATURE_FIND_DEPTH is not set
+# CONFIG_FEATURE_FIND_PAREN is not set
+# CONFIG_FEATURE_FIND_SIZE is not set
+# CONFIG_FEATURE_FIND_PRUNE is not set
+# CONFIG_FEATURE_FIND_QUIT is not set
+# CONFIG_FEATURE_FIND_DELETE is not set
+# CONFIG_FEATURE_FIND_EMPTY is not set
+# CONFIG_FEATURE_FIND_PATH is not set
+# CONFIG_FEATURE_FIND_REGEX is not set
+# CONFIG_FEATURE_FIND_CONTEXT is not set
+# CONFIG_FEATURE_FIND_LINKS is not set
+# CONFIG_GREP is not set
+# CONFIG_EGREP is not set
+# CONFIG_FGREP is not set
+# CONFIG_FEATURE_GREP_CONTEXT is not set
+# CONFIG_XARGS is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set
+
+#
+# Init Utilities
+#
+# CONFIG_BOOTCHARTD is not set
+# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set
+# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set
+# CONFIG_HALT is not set
+# CONFIG_POWEROFF is not set
+# CONFIG_REBOOT is not set
+# CONFIG_FEATURE_WAIT_FOR_INIT is not set
+# CONFIG_FEATURE_CALL_TELINIT is not set
+CONFIG_TELINIT_PATH=""
+# CONFIG_INIT is not set
+# CONFIG_LINUXRC is not set
+# CONFIG_FEATURE_USE_INITTAB is not set
+# CONFIG_FEATURE_KILL_REMOVED is not set
+CONFIG_FEATURE_KILL_DELAY=0
+# CONFIG_FEATURE_INIT_SCTTY is not set
+# CONFIG_FEATURE_INIT_SYSLOG is not set
+# CONFIG_FEATURE_INIT_QUIET is not set
+# CONFIG_FEATURE_INIT_COREDUMPS is not set
+CONFIG_INIT_TERMINAL_TYPE=""
+# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set
+
+#
+# Login/Password Management Utilities
+#
+# CONFIG_FEATURE_SHADOWPASSWDS is not set
+# CONFIG_USE_BB_PWD_GRP is not set
+# CONFIG_USE_BB_SHADOW is not set
+# CONFIG_USE_BB_CRYPT is not set
+# CONFIG_USE_BB_CRYPT_SHA is not set
+# CONFIG_ADDGROUP is not set
+# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set
+# CONFIG_ADD_SHELL is not set
+# CONFIG_REMOVE_SHELL is not set
+# CONFIG_ADDUSER is not set
+# CONFIG_FEATURE_CHECK_NAMES is not set
+CONFIG_LAST_ID=0
+CONFIG_FIRST_SYSTEM_ID=0
+CONFIG_LAST_SYSTEM_ID=0
+# CONFIG_CHPASSWD is not set
+CONFIG_FEATURE_DEFAULT_PASSWD_ALGO=""
+# CONFIG_CRYPTPW is not set
+# CONFIG_MKPASSWD is not set
+# CONFIG_DELUSER is not set
+# CONFIG_DELGROUP is not set
+# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set
+# CONFIG_GETTY is not set
+# CONFIG_LOGIN is not set
+# CONFIG_LOGIN_SESSION_AS_CHILD is not set
+# CONFIG_LOGIN_SCRIPTS is not set
+# CONFIG_FEATURE_NOLOGIN is not set
+# CONFIG_FEATURE_SECURETTY is not set
+# CONFIG_PASSWD is not set
+# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set
+# CONFIG_SU is not set
+# CONFIG_FEATURE_SU_SYSLOG is not set
+# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set
+# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set
+# CONFIG_SULOGIN is not set
+# CONFIG_VLOCK is not set
+
+#
+# Linux Ext2 FS Progs
+#
+# CONFIG_CHATTR is not set
+# CONFIG_FSCK is not set
+# CONFIG_LSATTR is not set
+# CONFIG_TUNE2FS is not set
+
+#
+# Linux Module Utilities
+#
+# CONFIG_MODPROBE_SMALL is not set
+# CONFIG_DEPMOD is not set
+# CONFIG_INSMOD is not set
+# CONFIG_LSMOD is not set
+# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set
+# CONFIG_MODINFO is not set
+# CONFIG_MODPROBE is not set
+# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set
+# CONFIG_RMMOD is not set
+
+#
+# Options common to multiple modutils
+#
+# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set
+# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set
+# CONFIG_FEATURE_2_4_MODULES is not set
+# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set
+# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set
+# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set
+# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set
+# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set
+# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set
+# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set
+# CONFIG_FEATURE_MODUTILS_ALIAS is not set
+# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set
+CONFIG_DEFAULT_MODULES_DIR=""
+CONFIG_DEFAULT_DEPMOD_FILE=""
+
+#
+# Linux System Utilities
+#
+# CONFIG_ACPID is not set
+# CONFIG_FEATURE_ACPID_COMPAT is not set
+# CONFIG_BLKDISCARD is not set
+# CONFIG_BLKID is not set
+# CONFIG_FEATURE_BLKID_TYPE is not set
+# CONFIG_BLOCKDEV is not set
+# CONFIG_CAL is not set
+# CONFIG_CHRT is not set
+# CONFIG_DMESG is not set
+# CONFIG_FEATURE_DMESG_PRETTY is not set
+# CONFIG_EJECT is not set
+# CONFIG_FEATURE_EJECT_SCSI is not set
+# CONFIG_FALLOCATE is not set
+# CONFIG_FATATTR is not set
+# CONFIG_FBSET is not set
+# CONFIG_FEATURE_FBSET_FANCY is not set
+# CONFIG_FEATURE_FBSET_READMODE is not set
+# CONFIG_FDFORMAT is not set
+# CONFIG_FDISK is not set
+# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set
+# CONFIG_FEATURE_FDISK_WRITABLE is not set
+# CONFIG_FEATURE_AIX_LABEL is not set
+# CONFIG_FEATURE_SGI_LABEL is not set
+# CONFIG_FEATURE_SUN_LABEL is not set
+# CONFIG_FEATURE_OSF_LABEL is not set
+# CONFIG_FEATURE_GPT_LABEL is not set
+# CONFIG_FEATURE_FDISK_ADVANCED is not set
+# CONFIG_FINDFS is not set
+# CONFIG_FLOCK is not set
+# CONFIG_FDFLUSH is not set
+# CONFIG_FREERAMDISK is not set
+# CONFIG_FSCK_MINIX is not set
+# CONFIG_FSFREEZE is not set
+# CONFIG_FSTRIM is not set
+# CONFIG_GETOPT is not set
+# CONFIG_FEATURE_GETOPT_LONG is not set
+# CONFIG_HEXDUMP is not set
+# CONFIG_FEATURE_HEXDUMP_REVERSE is not set
+# CONFIG_HD is not set
+# CONFIG_XXD is not set
+# CONFIG_HWCLOCK is not set
+# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set
+# CONFIG_IONICE is not set
+# CONFIG_IPCRM is not set
+# CONFIG_IPCS is not set
+# CONFIG_LAST is not set
+# CONFIG_FEATURE_LAST_FANCY is not set
+# CONFIG_LOSETUP is not set
+# CONFIG_LSPCI is not set
+# CONFIG_LSUSB is not set
+# CONFIG_MDEV is not set
+# CONFIG_FEATURE_MDEV_CONF is not set
+# CONFIG_FEATURE_MDEV_RENAME is not set
+# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set
+# CONFIG_FEATURE_MDEV_EXEC is not set
+# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set
+# CONFIG_FEATURE_MDEV_DAEMON is not set
+# CONFIG_MESG is not set
+# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set
+# CONFIG_MKE2FS is not set
+# CONFIG_MKFS_EXT2 is not set
+# CONFIG_MKFS_MINIX is not set
+# CONFIG_FEATURE_MINIX2 is not set
+# CONFIG_MKFS_REISER is not set
+# CONFIG_MKDOSFS is not set
+# CONFIG_MKFS_VFAT is not set
+# CONFIG_MKSWAP is not set
+# CONFIG_FEATURE_MKSWAP_UUID is not set
+# CONFIG_MORE is not set
+# CONFIG_MOUNT is not set
+# CONFIG_FEATURE_MOUNT_FAKE is not set
+# CONFIG_FEATURE_MOUNT_VERBOSE is not set
+# CONFIG_FEATURE_MOUNT_HELPERS is not set
+# CONFIG_FEATURE_MOUNT_LABEL is not set
+# CONFIG_FEATURE_MOUNT_NFS is not set
+# CONFIG_FEATURE_MOUNT_CIFS is not set
+# CONFIG_FEATURE_MOUNT_FLAGS is not set
+# CONFIG_FEATURE_MOUNT_FSTAB is not set
+# CONFIG_FEATURE_MOUNT_OTHERTAB is not set
+# CONFIG_MOUNTPOINT is not set
+# CONFIG_NOLOGIN is not set
+# CONFIG_NOLOGIN_DEPENDENCIES is not set
+# CONFIG_NSENTER is not set
+# CONFIG_PIVOT_ROOT is not set
+# CONFIG_RDATE is not set
+# CONFIG_RDEV is not set
+# CONFIG_READPROFILE is not set
+# CONFIG_RENICE is not set
+# CONFIG_REV is not set
+# CONFIG_RTCWAKE is not set
+# CONFIG_SCRIPT is not set
+# CONFIG_SCRIPTREPLAY is not set
+# CONFIG_SETARCH is not set
+# CONFIG_LINUX32 is not set
+# CONFIG_LINUX64 is not set
+# CONFIG_SETPRIV is not set
+# CONFIG_FEATURE_SETPRIV_DUMP is not set
+# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set
+# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set
+# CONFIG_SETSID is not set
+# CONFIG_SWAPON is not set
+# CONFIG_FEATURE_SWAPON_DISCARD is not set
+# CONFIG_FEATURE_SWAPON_PRI is not set
+# CONFIG_SWAPOFF is not set
+# CONFIG_FEATURE_SWAPONOFF_LABEL is not set
+# CONFIG_SWITCH_ROOT is not set
+# CONFIG_TASKSET is not set
+# CONFIG_FEATURE_TASKSET_FANCY is not set
+# CONFIG_FEATURE_TASKSET_CPULIST is not set
+# CONFIG_UEVENT is not set
+# CONFIG_UMOUNT is not set
+# CONFIG_FEATURE_UMOUNT_ALL is not set
+# CONFIG_UNSHARE is not set
+# CONFIG_WALL is not set
+# CONFIG_FEATURE_MOUNT_LOOP is not set
+# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set
+# CONFIG_FEATURE_MTAB_SUPPORT is not set
+# CONFIG_VOLUMEID is not set
+# CONFIG_FEATURE_VOLUMEID_BCACHE is not set
+# CONFIG_FEATURE_VOLUMEID_BTRFS is not set
+# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set
+# CONFIG_FEATURE_VOLUMEID_EXFAT is not set
+# CONFIG_FEATURE_VOLUMEID_EXT is not set
+# CONFIG_FEATURE_VOLUMEID_F2FS is not set
+# CONFIG_FEATURE_VOLUMEID_FAT is not set
+# CONFIG_FEATURE_VOLUMEID_HFS is not set
+# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set
+# CONFIG_FEATURE_VOLUMEID_JFS is not set
+# CONFIG_FEATURE_VOLUMEID_LFS is not set
+# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set
+# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set
+# CONFIG_FEATURE_VOLUMEID_LUKS is not set
+# CONFIG_FEATURE_VOLUMEID_MINIX is not set
+# CONFIG_FEATURE_VOLUMEID_NILFS is not set
+# CONFIG_FEATURE_VOLUMEID_NTFS is not set
+# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set
+# CONFIG_FEATURE_VOLUMEID_REISERFS is not set
+# CONFIG_FEATURE_VOLUMEID_ROMFS is not set
+# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set
+# CONFIG_FEATURE_VOLUMEID_SYSV is not set
+# CONFIG_FEATURE_VOLUMEID_UBIFS is not set
+# CONFIG_FEATURE_VOLUMEID_UDF is not set
+# CONFIG_FEATURE_VOLUMEID_XFS is not set
+
+#
+# Miscellaneous Utilities
+#
+# CONFIG_ADJTIMEX is not set
+# CONFIG_BBCONFIG is not set
+# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set
+# CONFIG_BC is not set
+# CONFIG_DC is not set
+# CONFIG_FEATURE_DC_BIG is not set
+# CONFIG_FEATURE_DC_LIBM is not set
+# CONFIG_FEATURE_BC_INTERACTIVE is not set
+# CONFIG_FEATURE_BC_LONG_OPTIONS is not set
+# CONFIG_BEEP is not set
+CONFIG_FEATURE_BEEP_FREQ=0
+CONFIG_FEATURE_BEEP_LENGTH_MS=0
+# CONFIG_CHAT is not set
+# CONFIG_FEATURE_CHAT_NOFAIL is not set
+# CONFIG_FEATURE_CHAT_TTY_HIFI is not set
+# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set
+# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set
+# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set
+# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set
+# CONFIG_FEATURE_CHAT_CLR_ABORT is not set
+# CONFIG_CONSPY is not set
+# CONFIG_CROND is not set
+# CONFIG_FEATURE_CROND_D is not set
+# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set
+# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set
+CONFIG_FEATURE_CROND_DIR=""
+# CONFIG_CRONTAB is not set
+# CONFIG_DEVFSD is not set
+# CONFIG_DEVFSD_MODLOAD is not set
+# CONFIG_DEVFSD_FG_NP is not set
+# CONFIG_DEVFSD_VERBOSE is not set
+# CONFIG_FEATURE_DEVFS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_FBSPLASH is not set
+# CONFIG_FLASHCP is not set
+# CONFIG_FLASH_ERASEALL is not set
+# CONFIG_FLASH_LOCK is not set
+# CONFIG_FLASH_UNLOCK is not set
+# CONFIG_HDPARM is not set
+# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set
+# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set
+# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set
+# CONFIG_HEXEDIT is not set
+# CONFIG_I2CGET is not set
+# CONFIG_I2CSET is not set
+# CONFIG_I2CDUMP is not set
+# CONFIG_I2CDETECT is not set
+# CONFIG_I2CTRANSFER is not set
+# CONFIG_INOTIFYD is not set
+# CONFIG_LESS is not set
+CONFIG_FEATURE_LESS_MAXLINES=0
+# CONFIG_FEATURE_LESS_BRACKETS is not set
+# CONFIG_FEATURE_LESS_FLAGS is not set
+# CONFIG_FEATURE_LESS_TRUNCATE is not set
+# CONFIG_FEATURE_LESS_MARKS is not set
+# CONFIG_FEATURE_LESS_REGEXP is not set
+# CONFIG_FEATURE_LESS_WINCH is not set
+# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set
+# CONFIG_FEATURE_LESS_DASHCMD is not set
+# CONFIG_FEATURE_LESS_LINENUMS is not set
+# CONFIG_FEATURE_LESS_RAW is not set
+# CONFIG_FEATURE_LESS_ENV is not set
+# CONFIG_LSSCSI is not set
+# CONFIG_MAKEDEVS is not set
+# CONFIG_FEATURE_MAKEDEVS_LEAF is not set
+# CONFIG_FEATURE_MAKEDEVS_TABLE is not set
+# CONFIG_MAN is not set
+# CONFIG_MICROCOM is not set
+# CONFIG_MIM is not set
+# CONFIG_MT is not set
+# CONFIG_NANDWRITE is not set
+# CONFIG_NANDDUMP is not set
+# CONFIG_PARTPROBE is not set
+# CONFIG_RAIDAUTORUN is not set
+# CONFIG_READAHEAD is not set
+# CONFIG_RFKILL is not set
+# CONFIG_RUNLEVEL is not set
+# CONFIG_RX is not set
+# CONFIG_SETFATTR is not set
+# CONFIG_SETSERIAL is not set
+# CONFIG_STRINGS is not set
+# CONFIG_TIME is not set
+# CONFIG_TS is not set
+# CONFIG_TTYSIZE is not set
+# CONFIG_UBIRENAME is not set
+# CONFIG_UBIATTACH is not set
+# CONFIG_UBIDETACH is not set
+# CONFIG_UBIMKVOL is not set
+# CONFIG_UBIRMVOL is not set
+# CONFIG_UBIRSVOL is not set
+# CONFIG_UBIUPDATEVOL is not set
+# CONFIG_VOLNAME is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Networking Utilities
+#
+# CONFIG_FEATURE_IPV6 is not set
+# CONFIG_FEATURE_UNIX_LOCAL is not set
+# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set
+# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set
+# CONFIG_FEATURE_TLS_SHA1 is not set
+# CONFIG_ARP is not set
+# CONFIG_ARPING is not set
+# CONFIG_BRCTL is not set
+# CONFIG_FEATURE_BRCTL_FANCY is not set
+# CONFIG_FEATURE_BRCTL_SHOW is not set
+# CONFIG_DNSD is not set
+# CONFIG_ETHER_WAKE is not set
+# CONFIG_FTPD is not set
+# CONFIG_FEATURE_FTPD_WRITE is not set
+# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set
+# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set
+# CONFIG_FTPGET is not set
+# CONFIG_FTPPUT is not set
+# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set
+# CONFIG_HOSTNAME is not set
+# CONFIG_DNSDOMAINNAME is not set
+# CONFIG_HTTPD is not set
+# CONFIG_FEATURE_HTTPD_RANGES is not set
+# CONFIG_FEATURE_HTTPD_SETUID is not set
+# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set
+# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set
+# CONFIG_FEATURE_HTTPD_CGI is not set
+# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set
+# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set
+# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set
+# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set
+# CONFIG_FEATURE_HTTPD_PROXY is not set
+# CONFIG_FEATURE_HTTPD_GZIP is not set
+# CONFIG_IFCONFIG is not set
+# CONFIG_FEATURE_IFCONFIG_STATUS is not set
+# CONFIG_FEATURE_IFCONFIG_SLIP is not set
+# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set
+# CONFIG_FEATURE_IFCONFIG_HW is not set
+# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set
+# CONFIG_IFENSLAVE is not set
+# CONFIG_IFPLUGD is not set
+# CONFIG_IFUP is not set
+# CONFIG_IFDOWN is not set
+CONFIG_IFUPDOWN_IFSTATE_PATH=""
+# CONFIG_FEATURE_IFUPDOWN_IP is not set
+# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set
+# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set
+# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set
+# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set
+# CONFIG_INETD is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set
+# CONFIG_FEATURE_INETD_RPC is not set
+# CONFIG_IP is not set
+# CONFIG_IPADDR is not set
+# CONFIG_IPLINK is not set
+# CONFIG_IPROUTE is not set
+# CONFIG_IPTUNNEL is not set
+# CONFIG_IPRULE is not set
+# CONFIG_IPNEIGH is not set
+# CONFIG_FEATURE_IP_ADDRESS is not set
+# CONFIG_FEATURE_IP_LINK is not set
+# CONFIG_FEATURE_IP_ROUTE is not set
+CONFIG_FEATURE_IP_ROUTE_DIR=""
+# CONFIG_FEATURE_IP_TUNNEL is not set
+# CONFIG_FEATURE_IP_RULE is not set
+# CONFIG_FEATURE_IP_NEIGH is not set
+# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set
+# CONFIG_IPCALC is not set
+# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set
+# CONFIG_FEATURE_IPCALC_FANCY is not set
+# CONFIG_FAKEIDENTD is not set
+# CONFIG_NAMEIF is not set
+# CONFIG_FEATURE_NAMEIF_EXTENDED is not set
+# CONFIG_NBDCLIENT is not set
+# CONFIG_NC is not set
+# CONFIG_NETCAT is not set
+# CONFIG_NC_SERVER is not set
+# CONFIG_NC_EXTRA is not set
+# CONFIG_NC_110_COMPAT is not set
+# CONFIG_NETSTAT is not set
+# CONFIG_FEATURE_NETSTAT_WIDE is not set
+# CONFIG_FEATURE_NETSTAT_PRG is not set
+# CONFIG_NSLOOKUP is not set
+# CONFIG_FEATURE_NSLOOKUP_BIG is not set
+# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set
+# CONFIG_NTPD is not set
+# CONFIG_FEATURE_NTPD_SERVER is not set
+# CONFIG_FEATURE_NTPD_CONF is not set
+# CONFIG_FEATURE_NTP_AUTH is not set
+# CONFIG_PING is not set
+# CONFIG_PING6 is not set
+# CONFIG_FEATURE_FANCY_PING is not set
+# CONFIG_PSCAN is not set
+# CONFIG_ROUTE is not set
+# CONFIG_SLATTACH is not set
+# CONFIG_SSL_CLIENT is not set
+# CONFIG_TC is not set
+# CONFIG_FEATURE_TC_INGRESS is not set
+# CONFIG_TCPSVD is not set
+# CONFIG_UDPSVD is not set
+# CONFIG_TELNET is not set
+# CONFIG_FEATURE_TELNET_TTYPE is not set
+# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set
+# CONFIG_FEATURE_TELNET_WIDTH is not set
+# CONFIG_TELNETD is not set
+# CONFIG_FEATURE_TELNETD_STANDALONE is not set
+# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set
+# CONFIG_TFTP is not set
+# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set
+# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set
+# CONFIG_TFTPD is not set
+# CONFIG_FEATURE_TFTP_GET is not set
+# CONFIG_FEATURE_TFTP_PUT is not set
+# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set
+# CONFIG_TFTP_DEBUG is not set
+# CONFIG_TLS is not set
+# CONFIG_TRACEROUTE is not set
+# CONFIG_TRACEROUTE6 is not set
+# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
+# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
+# CONFIG_TUNCTL is not set
+# CONFIG_FEATURE_TUNCTL_UG is not set
+# CONFIG_VCONFIG is not set
+# CONFIG_WGET is not set
+# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set
+# CONFIG_FEATURE_WGET_STATUSBAR is not set
+# CONFIG_FEATURE_WGET_AUTHENTICATION is not set
+# CONFIG_FEATURE_WGET_TIMEOUT is not set
+# CONFIG_FEATURE_WGET_HTTPS is not set
+# CONFIG_FEATURE_WGET_OPENSSL is not set
+# CONFIG_WHOIS is not set
+# CONFIG_ZCIP is not set
+# CONFIG_UDHCPD is not set
+# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set
+# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set
+CONFIG_DHCPD_LEASES_FILE=""
+# CONFIG_DUMPLEASES is not set
+# CONFIG_DHCPRELAY is not set
+# CONFIG_UDHCPC is not set
+# CONFIG_FEATURE_UDHCPC_ARPING is not set
+# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set
+CONFIG_UDHCPC_DEFAULT_SCRIPT=""
+# CONFIG_UDHCPC6 is not set
+# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set
+# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set
+# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set
+# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set
+# CONFIG_FEATURE_UDHCP_PORT is not set
+CONFIG_UDHCP_DEBUG=0
+CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0
+# CONFIG_FEATURE_UDHCP_RFC3397 is not set
+# CONFIG_FEATURE_UDHCP_8021Q is not set
+CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS=""
+
+#
+# Print Utilities
+#
+# CONFIG_LPD is not set
+# CONFIG_LPR is not set
+# CONFIG_LPQ is not set
+
+#
+# Mail Utilities
+#
+# CONFIG_MAKEMIME is not set
+# CONFIG_POPMAILDIR is not set
+# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set
+# CONFIG_REFORMIME is not set
+# CONFIG_FEATURE_REFORMIME_COMPAT is not set
+# CONFIG_SENDMAIL is not set
+CONFIG_FEATURE_MIME_CHARSET=""
+
+#
+# Process Utilities
+#
+# CONFIG_FREE is not set
+# CONFIG_FUSER is not set
+# CONFIG_IOSTAT is not set
+# CONFIG_KILL is not set
+# CONFIG_KILLALL is not set
+# CONFIG_KILLALL5 is not set
+# CONFIG_LSOF is not set
+# CONFIG_MPSTAT is not set
+# CONFIG_NMETER is not set
+# CONFIG_PGREP is not set
+# CONFIG_PKILL is not set
+# CONFIG_PIDOF is not set
+# CONFIG_FEATURE_PIDOF_SINGLE is not set
+# CONFIG_FEATURE_PIDOF_OMIT is not set
+# CONFIG_PMAP is not set
+# CONFIG_POWERTOP is not set
+# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set
+# CONFIG_PS is not set
+# CONFIG_FEATURE_PS_WIDE is not set
+# CONFIG_FEATURE_PS_LONG is not set
+# CONFIG_FEATURE_PS_TIME is not set
+# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set
+# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set
+# CONFIG_PSTREE is not set
+# CONFIG_PWDX is not set
+# CONFIG_SMEMCAP is not set
+# CONFIG_BB_SYSCTL is not set
+# CONFIG_TOP is not set
+# CONFIG_FEATURE_TOP_INTERACTIVE is not set
+# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set
+# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set
+# CONFIG_FEATURE_TOP_SMP_CPU is not set
+# CONFIG_FEATURE_TOP_DECIMALS is not set
+# CONFIG_FEATURE_TOP_SMP_PROCESS is not set
+# CONFIG_FEATURE_TOPMEM is not set
+# CONFIG_UPTIME is not set
+# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set
+# CONFIG_WATCH is not set
+# CONFIG_FEATURE_SHOW_THREADS is not set
+
+#
+# Runit Utilities
+#
+# CONFIG_CHPST is not set
+# CONFIG_SETUIDGID is not set
+# CONFIG_ENVUIDGID is not set
+# CONFIG_ENVDIR is not set
+# CONFIG_SOFTLIMIT is not set
+# CONFIG_RUNSV is not set
+# CONFIG_RUNSVDIR is not set
+# CONFIG_FEATURE_RUNSVDIR_LOG is not set
+# CONFIG_SV is not set
+CONFIG_SV_DEFAULT_SERVICE_DIR=""
+# CONFIG_SVC is not set
+# CONFIG_SVOK is not set
+# CONFIG_SVLOGD is not set
+# CONFIG_CHCON is not set
+# CONFIG_GETENFORCE is not set
+# CONFIG_GETSEBOOL is not set
+# CONFIG_LOAD_POLICY is not set
+# CONFIG_MATCHPATHCON is not set
+# CONFIG_RUNCON is not set
+# CONFIG_SELINUXENABLED is not set
+# CONFIG_SESTATUS is not set
+# CONFIG_SETENFORCE is not set
+# CONFIG_SETFILES is not set
+# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set
+# CONFIG_RESTORECON is not set
+# CONFIG_SETSEBOOL is not set
+
+#
+# Shells
+#
+CONFIG_SH_IS_ASH=y
+# CONFIG_SH_IS_HUSH is not set
+# CONFIG_SH_IS_NONE is not set
+# CONFIG_BASH_IS_ASH is not set
+# CONFIG_BASH_IS_HUSH is not set
+CONFIG_BASH_IS_NONE=y
+CONFIG_SHELL_ASH=y
+# CONFIG_ASH is not set
+# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set
+# CONFIG_ASH_INTERNAL_GLOB is not set
+# CONFIG_ASH_BASH_COMPAT is not set
+# CONFIG_ASH_BASH_SOURCE_CURDIR is not set
+# CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set
+# CONFIG_ASH_JOB_CONTROL is not set
+# CONFIG_ASH_ALIAS is not set
+# CONFIG_ASH_RANDOM_SUPPORT is not set
+# CONFIG_ASH_EXPAND_PRMT is not set
+# CONFIG_ASH_IDLE_TIMEOUT is not set
+# CONFIG_ASH_MAIL is not set
+# CONFIG_ASH_ECHO is not set
+# CONFIG_ASH_PRINTF is not set
+# CONFIG_ASH_TEST is not set
+# CONFIG_ASH_HELP is not set
+# CONFIG_ASH_GETOPTS is not set
+# CONFIG_ASH_CMDCMD is not set
+# CONFIG_CTTYHACK is not set
+# CONFIG_HUSH is not set
+# CONFIG_SHELL_HUSH is not set
+# CONFIG_HUSH_BASH_COMPAT is not set
+# CONFIG_HUSH_BRACE_EXPANSION is not set
+# CONFIG_HUSH_LINENO_VAR is not set
+# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set
+# CONFIG_HUSH_INTERACTIVE is not set
+# CONFIG_HUSH_SAVEHISTORY is not set
+# CONFIG_HUSH_JOB is not set
+# CONFIG_HUSH_TICK is not set
+# CONFIG_HUSH_IF is not set
+# CONFIG_HUSH_LOOPS is not set
+# CONFIG_HUSH_CASE is not set
+# CONFIG_HUSH_FUNCTIONS is not set
+# CONFIG_HUSH_LOCAL is not set
+# CONFIG_HUSH_RANDOM_SUPPORT is not set
+# CONFIG_HUSH_MODE_X is not set
+# CONFIG_HUSH_ECHO is not set
+# CONFIG_HUSH_PRINTF is not set
+# CONFIG_HUSH_TEST is not set
+# CONFIG_HUSH_HELP is not set
+# CONFIG_HUSH_EXPORT is not set
+# CONFIG_HUSH_EXPORT_N is not set
+# CONFIG_HUSH_READONLY is not set
+# CONFIG_HUSH_KILL is not set
+# CONFIG_HUSH_WAIT is not set
+# CONFIG_HUSH_COMMAND is not set
+# CONFIG_HUSH_TRAP is not set
+# CONFIG_HUSH_TYPE is not set
+# CONFIG_HUSH_TIMES is not set
+# CONFIG_HUSH_READ is not set
+# CONFIG_HUSH_SET is not set
+# CONFIG_HUSH_UNSET is not set
+# CONFIG_HUSH_ULIMIT is not set
+# CONFIG_HUSH_UMASK is not set
+# CONFIG_HUSH_GETOPTS is not set
+# CONFIG_HUSH_MEMLEAK is not set
+
+#
+# Options common to all shells
+#
+# CONFIG_FEATURE_SH_MATH is not set
+# CONFIG_FEATURE_SH_MATH_64 is not set
+# CONFIG_FEATURE_SH_MATH_BASE is not set
+# CONFIG_FEATURE_SH_EXTRA_QUIET is not set
+# CONFIG_FEATURE_SH_STANDALONE is not set
+# CONFIG_FEATURE_SH_NOFORK is not set
+# CONFIG_FEATURE_SH_READ_FRAC is not set
+# CONFIG_FEATURE_SH_HISTFILESIZE is not set
+# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set
+
+#
+# System Logging Utilities
+#
+# CONFIG_KLOGD is not set
+# CONFIG_FEATURE_KLOGD_KLOGCTL is not set
+# CONFIG_LOGGER is not set
+# CONFIG_LOGREAD is not set
+# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set
+# CONFIG_SYSLOGD is not set
+# CONFIG_FEATURE_ROTATE_LOGFILE is not set
+# CONFIG_FEATURE_REMOTE_LOG is not set
+# CONFIG_FEATURE_SYSLOGD_DUP is not set
+# CONFIG_FEATURE_SYSLOGD_CFG is not set
+# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set
+CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0
+# CONFIG_FEATURE_IPC_SYSLOG is not set
+CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0
+# CONFIG_FEATURE_KMSG_SYSLOG is not set
6. get dmsetup/dmsetup.static as the dmsetupaa64 binary file\r
\r
\r
+======================== Build for mips64 dmsetup =========================\r
+1. extract device mapper source code\r
+2. ./configure CC="mips64el-linux-musl-gcc -mips64r2 -mabi=64" --target=mips --host=x86_64-linux-gnu --disable-nls --disable-selinux --disable-shared --enable-static_link\r
+3. modify include/configure.h file\r
+ --- delete the line with "#define malloc rpl_malloc"\r
+4. make\r
+5. mips64el-linux-musl-strip dmsetup/dmsetup.static\r
+6. get dmsetup/dmsetup.static as the dmsetupm64e binary file\r
+\r
+\r
\r
\r
\r
https://codeload.github.com/libfuse/libfuse/zip/fuse-2.9.9 ===> /home/Ventoy-master/ExFAT/libfuse-fuse-2.9.9.zip\r
https://releases.linaro.org/components/toolchain/binaries/7.4-2019.02/aarch64-linux-gnu/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz ===> /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz\r
https://toolchains.bootlin.com/downloads/releases/toolchains/aarch64/tarballs/aarch64--uclibc--stable-2020.08-1.tar.bz2 ===> /opt/aarch64--uclibc--stable-2020.08-1.tar.bz2\r
+ http://ftp.loongnix.org/toolchain/gcc/release/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz ===> /opt/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz\r
+ https://github.com/ventoy/musl-cross-make/releases/download/latest/output.tar.bz2 ===> /opt/output.tar.bz2\r
+\r
\r
http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/vmlinuz64 ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/vmlinuz64\r
http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/corepure64.gz ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/corepure64.gz\r
- http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/modules64.gz ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/modules64.gz\r
- http://distro.ibiblio.org/tinycorelinux/11.x/x86_64/tcz/glib2.tcz /home/Ventoy-master/LiveCD/VTOY/ventoy/tcz/glib2.tcz\r
- http://distro.ibiblio.org/tinycorelinux/11.x/x86_64/tcz/libffi.tcz /home/Ventoy-master/LiveCD/VTOY/ventoy/tcz/libffi.tcz\r
- http://distro.ibiblio.org/tinycorelinux/11.x/x86_64/tcz/liblvm2.tcz /home/Ventoy-master/LiveCD/VTOY/ventoy/tcz/liblvm2.tcz\r
- http://distro.ibiblio.org/tinycorelinux/11.x/x86_64/tcz/ncursesw.tcz /home/Ventoy-master/LiveCD/VTOY/ventoy/tcz/ncursesw.tcz\r
- http://distro.ibiblio.org/tinycorelinux/11.x/x86_64/tcz/parted.tcz /home/Ventoy-master/LiveCD/VTOY/ventoy/tcz/parted.tcz\r
- http://distro.ibiblio.org/tinycorelinux/11.x/x86_64/tcz/readline.tcz /home/Ventoy-master/LiveCD/VTOY/ventoy/tcz/readline.tcz\r
- http://distro.ibiblio.org/tinycorelinux/11.x/x86_64/tcz/udev-lib.tcz /home/Ventoy-master/LiveCD/VTOY/ventoy/tcz/udev-lib.tcz\r
+ http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/modules64.gz ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/modules64.gz \r
\r
2.3 Prepare third-part tools\r
cd /home/Ventoy-master/DOC/\r
\r
tar xf /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz -C /opt\r
tar xf /opt/aarch64--uclibc--stable-2020.08-1.tar.bz2 -C /opt\r
+ tar xf /opt/output.tar.bz2 -C /opt\r
+ mv /opt/output /opt/mips64el-linux-musl-gcc730\r
+ \r
\r
2.4 Set PATH envrioment\r
- export PATH=$PATH:/opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin:/opt/aarch64--uclibc--stable-2020.08-1/bin\r
+ export PATH=$PATH:/opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin:/opt/aarch64--uclibc--stable-2020.08-1/bin:/opt/mips64el-linux-musl-gcc730/bin\r
better to add this line to /root/.bashrc and relogin as root\r
\r
\r
[ -d /opt/aarch64--uclibc--stable-2020.08-1 ] || tar xf /opt/aarch64--uclibc--stable-2020.08-1.tar.bz2 -C /opt
+[ -d /opt/mips-loongson-gcc7.3-linux-gnu ] || tar xf /opt/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz -C /opt
--- /dev/null
+# -*- autoconf -*-
+
+# Process this file with autoconf to produce a configure script.
+
+# Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
+#
+# This configure.ac is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+dnl This configure script is complicated, because GRUB needs to deal
+dnl with three potentially different types:
+dnl
+dnl build -- the environment for building GRUB
+dnl host -- the environment for running utilities
+dnl target -- the environment for running GRUB
+dnl
+dnl In addition, GRUB needs to deal with a platform specification
+dnl which specifies the system running GRUB, such as firmware.
+dnl This is necessary because the target type in autoconf does not
+dnl describe such a system very well.
+dnl
+dnl The current strategy is to use variables with no prefix (such as
+dnl CC, CFLAGS, etc.) for the host type, variables with prefix "BUILD_"
+dnl (such as BUILD_CC, BUILD_CFLAGS, etc.) for the build type and variables
+dnl with the prefix "TARGET_" (such as TARGET_CC, TARGET_CFLAGS, etc.) are
+dnl used for the target type. See INSTALL for full list of variables.
+
+AC_INIT([GRUB],[2.04],[bug-grub@gnu.org])
+
+AC_CONFIG_AUX_DIR([build-aux])
+
+# We don't want -g -O2 by default in CFLAGS
+: ${CFLAGS=""}
+
+# Checks for build, host and target systems.
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+save_program_prefix="${program_prefix}"
+AC_CANONICAL_TARGET
+program_prefix="${save_program_prefix}"
+
+AM_INIT_AUTOMAKE([1.11])
+AC_PREREQ(2.63)
+AC_CONFIG_SRCDIR([include/grub/dl.h])
+AC_CONFIG_HEADER([config-util.h])
+
+# Explicitly check for pkg-config early on, since otherwise conditional
+# calls are problematic.
+PKG_PROG_PKG_CONFIG
+
+# Program name transformations
+AC_ARG_PROGRAM
+grub_TRANSFORM([grub-bios-setup])
+grub_TRANSFORM([grub-editenv])
+grub_TRANSFORM([grub-install])
+grub_TRANSFORM([grub-mkconfig])
+grub_TRANSFORM([grub-mkfont])
+grub_TRANSFORM([grub-mkimage])
+grub_TRANSFORM([grub-glue-efi])
+grub_TRANSFORM([grub-mklayout])
+grub_TRANSFORM([grub-mkpasswd-pbkdf2])
+grub_TRANSFORM([grub-mkrelpath])
+grub_TRANSFORM([grub-mkrescue])
+grub_TRANSFORM([grub-probe])
+grub_TRANSFORM([grub-reboot])
+grub_TRANSFORM([grub-script-check])
+grub_TRANSFORM([grub-set-default])
+grub_TRANSFORM([grub-sparc64-setup])
+grub_TRANSFORM([grub-render-label])
+grub_TRANSFORM([grub-file])
+
+# Optimization flag. Allow user to override.
+if test "x$TARGET_CFLAGS" = x; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -Os"
+fi
+
+# Default HOST_CPPFLAGS
+HOST_CPPFLAGS="$HOST_CPPFLAGS -Wall -W"
+HOST_CPPFLAGS="$HOST_CPPFLAGS -DGRUB_UTIL=1"
+
+TARGET_CPPFLAGS="$TARGET_CPPFLAGS -Wall -W"
+
+case "$target_cpu" in
+ i[[3456]]86) target_cpu=i386 ;;
+ amd64) target_cpu=x86_64 ;;
+ sparc) target_cpu=sparc64 ;;
+ mips64el)
+ target_cpu=mips64el
+ machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPS64EL=1"
+ ;;
+ mipsel)
+ target_cpu=mipsel
+ machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPSEL=1"
+ ;;
+ mips|mips64)
+ target_cpu=mips
+ machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPS=1"
+ ;;
+ arm*)
+ target_cpu=arm
+ ;;
+ aarch64*)
+ target_cpu=arm64
+ ;;
+ riscv32*)
+ target_cpu=riscv32
+ ;;
+ riscv64*)
+ target_cpu=riscv64
+ ;;
+esac
+
+# Specify the platform (such as firmware).
+AC_ARG_WITH([platform],
+ AS_HELP_STRING([--with-platform=PLATFORM],
+ [select the host platform [[guessed]]]))
+
+# Guess the platform if not specified.
+if test "x$with_platform" = x; then
+ case "$target_cpu"-"$target_vendor" in
+ i386-apple) platform=efi ;;
+ i386-*) platform=pc ;;
+ x86_64-apple) platform=efi ;;
+ x86_64-*) platform=pc ;;
+ powerpc-*) platform=ieee1275 ;;
+ powerpc64-*) platform=ieee1275 ;;
+ powerpc64le-*) platform=ieee1275 ;;
+ sparc64-*) platform=ieee1275 ;;
+ mips64el-*) platform=efi;;
+ mipsel-*) platform=loongson ;;
+ mips-*) platform=arc ;;
+ ia64-*) platform=efi ;;
+ arm-*) platform=uboot ;;
+ arm64-*) platform=efi ;;
+ riscv32-*) platform=efi ;;
+ riscv64-*) platform=efi ;;
+ *)
+ AC_MSG_WARN([unsupported CPU: "$target_cpu" - only building utilities])
+ platform=none
+ ;;
+ esac
+else
+ platform="$with_platform"
+fi
+
+case "$target_cpu"-"$platform" in
+ x86_64-efi) ;;
+ x86_64-emu) ;;
+ x86_64-xen) ;;
+ x86_64-none) ;;
+ x86_64-*) target_cpu=i386 ;;
+ powerpc64-ieee1275) target_cpu=powerpc ;;
+ powerpc64le-ieee1275) target_cpu=powerpc ;;
+esac
+
+# Check if the platform is supported, make final adjustments.
+case "$target_cpu"-"$platform" in
+ i386-efi) ;;
+ x86_64-efi) ;;
+ i386-xen) ;;
+ i386-xen_pvh) ;;
+ x86_64-xen) ;;
+ i386-pc) ;;
+ i386-multiboot) ;;
+ i386-coreboot) ;;
+ i386-linuxbios) platform=coreboot ;;
+ i386-ieee1275) ;;
+ i386-qemu) ;;
+ powerpc-ieee1275) ;;
+ sparc64-ieee1275) ;;
+ ia64-efi) ;;
+ mips-qemu_mips) ;;
+ mips-qemu-mips) platform=qemu_mips;;
+ mips-arc) ;;
+ mipsel-arc) ;;
+ mipsel-qemu_mips) ;;
+ mipsel-qemu-mips) platform=qemu_mips;;
+ mipsel-yeeloong) platform=loongson ;;
+ mipsel-fuloong) platform=loongson ;;
+ mipsel-loongson) ;;
+ mips64el-efi) ;;
+ arm-uboot) ;;
+ arm-coreboot) ;;
+ arm-efi) ;;
+ arm64-efi) ;;
+ riscv32-efi) ;;
+ riscv64-efi) ;;
+ *-emu) ;;
+ *-none) ;;
+ *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
+esac
+
+if test x$platform != xemu ; then
+ case "$target_cpu" in
+ i386 | powerpc) target_m32=1 ;;
+ x86_64 | sparc64) target_m64=1 ;;
+ esac
+fi
+
+if test x"$target_cpu-$platform" = xsparc64-emu ; then
+ target_m64=1
+fi
+
+case "$target_os" in
+ windows* | mingw32*) target_os=cygwin ;;
+esac
+
+# This normalizes the names, and creates a new variable ("host_kernel")
+# while at it, since the mapping is not always 1:1 (e.g. different OSes
+# using the same kernel type).
+case "$host_os" in
+ gnu*) host_kernel=hurd ;;
+ linux*) host_kernel=linux ;;
+ freebsd* | kfreebsd*-gnu) host_kernel=kfreebsd ;;
+ netbsd*) host_kernel=netbsd ;;
+ solaris*) host_kernel=illumos ;;
+ darwin*) host_kernel=xnu ;;
+ cygwin | windows* | mingw32*) host_kernel=windows ;;
+esac
+
+case "$host_os" in
+ cygwin) have_exec=y ;;
+ windows* | mingw32*) have_exec=n ;;
+ aros*) have_exec=n ;;
+ *) have_exec=y;;
+esac
+
+case "$platform" in
+ coreboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_COREBOOT=1" ;;
+ multiboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MULTIBOOT=1" ;;
+ efi) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EFI=1" ;;
+ xen) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_XEN=1" ;;
+ xen_pvh) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_XEN_PVH=1" ;;
+ ieee1275) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_IEEE1275=1" ;;
+ uboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_UBOOT=1" ;;
+ qemu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_QEMU=1" ;;
+ pc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_PCBIOS=1" ;;
+ emu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EMU=1" ;;
+ loongson) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_LOONGSON=1" ;;
+ qemu_mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_QEMU_MIPS=1" ;;
+ arc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARC=1" ;;
+esac
+if test x${target_cpu} = xmipsel ; then
+ machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE=`echo mips_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`"
+else
+ machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE=`echo ${target_cpu}_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`"
+fi
+
+case "${target_cpu}-$platform" in
+ mips-arc)
+ TARGET_LINK_ADDR=0x88200000
+ TARGET_DECOMPRESSOR_LINK_ADDR=0x88100000
+ ;;
+ mipsel-arc)
+ TARGET_LINK_ADDR=0x80700000
+ TARGET_DECOMPRESSOR_LINK_ADDR=0x80600000
+ ;;
+ mips*-qemu_mips | mips*-loongson)
+ TARGET_DECOMPRESSOR_LINK_ADDR=0x80100000
+ ;;
+esac
+
+AC_SUBST(TARGET_LINK_ADDR)
+AC_SUBST(TARGET_DECOMPRESSOR_LINK_ADDR)
+
+TARGET_CPPFLAGS="$TARGET_CPPFLAGS $machine_CPPFLAGS"
+
+AC_SUBST(host_cpu)
+AC_SUBST(host_os)
+AC_SUBST(host_kernel)
+
+AC_SUBST(target_cpu)
+AC_SUBST(platform)
+
+# Define default variables
+
+have_with_bootdir=n
+AC_ARG_WITH([bootdir],
+ AS_HELP_STRING([--with-bootdir=DIR],
+ [set the name of /boot directory [[guessed]]]),
+ [have_with_bootdir=y],
+ [have_with_bootdir=n])
+if test x$have_with_bootdir = xy; then
+ bootdirname="$with_bootdir"
+else
+ case "$host_os" in
+ netbsd* | openbsd*)
+ # Because /boot is used for the boot block in NetBSD and OpenBSD,
+ bootdirname='' ;;
+ *) bootdirname='boot' ;;
+ esac
+fi
+
+AC_SUBST(bootdirname)
+AC_DEFINE_UNQUOTED(GRUB_BOOT_DIR_NAME, "$bootdirname",
+ [Default boot directory name])
+
+AC_ARG_WITH([grubdir],
+ AS_HELP_STRING([--with-grubdir=DIR],
+ [set the name of grub directory [[guessed]]]),
+ [grubdirname="$with_grubdir"],
+ [grubdirname="$PACKAGE"])
+
+AC_SUBST(grubdirname)
+AC_DEFINE_UNQUOTED(GRUB_DIR_NAME, "$grubdirname",
+ [Default grub directory name])
+
+#
+# Checks for build programs.
+#
+
+# Although cmp is listed in the GNU Coding Standards as a command which
+# can used directly, OpenBSD lacks cmp in the default installation.
+AC_CHECK_PROGS([CMP], [cmp])
+if test "x$CMP" = x; then
+ AC_MSG_ERROR([cmp is not found])
+fi
+
+AC_CHECK_PROGS([YACC], [bison])
+if test "x$YACC" = x; then
+ AC_MSG_ERROR([bison is not found])
+fi
+
+AC_PROG_RANLIB
+AC_PROG_INSTALL
+AC_PROG_AWK
+AC_PROG_LEX
+AC_PROG_YACC
+AC_PROG_MAKE_SET
+AC_PROG_MKDIR_P
+AC_PROG_LN_S
+
+if test "x$LEX" = "x:"; then
+ AC_MSG_ERROR([flex is not found])
+else
+ version=`$LEX --version | $AWK '{ split($2,x,"."); print x[[1]]*10000+x[[2]]*100+x[[3]]; }'`
+ if test -n "$version" -a "$version" -ge 20535; then
+ :
+ else
+ AC_MSG_ERROR([flex is too old. GRUB requires 2.5.35 or above])
+ fi
+fi
+
+# These are not a "must".
+AC_PATH_PROGS(MAKEINFO, makeinfo true)
+
+#
+# Checks for host programs.
+#
+
+AC_PROG_CC
+gl_EARLY
+AC_PROG_CXX
+AM_PROG_CC_C_O
+AM_PROG_AS
+AM_PATH_PYTHON([2.6])
+
+# Must be GCC.
+test "x$GCC" = xyes || AC_MSG_ERROR([GCC is required])
+
+AC_CHECK_PROG(HAVE_CXX, $CXX, yes, no)
+
+AC_GNU_SOURCE
+AM_GNU_GETTEXT([external])
+AM_GNU_GETTEXT_VERSION([0.18.3])
+AC_SYS_LARGEFILE
+
+# Identify characteristics of the host architecture.
+unset ac_cv_c_bigendian
+
+if test x"$target_cpu-$platform" = xsparc64-emu ; then
+ CFLAGS="$CFLAGS -m64"
+ HOST_CFLAGS="$HOST_CFLAGS -m64"
+fi
+
+CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64"
+HOST_CPPFLAGS="$HOST_CPPFLAGS -D_FILE_OFFSET_BITS=64"
+
+AC_C_BIGENDIAN
+AC_CHECK_SIZEOF(void *)
+AC_CHECK_SIZEOF(long)
+
+case "$host_os" in
+ cygwin | windows* | mingw32*)
+ HOST_CPPFLAGS="$HOST_CPPFLAGS -DUNICODE=1 -D_WIN32_WINNT=0x0500"
+ CPPFLAGS="$CPPFLAGS -DUNICODE=1 -D_WIN32_WINNT=0x0500"
+ AC_CHECK_SIZEOF(TCHAR,,[#include <windows.h>])
+ ;;
+esac
+
+case "$host_os" in
+ cygwin | windows* | mingw32* | aros*)
+ ;;
+ *)
+ AC_CHECK_SIZEOF(off_t)
+ if test x"$ac_cv_sizeof_off_t" != x8 ; then
+ AC_CHECK_SIZEOF(off64_t)
+ test x"$ac_cv_sizeof_off64_t" = x8 || AC_MSG_ERROR([Large file support is required])
+ fi;;
+esac
+
+if test x$USE_NLS = xno; then
+ HOST_CFLAGS="$HOST_CFLAGS -fno-builtin-gettext"
+fi
+
+if test "x$cross_compiling" = xyes; then
+ AC_MSG_WARN([cannot generate manual pages while cross compiling])
+else
+ AC_PATH_PROG(HELP2MAN, help2man)
+fi
+
+# Check for functions and headers.
+AC_CHECK_FUNCS(posix_memalign memalign getextmntent)
+AC_CHECK_HEADERS(sys/param.h sys/mount.h sys/mnttab.h limits.h)
+
+# glibc 2.25 still includes sys/sysmacros.h in sys/types.h but emits deprecation
+# warning which causes compilation failure later with -Werror. So use -Werror here
+# as well to force proper sys/sysmacros.h detection.
+SAVED_CFLAGS="$CFLAGS"
+CFLAGS="$HOST_CFLAGS -Werror"
+AC_HEADER_MAJOR
+CFLAGS="$SAVED_CFLAGS"
+
+AC_CHECK_MEMBERS([struct statfs.f_fstypename],,,[$ac_includes_default
+#include <sys/param.h>
+#include <sys/mount.h>])
+
+AC_CHECK_MEMBERS([struct statfs.f_mntfromname],,,[$ac_includes_default
+#include <sys/param.h>
+#include <sys/mount.h>])
+
+# For opendisk() and getrawpartition() on NetBSD.
+# Used in util/deviceiter.c and in util/hostdisk.c.
+AC_CHECK_HEADER([util.h], [
+ AC_CHECK_LIB([util], [opendisk], [
+ LIBUTIL="-lutil"
+ AC_DEFINE(HAVE_OPENDISK, 1, [Define if opendisk() in -lutil can be used])
+ ])
+ AC_CHECK_LIB([util], [getrawpartition], [
+ LIBUTIL="-lutil"
+ AC_DEFINE(HAVE_GETRAWPARTITION, 1, [Define if getrawpartition() in -lutil can be used])
+ ])
+])
+AC_SUBST([LIBUTIL])
+
+AC_CACHE_CHECK([whether -Wtrampolines work], [grub_cv_host_cc_wtrampolines], [
+ SAVED_CFLAGS="$CFLAGS"
+ CFLAGS="$HOST_CFLAGS -Wtrampolines -Werror"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdarg.h>
+int va_arg_func (int fixed, va_list args);]], [[]])],
+ [grub_cv_host_cc_wtrampolines=yes],
+ [grub_cv_host_cc_wtrampolines=no])
+ CFLAGS="$SAVED_CFLAGS"
+])
+
+if test x"$grub_host_cv_cc_wtrampolines" = xyes ; then
+ HOST_CFLAGS="$HOST_CFLAGS -Wtrampolines"
+fi
+
+#
+# Check for host and build compilers.
+#
+HOST_CC=$CC
+AC_CHECK_PROGS(BUILD_CC, [gcc egcs cc])
+test -z "$BUILD_CC" && AC_MSG_ERROR([none of gcc, egcs and cc is found. set BUILD_CC manually.])
+BUILD_CPP="$BUILD_CC -E"
+
+case "$build_os" in
+ haiku*) BUILD_LIBM= ;;
+ *) BUILD_LIBM=-lm ;;
+esac
+
+dnl FIXME proper test seems to require too deep dive into Autoconf internals.
+dnl For now just list known platforms that we support.
+
+case "$build_os" in
+ cygwin*|mingw32*|mingw64*) BUILD_EXEEXT=.exe ;;
+ *) BUILD_EXEEXT= ;;
+esac
+AC_SUBST(BUILD_EXEEXT)
+
+# In some build environments like termux /bin/sh is not a valid
+# shebang. Use $SHELL instead if it's executable and /bin/sh isn't
+BUILD_SHEBANG=/bin/sh
+for she in /bin/sh "$SHELL"; do
+ if test -x "$she" ; then
+ BUILD_SHEBANG="$she"
+ fi
+done
+AC_SUBST(BUILD_SHEBANG)
+
+# For gnulib.
+gl_INIT
+
+WARN_FLAGS="-Wall -W -Wshadow -Wpointer-arith -Wundef -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wmain -Wmissing-braces -Wmissing-format-attribute -Wmultichar -Wparentheses -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wswitch -Wtrigraphs -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wwrite-strings -Wnested-externs -Wstrict-prototypes"
+EXTRA_WARN_FLAGS="-Wextra -Wattributes -Wendif-labels -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmissing-field-initializers -Wnonnull -Woverflow -Wvla -Wpointer-to-int-cast -Wstrict-aliasing -Wvariadic-macros -Wvolatile-register-var -Wpointer-sign -Wmissing-include-dirs -Wmissing-prototypes -Wmissing-declarations -Wformat=2"
+
+HOST_CFLAGS="$HOST_CFLAGS $WARN_FLAGS -Wcast-align"
+
+AC_CACHE_CHECK([which extra warnings work], [grub_cv_cc_w_extra_flags], [
+ SAVED_CFLAGS="$CFLAGS"
+ grub_cv_cc_w_extra_flags=
+ for x in $EXTRA_WARN_FLAGS; do
+ CFLAGS="$HOST_CFLAGS $x -Werror"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [flag=1], [flag=0])
+ if test x$flag = x1 ; then
+ grub_cv_cc_w_extra_flags="$grub_cv_cc_w_extra_flags $x"
+ fi
+ done
+ CFLAGS="$SAVED_CFLAGS"
+])
+
+HOST_CFLAGS="$HOST_CFLAGS $grub_cv_cc_w_extra_flags"
+
+#
+# Check for target programs.
+#
+
+# Find tools for the target.
+if test "x$target_alias" != x && test "x$host_alias" != "x$target_alias"; then
+ tmp_ac_tool_prefix="$ac_tool_prefix"
+ ac_tool_prefix=$target_alias-
+
+ AC_CHECK_TOOLS(TARGET_CC, [gcc egcs cc],
+ [AC_MSG_ERROR([none of gcc, egcs and cc is found. set TARGET_CC manually.])])
+ AC_CHECK_TOOL(TARGET_OBJCOPY, objcopy)
+ AC_CHECK_TOOL(TARGET_STRIP, strip)
+ AC_CHECK_TOOL(TARGET_NM, nm)
+ AC_CHECK_TOOL(TARGET_RANLIB, ranlib)
+
+ ac_tool_prefix="$tmp_ac_tool_prefix"
+else
+ if test "x$TARGET_CC" = x; then
+ TARGET_CC=$CC
+ fi
+ AC_CHECK_TOOL(TARGET_OBJCOPY, objcopy)
+ AC_CHECK_TOOL(TARGET_STRIP, strip)
+ AC_CHECK_TOOL(TARGET_NM, nm)
+ AC_CHECK_TOOL(TARGET_RANLIB, ranlib)
+fi
+
+AC_SUBST(HOST_CC)
+AC_SUBST(BUILD_CC)
+AC_SUBST(BUILD_CFLAGS)
+AC_SUBST(BUILD_CPPFLAGS)
+AC_SUBST(BUILD_LDFLAGS)
+AC_SUBST(TARGET_CC)
+AC_SUBST(TARGET_NM)
+AC_SUBST(TARGET_RANLIB)
+AC_SUBST(TARGET_STRIP)
+AC_SUBST(TARGET_OBJCOPY)
+
+# Test the C compiler for the target environment.
+tmp_CC="$CC"
+tmp_CFLAGS="$CFLAGS"
+tmp_LDFLAGS="$LDFLAGS"
+tmp_CPPFLAGS="$CPPFLAGS"
+tmp_LIBS="$LIBS"
+CC="$TARGET_CC"
+CFLAGS="$TARGET_CFLAGS"
+CPPFLAGS="$TARGET_CPPFLAGS"
+LDFLAGS="$TARGET_LDFLAGS"
+LIBS=""
+
+# debug flags.
+TARGET_CFLAGS="$TARGET_CFLAGS $WARN_FLAGS -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations"
+TARGET_CCASFLAGS="$TARGET_CCASFLAGS -g"
+
+if test "x$target_cpu" != xi386 && test "x$target_cpu" != xx86_64; then
+TARGET_CFLAGS="$TARGET_CFLAGS -Wcast-align"
+fi
+
+TARGET_CC_VERSION="$(LC_ALL=C $TARGET_CC --version | head -n1)"
+
+AC_CACHE_CHECK([which extra warnings work], [grub_cv_target_cc_w_extra_flags], [
+ LDFLAGS="$TARGET_LDFLAGS -nostdlib -static"
+
+ grub_cv_target_cc_w_extra_flags=
+ for x in $EXTRA_WARN_FLAGS; do
+ CFLAGS="$TARGET_CFLAGS $x -Werror"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+asm (".globl start; start:");
+void __main (void);
+void __main (void) {}
+int main (void);
+]], [[]])], [flag=1], [flag=0])
+ if test x$flag = x1 ; then
+ grub_cv_target_cc_w_extra_flags="$grub_cv_target_cc_w_extra_flags $x"
+ fi
+ done
+])
+
+TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_w_extra_flags"
+
+AC_CACHE_CHECK([if compiling with clang], [grub_cv_cc_target_clang],
+[
+CFLAGS="$TARGET_CFLAGS"
+AC_COMPILE_IFELSE(
+[AC_LANG_PROGRAM([], [[
+#ifdef __clang__
+#error "is clang"
+#endif
+]])],
+[grub_cv_cc_target_clang=no], [grub_cv_cc_target_clang=yes])])
+
+if test x$target_cpu = xpowerpc -o x$target_cpu = xmips; then
+ AC_CACHE_CHECK([for options to get big-endian compilation], grub_cv_target_cc_big_endian, [
+ grub_cv_target_cc_big_endian=no
+ for cand in "-target $target_cpu -Wl,-EB" "-target $target_cpu" \
+ "-target $target_cpu-linux-gnu -Wl,-EB" "-target $target_cpu-linux-gnu" \
+ "-EB" "-mbig-endian"; do
+ if test x"$grub_cv_target_cc_big_endian" != xno ; then
+ break
+ fi
+ CFLAGS="$TARGET_CFLAGS $cand -Werror"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__ORDER_BIG_ENDIAN__ != __BYTE_ORDER__)
+#error still little endian
+#endif
+asm (".globl start; start:");
+asm (".globl _start; _start:");
+asm (".globl __start; __start:");
+void __main (void);
+void __main (void) {}
+int main (void);
+]], [[]])],
+ [grub_cv_target_cc_big_endian="$cand"], [])
+ done
+ ])
+
+ if test x"$grub_cv_target_cc_big_endian" = xno ; then
+ AC_MSG_ERROR([could not force big-endian])
+ fi
+
+ skip_linkflags="$(echo "$grub_cv_target_cc_big_endian"|sed 's@-Wl,-EB@@')"
+
+ TARGET_CFLAGS="$TARGET_CFLAGS $skip_linkflags"
+ TARGET_CPPFLAGS="$TARGET_CPPFLAGS $skip_linkflags"
+ TARGET_CCASFLAGS="$TARGET_CCASFLAGS $skip_linkflags"
+ TARGET_LDFLAGS="$TARGET_LDFLAGS $grub_cv_target_cc_big_endian"
+elif test x$target_cpu = xmipsel; then
+ AC_CACHE_CHECK([for options to get little-endian compilation], grub_cv_target_cc_little_endian, [
+ grub_cv_target_cc_little_endian=no
+ for cand in "-target $target_cpu -Wl,-EL" "-target $target_cpu" \
+ "-target $target_cpu-linux-gnu -Wl,-EL" "-target $target_cpu-linux-gnu" \
+ "-EL"; do
+ if test x"$grub_cv_target_cc_little_endian" != xno ; then
+ break
+ fi
+ CFLAGS="$TARGET_CFLAGS $cand -Werror"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__ORDER_BIG_ENDIAN__ == __BYTE_ORDER__)
+#error still big endian
+#endif
+asm (".globl start; start:");
+asm (".globl _start; _start:");
+asm (".globl __start; __start:");
+void __main (void);
+void __main (void) {}
+int main (void);
+]], [[]])],
+ [grub_cv_target_cc_little_endian="$cand"], [])
+ done
+ ])
+
+ if test x"$grub_cv_target_cc_little_endian" = xno ; then
+ AC_MSG_ERROR([could not force little-endian])
+ fi
+
+ skip_linkflags="$(echo "$grub_cv_target_cc_little_endian"|sed 's@-Wl,-EL@@')"
+
+ TARGET_CFLAGS="$TARGET_CFLAGS $skip_linkflags"
+ TARGET_CPPFLAGS="$TARGET_CPPFLAGS $skip_linkflags"
+ TARGET_CCASFLAGS="$TARGET_CCASFLAGS $skip_linkflags"
+ TARGET_LDFLAGS="$TARGET_LDFLAGS $grub_cv_target_cc_little_endian"
+fi
+
+# GRUB code is N32-compliant but it's experimental and we would prefer to
+# avoid having too much variety when it doesn't result in any real improvement.
+# Moreover N64 isn't supported.
+if test "x$target_cpu" = xmips || test "x$target_cpu" = xmipsel ; then
+ AC_CACHE_CHECK([for options to force MIPS o32 ABI], grub_cv_target_cc_mips_o32_abi, [
+ grub_cv_target_cc_mips_o32_abi=no
+ for arg in "" "-mabi=32" "-target $target_cpu -mabi=32" ; do
+ if test x"$grub_cv_target_cc_mips_o32_abi" != xno ; then
+ break
+ fi
+ CFLAGS="$TARGET_CFLAGS $arg -Werror"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#if !defined(_ABIO32) || !defined(_MIPS_SIM) || (_MIPS_SIM != _ABIO32)
+#error not o32 ABI
+#endif
+asm (".globl start; start:");
+asm (".globl _start; _start:");
+asm (".globl __start; __start:");
+void __main (void);
+void __main (void) {}
+int main (void);
+]], [[]])],
+ [grub_cv_target_cc_mips_o32_abi="$arg"], [])
+ done
+ ])
+
+ if test x"$grub_cv_target_cc_mips_o32_abi" = xno ; then
+ AC_MSG_ERROR([could not force MIPS o32 ABI])
+ fi
+
+ TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_mips_o32_abi"
+ TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_mips_o32_abi"
+fi
+
+AC_CACHE_CHECK([for options to compile assembly], [grub_cv_cc_target_asm_compile], [
+test_program=
+case "x$target_cpu-$platform" in
+ xmips-* | xmipsel-*)
+ test_program=mips
+ ;;
+ xi386-pc)
+ test_program=i386-pc
+ ;;
+ xi386-* | xx86_64-*)
+ test_program=i386
+ ;;
+ xpowerpc-* | xsparc64-* | xarm-*)
+ test_program=$target_cpu
+ ;;
+esac
+if test x"$test_program" = x ; then
+ grub_cv_cc_target_asm_compile=
+else
+ found=no
+ for arg in "" "-no-integrated-as"; do
+ cmdline="$TARGET_CC -c -o /dev/null $TARGET_CCASFLAGS $arg $TARGET_CPPFLAGS $srcdir/asm-tests/$test_program.S"
+ echo "Running $cmdline" >&AS_MESSAGE_LOG_FD
+ if $cmdline >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then
+ grub_cv_cc_target_asm_compile="$arg"
+ found=yes
+ break
+ fi
+ done
+ if test x"$found" = xno ; then
+ AC_MSG_ERROR([could not compile assembly])
+ fi
+fi
+])
+
+TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_cc_target_asm_compile"
+
+if test "x$target_cpu" = xi386 && test "x$platform" != xemu; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -march=i386"
+fi
+
+if test "x$target_m32" = x1; then
+ # Force 32-bit mode.
+ TARGET_CFLAGS="$TARGET_CFLAGS -m32"
+ TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m32"
+ TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m32"
+ TARGET_LDFLAGS="$TARGET_LDFLAGS -m32"
+ TARGET_MODULE_FORMAT="elf32"
+fi
+
+if test "x$target_m64" = x1; then
+ # Force 64-bit mode.
+ TARGET_CFLAGS="$TARGET_CFLAGS -m64"
+ TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m64"
+ TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m64"
+ TARGET_LDFLAGS="$TARGET_LDFLAGS -m64"
+ TARGET_MODULE_FORMAT="elf64"
+fi
+
+if test "x$grub_cv_cc_target_clang" = xno && test "x$target_cpu" = xi386 && test "x$platform" != xemu && test "x$platform" != xefi; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -mrtd -mregparm=3"
+fi
+
+# on mips redirect cache flushing function to non-existant one.
+if test "x$target_cpu" = xmips || test "x$target_cpu" = xmipsel ; then
+ AC_CACHE_CHECK([whether -mflush-func=grub_red_herring works], [grub_cv_cc_mflush_func], [
+ CFLAGS="$TARGET_CFLAGS -mflush-func=grub_red_herring -Werror"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_cc_mflush_func=yes],
+ [grub_cv_cc_mflush_func=no])
+ ])
+
+ if test "x$grub_cv_cc_mflush_func" = xyes; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -mflush-func=grub_red_herring"
+ fi
+fi
+
+
+# Force no alignment to save space on i386.
+if test "x$target_cpu" = xi386; then
+ AC_CACHE_CHECK([whether -falign-loops works], [grub_cv_cc_falign_loop], [
+ CFLAGS="$TARGET_CFLAGS -falign-loops=1 -Werror"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_cc_falign_loop=yes],
+ [grub_cv_cc_falign_loop=no])
+ ])
+
+ AC_CACHE_CHECK([whether -malign-loops works], [grub_cv_cc_malign_loop], [
+ CFLAGS="$TARGET_CFLAGS -malign-loops=1 -Werror"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_cc_malign_loop=yes],
+ [grub_cv_cc_malign_loop=no])
+ ])
+
+ if test "x$grub_cv_cc_falign_loop" = xyes; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -falign-jumps=1 -falign-loops=1 -falign-functions=1"
+ elif test "x$grub_cv_cc_malign_loop" = xyes; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1"
+ fi
+fi
+
+AC_CACHE_CHECK([whether -freg-struct-return works], [grub_cv_cc_freg_struct_return], [
+ CFLAGS="$TARGET_CFLAGS -freg-struct-return -Werror"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_cc_freg_struct_return=yes],
+ [grub_cv_cc_freg_struct_return=no])
+])
+
+if test "x$grub_cv_cc_freg_struct_return" = xyes; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -freg-struct-return"
+fi
+
+if ( test "x$target_cpu" = xi386 || test "x$target_cpu" = xx86_64 ) && test "x$platform" != xemu; then
+ # Some toolchains enable these features by default, but they need
+ # registers that aren't set up properly in GRUB.
+ TARGET_CFLAGS="$TARGET_CFLAGS -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow"
+fi
+
+# GRUB doesn't use float or doubles at all. Yet some toolchains may decide
+# that floats are a good fit to run instead of what's written in the code.
+# Given that floating point unit is disabled (if present to begin with)
+# when GRUB is running which may result in various hard crashes.
+#if test x"$platform" != xemu ; then
+if ( test x"$platform" != xemu && x"$platform" != mips64el-efi ) ; then
+ AC_CACHE_CHECK([for options to get soft-float], grub_cv_target_cc_soft_float, [
+ grub_cv_target_cc_soft_float=no
+ if test "x$target_cpu" = xarm64; then
+ CFLAGS="$TARGET_CFLAGS -mgeneral-regs-only -Werror"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_target_cc_soft_float="-mgeneral-regs-only"], [])
+ fi
+ if test "x$target_cpu" = xriscv32; then
+ CFLAGS="$TARGET_CFLAGS -march=rv32imac -mabi=ilp32 -Werror"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_target_cc_soft_float="-march=rv32imac -mabi=ilp32"], [])
+ fi
+ if test "x$target_cpu" = xriscv64; then
+ CFLAGS="$TARGET_CFLAGS -march=rv64imac -mabi=lp64 -Werror"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_target_cc_soft_float="-march=rv64imac -mabi=lp64"], [])
+ fi
+ if test "x$target_cpu" = xia64; then
+ CFLAGS="$TARGET_CFLAGS -mno-inline-float-divide -mno-inline-sqrt -Werror"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_target_cc_soft_float="-mno-inline-float-divide -mno-inline-sqrt"], [])
+ fi
+ for cand in "-msoft-float -Xclang -msoft-float -Xclang -no-implicit-float" \
+ "-Xclang -msoft-float -Xclang -no-implicit-float" \
+ "-Xclang -msoft-float" "-msoft-float"; do
+ if test x"$grub_cv_target_cc_soft_float" != xno ; then
+ break
+ fi
+ CFLAGS="$TARGET_CFLAGS $cand -Werror"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_target_cc_soft_float="$cand"], [])
+ done
+ ])
+
+ if test x"$grub_cv_target_cc_soft_float" = xno ; then
+ AC_MSG_ERROR([could not force soft-float])
+ fi
+
+ case x"$grub_cv_target_cc_soft_float" in
+ x*"-Xclang"*)
+ # A trick so that clang doesn't see it on link stаge
+ TARGET_CPPFLAGS="$TARGET_CPPFLAGS $grub_cv_target_cc_soft_float"
+ ;;
+ *)
+ TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_soft_float"
+ ;;
+ esac
+ TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_soft_float"
+
+fi
+
+if test x"$target_cpu" = xsparc64 ; then
+ AC_CACHE_CHECK([for options to reserve application registers], grub_cv_target_cc_mno_app_regs, [
+ grub_cv_target_cc_mno_app_regs=no
+ for cand in "-mllvm -sparc-reserve-app-registers" \
+ "-mno-app-regs"; do
+ if test x"$grub_cv_target_cc_mno_app_regs" != xno ; then
+ break
+ fi
+ CFLAGS="$TARGET_CFLAGS $cand -Werror"
+ CPPFLAGS="$TARGET_CPPFLAGS"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_target_cc_mno_app_regs="$cand"], [])
+ done
+ ])
+
+ if test x"$grub_cv_target_cc_mno_app_regs" = xno ; then
+ AC_MSG_ERROR([could not reserve application registers])
+ fi
+ if test x"$grub_cv_target_cc_mno_app_regs" = x"-mllvm -sparc-reserve-app-registers" ; then
+ # A trick so that clang doesn't see it on link stаge
+ TARGET_CPPFLAGS="$TARGET_CPPFLAGS $grub_cv_target_cc_mno_app_regs"
+ else
+ TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_mno_app_regs"
+ fi
+
+ AC_CACHE_CHECK([for no-relax options], grub_cv_target_cc_mno_relax, [
+ grub_cv_target_cc_mno_relax=no
+ for cand in "-mno-relax" "-Wl,--no-relax"; do
+ if test x"$grub_cv_target_cc_mno_relax" != xno ; then
+ break
+ fi
+ LDFLAGS="$TARGET_LDFLAGS $cand -nostdlib -static"
+ CFLAGS="$TARGET_CFLAGS -Werror"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+ asm (".globl start; start:");
+ void __main (void);
+ void __main (void) {}
+ int main (void);
+ ]], [[]])], [grub_cv_target_cc_mno_relax="$cand"], [])
+ done
+ ])
+ LDFLAGS="$TARGET_LDFLAGS"
+ CFLAGS="$TARGET_CFLAGS"
+
+ if test x"$grub_cv_target_cc_mno_relax" = xno ; then
+ AC_MSG_ERROR([could not find no-relax options])
+ fi
+ TARGET_LDFLAGS="$TARGET_LDFLAGS $grub_cv_target_cc_mno_relax"
+fi
+
+# By default, GCC 4.4 generates .eh_frame sections containing unwind
+# information in some cases where it previously did not. GRUB doesn't need
+# these and they just use up vital space. Restore the old compiler
+# behaviour.
+AC_CACHE_CHECK([whether -fno-dwarf2-cfi-asm works], [grub_cv_cc_fno_dwarf2_cfi_asm], [
+ CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_cc_fno_dwarf2_cfi_asm=yes],
+ [grub_cv_cc_fno_dwarf2_cfi_asm=no])
+])
+
+if test "x$grub_cv_cc_fno_dwarf2_cfi_asm" = xyes; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm"
+fi
+
+if test x"$target_os" = xcygwin; then
+ AC_CACHE_CHECK([whether option -fno-reorder-functions works], grub_cv_cc_no_reorder_functions, [
+ CFLAGS="$TARGET_CFLAGS -fno-reorder-functions"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_cc_no_reorder_functions=yes],
+ [grub_cv_cc_no_reorder_functions=no])
+ ])
+fi
+
+if test x"$target_os" = xcygwin && test "x$grub_cv_cc_no_reorder_functions" = xyes; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -fno-reorder-functions"
+fi
+
+AC_CACHE_CHECK([whether -mno-stack-arg-probe works], [grub_cv_cc_mno_stack_arg_probe], [
+ CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_cc_mno_stack_arg_probe=yes],
+ [grub_cv_cc_mno_stack_arg_probe=no])
+])
+
+if test "x$grub_cv_cc_mno_stack_arg_probe" = xyes; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe"
+fi
+
+
+# By default, GCC 4.6 generates .eh_frame sections containing unwind
+# information in some cases where it previously did not. GRUB doesn't need
+# these and they just use up vital space. Restore the old compiler
+# behaviour.
+AC_CACHE_CHECK([whether -fno-asynchronous-unwind-tables works], [grub_cv_cc_fno_asynchronous_unwind_tables], [
+ CFLAGS="$TARGET_CFLAGS -fno-asynchronous-unwind-tables"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_cc_fno_asynchronous_unwind_tables=yes],
+ [grub_cv_cc_fno_asynchronous_unwind_tables=no])
+])
+
+if test "x$grub_cv_cc_fno_asynchronous_unwind_tables" = xyes; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -fno-asynchronous-unwind-tables"
+fi
+
+AC_CACHE_CHECK([whether -fno-unwind-tables works], [grub_cv_cc_fno_unwind_tables], [
+ CFLAGS="$TARGET_CFLAGS -fno-unwind-tables"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_cc_fno_unwind_tables=yes],
+ [grub_cv_cc_fno_unwind_tables=no])
+])
+
+if test "x$grub_cv_cc_fno_unwind_tables" = xyes; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -fno-unwind-tables"
+fi
+
+
+CFLAGS="$TARGET_CFLAGS"
+
+
+if test x"$platform" = xemu ; then
+ TARGET_OBJ2ELF=
+ grub_cv_target_cc_link_format=
+ case "$host_os" in
+ *darwin* | *mac*)
+ grub_cv_target_cc_link_format="-arch,${target_cpu}"
+ TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,$grub_cv_target_cc_link_format"
+ ;;
+ *windows* | *cygwin* | *mingw*)
+ if test x${target_cpu} = xi386 ; then
+ grub_cv_target_cc_link_format=-mi386pe
+ TARGET_OBJ2ELF='./build-grub-pe2elf$(BUILD_EXEEXT)'
+ fi
+ if test x${target_cpu} = xx86_64 ; then
+ grub_cv_target_cc_link_format=-mi386pep
+ TARGET_OBJ2ELF='./build-grub-pep2elf$(BUILD_EXEEXT)'
+ fi
+ TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,$grub_cv_target_cc_link_format"
+ ;;
+ esac
+elif test x"$target_cpu" = xi386 || test x"$target_cpu" = xx86_64; then
+ AC_CACHE_CHECK([for target linking format], [grub_cv_target_cc_link_format], [
+ grub_cv_target_cc_link_format=unknown
+ for format in -melf_${target_cpu} -melf_${target_cpu}_fbsd -melf_${target_cpu}_obsd -melf_${target_cpu}_haiku -mi386pe -mi386pep -arch,${target_cpu}; do
+ if test x${target_cpu} != xi386 && test x$format = x-mi386pe; then
+ continue
+ fi
+ if test x${target_cpu} != xx86_64 && test x$format = x-mi386pep; then
+ continue
+ fi
+ CFLAGS="$TARGET_CFLAGS"
+ LDFLAGS="$TARGET_LDFLAGS -Wl,$format -nostdlib -static"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+ asm (".globl start; start:");
+ asm (".globl _start; _start:");
+ asm (".globl __start; __start:");
+ void __main (void);
+ void __main (void) {}
+ ]], [[]])], [flag=1], [flag=0])
+ if test x"$flag" = x1; then
+ grub_cv_target_cc_link_format="$format"
+ break
+ fi
+ done])
+ if test x"$grub_cv_target_cc_link_format" = xunknown; then
+ AC_MSG_ERROR([no suitable link format found])
+ fi
+ TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,$grub_cv_target_cc_link_format"
+ if test x"$grub_cv_target_cc_link_format" = x-mi386pe ; then
+ TARGET_OBJ2ELF='./build-grub-pe2elf$(BUILD_EXEEXT)'
+ fi
+ if test x"$grub_cv_target_cc_link_format" = x-mi386pep ; then
+ TARGET_OBJ2ELF='./build-grub-pep2elf$(BUILD_EXEEXT)'
+ fi
+fi
+
+if test x$grub_cv_target_cc_link_format = x-arch,i386 || test x$grub_cv_target_cc_link_format = x-arch,x86_64; then
+ TARGET_APPLE_LINKER=1
+ AC_CHECK_PROG([TARGET_OBJCONV], [objconv], [objconv], [])
+ if test "x$TARGET_OBJCONV" = x ; then
+ AC_CHECK_PROG([TARGET_OBJCONV], [objconv], [./objconv], [], [.])
+ fi
+ if test "x$TARGET_OBJCONV" = x ; then
+ AC_MSG_ERROR([objconv not found which is required when building with apple compiler])
+ fi
+ TARGET_IMG_LDSCRIPT=
+ TARGET_IMG_CFLAGS="-static"
+ TARGET_IMG_LDFLAGS='-nostdlib -static -Wl,-preload -Wl,-segalign,20'
+ TARGET_IMG_LDFLAGS_AC='-nostdlib -static -Wl,-preload -Wl,-segalign,20'
+ TARGET_IMG_BASE_LDOPT="-Wl,-image_base"
+ TARGET_LDFLAGS_OLDMAGIC=""
+elif test x$grub_cv_target_cc_link_format = x-mi386pe || test x$grub_cv_target_cc_link_format = x-mi386pep ; then
+ TARGET_APPLE_LINKER=0
+ TARGET_LDFLAGS_OLDMAGIC="-Wl,-N"
+ TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/${grub_coredir}/conf/i386-cygwin-img-ld.sc"
+ TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}"
+ TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/${grub_coredir}/conf/i386-cygwin-img-ld.sc"
+ TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
+ TARGET_IMG_CFLAGS=
+else
+ TARGET_APPLE_LINKER=0
+ TARGET_LDFLAGS_OLDMAGIC="-Wl,-N"
+ TARGET_IMG_LDSCRIPT=
+ TARGET_IMG_LDFLAGS='-Wl,-N'
+ TARGET_IMG_LDFLAGS_AC='-Wl,-N'
+ TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
+ TARGET_IMG_CFLAGS=
+fi
+
+CFLAGS="$TARGET_CFLAGS"
+
+AC_ARG_ENABLE([efiemu],
+ [AS_HELP_STRING([--enable-efiemu],
+ [build and install the efiemu runtimes (default=guessed)])])
+if test x"$enable_efiemu" = xno ; then
+ efiemu_excuse="explicitly disabled"
+fi
+
+if test x"$grub_cv_target_cc_link_format" = x-mi386pe || test x"$grub_cv_target_cc_link_format" = x-mi386pep ; then
+ efiemu_excuse="not available on cygwin"
+fi
+if test x"$target_cpu" != xi386 ; then
+ efiemu_excuse="only available on i386"
+fi
+if test x"$platform" = xefi ; then
+ efiemu_excuse="not available on efi"
+fi
+
+if test x"$efiemu_excuse" = x ; then
+ AC_CACHE_CHECK([whether options required for efiemu work], grub_cv_cc_efiemu, [
+ CFLAGS="-m64 -nostdlib -O2 -mcmodel=large -mno-red-zone"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_cc_efiemu=yes],
+ [grub_cv_cc_efiemu=no])
+ ])
+ if test x$grub_cv_cc_efiemu = xno; then
+ efiemu_excuse="cannot compile with -m64 -mcmodel=large -mno-red-zone -nostdlib"
+ fi
+fi
+if test x"$efiemu_excuse" = x ; then
+ AC_CACHE_CHECK([for efiemu64 linking format], [grub_cv_target_cc_efiemu64_link_format], [
+ grub_cv_target_cc_efiemu64_link_format=unknown
+ for format in -melf_x86_64 -melf_x86_64_fbsd -melf_x86_64_obsd -melf_x86_64_haiku -arch,x86_64; do
+ CFLAGS="-m64 -nostdlib -O2 -mcmodel=large -mno-red-zone"
+ LDFLAGS="-m64 -Wl,$format -nostdlib -static"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+ asm (".globl start; start:");
+ asm (".globl _start; _start:");
+ asm (".globl __start; __start:");
+ void __main (void);
+ void __main (void) {}
+ ]], [[]])], [flag=1], [flag=0])
+ if test x"$flag" = x1; then
+ grub_cv_target_cc_efiemu64_link_format="$format"
+ break
+ fi
+ done])
+ if test x"$grub_cv_target_cc_efiemu64_link_format" = xunknown; then
+ efiemu_excuse="no suitable link format for efiemu64 found"
+ else
+ EFIEMU64_LINK_FORMAT="-Wl,$grub_cv_target_cc_efiemu64_link_format"
+ fi
+fi
+if test x"$enable_efiemu" = xyes && test x"$efiemu_excuse" != x ; then
+ AC_MSG_ERROR([efiemu runtime was explicitly requested but can't be compiled ($efiemu_excuse)])
+fi
+if test x"$efiemu_excuse" = x ; then
+enable_efiemu=yes
+else
+enable_efiemu=no
+fi
+AC_SUBST([enable_efiemu])
+AC_SUBST([EFIEMU64_LINK_FORMAT])
+
+CFLAGS="$TARGET_CFLAGS"
+
+AC_SUBST(TARGET_LDFLAGS_OLDMAGIC)
+
+
+LDFLAGS="$TARGET_LDFLAGS"
+
+if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64 ; then
+ # Use large model to support 4G memory
+ AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [
+ CFLAGS="$TARGET_CFLAGS -mcmodel=large"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_cc_mcmodel=yes],
+ [grub_cv_cc_mcmodel=no])
+ ])
+ if test "x$grub_cv_cc_mcmodel" = xyes; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large"
+ elif test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=medany"
+ fi
+fi
+
+if test "$target_cpu"-"$platform" = x86_64-efi; then
+ # EFI writes to stack below %rsp, we must not use the red zone
+ AC_CACHE_CHECK([whether option -mno-red-zone works], grub_cv_cc_no_red_zone, [
+ CFLAGS="$TARGET_CFLAGS -mno-red-zone"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_cc_no_red_zone=yes],
+ [grub_cv_cc_no_red_zone=no])
+ ])
+ if test "x$grub_cv_cc_no_red_zone" = xno; then
+ AC_MSG_ERROR([-mno-red-zone not supported, upgrade your gcc])
+ fi
+
+ TARGET_CFLAGS="$TARGET_CFLAGS -mno-red-zone"
+fi
+
+if test "x$target_cpu" = xarm; then
+ AC_CACHE_CHECK([for options to disable movt and movw], grub_cv_target_cc_mno_movt, [
+ grub_cv_target_cc_mno_movt=no
+ for cand in "-mno-movt" \
+ "-mllvm -arm-use-movt=0"; do
+ if test x"$grub_cv_target_cc_mno_movt" != xno ; then
+ break
+ fi
+ CFLAGS="$TARGET_CFLAGS $cand -Werror"
+ CPPFLAGS="$TARGET_CPPFLAGS"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_target_cc_mno_movt="$cand"], [])
+ done
+ ])
+
+ if test x"$grub_cv_target_cc_mno_movt" != xno ; then
+ # A trick so that clang doesn't see it on link stage
+ TARGET_CPPFLAGS="$TARGET_CPPFLAGS $grub_cv_target_cc_mno_movt"
+ fi
+ AC_CACHE_CHECK([whether option -mthumb-interwork works], grub_cv_cc_mthumb_interwork, [
+ CFLAGS="$TARGET_CFLAGS -mthumb-interwork -Werror"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_cc_mthumb_interwork=yes],
+ [grub_cv_cc_mthumb_interwork=no])
+ ])
+ if test "x$grub_cv_cc_mthumb_interwork" = xyes; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -mthumb-interwork"
+ # Clang defaults to thumb interworking
+ elif test "x$grub_cv_cc_target_clang" = xno ; then
+ AC_MSG_ERROR([your compiler doesn't support -mthumb-interwork])
+ fi
+fi
+
+AC_CACHE_CHECK([whether option -Qn works], grub_cv_target_cc_qn, [
+ CFLAGS="$TARGET_CFLAGS -Qn -Qunused-arguments -Werror"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [grub_cv_target_cc_qn=yes],
+ [grub_cv_target_cc_qn=no])])
+if test "x$grub_cv_target_cc_qn" = xyes; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -Qn -Qunused-arguments"
+fi
+
+#
+# Compiler features.
+#
+
+CFLAGS="$TARGET_CFLAGS"
+
+# Position independent executable.
+grub_CHECK_PIE
+grub_CHECK_NO_PIE
+grub_CHECK_NO_PIE_ONEWORD
+grub_CHECK_LINK_PIE
+[# Need that, because some distributions ship compilers that include
+# `-fPIE' or '-fpie' and '-pie' in the default specs.
+if [ x"$pie_possible" = xyes ]; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE -fno-pie"
+fi
+
+if [ x"$link_nopie_needed" = xyes ] || [ x"$pie_possible" = xyes ]; then
+ if [ x"$nopie_possible" = xyes ]; then
+ TARGET_LDFLAGS="$TARGET_LDFLAGS -no-pie"
+ fi
+ if [ x"$nopie_oneword_possible" = xyes ]; then
+ TARGET_LDFLAGS="$TARGET_LDFLAGS -nopie"
+ fi
+fi]
+
+CFLAGS="$TARGET_CFLAGS"
+LDFLAGS="$TARGET_LDFLAGS"
+
+# Position independent executable.
+grub_CHECK_PIC
+[# On most platforms we don't want PIC as it only makes relocations harder
+# and code less efficient. On mips we want to have one got table per module
+# and reload $gp in every function.
+# GCC implements it using symbol __gnu_local_gp in non-PIC as well.
+# However with clang we need PIC for this reloading to happen.
+# With arm64 we need relocations that are in some way representable in
+# PE as we need to support arm64-efi. Without -fPIC clang generates
+# movk's which aren't representable.
+# Since default varies across dictributions use either -fPIC or -fno-PIC
+# explicitly.
+if ( test x$target_cpu = xmips || test x$target_cpu = xmipsel || test x$target_cpu = xarm64 || test x$target_cpu = xmips64el ) && test "x$grub_cv_cc_target_clang" = xyes ; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -fPIC"
+elif [ x"$pic_possible" = xyes ]; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIC"
+fi
+# Don't generate SVR4-style position-independent code for MIPS64.
+if test x$target_cpu = xmips64el ; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -mno-abicalls"
+ TARGET_CCASFLAGS="$TARGET_CCASFLAGS -mno-abicalls"
+fi]
+
+CFLAGS="$TARGET_CFLAGS"
+
+# Smashing stack protector.
+grub_CHECK_STACK_PROTECTOR
+# Need that, because some distributions ship compilers that include
+# `-fstack-protector' in the default specs.
+if test "x$ssp_possible" = xyes; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -fno-stack-protector"
+fi
+
+CFLAGS="$TARGET_CFLAGS"
+
+grub_CHECK_STACK_ARG_PROBE
+# Cygwin's GCC uses alloca() to probe the stackframe on static
+# stack allocations above some threshold.
+if test x"$sap_possible" = xyes; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe"
+fi
+
+CFLAGS="$TARGET_CFLAGS"
+
+# -mno-unaligned-access -mstrict-align
+if test "$target_cpu" = arm; then
+ AC_CACHE_CHECK([for compile options to get strict alignment], [grub_cv_target_cc_strict_align], [
+ grub_cv_target_cc_strict_align=
+ for arg in -mno-unaligned-access "-Xclang -mstrict-align" -mstrict-align; do
+ CFLAGS="$TARGET_CFLAGS $arg -Werror"
+ LDFLAGS="$TARGET_LDFLAGS"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [flag=1], [flag=0])
+ if test x"$flag" = x1; then
+ grub_cv_target_cc_strict_align="$arg"
+ break
+ fi
+ done])
+
+ TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_strict_align"
+ if test x"$grub_cv_target_cc_strict_align" = x"-Xclang -mstrict-align"; then
+ TARGET_LDFLAGS="$TARGET_LDFLAGS -Qunused-arguments"
+ fi
+ AC_CACHE_CHECK([if compiler generates unaligned accesses], [grub_cv_cc_target_emits_unaligned],
+ [CFLAGS="$TARGET_CFLAGS"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[
+#ifdef __ARM_FEATURE_UNALIGNED
+#error "unaligned"
+#endif
+ ]])],
+ [grub_cv_cc_target_emits_unaligned=no], [grub_cv_cc_target_emits_unaligned=yes])])
+ if test x$grub_cv_cc_target_emits_unaligned = xyes; then
+ AC_MSG_ERROR([compiler generates unaligned accesses])
+ fi
+fi
+
+# Set them to their new values for the tests below.
+CC="$TARGET_CC"
+if test x"$platform" = xemu ; then
+CFLAGS="$TARGET_CFLAGS -Wno-error"
+elif test "x$TARGET_APPLE_LINKER" = x1 ; then
+CFLAGS="$TARGET_CFLAGS -nostdlib -static -Wno-error"
+else
+CFLAGS="$TARGET_CFLAGS -nostdlib -Wno-error"
+fi
+CPPFLAGS="$TARGET_CPPFLAGS"
+
+grub_ASM_USCORE
+if test "x$TARGET_APPLE_LINKER" = x0 && test x"$platform" != xemu; then
+if test x$grub_cv_asm_uscore = xyes; then
+DEFSYM="-Wl,--defsym,_abort=_main -Wl,--defsym,__main=_main"
+else
+DEFSYM="-Wl,--defsym,abort=main -Wl,--defsym,_main=main -Wl,--defsym,__main=main"
+fi
+CFLAGS="$TARGET_CFLAGS -nostdlib $DEFSYM"
+fi
+
+# Check for libgcc symbols
+if test x"$platform" = xemu; then
+AC_CHECK_FUNCS(__udivsi3 __umodsi3 __divsi3 __modsi3 __divdi3 __moddi3 __udivdi3 __umoddi3 __ctzdi2 __ctzsi2 __aeabi_uidiv __aeabi_uidivmod __aeabi_idiv __aeabi_idivmod __aeabi_ulcmp __muldi3 __aeabi_lmul __aeabi_memcpy __aeabi_memcpy4 __aeabi_memcpy8 __aeabi_memclr __aeabi_memclr4 __aeabi_memclr8 __aeabi_memset __aeabi_lasr __aeabi_llsl __aeabi_llsr _restgpr_14_x __ucmpdi2 __ashldi3 __ashrdi3 __lshrdi3 __bswapsi2 __bswapdi2 __bzero __register_frame_info __deregister_frame_info ___chkstk_ms __chkstk_ms)
+fi
+
+if test "x$TARGET_APPLE_LINKER" = x1 ; then
+CFLAGS="$TARGET_CFLAGS -nostdlib -static"
+else
+CFLAGS="$TARGET_CFLAGS -nostdlib"
+fi
+LIBS=""
+
+# Defined in aclocal.m4.
+grub_PROG_TARGET_CC
+if test "x$TARGET_APPLE_LINKER" != x1 ; then
+grub_PROG_OBJCOPY_ABSOLUTE
+fi
+grub_PROG_LD_BUILD_ID_NONE
+if test "x$target_cpu" = xi386; then
+ if test "$platform" != emu && test "x$TARGET_APPLE_LINKER" != x1 ; then
+ if test ! -z "$TARGET_IMG_LDSCRIPT"; then
+ # Check symbols provided by linker script.
+ CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC} ${TARGET_IMG_BASE_LDOPT},0x8000"
+ fi
+ grub_CHECK_BSS_START_SYMBOL
+ grub_CHECK_END_SYMBOL
+ fi
+ CFLAGS="$TARGET_CFLAGS"
+fi
+
+grub_PROG_NM_WORKS
+grub_PROG_NM_MINUS_P
+grub_PROG_NM_DEFINED_ONLY
+AC_SUBST(TARGET_NMFLAGS_MINUS_P)
+AC_SUBST(TARGET_NMFLAGS_DEFINED_ONLY)
+
+if test "$platform" != emu; then
+AC_CACHE_CHECK([whether -nostdinc -isystem works], [grub_cv_cc_isystem], [
+ SAVED_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$TARGET_CPPFLAGS -nostdlib -nostdinc -isystem `$TARGET_CC -print-file-name=include`"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdarg.h>
+#include <stddef.h>
+int va_arg_func (int fixed, va_list args);]], [[]])],
+ [grub_cv_cc_isystem=yes],
+ [grub_cv_cc_isystem=no])
+ CPPFLAGS="$SAVED_CPPFLAGS"
+])
+
+if test x"$grub_cv_cc_isystem" = xyes ; then
+ TARGET_CPPFLAGS="$TARGET_CPPFLAGS -nostdinc -isystem `$TARGET_CC -print-file-name=include`"
+fi
+fi
+
+AC_CACHE_CHECK([whether -Wtrampolines work], [grub_cv_cc_wtrampolines], [
+ CFLAGS="$TARGET_CFLAGS -Wtrampolines -Werror"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdarg.h>
+int va_arg_func (int fixed, va_list args);]], [[]])],
+ [grub_cv_cc_wtrampolines=yes],
+ [grub_cv_cc_wtrampolines=no])
+])
+
+if test x"$grub_cv_cc_wtrampolines" = xyes ; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -Wtrampolines"
+fi
+
+# Restore the flags.
+CC="$tmp_CC"
+CFLAGS="$tmp_CFLAGS"
+CPPFLAGS="$tmp_CPPFLAGS"
+LDFLAGS="$tmp_LDFLAGS"
+LIBS="$tmp_LIBS"
+
+#
+# Check for options.
+#
+
+# Memory manager debugging.
+AC_ARG_ENABLE([mm-debug],
+ AS_HELP_STRING([--enable-mm-debug],
+ [include memory manager debugging]),
+ [AC_DEFINE([MM_DEBUG], [1],
+ [Define to 1 if you enable memory manager debugging.])])
+
+AC_ARG_ENABLE([cache-stats],
+ AS_HELP_STRING([--enable-cache-stats],
+ [enable disk cache statistics collection]))
+
+if test x$enable_cache_stats = xyes; then
+ DISK_CACHE_STATS=1
+else
+ DISK_CACHE_STATS=0
+fi
+AC_SUBST([DISK_CACHE_STATS])
+
+AC_ARG_ENABLE([boot-time],
+ AS_HELP_STRING([--enable-boot-time],
+ [enable boot time statistics collection]))
+
+if test x$enable_boot_time = xyes; then
+ BOOT_TIME_STATS=1
+else
+ BOOT_TIME_STATS=0
+fi
+AC_SUBST([BOOT_TIME_STATS])
+
+AC_ARG_ENABLE([grub-emu-sdl],
+ [AS_HELP_STRING([--enable-grub-emu-sdl],
+ [build and install the `grub-emu' debugging utility with SDL support (default=guessed)])])
+
+AC_ARG_ENABLE([grub-emu-pci],
+ [AS_HELP_STRING([--enable-grub-emu-pci],
+ [build and install the `grub-emu' debugging utility with PCI support (potentially dangerous) (default=no)])])
+
+if test "$platform" = emu; then
+
+if test x"$enable_grub_emu_sdl" = xno ; then
+ grub_emu_sdl_excuse="explicitly disabled"
+fi
+[if [ x"$grub_emu_sdl_excuse" = x ]; then
+ # Check for libSDL libraries.]
+AC_CHECK_LIB([SDL], [SDL_Init], [LIBSDL="-lSDL"],
+ [grub_emu_sdl_excuse=["libSDL libraries are required to build \`grub-emu' with SDL support"]])
+ AC_SUBST([LIBSDL])
+[fi]
+
+[if [ x"$grub_emu_sdl_excuse" = x ]; then
+ # Check for headers.]
+ AC_CHECK_HEADERS([SDL/SDL.h], [],
+ [grub_emu_sdl_excuse=["libSDL header file is required to build \`grub-emu' with SDL support"]])
+[fi]
+
+if test x"enable_grub_emu_sdl" = xyes && test x"$grub_emu_sdl_excuse" != x ; then
+ AC_MSG_ERROR([SDL support for grub-emu was explicitly requested but can't be compiled ($grub_emu_sdl_excuse)])
+fi
+if test x"$grub_emu_sdl_excuse" = x ; then
+enable_grub_emu_sdl=yes
+else
+enable_grub_emu_sdl=no
+fi
+
+if test x"$enable_grub_emu_pci" != xyes ; then
+ grub_emu_pci_excuse="not enabled"
+fi
+
+[if [ x"$grub_emu_pci_excuse" = x ]; then
+ # Check for libpci libraries.]
+ AC_CHECK_LIB([pciaccess], [pci_system_init], [LIBPCIACCESS="-lpciaccess"],
+ [grub_emu_pci_excuse=["need libpciaccess library"]])
+ AC_SUBST([LIBPCIACCESS])
+[fi]
+[if [ x"$grub_emu_pci_excuse" = x ]; then
+ # Check for headers.]
+ AC_CHECK_HEADERS([pciaccess.h], [],
+ [grub_emu_pci_excuse=["need libpciaccess headers"]])
+[fi]
+
+if test x"$grub_emu_pci_excuse" = x ; then
+enable_grub_emu_pci=yes
+else
+
+enable_grub_emu_pci=no
+fi
+
+AC_SUBST([enable_grub_emu_sdl])
+AC_SUBST([enable_grub_emu_pci])
+
+else
+
+# Ignore --enable-emu-* if platform is not emu
+enable_grub_emu_sdl=no
+enable_grub_emu_pci=no
+fi
+
+AC_ARG_ENABLE([grub-mkfont],
+ [AS_HELP_STRING([--enable-grub-mkfont],
+ [build and install the `grub-mkfont' utility (default=guessed)])])
+if test x"$enable_grub_mkfont" = xno ; then
+ grub_mkfont_excuse="explicitly disabled"
+fi
+
+unset ac_cv_header_ft2build_h
+
+if test x"$grub_mkfont_excuse" = x ; then
+ # Check for freetype libraries.
+ PKG_CHECK_MODULES([FREETYPE], [freetype2], [
+ SAVED_CPPFLAGS="$CPPFLAGS"
+ SAVED_LIBS="$LIBS"
+ CPPFLAGS="$CPPFLAGS $FREETYPE_CFLAGS"
+ LIBS="$LIBS $FREETYPE_LIBS"
+ AC_CHECK_HEADERS([ft2build.h], [],
+ [grub_mkfont_excuse=["need freetype2 headers"]])
+ AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [],
+ [grub_mkfont_excuse=["freetype2 library unusable"]])
+ CPPFLAGS="$SAVED_CPPFLAGS"
+ LIBS="$SAVED_LIBS"
+ ], [grub_mkfont_excuse=["need freetype2 library"]])
+fi
+
+if test x"$enable_grub_mkfont" = xyes && test x"$grub_mkfont_excuse" != x ; then
+ AC_MSG_ERROR([grub-mkfont was explicitly requested but can't be compiled ($grub_mkfont_excuse)])
+fi
+if test x"$grub_mkfont_excuse" = x ; then
+enable_grub_mkfont=yes
+else
+enable_grub_mkfont=no
+fi
+AC_SUBST([enable_grub_mkfont])
+
+SAVED_CC="$CC"
+SAVED_CPP="$CPP"
+SAVED_CFLAGS="$CFLAGS"
+SAVED_CPPFLAGS="$CPPFLAGS"
+SAVED_LDFLAGS="$LDFLAGS"
+CC="$BUILD_CC"
+CPP="$BUILD_CPP"
+CFLAGS="$BUILD_CFLAGS"
+CPPFLAGS="$BUILD_CPPFLAGS"
+LDFLAGS="$BUILD_LDFAGS"
+
+unset ac_cv_c_bigendian
+unset ac_cv_header_ft2build_h
+
+AC_COMPUTE_INT([BUILD_SIZEOF_VOID_P], [sizeof (void *)])
+AC_COMPUTE_INT([BUILD_SIZEOF_LONG], [sizeof (long)])
+AC_C_BIGENDIAN([BUILD_WORDS_BIGENDIAN=1], [BUILD_WORDS_BIGENDIAN=0], [BUILD_WORDS_BIGENDIAN=err], [BUILD_WORDS_BIGENDIAN=err])
+
+if test x$BUILD_WORDS_BIGENDIAN = xerr ; then
+ AC_MSG_ERROR([couldnt determine build endianness])
+fi
+
+AC_SUBST([BUILD_SIZEOF_LONG])
+AC_SUBST([BUILD_SIZEOF_VOID_P])
+AC_SUBST([BUILD_WORDS_BIGENDIAN])
+
+if test x"$grub_build_mkfont_excuse" = x ; then
+ # Check for freetype libraries.
+ SAVED_PKG_CONFIG="$PKG_CONFIG"
+ test -z "$BUILD_PKG_CONFIG" || PKG_CONFIG="$BUILD_PKG_CONFIG"
+ PKG_CHECK_MODULES([BUILD_FREETYPE], [freetype2], [
+ SAVED_CPPFLAGS_2="$CPPFLAGS"
+ SAVED_LIBS="$LIBS"
+ CPPFLAGS="$CPPFLAGS $BUILD_FREETYPE_CFLAGS"
+ LIBS="$LIBS $BUILD_FREETYPE_LIBS"
+ AC_CHECK_HEADERS([ft2build.h], [],
+ [grub_build_mkfont_excuse=["need freetype2 headers"]])
+ AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [],
+ [grub_build_mkfont_excuse=["freetype2 library unusable"]])
+ LIBS="$SAVED_LIBS"
+ CPPFLAGS="$SAVED_CPPFLAGS_2"
+ ], [grub_build_mkfont_excuse=["need freetype2 library"]])
+ PKG_CONFIG="$SAVED_PKG_CONFIG"
+fi
+
+if test x"$enable_build_grub_mkfont" = xyes && test x"$grub_build_mkfont_excuse" != x ; then
+ AC_MSG_ERROR([build-grub-mkfont was explicitly requested but can't be compiled ($grub_build_mkfont_excuse)])
+fi
+if test x"$grub_build_mkfont_excuse" = x ; then
+ enable_build_grub_mkfont=yes
+else
+ enable_build_grub_mkfont=no
+fi
+if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$platform" = xcoreboot ); then
+ if test x"$grub_build_mkfont_excuse" = x ; then
+ AC_MSG_ERROR([qemu, coreboot and loongson ports need build-time grub-mkfont])
+ else
+ AC_MSG_ERROR([qemu, coreboot and loongson ports need build-time grub-mkfont ($grub_build_mkfont_excuse)])
+ fi
+fi
+
+CC="$SAVED_CC"
+CPP="$SAVED_CPP"
+CFLAGS="$SAVED_CFLAGS"
+CPPFLAGS="$SAVED_CPPFLAGS"
+LDFLAGS="$SAVED_LDFLAGS"
+
+
+DJVU_FONT_SOURCE=
+
+starfield_excuse=
+
+AC_ARG_ENABLE([grub-themes],
+ [AS_HELP_STRING([--enable-grub-themes],
+ [build and install GRUB themes (default=guessed)])])
+if test x"$enable_grub_themes" = xno ; then
+ starfield_excuse="explicitly disabled"
+fi
+
+if test x"$starfield_excuse" = x && test x"$enable_build_grub_mkfont" = xno ; then
+ starfield_excuse="No build-time grub-mkfont"
+fi
+
+if test x"$starfield_excuse" = x; then
+ for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do
+ for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/truetype/ttf-dejavu /usr/share/fonts/dejavu /usr/share/fonts/truetype; do
+ if test -f "$dir/DejaVuSans.$ext"; then
+ DJVU_FONT_SOURCE="$dir/DejaVuSans.$ext"
+ break 2
+ fi
+ done
+ done
+
+ if test "x$DJVU_FONT_SOURCE" = x; then
+ starfield_excuse="No DejaVu found"
+ fi
+fi
+
+if test x"$enable_grub_themes" = xyes && test x"$starfield_excuse" != x; then
+ AC_MSG_ERROR([themes were explicitly requested but requirements are not satisfied ($starfield_excuse)])
+fi
+
+AC_SUBST([DJVU_FONT_SOURCE])
+
+FONT_SOURCE=
+
+for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do
+ for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/unifont /usr/share/fonts/uni /usr/share/fonts/truetype/unifont /usr/share/fonts/misc; do
+ if test -f "$dir/unifont.$ext"; then
+ md5="$(md5sum "$dir/unifont.$ext"|awk '{ print $1; }')"
+ # PCF and BDF from version 6.3 isn't hanled properly by libfreetype.
+ if test "$md5" = 0a54834d2788c83886a3e1785a6a1e61 || test "$md5" = 28f2565c7a41d8d407e2551159385edb || test "$md5" = dae5e588461b3b92b87b6ffee734f936 || test "$md5" = 4a3d687aa5bb329ed05f4263a1016791 ; then
+ continue
+ fi
+ FONT_SOURCE="$dir/unifont.$ext"
+ break 2
+ fi
+ done
+done
+
+if test x"$enable_build_grub_mkfont" = xno ; then
+ FONT_SOURCE=
+fi
+
+if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$platform" = xcoreboot ); then
+ if test x"$grub_build_mkfont_excuse" = x ; then
+ AC_MSG_ERROR([qemu, coreboot and loongson ports need unifont])
+ else
+ AC_MSG_ERROR([qemu, coreboot and loongson ports need unifont ($grub_build_mkfont_excuse)])
+ fi
+fi
+
+AC_SUBST([FONT_SOURCE])
+
+if test x"$FONT_SOURCE" = x && test x"$DJVU_FONT_SOURCE" = x && test x"$grub_build_mkfont_excuse" = x; then
+ grub_build_mkfont_excuse="no fonts"
+fi
+
+
+AC_ARG_ENABLE([grub-mount],
+ [AS_HELP_STRING([--enable-grub-mount],
+ [build and install the `grub-mount' utility (default=guessed)])])
+if test x"$enable_grub_mount" = xno ; then
+ grub_mount_excuse="explicitly disabled"
+fi
+
+if test x"$grub_mount_excuse" = x ; then
+ AC_CHECK_LIB([fuse], [fuse_main_real], [],
+ [grub_mount_excuse="need FUSE library"])
+fi
+
+if test x"$grub_mount_excuse" = x ; then
+ # Check for fuse headers.
+ SAVED_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -DFUSE_USE_VERSION=26"
+ AC_CHECK_HEADERS([fuse/fuse.h], [],
+ [grub_mount_excuse=["need FUSE headers"]])
+ CPPFLAGS="$SAVED_CPPFLAGS"
+fi
+
+if test x"$enable_grub_mount" = xyes && test x"$grub_mount_excuse" != x ; then
+ AC_MSG_ERROR([grub-mount was explicitly requested but can't be compiled ($grub_mount_excuse)])
+fi
+if test x"$grub_mount_excuse" = x ; then
+enable_grub_mount=yes
+else
+enable_grub_mount=no
+fi
+AC_SUBST([enable_grub_mount])
+
+AC_ARG_ENABLE([device-mapper],
+ [AS_HELP_STRING([--enable-device-mapper],
+ [enable Linux device-mapper support (default=guessed)])])
+if test x"$enable_device_mapper" = xno ; then
+ device_mapper_excuse="explicitly disabled"
+fi
+
+if test x"$device_mapper_excuse" = x ; then
+ # Check for device-mapper header.
+ AC_CHECK_HEADER([libdevmapper.h], [],
+ [device_mapper_excuse="need libdevmapper header"])
+fi
+
+if test x"$device_mapper_excuse" = x ; then
+ # Check for device-mapper library.
+ AC_CHECK_LIB([devmapper], [dm_task_create], [],
+ [device_mapper_excuse="need devmapper library"])
+fi
+
+if test x"$device_mapper_excuse" = x ; then
+ # Check for device-mapper library.
+ AC_CHECK_LIB([devmapper], [dm_log_with_errno_init],
+ [],
+ [device_mapper_excuse="need devmapper library"])
+fi
+
+if test x"$device_mapper_excuse" = x ; then
+ LIBDEVMAPPER="-ldevmapper"
+ AC_DEFINE([HAVE_DEVICE_MAPPER], [1],
+ [Define to 1 if you have the devmapper library.])
+fi
+
+AC_SUBST([LIBDEVMAPPER])
+
+LIBGEOM=
+if test x$host_kernel = xkfreebsd; then
+ AC_CHECK_LIB([geom], [geom_gettree], [],
+ [AC_MSG_ERROR([Your platform requires libgeom])])
+ LIBGEOM="-lgeom"
+fi
+
+AC_SUBST([LIBGEOM])
+
+AC_ARG_ENABLE([liblzma],
+ [AS_HELP_STRING([--enable-liblzma],
+ [enable liblzma integration (default=guessed)])])
+if test x"$enable_liblzma" = xno ; then
+ liblzma_excuse="explicitly disabled"
+fi
+
+if test x"$liblzma_excuse" = x ; then
+AC_CHECK_LIB([lzma], [lzma_code],
+ [],[liblzma_excuse="need lzma library"])
+fi
+if test x"$liblzma_excuse" = x ; then
+AC_CHECK_HEADER([lzma.h], [], [liblzma_excuse="need lzma header"])
+fi
+
+if test x"$enable_liblzma" = xyes && test x"$liblzma_excuse" != x ; then
+ AC_MSG_ERROR([liblzma support was explicitly requested but requirements are not satisfied ($liblzma_excuse)])
+fi
+
+
+if test x"$liblzma_excuse" = x ; then
+ LIBLZMA="-llzma"
+ AC_DEFINE([USE_LIBLZMA], [1],
+ [Define to 1 if you have the LZMA library.])
+fi
+
+AC_SUBST([LIBLZMA])
+
+AC_ARG_ENABLE([libzfs],
+ [AS_HELP_STRING([--enable-libzfs],
+ [enable libzfs integration (default=guessed)])])
+if test x"$enable_libzfs" = xno ; then
+ libzfs_excuse="explicitly disabled"
+fi
+
+if test x"$libzfs_excuse" = x ; then
+ # Only check for system headers if libzfs support has not been disabled.
+ AC_CHECK_HEADERS(libzfs.h libnvpair.h)
+fi
+
+if test x"$libzfs_excuse" = x ; then
+ AC_CHECK_LIB([zfs], [libzfs_init],
+ [],
+ [libzfs_excuse="need zfs library"])
+fi
+
+if test x"$libzfs_excuse" = x ; then
+ AC_CHECK_LIB([nvpair], [nvlist_lookup_string],
+ [],
+ [libzfs_excuse="need nvpair library"])
+fi
+
+if test x"$enable_libzfs" = xyes && test x"$libzfs_excuse" != x ; then
+ AC_MSG_ERROR([libzfs support was explicitly requested but requirements are not satisfied ($libzfs_excuse)])
+fi
+
+if test x"$libzfs_excuse" = x ; then
+ # We need both libzfs and libnvpair for a successful build.
+ LIBZFS="-lzfs"
+ AC_DEFINE([HAVE_LIBZFS], [1],
+ [Define to 1 if you have the ZFS library.])
+ LIBNVPAIR="-lnvpair"
+ AC_DEFINE([HAVE_LIBNVPAIR], [1],
+ [Define to 1 if you have the NVPAIR library.])
+fi
+
+AC_SUBST([LIBZFS])
+AC_SUBST([LIBNVPAIR])
+
+LIBS=""
+
+AC_SUBST([FONT_SOURCE])
+AS_IF([test x$target_cpu = xi386 -a x$platform = xqemu],
+ [AC_SUBST([GRUB_BOOT_MACHINE_LINK_ADDR], 0xffe00)])
+
+AC_SUBST(HAVE_ASM_USCORE)
+AC_SUBST(BSS_START_SYMBOL)
+AC_SUBST(END_SYMBOL)
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+
+AC_ARG_ENABLE([werror],
+ [AS_HELP_STRING([--disable-werror],
+ [do not use -Werror when building GRUB])])
+if test x"$enable_werror" != xno ; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -Werror"
+ HOST_CFLAGS="$HOST_CFLAGS -Werror"
+fi
+
+TARGET_CPP="$TARGET_CC -E"
+TARGET_CCAS=$TARGET_CC
+
+# Includes which include make-time substitutions. They must come last
+# as to avoid executing top_builddir in shell.
+HOST_CPPFLAGS="$HOST_CPPFLAGS -I\$(top_builddir)/include"
+TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_srcdir)/include"
+TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_builddir)/include"
+
+GRUB_TARGET_CPU="${target_cpu}"
+GRUB_PLATFORM="${platform}"
+
+AC_SUBST(GRUB_TARGET_CPU)
+AC_SUBST(GRUB_PLATFORM)
+
+AC_SUBST(TARGET_OBJCONV)
+AC_SUBST(TARGET_CPP)
+AC_SUBST(TARGET_CCAS)
+AC_SUBST(TARGET_OBJ2ELF)
+AC_SUBST(TARGET_MODULE_FORMAT)
+AC_SUBST(TARGET_CC_VERSION)
+
+AC_SUBST(TARGET_CFLAGS)
+AC_SUBST(TARGET_LDFLAGS)
+AC_SUBST(TARGET_CPPFLAGS)
+AC_SUBST(TARGET_CCASFLAGS)
+
+AC_SUBST(TARGET_IMG_LDFLAGS)
+AC_SUBST(TARGET_IMG_CFLAGS)
+AC_SUBST(TARGET_IMG_BASE_LDOPT)
+AC_SUBST(TARGET_APPLE_LINKER)
+
+AC_SUBST(HOST_CFLAGS)
+AC_SUBST(HOST_LDFLAGS)
+AC_SUBST(HOST_CPPFLAGS)
+AC_SUBST(HOST_CCASFLAGS)
+
+AC_SUBST(BUILD_LIBM)
+
+#
+# Automake conditionals
+#
+
+AM_CONDITIONAL([COND_real_platform], [test x$platform != xnone])
+AM_CONDITIONAL([COND_emu], [test x$platform = xemu])
+AM_CONDITIONAL([COND_i386_pc], [test x$target_cpu = xi386 -a x$platform = xpc])
+AM_CONDITIONAL([COND_i386_efi], [test x$target_cpu = xi386 -a x$platform = xefi])
+AM_CONDITIONAL([COND_ia64_efi], [test x$target_cpu = xia64 -a x$platform = xefi])
+AM_CONDITIONAL([COND_i386_qemu], [test x$target_cpu = xi386 -a x$platform = xqemu])
+AM_CONDITIONAL([COND_i386_ieee1275], [test x$target_cpu = xi386 -a x$platform = xieee1275])
+AM_CONDITIONAL([COND_i386_coreboot], [test x$target_cpu = xi386 -a x$platform = xcoreboot])
+AM_CONDITIONAL([COND_i386_multiboot], [test x$target_cpu = xi386 -a x$platform = xmultiboot])
+AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi])
+AM_CONDITIONAL([COND_i386_xen], [test x$target_cpu = xi386 -a x$platform = xxen])
+AM_CONDITIONAL([COND_i386_xen_pvh], [test x$target_cpu = xi386 -a x$platform = xxen_pvh])
+AM_CONDITIONAL([COND_x86_64_xen], [test x$target_cpu = xx86_64 -a x$platform = xxen])
+AM_CONDITIONAL([COND_mips64_efi], [test x$target_cpu = xmips64el -a x$platform = xefi])
+AM_CONDITIONAL([COND_mips_loongson], [test x$target_cpu = xmipsel -a x$platform = xloongson])
+AM_CONDITIONAL([COND_mips_qemu_mips], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xqemu_mips])
+AM_CONDITIONAL([COND_mips_arc], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xarc])
+AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275])
+AM_CONDITIONAL([COND_sparc64_emu], [test x$target_cpu = xsparc64 -a x$platform = xemu])
+AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275])
+AM_CONDITIONAL([COND_mips64el], [test x$target_cpu = xmips64el])
+AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips -o x$target_cpu = xmipsel])
+AM_CONDITIONAL([COND_mipsel], [test x$target_cpu = xmipsel])
+AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips])
+AM_CONDITIONAL([COND_arm], [test x$target_cpu = xarm ])
+AM_CONDITIONAL([COND_arm_uboot], [test x$target_cpu = xarm -a x$platform = xuboot])
+AM_CONDITIONAL([COND_arm_coreboot], [test x$target_cpu = xarm -a x$platform = xcoreboot])
+AM_CONDITIONAL([COND_arm_efi], [test x$target_cpu = xarm -a x$platform = xefi])
+AM_CONDITIONAL([COND_arm64], [test x$target_cpu = xarm64 ])
+AM_CONDITIONAL([COND_arm64_efi], [test x$target_cpu = xarm64 -a x$platform = xefi])
+AM_CONDITIONAL([COND_riscv32], [test x$target_cpu = xriscv32 ])
+AM_CONDITIONAL([COND_riscv64], [test x$target_cpu = xriscv64 ])
+AM_CONDITIONAL([COND_riscv32_efi], [test x$target_cpu = xriscv32 -a x$platform = xefi])
+AM_CONDITIONAL([COND_riscv64_efi], [test x$target_cpu = xriscv64 -a x$platform = xefi])
+
+AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd])
+AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux])
+AM_CONDITIONAL([COND_HOST_NETBSD], [test x$host_kernel = xnetbsd])
+AM_CONDITIONAL([COND_HOST_WINDOWS], [test x$host_kernel = xwindows])
+AM_CONDITIONAL([COND_HOST_KFREEBSD], [test x$host_kernel = xkfreebsd])
+AM_CONDITIONAL([COND_HOST_XNU], [test x$host_kernel = xxnu])
+AM_CONDITIONAL([COND_HOST_ILLUMOS], [test x$host_kernel = xillumos])
+
+AM_CONDITIONAL([COND_MAN_PAGES], [test x$cross_compiling = xno -a x$HELP2MAN != x])
+AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test x$enable_grub_emu_sdl = xyes])
+AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes])
+AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes])
+AM_CONDITIONAL([COND_GRUB_MOUNT], [test x$enable_grub_mount = xyes])
+AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x])
+if test x$FONT_SOURCE != x ; then
+ HAVE_FONT_SOURCE=1
+else
+ HAVE_FONT_SOURCE=0
+fi
+AC_SUBST(HAVE_FONT_SOURCE)
+AM_CONDITIONAL([COND_APPLE_LINKER], [test x$TARGET_APPLE_LINKER = x1])
+AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes])
+AM_CONDITIONAL([COND_ENABLE_CACHE_STATS], [test x$DISK_CACHE_STATS = x1])
+AM_CONDITIONAL([COND_ENABLE_BOOT_TIME_STATS], [test x$BOOT_TIME_STATS = x1])
+
+AM_CONDITIONAL([COND_HAVE_CXX], [test x$HAVE_CXX = xyes])
+
+AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1])
+AM_CONDITIONAL([COND_STARFIELD], [test "x$starfield_excuse" = x])
+AM_CONDITIONAL([COND_HAVE_EXEC], [test "x$have_exec" = xy])
+
+test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+datarootdir="$(eval echo "$datarootdir")"
+grub_libdir="$(eval echo "$libdir")"
+grub_localedir="$(eval echo "$localedir")"
+grub_datadir="$(eval echo "$datadir")"
+grub_sysconfdir="$(eval echo "$sysconfdir")"
+AC_DEFINE_UNQUOTED(LOCALEDIR, "$grub_localedir", [Locale dir])
+AC_DEFINE_UNQUOTED(GRUB_LIBDIR, "$grub_libdir", [Library dir])
+AC_DEFINE_UNQUOTED(GRUB_DATADIR, "$grub_datadir", [Data dir])
+AC_DEFINE_UNQUOTED(GRUB_SYSCONFDIR, "$grub_sysconfdir", [Configuration dir])
+
+
+# Output files.
+if test "$platform" != none; then
+ cpudir="${target_cpu}"
+ if test x${cpudir} = xmips64el; then
+ cpudir=mips64;
+ elif test x${cpudir} = xmipsel; then
+ cpudir=mips;
+ fi
+ grub_CHECK_LINK_DIR
+ if test x"$link_dir" = xyes ; then
+ AC_CONFIG_LINKS([include/grub/cpu:include/grub/$cpudir])
+ if test "$platform" != emu ; then
+ AC_CONFIG_LINKS([include/grub/machine:include/grub/$cpudir/$platform])
+ fi
+ else
+ mkdir -p include/grub 2>/dev/null
+ rm -rf include/grub/cpu
+ cp -rp $srcdir/include/grub/$cpudir include/grub/cpu 2>/dev/null
+ if test "$platform" != emu ; then
+ rm -rf include/grub/machine
+ cp -rp $srcdir/include/grub/$cpudir/$platform include/grub/machine 2>/dev/null
+ fi
+ fi
+else
+ # Just enough to stop the compiler failing with -I$(srcdir)/include.
+ mkdir -p include 2>/dev/null
+ rm -rf include/grub/cpu include/grub/machine
+fi
+
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([grub-core/Makefile])
+AC_CONFIG_FILES([grub-core/lib/gnulib/Makefile])
+AC_CONFIG_FILES([po/Makefile.in])
+AC_CONFIG_FILES([docs/Makefile])
+AC_CONFIG_FILES([util/bash-completion.d/Makefile])
+AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h])
+AC_CONFIG_FILES([config.h])
+
+AC_OUTPUT
+[
+echo "*******************************************************"
+echo GRUB2 will be compiled with following components:
+echo Platform: "$target_cpu"-"$platform"
+if [ x"$platform" = xemu ]; then
+if [ x"$grub_emu_sdl_excuse" = x ]; then
+echo SDL support for grub-emu: Yes
+else
+echo SDL support for grub-emu: No "($grub_emu_sdl_excuse)"
+fi
+if [ x"$grub_emu_pci_excuse" = x ]; then
+echo PCI support for grub-emu: Yes
+else
+echo PCI support for grub-emu: No "($grub_emu_pci_excuse)"
+fi
+fi
+if test x"$device_mapper_excuse" = x ; then
+echo With devmapper support: Yes
+else
+echo With devmapper support: No "($device_mapper_excuse)"
+fi
+if [ x"$enable_mm_debug" = xyes ]; then
+echo With memory debugging: Yes
+else
+echo With memory debugging: No
+fi
+if [ x"$enable_cache_stats" = xyes ]; then
+echo With disk cache statistics: Yes
+else
+echo With disk cache statistics: No
+fi
+
+if [ x"$enable_boot_time" = xyes ]; then
+echo With boot time statistics: Yes
+else
+echo With boot time statistics: No
+fi
+
+if [ x"$efiemu_excuse" = x ]; then
+echo efiemu runtime: Yes
+else
+echo efiemu runtime: No "($efiemu_excuse)"
+fi
+if [ x"$grub_mkfont_excuse" = x ]; then
+echo grub-mkfont: Yes
+else
+echo grub-mkfont: No "($grub_mkfont_excuse)"
+fi
+if [ x"$grub_mount_excuse" = x ]; then
+echo grub-mount: Yes
+else
+echo grub-mount: No "($grub_mount_excuse)"
+fi
+if [ x"$starfield_excuse" = x ]; then
+echo starfield theme: Yes
+echo With DejaVuSans font from $DJVU_FONT_SOURCE
+else
+echo starfield theme: No "($starfield_excuse)"
+fi
+if [ x"$libzfs_excuse" = x ]; then
+echo With libzfs support: Yes
+else
+echo With libzfs support: No "($libzfs_excuse)"
+fi
+if [ x"$grub_build_mkfont_excuse" = x ]; then
+ echo Build-time grub-mkfont: Yes
+ if test "x$FONT_SOURCE" = x ; then
+ echo "Without unifont"
+ else
+ echo "With unifont from $FONT_SOURCE"
+ fi
+else
+ echo Build-time grub-mkfont: No "($grub_build_mkfont_excuse)"
+ echo "Without unifont (no build-time grub-mkfont)"
+fi
+if test x"$liblzma_excuse" != x ; then
+echo "Without liblzma (no support for XZ-compressed mips images) ($liblzma_excuse)"
+else
+echo "With liblzma from $LIBLZMA (support for XZ-compressed mips images)"
+fi
+echo "*******************************************************"
+]
--- /dev/null
+#! /usr/bin/python
+# GRUB -- GRand Unified Bootloader
+# Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc.
+#
+# GRUB is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import print_function
+
+__metaclass__ = type
+
+from optparse import OptionParser
+import re
+
+#
+# This is the python script used to generate Makefile.*.am
+#
+
+GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
+ "i386_multiboot", "i386_ieee1275", "x86_64_efi",
+ "i386_xen", "x86_64_xen", "i386_xen_pvh",
+ "mips_loongson", "mips64_efi", "sparc64_ieee1275",
+ "powerpc_ieee1275", "mips_arc", "ia64_efi",
+ "mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi",
+ "arm_coreboot", "riscv32_efi", "riscv64_efi" ]
+
+GROUPS = {}
+
+GROUPS["common"] = GRUB_PLATFORMS[:]
+
+# Groups based on CPU
+GROUPS["i386"] = [ "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275" ]
+GROUPS["x86_64"] = [ "x86_64_efi" ]
+GROUPS["x86"] = GROUPS["i386"] + GROUPS["x86_64"]
+GROUPS["mips"] = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ]
+GROUPS["mips64"] = [ "mips64_efi" ]
+GROUPS["sparc64"] = [ "sparc64_ieee1275" ]
+GROUPS["powerpc"] = [ "powerpc_ieee1275" ]
+GROUPS["arm"] = [ "arm_uboot", "arm_efi", "arm_coreboot" ]
+GROUPS["arm64"] = [ "arm64_efi" ]
+GROUPS["riscv32"] = [ "riscv32_efi" ]
+GROUPS["riscv64"] = [ "riscv64_efi" ]
+
+# Groups based on firmware
+GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi", "mips64_efi",
+ "riscv32_efi", "riscv64_efi" ]
+GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ]
+GROUPS["uboot"] = [ "arm_uboot" ]
+GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ]
+GROUPS["coreboot"] = [ "i386_coreboot", "arm_coreboot" ]
+
+# emu is a special case so many core functionality isn't needed on this platform
+GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu")
+
+# Groups based on hardware features
+GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_loongson", "mips_qemu_mips",
+ "sparc64_ieee1275", "powerpc_ieee1275"]
+GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi");
+GROUPS["pci"] = GROUPS["x86"] + ["mips_loongson"]
+GROUPS["usb"] = GROUPS["pci"] + ["arm_coreboot"]
+
+# If gfxterm is main output console integrate it into kernel
+GROUPS["videoinkernel"] = ["mips_loongson", "i386_coreboot", "arm_coreboot" ]
+GROUPS["videomodules"] = GRUB_PLATFORMS[:];
+for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i)
+
+# Similar for terminfo
+GROUPS["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips", "i386_xen_pvh" ] + GROUPS["xen"] + GROUPS["ieee1275"] + GROUPS["uboot"];
+GROUPS["terminfomodule"] = GRUB_PLATFORMS[:];
+for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i)
+
+# Flattened Device Trees (FDT)
+GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi", "riscv32_efi", "riscv64_efi" ]
+
+# Needs software helpers for division
+# Must match GRUB_DIVISION_IN_SOFTWARE in misc.h
+GROUPS["softdiv"] = GROUPS["arm"] + ["ia64_efi"] + GROUPS["riscv32"]
+GROUPS["no_softdiv"] = GRUB_PLATFORMS[:]
+for i in GROUPS["softdiv"]: GROUPS["no_softdiv"].remove(i)
+
+# Miscellaneous groups scheduled to disappear in future
+GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"]
+GROUPS["nopc"] = GRUB_PLATFORMS[:]; GROUPS["nopc"].remove("i386_pc")
+
+#
+# Create platform => groups reverse map, where groups covering that
+# platform are ordered by their sizes
+#
+RMAP = {}
+for platform in GRUB_PLATFORMS:
+ # initialize with platform itself as a group
+ RMAP[platform] = [ platform ]
+
+ for k in GROUPS.keys():
+ v = GROUPS[k]
+ # skip groups that don't cover this platform
+ if platform not in v: continue
+
+ bigger = []
+ smaller = []
+ # partition currently known groups based on their size
+ for group in RMAP[platform]:
+ if group in GRUB_PLATFORMS: smaller.append(group)
+ elif len(GROUPS[group]) < len(v): smaller.append(group)
+ else: bigger.append(group)
+ # insert in the middle
+ RMAP[platform] = smaller + [ k ] + bigger
+
+#
+# Input
+#
+
+# We support a subset of the AutoGen definitions file syntax. Specifically,
+# compound names are disallowed; some preprocessing directives are
+# disallowed (though #if/#endif are allowed; note that, like AutoGen, #if
+# skips everything to the next #endif regardless of the value of the
+# conditional); and shell-generated strings, Scheme-generated strings, and
+# here strings are disallowed.
+
+class AutogenToken:
+ (autogen, definitions, eof, var_name, other_name, string, number,
+ semicolon, equals, comma, lbrace, rbrace, lbracket, rbracket) = range(14)
+
+class AutogenState:
+ (init, need_def, need_tpl, need_semi, need_name, have_name, need_value,
+ need_idx, need_rbracket, indx_name, have_value, done) = range(12)
+
+class AutogenParseError(Exception):
+ def __init__(self, message, path, line):
+ super(AutogenParseError, self).__init__(message)
+ self.path = path
+ self.line = line
+
+ def __str__(self):
+ return (
+ super(AutogenParseError, self).__str__() +
+ " at file %s line %d" % (self.path, self.line))
+
+class AutogenDefinition(list):
+ def __getitem__(self, key):
+ try:
+ return super(AutogenDefinition, self).__getitem__(key)
+ except TypeError:
+ for name, value in self:
+ if name == key:
+ return value
+
+ def __contains__(self, key):
+ for name, value in self:
+ if name == key:
+ return True
+ return False
+
+ def get(self, key, default):
+ for name, value in self:
+ if name == key:
+ return value
+ else:
+ return default
+
+ def find_all(self, key):
+ for name, value in self:
+ if name == key:
+ yield value
+
+class AutogenParser:
+ def __init__(self):
+ self.definitions = AutogenDefinition()
+ self.def_stack = [("", self.definitions)]
+ self.curdef = None
+ self.new_name = None
+ self.cur_path = None
+ self.cur_line = 0
+
+ @staticmethod
+ def is_unquotable_char(c):
+ return (ord(c) in range(ord("!"), ord("~") + 1) and
+ c not in "#,;<=>[\\]`{}?*'\"()")
+
+ @staticmethod
+ def is_value_name_char(c):
+ return c in ":^-_" or c.isalnum()
+
+ def error(self, message):
+ raise AutogenParseError(message, self.cur_file, self.cur_line)
+
+ def read_tokens(self, f):
+ data = f.read()
+ end = len(data)
+ offset = 0
+ while offset < end:
+ while offset < end and data[offset].isspace():
+ if data[offset] == "\n":
+ self.cur_line += 1
+ offset += 1
+ if offset >= end:
+ break
+ c = data[offset]
+ if c == "#":
+ offset += 1
+ try:
+ end_directive = data.index("\n", offset)
+ directive = data[offset:end_directive]
+ offset = end_directive
+ except ValueError:
+ directive = data[offset:]
+ offset = end
+ name, value = directive.split(None, 1)
+ if name == "if":
+ try:
+ end_if = data.index("\n#endif", offset)
+ new_offset = end_if + len("\n#endif")
+ self.cur_line += data[offset:new_offset].count("\n")
+ offset = new_offset
+ except ValueError:
+ self.error("#if without matching #endif")
+ else:
+ self.error("Unhandled directive '#%s'" % name)
+ elif c == "{":
+ yield AutogenToken.lbrace, c
+ offset += 1
+ elif c == "=":
+ yield AutogenToken.equals, c
+ offset += 1
+ elif c == "}":
+ yield AutogenToken.rbrace, c
+ offset += 1
+ elif c == "[":
+ yield AutogenToken.lbracket, c
+ offset += 1
+ elif c == "]":
+ yield AutogenToken.rbracket, c
+ offset += 1
+ elif c == ";":
+ yield AutogenToken.semicolon, c
+ offset += 1
+ elif c == ",":
+ yield AutogenToken.comma, c
+ offset += 1
+ elif c in ("'", '"'):
+ s = []
+ while True:
+ offset += 1
+ if offset >= end:
+ self.error("EOF in quoted string")
+ if data[offset] == "\n":
+ self.cur_line += 1
+ if data[offset] == "\\":
+ offset += 1
+ if offset >= end:
+ self.error("EOF in quoted string")
+ if data[offset] == "\n":
+ self.cur_line += 1
+ # Proper escaping unimplemented; this can be filled
+ # out if needed.
+ s.append("\\")
+ s.append(data[offset])
+ elif data[offset] == c:
+ offset += 1
+ break
+ else:
+ s.append(data[offset])
+ yield AutogenToken.string, "".join(s)
+ elif c == "/":
+ offset += 1
+ if data[offset] == "*":
+ offset += 1
+ try:
+ end_comment = data.index("*/", offset)
+ new_offset = end_comment + len("*/")
+ self.cur_line += data[offset:new_offset].count("\n")
+ offset = new_offset
+ except ValueError:
+ self.error("/* without matching */")
+ elif data[offset] == "/":
+ try:
+ offset = data.index("\n", offset)
+ except ValueError:
+ pass
+ elif (c.isdigit() or
+ (c == "-" and offset < end - 1 and
+ data[offset + 1].isdigit())):
+ end_number = offset + 1
+ while end_number < end and data[end_number].isdigit():
+ end_number += 1
+ yield AutogenToken.number, data[offset:end_number]
+ offset = end_number
+ elif self.is_unquotable_char(c):
+ end_name = offset
+ while (end_name < end and
+ self.is_value_name_char(data[end_name])):
+ end_name += 1
+ if end_name < end and self.is_unquotable_char(data[end_name]):
+ while (end_name < end and
+ self.is_unquotable_char(data[end_name])):
+ end_name += 1
+ yield AutogenToken.other_name, data[offset:end_name]
+ offset = end_name
+ else:
+ s = data[offset:end_name]
+ if s.lower() == "autogen":
+ yield AutogenToken.autogen, s
+ elif s.lower() == "definitions":
+ yield AutogenToken.definitions, s
+ else:
+ yield AutogenToken.var_name, s
+ offset = end_name
+ else:
+ self.error("Invalid input character '%s'" % c)
+ yield AutogenToken.eof, None
+
+ def do_need_name_end(self, token):
+ if len(self.def_stack) > 1:
+ self.error("Definition blocks were left open")
+
+ def do_need_name_var_name(self, token):
+ self.new_name = token
+
+ def do_end_block(self, token):
+ if len(self.def_stack) <= 1:
+ self.error("Too many close braces")
+ new_name, parent_def = self.def_stack.pop()
+ parent_def.append((new_name, self.curdef))
+ self.curdef = parent_def
+
+ def do_empty_val(self, token):
+ self.curdef.append((self.new_name, ""))
+
+ def do_str_value(self, token):
+ self.curdef.append((self.new_name, token))
+
+ def do_start_block(self, token):
+ self.def_stack.append((self.new_name, self.curdef))
+ self.curdef = AutogenDefinition()
+
+ def do_indexed_name(self, token):
+ self.new_name = token
+
+ def read_definitions_file(self, f):
+ self.curdef = self.definitions
+ self.cur_line = 0
+ state = AutogenState.init
+
+ # The following transition table was reduced from the Autogen
+ # documentation:
+ # info -f autogen -n 'Full Syntax'
+ transitions = {
+ AutogenState.init: {
+ AutogenToken.autogen: (AutogenState.need_def, None),
+ },
+ AutogenState.need_def: {
+ AutogenToken.definitions: (AutogenState.need_tpl, None),
+ },
+ AutogenState.need_tpl: {
+ AutogenToken.var_name: (AutogenState.need_semi, None),
+ AutogenToken.other_name: (AutogenState.need_semi, None),
+ AutogenToken.string: (AutogenState.need_semi, None),
+ },
+ AutogenState.need_semi: {
+ AutogenToken.semicolon: (AutogenState.need_name, None),
+ },
+ AutogenState.need_name: {
+ AutogenToken.autogen: (AutogenState.need_def, None),
+ AutogenToken.eof: (AutogenState.done, self.do_need_name_end),
+ AutogenToken.var_name: (
+ AutogenState.have_name, self.do_need_name_var_name),
+ AutogenToken.rbrace: (
+ AutogenState.have_value, self.do_end_block),
+ },
+ AutogenState.have_name: {
+ AutogenToken.semicolon: (
+ AutogenState.need_name, self.do_empty_val),
+ AutogenToken.equals: (AutogenState.need_value, None),
+ AutogenToken.lbracket: (AutogenState.need_idx, None),
+ },
+ AutogenState.need_value: {
+ AutogenToken.var_name: (
+ AutogenState.have_value, self.do_str_value),
+ AutogenToken.other_name: (
+ AutogenState.have_value, self.do_str_value),
+ AutogenToken.string: (
+ AutogenState.have_value, self.do_str_value),
+ AutogenToken.number: (
+ AutogenState.have_value, self.do_str_value),
+ AutogenToken.lbrace: (
+ AutogenState.need_name, self.do_start_block),
+ },
+ AutogenState.need_idx: {
+ AutogenToken.var_name: (
+ AutogenState.need_rbracket, self.do_indexed_name),
+ AutogenToken.number: (
+ AutogenState.need_rbracket, self.do_indexed_name),
+ },
+ AutogenState.need_rbracket: {
+ AutogenToken.rbracket: (AutogenState.indx_name, None),
+ },
+ AutogenState.indx_name: {
+ AutogenToken.semicolon: (
+ AutogenState.need_name, self.do_empty_val),
+ AutogenToken.equals: (AutogenState.need_value, None),
+ },
+ AutogenState.have_value: {
+ AutogenToken.semicolon: (AutogenState.need_name, None),
+ AutogenToken.comma: (AutogenState.need_value, None),
+ },
+ }
+
+ for code, token in self.read_tokens(f):
+ if code in transitions[state]:
+ state, handler = transitions[state][code]
+ if handler is not None:
+ handler(token)
+ else:
+ self.error(
+ "Parse error in state %s: unexpected token '%s'" % (
+ state, token))
+ if state == AutogenState.done:
+ break
+
+ def read_definitions(self, path):
+ self.cur_file = path
+ with open(path) as f:
+ self.read_definitions_file(f)
+
+defparser = AutogenParser()
+
+#
+# Output
+#
+
+outputs = {}
+
+def output(s, section=''):
+ if s == "":
+ return
+ outputs.setdefault(section, [])
+ outputs[section].append(s)
+
+def write_output(section=''):
+ for s in outputs.get(section, []):
+ print(s, end='')
+
+#
+# Global variables
+#
+
+def gvar_add(var, value):
+ output(var + " += " + value + "\n")
+
+#
+# Per PROGRAM/SCRIPT variables
+#
+
+seen_vars = set()
+
+def vars_init(defn, *var_list):
+ name = defn['name']
+
+ if name not in seen_target and name not in seen_vars:
+ for var in var_list:
+ output(var + " = \n", section='decl')
+ seen_vars.add(name)
+
+def var_set(var, value):
+ output(var + " = " + value + "\n")
+
+def var_add(var, value):
+ output(var + " += " + value + "\n")
+
+#
+# Variable names and rules
+#
+
+canonical_name_re = re.compile(r'[^0-9A-Za-z@_]')
+canonical_name_suffix = ""
+
+def set_canonical_name_suffix(suffix):
+ global canonical_name_suffix
+ canonical_name_suffix = suffix
+
+def cname(defn):
+ return canonical_name_re.sub('_', defn['name'] + canonical_name_suffix)
+
+def rule(target, source, cmd):
+ if cmd[0] == "\n":
+ output("\n" + target + ": " + source + cmd.replace("\n", "\n\t") + "\n")
+ else:
+ output("\n" + target + ": " + source + "\n\t" + cmd.replace("\n", "\n\t") + "\n")
+
+#
+# Handle keys with platform names as values, for example:
+#
+# kernel = {
+# nostrip = emu;
+# ...
+# }
+#
+def platform_tagged(defn, platform, tag):
+ for value in defn.find_all(tag):
+ for group in RMAP[platform]:
+ if value == group:
+ return True
+ return False
+
+def if_platform_tagged(defn, platform, tag, snippet_if, snippet_else=None):
+ if platform_tagged(defn, platform, tag):
+ return snippet_if
+ elif snippet_else is not None:
+ return snippet_else
+
+#
+# Handle tagged values
+#
+# module = {
+# extra_dist = ...
+# extra_dist = ...
+# ...
+# };
+#
+def foreach_value(defn, tag, closure):
+ r = []
+ for value in defn.find_all(tag):
+ r.append(closure(value))
+ return ''.join(r)
+
+#
+# Handle best matched values for a platform, for example:
+#
+# module = {
+# cflags = '-Wall';
+# emu_cflags = '-Wall -DGRUB_EMU=1';
+# ...
+# }
+#
+def foreach_platform_specific_value(defn, platform, suffix, nonetag, closure):
+ r = []
+ for group in RMAP[platform]:
+ values = list(defn.find_all(group + suffix))
+ if values:
+ for value in values:
+ r.append(closure(value))
+ break
+ else:
+ for value in defn.find_all(nonetag):
+ r.append(closure(value))
+ return ''.join(r)
+
+#
+# Handle values from sum of all groups for a platform, for example:
+#
+# module = {
+# common = kern/misc.c;
+# emu = kern/emu/misc.c;
+# ...
+# }
+#
+def foreach_platform_value(defn, platform, suffix, closure):
+ r = []
+ for group in RMAP[platform]:
+ for value in defn.find_all(group + suffix):
+ r.append(closure(value))
+ return ''.join(r)
+
+def platform_conditional(platform, closure):
+ output("\nif COND_" + platform + "\n")
+ closure(platform)
+ output("endif\n")
+
+#
+# Handle guarding with platform-specific "enable" keys, for example:
+#
+# module = {
+# name = pci;
+# noemu = bus/pci.c;
+# emu = bus/emu/pci.c;
+# emu = commands/lspci.c;
+#
+# enable = emu;
+# enable = i386_pc;
+# enable = x86_efi;
+# enable = i386_ieee1275;
+# enable = i386_coreboot;
+# };
+#
+def foreach_enabled_platform(defn, closure):
+ if 'enable' in defn:
+ for platform in GRUB_PLATFORMS:
+ if platform_tagged(defn, platform, "enable"):
+ platform_conditional(platform, closure)
+ else:
+ for platform in GRUB_PLATFORMS:
+ platform_conditional(platform, closure)
+
+#
+# Handle guarding with platform-specific automake conditionals, for example:
+#
+# module = {
+# name = usb;
+# common = bus/usb/usb.c;
+# noemu = bus/usb/usbtrans.c;
+# noemu = bus/usb/usbhub.c;
+# enable = emu;
+# enable = i386;
+# enable = mips_loongson;
+# emu_condition = COND_GRUB_EMU_SDL;
+# };
+#
+def under_platform_specific_conditionals(defn, platform, closure):
+ output(foreach_platform_specific_value(defn, platform, "_condition", "condition", lambda cond: "if " + cond + "\n"))
+ closure(defn, platform)
+ output(foreach_platform_specific_value(defn, platform, "_condition", "condition", lambda cond: "endif " + cond + "\n"))
+
+def platform_specific_values(defn, platform, suffix, nonetag):
+ return foreach_platform_specific_value(defn, platform, suffix, nonetag,
+ lambda value: value + " ")
+
+def platform_values(defn, platform, suffix):
+ return foreach_platform_value(defn, platform, suffix, lambda value: value + " ")
+
+def extra_dist(defn):
+ return foreach_value(defn, "extra_dist", lambda value: value + " ")
+
+def platform_sources(defn, p): return platform_values(defn, p, "")
+def platform_nodist_sources(defn, p): return platform_values(defn, p, "_nodist")
+
+def platform_startup(defn, p): return platform_specific_values(defn, p, "_startup", "startup")
+def platform_ldadd(defn, p): return platform_specific_values(defn, p, "_ldadd", "ldadd")
+def platform_dependencies(defn, p): return platform_specific_values(defn, p, "_dependencies", "dependencies")
+def platform_cflags(defn, p): return platform_specific_values(defn, p, "_cflags", "cflags")
+def platform_ldflags(defn, p): return platform_specific_values(defn, p, "_ldflags", "ldflags")
+def platform_cppflags(defn, p): return platform_specific_values(defn, p, "_cppflags", "cppflags")
+def platform_ccasflags(defn, p): return platform_specific_values(defn, p, "_ccasflags", "ccasflags")
+def platform_stripflags(defn, p): return platform_specific_values(defn, p, "_stripflags", "stripflags")
+def platform_objcopyflags(defn, p): return platform_specific_values(defn, p, "_objcopyflags", "objcopyflags")
+
+#
+# Emit snippet only the first time through for the current name.
+#
+seen_target = set()
+
+def first_time(defn, snippet):
+ if defn['name'] not in seen_target:
+ return snippet
+ return ''
+
+def is_platform_independent(defn):
+ if 'enable' in defn:
+ return False
+ for suffix in [ "", "_nodist" ]:
+ template = platform_values(defn, GRUB_PLATFORMS[0], suffix)
+ for platform in GRUB_PLATFORMS[1:]:
+ if template != platform_values(defn, platform, suffix):
+ return False
+
+ for suffix in [ "startup", "ldadd", "dependencies", "cflags", "ldflags", "cppflags", "ccasflags", "stripflags", "objcopyflags", "condition" ]:
+ template = platform_specific_values(defn, GRUB_PLATFORMS[0], "_" + suffix, suffix)
+ for platform in GRUB_PLATFORMS[1:]:
+ if template != platform_specific_values(defn, platform, "_" + suffix, suffix):
+ return False
+ for tag in [ "nostrip" ]:
+ template = platform_tagged(defn, GRUB_PLATFORMS[0], tag)
+ for platform in GRUB_PLATFORMS[1:]:
+ if template != platform_tagged(defn, platform, tag):
+ return False
+
+ return True
+
+def module(defn, platform):
+ name = defn['name']
+ set_canonical_name_suffix(".module")
+
+ gvar_add("platform_PROGRAMS", name + ".module")
+ gvar_add("MODULE_FILES", name + ".module$(EXEEXT)")
+
+ var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform) + " ## platform sources")
+ var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + " ## platform nodist sources")
+ var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform))
+ var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_MODULE) " + platform_cflags(defn, platform))
+ var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_MODULE) " + platform_ldflags(defn, platform))
+ var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_MODULE) " + platform_cppflags(defn, platform))
+ var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_MODULE) " + platform_ccasflags(defn, platform))
+ var_set(cname(defn) + "_DEPENDENCIES", "$(TARGET_OBJ2ELF) " + platform_dependencies(defn, platform))
+
+ gvar_add("dist_noinst_DATA", extra_dist(defn))
+ gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)")
+ gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)")
+
+ gvar_add("MOD_FILES", name + ".mod")
+ gvar_add("MARKER_FILES", name + ".marker")
+ gvar_add("CLEANFILES", name + ".marker")
+ output("""
+""" + name + """.marker: $(""" + cname(defn) + """_SOURCES) $(nodist_""" + cname(defn) + """_SOURCES)
+ $(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + cname(defn) + """_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1)
+ grep 'MARKER' $@.new > $@; rm -f $@.new
+""")
+
+def kernel(defn, platform):
+ name = defn['name']
+ set_canonical_name_suffix(".exec")
+ gvar_add("platform_PROGRAMS", name + ".exec")
+ var_set(cname(defn) + "_SOURCES", platform_startup(defn, platform))
+ var_add(cname(defn) + "_SOURCES", platform_sources(defn, platform))
+ var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + " ## platform nodist sources")
+ var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform))
+ var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_KERNEL) " + platform_cflags(defn, platform))
+ var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_KERNEL) " + platform_ldflags(defn, platform))
+ var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) " + platform_cppflags(defn, platform))
+ var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_KERNEL) " + platform_ccasflags(defn, platform))
+ var_set(cname(defn) + "_STRIPFLAGS", "$(AM_STRIPFLAGS) $(STRIPFLAGS_KERNEL) " + platform_stripflags(defn, platform))
+ var_set(cname(defn) + "_DEPENDENCIES", "$(TARGET_OBJ2ELF)")
+
+ gvar_add("dist_noinst_DATA", extra_dist(defn))
+ gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)")
+ gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)")
+
+ gvar_add("platform_DATA", name + ".img")
+ gvar_add("CLEANFILES", name + ".img")
+ rule(name + ".img", name + ".exec$(EXEEXT)",
+ if_platform_tagged(defn, platform, "nostrip",
+"""if test x$(TARGET_APPLE_LINKER) = x1; then \
+ $(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -wd1106 -nu -nd $< $@; \
+ elif test ! -z '$(TARGET_OBJ2ELF)'; then \
+ $(TARGET_OBJ2ELF) $< $@ || (rm -f $@; exit 1); \
+ else cp $< $@; fi""",
+"""if test x$(TARGET_APPLE_LINKER) = x1; then \
+ $(TARGET_STRIP) -S -x $(""" + cname(defn) + """) -o $@.bin $<; \
+ $(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -ed2016 -wd1106 -nu -nd $@.bin $@; \
+ rm -f $@.bin; \
+ elif test ! -z '$(TARGET_OBJ2ELF)'; then \
+ """ + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@.bin $< && \
+ $(TARGET_OBJ2ELF) $@.bin $@ || (rm -f $@; rm -f $@.bin; exit 1); \
+ rm -f $@.bin; \
+else """ + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@ $<; \
+fi"""))
+
+def image(defn, platform):
+ name = defn['name']
+ set_canonical_name_suffix(".image")
+ gvar_add("platform_PROGRAMS", name + ".image")
+ var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform))
+ var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + "## platform nodist sources")
+ var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform))
+ var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_IMAGE) " + platform_cflags(defn, platform))
+ var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_IMAGE) " + platform_ldflags(defn, platform))
+ var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_IMAGE) " + platform_cppflags(defn, platform))
+ var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_IMAGE) " + platform_ccasflags(defn, platform))
+ var_set(cname(defn) + "_OBJCOPYFLAGS", "$(OBJCOPYFLAGS_IMAGE) " + platform_objcopyflags(defn, platform))
+ # var_set(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform))
+
+ gvar_add("dist_noinst_DATA", extra_dist(defn))
+ gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)")
+ gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)")
+
+ gvar_add("platform_DATA", name + ".img")
+ gvar_add("CLEANFILES", name + ".img")
+ rule(name + ".img", name + ".image$(EXEEXT)", """
+if test x$(TARGET_APPLE_LINKER) = x1; then \
+ $(MACHO2IMG) $< $@; \
+else \
+ $(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version -R .ARM.exidx $< $@; \
+fi
+""")
+
+def library(defn, platform):
+ name = defn['name']
+ set_canonical_name_suffix("")
+
+ vars_init(defn,
+ cname(defn) + "_SOURCES",
+ "nodist_" + cname(defn) + "_SOURCES",
+ cname(defn) + "_CFLAGS",
+ cname(defn) + "_CPPFLAGS",
+ cname(defn) + "_CCASFLAGS")
+ # cname(defn) + "_DEPENDENCIES")
+
+ if name not in seen_target:
+ gvar_add("noinst_LIBRARIES", name)
+ var_add(cname(defn) + "_SOURCES", platform_sources(defn, platform))
+ var_add("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform))
+ var_add(cname(defn) + "_CFLAGS", first_time(defn, "$(AM_CFLAGS) $(CFLAGS_LIBRARY) ") + platform_cflags(defn, platform))
+ var_add(cname(defn) + "_CPPFLAGS", first_time(defn, "$(AM_CPPFLAGS) $(CPPFLAGS_LIBRARY) ") + platform_cppflags(defn, platform))
+ var_add(cname(defn) + "_CCASFLAGS", first_time(defn, "$(AM_CCASFLAGS) $(CCASFLAGS_LIBRARY) ") + platform_ccasflags(defn, platform))
+ # var_add(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform))
+
+ gvar_add("dist_noinst_DATA", extra_dist(defn))
+ if name not in seen_target:
+ gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)")
+ gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)")
+
+def installdir(defn, default="bin"):
+ return defn.get('installdir', default)
+
+def manpage(defn, adddeps):
+ name = defn['name']
+ mansection = defn['mansection']
+
+ output("if COND_MAN_PAGES\n")
+ gvar_add("man_MANS", name + "." + mansection)
+ rule(name + "." + mansection, name + " " + adddeps, """
+chmod a+x """ + name + """
+PATH=$(builddir):$$PATH pkgdatadir=$(builddir) $(HELP2MAN) --section=""" + mansection + """ -i $(top_srcdir)/docs/man/""" + name + """.h2m -o $@ """ + name + """
+""")
+ gvar_add("CLEANFILES", name + "." + mansection)
+ output("endif\n")
+
+def program(defn, platform, test=False):
+ name = defn['name']
+ set_canonical_name_suffix("")
+
+ if 'testcase' in defn:
+ gvar_add("check_PROGRAMS", name)
+ gvar_add("TESTS", name)
+ else:
+ var_add(installdir(defn) + "_PROGRAMS", name)
+ if 'mansection' in defn:
+ manpage(defn, "")
+
+ var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform))
+ var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform))
+ var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform))
+ var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_PROGRAM) " + platform_cflags(defn, platform))
+ var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_PROGRAM) " + platform_ldflags(defn, platform))
+ var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_PROGRAM) " + platform_cppflags(defn, platform))
+ var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_PROGRAM) " + platform_ccasflags(defn, platform))
+ # var_set(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform))
+
+ gvar_add("dist_noinst_DATA", extra_dist(defn))
+ gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)")
+ gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)")
+
+def data(defn, platform):
+ var_add("dist_" + installdir(defn) + "_DATA", platform_sources(defn, platform))
+ gvar_add("dist_noinst_DATA", extra_dist(defn))
+
+def transform_data(defn, platform):
+ name = defn['name']
+
+ var_add(installdir(defn) + "_DATA", name)
+
+ rule(name, "$(top_builddir)/config.status " + platform_sources(defn, platform) + platform_dependencies(defn, platform), """
+(for x in """ + platform_sources(defn, platform) + """; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:-
+chmod a+x """ + name + """
+""")
+
+ gvar_add("CLEANFILES", name)
+ gvar_add("EXTRA_DIST", extra_dist(defn))
+ gvar_add("dist_noinst_DATA", platform_sources(defn, platform))
+
+def script(defn, platform):
+ name = defn['name']
+
+ if 'testcase' in defn:
+ gvar_add("check_SCRIPTS", name)
+ gvar_add ("TESTS", name)
+ else:
+ var_add(installdir(defn) + "_SCRIPTS", name)
+ if 'mansection' in defn:
+ manpage(defn, "grub-mkconfig_lib")
+
+ rule(name, "$(top_builddir)/config.status " + platform_sources(defn, platform) + platform_dependencies(defn, platform), """
+(for x in """ + platform_sources(defn, platform) + """; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:-
+chmod a+x """ + name + """
+""")
+
+ gvar_add("CLEANFILES", name)
+ gvar_add("EXTRA_DIST", extra_dist(defn))
+ gvar_add("dist_noinst_DATA", platform_sources(defn, platform))
+
+def rules(target, closure):
+ seen_target.clear()
+ seen_vars.clear()
+
+ for defn in defparser.definitions.find_all(target):
+ if is_platform_independent(defn):
+ under_platform_specific_conditionals(defn, GRUB_PLATFORMS[0], closure)
+ else:
+ foreach_enabled_platform(
+ defn,
+ lambda p: under_platform_specific_conditionals(defn, p, closure))
+ # Remember that we've seen this target.
+ seen_target.add(defn['name'])
+
+parser = OptionParser(usage="%prog DEFINITION-FILES")
+_, args = parser.parse_args()
+
+for arg in args:
+ defparser.read_definitions(arg)
+
+rules("module", module)
+rules("kernel", kernel)
+rules("image", image)
+rules("library", library)
+rules("program", program)
+rules("script", script)
+rules("data", data)
+rules("transform_data", transform_data)
+
+write_output(section='decl')
+write_output()
--- /dev/null
+AUTOMAKE_OPTIONS = subdir-objects -Wno-portability
+
+DEPDIR=.deps-core
+
+include $(top_srcdir)/conf/Makefile.common
+
+CC=$(TARGET_CC)
+CPP=$(TARGET_CC)
+CCAS=$(TARGET_CC)
+RANLIB=$(TARGET_RANLIB)
+STRIP=$(TARGET_STRIP)
+
+MACHO2IMG=$(top_builddir)/grub-macho2img
+
+AM_CFLAGS = $(TARGET_CFLAGS)
+AM_LDFLAGS = $(TARGET_LDFLAGS)
+AM_CPPFLAGS = $(TARGET_CPPFLAGS) $(CPPFLAGS_DEFAULT)
+AM_CCASFLAGS = $(TARGET_CCASFLAGS) $(CCASFLAGS_DEFAULT)
+
+CFLAGS_PROGRAM += $(CFLAGS_PLATFORM)
+LDFLAGS_PROGRAM += $(LDFLAGS_PLATFORM)
+CPPFLAGS_PROGRAM += $(CPPFLAGS_PLATFORM)
+CCASFLAGS_PROGRAM += $(CCASFLAGS_PLATFORM)
+
+CFLAGS_LIBRARY += $(CFLAGS_PLATFORM) -fno-builtin
+CPPFLAGS_LIBRARY += $(CPPFLAGS_PLATFORM)
+CCASFLAGS_LIBRARY += $(CCASFLAGS_PLATFORM)
+
+build-grub-pep2elf$(BUILD_EXEEXT): $(top_srcdir)/util/grub-pe2elf.c $(top_srcdir)/grub-core/kern/emu/misc.c $(top_srcdir)/util/misc.c
+ $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_BUILD=1 -DGRUB_TARGET_WORDSIZE=64 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-pep2elf\" $^
+CLEANFILES += build-grub-pep2elf$(BUILD_EXEEXT)
+
+build-grub-pe2elf$(BUILD_EXEEXT): $(top_srcdir)/util/grub-pe2elf.c $(top_srcdir)/grub-core/kern/emu/misc.c $(top_srcdir)/util/misc.c
+ $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_BUILD=1 -DGRUB_TARGET_WORDSIZE=32 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-pe2elf\" $^
+CLEANFILES += build-grub-pe2elf$(BUILD_EXEEXT)
+
+# gentrigtables
+gentrigtables$(BUILD_EXEEXT): gentrigtables.c
+ $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) $< $(BUILD_LIBM)
+CLEANFILES += gentrigtables$(BUILD_EXEEXT)
+
+build-grub-module-verifier$(BUILD_EXEEXT): $(top_srcdir)/util/grub-module-verifier.c $(top_srcdir)/util/grub-module-verifier32.c $(top_srcdir)/util/grub-module-verifier64.c $(top_srcdir)/grub-core/kern/emu/misc.c $(top_srcdir)/util/misc.c
+ $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_BUILD=1 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-module-verifier\" $^
+CLEANFILES += build-grub-module-verifier$(BUILD_EXEEXT)
+
+# trigtables.c
+trigtables.c: gentrigtables$(BUILD_EXEEXT) gentrigtables.c $(top_srcdir)/configure.ac
+ ./gentrigtables$(BUILD_EXEEXT) > $@
+CLEANFILES += trigtables.c
+
+# XXX Use Automake's LEX & YACC support
+grub_script.tab.h: script/parser.y
+ $(YACC) -d -p grub_script_yy -b grub_script $<
+grub_script.tab.c: grub_script.tab.h
+CLEANFILES += grub_script.tab.c grub_script.tab.h
+
+# For the lexer.
+grub_script.yy.h: script/yylex.l
+ $(LEX) -o grub_script.yy.c --header-file=grub_script.yy.h $<
+grub_script.yy.c: grub_script.yy.h
+
+rs_decoder.h: $(srcdir)/lib/reed_solomon.c
+ $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Os -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 -mregparm=3 -ffreestanding
+
+CLEANFILES += grub_script.yy.c grub_script.yy.h
+
+include $(srcdir)/Makefile.core.am
+
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cache.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/command.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/device.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/disk.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/dl.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env_private.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/err.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/file.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fs.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/kernel.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h
+if COND_emu
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt-emu.h
+else
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt.h
+endif
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h
+
+if COND_i386_pc
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+endif
+
+if COND_i386_xen_pvh
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h
+endif
+
+if COND_i386_efi
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h
+endif
+
+if COND_i386_coreboot
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/coreboot/lbio.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
+endif
+
+if COND_i386_multiboot
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
+endif
+
+if COND_i386_qemu
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+endif
+
+if COND_i386_ieee1275
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+endif
+
+if COND_i386_xen
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
+endif
+
+if COND_x86_64_xen
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/x86_64/xen/hypercall.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
+endif
+
+if COND_x86_64_efi
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h
+endif
+
+if COND_ia64_efi
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
+endif
+
+if COND_mips
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/kernel.h
+endif
+
+if COND_mips_arc
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arc/arc.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
+endif
+
+if COND_mips_qemu_mips
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/serial.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
+endif
+
+if COND_mips_loongson
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/time.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cs5536.h
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pci.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/serial.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
+endif
+
+if COND_mips_qemu_mips
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+endif
+
+if COND_mips64_efi
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loongson.h
+endif
+
+if COND_powerpc_ieee1275
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
+endif
+
+if COND_sparc64_ieee1275
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sparc64/ieee1275/ieee1275.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
+endif
+
+if COND_arm_uboot
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/uboot/uboot.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/uboot/disk.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h
+endif
+
+if COND_arm_coreboot
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdt.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/dma.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/coreboot/kernel.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdtbus.h
+endif
+
+if COND_arm_efi
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
+endif
+
+if COND_arm64_efi
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
+endif
+
+if COND_riscv32_efi
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
+endif
+
+if COND_riscv64_efi
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
+endif
+
+if COND_emu
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/net.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/hostdisk.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/hostfile.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
+if COND_GRUB_EMU_SDL
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sdl.h
+endif
+if COND_GRUB_EMU_PCI
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libpciaccess.h
+endif
+endif
+
+symlist.h: $(top_builddir)/config.h $(KERNEL_HEADER_FILES)
+ @list='$^'; \
+ for p in $$list; do \
+ echo "#include <$$p>" >> $@ || (rm -f $@; exit 1); \
+ done
+CLEANFILES += symlist.h
+BUILT_SOURCES += symlist.h
+
+symlist.c: symlist.h gensymlist.sh
+ $(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) -DGRUB_SYMBOL_GENERATOR=1 symlist.h > symlist.p || (rm -f symlist.p; exit 1)
+ cat symlist.p | $(SHELL) $(srcdir)/gensymlist.sh $(top_builddir)/config.h $(KERNEL_HEADER_FILES) >$@ || (rm -f $@; exit 1)
+ rm -f symlist.p
+CLEANFILES += symlist.c
+BUILT_SOURCES += symlist.c
+
+if COND_HAVE_ASM_USCORE
+ASM_PREFIX=_
+else
+ASM_PREFIX=
+endif
+
+noinst_DATA += kernel_syms.lst
+
+kernel_syms.lst: $(KERNEL_HEADER_FILES) $(top_builddir)/config.h
+ $(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) $(CFLAGS) -DGRUB_SYMBOL_GENERATOR=1 $^ >kernel_syms.input
+ cat kernel_syms.input | grep -v '^#' | sed -n \
+ -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \
+ -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \
+ | sort -u >$@
+ rm -f kernel_syms.input
+CLEANFILES += kernel_syms.lst
+
+if COND_emu
+kern/emu/grub_emu-main.$(OBJEXT):grub_emu_init.h
+grub_emu-grub_emu_init.$(OBJEXT):grub_emu_init.h
+kern/emu/grub_emu_dyn-main.$(OBJEXT):grub_emu_init.h
+grub_emu_dyn-grub_emu_init.$(OBJEXT):grub_emu_init.h
+
+grub_emu_init.h: genemuinitheader.sh $(MODULE_FILES)
+ rm -f $@; echo $(MODULE_FILES) | sh $(srcdir)/genemuinitheader.sh $(TARGET_NM) > $@
+CLEANFILES += grub_emu_init.h
+
+grub_emu_init.c: grub_emu_init.h genemuinit.sh $(MODULE_FILES)
+ rm -f $@; echo $(MODULE_FILES) | sh $(srcdir)/genemuinit.sh $(TARGET_NM) > $@
+CLEANFILES += grub_emu_init.c
+endif
+
+# List files
+
+fs.lst: $(MARKER_FILES)
+ (for pp in $^; do \
+ b=`basename $$pp .marker`; \
+ if grep 'FS_LIST_MARKER' $$pp >/dev/null 2>&1; then \
+ echo $$b; \
+ fi; \
+ done) | sort -u > $@
+platform_DATA += fs.lst
+CLEANFILES += fs.lst
+
+command.lst: $(MARKER_FILES)
+ (for pp in $^; do \
+ b=`basename $$pp .marker`; \
+ sed -n \
+ -e "/EXTCOMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \
+ -e "/P1COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \
+ -e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \
+ done) | sort -u > $@
+platform_DATA += command.lst
+CLEANFILES += command.lst
+
+partmap.lst: $(MARKER_FILES)
+ (for pp in $^; do \
+ b=`basename $$pp .marker`; \
+ if grep 'PARTMAP_LIST_MARKER' $$pp >/dev/null 2>&1; then \
+ echo $$b; \
+ fi; \
+ done) | sort -u > $@
+platform_DATA += partmap.lst
+CLEANFILES += partmap.lst
+
+terminal.lst: $(MARKER_FILES)
+ (for pp in $^; do \
+ b=`basename $$pp .marker`; \
+ sed -n \
+ -e "/INPUT_TERMINAL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \
+ -e "/OUTPUT_TERMINAL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}" $$pp; \
+ done) | sort -u > $@
+platform_DATA += terminal.lst
+CLEANFILES += terminal.lst
+
+fdt.lst: $(MARKER_FILES)
+ (for pp in $^; do \
+ b=`basename $$pp .marker`; \
+ sed -n \
+ -e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \
+ -e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}" $$pp; \
+ done) | sort -u > $@
+platform_DATA += fdt.lst
+CLEANFILES += fdt.lst
+
+parttool.lst: $(MARKER_FILES)
+ (for pp in $^; do \
+ b=`basename $$pp .marker`; \
+ sed -n \
+ -e "/PARTTOOL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \
+ done) | sort -u > $@
+platform_DATA += parttool.lst
+CLEANFILES += parttool.lst
+
+video.lst: $(MARKER_FILES)
+ (for pp in $^; do \
+ b=`basename $$pp .marker`; \
+ if grep 'VIDEO_LIST_MARKER' $$pp >/dev/null 2>&1; then \
+ echo $$b; \
+ fi; \
+ done) | sort -u > $@
+platform_DATA += video.lst
+CLEANFILES += video.lst
+
+# but, crypto.lst is simply copied
+crypto.lst: $(srcdir)/lib/libgcrypt-grub/cipher/crypto.lst
+ cp $^ $@
+platform_DATA += crypto.lst
+CLEANFILES += crypto.lst
+
+syminfo.lst: gensyminfo.sh kernel_syms.lst $(MODULE_FILES)
+ cat kernel_syms.lst > $@.new
+ for m in $(MODULE_FILES); do \
+ sh $< $$m >> $@.new || exit 1; \
+ done
+ mv $@.new $@
+
+# generate global module dependencies list
+moddep.lst: syminfo.lst genmoddep.awk video.lst
+ cat $< | sort | $(AWK) -f $(srcdir)/genmoddep.awk > $@ || (rm -f $@; exit 1)
+platform_DATA += moddep.lst
+CLEANFILES += config.log syminfo.lst moddep.lst
+
+$(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT) build-grub-module-verifier$(BUILD_EXEEXT)
+ TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@
+platform_DATA += $(MOD_FILES)
+platform_DATA += modinfo.sh
+CLEANFILES += $(MOD_FILES)
+
+if COND_ENABLE_EFIEMU
+efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF)
+ -rm -f $@
+ -rm -f $@.bin
+ $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m32 -Wall -Werror -nostdlib -static -O2 -c -o $@.bin $<
+ if test "x$(TARGET_APPLE_LINKER)" = x1; then \
+ $(TARGET_OBJCONV) -felf32 -nu -nd $@.bin $@ || exit 1; \
+ rm -f $@.bin ; \
+ elif test ! -z "$(TARGET_OBJ2ELF)"; then \
+ $(TARGET_OBJ2ELF) $@.bin || (rm -f $@.bin; exit 1); \
+ mv $@.bin $@ ; \
+ else \
+ mv $@.bin $@ ; \
+ fi
+
+# Link format -arch,x86_64 means Apple linker
+efiemu64_c.o: efiemu/runtime/efiemu.c
+ $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -nostdlib -Wall -Werror -O2 -mcmodel=large -mno-red-zone -c -o $@ $<
+
+efiemu64_s.o: efiemu/runtime/efiemu.S
+ $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -Wall -Werror -nostdlib -O2 -mcmodel=large -mno-red-zone -c -o $@ $<
+
+efiemu64.o: efiemu64_c.o efiemu64_s.o $(TARGET_OBJ2ELEF)
+ -rm -f $@
+ -rm -f $@.bin
+ $(TARGET_CC) -m64 $(EFIEMU64_LINK_FORMAT) -nostdlib -static -Wl,-r -o $@.bin $^
+ if test "x$(EFIEMU64_LINK_FORMAT)" = x-arch,x86_64; then \
+ $(TARGET_OBJCONV) -felf64 -nu -nd $@.bin $@ || exit 1; \
+ rm -f $@.bin; \
+ else \
+ mv $@.bin $@ ; \
+ fi
+
+platform_DATA += efiemu32.o efiemu64.o
+CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o
+endif
+
+windowsdir=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows
+windowsdir: $(PROGRAMS) $(starfield_DATA) $(platform_DATA)
+ test -d $(windowsdir)/$(target_cpu)-$(platform) || mkdir $(windowsdir)/$(target_cpu)-$(platform)
+ for x in $(platform_DATA); do \
+ cp -fp $$x $(windowsdir)/$(target_cpu)-$(platform)/$$x; \
+ done
emu_cppflags = '$(CPPFLAGS_GNULIB)';
arm_uboot_ldflags = '-Wl,-r,-d';
arm_uboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
+
+ mips64_efi_ldflags = '-Wl,-r,-d';
+ mips64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame -R .MIPS.abiflags';
+
arm_coreboot_ldflags = '-Wl,-r,-d';
arm_coreboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
i386_coreboot_startup = kern/i386/coreboot/startup.S;
i386_multiboot_startup = kern/i386/coreboot/startup.S;
mips_startup = kern/mips/startup.S;
+ mips64_efi_startup = kern/mips64/efi/startup.S;
sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S;
powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S;
arm_uboot_startup = kern/arm/startup.S;
extra_dist = video/sis315_init.c;
mips_loongson = commands/keylayouts.c;
+ mips64 = kern/mips64/init.c;
+ mips64 = kern/mips64/dl.c;
+ mips64 = kern/mips64/cache.S;
+ mips64 = kern/generic/rtc_get_time_ms.c;
+ mips64_efi = kern/mips64/efi/init.c;
+ mips64_efi = kern/mips64/efi/loongson.c;
+ mips64_efi = lib/mips64/efi/loongson.c;
+ mips64_efi = lib/mips64/efi/loongson_asm.S;
+
powerpc_ieee1275 = kern/powerpc/cache.S;
powerpc_ieee1275 = kern/powerpc/dl.c;
powerpc_ieee1275 = kern/powerpc/compiler-rt.S;
enable = sparc64_ieee1275;
enable = powerpc_ieee1275;
enable = mips_arc;
+ enable = mips64_efi;
enable = ia64_efi;
enable = arm_efi;
enable = arm64_efi;
efi = lib/efi/relocator.c;
mips = lib/mips/relocator_asm.S;
mips = lib/mips/relocator.c;
+ mips64 = lib/mips64/relocator_asm.S;
+ mips64 = lib/mips64/relocator.c;
powerpc = lib/powerpc/relocator_asm.S;
powerpc = lib/powerpc/relocator.c;
xen = lib/xen/relocator.c;
extra_dist = kern/powerpc/cache_flush.S;
enable = mips;
+ enable = mips64;
enable = powerpc;
enable = x86;
enable = i386_xen_pvh;
i386_pc = lib/i386/pc/vesa_modes_table.c;
i386_xen_pvh = lib/i386/pc/vesa_modes_table.c;
mips = loader/mips/linux.c;
+ mips64 = loader/mips64/linux.c;
powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
ia64_efi = loader/ia64/efi/linux.c;
enable = riscv32_efi;
enable = riscv64_efi;
enable = mips;
+ enable = mips64_efi;
};
module = {
--- /dev/null
+/* mm.c - generic EFI memory management */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/cpu/efi/memory.h>
+
+#if defined (__i386__) || defined (__x86_64__)
+#include <grub/pci.h>
+#endif
+
+#define NEXT_MEMORY_DESCRIPTOR(desc, size) \
+ ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
+
+#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
+#define BYTES_TO_PAGES_DOWN(bytes) ((bytes) >> 12)
+#define PAGES_TO_BYTES(pages) ((pages) << 12)
+
+/* The size of a memory map obtained from the firmware. This must be
+ a multiplier of 4KB. */
+#define MEMORY_MAP_SIZE 0x3000
+
+/* The minimum and maximum heap size for GRUB itself. */
+#define MIN_HEAP_SIZE 0x100000
+#define MAX_HEAP_SIZE (1600 * 0x100000)
+
+static void *finish_mmap_buf = 0;
+static grub_efi_uintn_t finish_mmap_size = 0;
+static grub_efi_uintn_t finish_key = 0;
+static grub_efi_uintn_t finish_desc_size;
+static grub_efi_uint32_t finish_desc_version;
+int grub_efi_is_finished = 0;
+
+/*
+ * We need to roll back EFI allocations on exit. Remember allocations that
+ * we'll free on exit.
+ */
+struct efi_allocation;
+struct efi_allocation {
+ grub_efi_physical_address_t address;
+ grub_efi_uint64_t pages;
+ struct efi_allocation *next;
+};
+static struct efi_allocation *efi_allocated_memory;
+
+static void
+grub_efi_store_alloc (grub_efi_physical_address_t address,
+ grub_efi_uintn_t pages)
+{
+ grub_efi_boot_services_t *b;
+ struct efi_allocation *alloc;
+ grub_efi_status_t status;
+
+ b = grub_efi_system_table->boot_services;
+ status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA,
+ sizeof(*alloc), (void**)&alloc);
+
+ if (status == GRUB_EFI_SUCCESS)
+ {
+ alloc->next = efi_allocated_memory;
+ alloc->address = address;
+ alloc->pages = pages;
+ efi_allocated_memory = alloc;
+ }
+ else
+ grub_printf ("Could not malloc memory to remember EFI allocation. "
+ "Exiting GRUB won't free all memory.\n");
+}
+
+static void
+grub_efi_drop_alloc (grub_efi_physical_address_t address,
+ grub_efi_uintn_t pages)
+{
+ struct efi_allocation *ea, *eap;
+ grub_efi_boot_services_t *b;
+
+ b = grub_efi_system_table->boot_services;
+
+ for (eap = NULL, ea = efi_allocated_memory; ea; eap = ea, ea = ea->next)
+ {
+ if (ea->address != address || ea->pages != pages)
+ continue;
+
+ /* Remove the current entry from the list. */
+ if (eap)
+ eap->next = ea->next;
+ else
+ efi_allocated_memory = ea->next;
+
+ /* Then free the memory backing it. */
+ efi_call_1 (b->free_pool, ea);
+
+ /* And leave, we're done. */
+ break;
+ }
+}
+
+/* Allocate pages. Return the pointer to the first of allocated pages. */
+void *
+grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
+ grub_efi_uintn_t pages,
+ grub_efi_allocate_type_t alloctype,
+ grub_efi_memory_type_t memtype)
+{
+ grub_efi_status_t status;
+ grub_efi_boot_services_t *b;
+
+ /* Limit the memory access to less than 4GB for 32-bit platforms. */
+ if (address > GRUB_EFI_MAX_USABLE_ADDRESS)
+ return 0;
+
+ b = grub_efi_system_table->boot_services;
+ status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
+ if (status != GRUB_EFI_SUCCESS)
+ return 0;
+
+ if (address == 0)
+ {
+ /* Uggh, the address 0 was allocated... This is too annoying,
+ so reallocate another one. */
+ address = GRUB_EFI_MAX_USABLE_ADDRESS;
+ status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
+ grub_efi_free_pages (0, pages);
+ if (status != GRUB_EFI_SUCCESS)
+ return 0;
+ }
+
+ grub_efi_store_alloc (address, pages);
+
+ return (void *) ((grub_addr_t) address);
+}
+
+void *
+grub_efi_allocate_any_pages (grub_efi_uintn_t pages)
+{
+ return grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS,
+ pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS,
+ GRUB_EFI_LOADER_DATA);
+}
+
+void *
+grub_efi_allocate_fixed (grub_efi_physical_address_t address,
+ grub_efi_uintn_t pages)
+{
+ return grub_efi_allocate_pages_real (address, pages,
+ GRUB_EFI_ALLOCATE_ADDRESS,
+ GRUB_EFI_LOADER_DATA);
+}
+
+/* Free pages starting from ADDRESS. */
+void
+grub_efi_free_pages (grub_efi_physical_address_t address,
+ grub_efi_uintn_t pages)
+{
+ grub_efi_boot_services_t *b;
+
+ b = grub_efi_system_table->boot_services;
+ efi_call_2 (b->free_pages, address, pages);
+
+ grub_efi_drop_alloc (address, pages);
+}
+
+#if defined (__i386__) || defined (__x86_64__)
+
+/* Helper for stop_broadcom. */
+static int
+find_card (grub_pci_device_t dev, grub_pci_id_t pciid,
+ void *data __attribute__ ((unused)))
+{
+ grub_pci_address_t addr;
+ grub_uint8_t cap;
+ grub_uint16_t pm_state;
+
+ if ((pciid & 0xffff) != GRUB_PCI_VENDOR_BROADCOM)
+ return 0;
+
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+ if (grub_pci_read (addr) >> 24 != GRUB_PCI_CLASS_NETWORK)
+ return 0;
+ cap = grub_pci_find_capability (dev, GRUB_PCI_CAP_POWER_MANAGEMENT);
+ if (!cap)
+ return 0;
+ addr = grub_pci_make_address (dev, cap + 4);
+ pm_state = grub_pci_read_word (addr);
+ pm_state = pm_state | 0x03;
+ grub_pci_write_word (addr, pm_state);
+ grub_pci_read_word (addr);
+ return 0;
+}
+
+static void
+stop_broadcom (void)
+{
+ grub_pci_iterate (find_card, NULL);
+}
+
+#endif
+
+grub_err_t
+grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf,
+ grub_efi_uintn_t *map_key,
+ grub_efi_uintn_t *efi_desc_size,
+ grub_efi_uint32_t *efi_desc_version)
+{
+ grub_efi_boot_services_t *b;
+ grub_efi_status_t status;
+
+#if defined (__i386__) || defined (__x86_64__)
+ const grub_uint16_t apple[] = { 'A', 'p', 'p', 'l', 'e' };
+ int is_apple;
+
+ is_apple = (grub_memcmp (grub_efi_system_table->firmware_vendor,
+ apple, sizeof (apple)) == 0);
+#endif
+
+ while (1)
+ {
+ if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key,
+ &finish_desc_size, &finish_desc_version) < 0)
+ return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
+
+ if (outbuf && *outbuf_size < finish_mmap_size)
+ return grub_error (GRUB_ERR_IO, "memory map buffer is too small");
+
+ finish_mmap_buf = grub_malloc (finish_mmap_size);
+ if (!finish_mmap_buf)
+ return grub_errno;
+
+ if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key,
+ &finish_desc_size, &finish_desc_version) <= 0)
+ {
+ grub_free (finish_mmap_buf);
+ return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
+ }
+
+ b = grub_efi_system_table->boot_services;
+ status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle,
+ finish_key);
+ if (status == GRUB_EFI_SUCCESS)
+ break;
+
+ if (status != GRUB_EFI_INVALID_PARAMETER)
+ {
+ grub_free (finish_mmap_buf);
+ return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services");
+ }
+
+ grub_free (finish_mmap_buf);
+ grub_printf ("Trying to terminate EFI services again\n");
+ }
+ grub_efi_is_finished = 1;
+ if (outbuf_size)
+ *outbuf_size = finish_mmap_size;
+ if (outbuf)
+ grub_memcpy (outbuf, finish_mmap_buf, finish_mmap_size);
+ if (map_key)
+ *map_key = finish_key;
+ if (efi_desc_size)
+ *efi_desc_size = finish_desc_size;
+ if (efi_desc_version)
+ *efi_desc_version = finish_desc_version;
+
+#if defined (__i386__) || defined (__x86_64__)
+ if (is_apple)
+ stop_broadcom ();
+#endif
+
+ return GRUB_ERR_NONE;
+}
+
+/*
+ * To obtain the UEFI memory map, we must pass a buffer of sufficient size
+ * to hold the entire map. This function returns a sane start value for
+ * buffer size.
+ */
+grub_efi_uintn_t
+grub_efi_find_mmap_size (void)
+{
+ grub_efi_uintn_t mmap_size = 0;
+ grub_efi_uintn_t desc_size;
+
+ if (grub_efi_get_memory_map (&mmap_size, NULL, NULL, &desc_size, 0) < 0)
+ {
+ grub_error (GRUB_ERR_IO, "cannot get EFI memory map size");
+ return 0;
+ }
+
+ /*
+ * Add an extra page, since UEFI can alter the memory map itself on
+ * callbacks or explicit calls, including console output.
+ */
+ return ALIGN_UP (mmap_size + GRUB_EFI_PAGE_SIZE, GRUB_EFI_PAGE_SIZE);
+}
+
+/* Get the memory map as defined in the EFI spec. Return 1 if successful,
+ return 0 if partial, or return -1 if an error occurs. */
+int
+grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size,
+ grub_efi_memory_descriptor_t *memory_map,
+ grub_efi_uintn_t *map_key,
+ grub_efi_uintn_t *descriptor_size,
+ grub_efi_uint32_t *descriptor_version)
+{
+ grub_efi_status_t status;
+ grub_efi_boot_services_t *b;
+ grub_efi_uintn_t key;
+ grub_efi_uint32_t version;
+ grub_efi_uintn_t size;
+
+ if (grub_efi_is_finished)
+ {
+ int ret = 1;
+ if (*memory_map_size < finish_mmap_size)
+ {
+ grub_memcpy (memory_map, finish_mmap_buf, *memory_map_size);
+ ret = 0;
+ }
+ else
+ {
+ grub_memcpy (memory_map, finish_mmap_buf, finish_mmap_size);
+ ret = 1;
+ }
+ *memory_map_size = finish_mmap_size;
+ if (map_key)
+ *map_key = finish_key;
+ if (descriptor_size)
+ *descriptor_size = finish_desc_size;
+ if (descriptor_version)
+ *descriptor_version = finish_desc_version;
+ return ret;
+ }
+
+ /* Allow some parameters to be missing. */
+ if (! map_key)
+ map_key = &key;
+ if (! descriptor_version)
+ descriptor_version = &version;
+ if (! descriptor_size)
+ descriptor_size = &size;
+
+ b = grub_efi_system_table->boot_services;
+ status = efi_call_5 (b->get_memory_map, memory_map_size, memory_map, map_key,
+ descriptor_size, descriptor_version);
+ if (*descriptor_size == 0)
+ *descriptor_size = sizeof (grub_efi_memory_descriptor_t);
+ if (status == GRUB_EFI_SUCCESS)
+ return 1;
+ else if (status == GRUB_EFI_BUFFER_TOO_SMALL)
+ return 0;
+ else
+ return -1;
+}
+
+/* Sort the memory map in place. */
+static void
+sort_memory_map (grub_efi_memory_descriptor_t *memory_map,
+ grub_efi_uintn_t desc_size,
+ grub_efi_memory_descriptor_t *memory_map_end)
+{
+ grub_efi_memory_descriptor_t *d1;
+ grub_efi_memory_descriptor_t *d2;
+
+ for (d1 = memory_map;
+ d1 < memory_map_end;
+ d1 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size))
+ {
+ grub_efi_memory_descriptor_t *max_desc = d1;
+
+ for (d2 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size);
+ d2 < memory_map_end;
+ d2 = NEXT_MEMORY_DESCRIPTOR (d2, desc_size))
+ {
+ if (max_desc->num_pages < d2->num_pages)
+ max_desc = d2;
+ }
+
+ if (max_desc != d1)
+ {
+ grub_efi_memory_descriptor_t tmp;
+
+ tmp = *d1;
+ *d1 = *max_desc;
+ *max_desc = tmp;
+ }
+ }
+}
+
+/* Filter the descriptors. GRUB needs only available memory. */
+static grub_efi_memory_descriptor_t *
+filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
+ grub_efi_memory_descriptor_t *filtered_memory_map,
+ grub_efi_uintn_t desc_size,
+ grub_efi_memory_descriptor_t *memory_map_end)
+{
+ grub_efi_memory_descriptor_t *desc;
+ grub_efi_memory_descriptor_t *filtered_desc;
+
+ for (desc = memory_map, filtered_desc = filtered_memory_map;
+ desc < memory_map_end;
+ desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+ {
+ if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
+#if 1
+ && desc->physical_start <= GRUB_EFI_MAX_USABLE_ADDRESS
+#endif
+ && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000
+ && desc->num_pages != 0)
+ {
+ grub_memcpy (filtered_desc, desc, desc_size);
+
+ /* Avoid less than 1MB, because some loaders seem to be confused. */
+ if (desc->physical_start < 0x100000)
+ {
+ desc->num_pages -= BYTES_TO_PAGES (0x100000
+ - desc->physical_start);
+ desc->physical_start = 0x100000;
+ }
+
+#if 1
+ if (BYTES_TO_PAGES (filtered_desc->physical_start)
+ + filtered_desc->num_pages
+ > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS))
+ filtered_desc->num_pages
+ = (BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS)
+ - BYTES_TO_PAGES (filtered_desc->physical_start));
+#endif
+
+ if (filtered_desc->num_pages == 0)
+ continue;
+
+ filtered_desc = NEXT_MEMORY_DESCRIPTOR (filtered_desc, desc_size);
+ }
+ }
+
+ return filtered_desc;
+}
+
+/* Return the total number of pages. */
+static grub_efi_uint64_t
+get_total_pages (grub_efi_memory_descriptor_t *memory_map,
+ grub_efi_uintn_t desc_size,
+ grub_efi_memory_descriptor_t *memory_map_end)
+{
+ grub_efi_memory_descriptor_t *desc;
+ grub_efi_uint64_t total = 0;
+
+ for (desc = memory_map;
+ desc < memory_map_end;
+ desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+ total += desc->num_pages;
+
+ return total;
+}
+
+/* Add memory regions. */
+static void
+add_memory_regions (grub_efi_memory_descriptor_t *memory_map,
+ grub_efi_uintn_t desc_size,
+ grub_efi_memory_descriptor_t *memory_map_end,
+ grub_efi_uint64_t required_pages)
+{
+ grub_efi_memory_descriptor_t *desc;
+
+ for (desc = memory_map;
+ desc < memory_map_end;
+ desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+ {
+ grub_efi_uint64_t pages;
+ grub_efi_physical_address_t start;
+ void *addr;
+
+ start = desc->physical_start;
+ pages = desc->num_pages;
+ if (pages > required_pages)
+ {
+ start += PAGES_TO_BYTES (pages - required_pages);
+ pages = required_pages;
+ }
+
+ addr = grub_efi_allocate_pages_real (start, pages,
+ GRUB_EFI_ALLOCATE_ADDRESS,
+ GRUB_EFI_LOADER_CODE);
+ if (! addr)
+ grub_fatal ("cannot allocate conventional memory %p with %u pages",
+ (void *) ((grub_addr_t) start),
+ (unsigned) pages);
+
+ grub_mm_init_region (addr, PAGES_TO_BYTES (pages));
+
+ required_pages -= pages;
+ if (required_pages == 0)
+ break;
+ }
+
+ if (required_pages > 0)
+ grub_fatal ("too little memory");
+}
+
+void
+grub_efi_memory_fini (void)
+{
+ /*
+ * Free all stale allocations. grub_efi_free_pages() will remove
+ * the found entry from the list and it will always find the first
+ * list entry (efi_allocated_memory is the list start). Hence we
+ * remove all entries from the list until none is left altogether.
+ */
+ while (efi_allocated_memory)
+ grub_efi_free_pages (efi_allocated_memory->address,
+ efi_allocated_memory->pages);
+}
+
+#if 0
+/* Print the memory map. */
+static void
+print_memory_map (grub_efi_memory_descriptor_t *memory_map,
+ grub_efi_uintn_t desc_size,
+ grub_efi_memory_descriptor_t *memory_map_end)
+{
+ grub_efi_memory_descriptor_t *desc;
+ int i;
+
+ for (desc = memory_map, i = 0;
+ desc < memory_map_end;
+ desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size), i++)
+ {
+ grub_printf ("MD: t=%x, p=%llx, v=%llx, n=%llx, a=%llx\n",
+ desc->type, desc->physical_start, desc->virtual_start,
+ desc->num_pages, desc->attribute);
+ }
+}
+#endif
+
+void
+grub_efi_mm_init (void)
+{
+ grub_efi_memory_descriptor_t *memory_map;
+ grub_efi_memory_descriptor_t *memory_map_end;
+ grub_efi_memory_descriptor_t *filtered_memory_map;
+ grub_efi_memory_descriptor_t *filtered_memory_map_end;
+ grub_efi_uintn_t map_size;
+ grub_efi_uintn_t desc_size;
+ grub_efi_uint64_t total_pages;
+ grub_efi_uint64_t required_pages;
+ int mm_status;
+
+ /* Prepare a memory region to store two memory maps. */
+ memory_map = grub_efi_allocate_any_pages (2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
+ if (! memory_map)
+ grub_fatal ("cannot allocate memory");
+
+ /* Obtain descriptors for available memory. */
+ map_size = MEMORY_MAP_SIZE;
+
+ mm_status = grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0);
+
+ if (mm_status == 0)
+ {
+ grub_efi_free_pages
+ ((grub_efi_physical_address_t) ((grub_addr_t) memory_map),
+ 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
+
+ /* Freeing/allocating operations may increase memory map size. */
+ map_size += desc_size * 32;
+
+ memory_map = grub_efi_allocate_any_pages (2 * BYTES_TO_PAGES (map_size));
+ if (! memory_map)
+ grub_fatal ("cannot allocate memory");
+
+ mm_status = grub_efi_get_memory_map (&map_size, memory_map, 0,
+ &desc_size, 0);
+ }
+
+ if (mm_status < 0)
+ grub_fatal ("cannot get memory map");
+
+ memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size);
+
+ filtered_memory_map = memory_map_end;
+
+ filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map,
+ desc_size, memory_map_end);
+
+ /* By default, request a quarter of the available memory. */
+ total_pages = get_total_pages (filtered_memory_map, desc_size,
+ filtered_memory_map_end);
+
+ #if defined (__mips__) && (_MIPS_SIM == _ABI64)
+ required_pages = (total_pages > 4096) ? (total_pages - 4096) : (total_pages >> 1);
+ #else
+ required_pages = (total_pages >> 2);
+ #endif
+
+ if (required_pages < BYTES_TO_PAGES (MIN_HEAP_SIZE))
+ required_pages = BYTES_TO_PAGES (MIN_HEAP_SIZE);
+ else if (required_pages > BYTES_TO_PAGES (MAX_HEAP_SIZE))
+ required_pages = BYTES_TO_PAGES (MAX_HEAP_SIZE);
+
+ /* Sort the filtered descriptors, so that GRUB can allocate pages
+ from smaller regions. */
+ sort_memory_map (filtered_memory_map, desc_size, filtered_memory_map_end);
+
+ /* Allocate memory regions for GRUB's memory management. */
+ add_memory_regions (filtered_memory_map, desc_size,
+ filtered_memory_map_end, required_pages);
+
+#if 0
+ /* For debug. */
+ map_size = MEMORY_MAP_SIZE;
+
+ if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0)
+ grub_fatal ("cannot get memory map");
+
+ grub_printf ("printing memory map\n");
+ print_memory_map (memory_map, desc_size,
+ NEXT_MEMORY_DESCRIPTOR (memory_map, map_size));
+ grub_fatal ("Debug. ");
+#endif
+
+ /* Release the memory maps. */
+ grub_efi_free_pages ((grub_addr_t) memory_map,
+ 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
+}
+
+#if defined (__aarch64__) || defined (__arm__) || defined (__riscv)
+grub_err_t
+grub_efi_get_ram_base(grub_addr_t *base_addr)
+{
+ grub_efi_memory_descriptor_t *memory_map, *desc;
+ grub_efi_uintn_t memory_map_size, desc_size;
+ int ret;
+
+ memory_map_size = grub_efi_find_mmap_size();
+
+ memory_map = grub_malloc (memory_map_size);
+ if (! memory_map)
+ return GRUB_ERR_OUT_OF_MEMORY;
+ ret = grub_efi_get_memory_map (&memory_map_size, memory_map, NULL,
+ &desc_size, NULL);
+
+ if (ret < 1)
+ return GRUB_ERR_BUG;
+
+ for (desc = memory_map, *base_addr = GRUB_EFI_MAX_USABLE_ADDRESS;
+ (grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size);
+ desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+ if (desc->attribute & GRUB_EFI_MEMORY_WB)
+ *base_addr = grub_min (*base_addr, desc->physical_start);
+
+ grub_free(memory_map);
+
+ return GRUB_ERR_NONE;
+}
+#endif
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009,2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+FUNCTION (grub_arch_sync_caches)
+ jr.hb $ra
+
--- /dev/null
+/* dl-mips64.c - arch-dependent part of loadable module support */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2005,2007,2009,2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/cpu/types.h>
+#include <grub/mm.h>
+#include <grub/i18n.h>
+
+/* Check if EHDR is a valid ELF header. */
+grub_err_t
+grub_arch_dl_check_header (void *ehdr)
+{
+ Elf_Ehdr *e = ehdr;
+
+ /* Check the magic numbers. */
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
+ if (e->e_ident[EI_CLASS] != ELFCLASS64
+ || e->e_ident[EI_DATA] != ELFDATA2MSB
+ || e->e_machine != EM_MIPS)
+#else
+ if (e->e_ident[EI_CLASS] != ELFCLASS64
+ || e->e_ident[EI_DATA] != ELFDATA2LSB
+ || e->e_machine != EM_MIPS)
+#endif
+ return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic"));
+
+ return GRUB_ERR_NONE;
+}
+
+#pragma GCC diagnostic ignored "-Wcast-align"
+
+grub_err_t
+grub_arch_dl_get_tramp_got_size (const void *ehdr __attribute__ ((unused)),
+ grub_size_t *tramp, grub_size_t *got)
+{
+ *tramp = 0;
+ *got = 0;
+ return GRUB_ERR_NONE;
+}
+
+/* Relocate symbols. */
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
+ Elf_Shdr *s, grub_dl_segment_t seg)
+{
+ Elf_Ehdr *e = ehdr;
+ Elf_Rel *rel, *max;
+
+ for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
+ max = (Elf_Rel *) ((char *) rel + s->sh_size);
+ rel < max;
+ rel = (Elf_Rel *) ((char *) rel + s->sh_entsize))
+ {
+ grub_uint8_t *addr;
+ Elf_Sym *sym;
+ Elf_Addr r_info;
+ grub_uint64_t sym_value;
+
+ if (seg->size < rel->r_offset)
+ return grub_error (GRUB_ERR_BAD_MODULE,
+ "reloc offset is out of the segment");
+
+ r_info = ((grub_uint64_t) rel->r_info << 32) |
+ (grub_uint32_t) grub_be_to_cpu64 (rel->r_info);
+
+ addr = (grub_uint8_t *) ((char *) seg->addr + rel->r_offset);
+ sym = (Elf_Sym *) ((char *) mod->symtab
+ + mod->symsize * ELF_R_SYM (r_info));
+ sym_value = sym->st_value;
+ if (s->sh_type == SHT_RELA)
+ {
+ sym_value += ((Elf_Rela *) rel)->r_addend;
+ }
+ switch (ELF_R_TYPE (r_info))
+ {
+ case R_MIPS_64:
+ *(grub_uint64_t *) addr += sym_value;
+ break;
+ case R_MIPS_32:
+ *(grub_uint32_t *) addr += sym_value;
+ break;
+ case R_MIPS_26:
+ {
+ grub_uint32_t value;
+ grub_uint32_t raw;
+ raw = (*(grub_uint32_t *) addr) & 0x3ffffff;
+ value = raw << 2;
+ value += sym_value;
+ raw = (value >> 2) & 0x3ffffff;
+
+ *(grub_uint32_t *) addr =
+ raw | ((*(grub_uint32_t *) addr) & 0xfc000000);
+ }
+ break;
+ case R_MIPS_LO16:
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
+ addr += 2;
+#endif
+ *(grub_uint16_t *) addr = (grub_int16_t) sym_value;
+ break;
+ case R_MIPS_HI16:
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
+ addr += 2;
+#endif
+ *(grub_uint16_t *) addr = (grub_int16_t) ((sym_value + 0x8000UL) >> 16);
+ break;
+ case R_MIPS_HIGHER:
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
+ addr += 2;
+#endif
+ *(grub_uint16_t *) addr = (grub_int16_t) ((sym_value + 0x80008000UL) >> 32);
+ break;
+ case R_MIPS_HIGHEST:
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
+ addr += 2;
+#endif
+ *(grub_uint16_t *) addr = (grub_uint16_t) ((sym_value + 0x800080008000UL) >> 48);
+ break;
+ default:
+ {
+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+ N_("relocation 0x%x is not implemented yet"),
+ ELF_R_TYPE (r_info));
+ }
+ break;
+ }
+ }
+
+ return GRUB_ERR_NONE;
+}
+
--- /dev/null
+/* init.c - initialize an arm-based EFI system */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/env.h>
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/cpu/time.h>
+#include <grub/efi/efi.h>
+#include <grub/loader.h>
+#include <grub/time.h>
+#include <grub/machine/loongson.h>
+
+static grub_uint64_t tmr;
+static grub_efi_event_t tmr_evt;
+
+static grub_uint64_t
+grub_efi_get_time_ms (void)
+{
+ return tmr;
+}
+
+static void
+grub_loongson_increment_timer (grub_efi_event_t event __attribute__ ((unused)),
+ void *context __attribute__ ((unused)))
+{
+ tmr += 10;
+}
+
+
+
+void
+grub_machine_init (void)
+{
+ grub_efi_boot_services_t *b;
+
+ grub_efi_init ();
+
+ b = grub_efi_system_table->boot_services;
+ efi_call_5 (b->create_event, GRUB_EFI_EVT_TIMER | GRUB_EFI_EVT_NOTIFY_SIGNAL,
+ GRUB_EFI_TPL_CALLBACK, grub_loongson_increment_timer, NULL, &tmr_evt);
+ efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_PERIODIC, 100000);
+
+ grub_install_get_time_ms (grub_efi_get_time_ms);
+
+ if (grub_efi_is_loongson ())
+ grub_efi_loongson_init ();
+ else
+ /* FIXME: Get cpuclock from EFI. */
+ grub_timer_init (1000000000U);
+}
+
+void
+grub_machine_fini (int flags)
+{
+ grub_efi_boot_services_t *b;
+
+ if (!(flags & GRUB_LOADER_FLAG_NORETURN))
+ return;
+
+ b = grub_efi_system_table->boot_services;
+
+ efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_CANCEL, 0);
+ efi_call_1 (b->close_event, tmr_evt);
+
+ if (grub_efi_is_loongson ())
+ grub_efi_loongson_fini ();
+ grub_efi_fini ();
+}
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/efi/efi.h>
+#include <grub/cpu/time.h>
+#include <grub/loader.h>
+#include <grub/machine/loongson.h>
+
+void
+grub_efi_loongson_init (void)
+{
+}
+
+void
+grub_efi_loongson_fini (void)
+{
+}
+
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+ .file "startup.S"
+ .text
+
+ .set push
+ .align 4
+
+FUNCTION(_start)
+ /*
+ * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in a1/a0.
+ */
+ daddiu $sp, -16
+ sd $ra, ($sp)
+
+ dla $a2, grub_efi_image_handle
+ sd $a0, ($a2)
+ dla $a2, grub_efi_system_table
+ sd $a1, ($a2)
+
+ jal grub_main
+
+1:
+ ld $ra, ($sp)
+ daddiu $sp, 16
+ jr $ra
+
+ .set pop
+
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009,2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/env.h>
+#include <grub/time.h>
+#include <grub/cpu/mips.h>
+
+grub_uint32_t grub_arch_cpuclock;
+
+/* FIXME: use interrupt to count high. */
+grub_uint64_t
+grub_get_rtc (void)
+{
+ static grub_uint32_t high = 0;
+ static grub_uint32_t last = 0;
+ grub_uint32_t low;
+
+ asm volatile ("mfc0 %0, " GRUB_CPU_MIPS_COP0_TIMER_COUNT : "=r" (low));
+ if (low < last)
+ high++;
+ last = low;
+
+ return (((grub_uint64_t) high) << 32) | low;
+}
+
+void
+grub_timer_init (grub_uint32_t cpuclock)
+{
+ grub_arch_cpuclock = cpuclock;
+ grub_install_get_time_ms (grub_rtc_get_time_ms);
+}
--- /dev/null
+/* efi.c - generic EFI support */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/kernel.h>
+#include <grub/acpi.h>
+#include <grub/loader.h>
+
+void
+grub_halt (void)
+{
+ grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
+#if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) && !defined(__mips__) &&\
+ !defined(__riscv)
+ grub_acpi_halt ();
+#endif
+ efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
+ GRUB_EFI_RESET_SHUTDOWN, GRUB_EFI_SUCCESS, 0, NULL);
+
+ while (1);
+}
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/cache.h>
+#include <grub/efi/efi.h>
+#include <grub/cpu/efi/memory.h>
+#include <grub/cpu/memory.h>
+#include <grub/machine/loongson.h>
+
+#pragma GCC diagnostic ignored "-Wunused-function"
+
+#define loongson_params (&loongson_boot_params->boot_params.efi.smbios.lp)
+#define loongson_boot_params_size ALIGN_UP (sizeof (*loongson_boot_params), 8)
+#define loongson_reset_code_size (&grub_efi_loongson_reset_end - &grub_efi_loongson_reset_start)
+
+extern grub_uint8_t grub_efi_loongson_reset_start;
+extern grub_uint8_t grub_efi_loongson_reset_end;
+
+static struct
+{
+ grub_efi_loongson_boot_params boot_params;
+ grub_efi_loongson_memory_map memory_map;
+ grub_efi_loongson_cpu_info cpu_info;
+ grub_efi_loongson_system_info system_info;
+ grub_efi_loongson_irq_src_routing_table irq_src_routing_table;
+ grub_efi_loongson_interface_info interface_info;
+ grub_efi_loongson_special_attribute special_attribute;
+ grub_efi_loongson_board_devices board_devices;
+} GRUB_PACKED
+* loongson_boot_params;
+
+static void
+grub_efi_loongson_init_reset_system (void)
+{
+ grub_efi_loongson_boot_params *boot_params;
+ grub_uint8_t *reset_code_addr = (grub_uint8_t *) loongson_boot_params +
+ loongson_boot_params_size;
+
+ boot_params = &loongson_boot_params->boot_params;
+ grub_efi_loongson_reset_system_addr =
+ (grub_uint64_t) grub_efi_system_table->runtime_services->reset_system;
+ grub_memcpy (reset_code_addr, &grub_efi_loongson_reset_start, loongson_reset_code_size);
+ grub_arch_sync_caches (reset_code_addr, loongson_reset_code_size);
+
+ boot_params->reset_system.reset_cold = (grub_uint64_t) reset_code_addr +
+ ((grub_uint64_t) &grub_efi_loongson_reset_cold -
+ (grub_uint64_t) &grub_efi_loongson_reset_start);
+ boot_params->reset_system.reset_warm = (grub_uint64_t) reset_code_addr +
+ ((grub_uint64_t) &grub_efi_loongson_reset_warm -
+ (grub_uint64_t) &grub_efi_loongson_reset_start);
+ boot_params->reset_system.shutdown = (grub_uint64_t) reset_code_addr +
+ ((grub_uint64_t) &grub_efi_loongson_reset_shutdown -
+ (grub_uint64_t) &grub_efi_loongson_reset_start);
+ boot_params->reset_system.do_suspend = (grub_uint64_t) reset_code_addr +
+ ((grub_uint64_t) &grub_efi_loongson_reset_suspend -
+ (grub_uint64_t) &grub_efi_loongson_reset_start);
+}
+
+static void
+grub_efi_loongson_init_smbios (grub_efi_loongson_smbios_table *smbios_table)
+{
+ grub_efi_loongson_smbios_table *dst = &loongson_boot_params->boot_params.efi.smbios;
+
+ dst->vers = smbios_table->vers;
+ dst->vga_bios = smbios_table->vga_bios;
+}
+
+static void
+grub_efi_loongson_init_cpu_info (grub_efi_loongson_smbios_table *smbios_table)
+{
+ grub_efi_loongson_cpu_info *src = (void *) smbios_table->lp.cpu_offset;
+ grub_efi_loongson_cpu_info *dst = &loongson_boot_params->cpu_info;
+
+ if (!src)
+ return;
+
+ grub_memcpy (dst, src, sizeof (grub_efi_loongson_cpu_info));
+ loongson_params->cpu_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params;
+}
+
+static void
+grub_efi_loongson_init_system_info (grub_efi_loongson_smbios_table *smbios_table)
+{
+ grub_efi_loongson_system_info *src = (void *) smbios_table->lp.system_offset;
+ grub_efi_loongson_system_info *dst = &loongson_boot_params->system_info;
+
+ if (!src)
+ return;
+
+ grub_memcpy (dst, src, sizeof (grub_efi_loongson_system_info));
+ loongson_params->system_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params;
+}
+
+static void
+grub_efi_loongson_init_irq_src_routing_table (grub_efi_loongson_smbios_table *smbios_table)
+{
+ grub_efi_loongson_irq_src_routing_table *src = (void *) smbios_table->lp.irq_offset;
+ grub_efi_loongson_irq_src_routing_table *dst = &loongson_boot_params->irq_src_routing_table;
+
+ if (!src)
+ return;
+
+ grub_memcpy (dst, src, sizeof (grub_efi_loongson_irq_src_routing_table));
+ loongson_params->irq_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params;
+}
+
+static void
+grub_efi_loongson_init_interface_info (grub_efi_loongson_smbios_table *smbios_table)
+{
+ grub_efi_loongson_interface_info *src = (void *) smbios_table->lp.interface_offset;
+ grub_efi_loongson_interface_info *dst = &loongson_boot_params->interface_info;
+
+ if (!src)
+ return;
+
+ grub_memcpy (dst, src, sizeof (grub_efi_loongson_interface_info));
+ loongson_params->interface_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params;
+}
+
+static void
+grub_efi_loongson_init_special_attribute (grub_efi_loongson_smbios_table *smbios_table)
+{
+ grub_efi_loongson_special_attribute *src = (void *) smbios_table->lp.special_offset;
+ grub_efi_loongson_special_attribute *dst = &loongson_boot_params->special_attribute;
+
+ if (!src)
+ return;
+
+ grub_memcpy (dst, src, sizeof (grub_efi_loongson_special_attribute));
+ loongson_params->special_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params;
+}
+
+static void
+grub_efi_loongson_init_board_devices (grub_efi_loongson_smbios_table *smbios_table)
+{
+ grub_efi_loongson_board_devices *src = (void *) smbios_table->lp.boarddev_table_offset;
+ grub_efi_loongson_board_devices *dst = &loongson_boot_params->board_devices;
+
+ if (!src)
+ return;
+
+ grub_memcpy (dst, src, sizeof (grub_efi_loongson_board_devices));
+ loongson_params->boarddev_table_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params;
+}
+
+#define ADD_MEMORY_DESCRIPTOR(desc, size) \
+ ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
+
+static void
+grub_efi_loongson_init_memory_map (grub_efi_loongson_smbios_table *smbios_table,
+ grub_efi_memory_descriptor_t *mmap_buf,
+ grub_efi_uintn_t mmap_size,
+ grub_efi_uintn_t desc_size)
+{
+ grub_efi_loongson_memory_map *src = (void *) smbios_table->lp.memory_offset;
+ grub_efi_loongson_memory_map *dst = &loongson_boot_params->memory_map;
+ grub_efi_memory_descriptor_t *mmap_end;
+ grub_efi_memory_descriptor_t *desc;
+ grub_efi_memory_descriptor_t *desc_next;
+ grub_efi_uint32_t mem_types_reserved[] =
+ {
+ 1, // GRUB_EFI_RESERVED_MEMORY_TYPE
+ 0, // GRUB_EFI_LOADER_CODE
+ 0, // GRUB_EFI_LOADER_DATA
+ 0, // GRUB_EFI_BOOT_SERVICES_CODE
+ 0, // GRUB_EFI_BOOT_SERVICES_DATA
+ 1, // GRUB_EFI_RUNTIME_SERVICES_CODE
+ 1, // GRUB_EFI_RUNTIME_SERVICES_DATA
+ 0, // GRUB_EFI_CONVENTIONAL_MEMORY
+ 1, // GRUB_EFI_UNUSABLE_MEMORY
+ 0, // GRUB_EFI_ACPI_RECLAIM_MEMORY
+ 0, // GRUB_EFI_ACPI_MEMORY_NVS
+ 1, // GRUB_EFI_MEMORY_MAPPED_IO
+ 1, // GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE
+ 1, // GRUB_EFI_PAL_CODE
+ 1, // GRUB_EFI_PERSISTENT_MEMORY
+ };
+ grub_uint32_t need_sort = 1;
+
+ if (!src)
+ return;
+
+ dst->vers = src->vers;
+ dst->nr_map = 0;
+ dst->mem_freq = src->mem_freq;
+ loongson_params->memory_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params;
+
+ if (!mmap_buf || !mmap_size || !desc_size)
+ return;
+
+ mmap_end = ADD_MEMORY_DESCRIPTOR (mmap_buf, mmap_size);
+
+ /* drop reserved */
+ for (desc = mmap_buf,
+ desc_next = desc;
+ desc < mmap_end;
+ desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size))
+ {
+ desc->type = mem_types_reserved[desc->type];
+ if (desc->type)
+ continue;
+
+ if (desc != desc_next)
+ *desc_next = *desc;
+ desc_next = ADD_MEMORY_DESCRIPTOR (desc_next, desc_size);
+ }
+ mmap_end = desc_next;
+
+ /* sort: low->high */
+ while (need_sort)
+ {
+ need_sort = 0;
+
+ for (desc = mmap_buf,
+ desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size);
+ (desc < mmap_end) && (desc_next < mmap_end);
+ desc = desc_next,
+ desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size))
+ {
+ grub_efi_memory_descriptor_t tmp;
+
+ if (desc->physical_start <= desc_next->physical_start)
+ continue;
+
+ tmp = *desc;
+ *desc = *desc_next;
+ *desc_next = tmp;
+ need_sort = 1;
+ }
+ }
+
+ /* combine continuous memory map */
+ for (desc = mmap_buf,
+ desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size);
+ desc_next < mmap_end;
+ desc_next = ADD_MEMORY_DESCRIPTOR (desc_next, desc_size))
+ {
+ grub_efi_physical_address_t prev_end = desc->physical_start + (desc->num_pages << 12);
+
+ if (prev_end == desc_next->physical_start)
+ {
+ desc->num_pages += desc_next->num_pages;
+ continue;
+ }
+
+ desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size);
+ grub_memcpy (desc, desc_next, desc_size);
+ }
+ mmap_end = ADD_MEMORY_DESCRIPTOR (desc, desc_size);
+
+ /* write to loongson memory map */
+ for (desc = mmap_buf;
+ desc < mmap_end;
+ desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size))
+ {
+ grub_efi_physical_address_t physical_start = grub_vtop ((void *) desc->physical_start);
+ grub_efi_physical_address_t physical_end = physical_start + (desc->num_pages << 12);
+
+ physical_start = ALIGN_UP (physical_start, 0x100000);
+ physical_end = ALIGN_DOWN (physical_end, 0x100000);
+
+ if (physical_start >= physical_end || (physical_end - physical_start) < 0x100000)
+ continue;
+
+ dst->map[dst->nr_map].node_id = (desc->physical_start >> 44) & 0xf;
+ dst->map[dst->nr_map].mem_type = (physical_end <= 0x10000000) ?
+ GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW :
+ GRUB_EFI_LOONGSON_SYSTEM_RAM_HIGH;
+ dst->map[dst->nr_map].mem_start = physical_start;
+ dst->map[dst->nr_map].mem_size = (physical_end - physical_start) >> 20;
+
+ grub_dprintf ("loongson", "memory map %03u: 0x%016lx 0x%016lx @ %u\n",
+ dst->nr_map, physical_start, physical_end - physical_start,
+ dst->map[dst->nr_map].node_id);
+
+ dst->nr_map ++;
+ }
+}
+
+#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
+#define SUB_MEMORY_DESCRIPTOR(desc, size) \
+ ((grub_efi_memory_descriptor_t *) ((char *) (desc) - (size)))
+
+void
+grub_efi_loongson_alloc_boot_params (void)
+{
+ grub_efi_memory_descriptor_t *mmap_buf;
+ grub_efi_memory_descriptor_t *mmap_end;
+ grub_efi_memory_descriptor_t *desc;
+ grub_efi_uintn_t mmap_size;
+ grub_efi_uintn_t desc_size;
+ grub_efi_physical_address_t address;
+ grub_efi_allocate_type_t type;
+ grub_efi_uintn_t pages;
+ grub_efi_status_t status;
+ grub_efi_boot_services_t *b;
+ int mm_status;
+
+ type = GRUB_EFI_ALLOCATE_ADDRESS;
+ pages = BYTES_TO_PAGES (loongson_boot_params_size + loongson_reset_code_size);
+
+ mmap_size = (1 << 12);
+ mmap_buf = grub_malloc (mmap_size);
+ if (!mmap_buf)
+ grub_fatal ("out of memory!");
+
+ mm_status = grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0);
+ if (mm_status == 0)
+ {
+ grub_free (mmap_buf);
+ mmap_size += desc_size * 32;
+
+ mmap_buf = grub_malloc (mmap_size);
+ if (!mmap_buf)
+ grub_fatal ("out of memory!");
+
+ mm_status = grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0);
+ }
+
+ if (mm_status < 0)
+ grub_fatal ("cannot get memory map!");
+
+ mmap_end = ADD_MEMORY_DESCRIPTOR (mmap_buf, mmap_size);
+
+ for (desc = SUB_MEMORY_DESCRIPTOR (mmap_end, desc_size);
+ desc >= mmap_buf;
+ desc = SUB_MEMORY_DESCRIPTOR (desc, desc_size))
+ {
+ if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY)
+ continue;
+ if (desc->physical_start >= GRUB_EFI_MAX_USABLE_ADDRESS)
+ continue;
+ if (desc->num_pages < pages)
+ continue;
+
+ address = desc->physical_start;
+ break;
+ }
+
+ grub_free (mmap_buf);
+
+ b = grub_efi_system_table->boot_services;
+ status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_RUNTIME_SERVICES_DATA, pages, &address);
+ if (status != GRUB_EFI_SUCCESS)
+ grub_fatal ("cannot allocate Loongson boot parameters!");
+
+ loongson_boot_params = (void *) ((grub_addr_t) address);
+}
+
+void
+grub_efi_loongson_free_boot_params (void)
+{
+ grub_efi_free_pages ((grub_addr_t) loongson_boot_params,
+ BYTES_TO_PAGES (loongson_boot_params_size + loongson_reset_code_size));
+}
+
+void *
+grub_efi_loongson_get_smbios_table (void)
+{
+ static grub_efi_loongson_smbios_table *smbios_table;
+ grub_efi_loongson_boot_params *old_boot_params;
+ struct bootparamsinterface* boot_params;
+ void * tmp_boot_params = NULL;
+ char * p = NULL;
+ if(smbios_table)
+ return smbios_table;
+
+ tmp_boot_params = grub_efi_loongson_get_boot_params();
+ if(tmp_boot_params == NULL)
+ {
+ grub_dprintf("loongson", "tmp_boot_params is NULL\n");
+ return tmp_boot_params;
+ }
+
+ boot_params = (struct bootparamsinterface *)tmp_boot_params;
+ p = (char *)&(boot_params->signature);
+ if(grub_strncmp(p, "BPI", 3) == 0)
+ {
+ grub_dprintf("loongson", "find new bpi\n");
+ return boot_params ? boot_params : 0;
+ }
+ else
+ {
+ old_boot_params = (grub_efi_loongson_boot_params *)tmp_boot_params;
+ return old_boot_params ? &old_boot_params->efi.smbios : 0;
+ }
+
+}
+
+int
+grub_efi_is_loongson (void)
+{
+ return grub_efi_loongson_get_smbios_table () ? 1 : 0;
+}
+
+void *
+grub_efi_loongson_get_boot_params (void)
+{
+ static void * boot_params = NULL;
+ grub_efi_configuration_table_t *tables;
+ grub_efi_guid_t smbios_guid = GRUB_EFI_LOONGSON_SMBIOS_TABLE_GUID;
+ unsigned int i;
+
+ if (boot_params)
+ return boot_params;
+
+ /* Look for Loongson SMBIOS in UEFI config tables. */
+ tables = grub_efi_system_table->configuration_table;
+
+ for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
+ if (grub_memcmp (&tables[i].vendor_guid, &smbios_guid, sizeof (smbios_guid)) == 0)
+ {
+ boot_params= tables[i].vendor_table;
+ grub_dprintf ("loongson", "found registered SMBIOS @ %p\n", boot_params);
+ break;
+ }
+ return boot_params;
+}
+
+grub_uint8_t
+grub_efi_loongson_calculatesum8 (const grub_uint8_t *buffer, grub_efi_uintn_t length)
+{
+ grub_uint8_t sum;
+ grub_efi_uintn_t count;
+
+ for (sum = 0, count = 0; count < length; count++)
+ {
+ sum = (grub_uint8_t) (sum + *(buffer + count));
+ }
+ return sum;
+}
+
+grub_uint8_t
+grub_efi_loongson_grub_calculatechecksum8 (const grub_uint8_t *buffer, grub_efi_uintn_t length)
+{
+ grub_uint8_t checksum;
+
+ checksum = grub_efi_loongson_calculatesum8(buffer, length);
+
+ return (grub_uint8_t) (0x100 - checksum);
+}
+
+
+grub_uint32_t
+grub_efi_loongson_memmap_sort(struct memmap array[], grub_uint32_t length, mem_map * bpmem, grub_uint32_t index, grub_uint32_t memtype)
+{
+ grub_uint64_t tempmemsize = 0;
+ grub_uint32_t j = 0;
+ grub_uint32_t t = 0;
+
+ for(j = 0; j < length;)
+ {
+ tempmemsize = array[j].memsize;
+ for(t = j + 1; t < length; t++)
+ {
+ if(array[j].memstart + tempmemsize == array[t].memstart)
+ {
+ tempmemsize += array[t].memsize;
+ }
+ else
+ {
+ break;
+ }
+ }
+ bpmem->map[index].memtype = memtype;
+ bpmem->map[index].memstart = array[j].memstart;
+ bpmem->map[index].memsize = tempmemsize;
+ grub_dprintf("loongson", "map[%d]:type %x, start 0x%llx, end 0x%llx\n",
+ index,
+ bpmem->map[index].memtype,
+ (unsigned long long)bpmem->map[index].memstart,
+ (unsigned long long)bpmem->map[index].memstart+ bpmem->map[index].memsize
+ );
+ j = t;
+ index++;
+ }
+ return index;
+}
+
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+ .file "loongson.S"
+ .text
+
+ .set push
+ .set noreorder
+ .align 4
+
+VARIABLE (grub_efi_loongson_reset_start)
+
+VARIABLE (grub_efi_loongson_reset_system_addr)
+ .dword 0
+
+reset_system:
+ bal 1f
+ move $a1, $zero
+1:
+ ld $t9, -16($ra)
+ move $a2, $zero
+ jalr $t9
+ move $a3, $zero
+
+FUNCTION(grub_efi_loongson_reset_cold)
+ b reset_system
+ li $a0, 0
+
+FUNCTION(grub_efi_loongson_reset_warm)
+ b reset_system
+ li $a0, 1
+
+FUNCTION(grub_efi_loongson_reset_shutdown)
+ b reset_system
+ li $a0, 2
+
+FUNCTION(grub_efi_loongson_reset_suspend)
+ b reset_system
+ li $a0, 3
+
+VARIABLE (grub_efi_loongson_reset_end)
+
+ .set pop
+
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+#include <grub/types.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/cache.h>
+
+#include <grub/mips64/relocator.h>
+#include <grub/relocator_private.h>
+
+extern grub_uint8_t grub_relocator_forward_start;
+extern grub_uint8_t grub_relocator_forward_end;
+extern grub_uint8_t grub_relocator_backward_start;
+extern grub_uint8_t grub_relocator_backward_end;
+
+#define REGW_SIZEOF (6 * sizeof (grub_uint32_t))
+#define JUMP_SIZEOF (2 * sizeof (grub_uint32_t))
+
+#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator_##x##_end \
+ - &grub_relocator_##x##_start)
+#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \
+ + REGW_SIZEOF * 3)
+grub_size_t grub_relocator_align = sizeof (grub_uint64_t);
+grub_size_t grub_relocator_forward_size;
+grub_size_t grub_relocator_backward_size;
+grub_size_t grub_relocator_jumper_size = JUMP_SIZEOF + REGW_SIZEOF;
+
+void
+grub_cpu_relocator_init (void)
+{
+ grub_relocator_forward_size = RELOCATOR_SIZEOF(forward);
+ grub_relocator_backward_size = RELOCATOR_SIZEOF(backward);
+}
+
+static void
+write_reg (int regn, grub_uint64_t val, void **target)
+{
+ grub_uint32_t lui;
+ grub_uint32_t ori;
+ grub_uint32_t dsll;
+
+ /* lui $r, 0 */
+ lui = (0x3c00 | regn) << 16;
+ /* ori $r, $r, 0 */
+ ori = (0x3400 | (regn << 5) | regn) << 16;
+ /* dsll $r, $r, 16 */
+ dsll = (regn << 16) | (regn << 11) | (16 << 6) | 56;
+
+ /* lui $r, val[63:48]. */
+ *(grub_uint32_t *) *target = lui | (grub_uint16_t) (val >> 48);
+ *target = ((grub_uint32_t *) *target) + 1;
+ /* ori $r, val[47:32]. */
+ *(grub_uint32_t *) *target = ori | (grub_uint16_t) (val >> 32);
+ *target = ((grub_uint32_t *) *target) + 1;
+ /* dsll $r, $r, 16 */
+ *(grub_uint32_t *) *target = dsll;
+ *target = ((grub_uint32_t *) *target) + 1;
+ /* ori $r, val[31:16]. */
+ *(grub_uint32_t *) *target = ori | (grub_uint16_t) (val >> 16);
+ *target = ((grub_uint32_t *) *target) + 1;
+ /* dsll $r, $r, 16 */
+ *(grub_uint32_t *) *target = dsll;
+ *target = ((grub_uint32_t *) *target) + 1;
+ /* ori $r, val[15:0]. */
+ *(grub_uint32_t *) *target = ori | (grub_uint16_t) val;
+ *target = ((grub_uint32_t *) *target) + 1;
+}
+
+static void
+write_jump (int regn, void **target)
+{
+ /* j $r. */
+ *(grub_uint32_t *) *target = (regn << 21) | 0x8;
+ *target = ((grub_uint32_t *) *target) + 1;
+ /* nop. */
+ *(grub_uint32_t *) *target = 0;
+ *target = ((grub_uint32_t *) *target) + 1;
+}
+
+void
+grub_cpu_relocator_jumper (void *rels, grub_addr_t addr)
+{
+ write_reg (1, addr, &rels);
+ write_jump (1, &rels);
+}
+
+void
+grub_cpu_relocator_backward (void *ptr0, void *src, void *dest,
+ grub_size_t size)
+{
+ void *ptr = ptr0;
+ write_reg (8, (grub_uint64_t) src, &ptr);
+ write_reg (9, (grub_uint64_t) dest, &ptr);
+ write_reg (10, (grub_uint64_t) size, &ptr);
+ grub_memcpy (ptr, &grub_relocator_backward_start,
+ RELOCATOR_SRC_SIZEOF (backward));
+}
+
+void
+grub_cpu_relocator_forward (void *ptr0, void *src, void *dest,
+ grub_size_t size)
+{
+ void *ptr = ptr0;
+ write_reg (8, (grub_uint64_t) src, &ptr);
+ write_reg (9, (grub_uint64_t) dest, &ptr);
+ write_reg (10, (grub_uint64_t) size, &ptr);
+ grub_memcpy (ptr, &grub_relocator_forward_start,
+ RELOCATOR_SRC_SIZEOF (forward));
+}
+
+grub_err_t
+grub_relocator64_boot (struct grub_relocator *rel,
+ struct grub_relocator64_state state)
+{
+ grub_relocator_chunk_t ch;
+ void *ptr;
+ grub_err_t err;
+ void *relst;
+ grub_size_t relsize;
+ grub_size_t stateset_size = 31 * REGW_SIZEOF + JUMP_SIZEOF;
+ unsigned i;
+ grub_addr_t vtarget;
+
+ err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
+ (0xffffffff - stateset_size)
+ + 1, stateset_size,
+ grub_relocator_align,
+ GRUB_RELOCATOR_PREFERENCE_NONE, 0);
+ if (err)
+ return err;
+
+ ptr = get_virtual_current_address (ch);
+ for (i = 1; i < 32; i++)
+ write_reg (i, state.gpr[i], &ptr);
+ write_jump (state.jumpreg, &ptr);
+
+ vtarget = (grub_addr_t) grub_map_memory (get_physical_target_address (ch),
+ stateset_size);
+
+ err = grub_relocator_prepare_relocs (rel, vtarget, &relst, &relsize);
+ if (err)
+ return err;
+
+ grub_arch_sync_caches ((void *) relst, relsize);
+
+ ((void (*) (void)) relst) ();
+
+ /* Not reached. */
+ return GRUB_ERR_NONE;
+}
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+ .p2align 4 /* force 16-byte alignment */
+
+ .set push
+ .set noreorder
+ .set nomacro
+
+VARIABLE (grub_relocator_forward_start)
+
+copycont1:
+ ld $11,0($8)
+ sd $11,0($9)
+ daddiu $8, $8, 8
+ daddiu $10, $10, -8
+ bne $10, $0, copycont1
+ daddiu $9, $9, 8
+
+VARIABLE (grub_relocator_forward_end)
+
+VARIABLE (grub_relocator_backward_start)
+
+ daddu $9, $9, $10
+ daddu $8, $8, $10
+ /* Backward movsl is implicitly off-by-one. compensate that. */
+ daddiu $9, $9, -8
+ daddiu $8, $8, -8
+copycont2:
+ ld $11,0($8)
+ sd $11,0($9)
+ daddiu $8, $8, -8
+ daddiu $10, $10, -8
+ bne $10, $0, copycont2
+ daddiu $9, $9, -8
+
+VARIABLE (grub_relocator_backward_end)
+
+ .set pop
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2003,2007,2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <grub/dl.h>
+#include <grub/mips64/asm.h>
+
+ .file "setjmp.S"
+
+GRUB_MOD_LICENSE "GPLv3+"
+
+ .text
+
+/*
+ * int grub_setjmp (grub_jmp_buf env)
+ */
+FUNCTION(grub_setjmp)
+ GRUB_ASM_REG_S $s0, 0($a0)
+ GRUB_ASM_REG_S $s1, 8($a0)
+ GRUB_ASM_REG_S $s2, 16($a0)
+ GRUB_ASM_REG_S $s3, 24($a0)
+ GRUB_ASM_REG_S $s4, 32($a0)
+ GRUB_ASM_REG_S $s5, 40($a0)
+ GRUB_ASM_REG_S $s6, 48($a0)
+ GRUB_ASM_REG_S $s7, 56($a0)
+ GRUB_ASM_REG_S $s8, 64($a0)
+ GRUB_ASM_REG_S $gp, 72($a0)
+ GRUB_ASM_REG_S $sp, 80($a0)
+ GRUB_ASM_REG_S $ra, 88($a0)
+ move $v0, $zero
+ move $v1, $zero
+ jr $ra
+ nop
+/*
+ * int grub_longjmp (grub_jmp_buf env, int val)
+ */
+FUNCTION(grub_longjmp)
+ GRUB_ASM_REG_L $s0, 0($a0)
+ GRUB_ASM_REG_L $s1, 8($a0)
+ GRUB_ASM_REG_L $s2, 16($a0)
+ GRUB_ASM_REG_L $s3, 24($a0)
+ GRUB_ASM_REG_L $s4, 32($a0)
+ GRUB_ASM_REG_L $s5, 40($a0)
+ GRUB_ASM_REG_L $s6, 48($a0)
+ GRUB_ASM_REG_L $s7, 56($a0)
+ GRUB_ASM_REG_L $s8, 64($a0)
+ GRUB_ASM_REG_L $gp, 72($a0)
+ GRUB_ASM_REG_L $sp, 80($a0)
+ GRUB_ASM_REG_L $ra, 88($a0)
+ addiu $v0, $zero, 1
+ movn $v0, $a1, $a1
+ move $v1, $zero
+ jr $ra
+ nop
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/relocator.h>
+#include <grub/relocator_private.h>
+#include <grub/mm_private.h>
+#include <grub/misc.h>
+#include <grub/cache.h>
+#include <grub/memory.h>
+#include <grub/dl.h>
+#include <grub/i18n.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+struct grub_relocator
+{
+ struct grub_relocator_chunk *chunks;
+ grub_phys_addr_t postchunks;
+ grub_phys_addr_t highestaddr;
+ grub_phys_addr_t highestnonpostaddr;
+ grub_size_t relocators_size;
+};
+
+struct grub_relocator_subchunk
+{
+ enum {CHUNK_TYPE_IN_REGION, CHUNK_TYPE_REGION_START,
+#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
+ CHUNK_TYPE_FIRMWARE, CHUNK_TYPE_LEFTOVER
+#endif
+ } type;
+ grub_mm_region_t reg;
+ grub_phys_addr_t start;
+ grub_size_t size;
+ grub_size_t pre_size;
+ struct grub_relocator_extra_block *extra;
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
+ struct grub_relocator_fw_leftover *pre, *post;
+#endif
+};
+
+struct grub_relocator_chunk
+{
+ struct grub_relocator_chunk *next;
+ grub_phys_addr_t src;
+ void *srcv;
+ grub_phys_addr_t target;
+ grub_size_t size;
+ struct grub_relocator_subchunk *subchunks;
+ unsigned nsubchunks;
+};
+
+struct grub_relocator_extra_block
+{
+ struct grub_relocator_extra_block *next;
+ struct grub_relocator_extra_block **prev;
+ grub_phys_addr_t start;
+ grub_phys_addr_t end;
+};
+
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
+struct grub_relocator_fw_leftover
+{
+ struct grub_relocator_fw_leftover *next;
+ struct grub_relocator_fw_leftover **prev;
+ grub_phys_addr_t quantstart;
+ grub_uint8_t freebytes[GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT / 8];
+};
+
+static struct grub_relocator_fw_leftover *leftovers;
+#endif
+
+static struct grub_relocator_extra_block *extra_blocks;
+
+void *
+get_virtual_current_address (grub_relocator_chunk_t in)
+{
+ return in->srcv;
+}
+
+grub_phys_addr_t
+get_physical_target_address (grub_relocator_chunk_t in)
+{
+ return in->target;
+}
+
+struct grub_relocator *
+grub_relocator_new (void)
+{
+ struct grub_relocator *ret;
+
+ grub_cpu_relocator_init ();
+
+ ret = grub_zalloc (sizeof (struct grub_relocator));
+ if (!ret)
+ return NULL;
+
+ ret->postchunks = ~(grub_phys_addr_t) 0;
+ ret->relocators_size = grub_relocator_jumper_size;
+ grub_dprintf ("relocator", "relocators_size=%lu\n",
+ (unsigned long) ret->relocators_size);
+ return ret;
+}
+
+#define DIGITSORT_BITS 8
+#define DIGITSORT_MASK ((1 << DIGITSORT_BITS) - 1)
+#define BITS_IN_BYTE 8
+
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+
+static inline int
+is_start (int type)
+{
+ return !(type & 1) && (type != COLLISION_START);
+}
+
+static void
+allocate_regstart (grub_phys_addr_t addr, grub_size_t size, grub_mm_region_t rb,
+ grub_mm_region_t *regancestor, grub_mm_header_t hancestor)
+{
+ grub_addr_t newreg_start, newreg_raw_start
+ = (grub_addr_t) rb + (addr - grub_vtop (rb)) + size;
+ grub_addr_t newreg_size, newreg_presize;
+ grub_mm_header_t new_header;
+ grub_mm_header_t hb = (grub_mm_header_t) (rb + 1);
+
+#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
+ grub_dprintf ("relocator", "ra = %p, rb = %p\n", regancestor, rb);
+#endif
+ newreg_start = ALIGN_UP (newreg_raw_start, GRUB_MM_ALIGN);
+ newreg_presize = newreg_start - newreg_raw_start;
+ newreg_size = rb->size - (newreg_start - (grub_addr_t) rb);
+ if ((hb->size << GRUB_MM_ALIGN_LOG2) >= newreg_start
+ - (grub_addr_t) rb)
+ {
+ grub_mm_header_t newhnext = hb->next;
+ grub_size_t newhsize = ((hb->size << GRUB_MM_ALIGN_LOG2)
+ - (newreg_start
+ - (grub_addr_t) rb)) >> GRUB_MM_ALIGN_LOG2;
+ new_header = (void *) (newreg_start + sizeof (*rb));
+ if (newhnext == hb)
+ newhnext = new_header;
+ new_header->next = newhnext;
+ new_header->size = newhsize;
+ new_header->magic = GRUB_MM_FREE_MAGIC;
+ }
+ else
+ {
+ new_header = hb->next;
+ if (new_header == hb)
+ new_header = (void *) (newreg_start + sizeof (*rb));
+ }
+ {
+ struct grub_mm_header *newregfirst = rb->first;
+ struct grub_mm_region *newregnext = rb->next;
+ struct grub_mm_region *newreg = (void *) newreg_start;
+ hancestor->next = new_header;
+ if (newregfirst == hb)
+ newregfirst = new_header;
+ newreg->first = newregfirst;
+ newreg->next = newregnext;
+ newreg->pre_size = newreg_presize;
+ newreg->size = newreg_size;
+ *regancestor = newreg;
+ {
+ grub_mm_header_t h = newreg->first, hp = NULL;
+ do
+ {
+ if ((void *) h < (void *) (newreg + 1))
+ grub_fatal ("Failed to adjust memory region: %p, %p, %p, %p, %p",
+ newreg, newreg->first, h, hp, hb);
+#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
+ if ((void *) h == (void *) (newreg + 1))
+ grub_dprintf ("relocator",
+ "Free start memory region: %p, %p, %p, %p, %p",
+ newreg, newreg->first, h, hp, hb);
+#endif
+ hp = h;
+ h = h->next;
+ }
+ while (h != newreg->first);
+ }
+ }
+}
+
+static void
+allocate_inreg (grub_phys_addr_t paddr, grub_size_t size,
+ grub_mm_header_t hb, grub_mm_header_t hbp,
+ grub_mm_region_t rb)
+{
+ struct grub_mm_header *foll = NULL;
+ grub_addr_t vaddr = (grub_addr_t) hb + (paddr - grub_vtop (hb));
+
+#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
+ grub_dprintf ("relocator", "inreg paddr = 0x%lx, size = %lu,"
+ " hb = %p, hbp = %p, rb = %p, vaddr = 0x%lx\n",
+ (unsigned long) paddr, (unsigned long) size, hb, hbp,
+ rb, (unsigned long) vaddr);
+#endif
+
+ if (ALIGN_UP (vaddr + size, GRUB_MM_ALIGN) + GRUB_MM_ALIGN
+ <= (grub_addr_t) (hb + hb->size))
+ {
+ foll = (void *) ALIGN_UP (vaddr + size, GRUB_MM_ALIGN);
+ foll->magic = GRUB_MM_FREE_MAGIC;
+ foll->size = hb + hb->size - foll;
+#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
+ grub_dprintf ("relocator", "foll = %p, foll->size = %lu\n", foll,
+ (unsigned long) foll->size);
+#endif
+ }
+
+ if (vaddr - (grub_addr_t) hb >= sizeof (*hb))
+ {
+ hb->size = ((vaddr - (grub_addr_t) hb) >> GRUB_MM_ALIGN_LOG2);
+ if (foll)
+ {
+ foll->next = hb;
+ hbp->next = foll;
+ if (rb->first == hb)
+ {
+ rb->first = foll;
+ }
+ }
+ }
+ else
+ {
+ if (foll)
+ {
+ foll->next = hb->next;
+ }
+ else
+ foll = hb->next;
+
+ hbp->next = foll;
+ if (rb->first == hb)
+ {
+ rb->first = foll;
+ }
+ if (rb->first == hb)
+ {
+ rb->first = (void *) (rb + 1);
+ }
+ }
+}
+
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
+static void
+check_leftover (struct grub_relocator_fw_leftover *lo)
+{
+ unsigned i;
+ for (i = 0; i < sizeof (lo->freebytes); i++)
+ if (lo->freebytes[i] != 0xff)
+ return;
+ grub_relocator_firmware_free_region (lo->quantstart,
+ GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT);
+ *lo->prev = lo->next;
+ if (lo->next)
+ lo->next->prev = lo->prev;
+}
+#endif
+
+static void
+free_subchunk (const struct grub_relocator_subchunk *subchu)
+{
+ switch (subchu->type)
+ {
+ case CHUNK_TYPE_REGION_START:
+ {
+ grub_mm_region_t r1, r2, *rp;
+ grub_mm_header_t h;
+ grub_size_t pre_size;
+ r1 = subchu->reg;
+ r2 = (grub_mm_region_t) ALIGN_UP ((grub_addr_t) subchu->reg
+ + (grub_vtop (subchu->reg)
+ - subchu->start) + subchu->size,
+ GRUB_MM_ALIGN);
+ for (rp = &grub_mm_base; *rp && *rp != r2; rp = &((*rp)->next));
+ pre_size = subchu->pre_size;
+
+ if (*rp)
+ {
+ grub_mm_header_t h2, *hp;
+ r1->first = r2->first;
+ r1->next = r2->next;
+ r1->pre_size = pre_size;
+ r1->size = r2->size + (r2 - r1) * sizeof (*r2);
+ *rp = r1;
+ h = (grub_mm_header_t) (r1 + 1);
+ h->next = r2->first;
+ h->magic = GRUB_MM_FREE_MAGIC;
+ h->size = (r2 - r1 - 1);
+ for (hp = &r2->first, h2 = *hp; h2->next != r2->first;
+ hp = &(h2->next), h2 = *hp)
+ if (h2 == (grub_mm_header_t) (r2 + 1))
+ break;
+ if (h2 == (grub_mm_header_t) (r2 + 1))
+ {
+ h->size = h2->size + (h2 - h);
+ h->next = h2->next;
+ *hp = h;
+ if (hp == &r2->first)
+ {
+ for (h2 = r2->first; h2->next != r2->first; h2 = h2->next);
+ h2->next = h;
+ }
+ }
+ else
+ {
+ h2->next = h;
+ }
+ }
+ else
+ {
+ r1->pre_size = pre_size;
+ r1->size = (r2 - r1) * sizeof (*r2);
+ /* Find where to insert this region.
+ Put a smaller one before bigger ones,
+ to prevent fragmentation. */
+ for (rp = &grub_mm_base; *rp; rp = &((*rp)->next))
+ if ((*rp)->size > r1->size)
+ break;
+ r1->next = *rp;
+ *rp = r1->next;
+ h = (grub_mm_header_t) (r1 + 1);
+ r1->first = h;
+ h->next = h;
+ h->magic = GRUB_MM_FREE_MAGIC;
+ h->size = (r2 - r1 - 1);
+ }
+ for (r2 = grub_mm_base; r2; r2 = r2->next)
+ if ((grub_addr_t) r2 + r2->size == (grub_addr_t) r1)
+ break;
+ if (r2)
+ {
+ grub_mm_header_t hl2, hl, g;
+ g = (grub_mm_header_t) ((grub_addr_t) r2 + r2->size);
+ g->size = (grub_mm_header_t) r1 - g;
+ r2->size += r1->size;
+ for (hl = r2->first; hl->next != r2->first; hl = hl->next);
+ for (hl2 = r1->first; hl2->next != r1->first; hl2 = hl2->next);
+ hl2->next = r2->first;
+ r2->first = r1->first;
+ hl->next = r2->first;
+ *rp = (*rp)->next;
+ grub_free (g + 1);
+ }
+ break;
+ }
+ case CHUNK_TYPE_IN_REGION:
+ {
+ grub_mm_header_t h = (grub_mm_header_t) ALIGN_DOWN ((grub_addr_t) subchu->start,
+ GRUB_MM_ALIGN);
+ h->size
+ = ((subchu->start + subchu->size + GRUB_MM_ALIGN - 1) / GRUB_MM_ALIGN)
+ - (subchu->start / GRUB_MM_ALIGN) - 1;
+ h->next = h;
+ h->magic = GRUB_MM_ALLOC_MAGIC;
+ grub_free (h + 1);
+ break;
+ }
+#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
+ case CHUNK_TYPE_FIRMWARE:
+ case CHUNK_TYPE_LEFTOVER:
+ {
+ grub_addr_t fstart, fend;
+ fstart = ALIGN_UP (subchu->start,
+ GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT);
+ fend = ALIGN_DOWN (subchu->start + subchu->size,
+ GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT);
+ if (fstart < fend)
+ grub_relocator_firmware_free_region (fstart, fend - fstart);
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
+ if (subchu->pre)
+ {
+ int off = subchu->start - fstart
+ - GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT;
+ grub_memset (subchu->pre->freebytes + off / 8 + 1,
+ 0xff, sizeof (subchu->pre->freebytes) - off / 8 - 1);
+ subchu->pre->freebytes[off / 8] |= ~((1 << (off % 8)) - 1);
+ check_leftover (subchu->pre);
+ }
+ if (subchu->post)
+ {
+ int off = subchu->start + subchu->size - fend;
+ grub_memset (subchu->pre->freebytes,
+ 0xff, sizeof (subchu->pre->freebytes) - off / 8);
+ subchu->pre->freebytes[off / 8] |= ((1 << (8 - (off % 8))) - 1);
+ check_leftover (subchu->post);
+ }
+#endif
+ *subchu->extra->prev = subchu->extra->next;
+ grub_free (subchu->extra);
+ }
+ break;
+#endif
+ }
+}
+
+static int
+malloc_in_range (struct grub_relocator *rel,
+ grub_addr_t start, grub_addr_t end, grub_addr_t align,
+ grub_size_t size, struct grub_relocator_chunk *res,
+ int from_low_priv, int collisioncheck)
+{
+ grub_mm_region_t r, *ra, base_saved;
+ struct grub_relocator_mmap_event *events = NULL, *eventt = NULL, *t;
+ /* 128 is just in case of additional malloc (shouldn't happen). */
+ unsigned maxevents = 2 + 128;
+ grub_mm_header_t p, pa;
+ unsigned *counter;
+ int nallocs = 0;
+ unsigned j, N = 0;
+ grub_addr_t target = 0;
+
+ grub_dprintf ("relocator",
+ "trying to allocate in 0x%lx-0x%lx aligned 0x%lx size 0x%lx\n",
+ (unsigned long) start, (unsigned long) end,
+ (unsigned long) align, (unsigned long) size);
+
+ start = ALIGN_UP (start, align);
+ end = ALIGN_DOWN (end - size, align) + size;
+
+ if (end < start + size)
+ return 0;
+
+ /* We have to avoid any allocations when filling scanline events.
+ Hence 2-stages.
+ */
+ for (r = grub_mm_base; r; r = r->next)
+ {
+ p = r->first;
+ do
+ {
+ if ((grub_addr_t) p < (grub_addr_t) (r + 1)
+ || (grub_addr_t) p >= (grub_addr_t) (r + 1) + r->size)
+ grub_fatal ("%d: out of range pointer: %p\n", __LINE__, p);
+ maxevents += 2;
+ p = p->next;
+ }
+ while (p != r->first);
+ maxevents += 4;
+ }
+
+ if (collisioncheck && rel)
+ {
+ struct grub_relocator_chunk *chunk;
+ for (chunk = rel->chunks; chunk; chunk = chunk->next)
+ maxevents += 2;
+ }
+
+#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
+ {
+ struct grub_relocator_extra_block *cur;
+ for (cur = extra_blocks; cur; cur = cur->next)
+ maxevents += 2;
+ }
+ for (r = grub_mm_base; r; r = r->next)
+ maxevents += 2;
+
+ maxevents += grub_relocator_firmware_get_max_events ();
+#endif
+
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
+ {
+ struct grub_relocator_fw_leftover *cur;
+ for (cur = leftovers; cur; cur = cur->next)
+ {
+ int l = 0;
+ unsigned i;
+ for (i = 0; i < GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; i++)
+ {
+ if (l != ((cur->freebytes[i / 8] >> (i % 8)) & 1))
+ maxevents++;
+ l = ((cur->freebytes[i / 8] >> (i % 8)) & 1);
+ }
+ if (l)
+ maxevents++;
+ }
+ }
+#endif
+
+ eventt = grub_malloc (maxevents * sizeof (events[0]));
+ counter = grub_malloc ((DIGITSORT_MASK + 2) * sizeof (counter[0]));
+ events = grub_malloc (maxevents * sizeof (events[0]));
+ if (!events || !eventt || !counter)
+ {
+ grub_dprintf ("relocator", "events or counter allocation failed %d\n",
+ maxevents);
+ grub_free (events);
+ grub_free (eventt);
+ grub_free (counter);
+ return 0;
+ }
+
+ if (collisioncheck && rel)
+ {
+ struct grub_relocator_chunk *chunk;
+ for (chunk = rel->chunks; chunk; chunk = chunk->next)
+ {
+ events[N].type = COLLISION_START;
+ events[N].pos = chunk->target;
+ N++;
+ events[N].type = COLLISION_END;
+ events[N].pos = chunk->target + chunk->size;
+ N++;
+ }
+ }
+
+#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
+ for (r = grub_mm_base; r; r = r->next)
+ {
+#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
+ grub_dprintf ("relocator", "Blocking at 0x%lx-0x%lx\n",
+ (unsigned long) r - r->pre_size,
+ (unsigned long) (r + 1) + r->size);
+#endif
+ events[N].type = FIRMWARE_BLOCK_START;
+ events[N].pos = (grub_addr_t) r - r->pre_size;
+ N++;
+ events[N].type = FIRMWARE_BLOCK_END;
+ events[N].pos = (grub_addr_t) (r + 1) + r->size;
+ N++;
+ }
+ {
+ struct grub_relocator_extra_block *cur;
+ for (cur = extra_blocks; cur; cur = cur->next)
+ {
+#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
+ grub_dprintf ("relocator", "Blocking at 0x%lx-0x%lx\n",
+ (unsigned long) cur->start, (unsigned long) cur->end);
+#endif
+ events[N].type = FIRMWARE_BLOCK_START;
+ events[N].pos = cur->start;
+ N++;
+ events[N].type = FIRMWARE_BLOCK_END;
+ events[N].pos = cur->end;
+ N++;
+ }
+ }
+
+ N += grub_relocator_firmware_fill_events (events + N);
+
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
+ {
+ struct grub_relocator_fw_leftover *cur;
+ for (cur = leftovers; cur; cur = cur->next)
+ {
+ unsigned i;
+ int l = 0;
+ for (i = 0; i < GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; i++)
+ {
+ if (l != ((cur->freebytes[i / 8] >> (i % 8)) & 1))
+ {
+ events[N].type = l ? REG_LEFTOVER_END : REG_LEFTOVER_START;
+ events[N].pos = cur->quantstart + i;
+ events[N].leftover = cur;
+ N++;
+ }
+ l = ((cur->freebytes[i / 8] >> (i % 8)) & 1);
+ }
+ if (l)
+ {
+ events[N].type = REG_LEFTOVER_END;
+ events[N].pos = cur->quantstart + i;
+ events[N].leftover = cur;
+ N++;
+ }
+ }
+ }
+#endif
+#endif
+
+ /* No malloc from this point. */
+ base_saved = grub_mm_base;
+ grub_mm_base = NULL;
+
+ for (ra = &base_saved, r = *ra; r; ra = &(r->next), r = *ra)
+ {
+ pa = r->first;
+ p = pa->next;
+ if (p->magic == GRUB_MM_ALLOC_MAGIC)
+ continue;
+ do
+ {
+ if (p->magic != GRUB_MM_FREE_MAGIC)
+ grub_fatal ("%s:%d free magic broken at %p (0x%x)\n",
+ __FILE__,
+ __LINE__, p, p->magic);
+ if (p == (grub_mm_header_t) (r + 1))
+ {
+ events[N].type = REG_BEG_START;
+ events[N].pos = grub_vtop (r) - r->pre_size;
+ events[N].reg = r;
+ events[N].regancestor = ra;
+ events[N].head = p;
+ events[N].hancestor = pa;
+ N++;
+ events[N].type = REG_BEG_END;
+ events[N].pos = grub_vtop (p + p->size) - sizeof (*r)
+ - sizeof (struct grub_mm_header);
+ N++;
+ }
+ else
+ {
+ events[N].type = IN_REG_START;
+ events[N].pos = grub_vtop (p);
+ events[N].head = p;
+ events[N].hancestor = pa;
+ events[N].reg = r;
+ N++;
+ events[N].type = IN_REG_END;
+ events[N].pos = grub_vtop (p + p->size);
+ N++;
+ }
+ pa = p;
+ p = pa->next;
+ }
+ while (pa != r->first);
+ }
+
+ /* Put ending events after starting events. */
+ {
+ int st = 0, e = N / 2;
+ for (j = 0; j < N; j++)
+ if (is_start (events[j].type) || events[j].type == COLLISION_START)
+ eventt[st++] = events[j];
+ else
+ eventt[e++] = events[j];
+ t = eventt;
+ eventt = events;
+ events = t;
+ }
+
+ {
+ unsigned i;
+ for (i = 0; i < (BITS_IN_BYTE * sizeof (grub_addr_t) / DIGITSORT_BITS);
+ i++)
+ {
+ grub_memset (counter, 0, (1 + (1 << DIGITSORT_BITS)) * sizeof (counter[0]));
+ for (j = 0; j < N; j++)
+ counter[((events[j].pos >> (DIGITSORT_BITS * i))
+ & DIGITSORT_MASK) + 1]++;
+ for (j = 0; j <= DIGITSORT_MASK; j++)
+ counter[j+1] += counter[j];
+ for (j = 0; j < N; j++)
+ eventt[counter[((events[j].pos >> (DIGITSORT_BITS * i))
+ & DIGITSORT_MASK)]++] = events[j];
+ t = eventt;
+ eventt = events;
+ events = t;
+ }
+ }
+
+#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
+ retry:
+#endif
+
+ /* Now events are nicely sorted. */
+ {
+ int nstarted = 0, ncollisions = 0, nstartedfw = 0, nblockfw = 0;
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
+ int nlefto = 0;
+#else
+ const int nlefto = 0;
+#endif
+ grub_addr_t starta = 0;
+ for (j = from_low_priv ? 0 : N - 1; from_low_priv ? j < N : (j + 1);
+ from_low_priv ? j++ : j--)
+ {
+ int isinsidebefore, isinsideafter;
+ isinsidebefore = (!ncollisions && (nstarted || (((nlefto || nstartedfw)
+ && !nblockfw))));
+ switch (events[j].type)
+ {
+#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
+ case REG_FIRMWARE_START:
+ nstartedfw++;
+ break;
+
+ case REG_FIRMWARE_END:
+ nstartedfw--;
+ break;
+
+ case FIRMWARE_BLOCK_START:
+ nblockfw++;
+ break;
+
+ case FIRMWARE_BLOCK_END:
+ nblockfw--;
+ break;
+#endif
+
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
+ case REG_LEFTOVER_START:
+ nlefto++;
+ break;
+
+ case REG_LEFTOVER_END:
+ nlefto--;
+ break;
+#endif
+
+ case COLLISION_START:
+ ncollisions++;
+ break;
+
+ case COLLISION_END:
+ ncollisions--;
+ break;
+
+ case IN_REG_START:
+ case REG_BEG_START:
+ nstarted++;
+ break;
+
+ case IN_REG_END:
+ case REG_BEG_END:
+ nstarted--;
+ break;
+ }
+ isinsideafter = (!ncollisions && (nstarted || ((nlefto || nstartedfw)
+ && !nblockfw)));
+ if (from_low_priv) {
+ if (!isinsidebefore && isinsideafter)
+ starta = ALIGN_UP (events[j].pos, align);
+
+ if (isinsidebefore && !isinsideafter)
+ {
+ target = starta;
+ if (target < start)
+ target = start;
+ if (target + size <= end && target + size <= events[j].pos)
+ /* Found an usable address. */
+ goto found;
+ }
+ } else {
+ if (!isinsidebefore && isinsideafter)
+ {
+ if (events[j].pos >= size)
+ starta = ALIGN_DOWN (events[j].pos - size, align) + size;
+ else
+ starta = 0;
+ }
+ if (isinsidebefore && !isinsideafter && starta >= size)
+ {
+ target = starta - size;
+ if (target > end - size)
+ target = end - size;
+ if (target >= start && target >= events[j].pos)
+ goto found;
+ }
+ }
+ }
+ }
+
+ grub_mm_base = base_saved;
+ grub_free (events);
+ grub_free (eventt);
+ grub_free (counter);
+ return 0;
+
+ found:
+ {
+ int inreg = 0, regbeg = 0, ncol = 0;
+#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
+ int fwin = 0, fwb = 0, fwlefto = 0;
+#endif
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
+ int last_lo = 0;
+#endif
+ int last_start = 0;
+ for (j = 0; j < N; j++)
+ {
+ int typepre;
+ if (ncol)
+ typepre = -1;
+ else if (regbeg)
+ typepre = CHUNK_TYPE_REGION_START;
+ else if (inreg)
+ typepre = CHUNK_TYPE_IN_REGION;
+#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
+ else if (fwin && !fwb)
+ typepre = CHUNK_TYPE_FIRMWARE;
+ else if (fwlefto && !fwb)
+ typepre = CHUNK_TYPE_LEFTOVER;
+#endif
+ else
+ typepre = -1;
+
+ if (j != 0 && events[j - 1].pos != events[j].pos)
+ {
+ grub_addr_t alloc_start, alloc_end;
+ alloc_start = max (events[j - 1].pos, target);
+ alloc_end = min (events[j].pos, target + size);
+ if (alloc_end > alloc_start)
+ {
+ switch (typepre)
+ {
+ case CHUNK_TYPE_REGION_START:
+ allocate_regstart (alloc_start, alloc_end - alloc_start,
+ events[last_start].reg,
+ events[last_start].regancestor,
+ events[last_start].hancestor);
+ /* TODO: maintain a reverse lookup tree for hancestor. */
+ {
+ unsigned k;
+ for (k = 0; k < N; k++)
+ if (events[k].hancestor == events[last_start].head)
+ events[k].hancestor = events[last_start].hancestor;
+ }
+ break;
+ case CHUNK_TYPE_IN_REGION:
+ allocate_inreg (alloc_start, alloc_end - alloc_start,
+ events[last_start].head,
+ events[last_start].hancestor,
+ events[last_start].reg);
+ {
+ unsigned k;
+ for (k = 0; k < N; k++)
+ if (events[k].hancestor == events[last_start].head)
+ events[k].hancestor = events[last_start].hancestor;
+ }
+ break;
+#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
+ case CHUNK_TYPE_FIRMWARE:
+ {
+ grub_addr_t fstart, fend;
+ fstart
+ = ALIGN_DOWN (alloc_start,
+ GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT);
+ fend
+ = ALIGN_UP (alloc_end,
+ GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT);
+#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
+ grub_dprintf ("relocator", "requesting %lx-%lx\n",
+ (unsigned long) fstart,
+ (unsigned long) fend);
+#endif
+ /* The failure here can be very expensive. */
+ if (!grub_relocator_firmware_alloc_region (fstart,
+ fend - fstart))
+ {
+ if (from_low_priv)
+ start = fend;
+ else
+ end = fstart;
+ goto retry;
+ }
+ break;
+ }
+#endif
+
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
+ case CHUNK_TYPE_LEFTOVER:
+ {
+ unsigned offstart = alloc_start
+ % GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT;
+ unsigned offend = alloc_end
+ % GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT;
+ struct grub_relocator_fw_leftover *lo
+ = events[last_lo].leftover;
+ if (offend == 0 && alloc_end != alloc_start)
+ offend = GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT;
+ lo->freebytes[offstart / 8]
+ &= ((1 << (8 - (start % 8))) - 1);
+ grub_memset (lo->freebytes + (offstart + 7) / 8, 0,
+ offend / 8 - (offstart + 7) / 8);
+ lo->freebytes[offend / 8] &= ~((1 << (offend % 8)) - 1);
+ }
+ break;
+#endif
+ }
+ nallocs++;
+ }
+ }
+
+ switch (events[j].type)
+ {
+ case REG_BEG_START:
+ case IN_REG_START:
+ if (events[j].type == REG_BEG_START &&
+ (grub_addr_t) (events[j].reg + 1) > target)
+ regbeg++;
+ else
+ inreg++;
+ last_start = j;
+ break;
+
+ case REG_BEG_END:
+ case IN_REG_END:
+ if (regbeg)
+ regbeg--;
+ else
+ inreg--;
+ break;
+
+#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
+ case REG_FIRMWARE_START:
+ fwin++;
+ break;
+
+ case REG_FIRMWARE_END:
+ fwin--;
+ break;
+
+ case FIRMWARE_BLOCK_START:
+ fwb++;
+ break;
+
+ case FIRMWARE_BLOCK_END:
+ fwb--;
+ break;
+#endif
+
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
+ case REG_LEFTOVER_START:
+ fwlefto++;
+ last_lo = j;
+ break;
+
+ case REG_LEFTOVER_END:
+ fwlefto--;
+ break;
+#endif
+ case COLLISION_START:
+ ncol++;
+ break;
+ case COLLISION_END:
+ ncol--;
+ break;
+ }
+
+ }
+ }
+
+ /* Malloc is available again. */
+ grub_mm_base = base_saved;
+
+ grub_free (eventt);
+ grub_free (counter);
+
+ {
+ int last_start = 0;
+ int inreg = 0, regbeg = 0, ncol = 0;
+#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
+ int fwin = 0, fwlefto = 0, fwb = 0;
+#endif
+ unsigned cural = 0;
+ int oom = 0;
+ res->subchunks = grub_malloc (sizeof (res->subchunks[0]) * nallocs);
+ if (!res->subchunks)
+ oom = 1;
+ res->nsubchunks = nallocs;
+
+ for (j = 0; j < N; j++)
+ {
+ int typepre;
+ if (ncol)
+ typepre = -1;
+ else if (regbeg)
+ typepre = CHUNK_TYPE_REGION_START;
+ else if (inreg)
+ typepre = CHUNK_TYPE_IN_REGION;
+#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
+ else if (fwin && !fwb)
+ typepre = CHUNK_TYPE_FIRMWARE;
+ else if (fwlefto && !fwb)
+ typepre = CHUNK_TYPE_LEFTOVER;
+#endif
+ else
+ typepre = -1;
+
+ if (j != 0 && events[j - 1].pos != events[j].pos)
+ {
+ grub_addr_t alloc_start, alloc_end;
+ struct grub_relocator_subchunk tofree;
+ struct grub_relocator_subchunk *curschu = &tofree;
+ if (!oom)
+ curschu = &res->subchunks[cural];
+ alloc_start = max (events[j - 1].pos, target);
+ alloc_end = min (events[j].pos, target + size);
+ if (alloc_end > alloc_start)
+ {
+#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
+ grub_dprintf ("relocator", "subchunk 0x%lx-0x%lx, %d\n",
+ (unsigned long) alloc_start,
+ (unsigned long) alloc_end, typepre);
+#endif
+ curschu->type = typepre;
+ curschu->start = alloc_start;
+ curschu->size = alloc_end - alloc_start;
+ if (typepre == CHUNK_TYPE_REGION_START
+ || typepre == CHUNK_TYPE_IN_REGION)
+ {
+ curschu->reg = events[last_start].reg;
+ curschu->pre_size = alloc_start - events[j - 1].pos;
+ }
+ if (!oom && (typepre == CHUNK_TYPE_REGION_START
+#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
+ || typepre == CHUNK_TYPE_FIRMWARE
+#endif
+ ))
+ {
+ struct grub_relocator_extra_block *ne;
+ ne = grub_malloc (sizeof (*ne));
+ if (!ne)
+ {
+ oom = 1;
+ grub_memcpy (&tofree, curschu, sizeof (tofree));
+ }
+ else
+ {
+ ne->start = alloc_start;
+ ne->end = alloc_end;
+ ne->next = extra_blocks;
+ ne->prev = &extra_blocks;
+ if (extra_blocks)
+ extra_blocks->prev = &(ne->next);
+ extra_blocks = ne;
+ curschu->extra = ne;
+ }
+ }
+
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
+ if (!oom && typepre == CHUNK_TYPE_FIRMWARE)
+ {
+ grub_addr_t fstart, fend;
+
+ fstart
+ = ALIGN_DOWN (alloc_start,
+ GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT);
+ fend
+ = ALIGN_UP (alloc_end,
+ GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT);
+
+ {
+ struct grub_relocator_fw_leftover *lo1 = NULL;
+ struct grub_relocator_fw_leftover *lo2 = NULL;
+ if (fstart != alloc_start)
+ lo1 = grub_malloc (sizeof (*lo1));
+ if (fend != alloc_end)
+ lo2 = grub_malloc (sizeof (*lo2));
+ if ((!lo1 && fstart != alloc_start)
+ || (!lo2 && fend != alloc_end))
+ {
+ struct grub_relocator_extra_block *ne;
+ grub_free (lo1);
+ grub_free (lo2);
+ lo1 = NULL;
+ lo2 = NULL;
+ oom = 1;
+ grub_memcpy (&tofree, curschu, sizeof (tofree));
+ ne = extra_blocks;
+ extra_blocks = extra_blocks->next;
+ grub_free (ne);
+ }
+ if (lo1)
+ {
+ lo1->quantstart = fstart;
+ grub_memset (lo1->freebytes, 0xff,
+ (alloc_start - fstart) / 8);
+ lo1->freebytes[(alloc_start - fstart) / 8]
+ = (1 << ((alloc_start - fstart) % 8)) - 1;
+ grub_memset (lo1->freebytes
+ + ((alloc_start - fstart) / 8) + 1, 0,
+ sizeof (lo1->freebytes)
+ - (alloc_start - fstart) / 8 - 1);
+ lo1->next = leftovers;
+ lo1->prev = &leftovers;
+ if (leftovers)
+ leftovers->prev = &lo1->next;
+ leftovers = lo1;
+ }
+ if (lo2)
+ {
+ lo2->quantstart
+ = fend - GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT;
+ grub_memset (lo2->freebytes, 0,
+ (alloc_end - lo2->quantstart) / 8);
+ lo2->freebytes[(alloc_end - lo2->quantstart) / 8]
+ = ~((1 << ((alloc_end - lo2->quantstart) % 8)) - 1);
+ grub_memset (lo2->freebytes
+ + ((alloc_end - lo2->quantstart) / 8)
+ + 1, 0, sizeof (lo2->freebytes)
+ - (alloc_end - lo2->quantstart) / 8 - 1);
+ lo2->prev = &leftovers;
+ if (leftovers)
+ leftovers->prev = &lo2->next;
+ lo2->next = leftovers;
+ leftovers = lo2;
+ }
+ curschu->pre = lo1;
+ curschu->post = lo2;
+ }
+ }
+
+ if (typepre == CHUNK_TYPE_LEFTOVER)
+ {
+ curschu->pre = events[last_start].leftover;
+ curschu->post = events[last_start].leftover;
+ }
+#endif
+
+ if (!oom)
+ cural++;
+ else
+ free_subchunk (&tofree);
+ }
+ }
+
+ switch (events[j].type)
+ {
+ case REG_BEG_START:
+ case IN_REG_START:
+ if (events[j].type == REG_BEG_START &&
+ (grub_addr_t) (events[j].reg + 1) > target)
+ regbeg++;
+ else
+ inreg++;
+ last_start = j;
+ break;
+
+ case REG_BEG_END:
+ case IN_REG_END:
+ inreg = regbeg = 0;
+ break;
+
+#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
+ case REG_FIRMWARE_START:
+ fwin++;
+ break;
+
+ case REG_FIRMWARE_END:
+ fwin--;
+ break;
+
+ case FIRMWARE_BLOCK_START:
+ fwb++;
+ break;
+
+ case FIRMWARE_BLOCK_END:
+ fwb--;
+ break;
+#endif
+
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
+ case REG_LEFTOVER_START:
+ fwlefto++;
+ break;
+
+ case REG_LEFTOVER_END:
+ fwlefto--;
+ break;
+#endif
+ case COLLISION_START:
+ ncol++;
+ break;
+ case COLLISION_END:
+ ncol--;
+ break;
+ }
+ }
+ if (oom)
+ {
+ unsigned i;
+ for (i = 0; i < cural; i++)
+ free_subchunk (&res->subchunks[i]);
+ grub_free (res->subchunks);
+ grub_dprintf ("relocator", "allocation failed with out-of-memory\n");
+ grub_free (events);
+
+ return 0;
+ }
+ }
+
+ res->src = target;
+ res->size = size;
+
+ grub_free (events);
+
+ grub_dprintf ("relocator", "allocated: 0x%lx+0x%lx\n", (unsigned long) target,
+ (unsigned long) size);
+
+ return 1;
+}
+
+static void
+adjust_limits (struct grub_relocator *rel,
+ grub_phys_addr_t *min_addr, grub_phys_addr_t *max_addr,
+ grub_phys_addr_t in_min, grub_phys_addr_t in_max)
+{
+ struct grub_relocator_chunk *chunk;
+
+ *min_addr = 0;
+ *max_addr = rel->postchunks;
+
+ /* Keep chunks in memory in the same order as they'll be after relocation. */
+ for (chunk = rel->chunks; chunk; chunk = chunk->next)
+ {
+ if (chunk->target > in_max && chunk->src < *max_addr
+ && chunk->src < rel->postchunks)
+ *max_addr = chunk->src;
+ if (chunk->target + chunk->size <= in_min
+ && chunk->src + chunk->size > *min_addr
+ && chunk->src < rel->postchunks)
+ *min_addr = chunk->src + chunk->size;
+ }
+}
+
+grub_err_t
+grub_relocator_alloc_chunk_addr (struct grub_relocator *rel,
+ grub_relocator_chunk_t *out,
+ grub_phys_addr_t target, grub_size_t size)
+{
+ struct grub_relocator_chunk *chunk;
+ grub_phys_addr_t min_addr = 0, max_addr;
+
+ if (target > ~size)
+ return grub_error (GRUB_ERR_BUG, "address is out of range");
+
+ adjust_limits (rel, &min_addr, &max_addr, target, target);
+
+ for (chunk = rel->chunks; chunk; chunk = chunk->next)
+ if ((chunk->target <= target && target < chunk->target + chunk->size)
+ || (target <= chunk->target && chunk->target < target + size))
+ return grub_error (GRUB_ERR_BUG, "overlap detected");
+
+ chunk = grub_malloc (sizeof (struct grub_relocator_chunk));
+ if (!chunk)
+ return grub_errno;
+
+ grub_dprintf ("relocator",
+ "min_addr = 0x%llx, max_addr = 0x%llx, target = 0x%llx\n",
+ (unsigned long long) min_addr, (unsigned long long) max_addr,
+ (unsigned long long) target);
+
+ do
+ {
+ /* A trick to improve Linux allocation. */
+#if defined (__i386__) || defined (__x86_64__)
+ if (target < 0x100000)
+ if (malloc_in_range (rel, rel->highestnonpostaddr, ~(grub_addr_t)0, 1,
+ size, chunk, 0, 1))
+ {
+ if (rel->postchunks > chunk->src)
+ rel->postchunks = chunk->src;
+ break;
+ }
+#elif defined(__mips__) && (_MIPS_SIM == _ABI64)
+ if (malloc_in_range (rel, target, max_addr, 8, size, chunk, 1, 0))
+ break;
+#endif
+ if (malloc_in_range (rel, target, max_addr, 1, size, chunk, 1, 0))
+ break;
+
+ if (malloc_in_range (rel, min_addr, target, 1, size, chunk, 0, 0))
+ break;
+
+ if (malloc_in_range (rel, rel->highestnonpostaddr, ~(grub_addr_t)0, 1,
+ size, chunk, 0, 1))
+ {
+ if (rel->postchunks > chunk->src)
+ rel->postchunks = chunk->src;
+ break;
+ }
+
+ grub_dprintf ("relocator", "not allocated\n");
+ grub_free (chunk);
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+ }
+ while (0);
+
+ grub_dprintf ("relocator", "allocated 0x%llx/0x%llx\n",
+ (unsigned long long) chunk->src, (unsigned long long) target);
+
+ if (rel->highestaddr < target + size)
+ rel->highestaddr = target + size;
+
+ if (rel->highestaddr < chunk->src + size)
+ rel->highestaddr = chunk->src + size;
+
+ if (chunk->src < rel->postchunks)
+ {
+ if (rel->highestnonpostaddr < target + size)
+ rel->highestnonpostaddr = target + size;
+
+ if (rel->highestnonpostaddr < chunk->src + size)
+ rel->highestnonpostaddr = chunk->src + size;
+ }
+
+ grub_dprintf ("relocator", "relocators_size=%ld\n",
+ (unsigned long) rel->relocators_size);
+
+ if (chunk->src < target)
+ rel->relocators_size += grub_relocator_backward_size;
+ if (chunk->src > target)
+ rel->relocators_size += grub_relocator_forward_size;
+
+ grub_dprintf ("relocator", "relocators_size=%ld\n",
+ (unsigned long) rel->relocators_size);
+
+ chunk->target = target;
+ chunk->size = size;
+ chunk->next = rel->chunks;
+ rel->chunks = chunk;
+ grub_dprintf ("relocator", "cur = %p, next = %p\n", rel->chunks,
+ rel->chunks->next);
+
+ chunk->srcv = grub_map_memory (chunk->src, chunk->size);
+ *out = chunk;
+#ifdef DEBUG_RELOCATOR
+ grub_memset (chunk->srcv, 0xfa, chunk->size);
+ grub_mm_check ();
+#endif
+ return GRUB_ERR_NONE;
+}
+
+/* Context for grub_relocator_alloc_chunk_align. */
+struct grub_relocator_alloc_chunk_align_ctx
+{
+ grub_phys_addr_t min_addr, max_addr;
+ grub_size_t size, align;
+ int preference;
+ struct grub_relocator_chunk *chunk;
+ int found;
+};
+
+/* Helper for grub_relocator_alloc_chunk_align. */
+static int
+grub_relocator_alloc_chunk_align_iter (grub_uint64_t addr, grub_uint64_t sz,
+ grub_memory_type_t type, void *data)
+{
+ struct grub_relocator_alloc_chunk_align_ctx *ctx = data;
+ grub_uint64_t candidate;
+
+ if (type != GRUB_MEMORY_AVAILABLE)
+ return 0;
+ candidate = ALIGN_UP (addr, ctx->align);
+ if (candidate < ctx->min_addr)
+ candidate = ALIGN_UP (ctx->min_addr, ctx->align);
+ if (candidate + ctx->size > addr + sz
+ || candidate > ALIGN_DOWN (ctx->max_addr, ctx->align))
+ return 0;
+ if (ctx->preference == GRUB_RELOCATOR_PREFERENCE_HIGH)
+ candidate = ALIGN_DOWN (min (addr + sz - ctx->size, ctx->max_addr),
+ ctx->align);
+ if (!ctx->found || (ctx->preference == GRUB_RELOCATOR_PREFERENCE_HIGH
+ && candidate > ctx->chunk->target))
+ ctx->chunk->target = candidate;
+ if (!ctx->found || (ctx->preference == GRUB_RELOCATOR_PREFERENCE_LOW
+ && candidate < ctx->chunk->target))
+ ctx->chunk->target = candidate;
+ ctx->found = 1;
+ return 0;
+}
+
+grub_err_t
+grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
+ grub_relocator_chunk_t *out,
+ grub_phys_addr_t min_addr,
+ grub_phys_addr_t max_addr,
+ grub_size_t size, grub_size_t align,
+ int preference,
+ int avoid_efi_boot_services)
+{
+ struct grub_relocator_alloc_chunk_align_ctx ctx = {
+ .min_addr = min_addr,
+ .max_addr = max_addr,
+ .size = size,
+ .align = align,
+ .preference = preference,
+ .found = 0
+ };
+ grub_addr_t min_addr2 = 0, max_addr2;
+
+ if (max_addr > ~size)
+ max_addr = ~size;
+
+#ifdef GRUB_MACHINE_PCBIOS
+ if (min_addr < 0x1000)
+ min_addr = 0x1000;
+#endif
+
+ grub_dprintf ("relocator", "chunks = %p\n", rel->chunks);
+
+ ctx.chunk = grub_malloc (sizeof (struct grub_relocator_chunk));
+ if (!ctx.chunk)
+ return grub_errno;
+
+ if (malloc_in_range (rel, min_addr, max_addr, align,
+ size, ctx.chunk,
+ preference != GRUB_RELOCATOR_PREFERENCE_HIGH, 1))
+ {
+ grub_dprintf ("relocator", "allocated 0x%llx/0x%llx\n",
+ (unsigned long long) ctx.chunk->src,
+ (unsigned long long) ctx.chunk->src);
+ grub_dprintf ("relocator", "chunks = %p\n", rel->chunks);
+ ctx.chunk->target = ctx.chunk->src;
+ ctx.chunk->size = size;
+ ctx.chunk->next = rel->chunks;
+ rel->chunks = ctx.chunk;
+ ctx.chunk->srcv = grub_map_memory (ctx.chunk->src, ctx.chunk->size);
+ *out = ctx.chunk;
+ return GRUB_ERR_NONE;
+ }
+
+ adjust_limits (rel, &min_addr2, &max_addr2, min_addr, max_addr);
+ grub_dprintf ("relocator", "Adjusted limits from %lx-%lx to %lx-%lx\n",
+ (unsigned long) min_addr, (unsigned long) max_addr,
+ (unsigned long) min_addr2, (unsigned long) max_addr2);
+
+ do
+ {
+ if (malloc_in_range (rel, min_addr2, max_addr2, align,
+ size, ctx.chunk, 1, 1))
+ break;
+
+ if (malloc_in_range (rel, rel->highestnonpostaddr, ~(grub_addr_t)0, 1,
+ size, ctx.chunk, 0, 1))
+ {
+ if (rel->postchunks > ctx.chunk->src)
+ rel->postchunks = ctx.chunk->src;
+ break;
+ }
+
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+ }
+ while (0);
+
+ {
+#ifdef GRUB_MACHINE_EFI
+ grub_efi_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx,
+ avoid_efi_boot_services);
+#elif defined (__powerpc__) || defined (GRUB_MACHINE_XEN)
+ (void) avoid_efi_boot_services;
+ grub_machine_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx);
+#else
+ (void) avoid_efi_boot_services;
+ grub_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx);
+#endif
+ if (!ctx.found)
+ return grub_error (GRUB_ERR_BAD_OS, "couldn't find suitable memory target");
+ }
+ while (1)
+ {
+ struct grub_relocator_chunk *chunk2;
+ for (chunk2 = rel->chunks; chunk2; chunk2 = chunk2->next)
+ if ((chunk2->target <= ctx.chunk->target
+ && ctx.chunk->target < chunk2->target + chunk2->size)
+ || (ctx.chunk->target <= chunk2->target && chunk2->target
+ < ctx.chunk->target + size))
+ {
+ if (preference == GRUB_RELOCATOR_PREFERENCE_HIGH)
+ ctx.chunk->target = ALIGN_DOWN (chunk2->target, align);
+ else
+ ctx.chunk->target = ALIGN_UP (chunk2->target + chunk2->size,
+ align);
+ break;
+ }
+ if (!chunk2)
+ break;
+ }
+
+ grub_dprintf ("relocator", "relocators_size=%ld\n",
+ (unsigned long) rel->relocators_size);
+
+ if (ctx.chunk->src < ctx.chunk->target)
+ rel->relocators_size += grub_relocator_backward_size;
+ if (ctx.chunk->src > ctx.chunk->target)
+ rel->relocators_size += grub_relocator_forward_size;
+
+ grub_dprintf ("relocator", "relocators_size=%ld\n",
+ (unsigned long) rel->relocators_size);
+
+ ctx.chunk->size = size;
+ ctx.chunk->next = rel->chunks;
+ rel->chunks = ctx.chunk;
+ grub_dprintf ("relocator", "cur = %p, next = %p\n", rel->chunks,
+ rel->chunks->next);
+ ctx.chunk->srcv = grub_map_memory (ctx.chunk->src, ctx.chunk->size);
+ *out = ctx.chunk;
+#ifdef DEBUG_RELOCATOR
+ grub_memset (ctx.chunk->srcv, 0xfa, ctx.chunk->size);
+ grub_mm_check ();
+#endif
+ return GRUB_ERR_NONE;
+}
+
+void
+grub_relocator_unload (struct grub_relocator *rel)
+{
+ struct grub_relocator_chunk *chunk, *next;
+ if (!rel)
+ return;
+ for (chunk = rel->chunks; chunk; chunk = next)
+ {
+ unsigned i;
+ for (i = 0; i < chunk->nsubchunks; i++)
+ free_subchunk (&chunk->subchunks[i]);
+ grub_unmap_memory (chunk->srcv, chunk->size);
+ next = chunk->next;
+ grub_free (chunk->subchunks);
+ grub_free (chunk);
+ }
+ grub_free (rel);
+}
+
+grub_err_t
+grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr,
+ void **relstart, grub_size_t *relsize)
+{
+ grub_uint8_t *rels;
+ grub_uint8_t *rels0;
+ struct grub_relocator_chunk *sorted;
+ grub_size_t nchunks = 0;
+ unsigned j;
+ struct grub_relocator_chunk movers_chunk;
+
+ grub_dprintf ("relocator", "Preparing relocs (size=%ld)\n",
+ (unsigned long) rel->relocators_size);
+
+ if (!malloc_in_range (rel, 0, ~(grub_addr_t)0 - rel->relocators_size + 1,
+ grub_relocator_align,
+ rel->relocators_size, &movers_chunk, 1, 1))
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+ movers_chunk.srcv = rels = rels0
+ = grub_map_memory (movers_chunk.src, movers_chunk.size);
+
+ if (relsize)
+ *relsize = rel->relocators_size;
+
+ grub_dprintf ("relocator", "Relocs allocated at %p\n", movers_chunk.srcv);
+
+ {
+ unsigned i;
+ grub_size_t count[257];
+ struct grub_relocator_chunk *from, *to, *tmp;
+
+ grub_memset (count, 0, sizeof (count));
+
+ {
+ struct grub_relocator_chunk *chunk;
+ for (chunk = rel->chunks; chunk; chunk = chunk->next)
+ {
+ grub_dprintf ("relocator", "chunk %p->%p, 0x%lx\n",
+ (void *) chunk->src, (void *) chunk->target,
+ (unsigned long) chunk->size);
+ nchunks++;
+ count[(chunk->src & 0xff) + 1]++;
+ }
+ }
+ from = grub_malloc (nchunks * sizeof (sorted[0]));
+ to = grub_malloc (nchunks * sizeof (sorted[0]));
+ if (!from || !to)
+ {
+ grub_free (from);
+ grub_free (to);
+ return grub_errno;
+ }
+
+ for (j = 0; j < 256; j++)
+ count[j+1] += count[j];
+
+ {
+ struct grub_relocator_chunk *chunk;
+ for (chunk = rel->chunks; chunk; chunk = chunk->next)
+ from[count[chunk->src & 0xff]++] = *chunk;
+ }
+
+ for (i = 1; i < GRUB_CPU_SIZEOF_VOID_P; i++)
+ {
+ grub_memset (count, 0, sizeof (count));
+ for (j = 0; j < nchunks; j++)
+ count[((from[j].src >> (8 * i)) & 0xff) + 1]++;
+ for (j = 0; j < 256; j++)
+ count[j+1] += count[j];
+ for (j = 0; j < nchunks; j++)
+ to[count[(from[j].src >> (8 * i)) & 0xff]++] = from[j];
+ tmp = to;
+ to = from;
+ from = tmp;
+ }
+ sorted = from;
+ grub_free (to);
+ }
+
+ for (j = 0; j < nchunks; j++)
+ {
+ grub_dprintf ("relocator", "sorted chunk %p->%p, 0x%lx\n",
+ (void *) sorted[j].src, (void *) sorted[j].target,
+ (unsigned long) sorted[j].size);
+ if (sorted[j].src < sorted[j].target)
+ {
+ grub_cpu_relocator_backward ((void *) rels,
+ sorted[j].srcv,
+ grub_map_memory (sorted[j].target,
+ sorted[j].size),
+ sorted[j].size);
+ rels += grub_relocator_backward_size;
+ }
+ if (sorted[j].src > sorted[j].target)
+ {
+ grub_cpu_relocator_forward ((void *) rels,
+ sorted[j].srcv,
+ grub_map_memory (sorted[j].target,
+ sorted[j].size),
+ sorted[j].size);
+ rels += grub_relocator_forward_size;
+ }
+ if (sorted[j].src == sorted[j].target)
+ grub_arch_sync_caches (sorted[j].srcv, sorted[j].size);
+ }
+ grub_cpu_relocator_jumper ((void *) rels, (grub_addr_t) addr);
+ *relstart = rels0;
+ grub_free (sorted);
+ return GRUB_ERR_NONE;
+}
+
+void
+grub_mm_check_real (const char *file, int line)
+{
+ grub_mm_region_t r;
+ grub_mm_header_t p, pa;
+
+ for (r = grub_mm_base; r; r = r->next)
+ {
+ pa = r->first;
+ p = pa->next;
+ if (p->magic == GRUB_MM_ALLOC_MAGIC)
+ continue;
+ do
+ {
+ if ((grub_addr_t) p < (grub_addr_t) (r + 1)
+ || (grub_addr_t) p >= (grub_addr_t) (r + 1) + r->size)
+ grub_fatal ("%s:%d: out of range pointer: %p\n", file, line, p);
+ if (p->magic != GRUB_MM_FREE_MAGIC)
+ grub_fatal ("%s:%d free magic broken at %p (0x%x)\n", file,
+ line, p, p->magic);
+ pa = p;
+ p = pa->next;
+ }
+ while (pa != r->first);
+ }
+}
--- /dev/null
+#if defined(__i386__)
+#include "./i386/setjmp.S"
+#elif defined(__x86_64__)
+#include "./x86_64/setjmp.S"
+#elif defined(__sparc__)
+#include "./sparc64/setjmp.S"
+#elif defined(__mips__)
+#if _MIPS_SIM == _ABI64
+#include "./mips64/setjmp.S"
+#else
+#include "./mips/setjmp.S"
+#endif
+#elif defined(__powerpc__) || defined(__PPC__)
+#include "./powerpc/setjmp.S"
+#elif defined(__ia64__)
+#include "./ia64/setjmp.S"
+#include "./ia64/longjmp.S"
+#elif defined(__arm__)
+#include "./arm/setjmp.S"
+#elif defined(__aarch64__)
+#include "./arm64/setjmp.S"
+#elif defined(__riscv)
+#include "./riscv/setjmp.S"
+#else
+#error "Unknown target cpu type"
+#endif
--- /dev/null
+/* linux.c - boot Linux */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2003,2004,2005,2007,2009,2010,2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/elf.h>
+#include <grub/elfload.h>
+#include <grub/loader.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+#include <grub/cpu/relocator.h>
+#include <grub/machine/loongson.h>
+#include <grub/memory.h>
+#include <grub/i18n.h>
+#include <grub/lib/cmdline.h>
+#include <grub/linux.h>
+#include <grub/term.h>
+#include <grub/env.h>
+
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+#define _ull unsigned long long
+#pragma GCC diagnostic ignored "-Wcast-align"
+
+typedef unsigned long size_t;
+
+static grub_dl_t my_mod;
+
+static int loaded;
+
+static grub_uint32_t tmp_index = 0;
+static grub_size_t linux_size;
+
+static struct grub_relocator *relocator;
+static grub_addr_t target_addr, entry_addr;
+static int linux_argc;
+static grub_uint8_t *linux_args_addr;
+static grub_off_t rd_addr_arg_off, rd_size_arg_off;
+static int initrd_loaded = 0;
+
+
+static grub_uint32_t j = 0;
+static grub_uint32_t t = 0;
+grub_uint64_t tempMemsize = 0;
+grub_uint32_t free_index = 0;
+grub_uint32_t reserve_index = 0;
+grub_uint32_t acpi_table_index = 0;
+grub_uint32_t acpi_nvs_index = 0;
+
+#define LINUX_MAX_ARGC 1024
+static int ventoy_debug = 0;
+static int ventoy_initrd_called = 0;
+static int ventoy_linux_argc = 0;
+static char **ventoy_linux_args = NULL;
+static int ventoy_extra_initrd_num = 0;
+static char *ventoy_extra_initrd_list[256];
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char *argv[]);
+
+
+
+static inline grub_size_t
+page_align (grub_size_t size)
+{
+ return (size + (1 << 12) - 1) & (~((1 << 12) - 1));
+}
+
+/* Find the optimal number of pages for the memory map. Is it better to
+ move this code to efi/mm.c? */
+static grub_efi_uintn_t
+find_mmap_size (void)
+{
+ static grub_efi_uintn_t mmap_size = 0;
+
+ if (mmap_size != 0)
+ return mmap_size;
+
+ mmap_size = (1 << 12);
+ while (1)
+ {
+ int ret;
+ grub_efi_memory_descriptor_t *mmap;
+ grub_efi_uintn_t desc_size;
+
+ mmap = grub_malloc (mmap_size);
+ if (! mmap)
+ return 0;
+
+ ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
+ grub_free (mmap);
+
+ if (ret < 0)
+ {
+ grub_error (GRUB_ERR_IO, "cannot get memory map");
+ return 0;
+ }
+ else if (ret > 0)
+ break;
+
+ mmap_size += (1 << 12);
+ }
+
+
+ /* Increase the size a bit for safety, because GRUB allocates more on
+ later, and EFI itself may allocate more. */
+ mmap_size += (1 << 12);
+
+ return page_align (mmap_size);
+}
+
+
+static void ventoy_debug_pause(void)
+{
+ char key;
+
+ if (0 == ventoy_debug)
+ {
+ return;
+ }
+
+ grub_printf("press Enter to continue ......\n");
+ while (1)
+ {
+ key = grub_getkey();
+ if (key == '\n' || key == '\r')
+ {
+ break;
+ }
+ }
+}
+
+static int ventoy_preboot(void)
+{
+ int i;
+ const char *file;
+ char buf[128];
+
+ if (ventoy_debug)
+ {
+ grub_printf("ventoy_preboot %d %d\n", ventoy_linux_argc, ventoy_initrd_called);
+ ventoy_debug_pause();
+ }
+
+ if (ventoy_linux_argc == 0)
+ {
+ return 0;
+ }
+
+ if (ventoy_initrd_called)
+ {
+ ventoy_initrd_called = 0;
+ return 0;
+ }
+
+ grub_snprintf(buf, sizeof(buf), "mem:%s:size:%s", grub_env_get("ventoy_cpio_addr"), grub_env_get("ventoy_cpio_size"));
+
+ ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf);
+
+ file = grub_env_get("vtoy_img_part_file");
+ if (file)
+ {
+ ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(file);
+ }
+
+ if (ventoy_debug)
+ {
+ grub_printf("========== initrd list ==========\n");
+ for (i = 0; i < ventoy_extra_initrd_num; i++)
+ {
+ grub_printf("%s\n", ventoy_extra_initrd_list[i]);
+ }
+ grub_printf("=================================\n");
+
+ ventoy_debug_pause();
+ }
+
+ grub_cmd_initrd(NULL, ventoy_extra_initrd_num, ventoy_extra_initrd_list);
+
+ return 0;
+}
+
+static int ventoy_boot_opt_filter(char *opt)
+{
+ if (grub_strcmp(opt, "noinitrd") == 0)
+ {
+ return 1;
+ }
+
+ if (grub_strcmp(opt, "vga=current") == 0)
+ {
+ return 1;
+ }
+
+ if (grub_strncmp(opt, "rdinit=", 7) == 0)
+ {
+ if (grub_strcmp(opt, "rdinit=/vtoy/vtoy") != 0)
+ {
+ opt[0] = 'v';
+ opt[1] = 't';
+ }
+ return 0;
+ }
+
+ if (grub_strncmp(opt, "init=", 5) == 0)
+ {
+ opt[0] = 'v';
+ opt[1] = 't';
+ return 0;
+ }
+
+ if (ventoy_debug)
+ {
+ if (grub_strcmp(opt, "quiet") == 0)
+ {
+ return 1;
+ }
+
+ if (grub_strncmp(opt, "loglevel=", 9) == 0)
+ {
+ return 1;
+ }
+
+ if (grub_strcmp(opt, "splash") == 0)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int ventoy_bootopt_hook(int argc, char *argv[])
+{
+ int i;
+ int count = 0;
+ const char *env;
+ char c;
+ char *newenv;
+ char *last, *pos;
+
+ //grub_printf("ventoy_bootopt_hook: %d %d\n", argc, ventoy_linux_argc);
+
+ if (ventoy_linux_argc == 0)
+ {
+ return 0;
+ }
+
+ /* the 1st parameter is BOOT_IMAGE=xxxx */
+ if (argc > 0 && 0 == ventoy_boot_opt_filter(argv[0]))
+ {
+ ventoy_linux_args[count++] = grub_strdup(argv[0]);
+ }
+
+ for (i = 0; i < ventoy_linux_argc; i++)
+ {
+ ventoy_linux_args[count] = ventoy_linux_args[i + (LINUX_MAX_ARGC / 2)];
+ ventoy_linux_args[i + (LINUX_MAX_ARGC / 2)] = NULL;
+
+ if (ventoy_linux_args[count][0] == '@')
+ {
+ env = grub_env_get(ventoy_linux_args[count] + 1);
+ if (env)
+ {
+ grub_free(ventoy_linux_args[count]);
+
+ newenv = grub_strdup(env);
+ last = newenv;
+
+ while (*last)
+ {
+ while (*last)
+ {
+ if (*last != ' ' && *last != '\t')
+ {
+ break;
+ }
+ last++;
+ }
+
+ if (*last == 0)
+ {
+ break;
+ }
+
+ for (pos = last; *pos; pos++)
+ {
+ if (*pos == ' ' || *pos == '\t')
+ {
+ c = *pos;
+ *pos = 0;
+ if (0 == ventoy_boot_opt_filter(last))
+ {
+ ventoy_linux_args[count++] = grub_strdup(last);
+ }
+ *pos = c;
+ break;
+ }
+ }
+
+ if (*pos == 0)
+ {
+ if (0 == ventoy_boot_opt_filter(last))
+ {
+ ventoy_linux_args[count++] = grub_strdup(last);
+ }
+ break;
+ }
+
+ last = pos + 1;
+ }
+ }
+ else
+ {
+ count++;
+ }
+ }
+ else
+ {
+ count++;
+ }
+ }
+
+ /* We have processed the 1st parameter before, so start from 1 */
+ for (i = 1; i < argc; i++)
+ {
+ if (ventoy_boot_opt_filter(argv[i]))
+ {
+ continue;
+ }
+
+ ventoy_linux_args[count++] = grub_strdup(argv[i]);
+ }
+
+ if (ventoy_debug)
+ {
+ ventoy_linux_args[count++] = grub_strdup("loglevel=7");
+ }
+
+ ventoy_linux_argc = count;
+
+ if (ventoy_debug)
+ {
+ grub_printf("========== bootoption ==========\n");
+ for (i = 0; i < count; i++)
+ {
+ grub_printf("%s ", ventoy_linux_args[i]);
+ }
+ grub_printf("\n================================\n");
+ }
+
+ return 0;
+}
+
+static grub_err_t
+grub_cmd_set_boot_opt (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char *argv[])
+{
+ int i;
+ const char *vtdebug;
+
+ for (i = 0; i < argc; i++)
+ {
+ ventoy_linux_args[ventoy_linux_argc + (LINUX_MAX_ARGC / 2) ] = grub_strdup(argv[i]);
+ ventoy_linux_argc++;
+ }
+
+ vtdebug = grub_env_get("vtdebug_flag");
+ if (vtdebug && vtdebug[0])
+ {
+ ventoy_debug = 1;
+ }
+
+ if (ventoy_debug) grub_printf("ventoy set boot opt %d\n", ventoy_linux_argc);
+
+ return 0;
+}
+
+static grub_err_t
+grub_cmd_unset_boot_opt (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char *argv[])
+{
+ int i;
+
+ (void)argc;
+ (void)argv;
+
+ for (i = 0; i < LINUX_MAX_ARGC; i++)
+ {
+ if (ventoy_linux_args[i])
+ {
+ grub_free(ventoy_linux_args[i]);
+ }
+ }
+
+ ventoy_debug = 0;
+ ventoy_linux_argc = 0;
+ ventoy_initrd_called = 0;
+ grub_memset(ventoy_linux_args, 0, sizeof(char *) * LINUX_MAX_ARGC);
+ return 0;
+}
+
+static grub_err_t
+grub_cmd_extra_initrd_append (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char *argv[])
+{
+ int newclen = 0;
+ char *pos = NULL;
+ char *end = NULL;
+ char buf[256] = {0};
+
+ if (argc != 1)
+ {
+ return 1;
+ }
+
+ for (pos = argv[0]; *pos; pos++)
+ {
+ if (*pos == '/')
+ {
+ end = pos;
+ }
+ }
+
+ if (end)
+ {
+ /* grub2 newc bug workaround */
+ newclen = (int)grub_strlen(end + 1);
+ if ((110 + newclen) % 4 == 0)
+ {
+ grub_snprintf(buf, sizeof(buf), "newc:.%s:%s", end + 1, argv[0]);
+ }
+ else
+ {
+ grub_snprintf(buf, sizeof(buf), "newc:%s:%s", end + 1, argv[0]);
+ }
+
+ if (ventoy_extra_initrd_num < 256)
+ {
+ ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf);
+ }
+ }
+
+ return 0;
+}
+
+static grub_err_t
+grub_cmd_extra_initrd_reset (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char *argv[])
+{
+ int i;
+
+ (void)argc;
+ (void)argv;
+
+ for (i = 0; i < ventoy_extra_initrd_num; i++)
+ {
+ if (ventoy_extra_initrd_list[i])
+ {
+ grub_free(ventoy_extra_initrd_list[i]);
+ }
+ }
+
+ grub_memset(ventoy_extra_initrd_list, 0, sizeof(ventoy_extra_initrd_list));
+
+ return 0;
+}
+
+
+static grub_err_t
+grub_linux_boot (void)
+{
+ struct grub_relocator64_state state;
+ grub_int8_t checksum = 0;
+ grub_efi_memory_descriptor_t * lsdesc = NULL;
+
+ ventoy_preboot();
+
+ grub_memset (&state, 0, sizeof (state));
+
+ /* Boot the kernel. */
+ state.gpr[1] = entry_addr;
+ grub_dprintf("loongson", "entry_addr is 0x%llx\n", (_ull)state.gpr[1]);
+ state.gpr[4] = linux_argc;
+ grub_dprintf("loongson", "linux_argc is %lld\n", (_ull)state.gpr[4]);
+ state.gpr[5] = (grub_addr_t) linux_args_addr;
+ grub_dprintf("loongson", "args_addr is 0x%llx\n", (_ull)state.gpr[5]);
+
+ if(grub_efi_is_loongson ())
+ {
+ grub_efi_uintn_t mmap_size;
+ grub_efi_uintn_t desc_size;
+ grub_efi_memory_descriptor_t *mmap_buf;
+ grub_err_t err;
+ struct bootparamsinterface * boot_params;
+ void * tmp_boot_params = NULL;
+ grub_efi_uint8_t new_interface_flag = 0;
+ mem_map * new_interface_mem = NULL;
+ char *p = NULL;
+
+ struct memmap reserve_mem[GRUB_EFI_LOONGSON_MMAP_MAX];
+ struct memmap free_mem[GRUB_EFI_LOONGSON_MMAP_MAX];
+ struct memmap acpi_table_mem[GRUB_EFI_LOONGSON_MMAP_MAX];
+ struct memmap acpi_nvs_mem[GRUB_EFI_LOONGSON_MMAP_MAX];
+
+ grub_memset(reserve_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX);
+ grub_memset(free_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX);
+ grub_memset(acpi_table_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX);
+ grub_memset(acpi_nvs_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX);
+
+ tmp_boot_params = grub_efi_loongson_get_boot_params();
+ if(tmp_boot_params == NULL)
+ {
+ grub_printf("not find param\n");
+ return -1;
+ }
+
+ boot_params = (struct bootparamsinterface *)tmp_boot_params;
+ p = (char *)&(boot_params->signature);
+ if(grub_strncmp(p, "BPI", 3) == 0)
+ {
+ /* Check extlist headers */
+ ext_list * listpointer = NULL;
+ listpointer = boot_params->extlist;
+ for( ;listpointer != NULL; listpointer = listpointer->next)
+ {
+ char *pl= (char *)&(listpointer->signature);
+ if(grub_strncmp(pl, "MEM", 3) == 0)
+ {
+ new_interface_mem = (mem_map *)listpointer;
+ }
+ }
+
+ new_interface_flag = 1;
+ grub_dprintf("loongson", "get new parameter interface\n");
+ }else{
+ new_interface_flag = 0;
+ grub_dprintf("loongson", "get old parameter interface\n");
+
+ }
+ state.gpr[6] = (grub_uint64_t)tmp_boot_params;
+ grub_dprintf("loongson", "boot_params is 0x%llx\n", (_ull)state.gpr[6]);
+
+ mmap_size = find_mmap_size ();
+ if (! mmap_size)
+ return grub_errno;
+ mmap_buf = grub_efi_allocate_any_pages (page_align (mmap_size) >> 12);
+ if (! mmap_buf)
+ return grub_error (GRUB_ERR_IO, "cannot allocate memory map");
+ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL,
+ &desc_size, NULL);
+ //grub_printf("%s-%d\n", __func__, __LINE__);
+ if (err)
+ return err;
+
+ if(new_interface_flag)
+ {
+ if (!mmap_buf || !mmap_size || !desc_size)
+ return -1;
+
+ tmp_index = new_interface_mem -> mapcount;
+ //grub_printf("%s-%d mapcount %d\n", __func__, __LINE__, tmp_index);
+
+ /*
+ According to UEFI SPEC,mmap_buf is the accurate Memory Map array \
+ now we can fill platform specific memory structure.
+ */
+ for(lsdesc = mmap_buf; lsdesc < (grub_efi_memory_descriptor_t *)((char *)mmap_buf + mmap_size); lsdesc = (grub_efi_memory_descriptor_t *)((char *)lsdesc + desc_size))
+ {
+ /* Recovery */
+ if((lsdesc->type != GRUB_EFI_ACPI_RECLAIM_MEMORY) && \
+ (lsdesc->type != GRUB_EFI_ACPI_MEMORY_NVS) && \
+ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_DATA) && \
+ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_CODE) && \
+ (lsdesc->type != GRUB_EFI_RESERVED_MEMORY_TYPE) && \
+ (lsdesc->type != GRUB_EFI_PAL_CODE))
+ {
+
+ free_mem[free_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW;
+ free_mem[free_index].memstart = (lsdesc->physical_start) & 0xffffffffffff;
+ free_mem[free_index].memsize = lsdesc->num_pages * 4096;
+ free_index++;
+ /*ACPI*/
+ }else if((lsdesc->type == GRUB_EFI_ACPI_RECLAIM_MEMORY)){
+ acpi_table_mem[acpi_table_index].memtype = GRUB_EFI_LOONGSON_ACPI_TABLE;
+ acpi_table_mem[acpi_table_index].memstart = (lsdesc->physical_start) & 0xffffffffffff;
+ acpi_table_mem[acpi_table_index].memsize = lsdesc->num_pages * 4096;
+ acpi_table_index++;
+
+ }else if((lsdesc->type == GRUB_EFI_ACPI_MEMORY_NVS)){
+ acpi_nvs_mem[acpi_nvs_index].memtype = GRUB_EFI_LOONGSON_ACPI_NVS;
+ acpi_nvs_mem[acpi_nvs_index].memstart = (lsdesc->physical_start) & 0xffffffffffff;
+ acpi_nvs_mem[acpi_nvs_index].memsize = lsdesc->num_pages * 4096;
+ acpi_nvs_index++;
+
+ /* Reserve */
+ }else{
+ reserve_mem[reserve_index].memtype = GRUB_EFI_LOONGSON_MEMORY_RESERVED;
+ reserve_mem[reserve_index].memstart = (lsdesc->physical_start) & 0xffffffffffff;
+ reserve_mem[reserve_index].memsize = lsdesc->num_pages * 4096;
+ reserve_index++;
+ }
+ }
+
+ /* Recovery sort */
+ for(j = 0; j < free_index;)
+ {
+ tempMemsize = free_mem[j].memsize;
+ for(t = j + 1; t < free_index; t++)
+ {
+ if((free_mem[j].memstart + tempMemsize == free_mem[t].memstart) && (free_mem[j].memtype == free_mem[t].memtype))
+ {
+ tempMemsize += free_mem[t].memsize;
+ }else{
+ break;
+ }
+ }
+ if(free_mem[j].memstart >= 0x10000000) /*HIGH MEM*/
+ new_interface_mem->map[tmp_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM_HIGH;
+ else
+ new_interface_mem->map[tmp_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW;
+ new_interface_mem->map[tmp_index].memstart = free_mem[j].memstart;
+ new_interface_mem->map[tmp_index].memsize = tempMemsize;
+ grub_dprintf("loongson", "map[%d]:type %x, start 0x%llx, end 0x%llx\n",
+ tmp_index,
+ new_interface_mem->map[tmp_index].memtype,
+ (_ull)new_interface_mem->map[tmp_index].memstart,
+ (_ull)new_interface_mem->map[tmp_index].memstart+ new_interface_mem->map[tmp_index].memsize
+ );
+ j = t;
+ tmp_index++;
+ }
+
+ /*ACPI Sort*/
+ tmp_index = grub_efi_loongson_memmap_sort(acpi_table_mem, acpi_table_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_ACPI_TABLE);
+ tmp_index = grub_efi_loongson_memmap_sort(acpi_nvs_mem, acpi_nvs_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_ACPI_NVS);
+ /*Reserve Sort*/
+ tmp_index = grub_efi_loongson_memmap_sort(reserve_mem, reserve_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_MEMORY_RESERVED);
+
+ new_interface_mem->mapcount = tmp_index;
+ new_interface_mem->header.checksum = 0;
+ //grub_printf("%s-%d mapcount %d\n", __func__, __LINE__, tmp_index);
+
+ checksum = grub_efi_loongson_grub_calculatechecksum8((grub_uint8_t *)new_interface_mem, new_interface_mem->header.length);
+ new_interface_mem->header.checksum = checksum;
+ }
+ }
+
+ state.jumpreg = 1;
+ grub_relocator64_boot (relocator, state);
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_unload (void)
+{
+ grub_relocator_unload (relocator);
+ grub_dl_unref (my_mod);
+
+ loaded = 0;
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_load32 (grub_elf_t elf, const char *filename)
+{
+ Elf32_Addr base;
+ grub_err_t err;
+ grub_uint8_t *playground;
+
+ /* Linux's entry point incorrectly contains a virtual address. */
+ entry_addr = elf->ehdr.ehdr32.e_entry;
+
+ linux_size = grub_elf32_size (elf, &base, 0);
+ if (linux_size == 0)
+ return grub_errno;
+ target_addr = base;
+ linux_size = ALIGN_UP (base + linux_size - base, 8);
+
+ relocator = grub_relocator_new ();
+ if (!relocator)
+ return grub_errno;
+
+ {
+ grub_relocator_chunk_t ch;
+ err = grub_relocator_alloc_chunk_addr (relocator, &ch,
+ grub_vtop ((void *) target_addr),
+ linux_size);
+ if (err)
+ return err;
+ playground = get_virtual_current_address (ch);
+ }
+
+ /* Now load the segments into the area we claimed. */
+ return grub_elf32_load (elf, filename, playground - base, GRUB_ELF_LOAD_FLAGS_NONE, 0, 0);
+}
+
+static grub_err_t
+grub_linux_load64 (grub_elf_t elf, const char *filename)
+{
+ Elf64_Addr base;
+ grub_err_t err;
+ grub_uint8_t *playground;
+
+ /* Linux's entry point incorrectly contains a virtual address. */
+ entry_addr = elf->ehdr.ehdr64.e_entry;
+ grub_dprintf("loongson", "entry address = 0x%llx\n", (_ull)entry_addr);
+
+ linux_size = grub_elf64_size (elf, &base, 0);
+ grub_dprintf("loongson", "base = 0x%llx\n", (_ull)base);
+
+ if (linux_size == 0)
+ return grub_errno;
+ target_addr = base;
+ linux_size = ALIGN_UP (base + linux_size - base, 8);
+
+ relocator = grub_relocator_new ();
+ if (!relocator)
+ return grub_errno;
+
+ {
+ grub_relocator_chunk_t ch;
+ err = grub_relocator_alloc_chunk_addr (relocator, &ch,
+ grub_vtop ((void *) target_addr),
+ linux_size);
+ if (err)
+ return err;
+ playground = get_virtual_current_address (ch);
+ //playground = 0xffffffff81ee0000; //½«ÄÚºËÖ±½Óloadµ½elfÍ·Ö¸¶¨Äڴ棬¶ø·Çgrub·ÖÅäµÄ¿Õ¼ä
+ //playground = 0xffffffff80200000;
+ }
+
+ grub_printf("playground:0x%llx\n", (_ull)playground);
+
+ /* Now load the segments into the area we claimed. */
+ return grub_elf64_load (elf, filename, playground - base, GRUB_ELF_LOAD_FLAGS_NONE, 0, 0);
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char *argv[])
+{
+ grub_elf_t elf = 0;
+ int size;
+ int i;
+ grub_uint32_t *linux_argv;
+ char *linux_args;
+ grub_err_t err;
+
+ if (argc == 0)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+
+ if (ventoy_linux_argc)
+ {
+ ventoy_bootopt_hook(argc, argv);
+ argc = ventoy_linux_argc;
+ argv = ventoy_linux_args;
+ }
+
+ elf = grub_elf_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
+ if (! elf)
+ return grub_errno;
+
+ if (elf->ehdr.ehdr32.e_type != ET_EXEC)
+ {
+ grub_elf_close (elf);
+ return grub_error (GRUB_ERR_UNKNOWN_OS,
+ N_("this ELF file is not of the right type"));
+ }
+
+ /* Release the previously used memory. */
+ grub_loader_unset ();
+ loaded = 0;
+
+ /* For arguments. */
+ linux_argc = argc;
+ /* Main arguments. */
+ size = (linux_argc) * sizeof (grub_uint32_t);
+ /* Initrd address and size. */
+ size += 2 * sizeof (grub_uint32_t);
+ /* NULL terminator. */
+ size += sizeof (grub_uint32_t);
+ /* First argument is always "a0". */
+ size += ALIGN_UP (sizeof ("a0"), 4);
+ /* Normal arguments. */
+ for (i = 1; i < argc; i++)
+ size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4);
+
+ /* rd arguments. */
+ size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4);
+ size += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4);
+
+ size = ALIGN_UP (size, 8);
+
+ if (grub_elf_is_elf32 (elf))
+ err = grub_linux_load32 (elf, argv[0]);
+ else
+ if (grub_elf_is_elf64 (elf))
+ err = grub_linux_load64 (elf, argv[0]);
+ else
+ err = grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic"));
+
+ grub_elf_close (elf);
+
+ if (err)
+ return err;
+
+ {
+ grub_relocator_chunk_t ch;
+ err = grub_relocator_alloc_chunk_align (relocator, &ch,
+ 0, (0xffffffff - size) + 1,
+ size, 8,
+ GRUB_RELOCATOR_PREFERENCE_HIGH, 0);
+ if (err)
+ return err;
+ linux_args_addr = get_virtual_current_address (ch);
+ }
+
+ linux_argv = (grub_uint32_t *) linux_args_addr;
+ linux_args = (char *) (linux_argv + (linux_argc + 1 + 2));
+
+ grub_memcpy (linux_args, "a0", sizeof ("a0"));
+ *linux_argv = (grub_uint32_t) (grub_addr_t) linux_args;
+ linux_argv++;
+ linux_args += ALIGN_UP (sizeof ("a0"), 4);
+
+ for (i = 1; i < argc; i++)
+ {
+ grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1);
+ *linux_argv = (grub_uint32_t) (grub_addr_t) linux_args;
+ linux_argv++;
+ linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4);
+ }
+
+ /* Reserve space for rd arguments. */
+ rd_addr_arg_off = (grub_uint8_t *) linux_args - linux_args_addr;
+ linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4);
+ *linux_argv = 0;
+ linux_argv++;
+
+ rd_size_arg_off = (grub_uint8_t *) linux_args - linux_args_addr;
+ linux_args += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4);
+ *linux_argv = 0;
+ linux_argv++;
+
+ *linux_argv = 0;
+
+ //wake up other cores
+ {
+ __asm__(
+ "dli $8, 0x900000003ff01000\n\t"
+ "dli $11, 0 \n\t"
+ "dsll $11, 8 \n\t"
+ "or $8, $8,$11 \n\t"
+ "li $9, 0x5a5a \n\t"
+ "sw $9, 32($8) \n\t"
+ "nop \n\t"
+ :
+ :
+ );
+ }
+ grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
+ initrd_loaded = 0;
+ loaded = 1;
+ grub_dl_ref (my_mod);
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char *argv[])
+{
+ grub_size_t size = 0;
+ void *initrd_dest;
+ grub_err_t err;
+ struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
+
+ if (argc == 0)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+
+ if (!loaded)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first"));
+
+ if (initrd_loaded)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "only one initrd command can be issued.");
+
+ if (grub_initrd_init (argc, argv, &initrd_ctx))
+ goto fail;
+
+ size = grub_get_initrd_size (&initrd_ctx);
+
+ {
+ grub_relocator_chunk_t ch;
+ err = grub_relocator_alloc_chunk_align (relocator, &ch,
+ 0, (0xffffffff - size) + 1,
+ size, 0x10000,
+ GRUB_RELOCATOR_PREFERENCE_HIGH, 0);
+
+ if (err)
+ goto fail;
+ initrd_dest = get_virtual_current_address (ch);
+ }
+
+ if (grub_initrd_load (&initrd_ctx, argv, initrd_dest))
+ goto fail;
+
+ grub_snprintf ((char *) linux_args_addr + rd_addr_arg_off,
+ sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), "rd_start=0x%lx",
+ (grub_uint64_t) initrd_dest);
+ ((grub_uint32_t *) linux_args_addr)[linux_argc]
+ = (grub_uint32_t) ((grub_addr_t) linux_args_addr + rd_addr_arg_off);
+ linux_argc++;
+
+ grub_snprintf ((char *) linux_args_addr + rd_size_arg_off,
+ sizeof ("rd_size=0xXXXXXXXXXXXXXXXXX"), "rd_size=0x%lx",
+ (grub_uint64_t) size);
+ ((grub_uint32_t *) linux_args_addr)[linux_argc]
+ = (grub_uint32_t) ((grub_addr_t) linux_args_addr + rd_size_arg_off);
+ linux_argc++;
+
+ initrd_loaded = 1;
+
+ fail:
+ grub_initrd_close (&initrd_ctx);
+
+ return grub_errno;
+}
+
+static grub_err_t
+ventoy_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char *argv[])
+{
+ int i;
+ const char *file;
+ char buf[64];
+
+ if (ventoy_debug) grub_printf("ventoy_cmd_initrd %d\n", ventoy_linux_argc);
+
+ if (ventoy_linux_argc == 0)
+ {
+ return grub_cmd_initrd(cmd, argc, argv);
+ }
+
+ grub_snprintf(buf, sizeof(buf), "mem:%s:size:%s", grub_env_get("ventoy_cpio_addr"), grub_env_get("ventoy_cpio_size"));
+
+ if (ventoy_debug) grub_printf("membuf=%s\n", buf);
+
+ ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf);
+
+ file = grub_env_get("vtoy_img_part_file");
+ if (file)
+ {
+ ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(file);
+ }
+
+ for (i = 0; i < argc; i++)
+ {
+ ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(argv[i]);
+ }
+
+ ventoy_initrd_called = 1;
+
+ if (ventoy_debug)
+ {
+ grub_printf("========== initrd list ==========\n");
+ for (i = 0; i < ventoy_extra_initrd_num; i++)
+ {
+ grub_printf("%s\n", ventoy_extra_initrd_list[i]);
+ }
+ grub_printf("=================================\n");
+ }
+
+ return grub_cmd_initrd(cmd, ventoy_extra_initrd_num, ventoy_extra_initrd_list);
+}
+
+static grub_command_t cmd_linux, cmd_initrd;
+static grub_command_t cmd_set_bootopt, cmd_unset_bootopt, cmd_extra_initrd_append, cmd_extra_initrd_reset;
+
+GRUB_MOD_INIT(linux)
+{
+ cmd_linux = grub_register_command ("linux", grub_cmd_linux,
+ 0, N_("Load Linux."));
+ cmd_initrd = grub_register_command ("initrd", ventoy_cmd_initrd,
+ 0, N_("Load initrd."));
+
+ cmd_set_bootopt = grub_register_command ("vt_set_boot_opt", grub_cmd_set_boot_opt, 0, N_("set ext boot opt"));
+ cmd_unset_bootopt = grub_register_command ("vt_unset_boot_opt", grub_cmd_unset_boot_opt, 0, N_("unset ext boot opt"));
+
+ cmd_extra_initrd_append = grub_register_command ("vt_img_extra_initrd_append", grub_cmd_extra_initrd_append, 0, N_(""));
+ cmd_extra_initrd_reset = grub_register_command ("vt_img_extra_initrd_reset", grub_cmd_extra_initrd_reset, 0, N_(""));
+
+ ventoy_linux_args = grub_zalloc(sizeof(char *) * LINUX_MAX_ARGC);
+
+ my_mod = mod;
+}
+
+GRUB_MOD_FINI(linux)
+{
+ grub_unregister_command (cmd_linux);
+ grub_unregister_command (cmd_initrd);
+}
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/serial.h>
+#include <grub/term.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/terminfo.h>
+#if !defined (GRUB_MACHINE_EMU) && ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__))
+#include <grub/cpu/io.h>
+#endif
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+#include <grub/list.h>
+#ifdef GRUB_MACHINE_MIPS_LOONGSON
+#include <grub/machine/kernel.h>
+#endif
+#ifdef GRUB_MACHINE_IEEE1275
+#include <grub/ieee1275/console.h>
+#endif
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+#define FOR_SERIAL_PORTS(var) FOR_LIST_ELEMENTS((var), (grub_serial_ports))
+
+enum
+ {
+ OPTION_UNIT,
+ OPTION_PORT,
+ OPTION_SPEED,
+ OPTION_WORD,
+ OPTION_PARITY,
+ OPTION_STOP,
+ OPTION_BASE_CLOCK,
+ OPTION_RTSCTS
+ };
+
+/* Argument options. */
+static const struct grub_arg_option options[] =
+{
+ {"unit", 'u', 0, N_("Set the serial unit."), 0, ARG_TYPE_INT},
+ {"port", 'p', 0, N_("Set the serial port address."), 0, ARG_TYPE_STRING},
+ {"speed", 's', 0, N_("Set the serial port speed."), 0, ARG_TYPE_INT},
+ {"word", 'w', 0, N_("Set the serial port word length."), 0, ARG_TYPE_INT},
+ {"parity", 'r', 0, N_("Set the serial port parity."), 0, ARG_TYPE_STRING},
+ {"stop", 't', 0, N_("Set the serial port stop bits."), 0, ARG_TYPE_INT},
+ {"base-clock", 'b', 0, N_("Set the base frequency."), 0, ARG_TYPE_STRING},
+ {"rtscts", 'f', 0, N_("Enable/disable RTS/CTS."), "on|off", ARG_TYPE_STRING},
+ {0, 0, 0, 0, 0, 0}
+};
+
+static struct grub_serial_port *grub_serial_ports;
+
+struct grub_serial_output_state
+{
+ struct grub_terminfo_output_state tinfo;
+ struct grub_serial_port *port;
+};
+
+struct grub_serial_input_state
+{
+ struct grub_terminfo_input_state tinfo;
+ struct grub_serial_port *port;
+};
+
+static void
+serial_put (grub_term_output_t term, const int c)
+{
+ struct grub_serial_output_state *data = term->data;
+ data->port->driver->put (data->port, c);
+}
+
+static int
+serial_fetch (grub_term_input_t term)
+{
+ struct grub_serial_input_state *data = term->data;
+ return data->port->driver->fetch (data->port);
+}
+
+static const struct grub_serial_input_state grub_serial_terminfo_input_template =
+ {
+ .tinfo =
+ {
+ .readkey = serial_fetch
+ }
+ };
+
+static const struct grub_serial_output_state grub_serial_terminfo_output_template =
+ {
+ .tinfo =
+ {
+ .put = serial_put,
+ .size = { 80, 24 }
+ }
+ };
+
+static struct grub_serial_input_state grub_serial_terminfo_input;
+
+static struct grub_serial_output_state grub_serial_terminfo_output;
+
+static int registered = 0;
+
+static struct grub_term_input grub_serial_term_input =
+{
+ .name = "serial",
+ .init = grub_terminfo_input_init,
+ .getkey = grub_terminfo_getkey,
+ .data = &grub_serial_terminfo_input
+};
+
+static struct grub_term_output grub_serial_term_output =
+{
+ .name = "serial",
+ .init = grub_terminfo_output_init,
+ .putchar = grub_terminfo_putchar,
+ .getwh = grub_terminfo_getwh,
+ .getxy = grub_terminfo_getxy,
+ .gotoxy = grub_terminfo_gotoxy,
+ .cls = grub_terminfo_cls,
+ .setcolorstate = grub_terminfo_setcolorstate,
+ .setcursor = grub_terminfo_setcursor,
+ .flags = GRUB_TERM_CODE_TYPE_ASCII,
+ .data = &grub_serial_terminfo_output,
+ .progress_update_divisor = GRUB_PROGRESS_SLOW
+};
+
+\f
+
+struct grub_serial_port *
+grub_serial_find (const char *name)
+{
+ struct grub_serial_port *port;
+
+ FOR_SERIAL_PORTS (port)
+ if (grub_strcmp (port->name, name) == 0)
+ break;
+
+#if ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__)) && !defined(GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC)
+ if (!port && grub_memcmp (name, "port", sizeof ("port") - 1) == 0
+ && grub_isxdigit (name [sizeof ("port") - 1]))
+ {
+ name = grub_serial_ns8250_add_port (grub_strtoul (&name[sizeof ("port") - 1],
+ 0, 16));
+ if (!name)
+ return NULL;
+
+ FOR_SERIAL_PORTS (port)
+ if (grub_strcmp (port->name, name) == 0)
+ break;
+ }
+#endif
+
+#ifdef GRUB_MACHINE_IEEE1275
+ if (!port && grub_memcmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) == 0)
+ {
+ name = grub_ofserial_add_port (&name[sizeof ("ieee1275/") - 1]);
+ if (!name)
+ return NULL;
+
+ FOR_SERIAL_PORTS (port)
+ if (grub_strcmp (port->name, name) == 0)
+ break;
+ }
+#endif
+
+ return port;
+}
+
+static grub_err_t
+grub_cmd_serial (grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ struct grub_arg_list *state = ctxt->state;
+ char pname[40];
+ const char *name = NULL;
+ struct grub_serial_port *port;
+ struct grub_serial_config config;
+ grub_err_t err;
+
+ if (state[OPTION_UNIT].set)
+ {
+ grub_snprintf (pname, sizeof (pname), "com%ld",
+ grub_strtoul (state[0].arg, 0, 0));
+ name = pname;
+ }
+
+ if (state[OPTION_PORT].set)
+ {
+ grub_snprintf (pname, sizeof (pname), "port%lx",
+ grub_strtoul (state[1].arg, 0, 0));
+ name = pname;
+ }
+
+ if (argc >= 1)
+ name = args[0];
+
+ if (!name)
+ name = "com0";
+
+ port = grub_serial_find (name);
+ if (!port)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("serial port `%s' isn't found"),
+ name);
+
+ config = port->config;
+
+ if (state[OPTION_SPEED].set) {
+ config.speed = grub_strtoul (state[OPTION_SPEED].arg, 0, 0);
+ if (config.speed == 0)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("unsupported serial port parity"));
+ }
+
+ if (state[OPTION_WORD].set)
+ config.word_len = grub_strtoul (state[OPTION_WORD].arg, 0, 0);
+
+ if (state[OPTION_PARITY].set)
+ {
+ if (! grub_strcmp (state[OPTION_PARITY].arg, "no"))
+ config.parity = GRUB_SERIAL_PARITY_NONE;
+ else if (! grub_strcmp (state[OPTION_PARITY].arg, "odd"))
+ config.parity = GRUB_SERIAL_PARITY_ODD;
+ else if (! grub_strcmp (state[OPTION_PARITY].arg, "even"))
+ config.parity = GRUB_SERIAL_PARITY_EVEN;
+ else
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("unsupported serial port parity"));
+ }
+
+ if (state[OPTION_RTSCTS].set)
+ {
+ if (grub_strcmp (state[OPTION_RTSCTS].arg, "on") == 0)
+ config.rtscts = 1;
+ else if (grub_strcmp (state[OPTION_RTSCTS].arg, "off") == 0)
+ config.rtscts = 0;
+ else
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("unsupported serial port flow control"));
+ }
+
+ if (state[OPTION_STOP].set)
+ {
+ if (! grub_strcmp (state[OPTION_STOP].arg, "1"))
+ config.stop_bits = GRUB_SERIAL_STOP_BITS_1;
+ else if (! grub_strcmp (state[OPTION_STOP].arg, "2"))
+ config.stop_bits = GRUB_SERIAL_STOP_BITS_2;
+ else if (! grub_strcmp (state[OPTION_STOP].arg, "1.5"))
+ config.stop_bits = GRUB_SERIAL_STOP_BITS_1_5;
+ else
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("unsupported serial port stop bits number"));
+ }
+
+ if (state[OPTION_BASE_CLOCK].set)
+ {
+ char *ptr;
+ config.base_clock = grub_strtoull (state[OPTION_BASE_CLOCK].arg, &ptr, 0);
+ if (grub_errno)
+ return grub_errno;
+ if (ptr && *ptr == 'M')
+ config.base_clock *= 1000000;
+ if (ptr && (*ptr == 'k' || *ptr == 'K'))
+ config.base_clock *= 1000;
+ }
+
+ if (config.speed == 0)
+ config.speed = 9600;
+
+ /* Initialize with new settings. */
+ err = port->driver->configure (port, &config);
+ if (err)
+ return err;
+#if !defined (GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) && ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__))
+
+ /* Compatibility kludge. */
+ if (port->driver == &grub_ns8250_driver)
+ {
+ if (!registered)
+ {
+ grub_terminfo_output_register (&grub_serial_term_output, "vt100");
+
+ grub_term_register_input ("serial", &grub_serial_term_input);
+ grub_term_register_output ("serial", &grub_serial_term_output);
+ }
+ grub_serial_terminfo_output.port = port;
+ grub_serial_terminfo_input.port = port;
+ registered = 1;
+ }
+#endif
+ return GRUB_ERR_NONE;
+}
+
+#ifdef GRUB_MACHINE_MIPS_LOONGSON
+const char loongson_defserial[][6] =
+ {
+ [GRUB_ARCH_MACHINE_YEELOONG] = "com0",
+ [GRUB_ARCH_MACHINE_FULOONG2F] = "com2",
+ [GRUB_ARCH_MACHINE_FULOONG2E] = "com1"
+ };
+#endif
+
+grub_err_t
+grub_serial_register (struct grub_serial_port *port)
+{
+ struct grub_term_input *in;
+ struct grub_term_output *out;
+ struct grub_serial_input_state *indata;
+ struct grub_serial_output_state *outdata;
+
+ in = grub_malloc (sizeof (*in));
+ if (!in)
+ return grub_errno;
+
+ indata = grub_malloc (sizeof (*indata));
+ if (!indata)
+ {
+ grub_free (in);
+ return grub_errno;
+ }
+
+ grub_memcpy (in, &grub_serial_term_input, sizeof (*in));
+ in->data = indata;
+ in->name = grub_xasprintf ("serial_%s", port->name);
+ grub_memcpy (indata, &grub_serial_terminfo_input, sizeof (*indata));
+
+ if (!in->name)
+ {
+ grub_free (in);
+ grub_free (indata);
+ return grub_errno;
+ }
+
+ out = grub_zalloc (sizeof (*out));
+ if (!out)
+ {
+ grub_free (indata);
+ grub_free ((char *) in->name);
+ grub_free (in);
+ return grub_errno;
+ }
+
+ outdata = grub_malloc (sizeof (*outdata));
+ if (!outdata)
+ {
+ grub_free (indata);
+ grub_free ((char *) in->name);
+ grub_free (out);
+ grub_free (in);
+ return grub_errno;
+ }
+
+ grub_memcpy (out, &grub_serial_term_output, sizeof (*out));
+ out->data = outdata;
+ out->name = in->name;
+ grub_memcpy (outdata, &grub_serial_terminfo_output, sizeof (*outdata));
+
+ grub_list_push (GRUB_AS_LIST_P (&grub_serial_ports), GRUB_AS_LIST (port));
+ ((struct grub_serial_input_state *) in->data)->port = port;
+ ((struct grub_serial_output_state *) out->data)->port = port;
+ port->term_in = in;
+ port->term_out = out;
+ grub_terminfo_output_register (out, "vt100");
+#ifdef GRUB_MACHINE_MIPS_LOONGSON
+ if (grub_strcmp (port->name, loongson_defserial[grub_arch_machine]) == 0)
+ {
+ grub_term_register_input_active ("serial_*", in);
+ grub_term_register_output_active ("serial_*", out);
+ }
+ else
+ {
+ grub_term_register_input_inactive ("serial_*", in);
+ grub_term_register_output_inactive ("serial_*", out);
+ }
+#else
+ grub_term_register_input ("serial_*", in);
+ grub_term_register_output ("serial_*", out);
+#endif
+
+ return GRUB_ERR_NONE;
+}
+
+void
+grub_serial_unregister (struct grub_serial_port *port)
+{
+ if (port->driver->fini)
+ port->driver->fini (port);
+
+ if (port->term_in)
+ grub_term_unregister_input (port->term_in);
+ if (port->term_out)
+ grub_term_unregister_output (port->term_out);
+
+ grub_list_remove (GRUB_AS_LIST (port));
+}
+
+void
+grub_serial_unregister_driver (struct grub_serial_driver *driver)
+{
+ struct grub_serial_port *port, *next;
+ for (port = grub_serial_ports; port; port = next)
+ {
+ next = port->next;
+ if (port->driver == driver)
+ grub_serial_unregister (port);
+ }
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(serial)
+{
+ cmd = grub_register_extcmd ("serial", grub_cmd_serial, 0,
+ N_("[OPTIONS...]"),
+ N_("Configure serial port."), options);
+ grub_memcpy (&grub_serial_terminfo_output,
+ &grub_serial_terminfo_output_template,
+ sizeof (grub_serial_terminfo_output));
+
+ grub_memcpy (&grub_serial_terminfo_input,
+ &grub_serial_terminfo_input_template,
+ sizeof (grub_serial_terminfo_input));
+
+#if !defined (GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) && ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__))
+ grub_ns8250_init ();
+#endif
+#ifdef GRUB_MACHINE_IEEE1275
+ grub_ofserial_init ();
+#endif
+#ifdef GRUB_MACHINE_EFI
+ grub_efiserial_init ();
+#endif
+#ifdef GRUB_MACHINE_ARC
+ grub_arcserial_init ();
+#endif
+}
+
+GRUB_MOD_FINI(serial)
+{
+ while (grub_serial_ports)
+ grub_serial_unregister (grub_serial_ports);
+ if (registered)
+ {
+ grub_term_unregister_input (&grub_serial_term_input);
+ grub_term_unregister_output (&grub_serial_term_output);
+ }
+ grub_unregister_extcmd (cmd);
+}
g_ventoy_plat_data = VTOY_PLAT_ARM64_UEFI;
grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "aa64");
}
+ else if (grub_strcmp(GRUB_TARGET_CPU, "mips64el") == 0)
+ {
+ g_ventoy_plat_data = VTOY_PLAT_MIPS_UEFI;
+ grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "mips");
+ }
else
{
g_ventoy_plat_data = VTOY_PLAT_X86_64_UEFI;
#define VTOY_PLAT_ARM64_UEFI 0x41413634
#define VTOY_PLAT_X86_64_UEFI 0x55454649
#define VTOY_PLAT_X86_LEGACY 0x42494f53
+#define VTOY_PLAT_MIPS_UEFI 0x4D495053
+
+#define VTOY_COMM_CPIO "ventoy.cpio"
+#if defined(__arm__) || defined(__aarch64__)
+#define VTOY_ARCH_CPIO "ventoy_arm64.cpio"
+#elif defined(__mips__)
+#define VTOY_ARCH_CPIO "ventoy_mips64.cpio"
+#else
+#define VTOY_ARCH_CPIO "ventoy_x86.cpio"
+#endif
#define VTOY_PWD_CORRUPTED(err) \
{\
grub_uint32_t injection_size = 0;
grub_uint32_t dud_size = 0;
grub_file_t file;
+ grub_file_t archfile;
grub_file_t tmpfile;
ventoy_img_chunk_list chunk_list;
img_chunk_size = g_img_chunk_list.cur_chunk * sizeof(ventoy_img_chunk);
- file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
+ file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/%s", args[0], VTOY_COMM_CPIO);
if (!file)
{
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]);
+ return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s/%s\n", args[0], VTOY_COMM_CPIO);
+ }
+
+ archfile = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/%s", args[0], VTOY_ARCH_CPIO);
+ if (!archfile)
+ {
+ return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s/%s\n", args[0], VTOY_ARCH_CPIO);
+ grub_file_close(file);
}
+ debug("load %s %s success\n", VTOY_COMM_CPIO, VTOY_ARCH_CPIO);
+
if (g_ventoy_cpio_buf)
{
grub_free(g_ventoy_cpio_buf);
debug("dud not configed %s\n", args[1]);
}
- g_ventoy_cpio_buf = grub_malloc(file->size + 40960 + template_size +
+ g_ventoy_cpio_buf = grub_malloc(file->size + archfile->size + 40960 + template_size +
persistent_size + injection_size + dud_size + img_chunk_size);
if (NULL == g_ventoy_cpio_buf)
{
grub_file_close(file);
+ grub_file_close(archfile);
return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't alloc memory %llu\n", file->size);
}
grub_file_read(file, g_ventoy_cpio_buf, file->size);
-
buf = (grub_uint8_t *)(g_ventoy_cpio_buf + file->size - 4);
while (*((grub_uint32_t *)buf) != 0x37303730)
{
buf -= 4;
}
+ grub_file_read(archfile, buf, archfile->size);
+ buf += (archfile->size - 4);
+ while (*((grub_uint32_t *)buf) != 0x37303730)
+ {
+ buf -= 4;
+ }
+
/* get initrd head len */
initrd_head_len = ventoy_cpio_newc_fill_head(buf, 0, NULL, "initrd000.xx");
ventoy_cpio_newc_fill_head(g_ventoy_initrd_head, 0, NULL, "initrd000.xx");
grub_file_close(file);
+ grub_file_close(archfile);
if (grub_strcmp(args[3], "busybox=64") == 0)
{
debug("cpio busybox proc %s\n", args[3]);
ventoy_cpio_busybox64((cpio_newc_header *)g_ventoy_cpio_buf, "a64");
}
+ else if (grub_strcmp(args[3], "busybox=m64") == 0)
+ {
+ debug("cpio busybox proc %s\n", args[3]);
+ ventoy_cpio_busybox64((cpio_newc_header *)g_ventoy_cpio_buf, "m64");
+ }
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
--- /dev/null
+/* cache.h - Flush the processor's cache. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2004,2007 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CACHE_H
+#define GRUB_CACHE_H 1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+#if defined (__i386__) || defined (__x86_64__)
+static inline void
+grub_arch_sync_caches (void *address __attribute__ ((unused)),
+ grub_size_t len __attribute__ ((unused)))
+{
+}
+#else
+void EXPORT_FUNC(grub_arch_sync_caches) (void *address, grub_size_t len);
+#endif
+
+#ifndef GRUB_MACHINE_EMU
+#if defined (__aarch64__) || defined (__ia64__) || defined (__powerpc__) || \
+ defined (__sparc__)
+
+#elif defined (__i386__) || defined (__x86_64__)
+static inline void
+grub_arch_sync_dma_caches (volatile void *address __attribute__ ((unused)),
+ grub_size_t len __attribute__ ((unused)))
+{
+}
+#elif defined(__mips__) && (_MIPS_SIM != _ABI64)
+void EXPORT_FUNC(grub_arch_sync_dma_caches) (volatile void *address, grub_size_t len);
+#endif
+#endif
+
+#ifdef __arm__
+void
+grub_arm_cache_enable (void);
+#endif
+
+#endif /* ! GRUB_CACHE_HEADER */
--- /dev/null
+/* dl.h - types and prototypes for loadable module support */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_DL_H
+#define GRUB_DL_H 1
+
+#include <grub/symbol.h>
+#ifndef ASM_FILE
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/elf.h>
+#include <grub/list.h>
+#include <grub/misc.h>
+#endif
+
+/*
+ * Macros GRUB_MOD_INIT and GRUB_MOD_FINI are also used by build rules
+ * to collect module names, so we define them only when they are not
+ * defined already.
+ */
+#ifndef ASM_FILE
+
+#ifndef GRUB_MOD_INIT
+
+#if !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_KERNEL)
+
+#define GRUB_MOD_INIT(name) \
+static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
+static void \
+grub_mod_init (grub_dl_t mod __attribute__ ((unused)))
+
+#define GRUB_MOD_FINI(name) \
+static void grub_mod_fini (void) __attribute__ ((used)); \
+static void \
+grub_mod_fini (void)
+
+#elif defined (GRUB_KERNEL)
+
+#define GRUB_MOD_INIT(name) \
+static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
+void \
+grub_##name##_init (void) { grub_mod_init (0); } \
+static void \
+grub_mod_init (grub_dl_t mod __attribute__ ((unused)))
+
+#define GRUB_MOD_FINI(name) \
+static void grub_mod_fini (void) __attribute__ ((used)); \
+void \
+grub_##name##_fini (void) { grub_mod_fini (); } \
+static void \
+grub_mod_fini (void)
+
+#else
+
+#define GRUB_MOD_INIT(name) \
+static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
+void grub_##name##_init (void); \
+void \
+grub_##name##_init (void) { grub_mod_init (0); } \
+static void \
+grub_mod_init (grub_dl_t mod __attribute__ ((unused)))
+
+#define GRUB_MOD_FINI(name) \
+static void grub_mod_fini (void) __attribute__ ((used)); \
+void grub_##name##_fini (void); \
+void \
+grub_##name##_fini (void) { grub_mod_fini (); } \
+static void \
+grub_mod_fini (void)
+
+#endif
+
+#endif
+
+#endif
+
+#ifndef ASM_FILE
+#ifdef __APPLE__
+#define GRUB_MOD_SECTION(x) "_" #x ", _" #x ""
+#else
+#define GRUB_MOD_SECTION(x) "." #x
+#endif
+#else
+#ifdef __APPLE__
+#define GRUB_MOD_SECTION(x) _ ## x , _ ##x
+#else
+#define GRUB_MOD_SECTION(x) . ## x
+#endif
+#endif
+
+/* Me, Vladimir Serbinenko, hereby I add this module check as per new
+ GNU module policy. Note that this license check is informative only.
+ Modules have to be licensed under GPLv3 or GPLv3+ (optionally
+ multi-licensed under other licences as well) independently of the
+ presence of this check and solely by linking (module loading in GRUB
+ constitutes linking) and GRUB core being licensed under GPLv3+.
+ Be sure to understand your license obligations.
+*/
+#ifndef ASM_FILE
+#if GNUC_PREREQ (3,2)
+#define ATTRIBUTE_USED __used__
+#else
+#define ATTRIBUTE_USED __unused__
+#endif
+#define GRUB_MOD_LICENSE(license) \
+ static char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION (module_license)), ATTRIBUTE_USED)) = "LICENSE=" license;
+#define GRUB_MOD_DEP(name) \
+static const char grub_module_depend_##name[] \
+ __attribute__((section(GRUB_MOD_SECTION(moddeps)), ATTRIBUTE_USED)) = #name
+#define GRUB_MOD_NAME(name) \
+static const char grub_module_name_##name[] \
+ __attribute__((section(GRUB_MOD_SECTION(modname)), __used__)) = #name
+#else
+#ifdef __APPLE__
+.macro GRUB_MOD_LICENSE
+ .section GRUB_MOD_SECTION(module_license)
+ .ascii "LICENSE="
+ .ascii $0
+ .byte 0
+.endm
+#else
+.macro GRUB_MOD_LICENSE license
+ .section GRUB_MOD_SECTION(module_license), "a"
+ .ascii "LICENSE="
+ .ascii "\license"
+ .byte 0
+.endm
+#endif
+#endif
+
+/* Under GPL license obligations you have to distribute your module
+ under GPLv3(+). However, you can also distribute the same code under
+ another license as long as GPLv3(+) version is provided.
+*/
+#define GRUB_MOD_DUAL_LICENSE(x)
+
+#ifndef ASM_FILE
+
+struct grub_dl_segment
+{
+ struct grub_dl_segment *next;
+ void *addr;
+ grub_size_t size;
+ unsigned section;
+};
+typedef struct grub_dl_segment *grub_dl_segment_t;
+
+struct grub_dl;
+
+struct grub_dl_dep
+{
+ struct grub_dl_dep *next;
+ struct grub_dl *mod;
+};
+typedef struct grub_dl_dep *grub_dl_dep_t;
+
+#ifndef GRUB_UTIL
+struct grub_dl
+{
+ char *name;
+ int ref_count;
+ int persistent;
+ grub_dl_dep_t dep;
+ grub_dl_segment_t segment;
+ Elf_Sym *symtab;
+ grub_size_t symsize;
+ void (*init) (struct grub_dl *mod);
+ void (*fini) (void);
+#if !defined (__i386__) && !defined (__x86_64__)
+ void *got;
+ void *gotptr;
+ void *tramp;
+ void *trampptr;
+#endif
+#if defined(__mips__) && (_MIPS_SIM != _ABI64)
+ grub_uint32_t *reginfo;
+#endif
+ void *base;
+ grub_size_t sz;
+ struct grub_dl *next;
+};
+#endif
+typedef struct grub_dl *grub_dl_t;
+
+grub_dl_t grub_dl_load_file (const char *filename);
+grub_dl_t EXPORT_FUNC(grub_dl_load) (const char *name);
+grub_dl_t grub_dl_load_core (void *addr, grub_size_t size);
+grub_dl_t EXPORT_FUNC(grub_dl_load_core_noinit) (void *addr, grub_size_t size);
+int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod);
+void grub_dl_unload_unneeded (void);
+int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod);
+int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod);
+extern grub_dl_t EXPORT_VAR(grub_dl_head);
+
+#ifndef GRUB_UTIL
+
+#define FOR_DL_MODULES(var) FOR_LIST_ELEMENTS ((var), (grub_dl_head))
+
+#ifdef GRUB_MACHINE_EMU
+void *
+grub_osdep_dl_memalign (grub_size_t align, grub_size_t size);
+void
+grub_dl_osdep_dl_free (void *ptr);
+#endif
+
+static inline void
+grub_dl_init (grub_dl_t mod)
+{
+ if (mod->init)
+ (mod->init) (mod);
+
+ mod->next = grub_dl_head;
+ grub_dl_head = mod;
+}
+
+static inline grub_dl_t
+grub_dl_get (const char *name)
+{
+ grub_dl_t l;
+
+ FOR_DL_MODULES(l)
+ if (grub_strcmp (name, l->name) == 0)
+ return l;
+
+ return 0;
+}
+
+static inline void
+grub_dl_set_persistent (grub_dl_t mod)
+{
+ mod->persistent = 1;
+}
+
+static inline int
+grub_dl_is_persistent (grub_dl_t mod)
+{
+ return mod->persistent;
+}
+
+#endif
+
+grub_err_t grub_dl_register_symbol (const char *name, void *addr,
+ int isfunc, grub_dl_t mod);
+
+grub_err_t grub_arch_dl_check_header (void *ehdr);
+#ifndef GRUB_UTIL
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
+ Elf_Shdr *s, grub_dl_segment_t seg);
+#endif
+
+#if defined (__mips__) && (_MIPS_SIM != _ABI64)
+#define GRUB_LINKER_HAVE_INIT 1
+void grub_arch_dl_init_linker (void);
+#endif
+
+#define GRUB_IA64_DL_TRAMP_ALIGN 16
+#define GRUB_IA64_DL_GOT_ALIGN 16
+
+grub_err_t
+grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
+ grub_size_t *got);
+grub_err_t
+grub_arm64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
+ grub_size_t *got);
+
+#if defined (__ia64__)
+#define GRUB_ARCH_DL_TRAMP_ALIGN GRUB_IA64_DL_TRAMP_ALIGN
+#define GRUB_ARCH_DL_GOT_ALIGN GRUB_IA64_DL_GOT_ALIGN
+#define grub_arch_dl_get_tramp_got_size grub_ia64_dl_get_tramp_got_size
+#elif defined (__aarch64__)
+#define grub_arch_dl_get_tramp_got_size grub_arm64_dl_get_tramp_got_size
+#else
+grub_err_t
+grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
+ grub_size_t *got);
+#endif
+
+#if defined (__powerpc__) || (defined (__mips__) && (_MIPS_SIM != _ABI64)) || defined (__arm__) || \
+ (defined(__riscv) && (__riscv_xlen == 32))
+#define GRUB_ARCH_DL_TRAMP_ALIGN 4
+#define GRUB_ARCH_DL_GOT_ALIGN 4
+#endif
+
+#if defined (__aarch64__) || defined (__sparc__) || (defined (__mips__) && (_MIPS_SIM == _ABI64)) || \
+ (defined(__riscv) && (__riscv_xlen == 64))
+#define GRUB_ARCH_DL_TRAMP_ALIGN 8
+#define GRUB_ARCH_DL_GOT_ALIGN 8
+#endif
+
+#endif
+
+#endif /* ! GRUB_DL_H */
--- /dev/null
+/* efi.h - declare EFI types and functions */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_API_HEADER
+#define GRUB_EFI_API_HEADER 1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+
+/* For consistency and safety, we name the EFI-defined types differently.
+ All names are transformed into lower case, _t appended, and
+ grub_efi_ prepended. */
+
+/* Constants. */
+#define GRUB_EFI_EVT_TIMER 0x80000000
+#define GRUB_EFI_EVT_RUNTIME 0x40000000
+#define GRUB_EFI_EVT_RUNTIME_CONTEXT 0x20000000
+#define GRUB_EFI_EVT_NOTIFY_WAIT 0x00000100
+#define GRUB_EFI_EVT_NOTIFY_SIGNAL 0x00000200
+#define GRUB_EFI_EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201
+#define GRUB_EFI_EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202
+
+#define GRUB_EFI_TPL_APPLICATION 4
+#define GRUB_EFI_TPL_CALLBACK 8
+#define GRUB_EFI_TPL_NOTIFY 16
+#define GRUB_EFI_TPL_HIGH_LEVEL 31
+
+#define GRUB_EFI_MEMORY_UC 0x0000000000000001LL
+#define GRUB_EFI_MEMORY_WC 0x0000000000000002LL
+#define GRUB_EFI_MEMORY_WT 0x0000000000000004LL
+#define GRUB_EFI_MEMORY_WB 0x0000000000000008LL
+#define GRUB_EFI_MEMORY_UCE 0x0000000000000010LL
+#define GRUB_EFI_MEMORY_WP 0x0000000000001000LL
+#define GRUB_EFI_MEMORY_RP 0x0000000000002000LL
+#define GRUB_EFI_MEMORY_XP 0x0000000000004000LL
+#define GRUB_EFI_MEMORY_NV 0x0000000000008000LL
+#define GRUB_EFI_MEMORY_MORE_RELIABLE 0x0000000000010000LL
+#define GRUB_EFI_MEMORY_RO 0x0000000000020000LL
+#define GRUB_EFI_MEMORY_RUNTIME 0x8000000000000000LL
+
+#define GRUB_EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001
+#define GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002
+#define GRUB_EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004
+#define GRUB_EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008
+#define GRUB_EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010
+#define GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE 0x00000020
+
+#define GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001ULL
+
+#define GRUB_EFI_VARIABLE_NON_VOLATILE 0x0000000000000001
+#define GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
+#define GRUB_EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004
+
+#define GRUB_EFI_TIME_ADJUST_DAYLIGHT 0x01
+#define GRUB_EFI_TIME_IN_DAYLIGHT 0x02
+
+#define GRUB_EFI_UNSPECIFIED_TIMEZONE 0x07FF
+
+#define GRUB_EFI_OPTIONAL_PTR 0x00000001
+
+#define GRUB_EFI_LOADED_IMAGE_GUID \
+ { 0x5b1b31a1, 0x9562, 0x11d2, \
+ { 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+#define GRUB_EFI_DISK_IO_GUID \
+ { 0xce345171, 0xba0b, 0x11d2, \
+ { 0x8e, 0x4f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+#define GRUB_EFI_BLOCK_IO_GUID \
+ { 0x964e5b21, 0x6459, 0x11d2, \
+ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+#define GRUB_EFI_SERIAL_IO_GUID \
+ { 0xbb25cf6f, 0xf1d4, 0x11d2, \
+ { 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0xfd } \
+ }
+
+#define GRUB_EFI_SIMPLE_NETWORK_GUID \
+ { 0xa19832b9, 0xac25, 0x11d3, \
+ { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+#define GRUB_EFI_PXE_GUID \
+ { 0x03c4e603, 0xac28, 0x11d3, \
+ { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+#define GRUB_EFI_DEVICE_PATH_GUID \
+ { 0x09576e91, 0x6d3f, 0x11d2, \
+ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+#define GRUB_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \
+ { 0x387477c1, 0x69c7, 0x11d2, \
+ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+#define GRUB_EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \
+ { 0xdd9e7534, 0x7762, 0x4698, \
+ { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } \
+ }
+
+#define GRUB_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID \
+ { 0x387477c2, 0x69c7, 0x11d2, \
+ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+#define GRUB_EFI_SIMPLE_POINTER_PROTOCOL_GUID \
+ { 0x31878c87, 0xb75, 0x11d5, \
+ { 0x9a, 0x4f, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+#define GRUB_EFI_ABSOLUTE_POINTER_PROTOCOL_GUID \
+ { 0x8D59D32B, 0xC655, 0x4AE9, \
+ { 0x9B, 0x15, 0xF2, 0x59, 0x04, 0x99, 0x2A, 0x43 } \
+ }
+
+#define GRUB_EFI_DRIVER_BINDING_PROTOCOL_GUID \
+ { 0x18A031AB, 0xB443, 0x4D1A, \
+ { 0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71 } \
+ }
+
+#define GRUB_EFI_LOADED_IMAGE_PROTOCOL_GUID \
+ { 0x5B1B31A1, 0x9562, 0x11d2, \
+ { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \
+ }
+
+#define GRUB_EFI_LOAD_FILE_PROTOCOL_GUID \
+ { 0x56EC3091, 0x954C, 0x11d2, \
+ { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \
+ }
+
+#define GRUB_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \
+ { 0x0964e5b22, 0x6459, 0x11d2, \
+ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+#define GRUB_EFI_TAPE_IO_PROTOCOL_GUID \
+ { 0x1e93e633, 0xd65a, 0x459e, \
+ { 0xab, 0x84, 0x93, 0xd9, 0xec, 0x26, 0x6d, 0x18 } \
+ }
+
+#define GRUB_EFI_UNICODE_COLLATION_PROTOCOL_GUID \
+ { 0x1d85cd7f, 0xf43d, 0x11d2, \
+ { 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+#define GRUB_EFI_SCSI_IO_PROTOCOL_GUID \
+ { 0x932f47e6, 0x2362, 0x4002, \
+ { 0x80, 0x3e, 0x3c, 0xd5, 0x4b, 0x13, 0x8f, 0x85 } \
+ }
+
+#define GRUB_EFI_USB2_HC_PROTOCOL_GUID \
+ { 0x3e745226, 0x9818, 0x45b6, \
+ { 0xa2, 0xac, 0xd7, 0xcd, 0x0e, 0x8b, 0xa2, 0xbc } \
+ }
+
+#define GRUB_EFI_DEBUG_SUPPORT_PROTOCOL_GUID \
+ { 0x2755590C, 0x6F3C, 0x42FA, \
+ { 0x9E, 0xA4, 0xA3, 0xBA, 0x54, 0x3C, 0xDA, 0x25 } \
+ }
+
+#define GRUB_EFI_DEBUGPORT_PROTOCOL_GUID \
+ { 0xEBA4E8D2, 0x3858, 0x41EC, \
+ { 0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 } \
+ }
+
+#define GRUB_EFI_DECOMPRESS_PROTOCOL_GUID \
+ { 0xd8117cfe, 0x94a6, 0x11d4, \
+ { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+#define GRUB_EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \
+ { 0x8b843e20, 0x8132, 0x4852, \
+ { 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c } \
+ }
+
+#define GRUB_EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID \
+ { 0x379be4e, 0xd706, 0x437d, \
+ { 0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4 } \
+ }
+
+#define GRUB_EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \
+ { 0x5c99a21, 0xc70f, 0x4ad2, \
+ { 0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e } \
+ }
+
+#define GRUB_EFI_ACPI_TABLE_PROTOCOL_GUID \
+ { 0xffe06bdd, 0x6107, 0x46a6, \
+ { 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c} \
+ }
+
+#define GRUB_EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID \
+ { 0x587e72d7, 0xcc50, 0x4f79, \
+ { 0x82, 0x09, 0xca, 0x29, 0x1f, 0xc1, 0xa1, 0x0f } \
+ }
+
+#define GRUB_EFI_HII_DATABASE_PROTOCOL_GUID \
+ { 0xef9fc172, 0xa1b2, 0x4693, \
+ { 0xb3, 0x27, 0x6d, 0x32, 0xfc, 0x41, 0x60, 0x42 } \
+ }
+
+#define GRUB_EFI_HII_STRING_PROTOCOL_GUID \
+ { 0xfd96974, 0x23aa, 0x4cdc, \
+ { 0xb9, 0xcb, 0x98, 0xd1, 0x77, 0x50, 0x32, 0x2a } \
+ }
+
+#define GRUB_EFI_HII_IMAGE_PROTOCOL_GUID \
+ { 0x31a6406a, 0x6bdf, 0x4e46, \
+ { 0xb2, 0xa2, 0xeb, 0xaa, 0x89, 0xc4, 0x9, 0x20 } \
+ }
+
+#define GRUB_EFI_HII_FONT_PROTOCOL_GUID \
+ { 0xe9ca4775, 0x8657, 0x47fc, \
+ { 0x97, 0xe7, 0x7e, 0xd6, 0x5a, 0x8, 0x43, 0x24 } \
+ }
+
+#define GRUB_EFI_HII_CONFIGURATION_ACCESS_PROTOCOL_GUID \
+ { 0x330d4706, 0xf2a0, 0x4e4f, \
+ { 0xa3, 0x69, 0xb6, 0x6f, 0xa8, 0xd5, 0x43, 0x85 } \
+ }
+
+#define GRUB_EFI_COMPONENT_NAME2_PROTOCOL_GUID \
+ { 0x6a7a5cff, 0xe8d9, 0x4f70, \
+ { 0xba, 0xda, 0x75, 0xab, 0x30, 0x25, 0xce, 0x14} \
+ }
+
+#define GRUB_EFI_USB_IO_PROTOCOL_GUID \
+ { 0x2B2F68D6, 0x0CD2, 0x44cf, \
+ { 0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75 } \
+ }
+
+#define GRUB_EFI_TIANO_CUSTOM_DECOMPRESS_GUID \
+ { 0xa31280ad, 0x481e, 0x41b6, \
+ { 0x95, 0xe8, 0x12, 0x7f, 0x4c, 0x98, 0x47, 0x79 } \
+ }
+
+#define GRUB_EFI_CRC32_GUIDED_SECTION_EXTRACTION_GUID \
+ { 0xfc1bcdb0, 0x7d31, 0x49aa, \
+ { 0x93, 0x6a, 0xa4, 0x60, 0x0d, 0x9d, 0xd0, 0x83 } \
+ }
+
+#define GRUB_EFI_LZMA_CUSTOM_DECOMPRESS_GUID \
+ { 0xee4e5898, 0x3914, 0x4259, \
+ { 0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x03, 0xcf } \
+ }
+
+#define GRUB_EFI_TSC_FREQUENCY_GUID \
+ { 0xdba6a7e3, 0xbb57, 0x4be7, \
+ { 0x8a, 0xf8, 0xd5, 0x78, 0xdb, 0x7e, 0x56, 0x87 } \
+ }
+
+#define GRUB_EFI_SYSTEM_RESOURCE_TABLE_GUID \
+ { 0xb122a263, 0x3661, 0x4f68, \
+ { 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80 } \
+ }
+
+#define GRUB_EFI_DXE_SERVICES_TABLE_GUID \
+ { 0x05ad34ba, 0x6f02, 0x4214, \
+ { 0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9 } \
+ }
+
+#define GRUB_EFI_HOB_LIST_GUID \
+ { 0x7739f24c, 0x93d7, 0x11d4, \
+ { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+#define GRUB_EFI_MEMORY_TYPE_INFORMATION_GUID \
+ { 0x4c19049f, 0x4137, 0x4dd3, \
+ { 0x9c, 0x10, 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa } \
+ }
+
+#define GRUB_EFI_DEBUG_IMAGE_INFO_TABLE_GUID \
+ { 0x49152e77, 0x1ada, 0x4764, \
+ { 0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b } \
+ }
+
+#define GRUB_EFI_MPS_TABLE_GUID \
+ { 0xeb9d2d2f, 0x2d88, 0x11d3, \
+ { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+#define GRUB_EFI_ACPI_TABLE_GUID \
+ { 0xeb9d2d30, 0x2d88, 0x11d3, \
+ { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+#define GRUB_EFI_ACPI_20_TABLE_GUID \
+ { 0x8868e871, 0xe4f1, 0x11d3, \
+ { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
+ }
+
+#define GRUB_EFI_SMBIOS_TABLE_GUID \
+ { 0xeb9d2d31, 0x2d88, 0x11d3, \
+ { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+#define GRUB_EFI_SAL_TABLE_GUID \
+ { 0xeb9d2d32, 0x2d88, 0x11d3, \
+ { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+#define GRUB_EFI_HCDP_TABLE_GUID \
+ { 0xf951938d, 0x620b, 0x42ef, \
+ { 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 } \
+ }
+
+#define GRUB_EFI_DEVICE_TREE_GUID \
+ { 0xb1b621d5, 0xf19c, 0x41a5, \
+ { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } \
+ }
+
+#define GRUB_EFI_VENDOR_APPLE_GUID \
+ { 0x2B0585EB, 0xD8B8, 0x49A9, \
+ { 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \
+ }
+
+struct grub_efi_sal_system_table
+{
+ grub_uint32_t signature;
+ grub_uint32_t total_table_len;
+ grub_uint16_t sal_rev;
+ grub_uint16_t entry_count;
+ grub_uint8_t checksum;
+ grub_uint8_t reserved1[7];
+ grub_uint16_t sal_a_version;
+ grub_uint16_t sal_b_version;
+ grub_uint8_t oem_id[32];
+ grub_uint8_t product_id[32];
+ grub_uint8_t reserved2[8];
+ grub_uint8_t entries[0];
+};
+
+enum
+ {
+ GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_ENTRYPOINT_DESCRIPTOR = 0,
+ GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_MEMORY_DESCRIPTOR = 1,
+ GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_PLATFORM_FEATURES = 2,
+ GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_TRANSLATION_REGISTER_DESCRIPTOR = 3,
+ GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_PURGE_TRANSLATION_COHERENCE = 4,
+ GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_AP_WAKEUP = 5
+ };
+
+struct grub_efi_sal_system_table_entrypoint_descriptor
+{
+ grub_uint8_t type;
+ grub_uint8_t pad[7];
+ grub_uint64_t pal_proc_addr;
+ grub_uint64_t sal_proc_addr;
+ grub_uint64_t global_data_ptr;
+ grub_uint64_t reserved[2];
+};
+
+struct grub_efi_sal_system_table_memory_descriptor
+{
+ grub_uint8_t type;
+ grub_uint8_t sal_used;
+ grub_uint8_t attr;
+ grub_uint8_t ar;
+ grub_uint8_t attr_mask;
+ grub_uint8_t mem_type;
+ grub_uint8_t usage;
+ grub_uint8_t unknown;
+ grub_uint64_t addr;
+ grub_uint64_t len;
+ grub_uint64_t unknown2;
+};
+
+struct grub_efi_sal_system_table_platform_features
+{
+ grub_uint8_t type;
+ grub_uint8_t flags;
+ grub_uint8_t reserved[14];
+};
+
+struct grub_efi_sal_system_table_translation_register_descriptor
+{
+ grub_uint8_t type;
+ grub_uint8_t register_type;
+ grub_uint8_t register_number;
+ grub_uint8_t reserved[5];
+ grub_uint64_t addr;
+ grub_uint64_t page_size;
+ grub_uint64_t reserver;
+};
+
+struct grub_efi_sal_system_table_purge_translation_coherence
+{
+ grub_uint8_t type;
+ grub_uint8_t reserved[3];
+ grub_uint32_t ndomains;
+ grub_uint64_t coherence;
+};
+
+struct grub_efi_sal_system_table_ap_wakeup
+{
+ grub_uint8_t type;
+ grub_uint8_t mechanism;
+ grub_uint8_t reserved[6];
+ grub_uint64_t vector;
+};
+
+enum
+ {
+ GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_BUSLOCK = 1,
+ GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IRQREDIRECT = 2,
+ GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IPIREDIRECT = 4,
+ GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_ITCDRIFT = 8,
+ };
+
+typedef enum grub_efi_parity_type
+ {
+ GRUB_EFI_SERIAL_DEFAULT_PARITY,
+ GRUB_EFI_SERIAL_NO_PARITY,
+ GRUB_EFI_SERIAL_EVEN_PARITY,
+ GRUB_EFI_SERIAL_ODD_PARITY
+ }
+grub_efi_parity_type_t;
+
+typedef enum grub_efi_stop_bits
+ {
+ GRUB_EFI_SERIAL_DEFAULT_STOP_BITS,
+ GRUB_EFI_SERIAL_1_STOP_BIT,
+ GRUB_EFI_SERIAL_1_5_STOP_BITS,
+ GRUB_EFI_SERIAL_2_STOP_BITS
+ }
+ grub_efi_stop_bits_t;
+
+/* Enumerations. */
+enum grub_efi_timer_delay
+ {
+ GRUB_EFI_TIMER_CANCEL,
+ GRUB_EFI_TIMER_PERIODIC,
+ GRUB_EFI_TIMER_RELATIVE
+ };
+typedef enum grub_efi_timer_delay grub_efi_timer_delay_t;
+
+enum grub_efi_allocate_type
+ {
+ GRUB_EFI_ALLOCATE_ANY_PAGES,
+ GRUB_EFI_ALLOCATE_MAX_ADDRESS,
+ GRUB_EFI_ALLOCATE_ADDRESS,
+ GRUB_EFI_MAX_ALLOCATION_TYPE
+ };
+typedef enum grub_efi_allocate_type grub_efi_allocate_type_t;
+
+enum grub_efi_memory_type
+ {
+ GRUB_EFI_RESERVED_MEMORY_TYPE,
+ GRUB_EFI_LOADER_CODE,
+ GRUB_EFI_LOADER_DATA,
+ GRUB_EFI_BOOT_SERVICES_CODE,
+ GRUB_EFI_BOOT_SERVICES_DATA,
+ GRUB_EFI_RUNTIME_SERVICES_CODE,
+ GRUB_EFI_RUNTIME_SERVICES_DATA,
+ GRUB_EFI_CONVENTIONAL_MEMORY,
+ GRUB_EFI_UNUSABLE_MEMORY,
+ GRUB_EFI_ACPI_RECLAIM_MEMORY,
+ GRUB_EFI_ACPI_MEMORY_NVS,
+ GRUB_EFI_MEMORY_MAPPED_IO,
+ GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE,
+ GRUB_EFI_PAL_CODE,
+ GRUB_EFI_PERSISTENT_MEMORY,
+ GRUB_EFI_MAX_MEMORY_TYPE
+ };
+typedef enum grub_efi_memory_type grub_efi_memory_type_t;
+
+enum grub_efi_interface_type
+ {
+ GRUB_EFI_NATIVE_INTERFACE
+ };
+typedef enum grub_efi_interface_type grub_efi_interface_type_t;
+
+enum grub_efi_locate_search_type
+ {
+ GRUB_EFI_ALL_HANDLES,
+ GRUB_EFI_BY_REGISTER_NOTIFY,
+ GRUB_EFI_BY_PROTOCOL
+ };
+typedef enum grub_efi_locate_search_type grub_efi_locate_search_type_t;
+
+enum grub_efi_reset_type
+ {
+ GRUB_EFI_RESET_COLD,
+ GRUB_EFI_RESET_WARM,
+ GRUB_EFI_RESET_SHUTDOWN
+ };
+typedef enum grub_efi_reset_type grub_efi_reset_type_t;
+
+/* Types. */
+typedef char grub_efi_boolean_t;
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+typedef grub_int64_t grub_efi_intn_t;
+typedef grub_uint64_t grub_efi_uintn_t;
+#else
+typedef grub_int32_t grub_efi_intn_t;
+typedef grub_uint32_t grub_efi_uintn_t;
+#endif
+typedef grub_int8_t grub_efi_int8_t;
+typedef grub_uint8_t grub_efi_uint8_t;
+typedef grub_int16_t grub_efi_int16_t;
+typedef grub_uint16_t grub_efi_uint16_t;
+typedef grub_int32_t grub_efi_int32_t;
+typedef grub_uint32_t grub_efi_uint32_t;
+typedef grub_int64_t grub_efi_int64_t;
+typedef grub_uint64_t grub_efi_uint64_t;
+typedef grub_uint8_t grub_efi_char8_t;
+typedef grub_uint16_t grub_efi_char16_t;
+
+typedef grub_efi_intn_t grub_efi_status_t;
+
+#define GRUB_EFI_ERROR_CODE(value) \
+ ((((grub_efi_status_t) 1) << (sizeof (grub_efi_status_t) * 8 - 1)) | (value))
+
+#define GRUB_EFI_WARNING_CODE(value) (value)
+
+#define GRUB_EFI_SUCCESS 0
+
+#define GRUB_EFI_LOAD_ERROR GRUB_EFI_ERROR_CODE (1)
+#define GRUB_EFI_INVALID_PARAMETER GRUB_EFI_ERROR_CODE (2)
+#define GRUB_EFI_UNSUPPORTED GRUB_EFI_ERROR_CODE (3)
+#define GRUB_EFI_BAD_BUFFER_SIZE GRUB_EFI_ERROR_CODE (4)
+#define GRUB_EFI_BUFFER_TOO_SMALL GRUB_EFI_ERROR_CODE (5)
+#define GRUB_EFI_NOT_READY GRUB_EFI_ERROR_CODE (6)
+#define GRUB_EFI_DEVICE_ERROR GRUB_EFI_ERROR_CODE (7)
+#define GRUB_EFI_WRITE_PROTECTED GRUB_EFI_ERROR_CODE (8)
+#define GRUB_EFI_OUT_OF_RESOURCES GRUB_EFI_ERROR_CODE (9)
+#define GRUB_EFI_VOLUME_CORRUPTED GRUB_EFI_ERROR_CODE (10)
+#define GRUB_EFI_VOLUME_FULL GRUB_EFI_ERROR_CODE (11)
+#define GRUB_EFI_NO_MEDIA GRUB_EFI_ERROR_CODE (12)
+#define GRUB_EFI_MEDIA_CHANGED GRUB_EFI_ERROR_CODE (13)
+#define GRUB_EFI_NOT_FOUND GRUB_EFI_ERROR_CODE (14)
+#define GRUB_EFI_ACCESS_DENIED GRUB_EFI_ERROR_CODE (15)
+#define GRUB_EFI_NO_RESPONSE GRUB_EFI_ERROR_CODE (16)
+#define GRUB_EFI_NO_MAPPING GRUB_EFI_ERROR_CODE (17)
+#define GRUB_EFI_TIMEOUT GRUB_EFI_ERROR_CODE (18)
+#define GRUB_EFI_NOT_STARTED GRUB_EFI_ERROR_CODE (19)
+#define GRUB_EFI_ALREADY_STARTED GRUB_EFI_ERROR_CODE (20)
+#define GRUB_EFI_ABORTED GRUB_EFI_ERROR_CODE (21)
+#define GRUB_EFI_ICMP_ERROR GRUB_EFI_ERROR_CODE (22)
+#define GRUB_EFI_TFTP_ERROR GRUB_EFI_ERROR_CODE (23)
+#define GRUB_EFI_PROTOCOL_ERROR GRUB_EFI_ERROR_CODE (24)
+#define GRUB_EFI_INCOMPATIBLE_VERSION GRUB_EFI_ERROR_CODE (25)
+#define GRUB_EFI_SECURITY_VIOLATION GRUB_EFI_ERROR_CODE (26)
+#define GRUB_EFI_CRC_ERROR GRUB_EFI_ERROR_CODE (27)
+
+#define GRUB_EFI_WARN_UNKNOWN_GLYPH GRUB_EFI_WARNING_CODE (1)
+#define GRUB_EFI_WARN_DELETE_FAILURE GRUB_EFI_WARNING_CODE (2)
+#define GRUB_EFI_WARN_WRITE_FAILURE GRUB_EFI_WARNING_CODE (3)
+#define GRUB_EFI_WARN_BUFFER_TOO_SMALL GRUB_EFI_WARNING_CODE (4)
+
+typedef void *grub_efi_handle_t;
+typedef void *grub_efi_event_t;
+typedef grub_efi_uint64_t grub_efi_lba_t;
+typedef grub_efi_uintn_t grub_efi_tpl_t;
+typedef grub_uint8_t grub_efi_mac_address_t[32];
+typedef grub_uint8_t grub_efi_ipv4_address_t[4];
+typedef grub_uint16_t grub_efi_ipv6_address_t[8];
+typedef grub_uint8_t grub_efi_ip_address_t[8] __attribute__ ((aligned(4)));
+typedef grub_efi_uint64_t grub_efi_physical_address_t;
+typedef grub_efi_uint64_t grub_efi_virtual_address_t;
+
+struct grub_efi_guid
+{
+ grub_uint32_t data1;
+ grub_uint16_t data2;
+ grub_uint16_t data3;
+ grub_uint8_t data4[8];
+} __attribute__ ((aligned(8)));
+typedef struct grub_efi_guid grub_efi_guid_t;
+
+struct grub_efi_packed_guid
+{
+ grub_uint32_t data1;
+ grub_uint16_t data2;
+ grub_uint16_t data3;
+ grub_uint8_t data4[8];
+} GRUB_PACKED;
+typedef struct grub_efi_packed_guid grub_efi_packed_guid_t;
+
+/* XXX although the spec does not specify the padding, this actually
+ must have the padding! */
+struct grub_efi_memory_descriptor
+{
+ grub_efi_uint32_t type;
+ grub_efi_uint32_t padding;
+ grub_efi_physical_address_t physical_start;
+ grub_efi_virtual_address_t virtual_start;
+ grub_efi_uint64_t num_pages;
+ grub_efi_uint64_t attribute;
+} GRUB_PACKED;
+typedef struct grub_efi_memory_descriptor grub_efi_memory_descriptor_t;
+
+/* Device Path definitions. */
+struct grub_efi_device_path
+{
+ grub_efi_uint8_t type;
+ grub_efi_uint8_t subtype;
+ grub_efi_uint16_t length;
+} GRUB_PACKED;
+typedef struct grub_efi_device_path grub_efi_device_path_t;
+/* XXX EFI does not define EFI_DEVICE_PATH_PROTOCOL but uses it.
+ It seems to be identical to EFI_DEVICE_PATH. */
+typedef struct grub_efi_device_path grub_efi_device_path_protocol_t;
+
+#define GRUB_EFI_DEVICE_PATH_TYPE(dp) ((dp)->type & 0x7f)
+#define GRUB_EFI_DEVICE_PATH_SUBTYPE(dp) ((dp)->subtype)
+#define GRUB_EFI_DEVICE_PATH_LENGTH(dp) ((dp)->length)
+
+/* The End of Device Path nodes. */
+#define GRUB_EFI_END_DEVICE_PATH_TYPE (0xff & 0x7f)
+
+#define GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff
+#define GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE 0x01
+
+#define GRUB_EFI_END_ENTIRE_DEVICE_PATH(dp) \
+ (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \
+ && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \
+ == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE))
+
+#define GRUB_EFI_NEXT_DEVICE_PATH(dp) \
+ ((grub_efi_device_path_t *) ((char *) (dp) \
+ + GRUB_EFI_DEVICE_PATH_LENGTH (dp)))
+
+/* Hardware Device Path. */
+#define GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE 1
+
+#define GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE 1
+
+struct grub_efi_pci_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint8_t function;
+ grub_efi_uint8_t device;
+} GRUB_PACKED;
+typedef struct grub_efi_pci_device_path grub_efi_pci_device_path_t;
+
+#define GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE 2
+
+struct grub_efi_pccard_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint8_t function;
+} GRUB_PACKED;
+typedef struct grub_efi_pccard_device_path grub_efi_pccard_device_path_t;
+
+#define GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE 3
+
+struct grub_efi_memory_mapped_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t memory_type;
+ grub_efi_physical_address_t start_address;
+ grub_efi_physical_address_t end_address;
+} GRUB_PACKED;
+typedef struct grub_efi_memory_mapped_device_path grub_efi_memory_mapped_device_path_t;
+
+#define GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE 4
+
+struct grub_efi_vendor_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_packed_guid_t vendor_guid;
+ grub_efi_uint8_t vendor_defined_data[0];
+} GRUB_PACKED;
+typedef struct grub_efi_vendor_device_path grub_efi_vendor_device_path_t;
+
+#define GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE 5
+
+struct grub_efi_controller_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t controller_number;
+} GRUB_PACKED;
+typedef struct grub_efi_controller_device_path grub_efi_controller_device_path_t;
+
+/* ACPI Device Path. */
+#define GRUB_EFI_ACPI_DEVICE_PATH_TYPE 2
+
+#define GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE 1
+
+struct grub_efi_acpi_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t hid;
+ grub_efi_uint32_t uid;
+} GRUB_PACKED;
+typedef struct grub_efi_acpi_device_path grub_efi_acpi_device_path_t;
+
+#define GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE 2
+
+struct grub_efi_expanded_acpi_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t hid;
+ grub_efi_uint32_t uid;
+ grub_efi_uint32_t cid;
+ char hidstr[0];
+} GRUB_PACKED;
+typedef struct grub_efi_expanded_acpi_device_path grub_efi_expanded_acpi_device_path_t;
+
+#define GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp) \
+ (((grub_efi_expanded_acpi_device_path_t *) dp)->hidstr)
+#define GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp) \
+ (GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp) \
+ + grub_strlen (GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp)) + 1)
+#define GRUB_EFI_EXPANDED_ACPI_CIDSTR(dp) \
+ (GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp) \
+ + grub_strlen (GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp)) + 1)
+
+/* Messaging Device Path. */
+#define GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE 3
+
+#define GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE 1
+
+struct grub_efi_atapi_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint8_t primary_secondary;
+ grub_efi_uint8_t slave_master;
+ grub_efi_uint16_t lun;
+} GRUB_PACKED;
+typedef struct grub_efi_atapi_device_path grub_efi_atapi_device_path_t;
+
+#define GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE 2
+
+struct grub_efi_scsi_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint16_t pun;
+ grub_efi_uint16_t lun;
+} GRUB_PACKED;
+typedef struct grub_efi_scsi_device_path grub_efi_scsi_device_path_t;
+
+#define GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE 3
+
+struct grub_efi_fibre_channel_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t reserved;
+ grub_efi_uint64_t wwn;
+ grub_efi_uint64_t lun;
+} GRUB_PACKED;
+typedef struct grub_efi_fibre_channel_device_path grub_efi_fibre_channel_device_path_t;
+
+#define GRUB_EFI_1394_DEVICE_PATH_SUBTYPE 4
+
+struct grub_efi_1394_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t reserved;
+ grub_efi_uint64_t guid;
+} GRUB_PACKED;
+typedef struct grub_efi_1394_device_path grub_efi_1394_device_path_t;
+
+#define GRUB_EFI_USB_DEVICE_PATH_SUBTYPE 5
+
+struct grub_efi_usb_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint8_t parent_port_number;
+ grub_efi_uint8_t usb_interface;
+} GRUB_PACKED;
+typedef struct grub_efi_usb_device_path grub_efi_usb_device_path_t;
+
+#define GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE 15
+
+struct grub_efi_usb_class_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint16_t vendor_id;
+ grub_efi_uint16_t product_id;
+ grub_efi_uint8_t device_class;
+ grub_efi_uint8_t device_subclass;
+ grub_efi_uint8_t device_protocol;
+} GRUB_PACKED;
+typedef struct grub_efi_usb_class_device_path grub_efi_usb_class_device_path_t;
+
+#define GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE 6
+
+struct grub_efi_i2o_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t tid;
+} GRUB_PACKED;
+typedef struct grub_efi_i2o_device_path grub_efi_i2o_device_path_t;
+
+#define GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE 11
+
+struct grub_efi_mac_address_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_mac_address_t mac_address;
+ grub_efi_uint8_t if_type;
+} GRUB_PACKED;
+typedef struct grub_efi_mac_address_device_path grub_efi_mac_address_device_path_t;
+
+#define GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE 12
+
+struct grub_efi_ipv4_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_ipv4_address_t local_ip_address;
+ grub_efi_ipv4_address_t remote_ip_address;
+ grub_efi_uint16_t local_port;
+ grub_efi_uint16_t remote_port;
+ grub_efi_uint16_t protocol;
+ grub_efi_uint8_t static_ip_address;
+} GRUB_PACKED;
+typedef struct grub_efi_ipv4_device_path grub_efi_ipv4_device_path_t;
+
+#define GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE 13
+
+struct grub_efi_ipv6_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_ipv6_address_t local_ip_address;
+ grub_efi_ipv6_address_t remote_ip_address;
+ grub_efi_uint16_t local_port;
+ grub_efi_uint16_t remote_port;
+ grub_efi_uint16_t protocol;
+ grub_efi_uint8_t static_ip_address;
+} GRUB_PACKED;
+typedef struct grub_efi_ipv6_device_path grub_efi_ipv6_device_path_t;
+
+#define GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE 9
+
+struct grub_efi_infiniband_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t resource_flags;
+ grub_efi_uint8_t port_gid[16];
+ grub_efi_uint64_t remote_id;
+ grub_efi_uint64_t target_port_id;
+ grub_efi_uint64_t device_id;
+} GRUB_PACKED;
+typedef struct grub_efi_infiniband_device_path grub_efi_infiniband_device_path_t;
+
+#define GRUB_EFI_UART_DEVICE_PATH_SUBTYPE 14
+
+struct grub_efi_uart_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t reserved;
+ grub_efi_uint64_t baud_rate;
+ grub_efi_uint8_t data_bits;
+ grub_efi_uint8_t parity;
+ grub_efi_uint8_t stop_bits;
+} GRUB_PACKED;
+typedef struct grub_efi_uart_device_path grub_efi_uart_device_path_t;
+
+#define GRUB_EFI_SATA_DEVICE_PATH_SUBTYPE 18
+
+struct grub_efi_sata_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint16_t hba_port;
+ grub_efi_uint16_t multiplier_port;
+ grub_efi_uint16_t lun;
+} GRUB_PACKED;
+typedef struct grub_efi_sata_device_path grub_efi_sata_device_path_t;
+
+#define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10
+
+/* Media Device Path. */
+#define GRUB_EFI_MEDIA_DEVICE_PATH_TYPE 4
+
+#define GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE 1
+
+struct grub_efi_hard_drive_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t partition_number;
+ grub_efi_lba_t partition_start;
+ grub_efi_lba_t partition_size;
+ grub_efi_uint8_t partition_signature[16];
+ grub_efi_uint8_t partmap_type;
+ grub_efi_uint8_t signature_type;
+} GRUB_PACKED;
+typedef struct grub_efi_hard_drive_device_path grub_efi_hard_drive_device_path_t;
+
+#define GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE 2
+
+struct grub_efi_cdrom_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint32_t boot_entry;
+ grub_efi_lba_t partition_start;
+ grub_efi_lba_t partition_size;
+} GRUB_PACKED;
+typedef struct grub_efi_cdrom_device_path grub_efi_cdrom_device_path_t;
+
+#define GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE 3
+
+struct grub_efi_vendor_media_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_packed_guid_t vendor_guid;
+ grub_efi_uint8_t vendor_defined_data[0];
+} GRUB_PACKED;
+typedef struct grub_efi_vendor_media_device_path grub_efi_vendor_media_device_path_t;
+
+#define GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE 4
+
+struct grub_efi_file_path_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_char16_t path_name[0];
+} GRUB_PACKED;
+typedef struct grub_efi_file_path_device_path grub_efi_file_path_device_path_t;
+
+#define GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE 5
+
+struct grub_efi_protocol_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_packed_guid_t guid;
+} GRUB_PACKED;
+typedef struct grub_efi_protocol_device_path grub_efi_protocol_device_path_t;
+
+#define GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE 6
+
+struct grub_efi_piwg_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_packed_guid_t guid;
+} GRUB_PACKED;
+typedef struct grub_efi_piwg_device_path grub_efi_piwg_device_path_t;
+
+
+/* BIOS Boot Specification Device Path. */
+#define GRUB_EFI_BIOS_DEVICE_PATH_TYPE 5
+
+#define GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE 1
+
+struct grub_efi_bios_device_path
+{
+ grub_efi_device_path_t header;
+ grub_efi_uint16_t device_type;
+ grub_efi_uint16_t status_flags;
+ char description[0];
+} GRUB_PACKED;
+typedef struct grub_efi_bios_device_path grub_efi_bios_device_path_t;
+
+struct grub_efi_open_protocol_information_entry
+{
+ grub_efi_handle_t agent_handle;
+ grub_efi_handle_t controller_handle;
+ grub_efi_uint32_t attributes;
+ grub_efi_uint32_t open_count;
+};
+typedef struct grub_efi_open_protocol_information_entry grub_efi_open_protocol_information_entry_t;
+
+struct grub_efi_time
+{
+ grub_efi_uint16_t year;
+ grub_efi_uint8_t month;
+ grub_efi_uint8_t day;
+ grub_efi_uint8_t hour;
+ grub_efi_uint8_t minute;
+ grub_efi_uint8_t second;
+ grub_efi_uint8_t pad1;
+ grub_efi_uint32_t nanosecond;
+ grub_efi_int16_t time_zone;
+ grub_efi_uint8_t daylight;
+ grub_efi_uint8_t pad2;
+} GRUB_PACKED;
+typedef struct grub_efi_time grub_efi_time_t;
+
+struct grub_efi_time_capabilities
+{
+ grub_efi_uint32_t resolution;
+ grub_efi_uint32_t accuracy;
+ grub_efi_boolean_t sets_to_zero;
+};
+typedef struct grub_efi_time_capabilities grub_efi_time_capabilities_t;
+
+struct grub_efi_input_key
+{
+ grub_efi_uint16_t scan_code;
+ grub_efi_char16_t unicode_char;
+};
+typedef struct grub_efi_input_key grub_efi_input_key_t;
+
+typedef grub_efi_uint8_t grub_efi_key_toggle_state_t;
+struct grub_efi_key_state
+{
+ grub_efi_uint32_t key_shift_state;
+ grub_efi_key_toggle_state_t key_toggle_state;
+};
+typedef struct grub_efi_key_state grub_efi_key_state_t;
+
+#define GRUB_EFI_SHIFT_STATE_VALID 0x80000000
+#define GRUB_EFI_RIGHT_SHIFT_PRESSED 0x00000001
+#define GRUB_EFI_LEFT_SHIFT_PRESSED 0x00000002
+#define GRUB_EFI_RIGHT_CONTROL_PRESSED 0x00000004
+#define GRUB_EFI_LEFT_CONTROL_PRESSED 0x00000008
+#define GRUB_EFI_RIGHT_ALT_PRESSED 0x00000010
+#define GRUB_EFI_LEFT_ALT_PRESSED 0x00000020
+#define GRUB_EFI_RIGHT_LOGO_PRESSED 0x00000040
+#define GRUB_EFI_LEFT_LOGO_PRESSED 0x00000080
+#define GRUB_EFI_MENU_KEY_PRESSED 0x00000100
+#define GRUB_EFI_SYS_REQ_PRESSED 0x00000200
+
+#define GRUB_EFI_TOGGLE_STATE_VALID 0x80
+#define GRUB_EFI_KEY_STATE_EXPOSED 0x40
+#define GRUB_EFI_SCROLL_LOCK_ACTIVE 0x01
+#define GRUB_EFI_NUM_LOCK_ACTIVE 0x02
+#define GRUB_EFI_CAPS_LOCK_ACTIVE 0x04
+
+struct grub_efi_simple_text_output_mode
+{
+ grub_efi_int32_t max_mode;
+ grub_efi_int32_t mode;
+ grub_efi_int32_t attribute;
+ grub_efi_int32_t cursor_column;
+ grub_efi_int32_t cursor_row;
+ grub_efi_boolean_t cursor_visible;
+};
+typedef struct grub_efi_simple_text_output_mode grub_efi_simple_text_output_mode_t;
+
+/* Tables. */
+struct grub_efi_table_header
+{
+ grub_efi_uint64_t signature;
+ grub_efi_uint32_t revision;
+ grub_efi_uint32_t header_size;
+ grub_efi_uint32_t crc32;
+ grub_efi_uint32_t reserved;
+};
+typedef struct grub_efi_table_header grub_efi_table_header_t;
+
+struct grub_efi_boot_services
+{
+ grub_efi_table_header_t hdr;
+
+ grub_efi_tpl_t
+ (*raise_tpl) (grub_efi_tpl_t new_tpl);
+
+ void
+ (*restore_tpl) (grub_efi_tpl_t old_tpl);
+
+ grub_efi_status_t
+ (*allocate_pages) (grub_efi_allocate_type_t type,
+ grub_efi_memory_type_t memory_type,
+ grub_efi_uintn_t pages,
+ grub_efi_physical_address_t *memory);
+
+ grub_efi_status_t
+ (*free_pages) (grub_efi_physical_address_t memory,
+ grub_efi_uintn_t pages);
+
+ grub_efi_status_t
+ (*get_memory_map) (grub_efi_uintn_t *memory_map_size,
+ grub_efi_memory_descriptor_t *memory_map,
+ grub_efi_uintn_t *map_key,
+ grub_efi_uintn_t *descriptor_size,
+ grub_efi_uint32_t *descriptor_version);
+
+ grub_efi_status_t
+ (*allocate_pool) (grub_efi_memory_type_t pool_type,
+ grub_efi_uintn_t size,
+ void **buffer);
+
+ grub_efi_status_t
+ (*free_pool) (void *buffer);
+
+ grub_efi_status_t
+ (*create_event) (grub_efi_uint32_t type,
+ grub_efi_tpl_t notify_tpl,
+ void (*notify_function) (grub_efi_event_t event,
+ void *context),
+ void *notify_context,
+ grub_efi_event_t *event);
+
+ grub_efi_status_t
+ (*set_timer) (grub_efi_event_t event,
+ grub_efi_timer_delay_t type,
+ grub_efi_uint64_t trigger_time);
+
+ grub_efi_status_t
+ (*wait_for_event) (grub_efi_uintn_t num_events,
+ grub_efi_event_t *event,
+ grub_efi_uintn_t *index);
+
+ grub_efi_status_t
+ (*signal_event) (grub_efi_event_t event);
+
+ grub_efi_status_t
+ (*close_event) (grub_efi_event_t event);
+
+ grub_efi_status_t
+ (*check_event) (grub_efi_event_t event);
+
+ grub_efi_status_t
+ (*install_protocol_interface) (grub_efi_handle_t *handle,
+ grub_efi_guid_t *protocol,
+ grub_efi_interface_type_t protocol_interface_type,
+ void *protocol_interface);
+
+ grub_efi_status_t
+ (*reinstall_protocol_interface) (grub_efi_handle_t handle,
+ grub_efi_guid_t *protocol,
+ void *old_interface,
+ void *new_interface);
+
+ grub_efi_status_t
+ (*uninstall_protocol_interface) (grub_efi_handle_t handle,
+ grub_efi_guid_t *protocol,
+ void *protocol_interface);
+
+ grub_efi_status_t
+ (*handle_protocol) (grub_efi_handle_t handle,
+ grub_efi_guid_t *protocol,
+ void **protocol_interface);
+
+ void *reserved;
+
+ grub_efi_status_t
+ (*register_protocol_notify) (grub_efi_guid_t *protocol,
+ grub_efi_event_t event,
+ void **registration);
+
+ grub_efi_status_t
+ (*locate_handle) (grub_efi_locate_search_type_t search_type,
+ grub_efi_guid_t *protocol,
+ void *search_key,
+ grub_efi_uintn_t *buffer_size,
+ grub_efi_handle_t *buffer);
+
+ grub_efi_status_t
+ (*locate_device_path) (grub_efi_guid_t *protocol,
+ grub_efi_device_path_t **device_path,
+ grub_efi_handle_t *device);
+
+ grub_efi_status_t
+ (*install_configuration_table) (grub_efi_guid_t *guid, void *table);
+
+ grub_efi_status_t
+ (*load_image) (grub_efi_boolean_t boot_policy,
+ grub_efi_handle_t parent_image_handle,
+ grub_efi_device_path_t *file_path,
+ void *source_buffer,
+ grub_efi_uintn_t source_size,
+ grub_efi_handle_t *image_handle);
+
+ grub_efi_status_t
+ (*start_image) (grub_efi_handle_t image_handle,
+ grub_efi_uintn_t *exit_data_size,
+ grub_efi_char16_t **exit_data);
+
+ grub_efi_status_t
+ (*exit) (grub_efi_handle_t image_handle,
+ grub_efi_status_t exit_status,
+ grub_efi_uintn_t exit_data_size,
+ grub_efi_char16_t *exit_data) __attribute__((noreturn));
+
+ grub_efi_status_t
+ (*unload_image) (grub_efi_handle_t image_handle);
+
+ grub_efi_status_t
+ (*exit_boot_services) (grub_efi_handle_t image_handle,
+ grub_efi_uintn_t map_key);
+
+ grub_efi_status_t
+ (*get_next_monotonic_count) (grub_efi_uint64_t *count);
+
+ grub_efi_status_t
+ (*stall) (grub_efi_uintn_t microseconds);
+
+ grub_efi_status_t
+ (*set_watchdog_timer) (grub_efi_uintn_t timeout,
+ grub_efi_uint64_t watchdog_code,
+ grub_efi_uintn_t data_size,
+ grub_efi_char16_t *watchdog_data);
+
+ grub_efi_status_t
+ (*connect_controller) (grub_efi_handle_t controller_handle,
+ grub_efi_handle_t *driver_image_handle,
+ grub_efi_device_path_protocol_t *remaining_device_path,
+ grub_efi_boolean_t recursive);
+
+ grub_efi_status_t
+ (*disconnect_controller) (grub_efi_handle_t controller_handle,
+ grub_efi_handle_t driver_image_handle,
+ grub_efi_handle_t child_handle);
+
+ grub_efi_status_t
+ (*open_protocol) (grub_efi_handle_t handle,
+ grub_efi_guid_t *protocol,
+ void **protocol_interface,
+ grub_efi_handle_t agent_handle,
+ grub_efi_handle_t controller_handle,
+ grub_efi_uint32_t attributes);
+
+ grub_efi_status_t
+ (*close_protocol) (grub_efi_handle_t handle,
+ grub_efi_guid_t *protocol,
+ grub_efi_handle_t agent_handle,
+ grub_efi_handle_t controller_handle);
+
+ grub_efi_status_t
+ (*open_protocol_information) (grub_efi_handle_t handle,
+ grub_efi_guid_t *protocol,
+ grub_efi_open_protocol_information_entry_t **entry_buffer,
+ grub_efi_uintn_t *entry_count);
+
+ grub_efi_status_t
+ (*protocols_per_handle) (grub_efi_handle_t handle,
+ grub_efi_packed_guid_t ***protocol_buffer,
+ grub_efi_uintn_t *protocol_buffer_count);
+
+ grub_efi_status_t
+ (*locate_handle_buffer) (grub_efi_locate_search_type_t search_type,
+ grub_efi_guid_t *protocol,
+ void *search_key,
+ grub_efi_uintn_t *no_handles,
+ grub_efi_handle_t **buffer);
+
+ grub_efi_status_t
+ (*locate_protocol) (grub_efi_guid_t *protocol,
+ void *registration,
+ void **protocol_interface);
+
+ grub_efi_status_t
+ (*install_multiple_protocol_interfaces) (grub_efi_handle_t *handle, ...);
+
+ grub_efi_status_t
+ (*uninstall_multiple_protocol_interfaces) (grub_efi_handle_t handle, ...);
+
+ grub_efi_status_t
+ (*calculate_crc32) (void *data,
+ grub_efi_uintn_t data_size,
+ grub_efi_uint32_t *crc32);
+
+ void
+ (*copy_mem) (void *destination, void *source, grub_efi_uintn_t length);
+
+ void
+ (*set_mem) (void *buffer, grub_efi_uintn_t size, grub_efi_uint8_t value);
+};
+typedef struct grub_efi_boot_services grub_efi_boot_services_t;
+
+struct grub_efi_runtime_services
+{
+ grub_efi_table_header_t hdr;
+
+ grub_efi_status_t
+ (*get_time) (grub_efi_time_t *time,
+ grub_efi_time_capabilities_t *capabilities);
+
+ grub_efi_status_t
+ (*set_time) (grub_efi_time_t *time);
+
+ grub_efi_status_t
+ (*get_wakeup_time) (grub_efi_boolean_t *enabled,
+ grub_efi_boolean_t *pending,
+ grub_efi_time_t *time);
+
+ grub_efi_status_t
+ (*set_wakeup_time) (grub_efi_boolean_t enabled,
+ grub_efi_time_t *time);
+
+ grub_efi_status_t
+ (*set_virtual_address_map) (grub_efi_uintn_t memory_map_size,
+ grub_efi_uintn_t descriptor_size,
+ grub_efi_uint32_t descriptor_version,
+ grub_efi_memory_descriptor_t *virtual_map);
+
+ grub_efi_status_t
+ (*convert_pointer) (grub_efi_uintn_t debug_disposition, void **address);
+
+#define GRUB_EFI_GLOBAL_VARIABLE_GUID \
+ { 0x8BE4DF61, 0x93CA, 0x11d2, { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B,0x8C }}
+
+
+ grub_efi_status_t
+ (*get_variable) (grub_efi_char16_t *variable_name,
+ const grub_efi_guid_t *vendor_guid,
+ grub_efi_uint32_t *attributes,
+ grub_efi_uintn_t *data_size,
+ void *data);
+
+ grub_efi_status_t
+ (*get_next_variable_name) (grub_efi_uintn_t *variable_name_size,
+ grub_efi_char16_t *variable_name,
+ grub_efi_guid_t *vendor_guid);
+
+ grub_efi_status_t
+ (*set_variable) (grub_efi_char16_t *variable_name,
+ const grub_efi_guid_t *vendor_guid,
+ grub_efi_uint32_t attributes,
+ grub_efi_uintn_t data_size,
+ void *data);
+
+ grub_efi_status_t
+ (*get_next_high_monotonic_count) (grub_efi_uint32_t *high_count);
+
+ void
+ (*reset_system) (grub_efi_reset_type_t reset_type,
+ grub_efi_status_t reset_status,
+ grub_efi_uintn_t data_size,
+ grub_efi_char16_t *reset_data);
+};
+typedef struct grub_efi_runtime_services grub_efi_runtime_services_t;
+
+struct grub_efi_configuration_table
+{
+ grub_efi_packed_guid_t vendor_guid;
+ void *vendor_table;
+} GRUB_PACKED;
+typedef struct grub_efi_configuration_table grub_efi_configuration_table_t;
+
+#define GRUB_EFIEMU_SYSTEM_TABLE_SIGNATURE 0x5453595320494249LL
+#define GRUB_EFIEMU_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552LL
+
+struct grub_efi_serial_io_interface
+{
+ grub_efi_uint32_t revision;
+ void (*reset) (void);
+ grub_efi_status_t (*set_attributes) (struct grub_efi_serial_io_interface *this,
+ grub_efi_uint64_t speed,
+ grub_efi_uint32_t fifo_depth,
+ grub_efi_uint32_t timeout,
+ grub_efi_parity_type_t parity,
+ grub_uint8_t word_len,
+ grub_efi_stop_bits_t stop_bits);
+ grub_efi_status_t (*set_control_bits) (struct grub_efi_serial_io_interface *this,
+ grub_efi_uint32_t flags);
+ void (*get_control_bits) (void);
+ grub_efi_status_t (*write) (struct grub_efi_serial_io_interface *this,
+ grub_efi_uintn_t *buf_size,
+ void *buffer);
+ grub_efi_status_t (*read) (struct grub_efi_serial_io_interface *this,
+ grub_efi_uintn_t *buf_size,
+ void *buffer);
+};
+
+struct grub_efi_simple_input_interface
+{
+ grub_efi_status_t
+ (*reset) (struct grub_efi_simple_input_interface *this,
+ grub_efi_boolean_t extended_verification);
+
+ grub_efi_status_t
+ (*read_key_stroke) (struct grub_efi_simple_input_interface *this,
+ grub_efi_input_key_t *key);
+
+ grub_efi_event_t wait_for_key;
+};
+typedef struct grub_efi_simple_input_interface grub_efi_simple_input_interface_t;
+
+struct grub_efi_key_data {
+ grub_efi_input_key_t key;
+ grub_efi_key_state_t key_state;
+};
+typedef struct grub_efi_key_data grub_efi_key_data_t;
+
+typedef grub_efi_status_t (*grub_efi_key_notify_function_t) (
+ grub_efi_key_data_t *key_data
+ );
+
+struct grub_efi_simple_text_input_ex_interface
+{
+ grub_efi_status_t
+ (*reset) (struct grub_efi_simple_text_input_ex_interface *this,
+ grub_efi_boolean_t extended_verification);
+
+ grub_efi_status_t
+ (*read_key_stroke) (struct grub_efi_simple_text_input_ex_interface *this,
+ grub_efi_key_data_t *key_data);
+
+ grub_efi_event_t wait_for_key;
+
+ grub_efi_status_t
+ (*set_state) (struct grub_efi_simple_text_input_ex_interface *this,
+ grub_efi_key_toggle_state_t *key_toggle_state);
+
+ grub_efi_status_t
+ (*register_key_notify) (struct grub_efi_simple_text_input_ex_interface *this,
+ grub_efi_key_data_t *key_data,
+ grub_efi_key_notify_function_t key_notification_function);
+
+ grub_efi_status_t
+ (*unregister_key_notify) (struct grub_efi_simple_text_input_ex_interface *this,
+ void *notification_handle);
+};
+typedef struct grub_efi_simple_text_input_ex_interface grub_efi_simple_text_input_ex_interface_t;
+
+struct grub_efi_simple_text_output_interface
+{
+ grub_efi_status_t
+ (*reset) (struct grub_efi_simple_text_output_interface *this,
+ grub_efi_boolean_t extended_verification);
+
+ grub_efi_status_t
+ (*output_string) (struct grub_efi_simple_text_output_interface *this,
+ grub_efi_char16_t *string);
+
+ grub_efi_status_t
+ (*test_string) (struct grub_efi_simple_text_output_interface *this,
+ grub_efi_char16_t *string);
+
+ grub_efi_status_t
+ (*query_mode) (struct grub_efi_simple_text_output_interface *this,
+ grub_efi_uintn_t mode_number,
+ grub_efi_uintn_t *columns,
+ grub_efi_uintn_t *rows);
+
+ grub_efi_status_t
+ (*set_mode) (struct grub_efi_simple_text_output_interface *this,
+ grub_efi_uintn_t mode_number);
+
+ grub_efi_status_t
+ (*set_attributes) (struct grub_efi_simple_text_output_interface *this,
+ grub_efi_uintn_t attribute);
+
+ grub_efi_status_t
+ (*clear_screen) (struct grub_efi_simple_text_output_interface *this);
+
+ grub_efi_status_t
+ (*set_cursor_position) (struct grub_efi_simple_text_output_interface *this,
+ grub_efi_uintn_t column,
+ grub_efi_uintn_t row);
+
+ grub_efi_status_t
+ (*enable_cursor) (struct grub_efi_simple_text_output_interface *this,
+ grub_efi_boolean_t visible);
+
+ grub_efi_simple_text_output_mode_t *mode;
+};
+typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output_interface_t;
+
+typedef grub_uint8_t grub_efi_pxe_packet_t[1472];
+
+typedef struct grub_efi_pxe_mode
+{
+ grub_uint8_t unused[52];
+ grub_efi_pxe_packet_t dhcp_discover;
+ grub_efi_pxe_packet_t dhcp_ack;
+ grub_efi_pxe_packet_t proxy_offer;
+ grub_efi_pxe_packet_t pxe_discover;
+ grub_efi_pxe_packet_t pxe_reply;
+} grub_efi_pxe_mode_t;
+
+typedef struct grub_efi_pxe
+{
+ grub_uint64_t rev;
+ void (*start) (void);
+ void (*stop) (void);
+ void (*dhcp) (void);
+ void (*discover) (void);
+ void (*mftp) (void);
+ void (*udpwrite) (void);
+ void (*udpread) (void);
+ void (*setipfilter) (void);
+ void (*arp) (void);
+ void (*setparams) (void);
+ void (*setstationip) (void);
+ void (*setpackets) (void);
+ struct grub_efi_pxe_mode *mode;
+} grub_efi_pxe_t;
+
+#define GRUB_EFI_BLACK 0x00
+#define GRUB_EFI_BLUE 0x01
+#define GRUB_EFI_GREEN 0x02
+#define GRUB_EFI_CYAN 0x03
+#define GRUB_EFI_RED 0x04
+#define GRUB_EFI_MAGENTA 0x05
+#define GRUB_EFI_BROWN 0x06
+#define GRUB_EFI_LIGHTGRAY 0x07
+#define GRUB_EFI_BRIGHT 0x08
+#define GRUB_EFI_DARKGRAY 0x08
+#define GRUB_EFI_LIGHTBLUE 0x09
+#define GRUB_EFI_LIGHTGREEN 0x0A
+#define GRUB_EFI_LIGHTCYAN 0x0B
+#define GRUB_EFI_LIGHTRED 0x0C
+#define GRUB_EFI_LIGHTMAGENTA 0x0D
+#define GRUB_EFI_YELLOW 0x0E
+#define GRUB_EFI_WHITE 0x0F
+
+#define GRUB_EFI_BACKGROUND_BLACK 0x00
+#define GRUB_EFI_BACKGROUND_BLUE 0x10
+#define GRUB_EFI_BACKGROUND_GREEN 0x20
+#define GRUB_EFI_BACKGROUND_CYAN 0x30
+#define GRUB_EFI_BACKGROUND_RED 0x40
+#define GRUB_EFI_BACKGROUND_MAGENTA 0x50
+#define GRUB_EFI_BACKGROUND_BROWN 0x60
+#define GRUB_EFI_BACKGROUND_LIGHTGRAY 0x70
+
+#define GRUB_EFI_TEXT_ATTR(fg, bg) ((fg) | ((bg)))
+
+struct grub_efi_system_table
+{
+ grub_efi_table_header_t hdr;
+ grub_efi_char16_t *firmware_vendor;
+ grub_efi_uint32_t firmware_revision;
+ grub_efi_handle_t console_in_handler;
+ grub_efi_simple_input_interface_t *con_in;
+ grub_efi_handle_t console_out_handler;
+ grub_efi_simple_text_output_interface_t *con_out;
+ grub_efi_handle_t standard_error_handle;
+ grub_efi_simple_text_output_interface_t *std_err;
+ grub_efi_runtime_services_t *runtime_services;
+ grub_efi_boot_services_t *boot_services;
+ grub_efi_uintn_t num_table_entries;
+ grub_efi_configuration_table_t *configuration_table;
+};
+typedef struct grub_efi_system_table grub_efi_system_table_t;
+
+struct grub_efi_loaded_image
+{
+ grub_efi_uint32_t revision;
+ grub_efi_handle_t parent_handle;
+ grub_efi_system_table_t *system_table;
+
+ grub_efi_handle_t device_handle;
+ grub_efi_device_path_t *file_path;
+ void *reserved;
+
+ grub_efi_uint32_t load_options_size;
+ void *load_options;
+
+ void *image_base;
+ grub_efi_uint64_t image_size;
+ grub_efi_memory_type_t image_code_type;
+ grub_efi_memory_type_t image_data_type;
+
+ grub_efi_status_t (*unload) (grub_efi_handle_t image_handle);
+};
+typedef struct grub_efi_loaded_image grub_efi_loaded_image_t;
+
+struct grub_efi_disk_io
+{
+ grub_efi_uint64_t revision;
+ grub_efi_status_t (*read) (struct grub_efi_disk_io *this,
+ grub_efi_uint32_t media_id,
+ grub_efi_uint64_t offset,
+ grub_efi_uintn_t buffer_size,
+ void *buffer);
+ grub_efi_status_t (*write) (struct grub_efi_disk_io *this,
+ grub_efi_uint32_t media_id,
+ grub_efi_uint64_t offset,
+ grub_efi_uintn_t buffer_size,
+ void *buffer);
+};
+typedef struct grub_efi_disk_io grub_efi_disk_io_t;
+
+struct grub_efi_block_io_media
+{
+ grub_efi_uint32_t media_id;
+ grub_efi_boolean_t removable_media;
+ grub_efi_boolean_t media_present;
+ grub_efi_boolean_t logical_partition;
+ grub_efi_boolean_t read_only;
+ grub_efi_boolean_t write_caching;
+ grub_efi_uint8_t pad[3];
+ grub_efi_uint32_t block_size;
+ grub_efi_uint32_t io_align;
+ grub_efi_uint8_t pad2[4];
+ grub_efi_lba_t last_block;
+};
+typedef struct grub_efi_block_io_media grub_efi_block_io_media_t;
+
+typedef grub_uint8_t grub_efi_mac_t[32];
+
+struct grub_efi_simple_network_mode
+{
+ grub_uint32_t state;
+ grub_uint32_t hwaddr_size;
+ grub_uint32_t media_header_size;
+ grub_uint32_t max_packet_size;
+ grub_uint32_t nvram_size;
+ grub_uint32_t nvram_access_size;
+ grub_uint32_t receive_filter_mask;
+ grub_uint32_t receive_filter_setting;
+ grub_uint32_t max_mcast_filter_count;
+ grub_uint32_t mcast_filter_count;
+ grub_efi_mac_t mcast_filter[16];
+ grub_efi_mac_t current_address;
+ grub_efi_mac_t broadcast_address;
+ grub_efi_mac_t permanent_address;
+ grub_uint8_t if_type;
+ grub_uint8_t mac_changeable;
+ grub_uint8_t multitx_supported;
+ grub_uint8_t media_present_supported;
+ grub_uint8_t media_present;
+};
+
+enum
+ {
+ GRUB_EFI_NETWORK_STOPPED,
+ GRUB_EFI_NETWORK_STARTED,
+ GRUB_EFI_NETWORK_INITIALIZED,
+ };
+
+enum
+ {
+ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST = 0x01,
+ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST = 0x02,
+ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST = 0x04,
+ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS = 0x08,
+ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST = 0x10,
+ };
+
+struct grub_efi_simple_network
+{
+ grub_uint64_t revision;
+ grub_efi_status_t (*start) (struct grub_efi_simple_network *this);
+ grub_efi_status_t (*stop) (struct grub_efi_simple_network *this);
+ grub_efi_status_t (*initialize) (struct grub_efi_simple_network *this,
+ grub_efi_uintn_t extra_rx,
+ grub_efi_uintn_t extra_tx);
+ void (*reset) (void);
+ grub_efi_status_t (*shutdown) (struct grub_efi_simple_network *this);
+ grub_efi_status_t (*receive_filters) (struct grub_efi_simple_network *this,
+ grub_uint32_t enable,
+ grub_uint32_t disable,
+ grub_efi_boolean_t reset_mcast_filter,
+ grub_efi_uintn_t mcast_filter_count,
+ grub_efi_mac_address_t *mcast_filter);
+ void (*station_address) (void);
+ void (*statistics) (void);
+ void (*mcastiptomac) (void);
+ void (*nvdata) (void);
+ grub_efi_status_t (*get_status) (struct grub_efi_simple_network *this,
+ grub_uint32_t *int_status,
+ void **txbuf);
+ grub_efi_status_t (*transmit) (struct grub_efi_simple_network *this,
+ grub_efi_uintn_t header_size,
+ grub_efi_uintn_t buffer_size,
+ void *buffer,
+ grub_efi_mac_t *src_addr,
+ grub_efi_mac_t *dest_addr,
+ grub_efi_uint16_t *protocol);
+ grub_efi_status_t (*receive) (struct grub_efi_simple_network *this,
+ grub_efi_uintn_t *header_size,
+ grub_efi_uintn_t *buffer_size,
+ void *buffer,
+ grub_efi_mac_t *src_addr,
+ grub_efi_mac_t *dest_addr,
+ grub_uint16_t *protocol);
+ void (*waitforpacket) (void);
+ struct grub_efi_simple_network_mode *mode;
+};
+typedef struct grub_efi_simple_network grub_efi_simple_network_t;
+
+
+struct grub_efi_block_io
+{
+ grub_efi_uint64_t revision;
+ grub_efi_block_io_media_t *media;
+ grub_efi_status_t (*reset) (struct grub_efi_block_io *this,
+ grub_efi_boolean_t extended_verification);
+ grub_efi_status_t (*read_blocks) (struct grub_efi_block_io *this,
+ grub_efi_uint32_t media_id,
+ grub_efi_lba_t lba,
+ grub_efi_uintn_t buffer_size,
+ void *buffer);
+ grub_efi_status_t (*write_blocks) (struct grub_efi_block_io *this,
+ grub_efi_uint32_t media_id,
+ grub_efi_lba_t lba,
+ grub_efi_uintn_t buffer_size,
+ void *buffer);
+ grub_efi_status_t (*flush_blocks) (struct grub_efi_block_io *this);
+};
+typedef struct grub_efi_block_io grub_efi_block_io_t;
+
+#if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \
+ || defined (__aarch64__) || defined(__mips__) || defined (__MINGW64__) || defined (__CYGWIN__) \
+ || defined(__riscv)
+
+#define efi_call_0(func) func()
+#define efi_call_1(func, a) func(a)
+#define efi_call_2(func, a, b) func(a, b)
+#define efi_call_3(func, a, b, c) func(a, b, c)
+#define efi_call_4(func, a, b, c, d) func(a, b, c, d)
+#define efi_call_5(func, a, b, c, d, e) func(a, b, c, d, e)
+#define efi_call_6(func, a, b, c, d, e, f) func(a, b, c, d, e, f)
+#define efi_call_7(func, a, b, c, d, e, f, g) func(a, b, c, d, e, f, g)
+#define efi_call_10(func, a, b, c, d, e, f, g, h, i, j) func(a, b, c, d, e, f, g, h, i, j)
+
+#else
+
+#define efi_call_0(func) \
+ efi_wrap_0(func)
+#define efi_call_1(func, a) \
+ efi_wrap_1(func, (grub_uint64_t) (a))
+#define efi_call_2(func, a, b) \
+ efi_wrap_2(func, (grub_uint64_t) (a), (grub_uint64_t) (b))
+#define efi_call_3(func, a, b, c) \
+ efi_wrap_3(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \
+ (grub_uint64_t) (c))
+#define efi_call_4(func, a, b, c, d) \
+ efi_wrap_4(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \
+ (grub_uint64_t) (c), (grub_uint64_t) (d))
+#define efi_call_5(func, a, b, c, d, e) \
+ efi_wrap_5(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \
+ (grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e))
+#define efi_call_6(func, a, b, c, d, e, f) \
+ efi_wrap_6(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \
+ (grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e), \
+ (grub_uint64_t) (f))
+#define efi_call_7(func, a, b, c, d, e, f, g) \
+ efi_wrap_7(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \
+ (grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e), \
+ (grub_uint64_t) (f), (grub_uint64_t) (g))
+#define efi_call_10(func, a, b, c, d, e, f, g, h, i, j) \
+ efi_wrap_10(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \
+ (grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e), \
+ (grub_uint64_t) (f), (grub_uint64_t) (g), (grub_uint64_t) (h), \
+ (grub_uint64_t) (i), (grub_uint64_t) (j))
+
+grub_uint64_t EXPORT_FUNC(efi_wrap_0) (void *func);
+grub_uint64_t EXPORT_FUNC(efi_wrap_1) (void *func, grub_uint64_t arg1);
+grub_uint64_t EXPORT_FUNC(efi_wrap_2) (void *func, grub_uint64_t arg1,
+ grub_uint64_t arg2);
+grub_uint64_t EXPORT_FUNC(efi_wrap_3) (void *func, grub_uint64_t arg1,
+ grub_uint64_t arg2, grub_uint64_t arg3);
+grub_uint64_t EXPORT_FUNC(efi_wrap_4) (void *func, grub_uint64_t arg1,
+ grub_uint64_t arg2, grub_uint64_t arg3,
+ grub_uint64_t arg4);
+grub_uint64_t EXPORT_FUNC(efi_wrap_5) (void *func, grub_uint64_t arg1,
+ grub_uint64_t arg2, grub_uint64_t arg3,
+ grub_uint64_t arg4, grub_uint64_t arg5);
+grub_uint64_t EXPORT_FUNC(efi_wrap_6) (void *func, grub_uint64_t arg1,
+ grub_uint64_t arg2, grub_uint64_t arg3,
+ grub_uint64_t arg4, grub_uint64_t arg5,
+ grub_uint64_t arg6);
+grub_uint64_t EXPORT_FUNC(efi_wrap_7) (void *func, grub_uint64_t arg1,
+ grub_uint64_t arg2, grub_uint64_t arg3,
+ grub_uint64_t arg4, grub_uint64_t arg5,
+ grub_uint64_t arg6, grub_uint64_t arg7);
+grub_uint64_t EXPORT_FUNC(efi_wrap_10) (void *func, grub_uint64_t arg1,
+ grub_uint64_t arg2, grub_uint64_t arg3,
+ grub_uint64_t arg4, grub_uint64_t arg5,
+ grub_uint64_t arg6, grub_uint64_t arg7,
+ grub_uint64_t arg8, grub_uint64_t arg9,
+ grub_uint64_t arg10);
+#endif
+
+#endif /* ! GRUB_EFI_API_HEADER */
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_PE32_HEADER
+#define GRUB_EFI_PE32_HEADER 1
+
+#include <grub/types.h>
+#include <grub/efi/memory.h>
+
+/* The MSDOS compatibility stub. This was copied from the output of
+ objcopy, and it is not necessary to care about what this means. */
+#define GRUB_PE32_MSDOS_STUB \
+ { \
+ 0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, \
+ 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, \
+ 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, \
+ 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, \
+ 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, \
+ 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, \
+ 0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, \
+ 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, \
+ 0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, \
+ 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, \
+ 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \
+ }
+
+#define GRUB_PE32_MSDOS_STUB_SIZE 0x80
+
+#define GRUB_PE32_MAGIC 0x5a4d
+
+/* According to the spec, the minimal alignment is 512 bytes...
+ But some examples (such as EFI drivers in the Intel
+ Sample Implementation) use 32 bytes (0x20) instead, and it seems
+ to be working.
+
+ However, there is firmware showing up in the field now with
+ page alignment constraints to guarantee that page protection
+ bits take effect. Because currently existing GRUB code can not
+ properly distinguish between in-memory and in-file layout, let's
+ bump all alignment to GRUB_EFI_PAGE_SIZE. */
+#define GRUB_PE32_SECTION_ALIGNMENT GRUB_EFI_PAGE_SIZE
+#define GRUB_PE32_FILE_ALIGNMENT GRUB_PE32_SECTION_ALIGNMENT
+
+struct grub_pe32_coff_header
+{
+ grub_uint16_t machine;
+ grub_uint16_t num_sections;
+ grub_uint32_t time;
+ grub_uint32_t symtab_offset;
+ grub_uint32_t num_symbols;
+ grub_uint16_t optional_header_size;
+ grub_uint16_t characteristics;
+};
+
+#define GRUB_PE32_MACHINE_I386 0x14c
+#define GRUB_PE32_MACHINE_MIPS 0x166
+#define GRUB_PE32_MACHINE_IA64 0x200
+#define GRUB_PE32_MACHINE_X86_64 0x8664
+#define GRUB_PE32_MACHINE_ARMTHUMB_MIXED 0x01c2
+#define GRUB_PE32_MACHINE_ARM64 0xAA64
+#define GRUB_PE32_MACHINE_RISCV32 0x5032
+#define GRUB_PE32_MACHINE_RISCV64 0x5064
+
+#define GRUB_PE32_RELOCS_STRIPPED 0x0001
+#define GRUB_PE32_EXECUTABLE_IMAGE 0x0002
+#define GRUB_PE32_LINE_NUMS_STRIPPED 0x0004
+#define GRUB_PE32_LOCAL_SYMS_STRIPPED 0x0008
+#define GRUB_PE32_AGGRESSIVE_WS_TRIM 0x0010
+#define GRUB_PE32_LARGE_ADDRESS_AWARE 0x0020
+#define GRUB_PE32_16BIT_MACHINE 0x0040
+#define GRUB_PE32_BYTES_REVERSED_LO 0x0080
+#define GRUB_PE32_32BIT_MACHINE 0x0100
+#define GRUB_PE32_DEBUG_STRIPPED 0x0200
+#define GRUB_PE32_REMOVABLE_RUN_FROM_SWAP 0x0400
+#define GRUB_PE32_SYSTEM 0x1000
+#define GRUB_PE32_DLL 0x2000
+#define GRUB_PE32_UP_SYSTEM_ONLY 0x4000
+#define GRUB_PE32_BYTES_REVERSED_HI 0x8000
+
+struct grub_pe32_data_directory
+{
+ grub_uint32_t rva;
+ grub_uint32_t size;
+};
+
+struct grub_pe32_optional_header
+{
+ grub_uint16_t magic;
+ grub_uint8_t major_linker_version;
+ grub_uint8_t minor_linker_version;
+ grub_uint32_t code_size;
+ grub_uint32_t data_size;
+ grub_uint32_t bss_size;
+ grub_uint32_t entry_addr;
+ grub_uint32_t code_base;
+
+ grub_uint32_t data_base;
+ grub_uint32_t image_base;
+
+ grub_uint32_t section_alignment;
+ grub_uint32_t file_alignment;
+ grub_uint16_t major_os_version;
+ grub_uint16_t minor_os_version;
+ grub_uint16_t major_image_version;
+ grub_uint16_t minor_image_version;
+ grub_uint16_t major_subsystem_version;
+ grub_uint16_t minor_subsystem_version;
+ grub_uint32_t reserved;
+ grub_uint32_t image_size;
+ grub_uint32_t header_size;
+ grub_uint32_t checksum;
+ grub_uint16_t subsystem;
+ grub_uint16_t dll_characteristics;
+
+ grub_uint32_t stack_reserve_size;
+ grub_uint32_t stack_commit_size;
+ grub_uint32_t heap_reserve_size;
+ grub_uint32_t heap_commit_size;
+
+ grub_uint32_t loader_flags;
+ grub_uint32_t num_data_directories;
+
+ /* Data directories. */
+ struct grub_pe32_data_directory export_table;
+ struct grub_pe32_data_directory import_table;
+ struct grub_pe32_data_directory resource_table;
+ struct grub_pe32_data_directory exception_table;
+ struct grub_pe32_data_directory certificate_table;
+ struct grub_pe32_data_directory base_relocation_table;
+ struct grub_pe32_data_directory debug;
+ struct grub_pe32_data_directory architecture;
+ struct grub_pe32_data_directory global_ptr;
+ struct grub_pe32_data_directory tls_table;
+ struct grub_pe32_data_directory load_config_table;
+ struct grub_pe32_data_directory bound_import;
+ struct grub_pe32_data_directory iat;
+ struct grub_pe32_data_directory delay_import_descriptor;
+ struct grub_pe32_data_directory com_runtime_header;
+ struct grub_pe32_data_directory reserved_entry;
+};
+
+struct grub_pe64_optional_header
+{
+ grub_uint16_t magic;
+ grub_uint8_t major_linker_version;
+ grub_uint8_t minor_linker_version;
+ grub_uint32_t code_size;
+ grub_uint32_t data_size;
+ grub_uint32_t bss_size;
+ grub_uint32_t entry_addr;
+ grub_uint32_t code_base;
+
+ grub_uint64_t image_base;
+
+ grub_uint32_t section_alignment;
+ grub_uint32_t file_alignment;
+ grub_uint16_t major_os_version;
+ grub_uint16_t minor_os_version;
+ grub_uint16_t major_image_version;
+ grub_uint16_t minor_image_version;
+ grub_uint16_t major_subsystem_version;
+ grub_uint16_t minor_subsystem_version;
+ grub_uint32_t reserved;
+ grub_uint32_t image_size;
+ grub_uint32_t header_size;
+ grub_uint32_t checksum;
+ grub_uint16_t subsystem;
+ grub_uint16_t dll_characteristics;
+
+ grub_uint64_t stack_reserve_size;
+ grub_uint64_t stack_commit_size;
+ grub_uint64_t heap_reserve_size;
+ grub_uint64_t heap_commit_size;
+
+ grub_uint32_t loader_flags;
+ grub_uint32_t num_data_directories;
+
+ /* Data directories. */
+ struct grub_pe32_data_directory export_table;
+ struct grub_pe32_data_directory import_table;
+ struct grub_pe32_data_directory resource_table;
+ struct grub_pe32_data_directory exception_table;
+ struct grub_pe32_data_directory certificate_table;
+ struct grub_pe32_data_directory base_relocation_table;
+ struct grub_pe32_data_directory debug;
+ struct grub_pe32_data_directory architecture;
+ struct grub_pe32_data_directory global_ptr;
+ struct grub_pe32_data_directory tls_table;
+ struct grub_pe32_data_directory load_config_table;
+ struct grub_pe32_data_directory bound_import;
+ struct grub_pe32_data_directory iat;
+ struct grub_pe32_data_directory delay_import_descriptor;
+ struct grub_pe32_data_directory com_runtime_header;
+ struct grub_pe32_data_directory reserved_entry;
+};
+
+#define GRUB_PE32_PE32_MAGIC 0x10b
+#define GRUB_PE32_PE64_MAGIC 0x20b
+
+#define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION 10
+
+#define GRUB_PE32_NUM_DATA_DIRECTORIES 16
+
+struct grub_pe32_section_table
+{
+ char name[8];
+ grub_uint32_t virtual_size;
+ grub_uint32_t virtual_address;
+ grub_uint32_t raw_data_size;
+ grub_uint32_t raw_data_offset;
+ grub_uint32_t relocations_offset;
+ grub_uint32_t line_numbers_offset;
+ grub_uint16_t num_relocations;
+ grub_uint16_t num_line_numbers;
+ grub_uint32_t characteristics;
+};
+
+#define GRUB_PE32_SCN_CNT_CODE 0x00000020
+#define GRUB_PE32_SCN_CNT_INITIALIZED_DATA 0x00000040
+#define GRUB_PE32_SCN_MEM_DISCARDABLE 0x02000000
+#define GRUB_PE32_SCN_MEM_EXECUTE 0x20000000
+#define GRUB_PE32_SCN_MEM_READ 0x40000000
+#define GRUB_PE32_SCN_MEM_WRITE 0x80000000
+
+#define GRUB_PE32_SCN_ALIGN_1BYTES 0x00100000
+#define GRUB_PE32_SCN_ALIGN_2BYTES 0x00200000
+#define GRUB_PE32_SCN_ALIGN_4BYTES 0x00300000
+#define GRUB_PE32_SCN_ALIGN_8BYTES 0x00400000
+#define GRUB_PE32_SCN_ALIGN_16BYTES 0x00500000
+#define GRUB_PE32_SCN_ALIGN_32BYTES 0x00600000
+#define GRUB_PE32_SCN_ALIGN_64BYTES 0x00700000
+
+#define GRUB_PE32_SCN_ALIGN_SHIFT 20
+#define GRUB_PE32_SCN_ALIGN_MASK 7
+
+#define GRUB_PE32_SIGNATURE_SIZE 4
+
+struct grub_pe32_header
+{
+ /* This should be filled in with GRUB_PE32_MSDOS_STUB. */
+ grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE];
+
+ /* This is always PE\0\0. */
+ char signature[GRUB_PE32_SIGNATURE_SIZE];
+
+ /* The COFF file header. */
+ struct grub_pe32_coff_header coff_header;
+
+#if GRUB_TARGET_SIZEOF_VOID_P == 8
+ /* The Optional header. */
+ struct grub_pe64_optional_header optional_header;
+#else
+ /* The Optional header. */
+ struct grub_pe32_optional_header optional_header;
+#endif
+};
+
+struct grub_pe32_fixup_block
+{
+ grub_uint32_t page_rva;
+ grub_uint32_t block_size;
+ grub_uint16_t entries[0];
+};
+
+#define GRUB_PE32_FIXUP_ENTRY(type, offset) (((type) << 12) | (offset))
+
+#define GRUB_PE32_REL_BASED_ABSOLUTE 0
+#define GRUB_PE32_REL_BASED_HIGH 1
+#define GRUB_PE32_REL_BASED_LOW 2
+#define GRUB_PE32_REL_BASED_HIGHLOW 3
+#define GRUB_PE32_REL_BASED_HIGHADJ 4
+#define GRUB_PE32_REL_BASED_MIPS_JMPADDR 5
+#define GRUB_PE32_REL_BASED_MIPS_LOW 6
+#define GRUB_PE32_REL_BASED_MIPS_HIGH 4
+#define GRUB_PE32_REL_BASED_MIPS_HIGHER 7
+#define GRUB_PE32_REL_BASED_MIPS_HIGHEST 8
+#define GRUB_PE32_REL_BASED_ARM_MOV32A 5
+#define GRUB_PE32_REL_BASED_RISCV_HI20 5
+#define GRUB_PE32_REL_BASED_SECTION 6
+#define GRUB_PE32_REL_BASED_REL 7
+#define GRUB_PE32_REL_BASED_ARM_MOV32T 7
+#define GRUB_PE32_REL_BASED_RISCV_LOW12I 7
+#define GRUB_PE32_REL_BASED_RISCV_LOW12S 8
+#define GRUB_PE32_REL_BASED_IA64_IMM64 9
+#define GRUB_PE32_REL_BASED_DIR64 10
+#define GRUB_PE32_REL_BASED_HIGH3ADJ 11
+
+struct grub_pe32_symbol
+{
+ union
+ {
+ char short_name[8];
+ grub_uint32_t long_name[2];
+ };
+
+ grub_uint32_t value;
+ grub_uint16_t section;
+ grub_uint16_t type;
+ grub_uint8_t storage_class;
+ grub_uint8_t num_aux;
+} GRUB_PACKED;
+
+#define GRUB_PE32_SYM_CLASS_EXTERNAL 2
+#define GRUB_PE32_SYM_CLASS_STATIC 3
+#define GRUB_PE32_SYM_CLASS_FILE 0x67
+
+#define GRUB_PE32_DT_FUNCTION 0x20
+
+struct grub_pe32_reloc
+{
+ grub_uint32_t offset;
+ grub_uint32_t symtab_index;
+ grub_uint16_t type;
+} GRUB_PACKED;
+
+#define GRUB_PE32_REL_I386_DIR32 0x6
+#define GRUB_PE32_REL_I386_REL32 0x14
+
+#endif /* ! GRUB_EFI_PE32_HEADER */
--- /dev/null
+#ifndef GRUB_MIPS64_ASM_HEADER
+#define GRUB_MIPS64_ASM_HEADER 1
+
+#define GRUB_ASM_T4 $a4
+#define GRUB_ASM_T5 $a5
+#define GRUB_ASM_SZREG 8
+#define GRUB_ASM_REG_S sd
+#define GRUB_ASM_REG_L ld
+
+#endif
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2003,2004,2006,2007,2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_MACHINE_HEADER
+#define GRUB_LOADER_MACHINE_HEADER 1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+
+#endif /* ! GRUB_LOADER_MACHINE_HEADER */
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_LOONGSON_HEADER
+#define GRUB_EFI_LOONGSON_HEADER 1
+
+#include <grub/types.h>
+
+#include <grub/efi/api.h>
+
+#define GRUB_EFI_LOONGSON_SMBIOS_TABLE_GUID \
+ { 0x4660f721, 0x2ec5, 0x416a, \
+ { 0x89, 0x9a, 0x43, 0x18, 0x02, 0x50, 0xa0, 0xc9 } \
+ }
+
+#define GRUB_EFI_LOONGSON_MMAP_MAX 128
+typedef enum
+ {
+ GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW = 1,
+ GRUB_EFI_LOONGSON_SYSTEM_RAM_HIGH,
+ GRUB_EFI_LOONGSON_MEMORY_RESERVED,
+ GRUB_EFI_LOONGSON_PCI_IO,
+ GRUB_EFI_LOONGSON_PCI_MEM,
+ GRUB_EFI_LOONGSON_CFG_REG,
+ GRUB_EFI_LOONGSON_VIDEO_ROM,
+ GRUB_EFI_LOONGSON_ADAPTER_ROM,
+ GRUB_EFI_LOONGSON_ACPI_TABLE,
+ GRUB_EFI_LOONGSON_SMBIOS_TABLE,
+ GRUB_EFI_LOONGSON_UMA_VIDEO_RAM,
+ GRUB_EFI_LOONGSON_VUMA_VIDEO_RAM,
+ GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW_DMA,
+ GRUB_EFI_LOONGSON_SYSTEM_RAM_HIGH_DMA,
+ GRUB_EFI_LOONGSON_ACPI_NVS,
+ GRUB_EFI_LOONGSON_MAX_MEMORY_TYPE
+ }
+grub_efi_loongson_memory_type;
+
+typedef struct
+{
+ grub_uint16_t vers; /* version */
+ grub_uint32_t nr_map; /* number of memory_maps */
+ grub_uint32_t mem_freq; /* memory frequence */
+ struct mem_map {
+ grub_uint32_t node_id; /* node_id which memory attached to */
+ grub_uint32_t mem_type; /* system memory, pci memory, pci io, etc. */
+ grub_uint64_t mem_start; /* memory map start address */
+ grub_uint32_t mem_size; /* each memory_map size, not the total size */
+ } map[GRUB_EFI_LOONGSON_MMAP_MAX];
+} GRUB_PACKED
+grub_efi_loongson_memory_map;
+
+/*
+ * Capability and feature descriptor structure for MIPS CPU
+ */
+typedef struct
+{
+ grub_uint16_t vers; /* version */
+ grub_uint32_t processor_id; /* PRID, e.g. 6305, 6306 */
+ grub_uint32_t cputype; /* Loongson_3A/3B, etc. */
+ grub_uint32_t total_node; /* num of total numa nodes */
+ grub_uint16_t cpu_startup_core_id; /* Boot core id */
+ grub_uint16_t reserved_cores_mask;
+ grub_uint32_t cpu_clock_freq; /* cpu_clock */
+ grub_uint32_t nr_cpus;
+} GRUB_PACKED
+grub_efi_loongson_cpu_info;
+
+#define GRUB_EFI_LOONGSON_MAX_UARTS 64
+
+typedef struct
+{
+ grub_uint32_t iotype; /* see include/linux/serial_core.h */
+ grub_uint32_t uartclk;
+ grub_uint32_t int_offset;
+ grub_uint64_t uart_base;
+} GRUB_PACKED
+grub_efi_loongson_uart_device;
+
+#define GRUB_EFI_LOONGSON_MAX_SENSORS 64
+
+typedef struct
+{
+ char name[32]; /* a formal name */
+ char label[64]; /* a flexible description */
+ grub_uint32_t type; /* SENSOR_* */
+ grub_uint32_t id; /* instance id of a sensor-class */
+ grub_uint32_t fan_policy;
+ grub_uint32_t fan_percent; /* only for constant speed policy */
+ grub_uint64_t base_addr; /* base address of device registers */
+} GRUB_PACKED
+grub_efi_loongson_sensor_device;
+
+typedef struct
+{
+ grub_uint16_t vers; /* version */
+ grub_uint32_t ccnuma_smp; /* 0: no numa; 1: has numa */
+ grub_uint32_t sing_double_channel; /* 1:single; 2:double */
+ grub_uint32_t nr_uarts;
+ grub_efi_loongson_uart_device uarts[GRUB_EFI_LOONGSON_MAX_UARTS];
+ grub_uint32_t nr_sensors;
+ grub_efi_loongson_sensor_device sensors[GRUB_EFI_LOONGSON_MAX_SENSORS];
+ char has_ec;
+ char ec_name[32];
+ grub_uint64_t ec_base_addr;
+ char has_tcm;
+ char tcm_name[32];
+ grub_uint64_t tcm_base_addr;
+ grub_uint64_t workarounds; /* see workarounds.h */
+} GRUB_PACKED
+grub_efi_loongson_system_info;
+
+typedef struct
+{
+ grub_uint16_t vers;
+ grub_uint16_t size;
+ grub_uint16_t rtr_bus;
+ grub_uint16_t rtr_devfn;
+ grub_uint32_t vendor;
+ grub_uint32_t device;
+ grub_uint32_t PIC_type; /* conform use HT or PCI to route to CPU-PIC */
+ grub_uint64_t ht_int_bit; /* 3A: 1<<24; 3B: 1<<16 */
+ grub_uint64_t ht_enable; /* irqs used in this PIC */
+ grub_uint32_t node_id; /* node id: 0x0-0; 0x1-1; 0x10-2; 0x11-3 */
+ grub_uint64_t pci_mem_start_addr;
+ grub_uint64_t pci_mem_end_addr;
+ grub_uint64_t pci_io_start_addr;
+ grub_uint64_t pci_io_end_addr;
+ grub_uint64_t pci_config_addr;
+ grub_uint32_t dma_mask_bits;
+} GRUB_PACKED
+grub_efi_loongson_irq_src_routing_table;
+
+typedef struct
+{
+ grub_uint16_t vers; /* version */
+ grub_uint16_t size;
+ grub_uint8_t flag;
+ char description[64];
+} GRUB_PACKED
+grub_efi_loongson_interface_info;
+
+#define GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER 128
+
+typedef struct
+{
+ grub_uint64_t start; /* resource start address */
+ grub_uint64_t end; /* resource end address */
+ char name[64];
+ grub_uint32_t flags;
+}
+grub_efi_loongson_resource;
+
+/* arch specific additions */
+typedef struct
+{
+}
+grub_efi_loongson_archdev_data;
+
+typedef struct
+{
+ char name[64]; /* hold the device name */
+ grub_uint32_t num_resources; /* number of device_resource */
+ /* for each device's resource */
+ grub_efi_loongson_resource resource[GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER];
+ /* arch specific additions */
+ grub_efi_loongson_archdev_data archdata;
+}
+grub_efi_loongson_board_devices;
+
+typedef struct
+{
+ grub_uint16_t vers; /* version */
+ char special_name[64]; /* special_atribute_name */
+ grub_uint32_t loongson_special_type; /* type of special device */
+ /* for each device's resource */
+ grub_efi_loongson_resource resource[GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER];
+}
+grub_efi_loongson_special_attribute;
+
+typedef struct
+{
+ grub_uint64_t memory_offset; /* efi_loongson_memory_map struct offset */
+ grub_uint64_t cpu_offset; /* efi_loongson_cpuinfo struct offset */
+ grub_uint64_t system_offset; /* efi_loongson_system_info struct offset */
+ grub_uint64_t irq_offset; /* efi_loongson_irq_src_routing_table struct offset */
+ grub_uint64_t interface_offset; /* interface_info struct offset */
+ grub_uint64_t special_offset; /* efi_loongson_special_attribute struct offset */
+ grub_uint64_t boarddev_table_offset; /* efi_loongson_board_devices offset */
+}
+grub_efi_loongson_params;
+
+typedef struct
+{
+ grub_uint16_t vers; /* version */
+ grub_uint64_t vga_bios; /* vga_bios address */
+ grub_efi_loongson_params lp;
+}
+grub_efi_loongson_smbios_table;
+
+typedef struct
+{
+ grub_uint64_t reset_cold;
+ grub_uint64_t reset_warm;
+ grub_uint64_t reset_type;
+ grub_uint64_t shutdown;
+ grub_uint64_t do_suspend; /* NULL if not support */
+}
+grub_efi_loongson_reset_system;
+
+typedef struct
+{
+ grub_uint64_t mps; /* MPS table */
+ grub_uint64_t acpi; /* ACPI table (IA64 ext 0.71) */
+ grub_uint64_t acpi20; /* ACPI table (ACPI 2.0) */
+ grub_efi_loongson_smbios_table smbios; /* SM BIOS table */
+ grub_uint64_t sal_systab; /* SAL system table */
+ grub_uint64_t boot_info; /* boot info table */
+}
+grub_efi_loongson;
+
+typedef struct
+{
+ grub_efi_loongson efi;
+ grub_efi_loongson_reset_system reset_system;
+}
+grub_efi_loongson_boot_params;
+
+extern grub_uint64_t grub_efi_loongson_reset_system_addr;
+
+extern void grub_efi_loongson_reset_cold (void);
+extern void grub_efi_loongson_reset_warm (void);
+extern void grub_efi_loongson_reset_shutdown (void);
+extern void grub_efi_loongson_reset_suspend (void);
+
+void grub_efi_loongson_init (void);
+void grub_efi_loongson_fini (void);
+void grub_efi_loongson_alloc_boot_params (void);
+void grub_efi_loongson_free_boot_params (void);
+void * grub_efi_loongson_get_smbios_table (void);
+
+int EXPORT_FUNC(grub_efi_is_loongson) (void);
+
+grub_uint8_t
+EXPORT_FUNC(grub_efi_loongson_calculatesum8) (const grub_uint8_t *Buffer, grub_efi_uintn_t Length);
+
+grub_uint8_t
+EXPORT_FUNC(grub_efi_loongson_grub_calculatechecksum8) (const grub_uint8_t *Buffer, grub_efi_uintn_t Length);
+
+
+void *
+EXPORT_FUNC(grub_efi_loongson_get_boot_params) (void);
+
+typedef struct _extention_list_hdr{
+ grub_uint64_t signature;
+ grub_uint32_t length;
+ grub_uint8_t revision;
+ grub_uint8_t checksum;
+ struct _extention_list_hdr *next;
+}GRUB_PACKED
+ext_list;
+
+typedef struct bootparamsinterface {
+ grub_uint64_t signature; //{'B', 'P', 'I', '_', '0', '_', '1'}
+ grub_efi_system_table_t *systemtable;
+ ext_list *extlist;
+}GRUB_PACKED
+bootparamsinterface;
+
+typedef struct {
+ ext_list header; // {'M', 'E', 'M'}
+ grub_uint8_t mapcount;
+ struct GRUB_PACKED memmap {
+ grub_uint32_t memtype;
+ grub_uint64_t memstart;
+ grub_uint64_t memsize;
+ } map[GRUB_EFI_LOONGSON_MMAP_MAX];
+}GRUB_PACKED
+mem_map;
+
+typedef struct {
+ ext_list header; // {VBIOS}
+ grub_uint64_t vbiosaddr;
+}GRUB_PACKED
+vbios;
+
+grub_uint32_t
+EXPORT_FUNC (grub_efi_loongson_memmap_sort) (struct memmap array[], grub_uint32_t length, mem_map * bpmem, grub_uint32_t index, grub_uint32_t memtype);
+#endif /* ! GRUB_EFI_LOONGSON_HEADER */
--- /dev/null
+#ifndef GRUB_MEMORY_CPU_HEADER
+#include <grub/efi/memory.h>
+
+//#define GRUB_EFI_MAX_USABLE_ADDRESS 0x980000000fffffffUL
+#define GRUB_EFI_MAX_USABLE_ADDRESS 0x98000000ffffffffUL
+
+#endif /* ! GRUB_MEMORY_CPU_HEADER */
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009,2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_IO_H
+#define GRUB_IO_H 1
+
+#include <grub/types.h>
+
+typedef grub_addr_t grub_port_t;
+
+static __inline unsigned char
+grub_inb (grub_port_t port)
+{
+ return *(volatile grub_uint8_t *) port;
+}
+
+static __inline unsigned short int
+grub_inw (grub_port_t port)
+{
+ return *(volatile grub_uint16_t *) port;
+}
+
+static __inline unsigned int
+grub_inl (grub_port_t port)
+{
+ return *(volatile grub_uint32_t *) port;
+}
+
+static __inline void
+grub_outb (unsigned char value, grub_port_t port)
+{
+ *(volatile grub_uint8_t *) port = value;
+}
+
+static __inline void
+grub_outw (unsigned short int value, grub_port_t port)
+{
+ *(volatile grub_uint16_t *) port = value;
+}
+
+static __inline void
+grub_outl (unsigned int value, grub_port_t port)
+{
+ *(volatile grub_uint32_t *) port = value;
+}
+
+#endif /* _SYS_IO_H */
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2005,2006,2007,2008,2009,2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_CPU_HEADER
+#define GRUB_KERNEL_CPU_HEADER 1
+
+#include <grub/symbol.h>
+
+#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MEMORY_CPU_HEADER
+#define GRUB_MEMORY_CPU_HEADER 1
+
+#ifndef ASM_FILE
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/types.h>
+#endif
+
+#ifndef ASM_FILE
+
+typedef grub_addr_t grub_phys_addr_t;
+
+static inline grub_phys_addr_t
+grub_vtop (void *a)
+{
+ if (-1 == ((grub_int64_t) a >> 32))
+ return ((grub_phys_addr_t) a) & 0x1fffffffUL;
+ return ((grub_phys_addr_t) a) & 0xffffffffffffUL;
+}
+
+static inline void *
+grub_map_memory (grub_phys_addr_t a, grub_size_t size)
+{
+ if ((a + size) < 0x20000000UL)
+ return (void *) (a | 0xffffffff80000000UL);
+// return (void *) (a | 0x9800000000000000UL);
+ return (void *) ((a&0x8fffffff) | 0xffffffff00000000UL);
+}
+
+static inline void
+grub_unmap_memory (void *a __attribute__ ((unused)),
+ grub_size_t size __attribute__ ((unused)))
+{
+}
+
+#endif
+
+#endif
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2010,2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_REGISTERS_CPU_HEADER
+#define GRUB_REGISTERS_CPU_HEADER 1
+
+#ifdef ASM_FILE
+#define GRUB_CPU_REGISTER_WRAP(x) x
+#else
+#define GRUB_CPU_REGISTER_WRAP(x) #x
+#endif
+
+#define GRUB_CPU_MIPS_COP0_TIMER_COUNT GRUB_CPU_REGISTER_WRAP($9)
+
+#endif
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_RELOCATOR_CPU_HEADER
+#define GRUB_RELOCATOR_CPU_HEADER 1
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/relocator.h>
+
+struct grub_relocator64_state
+{
+ /* gpr[0] is ignored since it's hardwired to 0. */
+ grub_uint64_t gpr[32];
+ /* Register holding target $pc. */
+ int jumpreg;
+};
+
+grub_err_t
+grub_relocator64_boot (struct grub_relocator *rel,
+ struct grub_relocator64_state state);
+
+#endif /* ! GRUB_RELOCATOR_CPU_HEADER */
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2004,2006,2007,2009,2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SETJMP_CPU_HEADER
+#define GRUB_SETJMP_CPU_HEADER 1
+
+typedef grub_uint64_t grub_jmp_buf[12];
+
+int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE;
+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
+
+#endif /* ! GRUB_SETJMP_CPU_HEADER */
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2003,2004,2005,2007,2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_CPU_TIME_HEADER
+#define KERNEL_CPU_TIME_HEADER 1
+
+#ifndef GRUB_UTIL
+
+#define GRUB_TICKS_PER_SECOND (grub_arch_cpuclock / 2)
+
+void grub_timer_init (grub_uint32_t cpuclock);
+
+/* Return the real time in ticks. */
+grub_uint64_t grub_get_rtc (void);
+
+extern grub_uint32_t grub_arch_cpuclock;
+#endif
+
+static inline void
+grub_cpu_idle(void)
+{
+}
+
+#endif
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2006,2007,2009,2017 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TYPES_CPU_HEADER
+#define GRUB_TYPES_CPU_HEADER 1
+
+/* The size of void *. */
+#define GRUB_TARGET_SIZEOF_VOID_P 8
+
+/* The size of long. */
+#define GRUB_TARGET_SIZEOF_LONG 8
+
+#ifdef GRUB_CPU_MIPS64EL
+/* mips64EL is little-endian. */
+#undef GRUB_TARGET_WORDS_BIGENDIAN
+#elif defined (GRUB_CPU_MIPS64)
+/* mips64 is big-endian. */
+#define GRUB_TARGET_WORDS_BIGENDIAN
+#elif !defined (GRUB_SYMBOL_GENERATOR)
+#error Neither GRUB_CPU_MIPS64 nor GRUB_CPU_MIPS64EL is defined
+#endif
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */
--- /dev/null
+/* misc.h - prototypes for misc functions */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MISC_HEADER
+#define GRUB_MISC_HEADER 1
+
+#include <stdarg.h>
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/i18n.h>
+#include <grub/compiler.h>
+
+#define ALIGN_UP(addr, align) \
+ ((addr + (typeof (addr)) align - 1) & ~((typeof (addr)) align - 1))
+#define ALIGN_UP_OVERHEAD(addr, align) ((-(addr)) & ((typeof (addr)) (align) - 1))
+#define ALIGN_DOWN(addr, align) \
+ ((addr) & ~((typeof (addr)) align - 1))
+#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0]))
+#define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; }
+
+#define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, __VA_ARGS__)
+
+void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n);
+char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src);
+
+static inline char *
+grub_strncpy (char *dest, const char *src, int c)
+{
+ char *p = dest;
+
+ while ((*p++ = *src++) != '\0' && --c)
+ ;
+
+ return dest;
+}
+
+static inline char *
+grub_stpcpy (char *dest, const char *src)
+{
+ char *d = dest;
+ const char *s = src;
+
+ do
+ *d++ = *s;
+ while (*s++ != '\0');
+
+ return d - 1;
+}
+
+/* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */
+static inline void *
+grub_memcpy (void *dest, const void *src, grub_size_t n)
+{
+ return grub_memmove (dest, src, n);
+}
+
+#if defined(__x86_64__) && !defined (GRUB_UTIL)
+#if defined (__MINGW32__) || defined (__CYGWIN__) || defined (__MINGW64__)
+#define GRUB_ASM_ATTR __attribute__ ((sysv_abi))
+#else
+#define GRUB_ASM_ATTR
+#endif
+#endif
+
+int EXPORT_FUNC(grub_memcmp) (const void *s1, const void *s2, grub_size_t n);
+int EXPORT_FUNC(grub_strcmp) (const char *s1, const char *s2);
+int EXPORT_FUNC(grub_strncmp) (const char *s1, const char *s2, grub_size_t n);
+
+char *EXPORT_FUNC(grub_strchr) (const char *s, int c);
+char *EXPORT_FUNC(grub_strrchr) (const char *s, int c);
+int EXPORT_FUNC(grub_strword) (const char *s, const char *w);
+
+/* Copied from gnulib.
+ Written by Bruno Haible <bruno@clisp.org>, 2005. */
+static inline char *
+grub_strstr (const char *haystack, const char *needle)
+{
+ /* Be careful not to look at the entire extent of haystack or needle
+ until needed. This is useful because of these two cases:
+ - haystack may be very long, and a match of needle found early,
+ - needle may be very long, and not even a short initial segment of
+ needle may be found in haystack. */
+ if (*needle != '\0')
+ {
+ /* Speed up the following searches of needle by caching its first
+ character. */
+ char b = *needle++;
+
+ for (;; haystack++)
+ {
+ if (*haystack == '\0')
+ /* No match. */
+ return 0;
+ if (*haystack == b)
+ /* The first character matches. */
+ {
+ const char *rhaystack = haystack + 1;
+ const char *rneedle = needle;
+
+ for (;; rhaystack++, rneedle++)
+ {
+ if (*rneedle == '\0')
+ /* Found a match. */
+ return (char *) haystack;
+ if (*rhaystack == '\0')
+ /* No match. */
+ return 0;
+ if (*rhaystack != *rneedle)
+ /* Nothing in this round. */
+ break;
+ }
+ }
+ }
+ }
+ else
+ return (char *) haystack;
+}
+
+int EXPORT_FUNC(grub_isspace) (int c);
+
+static inline int
+grub_isprint (int c)
+{
+ return (c >= ' ' && c <= '~');
+}
+
+static inline int
+grub_iscntrl (int c)
+{
+ return (c >= 0x00 && c <= 0x1F) || c == 0x7F;
+}
+
+static inline int
+grub_isalpha (int c)
+{
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+}
+
+static inline int
+grub_islower (int c)
+{
+ return (c >= 'a' && c <= 'z');
+}
+
+static inline int
+grub_isupper (int c)
+{
+ return (c >= 'A' && c <= 'Z');
+}
+
+static inline int
+grub_isgraph (int c)
+{
+ return (c >= '!' && c <= '~');
+}
+
+static inline int
+grub_isdigit (int c)
+{
+ return (c >= '0' && c <= '9');
+}
+
+static inline int
+grub_isxdigit (int c)
+{
+ return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
+}
+
+static inline int
+grub_isalnum (int c)
+{
+ return grub_isalpha (c) || grub_isdigit (c);
+}
+
+static inline int
+grub_tolower (int c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return c - 'A' + 'a';
+
+ return c;
+}
+
+static inline int
+grub_toupper (int c)
+{
+ if (c >= 'a' && c <= 'z')
+ return c - 'a' + 'A';
+
+ return c;
+}
+
+static inline int
+grub_strcasecmp (const char *s1, const char *s2)
+{
+ while (*s1 && *s2)
+ {
+ if (grub_tolower ((grub_uint8_t) *s1)
+ != grub_tolower ((grub_uint8_t) *s2))
+ break;
+
+ s1++;
+ s2++;
+ }
+
+ return (int) grub_tolower ((grub_uint8_t) *s1)
+ - (int) grub_tolower ((grub_uint8_t) *s2);
+}
+
+static inline int
+grub_strncasecmp (const char *s1, const char *s2, grub_size_t n)
+{
+ if (n == 0)
+ return 0;
+
+ while (*s1 && *s2 && --n)
+ {
+ if (grub_tolower (*s1) != grub_tolower (*s2))
+ break;
+
+ s1++;
+ s2++;
+ }
+
+ return (int) grub_tolower ((grub_uint8_t) *s1)
+ - (int) grub_tolower ((grub_uint8_t) *s2);
+}
+
+unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int base);
+unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, char **end, int base);
+
+static inline long
+grub_strtol (const char *str, char **end, int base)
+{
+ int negative = 0;
+ unsigned long long magnitude;
+
+ while (*str && grub_isspace (*str))
+ str++;
+
+ if (*str == '-')
+ {
+ negative = 1;
+ str++;
+ }
+
+ magnitude = grub_strtoull (str, end, base);
+ if (negative)
+ {
+ if (magnitude > (unsigned long) GRUB_LONG_MAX + 1)
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
+ return GRUB_LONG_MIN;
+ }
+ return -((long) magnitude);
+ }
+ else
+ {
+ if (magnitude > GRUB_LONG_MAX)
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
+ return GRUB_LONG_MAX;
+ }
+ return (long) magnitude;
+ }
+}
+
+char *EXPORT_FUNC(grub_strdup) (const char *s) WARN_UNUSED_RESULT;
+char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n) WARN_UNUSED_RESULT;
+void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n);
+grub_size_t EXPORT_FUNC(grub_strlen) (const char *s) WARN_UNUSED_RESULT;
+int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2)));
+int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2)));
+
+/* Replace all `ch' characters of `input' with `with' and copy the
+ result into `output'; return EOS address of `output'. */
+static inline char *
+grub_strchrsub (char *output, const char *input, char ch, const char *with)
+{
+ while (*input)
+ {
+ if (*input == ch)
+ {
+ grub_strcpy (output, with);
+ output += grub_strlen (with);
+ input++;
+ continue;
+ }
+ *output++ = *input++;
+ }
+ *output = '\0';
+ return output;
+}
+
+extern void (*EXPORT_VAR (grub_xputs)) (const char *str);
+
+static inline int
+grub_puts (const char *s)
+{
+ const char nl[2] = "\n";
+ grub_xputs (s);
+ grub_xputs (nl);
+
+ return 1; /* Cannot fail. */
+}
+
+int EXPORT_FUNC(grub_puts_) (const char *s);
+void EXPORT_FUNC(grub_real_dprintf) (const char *file,
+ const int line,
+ const char *condition,
+ const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 4, 5)));
+int EXPORT_FUNC(grub_vprintf) (const char *fmt, va_list args);
+int EXPORT_FUNC(grub_snprintf) (char *str, grub_size_t n, const char *fmt, ...)
+ __attribute__ ((format (GNU_PRINTF, 3, 4)));
+int EXPORT_FUNC(grub_vsnprintf) (char *str, grub_size_t n, const char *fmt,
+ va_list args);
+char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...)
+ __attribute__ ((format (GNU_PRINTF, 1, 2))) WARN_UNUSED_RESULT;
+char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args) WARN_UNUSED_RESULT;
+void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn));
+grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
+ grub_uint64_t d,
+ grub_uint64_t *r);
+
+/* Must match softdiv group in gentpl.py. */
+#if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \
+ (defined(__riscv) && (__riscv_xlen == 32)))
+#define GRUB_DIVISION_IN_SOFTWARE 1
+#else
+#define GRUB_DIVISION_IN_SOFTWARE 0
+#endif
+
+/* Some division functions need to be in kernel if compiler generates calls
+ to them. Otherwise we still need them for consistent tests but they go
+ into a separate module. */
+#if GRUB_DIVISION_IN_SOFTWARE
+#define EXPORT_FUNC_IF_SOFTDIV EXPORT_FUNC
+#else
+#define EXPORT_FUNC_IF_SOFTDIV(x) x
+#endif
+
+grub_int64_t
+EXPORT_FUNC_IF_SOFTDIV(grub_divmod64s) (grub_int64_t n,
+ grub_int64_t d,
+ grub_int64_t *r);
+
+grub_uint32_t
+EXPORT_FUNC_IF_SOFTDIV (grub_divmod32) (grub_uint32_t n,
+ grub_uint32_t d,
+ grub_uint32_t *r);
+
+grub_int32_t
+EXPORT_FUNC_IF_SOFTDIV (grub_divmod32s) (grub_int32_t n,
+ grub_int32_t d,
+ grub_int32_t *r);
+
+/* Inline functions. */
+
+static inline char *
+grub_memchr (const void *p, int c, grub_size_t len)
+{
+ const char *s = (const char *) p;
+ const char *e = s + len;
+
+ for (; s < e; s++)
+ if (*s == c)
+ return (char *) s;
+
+ return 0;
+}
+
+
+static inline unsigned int
+grub_abs (int x)
+{
+ if (x < 0)
+ return (unsigned int) (-x);
+ else
+ return (unsigned int) x;
+}
+
+/* Reboot the machine. */
+#if defined (GRUB_MACHINE_EMU) || defined (GRUB_MACHINE_QEMU_MIPS) || \
+ defined (GRUB_MACHINE_EFI)
+void EXPORT_FUNC(grub_reboot) (void) __attribute__ ((noreturn));
+#else
+void grub_reboot (void) __attribute__ ((noreturn));
+#endif
+
+#if defined (__clang__) && !defined (GRUB_UTIL)
+void __attribute__ ((noreturn)) EXPORT_FUNC (abort) (void);
+#endif
+
+#ifdef GRUB_MACHINE_PCBIOS
+/* Halt the system, using APM if possible. If NO_APM is true, don't
+ * use APM even if it is available. */
+void grub_halt (int no_apm) __attribute__ ((noreturn));
+#elif (defined (__mips__) && (_MIPS_SIM != _ABI64)) && !defined (GRUB_MACHINE_EMU)
+void EXPORT_FUNC (grub_halt) (void) __attribute__ ((noreturn));
+#else
+void grub_halt (void) __attribute__ ((noreturn));
+#endif
+
+#ifdef GRUB_MACHINE_EMU
+/* Flag to check if module loading is available. */
+extern const int EXPORT_VAR(grub_no_modules);
+#else
+#define grub_no_modules 0
+#endif
+
+static inline void
+grub_error_save (struct grub_error_saved *save)
+{
+ grub_memcpy (save->errmsg, grub_errmsg, sizeof (save->errmsg));
+ save->grub_errno = grub_errno;
+ grub_errno = GRUB_ERR_NONE;
+}
+
+static inline void
+grub_error_load (const struct grub_error_saved *save)
+{
+ grub_memcpy (grub_errmsg, save->errmsg, sizeof (grub_errmsg));
+ grub_errno = save->grub_errno;
+}
+
+#if BOOT_TIME_STATS
+struct grub_boot_time
+{
+ struct grub_boot_time *next;
+ grub_uint64_t tp;
+ const char *file;
+ int line;
+ char *msg;
+};
+
+extern struct grub_boot_time *EXPORT_VAR(grub_boot_time_head);
+
+void EXPORT_FUNC(grub_real_boot_time) (const char *file,
+ const int line,
+ const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 3, 4)));
+#define grub_boot_time(...) grub_real_boot_time(GRUB_FILE, __LINE__, __VA_ARGS__)
+#else
+#define grub_boot_time(...)
+#endif
+
+#define grub_max(a, b) (((a) > (b)) ? (a) : (b))
+#define grub_min(a, b) (((a) < (b)) ? (a) : (b))
+
+#endif /* ! GRUB_MISC_HEADER */
--- /dev/null
+/* serial.h - serial device interface */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SERIAL_HEADER
+#define GRUB_SERIAL_HEADER 1
+
+#include <grub/types.h>
+#if (defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__)
+#include <grub/cpu/io.h>
+#endif
+#include <grub/usb.h>
+#include <grub/list.h>
+#include <grub/term.h>
+#ifdef GRUB_MACHINE_IEEE1275
+#include <grub/ieee1275/ieee1275.h>
+#endif
+#ifdef GRUB_MACHINE_ARC
+#include <grub/arc/arc.h>
+#endif
+
+struct grub_serial_port;
+struct grub_serial_config;
+
+struct grub_serial_driver
+{
+ grub_err_t (*configure) (struct grub_serial_port *port,
+ struct grub_serial_config *config);
+ int (*fetch) (struct grub_serial_port *port);
+ void (*put) (struct grub_serial_port *port, const int c);
+ void (*fini) (struct grub_serial_port *port);
+};
+
+/* The type of parity. */
+typedef enum
+ {
+ GRUB_SERIAL_PARITY_NONE,
+ GRUB_SERIAL_PARITY_ODD,
+ GRUB_SERIAL_PARITY_EVEN,
+ } grub_serial_parity_t;
+
+typedef enum
+ {
+ GRUB_SERIAL_STOP_BITS_1,
+ GRUB_SERIAL_STOP_BITS_1_5,
+ GRUB_SERIAL_STOP_BITS_2,
+ } grub_serial_stop_bits_t;
+
+struct grub_serial_config
+{
+ unsigned speed;
+ int word_len;
+ grub_serial_parity_t parity;
+ grub_serial_stop_bits_t stop_bits;
+ grub_uint64_t base_clock;
+ int rtscts;
+};
+
+struct grub_serial_port
+{
+ struct grub_serial_port *next;
+ struct grub_serial_port **prev;
+ char *name;
+ struct grub_serial_driver *driver;
+ struct grub_serial_config config;
+ int configured;
+ int broken;
+
+ /* This should be void *data but since serial is useful as an early console
+ when malloc isn't available it's a union.
+ */
+ union
+ {
+#if (defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__)
+ grub_port_t port;
+#endif
+ struct
+ {
+ grub_usb_device_t usbdev;
+ int configno;
+ int interfno;
+ char buf[64];
+ int bufstart, bufend;
+ struct grub_usb_desc_endp *in_endp;
+ struct grub_usb_desc_endp *out_endp;
+ };
+ struct grub_escc_descriptor *escc_desc;
+#ifdef GRUB_MACHINE_IEEE1275
+ struct
+ {
+ grub_ieee1275_ihandle_t handle;
+ struct ofserial_hash_ent *elem;
+ };
+#endif
+#ifdef GRUB_MACHINE_EFI
+ struct grub_efi_serial_io_interface *interface;
+#endif
+#ifdef GRUB_MACHINE_ARC
+ struct
+ {
+ grub_arc_fileno_t handle;
+ int handle_valid;
+ };
+#endif
+ };
+ grub_term_output_t term_out;
+ grub_term_input_t term_in;
+};
+
+grub_err_t EXPORT_FUNC(grub_serial_register) (struct grub_serial_port *port);
+
+void EXPORT_FUNC(grub_serial_unregister) (struct grub_serial_port *port);
+
+ /* Convenience functions to perform primitive operations on a port. */
+static inline grub_err_t
+grub_serial_port_configure (struct grub_serial_port *port,
+ struct grub_serial_config *config)
+{
+ return port->driver->configure (port, config);
+}
+
+static inline int
+grub_serial_port_fetch (struct grub_serial_port *port)
+{
+ return port->driver->fetch (port);
+}
+
+static inline void
+grub_serial_port_put (struct grub_serial_port *port, const int c)
+{
+ port->driver->put (port, c);
+}
+
+static inline void
+grub_serial_port_fini (struct grub_serial_port *port)
+{
+ port->driver->fini (port);
+}
+
+ /* Set default settings. */
+static inline grub_err_t
+grub_serial_config_defaults (struct grub_serial_port *port)
+{
+ struct grub_serial_config config =
+ {
+#ifdef GRUB_MACHINE_MIPS_LOONGSON
+ .speed = 115200,
+ /* On Loongson machines serial port has only 3 wires. */
+ .rtscts = 0,
+#else
+ .speed = 9600,
+ .rtscts = 1,
+#endif
+ .word_len = 8,
+ .parity = GRUB_SERIAL_PARITY_NONE,
+ .stop_bits = GRUB_SERIAL_STOP_BITS_1,
+ .base_clock = 0
+ };
+
+ return port->driver->configure (port, &config);
+}
+
+#if (defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__)
+void grub_ns8250_init (void);
+char *grub_serial_ns8250_add_port (grub_port_t port);
+#endif
+#ifdef GRUB_MACHINE_IEEE1275
+void grub_ofserial_init (void);
+#endif
+#ifdef GRUB_MACHINE_EFI
+void
+grub_efiserial_init (void);
+#endif
+#ifdef GRUB_MACHINE_ARC
+void
+grub_arcserial_init (void);
+const char *
+grub_arcserial_add_port (const char *path);
+#endif
+
+struct grub_serial_port *grub_serial_find (const char *name);
+extern struct grub_serial_driver grub_ns8250_driver;
+void EXPORT_FUNC(grub_serial_unregister_driver) (struct grub_serial_driver *driver);
+
+#ifndef GRUB_MACHINE_EMU
+extern void grub_serial_init (void);
+extern void grub_serial_fini (void);
+#endif
+
+#endif
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_UTIL_INSTALL_HEADER
+#define GRUB_UTIL_INSTALL_HEADER 1
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/emu/hostfile.h>
+
+#define GRUB_INSTALL_OPTIONS \
+ { "modules", GRUB_INSTALL_OPTIONS_MODULES, N_("MODULES"), \
+ 0, N_("pre-load specified modules MODULES"), 1 }, \
+ { "dtb", GRUB_INSTALL_OPTIONS_DTB, N_("FILE"), \
+ 0, N_("embed a specific DTB"), 1 }, \
+ { "install-modules", GRUB_INSTALL_OPTIONS_INSTALL_MODULES, \
+ N_("MODULES"), 0, \
+ N_("install only MODULES and their dependencies [default=all]"), 1 }, \
+ { "themes", GRUB_INSTALL_OPTIONS_INSTALL_THEMES, N_("THEMES"), \
+ 0, N_("install THEMES [default=%s]"), 1 }, \
+ { "fonts", GRUB_INSTALL_OPTIONS_INSTALL_FONTS, N_("FONTS"), \
+ 0, N_("install FONTS [default=%s]"), 1 }, \
+ { "locales", GRUB_INSTALL_OPTIONS_INSTALL_LOCALES, N_("LOCALES"),\
+ 0, N_("install only LOCALES [default=all]"), 1 }, \
+ { "compress", GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS, \
+ "no|xz|gz|lzo", 0, \
+ N_("compress GRUB files [optional]"), 1 }, \
+ {"core-compress", GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS, \
+ "xz|none|auto", \
+ 0, N_("choose the compression to use for core image"), 2}, \
+ /* TRANSLATORS: platform here isn't identifier. It can be translated. */ \
+ { "directory", 'd', N_("DIR"), 0, \
+ N_("use images and modules under DIR [default=%s/<platform>]"), 1 }, \
+ { "override-directory", GRUB_INSTALL_OPTIONS_DIRECTORY2, \
+ N_("DIR"), OPTION_HIDDEN, \
+ N_("use images and modules under DIR [default=%s/<platform>]"), 1 }, \
+ { "locale-directory", GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY, \
+ N_("DIR"), 0, \
+ N_("use translations under DIR [default=%s]"), 1 }, \
+ { "themes-directory", GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY, \
+ N_("DIR"), OPTION_HIDDEN, \
+ N_("use themes under DIR [default=%s]"), 1 }, \
+ { "grub-mkimage", GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE, \
+ "FILE", OPTION_HIDDEN, 0, 1 }, \
+ /* TRANSLATORS: "embed" is a verb (command description). "*/ \
+ { "pubkey", 'k', N_("FILE"), 0, \
+ N_("embed FILE as public key for signature checking"), 0}, \
+ { "verbose", 'v', 0, 0, \
+ N_("print verbose messages."), 1 }
+
+int
+grub_install_parse (int key, char *arg);
+
+void
+grub_install_push_module (const char *val);
+
+void
+grub_install_pop_module (void);
+
+char *
+grub_install_help_filter (int key, const char *text,
+ void *input __attribute__ ((unused)));
+
+enum grub_install_plat
+ {
+ GRUB_INSTALL_PLATFORM_I386_PC,
+ GRUB_INSTALL_PLATFORM_I386_EFI,
+ GRUB_INSTALL_PLATFORM_I386_QEMU,
+ GRUB_INSTALL_PLATFORM_I386_COREBOOT,
+ GRUB_INSTALL_PLATFORM_I386_MULTIBOOT,
+ GRUB_INSTALL_PLATFORM_I386_IEEE1275,
+ GRUB_INSTALL_PLATFORM_X86_64_EFI,
+ GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON,
+ GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275,
+ GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275,
+ GRUB_INSTALL_PLATFORM_MIPSEL_ARC,
+ GRUB_INSTALL_PLATFORM_MIPS_ARC,
+ GRUB_INSTALL_PLATFORM_IA64_EFI,
+ GRUB_INSTALL_PLATFORM_ARM_UBOOT,
+ GRUB_INSTALL_PLATFORM_ARM_EFI,
+ GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS,
+ GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS,
+ GRUB_INSTALL_PLATFORM_I386_XEN,
+ GRUB_INSTALL_PLATFORM_X86_64_XEN,
+ GRUB_INSTALL_PLATFORM_I386_XEN_PVH,
+ GRUB_INSTALL_PLATFORM_ARM64_EFI,
+ GRUB_INSTALL_PLATFORM_MIPS64EL_EFI,
+ GRUB_INSTALL_PLATFORM_ARM_COREBOOT,
+ GRUB_INSTALL_PLATFORM_RISCV32_EFI,
+ GRUB_INSTALL_PLATFORM_RISCV64_EFI,
+ GRUB_INSTALL_PLATFORM_MAX
+ };
+
+enum grub_install_options {
+ GRUB_INSTALL_OPTIONS_DIRECTORY = 'd',
+ GRUB_INSTALL_OPTIONS_VERBOSITY = 'v',
+ GRUB_INSTALL_OPTIONS_MODULES = 0x201,
+ GRUB_INSTALL_OPTIONS_INSTALL_MODULES,
+ GRUB_INSTALL_OPTIONS_INSTALL_THEMES,
+ GRUB_INSTALL_OPTIONS_INSTALL_FONTS,
+ GRUB_INSTALL_OPTIONS_INSTALL_LOCALES,
+ GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS,
+ GRUB_INSTALL_OPTIONS_DIRECTORY2,
+ GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY,
+ GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY,
+ GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE,
+ GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS,
+ GRUB_INSTALL_OPTIONS_DTB
+};
+
+extern char *grub_install_source_directory;
+
+enum grub_install_plat
+grub_install_get_target (const char *src);
+void
+grub_install_mkdir_p (const char *dst);
+
+void
+grub_install_copy_files (const char *src,
+ const char *dst,
+ enum grub_install_plat platid);
+char *
+grub_install_get_platform_name (enum grub_install_plat platid);
+
+const char *
+grub_install_get_platform_cpu (enum grub_install_plat platid);
+
+const char *
+grub_install_get_platform_platform (enum grub_install_plat platid);
+
+char *
+grub_install_get_platforms_string (void);
+
+typedef enum {
+ GRUB_COMPRESSION_AUTO,
+ GRUB_COMPRESSION_NONE,
+ GRUB_COMPRESSION_XZ,
+ GRUB_COMPRESSION_LZMA
+} grub_compression_t;
+
+void
+grub_install_make_image_wrap (const char *dir, const char *prefix,
+ const char *outname, char *memdisk_path,
+ char *config_path,
+ const char *format, int note);
+void
+grub_install_make_image_wrap_file (const char *dir, const char *prefix,
+ FILE *fp, const char *outname,
+ char *memdisk_path,
+ char *config_path,
+ const char *mkimage_target, int note);
+
+int
+grub_install_copy_file (const char *src,
+ const char *dst,
+ int is_critical);
+
+struct grub_install_image_target_desc;
+
+void
+grub_install_generate_image (const char *dir, const char *prefix,
+ FILE *out,
+ const char *outname, char *mods[],
+ char *memdisk_path, char **pubkey_paths,
+ size_t npubkeys,
+ char *config_path,
+ const struct grub_install_image_target_desc *image_target,
+ int note,
+ grub_compression_t comp, const char *dtb_file);
+
+const struct grub_install_image_target_desc *
+grub_install_get_image_target (const char *arg);
+
+void
+grub_util_bios_setup (const char *dir,
+ const char *boot_file, const char *core_file,
+ const char *dest, int force,
+ int fs_probe, int allow_floppy,
+ int add_rs_codes);
+void
+grub_util_sparc_setup (const char *dir,
+ const char *boot_file, const char *core_file,
+ const char *dest, int force,
+ int fs_probe, int allow_floppy,
+ int add_rs_codes);
+
+char *
+grub_install_get_image_targets_string (void);
+
+const char *
+grub_util_get_target_dirname (const struct grub_install_image_target_desc *t);
+
+void
+grub_install_create_envblk_file (const char *name);
+
+const char *
+grub_install_get_default_arm_platform (void);
+
+const char *
+grub_install_get_default_x86_platform (void);
+
+int
+grub_install_register_efi (grub_device_t efidir_grub_dev,
+ const char *efifile_path,
+ const char *efi_distributor);
+
+void
+grub_install_register_ieee1275 (int is_prep, const char *install_device,
+ int partno, const char *relpath);
+
+void
+grub_install_sgi_setup (const char *install_device,
+ const char *imgfile, const char *destname);
+
+int
+grub_install_compress_gzip (const char *src, const char *dest);
+int
+grub_install_compress_lzop (const char *src, const char *dest);
+int
+grub_install_compress_xz (const char *src, const char *dest);
+
+void
+grub_install_get_blocklist (grub_device_t root_dev,
+ const char *core_path, const char *core_img,
+ size_t core_size,
+ void (*callback) (grub_disk_addr_t sector,
+ unsigned offset,
+ unsigned length,
+ void *data),
+ void *hook_data);
+
+void
+grub_util_create_envblk_file (const char *name);
+
+void
+grub_util_glue_efi (const char *file32, const char *file64, const char *out);
+
+void
+grub_util_render_label (const char *label_font,
+ const char *label_bgcolor,
+ const char *label_color,
+ const char *label_string,
+ const char *label);
+
+const char *
+grub_util_get_target_name (const struct grub_install_image_target_desc *t);
+
+extern char *grub_install_copy_buffer;
+#define GRUB_INSTALL_COPY_BUFFER_SIZE 1048576
+
+#endif
all_modules_arm64_uefi="setkey blocklist ventoy test true regexp newc search gcry_md5 hashsum gzio xzio lzopio ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop video video_fb gfxterm_background gfxterm_menu"
+all_modules_mips64el_uefi="setkey blocklist ventoy test true regexp newc search gcry_md5 hashsum gzio xzio lzopio ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop video video_fb gfxterm_background gfxterm_menu"
+
if [ "$1" = "uefi" ]; then
all_modules="$net_modules_uefi $all_modules_uefi "
all_modules="$net_modules_uefi $all_modules_arm64_uefi "
grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/arm64-efi" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/EFI/BOOT/BOOTAA64.EFI" --format 'arm64-efi' --compression 'auto' $all_modules_arm64_uefi
+elif [ "$1" = "mips64el" ]; then
+ all_modules="$net_modules_uefi $all_modules_mips64el_uefi "
+
+ grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/mips64el-efi" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/EFI/BOOT/BOOTMIPS.EFI" --format 'mips64el-efi' --compression 'auto' $all_modules_mips64el_uefi
else
all_modules="$net_modules_legacy $all_modules_legacy "
grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/grub/i386-pc/core.img" --format 'i386-pc' --compression 'auto' $all_modules_legacy 'fat' 'part_msdos' 'biosdisk'
cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/arm64-efi/$line $VT_DIR/INSTALL/grub/arm64-efi/
fi
done
+elif [ "$1" = "mips64el" ]; then
+ rm -f $VT_DIR/GRUB2/NBP/core.efi
+ cp -a $VT_DIR/GRUB2/PXE/grub2/mips64el-efi/core.efi $VT_DIR/GRUB2/NBP/core.efi || exit 1
+
+ rm -rf $VT_DIR/INSTALL/grub/mips64el-efi
+ mkdir -p $VT_DIR/INSTALL/grub/mips64el-efi
+
+ cp -a $VT_DIR/GRUB2/PXE/grub2/mips64el-efi/normal.mod $VT_DIR/INSTALL/grub/mips64el-efi/normal.mod || exit 1
+
+ #copy other modules
+ ls -1 $VT_DIR/GRUB2/INSTALL/lib/grub/mips64el-efi/ | egrep '\.(lst|mod)$' | while read line; do
+ if ! echo $all_modules | grep -q " ${line%.mod} "; then
+ echo "Copy $line ..."
+ cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/mips64el-efi/$line $VT_DIR/INSTALL/grub/mips64el-efi/
+ xz $VT_DIR/INSTALL/grub/mips64el-efi/$line
+ mv $VT_DIR/INSTALL/grub/mips64el-efi/${line}.xz $VT_DIR/INSTALL/grub/mips64el-efi/${line}
+ fi
+ done
else
rm -f $VT_DIR/GRUB2/NBP/core.0
cp -a $VT_DIR/GRUB2/PXE/grub2/i386-pc/core.0 $VT_DIR/GRUB2/NBP/core.0 || exit 1
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/emu/misc.h>
+#include <grub/util/misc.h>
+#include <grub/misc.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/fs.h>
+#include <grub/env.h>
+#include <grub/term.h>
+#include <grub/mm.h>
+#include <grub/lib/hexdump.h>
+#include <grub/crypto.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+#include <grub/zfs/zfs.h>
+#include <grub/util/install.h>
+#include <grub/util/resolve.h>
+#include <grub/emu/hostfile.h>
+#include <grub/emu/config.h>
+#include <grub/emu/hostfile.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+
+char *
+grub_install_help_filter (int key, const char *text,
+ void *input __attribute__ ((unused)))
+{
+ switch (key)
+ {
+ case GRUB_INSTALL_OPTIONS_INSTALL_THEMES:
+ return xasprintf(text, "starfield");
+ case GRUB_INSTALL_OPTIONS_INSTALL_FONTS:
+ return xasprintf(text, "unicode");
+ case GRUB_INSTALL_OPTIONS_DIRECTORY:
+ case GRUB_INSTALL_OPTIONS_DIRECTORY2:
+ return xasprintf(text, grub_util_get_pkglibdir ());
+ case GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY:
+ return xasprintf(text, grub_util_get_localedir ());
+ case GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY:
+ return grub_util_path_concat (2, grub_util_get_pkgdatadir (), "themes");
+ default:
+ return (char *) text;
+ }
+}
+
+#pragma GCC diagnostic error "-Wformat-nonliteral"
+
+static int (*compress_func) (const char *src, const char *dest) = NULL;
+char *grub_install_copy_buffer;
+static char *dtb;
+
+int
+grub_install_copy_file (const char *src,
+ const char *dst,
+ int is_needed)
+{
+ grub_util_fd_t in, out;
+ ssize_t r;
+
+ grub_util_info ("copying `%s' -> `%s'", src, dst);
+
+ in = grub_util_fd_open (src, GRUB_UTIL_FD_O_RDONLY);
+ if (!GRUB_UTIL_FD_IS_VALID (in))
+ {
+ if (is_needed)
+ grub_util_error (_("cannot open `%s': %s"), src, grub_util_fd_strerror ());
+ else
+ grub_util_info (_("cannot open `%s': %s"), src, grub_util_fd_strerror ());
+ return 0;
+ }
+ out = grub_util_fd_open (dst, GRUB_UTIL_FD_O_WRONLY
+ | GRUB_UTIL_FD_O_CREATTRUNC);
+ if (!GRUB_UTIL_FD_IS_VALID (out))
+ {
+ grub_util_error (_("cannot open `%s': %s"), dst,
+ grub_util_fd_strerror ());
+ grub_util_fd_close (in);
+ return 0;
+ }
+
+ if (!grub_install_copy_buffer)
+ grub_install_copy_buffer = xmalloc (GRUB_INSTALL_COPY_BUFFER_SIZE);
+
+ while (1)
+ {
+ r = grub_util_fd_read (in, grub_install_copy_buffer, GRUB_INSTALL_COPY_BUFFER_SIZE);
+ if (r <= 0)
+ break;
+ r = grub_util_fd_write (out, grub_install_copy_buffer, r);
+ if (r <= 0)
+ break;
+ }
+ if (grub_util_fd_sync (out) < 0)
+ r = -1;
+ if (grub_util_fd_close (in) < 0)
+ r = -1;
+ if (grub_util_fd_close (out) < 0)
+ r = -1;
+
+ if (r < 0)
+ grub_util_error (_("cannot copy `%s' to `%s': %s"),
+ src, dst, grub_util_fd_strerror ());
+
+ return 1;
+}
+
+static int
+grub_install_compress_file (const char *in_name,
+ const char *out_name,
+ int is_needed)
+{
+ int ret;
+
+ if (!compress_func)
+ ret = grub_install_copy_file (in_name, out_name, is_needed);
+ else
+ {
+ grub_util_info ("compressing `%s' -> `%s'", in_name, out_name);
+ ret = !compress_func (in_name, out_name);
+ if (!ret && is_needed)
+ grub_util_warn (_("can't compress `%s' to `%s'"), in_name, out_name);
+ }
+
+ if (!ret && is_needed)
+ grub_util_error (_("cannot copy `%s' to `%s': %s"),
+ in_name, out_name, grub_util_fd_strerror ());
+
+ return ret;
+}
+
+static int
+is_path_separator (char c)
+{
+#if defined (__MINGW32__) || defined (__CYGWIN__)
+ if (c == '\\')
+ return 1;
+#endif
+ if (c == '/')
+ return 1;
+ return 0;
+}
+
+void
+grub_install_mkdir_p (const char *dst)
+{
+ char *t = xstrdup (dst);
+ char *p;
+ for (p = t; *p; p++)
+ {
+ if (is_path_separator (*p))
+ {
+ char s = *p;
+ *p = '\0';
+ grub_util_mkdir (t);
+ *p = s;
+ }
+ }
+ grub_util_mkdir (t);
+ free (t);
+}
+
+static void
+clean_grub_dir (const char *di)
+{
+ grub_util_fd_dir_t d;
+ grub_util_fd_dirent_t de;
+
+ d = grub_util_fd_opendir (di);
+ if (!d)
+ grub_util_error (_("cannot open directory `%s': %s"),
+ di, grub_util_fd_strerror ());
+
+ while ((de = grub_util_fd_readdir (d)))
+ {
+ const char *ext = strrchr (de->d_name, '.');
+ if ((ext && (strcmp (ext, ".mod") == 0
+ || strcmp (ext, ".lst") == 0
+ || strcmp (ext, ".img") == 0
+ || strcmp (ext, ".mo") == 0)
+ && strcmp (de->d_name, "menu.lst") != 0)
+ || strcmp (de->d_name, "efiemu32.o") == 0
+ || strcmp (de->d_name, "efiemu64.o") == 0)
+ {
+ char *x = grub_util_path_concat (2, di, de->d_name);
+ if (grub_util_unlink (x) < 0)
+ grub_util_error (_("cannot delete `%s': %s"), x,
+ grub_util_fd_strerror ());
+ free (x);
+ }
+ }
+ grub_util_fd_closedir (d);
+}
+
+struct install_list
+{
+ int is_default;
+ char **entries;
+ size_t n_entries;
+ size_t n_alloc;
+};
+
+struct install_list install_modules = { 1, 0, 0, 0 };
+struct install_list modules = { 1, 0, 0, 0 };
+struct install_list install_locales = { 1, 0, 0, 0 };
+struct install_list install_fonts = { 1, 0, 0, 0 };
+struct install_list install_themes = { 1, 0, 0, 0 };
+char *grub_install_source_directory = NULL;
+char *grub_install_locale_directory = NULL;
+char *grub_install_themes_directory = NULL;
+
+void
+grub_install_push_module (const char *val)
+{
+ modules.is_default = 0;
+ if (modules.n_entries + 1 >= modules.n_alloc)
+ {
+ modules.n_alloc <<= 1;
+ if (modules.n_alloc < 16)
+ modules.n_alloc = 16;
+ modules.entries = xrealloc (modules.entries,
+ modules.n_alloc * sizeof (*modules.entries));
+ }
+ modules.entries[modules.n_entries++] = xstrdup (val);
+ modules.entries[modules.n_entries] = NULL;
+}
+
+void
+grub_install_pop_module (void)
+{
+ modules.n_entries--;
+ free (modules.entries[modules.n_entries]);
+ modules.entries[modules.n_entries] = NULL;
+}
+
+
+static void
+handle_install_list (struct install_list *il, const char *val,
+ int default_all)
+{
+ const char *ptr;
+ char **ce;
+ il->is_default = 0;
+ free (il->entries);
+ il->entries = NULL;
+ il->n_entries = 0;
+ if (strcmp (val, "all") == 0 && default_all)
+ {
+ il->is_default = 1;
+ return;
+ }
+ ptr = val;
+ while (1)
+ {
+ while (*ptr && grub_isspace (*ptr))
+ ptr++;
+ if (!*ptr)
+ break;
+ while (*ptr && !grub_isspace (*ptr))
+ ptr++;
+ il->n_entries++;
+ }
+ il->n_alloc = il->n_entries + 1;
+ il->entries = xmalloc (il->n_alloc * sizeof (il->entries[0]));
+ ptr = val;
+ for (ce = il->entries; ; ce++)
+ {
+ const char *bptr;
+ while (*ptr && grub_isspace (*ptr))
+ ptr++;
+ if (!*ptr)
+ break;
+ bptr = ptr;
+ while (*ptr && !grub_isspace (*ptr))
+ ptr++;
+ *ce = xmalloc (ptr - bptr + 1);
+ memcpy (*ce, bptr, ptr - bptr);
+ (*ce)[ptr - bptr] = '\0';
+ }
+ *ce = NULL;
+}
+
+static char **pubkeys;
+static size_t npubkeys;
+static grub_compression_t compression;
+
+int
+grub_install_parse (int key, char *arg)
+{
+ switch (key)
+ {
+ case 'C':
+ if (grub_strcmp (arg, "xz") == 0)
+ {
+#ifdef HAVE_LIBLZMA
+ compression = GRUB_COMPRESSION_XZ;
+#else
+ grub_util_error ("%s",
+ _("grub-mkimage is compiled without XZ support"));
+#endif
+ }
+ else if (grub_strcmp (arg, "none") == 0)
+ compression = GRUB_COMPRESSION_NONE;
+ else if (grub_strcmp (arg, "auto") == 0)
+ compression = GRUB_COMPRESSION_AUTO;
+ else
+ grub_util_error (_("Unknown compression format %s"), arg);
+ return 1;
+ case 'k':
+ pubkeys = xrealloc (pubkeys,
+ sizeof (pubkeys[0])
+ * (npubkeys + 1));
+ pubkeys[npubkeys++] = xstrdup (arg);
+ return 1;
+
+ case GRUB_INSTALL_OPTIONS_VERBOSITY:
+ verbosity++;
+ return 1;
+
+ case GRUB_INSTALL_OPTIONS_DIRECTORY:
+ case GRUB_INSTALL_OPTIONS_DIRECTORY2:
+ free (grub_install_source_directory);
+ grub_install_source_directory = xstrdup (arg);
+ return 1;
+ case GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY:
+ free (grub_install_locale_directory);
+ grub_install_locale_directory = xstrdup (arg);
+ return 1;
+ case GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY:
+ free (grub_install_themes_directory);
+ grub_install_themes_directory = xstrdup (arg);
+ return 1;
+ case GRUB_INSTALL_OPTIONS_INSTALL_MODULES:
+ handle_install_list (&install_modules, arg, 0);
+ return 1;
+ case GRUB_INSTALL_OPTIONS_MODULES:
+ handle_install_list (&modules, arg, 0);
+ return 1;
+ case GRUB_INSTALL_OPTIONS_INSTALL_LOCALES:
+ handle_install_list (&install_locales, arg, 0);
+ return 1;
+ case GRUB_INSTALL_OPTIONS_INSTALL_THEMES:
+ handle_install_list (&install_themes, arg, 0);
+ return 1;
+ case GRUB_INSTALL_OPTIONS_INSTALL_FONTS:
+ handle_install_list (&install_fonts, arg, 0);
+ return 1;
+ case GRUB_INSTALL_OPTIONS_DTB:
+ if (dtb)
+ free (dtb);
+ dtb = xstrdup (arg);
+ return 1;
+ case GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS:
+ if (strcmp (arg, "no") == 0
+ || strcmp (arg, "none") == 0)
+ {
+ compress_func = NULL;
+ return 1;
+ }
+ if (strcmp (arg, "gz") == 0)
+ {
+ compress_func = grub_install_compress_gzip;
+ return 1;
+ }
+ if (strcmp (arg, "xz") == 0)
+ {
+ compress_func = grub_install_compress_xz;
+ return 1;
+ }
+ if (strcmp (arg, "lzo") == 0)
+ {
+ compress_func = grub_install_compress_lzop;
+ return 1;
+ }
+ grub_util_error (_("Unrecognized compression `%s'"), arg);
+ case GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int
+decompressors (void)
+{
+ if (compress_func == grub_install_compress_gzip)
+ {
+ grub_install_push_module ("gzio");
+ return 1;
+ }
+ if (compress_func == grub_install_compress_xz)
+ {
+ grub_install_push_module ("xzio");
+ grub_install_push_module ("gcry_crc");
+ return 2;
+ }
+ if (compress_func == grub_install_compress_lzop)
+ {
+ grub_install_push_module ("lzopio");
+ grub_install_push_module ("adler32");
+ grub_install_push_module ("gcry_crc");
+ return 3;
+ }
+ return 0;
+}
+
+void
+grub_install_make_image_wrap_file (const char *dir, const char *prefix,
+ FILE *fp, const char *outname,
+ char *memdisk_path,
+ char *config_path,
+ const char *mkimage_target, int note)
+{
+ const struct grub_install_image_target_desc *tgt;
+ const char *const compnames[] =
+ {
+ [GRUB_COMPRESSION_AUTO] = "auto",
+ [GRUB_COMPRESSION_NONE] = "none",
+ [GRUB_COMPRESSION_XZ] = "xz",
+ [GRUB_COMPRESSION_LZMA] = "lzma",
+ };
+ grub_size_t slen = 1;
+ char *s, *p;
+ char **pk, **md;
+ int dc = decompressors ();
+
+ if (memdisk_path)
+ slen += 20 + grub_strlen (memdisk_path);
+ if (config_path)
+ slen += 20 + grub_strlen (config_path);
+
+ for (pk = pubkeys; pk < pubkeys + npubkeys; pk++)
+ slen += 20 + grub_strlen (*pk);
+
+ for (md = modules.entries; *md; md++)
+ {
+ slen += 10 + grub_strlen (*md);
+ }
+
+ p = s = xmalloc (slen);
+ if (memdisk_path)
+ {
+ p = grub_stpcpy (p, "--memdisk '");
+ p = grub_stpcpy (p, memdisk_path);
+ *p++ = '\'';
+ *p++ = ' ';
+ }
+ if (config_path)
+ {
+ p = grub_stpcpy (p, "--config '");
+ p = grub_stpcpy (p, config_path);
+ *p++ = '\'';
+ *p++ = ' ';
+ }
+ for (pk = pubkeys; pk < pubkeys + npubkeys; pk++)
+ {
+ p = grub_stpcpy (p, "--pubkey '");
+ p = grub_stpcpy (p, *pk);
+ *p++ = '\'';
+ *p++ = ' ';
+ }
+
+ for (md = modules.entries; *md; md++)
+ {
+ *p++ = '\'';
+ p = grub_stpcpy (p, *md);
+ *p++ = '\'';
+ *p++ = ' ';
+ }
+
+ *p = '\0';
+
+ grub_util_info ("grub-mkimage --directory '%s' --prefix '%s'"
+ " --output '%s' "
+ " --dtb '%s' "
+ "--format '%s' --compression '%s' %s %s\n",
+ dir, prefix,
+ outname, dtb ? : "", mkimage_target,
+ compnames[compression], note ? "--note" : "", s);
+ free (s);
+
+ tgt = grub_install_get_image_target (mkimage_target);
+ if (!tgt)
+ grub_util_error (_("unknown target format %s"), mkimage_target);
+
+ grub_install_generate_image (dir, prefix, fp, outname,
+ modules.entries, memdisk_path,
+ pubkeys, npubkeys, config_path, tgt,
+ note, compression, dtb);
+ while (dc--)
+ grub_install_pop_module ();
+}
+
+void
+grub_install_make_image_wrap (const char *dir, const char *prefix,
+ const char *outname, char *memdisk_path,
+ char *config_path,
+ const char *mkimage_target, int note)
+{
+ FILE *fp;
+
+ fp = grub_util_fopen (outname, "wb");
+ if (! fp)
+ grub_util_error (_("cannot open `%s': %s"), outname,
+ strerror (errno));
+ grub_install_make_image_wrap_file (dir, prefix, fp, outname,
+ memdisk_path, config_path,
+ mkimage_target, note);
+ if (grub_util_file_sync (fp) < 0)
+ grub_util_error (_("cannot sync `%s': %s"), outname, strerror (errno));
+ fclose (fp);
+}
+
+static void
+copy_by_ext (const char *srcd,
+ const char *dstd,
+ const char *extf,
+ int req)
+{
+ grub_util_fd_dir_t d;
+ grub_util_fd_dirent_t de;
+
+ d = grub_util_fd_opendir (srcd);
+ if (!d && !req)
+ return;
+ if (!d)
+ grub_util_error (_("cannot open directory `%s': %s"),
+ srcd, grub_util_fd_strerror ());
+
+ while ((de = grub_util_fd_readdir (d)))
+ {
+ const char *ext = strrchr (de->d_name, '.');
+ if (ext && strcmp (ext, extf) == 0)
+ {
+ char *srcf = grub_util_path_concat (2, srcd, de->d_name);
+ char *dstf = grub_util_path_concat (2, dstd, de->d_name);
+ grub_install_compress_file (srcf, dstf, 1);
+ free (srcf);
+ free (dstf);
+ }
+ }
+ grub_util_fd_closedir (d);
+}
+
+static void
+copy_all (const char *srcd,
+ const char *dstd)
+{
+ grub_util_fd_dir_t d;
+ grub_util_fd_dirent_t de;
+
+ d = grub_util_fd_opendir (srcd);
+ if (!d)
+ grub_util_error (_("cannot open directory `%s': %s"),
+ srcd, grub_util_fd_strerror ());
+
+ while ((de = grub_util_fd_readdir (d)))
+ {
+ char *srcf;
+ char *dstf;
+ if (strcmp (de->d_name, ".") == 0
+ || strcmp (de->d_name, "..") == 0)
+ continue;
+ srcf = grub_util_path_concat (2, srcd, de->d_name);
+ if (grub_util_is_special_file (srcf)
+ || grub_util_is_directory (srcf))
+ continue;
+ dstf = grub_util_path_concat (2, dstd, de->d_name);
+ grub_install_compress_file (srcf, dstf, 1);
+ free (srcf);
+ free (dstf);
+ }
+ grub_util_fd_closedir (d);
+}
+
+#if !(defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS)
+static const char *
+get_localedir (void)
+{
+ if (grub_install_locale_directory)
+ return grub_install_locale_directory;
+ else
+ return grub_util_get_localedir ();
+}
+
+static void
+copy_locales (const char *dstd)
+{
+ grub_util_fd_dir_t d;
+ grub_util_fd_dirent_t de;
+ const char *locale_dir = get_localedir ();
+
+ d = grub_util_fd_opendir (locale_dir);
+ if (!d)
+ {
+ grub_util_warn (_("cannot open directory `%s': %s"),
+ locale_dir, grub_util_fd_strerror ());
+ return;
+ }
+
+ while ((de = grub_util_fd_readdir (d)))
+ {
+ char *srcf;
+ char *dstf;
+ char *ext;
+ if (strcmp (de->d_name, ".") == 0)
+ continue;
+ if (strcmp (de->d_name, "..") == 0)
+ continue;
+ ext = grub_strrchr (de->d_name, '.');
+ if (ext && (grub_strcmp (ext, ".mo") == 0
+ || grub_strcmp (ext, ".gmo") == 0))
+ {
+ srcf = grub_util_path_concat (2, locale_dir, de->d_name);
+ dstf = grub_util_path_concat (2, dstd, de->d_name);
+ ext = grub_strrchr (dstf, '.');
+ grub_strcpy (ext, ".mo");
+ }
+ else
+ {
+ srcf = grub_util_path_concat_ext (4, locale_dir, de->d_name,
+ "LC_MESSAGES", PACKAGE, ".mo");
+ dstf = grub_util_path_concat_ext (2, dstd, de->d_name, ".mo");
+ }
+ grub_install_compress_file (srcf, dstf, 0);
+ free (srcf);
+ free (dstf);
+ }
+ grub_util_fd_closedir (d);
+}
+#endif
+
+static void
+grub_install_copy_nls(const char *src __attribute__ ((unused)),
+ const char *dst __attribute__ ((unused)))
+{
+#if !(defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS)
+ char *dst_locale;
+
+ dst_locale = grub_util_path_concat (2, dst, "locale");
+ grub_install_mkdir_p (dst_locale);
+ clean_grub_dir (dst_locale);
+
+ if (install_locales.is_default)
+ {
+ char *srcd = grub_util_path_concat (2, src, "po");
+ copy_by_ext (srcd, dst_locale, ".mo", 0);
+ copy_locales (dst_locale);
+ free (srcd);
+ }
+ else
+ {
+ size_t i;
+ const char *locale_dir = get_localedir ();
+
+ for (i = 0; i < install_locales.n_entries; i++)
+ {
+ char *srcf = grub_util_path_concat_ext (3, src, "po",
+ install_locales.entries[i],
+ ".mo");
+ char *dstf = grub_util_path_concat_ext (2, dst_locale,
+ install_locales.entries[i],
+ ".mo");
+ if (grub_install_compress_file (srcf, dstf, 0))
+ {
+ free (srcf);
+ free (dstf);
+ continue;
+ }
+ free (srcf);
+ srcf = grub_util_path_concat_ext (4, locale_dir,
+ install_locales.entries[i],
+ "LC_MESSAGES", PACKAGE, ".mo");
+ if (grub_install_compress_file (srcf, dstf, 0) == 0)
+ grub_util_error (_("cannot find locale `%s'"),
+ install_locales.entries[i]);
+ free (srcf);
+ free (dstf);
+ }
+ }
+ free (dst_locale);
+#endif
+}
+
+static struct
+{
+ const char *cpu;
+ const char *platform;
+} platforms[GRUB_INSTALL_PLATFORM_MAX] =
+ {
+ [GRUB_INSTALL_PLATFORM_I386_PC] = { "i386", "pc" },
+ [GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386", "efi" },
+ [GRUB_INSTALL_PLATFORM_I386_QEMU] = { "i386", "qemu" },
+ [GRUB_INSTALL_PLATFORM_I386_COREBOOT] = { "i386", "coreboot" },
+ [GRUB_INSTALL_PLATFORM_I386_MULTIBOOT] = { "i386", "multiboot" },
+ [GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386", "ieee1275" },
+ [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64", "efi" },
+ [GRUB_INSTALL_PLATFORM_I386_XEN] = { "i386", "xen" },
+ [GRUB_INSTALL_PLATFORM_X86_64_XEN] = { "x86_64", "xen" },
+ [GRUB_INSTALL_PLATFORM_I386_XEN_PVH] = { "i386", "xen_pvh" },
+ [GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON] = { "mipsel", "loongson" },
+ [GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS] = { "mipsel", "qemu_mips" },
+ [GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS] = { "mips", "qemu_mips" },
+ [GRUB_INSTALL_PLATFORM_MIPSEL_ARC] = { "mipsel", "arc" },
+ [GRUB_INSTALL_PLATFORM_MIPS_ARC] = { "mips", "arc" },
+ [GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64", "ieee1275" },
+ [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc", "ieee1275" },
+ [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64", "efi" },
+ [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm", "efi" },
+ [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64", "efi" },
+ [GRUB_INSTALL_PLATFORM_MIPS64EL_EFI] = { "mips64el","efi" },
+ [GRUB_INSTALL_PLATFORM_ARM_UBOOT] = { "arm", "uboot" },
+ [GRUB_INSTALL_PLATFORM_ARM_COREBOOT] = { "arm", "coreboot" },
+ [GRUB_INSTALL_PLATFORM_RISCV32_EFI] = { "riscv32", "efi" },
+ [GRUB_INSTALL_PLATFORM_RISCV64_EFI] = { "riscv64", "efi" },
+ };
+
+char *
+grub_install_get_platforms_string (void)
+{
+ char **arr = xmalloc (sizeof (char *) * ARRAY_SIZE (platforms));
+ int platform_strins_len = 0;
+ char *platforms_string;
+ char *ptr;
+ unsigned i;
+ for (i = 0; i < ARRAY_SIZE (platforms); i++)
+ {
+ arr[i] = xasprintf ("%s-%s", platforms[i].cpu,
+ platforms[i].platform);
+ platform_strins_len += strlen (arr[i]) + 2;
+ }
+ ptr = platforms_string = xmalloc (platform_strins_len);
+ qsort (arr, ARRAY_SIZE (platforms), sizeof (char *), grub_qsort_strcmp);
+ for (i = 0; i < ARRAY_SIZE (platforms); i++)
+ {
+ strcpy (ptr, arr[i]);
+ ptr += strlen (arr[i]);
+ *ptr++ = ',';
+ *ptr++ = ' ';
+ free (arr[i]);
+ }
+ ptr[-2] = 0;
+ free (arr);
+
+ return platforms_string;
+}
+
+char *
+grub_install_get_platform_name (enum grub_install_plat platid)
+{
+ return xasprintf ("%s-%s", platforms[platid].cpu,
+ platforms[platid].platform);
+}
+
+const char *
+grub_install_get_platform_cpu (enum grub_install_plat platid)
+{
+ return platforms[platid].cpu;
+}
+
+const char *
+grub_install_get_platform_platform (enum grub_install_plat platid)
+{
+ return platforms[platid].platform;
+}
+
+
+void
+grub_install_copy_files (const char *src,
+ const char *dst,
+ enum grub_install_plat platid)
+{
+ char *dst_platform, *dst_fonts;
+ const char *pkgdatadir = grub_util_get_pkgdatadir ();
+ char *themes_dir;
+
+ {
+ char *platform;
+ platform = xasprintf ("%s-%s", platforms[platid].cpu,
+ platforms[platid].platform);
+ dst_platform = grub_util_path_concat (2, dst, platform);
+ free (platform);
+ }
+ dst_fonts = grub_util_path_concat (2, dst, "fonts");
+ grub_install_mkdir_p (dst_platform);
+ clean_grub_dir (dst);
+ clean_grub_dir (dst_platform);
+
+ grub_install_copy_nls(src, dst);
+
+ if (install_modules.is_default)
+ copy_by_ext (src, dst_platform, ".mod", 1);
+ else
+ {
+ struct grub_util_path_list *path_list, *p;
+
+ path_list = grub_util_resolve_dependencies (src, "moddep.lst",
+ install_modules.entries);
+ for (p = path_list; p; p = p->next)
+ {
+ const char *srcf = p->name;
+ const char *dir;
+ char *dstf;
+
+ dir = grub_strrchr (srcf, '/');
+ if (dir)
+ dir++;
+ else
+ dir = srcf;
+ dstf = grub_util_path_concat (2, dst_platform, dir);
+ grub_install_compress_file (srcf, dstf, 1);
+ free (dstf);
+ }
+
+ grub_util_free_path_list (path_list);
+ }
+
+ const char *pkglib_DATA[] = {"efiemu32.o", "efiemu64.o",
+ "moddep.lst", "command.lst",
+ "fs.lst", "partmap.lst",
+ "parttool.lst",
+ "video.lst", "crypto.lst",
+ "terminal.lst", "modinfo.sh" };
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE (pkglib_DATA); i++)
+ {
+ char *srcf = grub_util_path_concat (2, src, pkglib_DATA[i]);
+ char *dstf = grub_util_path_concat (2, dst_platform, pkglib_DATA[i]);
+ if (i == 0 || i == 1)
+ grub_install_compress_file (srcf, dstf, 0);
+ else
+ grub_install_compress_file (srcf, dstf, 1);
+ free (srcf);
+ free (dstf);
+ }
+
+ if (install_themes.is_default)
+ {
+ install_themes.is_default = 0;
+ install_themes.n_entries = 1;
+ install_themes.entries = xmalloc (2 * sizeof (install_themes.entries[0]));
+ install_themes.entries[0] = xstrdup ("starfield");
+ install_themes.entries[1] = NULL;
+ }
+
+ if (grub_install_themes_directory)
+ themes_dir = xstrdup (grub_install_themes_directory);
+ else
+ themes_dir = grub_util_path_concat (2, grub_util_get_pkgdatadir (),
+ "themes");
+
+ for (i = 0; i < install_themes.n_entries; i++)
+ {
+ char *srcf = grub_util_path_concat (3, themes_dir,
+ install_themes.entries[i],
+ "theme.txt");
+ if (grub_util_is_regular (srcf))
+ {
+ char *srcd = grub_util_path_concat (2, themes_dir,
+ install_themes.entries[i]);
+ char *dstd = grub_util_path_concat (3, dst, "themes",
+ install_themes.entries[i]);
+ grub_install_mkdir_p (dstd);
+ copy_all (srcd, dstd);
+ free (srcd);
+ free (dstd);
+ }
+ free (srcf);
+ }
+
+ free (themes_dir);
+
+ if (install_fonts.is_default)
+ {
+ install_fonts.is_default = 0;
+ install_fonts.n_entries = 1;
+ install_fonts.entries = xmalloc (2 * sizeof (install_fonts.entries[0]));
+ install_fonts.entries[0] = xstrdup ("unicode");
+ install_fonts.entries[1] = NULL;
+ }
+
+ grub_install_mkdir_p (dst_fonts);
+
+ for (i = 0; i < install_fonts.n_entries; i++)
+ {
+ char *srcf = grub_util_path_concat_ext (2, pkgdatadir,
+ install_fonts.entries[i],
+ ".pf2");
+ char *dstf = grub_util_path_concat_ext (2, dst_fonts,
+ install_fonts.entries[i],
+ ".pf2");
+
+ grub_install_compress_file (srcf, dstf, 0);
+ free (srcf);
+ free (dstf);
+ }
+
+ free (dst_platform);
+ free (dst_fonts);
+}
+
+enum grub_install_plat
+grub_install_get_target (const char *src)
+{
+ char *fn;
+ grub_util_fd_t f;
+ char buf[8192];
+ ssize_t r;
+ char *c, *pl, *p;
+ size_t i;
+ fn = grub_util_path_concat (2, src, "modinfo.sh");
+ f = grub_util_fd_open (fn, GRUB_UTIL_FD_O_RDONLY);
+ if (!GRUB_UTIL_FD_IS_VALID (f))
+ grub_util_error (_("%s doesn't exist. Please specify --target or --directory"),
+ fn);
+ r = grub_util_fd_read (f, buf, sizeof (buf) - 1);
+ if (r < 0)
+ grub_util_error (_("cannot read `%s': %s"), fn, strerror (errno));
+ grub_util_fd_close (f);
+ buf[r] = '\0';
+ c = strstr (buf, "grub_modinfo_target_cpu=");
+ if (!c || (c != buf && !grub_isspace (*(c-1))))
+ grub_util_error (_("invalid modinfo file `%s'"), fn);
+ pl = strstr (buf, "grub_modinfo_platform=");
+ if (!pl || (pl != buf && !grub_isspace (*(pl-1))))
+ grub_util_error (_("invalid modinfo file `%s'"), fn);
+ c += sizeof ("grub_modinfo_target_cpu=") - 1;
+ pl += sizeof ("grub_modinfo_platform=") - 1;
+ for (p = c; *p && !grub_isspace (*p); p++);
+ *p = '\0';
+ for (p = pl; *p && !grub_isspace (*p); p++);
+ *p = '\0';
+
+ for (i = 0; i < ARRAY_SIZE (platforms); i++)
+ if (strcmp (platforms[i].cpu, c) == 0
+ && strcmp (platforms[i].platform, pl) == 0)
+ {
+ free (fn);
+ return i;
+ }
+ grub_util_error (_("Unknown platform `%s-%s'"), c, pl);
+}
+
+
+void
+grub_util_unlink_recursive (const char *name)
+{
+ grub_util_fd_dir_t d;
+ grub_util_fd_dirent_t de;
+
+ d = grub_util_fd_opendir (name);
+
+ while ((de = grub_util_fd_readdir (d)))
+ {
+ char *fp;
+ if (strcmp (de->d_name, ".") == 0)
+ continue;
+ if (strcmp (de->d_name, "..") == 0)
+ continue;
+ fp = grub_util_path_concat (2, name, de->d_name);
+ if (grub_util_is_special_file (fp))
+ {
+ free (fp);
+ continue;
+ }
+ if (grub_util_is_regular (fp))
+ grub_util_unlink (fp);
+ else if (grub_util_is_directory (fp))
+ grub_util_unlink_recursive (fp);
+ free (fp);
+ }
+ grub_util_rmdir (name);
+ grub_util_fd_closedir (d);
+}
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/emu/misc.h>
+#include <grub/util/misc.h>
+#include <grub/misc.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/fs.h>
+#include <grub/env.h>
+#include <grub/term.h>
+#include <grub/mm.h>
+#include <grub/lib/hexdump.h>
+#include <grub/crypto.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+#include <grub/zfs/zfs.h>
+#include <grub/util/install.h>
+#include <grub/emu/getroot.h>
+#include <grub/diskfilter.h>
+#include <grub/cryptodisk.h>
+#include <grub/legacy_parse.h>
+#include <grub/gpt_partition.h>
+#include <grub/emu/config.h>
+#include <grub/util/ofpath.h>
+#include <grub/hfsplus.h>
+
+#include <string.h>
+
+#pragma GCC diagnostic ignored "-Wmissing-prototypes"
+#pragma GCC diagnostic ignored "-Wmissing-declarations"
+#include <argp.h>
+#pragma GCC diagnostic error "-Wmissing-prototypes"
+#pragma GCC diagnostic error "-Wmissing-declarations"
+
+#include "progname.h"
+
+static char *target;
+static int removable = 0;
+static int recheck = 0;
+static int update_nvram = 1;
+static char *install_device = NULL;
+static char *debug_image = NULL;
+static char *rootdir = NULL;
+static char *bootdir = NULL;
+static int allow_floppy = 0;
+static int force_file_id = 0;
+static char *disk_module = NULL;
+static char *efidir = NULL;
+static char *macppcdir = NULL;
+static int force = 0;
+static int have_abstractions = 0;
+static int have_cryptodisk = 0;
+static char * bootloader_id;
+static int have_load_cfg = 0;
+static FILE * load_cfg_f = NULL;
+static char *load_cfg;
+static int install_bootsector = 1;
+static char *label_font;
+static char *label_color;
+static char *label_bgcolor;
+static char *product_version;
+static int add_rs_codes = 1;
+
+enum
+ {
+ OPTION_BOOT_DIRECTORY = 0x301,
+ OPTION_ROOT_DIRECTORY,
+ OPTION_TARGET,
+ OPTION_SETUP,
+ OPTION_MKRELPATH,
+ OPTION_MKDEVICEMAP,
+ OPTION_PROBE,
+ OPTION_EDITENV,
+ OPTION_ALLOW_FLOPPY,
+ OPTION_RECHECK,
+ OPTION_FORCE,
+ OPTION_FORCE_FILE_ID,
+ OPTION_NO_NVRAM,
+ OPTION_REMOVABLE,
+ OPTION_BOOTLOADER_ID,
+ OPTION_EFI_DIRECTORY,
+ OPTION_FONT,
+ OPTION_DEBUG,
+ OPTION_DEBUG_IMAGE,
+ OPTION_NO_FLOPPY,
+ OPTION_DISK_MODULE,
+ OPTION_NO_BOOTSECTOR,
+ OPTION_NO_RS_CODES,
+ OPTION_MACPPC_DIRECTORY,
+ OPTION_LABEL_FONT,
+ OPTION_LABEL_COLOR,
+ OPTION_LABEL_BGCOLOR,
+ OPTION_PRODUCT_VERSION
+ };
+
+static int fs_probe = 1;
+
+static error_t
+argp_parser (int key, char *arg, struct argp_state *state)
+{
+ if (grub_install_parse (key, arg))
+ return 0;
+ switch (key)
+ {
+ case OPTION_FORCE_FILE_ID:
+ force_file_id = 1;
+ return 0;
+ case 's':
+ fs_probe = 0;
+ return 0;
+
+ case OPTION_SETUP:
+ if (!grub_strstr (arg, "setup"))
+ install_bootsector = 0;
+ return 0;
+
+ case OPTION_PRODUCT_VERSION:
+ free (product_version);
+ product_version = xstrdup (arg);
+ return 0;
+ case OPTION_LABEL_FONT:
+ free (label_font);
+ label_font = xstrdup (arg);
+ return 0;
+
+ case OPTION_LABEL_COLOR:
+ free (label_color);
+ label_color = xstrdup (arg);
+ return 0;
+
+ case OPTION_LABEL_BGCOLOR:
+ free (label_bgcolor);
+ label_bgcolor = xstrdup (arg);
+ return 0;
+
+ /* Accept and ignore for compatibility. */
+ case OPTION_FONT:
+ case OPTION_MKRELPATH:
+ case OPTION_PROBE:
+ case OPTION_EDITENV:
+ case OPTION_MKDEVICEMAP:
+ case OPTION_NO_FLOPPY:
+ return 0;
+ case OPTION_ROOT_DIRECTORY:
+ /* Accept for compatibility. */
+ free (rootdir);
+ rootdir = xstrdup (arg);
+ return 0;
+
+ case OPTION_BOOT_DIRECTORY:
+ free (bootdir);
+ bootdir = xstrdup (arg);
+ return 0;
+
+ case OPTION_MACPPC_DIRECTORY:
+ free (macppcdir);
+ macppcdir = xstrdup (arg);
+ return 0;
+
+ case OPTION_EFI_DIRECTORY:
+ free (efidir);
+ efidir = xstrdup (arg);
+ return 0;
+
+ case OPTION_DISK_MODULE:
+ free (disk_module);
+ disk_module = xstrdup (arg);
+ return 0;
+
+ case OPTION_TARGET:
+ free (target);
+ target = xstrdup (arg);
+ return 0;
+
+ case OPTION_DEBUG_IMAGE:
+ free (debug_image);
+ debug_image = xstrdup (arg);
+ return 0;
+
+ case OPTION_NO_NVRAM:
+ update_nvram = 0;
+ return 0;
+
+ case OPTION_FORCE:
+ force = 1;
+ return 0;
+
+ case OPTION_RECHECK:
+ recheck = 1;
+ return 0;
+
+ case OPTION_REMOVABLE:
+ removable = 1;
+ return 0;
+
+ case OPTION_ALLOW_FLOPPY:
+ allow_floppy = 1;
+ return 0;
+
+ case OPTION_NO_BOOTSECTOR:
+ install_bootsector = 0;
+ return 0;
+
+ case OPTION_NO_RS_CODES:
+ add_rs_codes = 0;
+ return 0;
+
+ case OPTION_DEBUG:
+ verbosity++;
+ return 0;
+
+ case OPTION_BOOTLOADER_ID:
+ free (bootloader_id);
+ bootloader_id = xstrdup (arg);
+ return 0;
+
+ case ARGP_KEY_ARG:
+ if (install_device)
+ grub_util_error ("%s", _("More than one install device?"));
+ install_device = xstrdup (arg);
+ return 0;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+}
+
+
+static struct argp_option options[] = {
+ GRUB_INSTALL_OPTIONS,
+ {"boot-directory", OPTION_BOOT_DIRECTORY, N_("DIR"),
+ 0, N_("install GRUB images under the directory DIR/%s instead of the %s directory"), 2},
+ {"root-directory", OPTION_ROOT_DIRECTORY, N_("DIR"),
+ OPTION_HIDDEN, 0, 2},
+ {"font", OPTION_FONT, N_("FILE"),
+ OPTION_HIDDEN, 0, 2},
+ {"target", OPTION_TARGET, N_("TARGET"),
+ /* TRANSLATORS: "TARGET" as in "target platform". */
+ 0, N_("install GRUB for TARGET platform [default=%s]; available targets: %s"), 2},
+ {"grub-setup", OPTION_SETUP, "FILE", OPTION_HIDDEN, 0, 2},
+ {"grub-mkrelpath", OPTION_MKRELPATH, "FILE", OPTION_HIDDEN, 0, 2},
+ {"grub-mkdevicemap", OPTION_MKDEVICEMAP, "FILE", OPTION_HIDDEN, 0, 2},
+ {"grub-probe", OPTION_PROBE, "FILE", OPTION_HIDDEN, 0, 2},
+ {"grub-editenv", OPTION_EDITENV, "FILE", OPTION_HIDDEN, 0, 2},
+ {"allow-floppy", OPTION_ALLOW_FLOPPY, 0, 0,
+ /* TRANSLATORS: "may break" doesn't just mean that option wouldn't have any
+ effect but that it will make the resulting install unbootable from HDD. */
+ N_("make the drive also bootable as floppy (default for fdX devices)."
+ " May break on some BIOSes."), 2},
+ {"recheck", OPTION_RECHECK, 0, 0,
+ N_("delete device map if it already exists"), 2},
+ {"force", OPTION_FORCE, 0, 0,
+ N_("install even if problems are detected"), 2},
+ {"force-file-id", OPTION_FORCE_FILE_ID, 0, 0,
+ N_("use identifier file even if UUID is available"), 2},
+ {"disk-module", OPTION_DISK_MODULE, N_("MODULE"), 0,
+ N_("disk module to use (biosdisk or native). "
+ "This option is only available on BIOS target."), 2},
+ {"no-nvram", OPTION_NO_NVRAM, 0, 0,
+ N_("don't update the `boot-device'/`Boot*' NVRAM variables. "
+ "This option is only available on EFI and IEEE1275 targets."), 2},
+ {"skip-fs-probe",'s',0, 0,
+ N_("do not probe for filesystems in DEVICE"), 0},
+ {"no-bootsector", OPTION_NO_BOOTSECTOR, 0, 0,
+ N_("do not install bootsector"), 0},
+ {"no-rs-codes", OPTION_NO_RS_CODES, 0, 0,
+ N_("Do not apply any reed-solomon codes when embedding core.img. "
+ "This option is only available on x86 BIOS targets."), 0},
+
+ {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2},
+ {"no-floppy", OPTION_NO_FLOPPY, 0, OPTION_HIDDEN, 0, 2},
+ {"debug-image", OPTION_DEBUG_IMAGE, N_("STRING"), OPTION_HIDDEN, 0, 2},
+ {"removable", OPTION_REMOVABLE, 0, 0,
+ N_("the installation device is removable. "
+ "This option is only available on EFI."), 2},
+ {"bootloader-id", OPTION_BOOTLOADER_ID, N_("ID"), 0,
+ N_("the ID of bootloader. This option is only available on EFI and Macs."), 2},
+ {"efi-directory", OPTION_EFI_DIRECTORY, N_("DIR"), 0,
+ N_("use DIR as the EFI System Partition root."), 2},
+ {"macppc-directory", OPTION_MACPPC_DIRECTORY, N_("DIR"), 0,
+ N_("use DIR for PPC MAC install."), 2},
+ {"label-font", OPTION_LABEL_FONT, N_("FILE"), 0, N_("use FILE as font for label"), 2},
+ {"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2},
+ {"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2},
+ {"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2},
+ {0, 0, 0, 0, 0, 0}
+};
+
+static const char *
+get_default_platform (void)
+{
+#ifdef __powerpc__
+ return "powerpc-ieee1275";
+#elif defined (__sparc__) || defined (__sparc64__)
+ return "sparc64-ieee1275";
+#elif defined (__MIPSEL__)
+#if _MIPS_SIM == _ABI64
+ return "mips64el-efi";
+#else
+ return "mipsel-loongson";
+#endif
+#elif defined (__MIPSEB__)
+ return "mips-arc";
+#elif defined (__ia64__)
+ return "ia64-efi";
+#elif defined (__arm__)
+ return grub_install_get_default_arm_platform ();
+#elif defined (__aarch64__)
+ return "arm64-efi";
+#elif defined (__amd64__) || defined (__x86_64__) || defined (__i386__)
+ return grub_install_get_default_x86_platform ();
+#else
+ return NULL;
+#endif
+}
+
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+
+static char *
+help_filter (int key, const char *text, void *input __attribute__ ((unused)))
+{
+ switch (key)
+ {
+ case OPTION_BOOT_DIRECTORY:
+ return xasprintf (text, GRUB_DIR_NAME, GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME);
+ case OPTION_TARGET:
+ {
+ char *plats = grub_install_get_platforms_string ();
+ char *ret;
+ ret = xasprintf (text, get_default_platform (), plats);
+ free (plats);
+ return ret;
+ }
+ case ARGP_KEY_HELP_POST_DOC:
+ return xasprintf (text, program_name, GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME);
+ default:
+ return grub_install_help_filter (key, text, input);
+ }
+}
+
+#pragma GCC diagnostic error "-Wformat-nonliteral"
+
+/* TRANSLATORS: INSTALL_DEVICE isn't an identifier and is the DEVICE you
+ install to. */
+struct argp argp = {
+ options, argp_parser, N_("[OPTION] [INSTALL_DEVICE]"),
+ N_("Install GRUB on your drive.")"\v"
+ N_("INSTALL_DEVICE must be system device filename.\n"
+ "%s copies GRUB images into %s. On some platforms, it"
+ " may also install GRUB into the boot sector."),
+ NULL, help_filter, NULL
+};
+
+static int
+probe_raid_level (grub_disk_t disk)
+{
+ /* disk might be NULL in the case of a LVM physical volume with no LVM
+ signature. Ignore such cases here. */
+ if (!disk)
+ return -1;
+
+ if (disk->dev->id != GRUB_DISK_DEVICE_DISKFILTER_ID)
+ return -1;
+
+ if (disk->name[0] != 'm' || disk->name[1] != 'd')
+ return -1;
+
+ if (!((struct grub_diskfilter_lv *) disk->data)->segments)
+ return -1;
+ return ((struct grub_diskfilter_lv *) disk->data)->segments->type;
+}
+
+static void
+push_partmap_module (const char *map, void *data __attribute__ ((unused)))
+{
+ char buf[50];
+
+ if (strcmp (map, "openbsd") == 0 || strcmp (map, "netbsd") == 0)
+ {
+ grub_install_push_module ("part_bsd");
+ return;
+ }
+
+ snprintf (buf, sizeof (buf), "part_%s", map);
+ grub_install_push_module (buf);
+}
+
+static void
+push_cryptodisk_module (const char *mod, void *data __attribute__ ((unused)))
+{
+ grub_install_push_module (mod);
+}
+
+static void
+probe_mods (grub_disk_t disk)
+{
+ grub_partition_t part;
+ grub_disk_memberlist_t list = NULL, tmp;
+ int raid_level;
+
+ if (disk->partition == NULL)
+ grub_util_info ("no partition map found for %s", disk->name);
+
+ for (part = disk->partition; part; part = part->parent)
+ push_partmap_module (part->partmap->name, NULL);
+
+ if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID)
+ {
+ grub_diskfilter_get_partmap (disk, push_partmap_module, NULL);
+ have_abstractions = 1;
+ }
+
+ if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID
+ && (grub_memcmp (disk->name, "lvm/", sizeof ("lvm/") - 1) == 0 ||
+ grub_memcmp (disk->name, "lvmid/", sizeof ("lvmid/") - 1) == 0))
+ grub_install_push_module ("lvm");
+
+ if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID
+ && grub_memcmp (disk->name, "ldm/", sizeof ("ldm/") - 1) == 0)
+ grub_install_push_module ("ldm");
+
+ if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
+ {
+ grub_util_cryptodisk_get_abstraction (disk,
+ push_cryptodisk_module, NULL);
+ have_abstractions = 1;
+ have_cryptodisk = 1;
+ }
+
+ raid_level = probe_raid_level (disk);
+ if (raid_level >= 0)
+ {
+ grub_install_push_module ("diskfilter");
+ if (disk->dev->disk_raidname)
+ grub_install_push_module (disk->dev->disk_raidname (disk));
+ }
+ if (raid_level == 5)
+ grub_install_push_module ("raid5rec");
+ if (raid_level == 6)
+ grub_install_push_module ("raid6rec");
+
+ /* In case of LVM/RAID, check the member devices as well. */
+ if (disk->dev->disk_memberlist)
+ list = disk->dev->disk_memberlist (disk);
+ while (list)
+ {
+ probe_mods (list->disk);
+ tmp = list->next;
+ free (list);
+ list = tmp;
+ }
+}
+
+static int
+have_bootdev (enum grub_install_plat pl)
+{
+ switch (pl)
+ {
+ case GRUB_INSTALL_PLATFORM_I386_PC:
+ case GRUB_INSTALL_PLATFORM_I386_EFI:
+ case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+ case GRUB_INSTALL_PLATFORM_IA64_EFI:
+ case GRUB_INSTALL_PLATFORM_ARM_EFI:
+ case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+ case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI:
+ case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+ case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
+ case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
+ case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
+ case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
+ case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
+ case GRUB_INSTALL_PLATFORM_MIPS_ARC:
+ return 1;
+
+ case GRUB_INSTALL_PLATFORM_I386_QEMU:
+ case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
+ case GRUB_INSTALL_PLATFORM_ARM_COREBOOT:
+ case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
+ case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
+ case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
+
+ case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
+ case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
+
+ case GRUB_INSTALL_PLATFORM_I386_XEN:
+ case GRUB_INSTALL_PLATFORM_X86_64_XEN:
+ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
+ return 0;
+
+ /* pacify warning. */
+ case GRUB_INSTALL_PLATFORM_MAX:
+ return 0;
+ }
+ return 0;
+}
+
+static void
+probe_cryptodisk_uuid (grub_disk_t disk)
+{
+ grub_disk_memberlist_t list = NULL, tmp;
+
+ /* In case of LVM/RAID, check the member devices as well. */
+ if (disk->dev->disk_memberlist)
+ {
+ list = disk->dev->disk_memberlist (disk);
+ }
+ while (list)
+ {
+ probe_cryptodisk_uuid (list->disk);
+ tmp = list->next;
+ free (list);
+ list = tmp;
+ }
+ if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
+ {
+ const char *uuid = grub_util_cryptodisk_get_uuid (disk);
+ if (!load_cfg_f)
+ load_cfg_f = grub_util_fopen (load_cfg, "wb");
+ have_load_cfg = 1;
+
+ fprintf (load_cfg_f, "cryptomount -u %s\n",
+ uuid);
+ }
+}
+
+static int
+is_same_disk (const char *a, const char *b)
+{
+ while (1)
+ {
+ if ((*a == ',' || *a == '\0') && (*b == ',' || *b == '\0'))
+ return 1;
+ if (*a != *b)
+ return 0;
+ if (*a == '\\')
+ {
+ if (a[1] != b[1])
+ return 0;
+ a += 2;
+ b += 2;
+ continue;
+ }
+ a++;
+ b++;
+ }
+}
+
+static char *
+get_rndstr (void)
+{
+ grub_uint8_t rnd[15];
+ const size_t sz = sizeof (rnd) * GRUB_CHAR_BIT / 5;
+ char * ret = xmalloc (sz + 1);
+ size_t i;
+ if (grub_get_random (rnd, sizeof (rnd)))
+ grub_util_error ("%s", _("couldn't retrieve random data"));
+ for (i = 0; i < sz; i++)
+ {
+ grub_size_t b = i * 5;
+ grub_uint8_t r;
+ grub_size_t f1 = GRUB_CHAR_BIT - b % GRUB_CHAR_BIT;
+ grub_size_t f2;
+ if (f1 > 5)
+ f1 = 5;
+ f2 = 5 - f1;
+ r = (rnd[b / GRUB_CHAR_BIT] >> (b % GRUB_CHAR_BIT)) & ((1 << f1) - 1);
+ if (f2)
+ r |= (rnd[b / GRUB_CHAR_BIT + 1] & ((1 << f2) - 1)) << f1;
+ if (r < 10)
+ ret[i] = '0' + r;
+ else
+ ret[i] = 'a' + (r - 10);
+ }
+ ret[sz] = '\0';
+ return ret;
+}
+
+static char *
+escape (const char *in)
+{
+ char *ptr;
+ char *ret;
+ int overhead = 0;
+
+ for (ptr = (char*)in; *ptr; ptr++)
+ if (*ptr == '\'')
+ overhead += 3;
+ ret = grub_malloc (ptr - in + overhead + 1);
+ if (!ret)
+ return NULL;
+
+ grub_strchrsub (ret, in, '\'', "'\\''");
+ return ret;
+}
+
+static struct grub_util_config config;
+
+static void
+device_map_check_duplicates (const char *dev_map)
+{
+ FILE *fp;
+ char buf[1024]; /* XXX */
+ size_t alloced = 8;
+ size_t filled = 0;
+ char **d;
+ size_t i;
+
+ if (dev_map[0] == '\0')
+ return;
+
+ fp = grub_util_fopen (dev_map, "r");
+ if (! fp)
+ return;
+
+ d = xmalloc (alloced * sizeof (d[0]));
+
+ while (fgets (buf, sizeof (buf), fp))
+ {
+ char *p = buf;
+ char *e;
+
+ /* Skip leading spaces. */
+ while (*p && grub_isspace (*p))
+ p++;
+
+ /* If the first character is `#' or NUL, skip this line. */
+ if (*p == '\0' || *p == '#')
+ continue;
+
+ if (*p != '(')
+ continue;
+
+ p++;
+
+ e = p;
+ p = strchr (p, ')');
+ if (! p)
+ continue;
+
+ if (filled >= alloced)
+ {
+ alloced *= 2;
+ d = xrealloc (d, alloced * sizeof (d[0]));
+ }
+
+ *p = '\0';
+
+ d[filled++] = xstrdup (e);
+ }
+
+ fclose (fp);
+
+ qsort (d, filled, sizeof (d[0]), grub_qsort_strcmp);
+
+ for (i = 0; i + 1 < filled; i++)
+ if (strcmp (d[i], d[i+1]) == 0)
+ {
+ grub_util_error (_("the drive %s is defined multiple times in the device map %s"),
+ d[i], dev_map);
+ }
+
+ for (i = 0; i < filled; i++)
+ free (d[i]);
+
+ free (d);
+}
+
+static grub_err_t
+write_to_disk (grub_device_t dev, const char *fn)
+{
+ char *core_img;
+ size_t core_size;
+ grub_err_t err;
+
+ core_size = grub_util_get_image_size (fn);
+
+ core_img = grub_util_read_image (fn);
+
+ grub_util_info ("writing `%s' to `%s'", fn, dev->disk->name);
+ err = grub_disk_write (dev->disk, 0, 0,
+ core_size, core_img);
+ free (core_img);
+ return err;
+}
+
+static int
+is_prep_partition (grub_device_t dev)
+{
+ if (!dev->disk)
+ return 0;
+ if (!dev->disk->partition)
+ return 0;
+ if (strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
+ return (dev->disk->partition->msdostype == 0x41);
+
+ if (strcmp (dev->disk->partition->partmap->name, "gpt") == 0)
+ {
+ struct grub_gpt_partentry gptdata;
+ grub_partition_t p = dev->disk->partition;
+ int ret = 0;
+ dev->disk->partition = dev->disk->partition->parent;
+
+ if (grub_disk_read (dev->disk, p->offset, p->index,
+ sizeof (gptdata), &gptdata) == 0)
+ {
+ const grub_gpt_part_guid_t template = {
+ grub_cpu_to_le32_compile_time (0x9e1a2d38),
+ grub_cpu_to_le16_compile_time (0xc612),
+ grub_cpu_to_le16_compile_time (0x4316),
+ { 0xaa, 0x26, 0x8b, 0x49, 0x52, 0x1e, 0x5a, 0x8b }
+ };
+
+ ret = grub_memcmp (&template, &gptdata.type,
+ sizeof (template)) == 0;
+ }
+ dev->disk->partition = p;
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+is_prep_empty (grub_device_t dev)
+{
+ grub_disk_addr_t dsize, addr;
+ grub_uint32_t buffer[32768];
+
+ dsize = grub_disk_get_size (dev->disk);
+ for (addr = 0; addr < dsize;
+ addr += sizeof (buffer) / GRUB_DISK_SECTOR_SIZE)
+ {
+ grub_size_t sz = sizeof (buffer);
+ grub_uint32_t *ptr;
+
+ if (sizeof (buffer) / GRUB_DISK_SECTOR_SIZE > dsize - addr)
+ sz = (dsize - addr) * GRUB_DISK_SECTOR_SIZE;
+ grub_disk_read (dev->disk, addr, 0, sz, buffer);
+
+ if (addr == 0 && grub_memcmp (buffer, ELFMAG, SELFMAG) == 0)
+ return 1;
+
+ for (ptr = buffer; ptr < buffer + sz / sizeof (*buffer); ptr++)
+ if (*ptr)
+ return 0;
+ }
+
+ return 1;
+}
+
+static void
+bless (grub_device_t dev, const char *path, int x86)
+{
+ struct stat st;
+ grub_err_t err;
+
+ grub_util_info ("blessing %s", path);
+
+ if (stat (path, &st) < 0)
+ grub_util_error (N_("cannot stat `%s': %s"),
+ path, strerror (errno));
+
+ err = grub_mac_bless_inode (dev, st.st_ino, S_ISDIR (st.st_mode), x86);
+ if (err)
+ grub_util_error ("%s", grub_errmsg);
+ grub_util_info ("blessed");
+}
+
+static void
+fill_core_services (const char *core_services)
+{
+ char *label;
+ FILE *f;
+ char *label_text;
+ char *label_string = xasprintf ("%s %s", bootloader_id, product_version);
+ char *sysv_plist;
+
+ label = grub_util_path_concat (2, core_services, ".disk_label");
+ grub_util_info ("rendering label %s", label_string);
+ grub_util_render_label (label_font, label_bgcolor ? : "white",
+ label_color ? : "black", label_string, label);
+ grub_util_info ("label rendered");
+ free (label);
+ label_text = grub_util_path_concat (2, core_services, ".disk_label.contentDetails");
+ f = grub_util_fopen (label_text, "wb");
+ fprintf (f, "%s\n", label_string);
+ fclose (f);
+ free (label_string);
+ free (label_text);
+
+ sysv_plist = grub_util_path_concat (2, core_services, "SystemVersion.plist");
+ f = grub_util_fopen (sysv_plist, "wb");
+ fprintf (f,
+ "<plist version=\"1.0\">\n"
+ "<dict>\n"
+ " <key>ProductBuildVersion</key>\n"
+ " <string></string>\n"
+ " <key>ProductName</key>\n"
+ " <string>%s</string>\n"
+ " <key>ProductVersion</key>\n"
+ " <string>%s</string>\n"
+ "</dict>\n"
+ "</plist>\n", bootloader_id, product_version);
+ fclose (f);
+ free (sysv_plist);
+}
+
+int
+main (int argc, char *argv[])
+{
+ int is_efi = 0;
+ const char *efi_distributor = NULL;
+ const char *efi_file = NULL;
+ char **grub_devices;
+ grub_fs_t grub_fs;
+ grub_device_t grub_dev = NULL;
+ enum grub_install_plat platform;
+ char *grubdir, *device_map;
+ char **curdev, **curdrive;
+ char **grub_drives;
+ char *relative_grubdir;
+ char **efidir_device_names = NULL;
+ grub_device_t efidir_grub_dev = NULL;
+ char *efidir_grub_devname;
+ int efidir_is_mac = 0;
+ int is_prep = 0;
+ const char *pkgdatadir;
+
+ grub_util_host_init (&argc, &argv);
+ product_version = xstrdup (PACKAGE_VERSION);
+ pkgdatadir = grub_util_get_pkgdatadir ();
+ label_font = grub_util_path_concat (2, pkgdatadir, "unicode.pf2");
+
+ argp_parse (&argp, argc, argv, 0, 0, 0);
+
+ if (verbosity > 1)
+ grub_env_set ("debug", "all");
+
+ grub_util_load_config (&config);
+
+ if (!bootloader_id && config.grub_distributor)
+ {
+ char *ptr;
+ bootloader_id = xstrdup (config.grub_distributor);
+ for (ptr = bootloader_id; *ptr && *ptr != ' '; ptr++)
+ if (*ptr >= 'A' && *ptr <= 'Z')
+ *ptr = *ptr - 'A' + 'a';
+ *ptr = '\0';
+ }
+ if (!bootloader_id || bootloader_id[0] == '\0')
+ {
+ free (bootloader_id);
+ bootloader_id = xstrdup ("grub");
+ }
+
+ if (!grub_install_source_directory)
+ {
+ if (!target)
+ {
+ const char * t;
+ t = get_default_platform ();
+ if (!t)
+ grub_util_error ("%s",
+ _("Unable to determine your platform."
+ " Use --target.")
+ );
+ target = xstrdup (t);
+ }
+ grub_install_source_directory
+ = grub_util_path_concat (2, grub_util_get_pkglibdir (), target);
+ }
+
+ platform = grub_install_get_target (grub_install_source_directory);
+
+ {
+ char *platname = grub_install_get_platform_name (platform);
+ fprintf (stderr, _("Installing for %s platform.\n"), platname);
+ free (platname);
+ }
+
+ switch (platform)
+ {
+ case GRUB_INSTALL_PLATFORM_I386_PC:
+ if (!disk_module)
+ disk_module = xstrdup ("biosdisk");
+ break;
+ case GRUB_INSTALL_PLATFORM_I386_EFI:
+ case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+ case GRUB_INSTALL_PLATFORM_ARM_EFI:
+ case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+ case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI:
+ case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+ case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
+ case GRUB_INSTALL_PLATFORM_IA64_EFI:
+ case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
+ case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
+ case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
+ case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
+ case GRUB_INSTALL_PLATFORM_MIPS_ARC:
+ case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
+ case GRUB_INSTALL_PLATFORM_I386_XEN:
+ case GRUB_INSTALL_PLATFORM_X86_64_XEN:
+ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
+ break;
+
+ case GRUB_INSTALL_PLATFORM_I386_QEMU:
+ case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
+ case GRUB_INSTALL_PLATFORM_ARM_COREBOOT:
+ case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
+ case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
+ case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
+ case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
+ disk_module = xstrdup ("native");
+ break;
+
+ /* pacify warning. */
+ case GRUB_INSTALL_PLATFORM_MAX:
+ break;
+ }
+
+ switch (platform)
+ {
+ case GRUB_INSTALL_PLATFORM_I386_PC:
+ case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
+ if (!install_device)
+ grub_util_error ("%s", _("install device isn't specified"));
+ break;
+ case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
+ if (install_device)
+ is_prep = 1;
+ break;
+ case GRUB_INSTALL_PLATFORM_MIPS_ARC:
+ case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
+ break;
+ case GRUB_INSTALL_PLATFORM_I386_EFI:
+ case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+ case GRUB_INSTALL_PLATFORM_ARM_EFI:
+ case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+ case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI:
+ case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+ case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
+ case GRUB_INSTALL_PLATFORM_IA64_EFI:
+ case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
+ case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
+ case GRUB_INSTALL_PLATFORM_I386_QEMU:
+ case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
+ case GRUB_INSTALL_PLATFORM_ARM_COREBOOT:
+ case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
+ case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
+ case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
+ case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
+ case GRUB_INSTALL_PLATFORM_I386_XEN:
+ case GRUB_INSTALL_PLATFORM_X86_64_XEN:
+ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
+ free (install_device);
+ install_device = NULL;
+ break;
+
+ /* pacify warning. */
+ case GRUB_INSTALL_PLATFORM_MAX:
+ break;
+ }
+
+ if (!bootdir)
+ bootdir = grub_util_path_concat (3, "/", rootdir, GRUB_BOOT_DIR_NAME);
+
+ {
+ char * t = grub_util_path_concat (2, bootdir, GRUB_DIR_NAME);
+ grub_install_mkdir_p (t);
+ grubdir = grub_canonicalize_file_name (t);
+ if (!grubdir)
+ grub_util_error (_("failed to get canonical path of `%s'"), t);
+ free (t);
+ }
+ device_map = grub_util_path_concat (2, grubdir, "device.map");
+
+ if (recheck)
+ grub_util_unlink (device_map);
+
+ device_map_check_duplicates (device_map);
+ grub_util_biosdisk_init (device_map);
+
+ /* Initialize all modules. */
+ grub_init_all ();
+ grub_gcry_init_all ();
+ grub_hostfs_init ();
+ grub_host_init ();
+
+ switch (platform)
+ {
+ case GRUB_INSTALL_PLATFORM_I386_EFI:
+ case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+ case GRUB_INSTALL_PLATFORM_ARM_EFI:
+ case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+ case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI:
+ case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+ case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
+ case GRUB_INSTALL_PLATFORM_IA64_EFI:
+ is_efi = 1;
+ break;
+ default:
+ is_efi = 0;
+ break;
+
+ /* pacify warning. */
+ case GRUB_INSTALL_PLATFORM_MAX:
+ break;
+ }
+
+ /* Find the EFI System Partition. */
+
+ if (is_efi)
+ {
+ grub_fs_t fs;
+ free (install_device);
+ install_device = NULL;
+ if (!efidir)
+ {
+ char *d = grub_util_path_concat (2, bootdir, "efi");
+ char *dr = NULL;
+ if (!grub_util_is_directory (d))
+ {
+ free (d);
+ d = grub_util_path_concat (2, bootdir, "EFI");
+ }
+ /*
+ The EFI System Partition may have been given directly using
+ --root-directory.
+ */
+ if (!grub_util_is_directory (d)
+ && rootdir && grub_strcmp (rootdir, "/") != 0)
+ {
+ free (d);
+ d = xstrdup (rootdir);
+ }
+ if (grub_util_is_directory (d))
+ dr = grub_make_system_path_relative_to_its_root (d);
+ /* Is it a mount point? */
+ if (dr && dr[0] == '\0')
+ efidir = d;
+ else
+ free (d);
+ free (dr);
+ }
+ if (!efidir)
+ grub_util_error ("%s", _("cannot find EFI directory"));
+ efidir_device_names = grub_guess_root_devices (efidir);
+ if (!efidir_device_names || !efidir_device_names[0])
+ grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),
+ efidir);
+ install_device = efidir_device_names[0];
+
+ for (curdev = efidir_device_names; *curdev; curdev++)
+ grub_util_pull_device (*curdev);
+
+ efidir_grub_devname = grub_util_get_grub_dev (efidir_device_names[0]);
+ if (!efidir_grub_devname)
+ grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"),
+ efidir_device_names[0]);
+
+ efidir_grub_dev = grub_device_open (efidir_grub_devname);
+ if (! efidir_grub_dev)
+ grub_util_error ("%s", grub_errmsg);
+
+ fs = grub_fs_probe (efidir_grub_dev);
+ if (! fs)
+ grub_util_error ("%s", grub_errmsg);
+
+ efidir_is_mac = 0;
+
+ if (grub_strcmp (fs->name, "hfs") == 0
+ || grub_strcmp (fs->name, "hfsplus") == 0)
+ efidir_is_mac = 1;
+
+ if (!efidir_is_mac && grub_strcmp (fs->name, "fat") != 0)
+ grub_util_error (_("%s doesn't look like an EFI partition"), efidir);
+
+ /* The EFI specification requires that an EFI System Partition must
+ contain an "EFI" subdirectory, and that OS loaders are stored in
+ subdirectories below EFI. Vendors are expected to pick names that do
+ not collide with other vendors. To minimise collisions, we use the
+ name of our distributor if possible.
+ */
+ char *t;
+ efi_distributor = bootloader_id;
+ if (removable)
+ {
+ /* The specification makes stricter requirements of removable
+ devices, in order that only one image can be automatically loaded
+ from them. The image must always reside under /EFI/BOOT, and it
+ must have a specific file name depending on the architecture.
+ */
+ efi_distributor = "BOOT";
+ switch (platform)
+ {
+ case GRUB_INSTALL_PLATFORM_I386_EFI:
+ efi_file = "BOOTIA32.EFI";
+ break;
+ case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+ efi_file = "BOOTX64.EFI";
+ break;
+ case GRUB_INSTALL_PLATFORM_IA64_EFI:
+ efi_file = "BOOTIA64.EFI";
+ break;
+ case GRUB_INSTALL_PLATFORM_ARM_EFI:
+ efi_file = "BOOTARM.EFI";
+ break;
+ case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+ efi_file = "BOOTAA64.EFI";
+ break;
+ case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI:
+ efi_file = "BOOTMIPS64EL.EFI";
+ break;
+ case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+ efi_file = "BOOTRISCV32.EFI";
+ break;
+ case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
+ efi_file = "BOOTRISCV64.EFI";
+ break;
+ default:
+ grub_util_error ("%s", _("You've found a bug"));
+ break;
+ }
+ }
+ else
+ {
+ /* It is convenient for each architecture to have a different
+ efi_file, so that different versions can be installed in parallel.
+ */
+ switch (platform)
+ {
+ case GRUB_INSTALL_PLATFORM_I386_EFI:
+ efi_file = "grubia32.efi";
+ break;
+ case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+ efi_file = "grubx64.efi";
+ break;
+ case GRUB_INSTALL_PLATFORM_IA64_EFI:
+ efi_file = "grubia64.efi";
+ break;
+ case GRUB_INSTALL_PLATFORM_ARM_EFI:
+ efi_file = "grubarm.efi";
+ break;
+ case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+ efi_file = "grubaa64.efi";
+ break;
+ case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI:
+ efi_file = "grubmips64el.efi";
+ case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+ efi_file = "grubriscv32.efi";
+ break;
+ case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
+ efi_file = "grubriscv64.efi";
+ break;
+ default:
+ efi_file = "grub.efi";
+ break;
+ }
+ }
+ t = grub_util_path_concat (3, efidir, "EFI", efi_distributor);
+ free (efidir);
+ efidir = t;
+ grub_install_mkdir_p (efidir);
+ }
+
+ if (platform == GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275)
+ {
+ int is_guess = 0;
+ if (!macppcdir)
+ {
+ char *d;
+
+ is_guess = 1;
+ d = grub_util_path_concat (2, bootdir, "macppc");
+ if (!grub_util_is_directory (d))
+ {
+ free (d);
+ d = grub_util_path_concat (2, bootdir, "efi");
+ }
+ /* Find the Mac HFS(+) System Partition. */
+ if (!grub_util_is_directory (d))
+ {
+ free (d);
+ d = grub_util_path_concat (2, bootdir, "EFI");
+ }
+ if (!grub_util_is_directory (d))
+ {
+ free (d);
+ d = 0;
+ }
+ if (d)
+ macppcdir = d;
+ }
+ if (macppcdir)
+ {
+ char **macppcdir_device_names = NULL;
+ grub_device_t macppcdir_grub_dev = NULL;
+ char *macppcdir_grub_devname;
+ grub_fs_t fs;
+
+ macppcdir_device_names = grub_guess_root_devices (macppcdir);
+ if (!macppcdir_device_names || !macppcdir_device_names[0])
+ grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),
+ macppcdir);
+
+ for (curdev = macppcdir_device_names; *curdev; curdev++)
+ grub_util_pull_device (*curdev);
+
+ macppcdir_grub_devname = grub_util_get_grub_dev (macppcdir_device_names[0]);
+ if (!macppcdir_grub_devname)
+ grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"),
+ macppcdir_device_names[0]);
+
+ macppcdir_grub_dev = grub_device_open (macppcdir_grub_devname);
+ if (! macppcdir_grub_dev)
+ grub_util_error ("%s", grub_errmsg);
+
+ fs = grub_fs_probe (macppcdir_grub_dev);
+ if (! fs)
+ grub_util_error ("%s", grub_errmsg);
+
+ if (grub_strcmp (fs->name, "hfs") != 0
+ && grub_strcmp (fs->name, "hfsplus") != 0
+ && !is_guess)
+ grub_util_error (_("filesystem on %s is neither HFS nor HFS+"),
+ macppcdir);
+ if (grub_strcmp (fs->name, "hfs") == 0
+ || grub_strcmp (fs->name, "hfsplus") == 0)
+ {
+ install_device = macppcdir_device_names[0];
+ is_prep = 0;
+ }
+ }
+ }
+
+ grub_install_copy_files (grub_install_source_directory,
+ grubdir, platform);
+
+ char *envfile = grub_util_path_concat (2, grubdir, "grubenv");
+ if (!grub_util_is_regular (envfile))
+ grub_util_create_envblk_file (envfile);
+
+ size_t ndev = 0;
+
+ /* Write device to a variable so we don't have to traverse /dev every time. */
+ grub_devices = grub_guess_root_devices (grubdir);
+ if (!grub_devices || !grub_devices[0])
+ grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),
+ grubdir);
+
+ for (curdev = grub_devices; *curdev; curdev++)
+ {
+ grub_util_pull_device (*curdev);
+ ndev++;
+ }
+
+ grub_drives = xmalloc (sizeof (grub_drives[0]) * (ndev + 1));
+
+ for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++,
+ curdrive++)
+ {
+ *curdrive = grub_util_get_grub_dev (*curdev);
+ if (! *curdrive)
+ grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"),
+ *curdev);
+ }
+ *curdrive = 0;
+
+ grub_dev = grub_device_open (grub_drives[0]);
+ if (! grub_dev)
+ grub_util_error ("%s", grub_errmsg);
+
+ grub_fs = grub_fs_probe (grub_dev);
+ if (! grub_fs)
+ grub_util_error ("%s", grub_errmsg);
+
+ grub_install_push_module (grub_fs->name);
+
+ if (grub_dev->disk)
+ probe_mods (grub_dev->disk);
+
+ for (curdrive = grub_drives + 1; *curdrive; curdrive++)
+ {
+ grub_device_t dev = grub_device_open (*curdrive);
+ if (!dev)
+ continue;
+ if (dev->disk)
+ probe_mods (dev->disk);
+ grub_device_close (dev);
+ }
+
+ if (!config.is_cryptodisk_enabled && have_cryptodisk)
+ grub_util_error (_("attempt to install to encrypted disk without cryptodisk enabled. "
+ "Set `%s' in file `%s'"), "GRUB_ENABLE_CRYPTODISK=y",
+ grub_util_get_config_filename ());
+
+ if (disk_module && grub_strcmp (disk_module, "ata") == 0)
+ grub_install_push_module ("pata");
+ else if (disk_module && grub_strcmp (disk_module, "native") == 0)
+ {
+ grub_install_push_module ("pata");
+ grub_install_push_module ("ahci");
+ grub_install_push_module ("ohci");
+ grub_install_push_module ("uhci");
+ grub_install_push_module ("ehci");
+ grub_install_push_module ("usbms");
+ }
+ else if (disk_module && disk_module[0])
+ grub_install_push_module (disk_module);
+
+ relative_grubdir = grub_make_system_path_relative_to_its_root (grubdir);
+ if (relative_grubdir[0] == '\0')
+ {
+ free (relative_grubdir);
+ relative_grubdir = xstrdup ("/");
+ }
+
+ char *platname = grub_install_get_platform_name (platform);
+ char *platdir;
+ {
+ char *t = grub_util_path_concat (2, grubdir,
+ platname);
+ platdir = grub_canonicalize_file_name (t);
+ if (!platdir)
+ grub_util_error (_("failed to get canonical path of `%s'"),
+ t);
+ free (t);
+ }
+ load_cfg = grub_util_path_concat (2, platdir,
+ "load.cfg");
+
+ grub_util_unlink (load_cfg);
+
+ if (debug_image && debug_image[0])
+ {
+ load_cfg_f = grub_util_fopen (load_cfg, "wb");
+ have_load_cfg = 1;
+ fprintf (load_cfg_f, "set debug='%s'\n",
+ debug_image);
+ }
+ char *prefix_drive = NULL;
+ char *install_drive = NULL;
+
+ if (install_device)
+ {
+ if (install_device[0] == '('
+ && install_device[grub_strlen (install_device) - 1] == ')')
+ {
+ size_t len = grub_strlen (install_device) - 2;
+ install_drive = xmalloc (len + 1);
+ memcpy (install_drive, install_device + 1, len);
+ install_drive[len] = '\0';
+ }
+ else
+ {
+ grub_util_pull_device (install_device);
+ install_drive = grub_util_get_grub_dev (install_device);
+ if (!install_drive)
+ grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"),
+ install_device);
+ }
+ }
+
+ if (!have_abstractions)
+ {
+ if ((disk_module && grub_strcmp (disk_module, "biosdisk") != 0)
+ || grub_drives[1]
+ || (!install_drive
+ && platform != GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275)
+ || (install_drive && !is_same_disk (grub_drives[0], install_drive))
+ || !have_bootdev (platform))
+ {
+ char *uuid = NULL;
+ /* generic method (used on coreboot and ata mod). */
+ if (!force_file_id
+ && grub_fs->fs_uuid && grub_fs->fs_uuid (grub_dev, &uuid))
+ {
+ grub_print_error ();
+ grub_errno = 0;
+ uuid = NULL;
+ }
+
+ if (!load_cfg_f)
+ load_cfg_f = grub_util_fopen (load_cfg, "wb");
+ have_load_cfg = 1;
+ if (uuid)
+ {
+ fprintf (load_cfg_f, "search.fs_uuid %s root ",
+ uuid);
+ grub_install_push_module ("search_fs_uuid");
+ }
+ else
+ {
+ char *rndstr = get_rndstr ();
+ char *fl = grub_util_path_concat (3, grubdir,
+ "uuid", rndstr);
+ char *fldir = grub_util_path_concat (2, grubdir,
+ "uuid");
+ char *relfl;
+ FILE *flf;
+ grub_install_mkdir_p (fldir);
+ flf = grub_util_fopen (fl, "w");
+ if (!flf)
+ grub_util_error (_("Can't create file: %s"), strerror (errno));
+ fclose (flf);
+ relfl = grub_make_system_path_relative_to_its_root (fl);
+ fprintf (load_cfg_f, "search.file %s root ",
+ relfl);
+ grub_install_push_module ("search_fs_file");
+ }
+ for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++,
+ curdrive++)
+ {
+ const char *map;
+ char *g = NULL;
+ grub_device_t dev;
+ if (curdrive == grub_drives)
+ dev = grub_dev;
+ else
+ dev = grub_device_open (*curdrive);
+ if (!dev)
+ continue;
+
+ if (dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID)
+ {
+ grub_util_fprint_full_disk_name (load_cfg_f,
+ dev->disk->name,
+ dev);
+ fprintf (load_cfg_f, " ");
+ if (dev != grub_dev)
+ grub_device_close (dev);
+ continue;
+ }
+
+ map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+
+ if (map)
+ {
+ grub_util_fprint_full_disk_name (load_cfg_f, map, dev);
+ fprintf (load_cfg_f, " ");
+ }
+
+
+ if (disk_module && disk_module[0]
+ && grub_strcmp (disk_module, "biosdisk") != 0)
+ g = grub_util_guess_baremetal_drive (*curdev);
+ else
+ switch (platform)
+ {
+ case GRUB_INSTALL_PLATFORM_I386_PC:
+ g = grub_util_guess_bios_drive (*curdev);
+ break;
+ case GRUB_INSTALL_PLATFORM_I386_EFI:
+ case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+ case GRUB_INSTALL_PLATFORM_ARM_EFI:
+ case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+ case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI:
+ case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+ case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
+ case GRUB_INSTALL_PLATFORM_IA64_EFI:
+ g = grub_util_guess_efi_drive (*curdev);
+ break;
+ case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
+ case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
+ case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
+ {
+ const char * ofpath = grub_util_devname_to_ofpath (*curdev);
+ g = xasprintf ("ieee1275/%s", ofpath);
+ break;
+ }
+ case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
+ case GRUB_INSTALL_PLATFORM_I386_QEMU:
+ case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
+ case GRUB_INSTALL_PLATFORM_ARM_COREBOOT:
+ case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
+ case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
+ case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
+ g = grub_util_guess_baremetal_drive (*curdev);
+ break;
+ case GRUB_INSTALL_PLATFORM_MIPS_ARC:
+ case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
+ case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
+ case GRUB_INSTALL_PLATFORM_I386_XEN:
+ case GRUB_INSTALL_PLATFORM_X86_64_XEN:
+ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
+ grub_util_warn ("%s", _("no hints available for your platform. Expect reduced performance"));
+ break;
+ /* pacify warning. */
+ case GRUB_INSTALL_PLATFORM_MAX:
+ break;
+ }
+ if (g)
+ {
+ grub_util_fprint_full_disk_name (load_cfg_f, g, dev);
+ fprintf (load_cfg_f, " ");
+ free (g);
+ }
+ if (dev != grub_dev)
+ grub_device_close (dev);
+ }
+ fprintf (load_cfg_f, "\n");
+ char *escaped_relpath = escape (relative_grubdir);
+ fprintf (load_cfg_f, "set prefix=($root)'%s'\n",
+ escaped_relpath);
+ }
+ else
+ {
+ /* We need to hardcode the partition number in the core image's prefix. */
+ char *p;
+ for (p = grub_drives[0]; *p; )
+ {
+ if (*p == '\\' && p[1])
+ {
+ p += 2;
+ continue;
+ }
+ if (*p == ',' || *p == '\0')
+ break;
+ p++;
+ }
+ prefix_drive = xasprintf ("(%s)", p);
+ }
+ }
+ else
+ {
+ if (config.is_cryptodisk_enabled)
+ {
+ if (grub_dev->disk)
+ probe_cryptodisk_uuid (grub_dev->disk);
+
+ for (curdrive = grub_drives + 1; *curdrive; curdrive++)
+ {
+ grub_device_t dev = grub_device_open (*curdrive);
+ if (!dev)
+ continue;
+ if (dev->disk)
+ probe_cryptodisk_uuid (dev->disk);
+ grub_device_close (dev);
+ }
+ }
+ prefix_drive = xasprintf ("(%s)", grub_drives[0]);
+ }
+
+ char mkimage_target[200];
+ const char *core_name = NULL;
+
+ switch (platform)
+ {
+ case GRUB_INSTALL_PLATFORM_I386_EFI:
+ case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+ case GRUB_INSTALL_PLATFORM_ARM_EFI:
+ case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+ case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI:
+ case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+ case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
+ case GRUB_INSTALL_PLATFORM_IA64_EFI:
+ core_name = "core.efi";
+ snprintf (mkimage_target, sizeof (mkimage_target),
+ "%s-%s",
+ grub_install_get_platform_cpu (platform),
+ grub_install_get_platform_platform (platform));
+ break;
+ case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
+ case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
+ case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
+ core_name = "core.elf";
+ snprintf (mkimage_target, sizeof (mkimage_target),
+ "%s-%s-elf",
+ grub_install_get_platform_cpu (platform),
+ grub_install_get_platform_platform (platform));
+ break;
+
+ case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
+ case GRUB_INSTALL_PLATFORM_ARM_COREBOOT:
+ case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
+ case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
+ case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
+ case GRUB_INSTALL_PLATFORM_I386_XEN:
+ case GRUB_INSTALL_PLATFORM_X86_64_XEN:
+ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
+ core_name = "core.elf";
+ snprintf (mkimage_target, sizeof (mkimage_target),
+ "%s-%s",
+ grub_install_get_platform_cpu (platform),
+ grub_install_get_platform_platform (platform));
+ break;
+
+
+ case GRUB_INSTALL_PLATFORM_I386_PC:
+ case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
+ case GRUB_INSTALL_PLATFORM_MIPS_ARC:
+ case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
+ case GRUB_INSTALL_PLATFORM_I386_QEMU:
+ snprintf (mkimage_target, sizeof (mkimage_target),
+ "%s-%s",
+ grub_install_get_platform_cpu (platform),
+ grub_install_get_platform_platform (platform));
+ core_name = "core.img";
+ break;
+ case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
+ strcpy (mkimage_target, "sparc64-ieee1275-raw");
+ core_name = "core.img";
+ break;
+ /* pacify warning. */
+ case GRUB_INSTALL_PLATFORM_MAX:
+ break;
+ }
+
+ if (!core_name)
+ grub_util_error ("%s", _("You've found a bug"));
+
+ if (load_cfg_f)
+ fclose (load_cfg_f);
+
+ char *imgfile = grub_util_path_concat (2, platdir,
+ core_name);
+ char *prefix = xasprintf ("%s%s", prefix_drive ? : "",
+ relative_grubdir);
+ grub_install_make_image_wrap (/* source dir */ grub_install_source_directory,
+ /*prefix */ prefix,
+ /* output */ imgfile,
+ /* memdisk */ NULL,
+ have_load_cfg ? load_cfg : NULL,
+ /* image target */ mkimage_target, 0);
+ /* Backward-compatibility kludges. */
+ switch (platform)
+ {
+ case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
+ {
+ char *dst = grub_util_path_concat (2, bootdir, "grub.elf");
+ grub_install_copy_file (imgfile, dst, 1);
+ free (dst);
+ }
+ break;
+
+ case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
+ case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
+ {
+ char *dst = grub_util_path_concat (2, grubdir, "grub");
+ grub_install_copy_file (imgfile, dst, 1);
+ free (dst);
+ }
+ break;
+
+ case GRUB_INSTALL_PLATFORM_I386_EFI:
+ case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+ {
+ char *dst = grub_util_path_concat (2, platdir, "grub.efi");
+ grub_install_make_image_wrap (/* source dir */ grub_install_source_directory,
+ /* prefix */ "",
+ /* output */ dst,
+ /* memdisk */ NULL,
+ have_load_cfg ? load_cfg : NULL,
+ /* image target */ mkimage_target, 0);
+ }
+ break;
+ case GRUB_INSTALL_PLATFORM_ARM_EFI:
+ case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+ case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI:
+ case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+ case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
+ case GRUB_INSTALL_PLATFORM_IA64_EFI:
+ case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
+ case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
+ case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
+ case GRUB_INSTALL_PLATFORM_ARM_COREBOOT:
+ case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
+ case GRUB_INSTALL_PLATFORM_I386_PC:
+ case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
+ case GRUB_INSTALL_PLATFORM_MIPS_ARC:
+ case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
+ case GRUB_INSTALL_PLATFORM_I386_QEMU:
+ case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
+ case GRUB_INSTALL_PLATFORM_I386_XEN:
+ case GRUB_INSTALL_PLATFORM_X86_64_XEN:
+ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
+ break;
+ /* pacify warning. */
+ case GRUB_INSTALL_PLATFORM_MAX:
+ break;
+ }
+
+ /* Perform the platform-dependent install */
+
+ switch (platform)
+ {
+ case GRUB_INSTALL_PLATFORM_I386_PC:
+ {
+ char *boot_img_src = grub_util_path_concat (2,
+ grub_install_source_directory,
+ "boot.img");
+ char *boot_img = grub_util_path_concat (2, platdir,
+ "boot.img");
+ grub_install_copy_file (boot_img_src, boot_img, 1);
+
+ grub_util_info ("%sgrub-bios-setup %s %s %s %s %s --directory='%s' --device-map='%s' '%s'",
+ /* TRANSLATORS: This is a prefix in the log to indicate that usually
+ a command would be executed but due to an option was skipped. */
+ install_bootsector ? "" : _("NOT RUNNING: "),
+ allow_floppy ? "--allow-floppy " : "",
+ verbosity ? "--verbose " : "",
+ force ? "--force " : "",
+ !fs_probe ? "--skip-fs-probe" : "",
+ !add_rs_codes ? "--no-rs-codes" : "",
+ platdir,
+ device_map,
+ install_device);
+
+ /* Now perform the installation. */
+ if (install_bootsector)
+ grub_util_bios_setup (platdir, "boot.img", "core.img",
+ install_drive, force,
+ fs_probe, allow_floppy, add_rs_codes);
+ break;
+ }
+ case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
+ {
+ char *boot_img_src = grub_util_path_concat (2,
+ grub_install_source_directory,
+ "boot.img");
+ char *boot_img = grub_util_path_concat (2, platdir,
+ "boot.img");
+ grub_install_copy_file (boot_img_src, boot_img, 1);
+
+ grub_util_info ("%sgrub-sparc64-setup %s %s %s %s --directory='%s' --device-map='%s' '%s'",
+ install_bootsector ? "" : "NOT RUNNING: ",
+ allow_floppy ? "--allow-floppy " : "",
+ verbosity ? "--verbose " : "",
+ force ? "--force " : "",
+ !fs_probe ? "--skip-fs-probe" : "",
+ platdir,
+ device_map,
+ install_drive);
+
+ /* Now perform the installation. */
+ if (install_bootsector)
+ grub_util_sparc_setup (platdir, "boot.img", "core.img",
+ install_drive, force,
+ fs_probe, allow_floppy,
+ 0 /* unused */ );
+ break;
+ }
+
+ case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
+ if (macppcdir)
+ {
+ char *core_services = grub_util_path_concat (4, macppcdir,
+ "System", "Library",
+ "CoreServices");
+ char *mach_kernel = grub_util_path_concat (2, macppcdir,
+ "mach_kernel");
+ char *grub_elf, *bootx;
+ FILE *f;
+ grub_device_t ins_dev;
+ char *grub_chrp = grub_util_path_concat (2,
+ grub_install_source_directory,
+ "grub.chrp");
+
+ grub_install_mkdir_p (core_services);
+
+ bootx = grub_util_path_concat (2, core_services, "BootX");
+ grub_install_copy_file (grub_chrp, bootx, 1);
+
+ grub_elf = grub_util_path_concat (2, core_services, "grub.elf");
+ grub_install_copy_file (imgfile, grub_elf, 1);
+
+ f = grub_util_fopen (mach_kernel, "a+");
+ if (!f)
+ grub_util_error (_("Can't create file: %s"), strerror (errno));
+ fclose (f);
+
+ fill_core_services (core_services);
+
+ ins_dev = grub_device_open (install_drive);
+
+ bless (ins_dev, core_services, 0);
+
+ if (update_nvram)
+ {
+ const char *dev;
+ int partno;
+
+ partno = ins_dev->disk->partition
+ ? ins_dev->disk->partition->number + 1 : 0;
+ dev = grub_util_get_os_disk (install_device);
+ grub_install_register_ieee1275 (0, dev, partno,
+ "\\\\BootX");
+ }
+ grub_device_close (ins_dev);
+ free (grub_elf);
+ free (bootx);
+ free (mach_kernel);
+ free (grub_chrp);
+ break;
+ }
+ /* If a install device is defined, copy the core.elf to PReP partition. */
+ if (is_prep && install_device && install_device[0])
+ {
+ grub_device_t ins_dev;
+ ins_dev = grub_device_open (install_drive);
+ if (!ins_dev || !is_prep_partition (ins_dev))
+ {
+ grub_util_error ("%s", _("the chosen partition is not a PReP partition"));
+ }
+ if (is_prep_empty (ins_dev))
+ {
+ if (write_to_disk (ins_dev, imgfile))
+ grub_util_error ("%s", _("failed to copy Grub to the PReP partition"));
+ }
+ else
+ {
+ char *s = xasprintf ("dd if=/dev/zero of=%s", install_device);
+ grub_util_error (_("the PReP partition is not empty. If you are sure you want to use it, run dd to clear it: `%s'"),
+ s);
+ }
+ grub_device_close (ins_dev);
+ if (update_nvram)
+ grub_install_register_ieee1275 (1, grub_util_get_os_disk (install_device),
+ 0, NULL);
+ break;
+ }
+ /* fallthrough. */
+ case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
+ if (update_nvram)
+ {
+ const char *dev;
+ char *relpath;
+ int partno;
+ relpath = grub_make_system_path_relative_to_its_root (imgfile);
+ partno = grub_dev->disk->partition
+ ? grub_dev->disk->partition->number + 1 : 0;
+ dev = grub_util_get_os_disk (grub_devices[0]);
+ grub_install_register_ieee1275 (0, dev,
+ partno, relpath);
+ }
+ break;
+ case GRUB_INSTALL_PLATFORM_MIPS_ARC:
+ grub_install_sgi_setup (install_device, imgfile, "grub");
+ break;
+
+ case GRUB_INSTALL_PLATFORM_I386_EFI:
+ if (!efidir_is_mac)
+ {
+ char *dst = grub_util_path_concat (2, efidir, "grub.efi");
+ /* For old macs. Suggested by Peter Jones. */
+ grub_install_copy_file (imgfile, dst, 1);
+ free (dst);
+ }
+ /* Fallthrough. */
+ case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+ if (efidir_is_mac)
+ {
+ char *boot_efi;
+ char *core_services = grub_util_path_concat (4, efidir,
+ "System", "Library",
+ "CoreServices");
+ char *mach_kernel = grub_util_path_concat (2, efidir,
+ "mach_kernel");
+ FILE *f;
+ grub_device_t ins_dev;
+
+ grub_install_mkdir_p (core_services);
+
+ boot_efi = grub_util_path_concat (2, core_services, "boot.efi");
+ grub_install_copy_file (imgfile, boot_efi, 1);
+
+ f = grub_util_fopen (mach_kernel, "r+");
+ if (!f)
+ grub_util_error (_("Can't create file: %s"), strerror (errno));
+ fclose (f);
+
+ fill_core_services(core_services);
+
+ ins_dev = grub_device_open (install_drive);
+
+ bless (ins_dev, boot_efi, 1);
+ if (!removable && update_nvram)
+ {
+ /* Try to make this image bootable using the EFI Boot Manager, if available. */
+ int ret;
+ ret = grub_install_register_efi (efidir_grub_dev,
+ "\\System\\Library\\CoreServices",
+ efi_distributor);
+ if (ret)
+ grub_util_error (_("efibootmgr failed to register the boot entry: %s"),
+ strerror (ret));
+ }
+
+ grub_device_close (ins_dev);
+ free (boot_efi);
+ free (mach_kernel);
+ break;
+ }
+ /* FALLTHROUGH */
+ case GRUB_INSTALL_PLATFORM_ARM_EFI:
+ case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+ case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI:
+ case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+ case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
+ case GRUB_INSTALL_PLATFORM_IA64_EFI:
+ {
+ char *dst = grub_util_path_concat (2, efidir, efi_file);
+ grub_install_copy_file (imgfile, dst, 1);
+ free (dst);
+ }
+ if (!removable && update_nvram)
+ {
+ char * efifile_path;
+ char * part;
+ int ret;
+
+ /* Try to make this image bootable using the EFI Boot Manager, if available. */
+ if (!efi_distributor || efi_distributor[0] == '\0')
+ grub_util_error ("%s", _("EFI bootloader id isn't specified."));
+ efifile_path = xasprintf ("\\EFI\\%s\\%s",
+ efi_distributor,
+ efi_file);
+ part = (efidir_grub_dev->disk->partition
+ ? grub_partition_get_name (efidir_grub_dev->disk->partition)
+ : 0);
+ grub_util_info ("Registering with EFI: distributor = `%s',"
+ " path = `%s', ESP at %s%s%s",
+ efi_distributor, efifile_path,
+ efidir_grub_dev->disk->name,
+ (part ? ",": ""), (part ? : ""));
+ grub_free (part);
+ ret = grub_install_register_efi (efidir_grub_dev,
+ efifile_path, efi_distributor);
+ if (ret)
+ grub_util_error (_("efibootmgr failed to register the boot entry: %s"),
+ strerror (ret));
+ }
+ break;
+
+ case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
+ case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
+ case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
+ case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
+ case GRUB_INSTALL_PLATFORM_ARM_COREBOOT:
+ case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
+ case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
+ case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
+ case GRUB_INSTALL_PLATFORM_I386_QEMU:
+ case GRUB_INSTALL_PLATFORM_I386_XEN:
+ case GRUB_INSTALL_PLATFORM_X86_64_XEN:
+ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
+ grub_util_warn ("%s",
+ _("WARNING: no platform-specific install was performed"));
+ break;
+ /* pacify warning. */
+ case GRUB_INSTALL_PLATFORM_MAX:
+ break;
+ }
+
+ fprintf (stderr, "%s\n", _("Installation finished. No error reported."));
+
+ /* Free resources. */
+ grub_gcry_fini_all ();
+ grub_fini_all ();
+
+ return 0;
+}
--- /dev/null
+# Helper library for grub-mkconfig
+# Copyright (C) 2007,2008,2009,2010 Free Software Foundation, Inc.
+#
+# GRUB is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+datarootdir="@datarootdir@"
+datadir="@datadir@"
+bindir="@bindir@"
+sbindir="@sbindir@"
+if [ "x$pkgdatadir" = x ]; then
+ pkgdatadir="${datadir}/@PACKAGE@"
+fi
+
+if test "x$grub_probe" = x; then
+ grub_probe="${sbindir}/@grub_probe@"
+fi
+if test "x$grub_file" = x; then
+ grub_file="${bindir}/@grub_file@"
+fi
+if test "x$grub_mkrelpath" = x; then
+ grub_mkrelpath="${bindir}/@grub_mkrelpath@"
+fi
+
+if which gettext >/dev/null 2>/dev/null; then
+ :
+else
+ gettext () {
+ printf "%s" "$@"
+ }
+fi
+
+grub_warn ()
+{
+ echo "$(gettext "Warning:")" "$@" >&2
+}
+
+make_system_path_relative_to_its_root ()
+{
+ "${grub_mkrelpath}" "$1"
+}
+
+is_path_readable_by_grub ()
+{
+ path="$1"
+
+ # abort if path doesn't exist
+ if test -e "$path" ; then : ;else
+ return 1
+ fi
+
+ # abort if file is in a filesystem we can't read
+ if "${grub_probe}" -t fs "$path" > /dev/null 2>&1 ; then : ; else
+ return 1
+ fi
+
+ # ... or if we can't figure out the abstraction module, for example if
+ # memberlist fails on an LVM volume group.
+ if abstractions="`"${grub_probe}" -t abstraction "$path"`" 2> /dev/null ; then
+ :
+ else
+ return 1
+ fi
+
+ if [ x$GRUB_ENABLE_CRYPTODISK = xy ]; then
+ return 0
+ fi
+
+ for abstraction in $abstractions; do
+ if [ "x$abstraction" = xcryptodisk ]; then
+ return 1
+ fi
+ done
+
+ return 0
+}
+
+convert_system_path_to_grub_path ()
+{
+ path="$1"
+
+ grub_warn "convert_system_path_to_grub_path() is deprecated. Use prepare_grub_to_access_device() instead."
+
+ # abort if GRUB can't access the path
+ if is_path_readable_by_grub "${path}" ; then : ; else
+ return 1
+ fi
+
+ if drive="`"${grub_probe}" -t drive "$path"`" ; then : ; else
+ return 1
+ fi
+
+ if relative_path="`make_system_path_relative_to_its_root "$path"`" ; then : ; else
+ return 1
+ fi
+
+ echo "${drive}${relative_path}"
+}
+
+save_default_entry ()
+{
+ if [ "x${GRUB_SAVEDEFAULT}" = "xtrue" ] ; then
+ cat << EOF
+savedefault
+EOF
+ fi
+}
+
+prepare_grub_to_access_device ()
+{
+ old_ifs="$IFS"
+ IFS='
+'
+:<<\EOF
+ partmap="`"${grub_probe}" --device $@ --target=partmap`"
+ for module in ${partmap} ; do
+ case "${module}" in
+ netbsd | openbsd)
+ echo "insmod part_bsd";;
+ *)
+ echo "insmod part_${module}";;
+ esac
+ done
+EOF
+
+ # Abstraction modules aren't auto-loaded.
+ abstraction="`"${grub_probe}" --device $@ --target=abstraction`"
+ for module in ${abstraction} ; do
+ echo "insmod ${module}"
+ done
+
+# fs="`"${grub_probe}" --device $@ --target=fs`"
+# for module in ${fs} ; do
+# echo "insmod ${module}"
+# done
+
+ if [ x$GRUB_ENABLE_CRYPTODISK = xy ]; then
+ for uuid in `"${grub_probe}" --device $@ --target=cryptodisk_uuid`; do
+ echo "cryptomount -u $uuid"
+ done
+ fi
+
+ # If there's a filesystem UUID that GRUB is capable of identifying, use it;
+ # otherwise set root as per value in device.map.
+ fs_hint="`"${grub_probe}" --device $@ --target=compatibility_hint`"
+ if [ "x$fs_hint" != x ]; then
+ echo "set root='$fs_hint'"
+ fi
+ if fs_uuid="`"${grub_probe}" --device $@ --target=fs_uuid 2> /dev/null`" ; then
+ hints="`"${grub_probe}" --device $@ --target=hints_string 2> /dev/null`" || hints=
+ echo "if [ x\$feature_platform_search_hint = xy ]; then"
+ echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}"
+ echo "else"
+ echo " search --no-floppy --fs-uuid --set=root ${fs_uuid}"
+ echo "fi"
+ fi
+ IFS="$old_ifs"
+}
+
+grub_get_device_id ()
+{
+ old_ifs="$IFS"
+ IFS='
+'
+ device="$1"
+ if fs_uuid="`"${grub_probe}" --device ${device} --target=fs_uuid 2> /dev/null`" ; then
+ echo "$fs_uuid";
+ else
+ echo $device |sed 's, ,_,g'
+ fi
+ IFS="$old_ifs"
+}
+
+grub_file_is_not_garbage ()
+{
+ if test -f "$1" ; then
+ case "$1" in
+ *.dpkg-*) return 1 ;; # debian dpkg
+ *.rpmsave|*.rpmnew) return 1 ;;
+ README*|*/README*) return 1 ;; # documentation
+ *.sig) return 1 ;; # signatures
+ esac
+ else
+ return 1
+ fi
+ return 0
+}
+
+version_sort ()
+{
+ case $version_sort_sort_has_v in
+ yes)
+ LC_ALL=C sort -V;;
+ no)
+ LC_ALL=C sort -n;;
+ *)
+ if sort -V </dev/null > /dev/null 2>&1; then
+ version_sort_sort_has_v=yes
+ LC_ALL=C sort -V
+ else
+ version_sort_sort_has_v=no
+ LC_ALL=C sort -n
+ fi;;
+ esac
+}
+
+version_test_numeric ()
+{
+ version_test_numeric_a="$1"
+ version_test_numeric_cmp="$2"
+ version_test_numeric_b="$3"
+ if [ "$version_test_numeric_a" = "$version_test_numeric_b" ] ; then
+ case "$version_test_numeric_cmp" in
+ ge|eq|le) return 0 ;;
+ gt|lt) return 1 ;;
+ esac
+ fi
+ if [ "$version_test_numeric_cmp" = "lt" ] ; then
+ version_test_numeric_c="$version_test_numeric_a"
+ version_test_numeric_a="$version_test_numeric_b"
+ version_test_numeric_b="$version_test_numeric_c"
+ fi
+ if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | version_sort | head -n 1 | grep -qx "$version_test_numeric_b" ; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+version_test_gt ()
+{
+ version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//"`"
+ version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//"`"
+ version_test_gt_cmp=gt
+ if [ "x$version_test_gt_b" = "x" ] ; then
+ return 0
+ fi
+ case "$version_test_gt_a:$version_test_gt_b" in
+ *.old:*.old) ;;
+ *.old:*) version_test_gt_a="`echo "$version_test_gt_a" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=gt ;;
+ *:*.old) version_test_gt_b="`echo "$version_test_gt_b" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=ge ;;
+ esac
+ version_test_numeric "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b"
+ return "$?"
+}
+
+version_find_latest ()
+{
+ version_find_latest_a=""
+ for i in "$@" ; do
+ if version_test_gt "$i" "$version_find_latest_a" ; then
+ version_find_latest_a="$i"
+ fi
+ done
+ echo "$version_find_latest_a"
+}
+
+# One layer of quotation is eaten by "" and the second by sed; so this turns
+# ' into \'.
+grub_quote () {
+ sed "s/'/'\\\\''/g"
+}
+
+gettext_quoted () {
+ gettext "$@" | grub_quote
+}
+
+# Run the first argument through gettext, and then pass that and all
+# remaining arguments to printf. This is a useful abbreviation and tends to
+# be easier to type.
+gettext_printf () {
+ gettext_printf_format="$1"
+ shift
+ printf "$(gettext "$gettext_printf_format")" "$@"
+}
+
+uses_abstraction () {
+ device="$1"
+ old_ifs="$IFS"
+ IFS='
+'
+
+ abstraction="`"${grub_probe}" --device ${device} --target=abstraction`"
+ for module in ${abstraction}; do
+ if test "x${module}" = "x$2"; then
+ IFS="$old_ifs"
+ return 0
+ fi
+ done
+ IFS="$old_ifs"
+ return 1
+}
+
+print_option_help () {
+ if test x$print_option_help_wc = x; then
+ if wc -L </dev/null > /dev/null 2>&1; then
+ print_option_help_wc=-L
+ elif wc -m </dev/null > /dev/null 2>&1; then
+ print_option_help_wc=-m
+ else
+ print_option_help_wc=-b
+ fi
+ fi
+ if test x$grub_have_fmt = x; then
+ if fmt -w 40 </dev/null > /dev/null 2>&1; then
+ grub_have_fmt=y;
+ else
+ grub_have_fmt=n;
+ fi
+ fi
+ print_option_help_lead=" $1"
+ print_option_help_lspace="$(echo "$print_option_help_lead" | wc $print_option_help_wc)"
+ print_option_help_fill="$((26 - print_option_help_lspace))"
+ printf "%s" "$print_option_help_lead"
+ if test $print_option_help_fill -le 0; then
+ print_option_help_nl=y
+ echo
+ else
+ print_option_help_i=0;
+ while test $print_option_help_i -lt $print_option_help_fill; do
+ printf " "
+ print_option_help_i=$((print_option_help_i+1))
+ done
+ print_option_help_nl=n
+ fi
+ if test x$grub_have_fmt = xy; then
+ print_option_help_split="$(echo "$2" | fmt -w 50)"
+ else
+ print_option_help_split="$2"
+ fi
+ if test x$print_option_help_nl = xy; then
+ echo "$print_option_help_split" | awk \
+ '{ print " " $0; }'
+ else
+ echo "$print_option_help_split" | awk 'BEGIN { n = 0 }
+ { if (n == 1) print " " $0; else print $0; n = 1 ; }'
+ fi
+}
+
+grub_fmt () {
+ if test x$grub_have_fmt = x; then
+ if fmt -w 40 < /dev/null > /dev/null; then
+ grub_have_fmt=y;
+ else
+ grub_have_fmt=n;
+ fi
+ fi
+
+ if test x$grub_have_fmt = xy; then
+ fmt
+ else
+ cat
+ fi
+}
+
+grub_tab=" "
+
+grub_add_tab () {
+ sed -e "s/^/$grub_tab/"
+}
+
--- /dev/null
+/* grub-mkimage.c - make a bootable image */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/elf.h>
+#include <grub/aout.h>
+#include <grub/i18n.h>
+#include <grub/kernel.h>
+#include <grub/disk.h>
+#include <grub/emu/misc.h>
+#include <grub/util/misc.h>
+#include <grub/util/resolve.h>
+#include <grub/misc.h>
+#include <grub/offsets.h>
+#include <grub/crypto.h>
+#include <grub/dl.h>
+#include <time.h>
+#include <multiboot.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <grub/efi/pe32.h>
+#include <grub/uboot/image.h>
+#include <grub/arm/reloc.h>
+#include <grub/arm64/reloc.h>
+#include <grub/ia64/reloc.h>
+#include <grub/osdep/hostfile.h>
+#include <grub/util/install.h>
+#include <grub/util/mkimage.h>
+
+#include <xen/elfnote.h>
+
+#pragma GCC diagnostic ignored "-Wcast-align"
+
+#define GRUB_MKIMAGEXX
+#if !defined(MKIMAGE_ELF32) && !defined(MKIMAGE_ELF64)
+#if __SIZEOF_POINTER__ == 8
+#include "grub-mkimage64.c"
+#else
+#include "grub-mkimage32.c"
+#endif
+#endif
+
+/* These structures are defined according to the CHRP binding to IEEE1275,
+ "Client Program Format" section. */
+
+struct grub_ieee1275_note_desc
+{
+ grub_uint32_t real_mode;
+ grub_uint32_t real_base;
+ grub_uint32_t real_size;
+ grub_uint32_t virt_base;
+ grub_uint32_t virt_size;
+ grub_uint32_t load_base;
+};
+
+#define GRUB_IEEE1275_NOTE_NAME "PowerPC"
+#define GRUB_IEEE1275_NOTE_TYPE 0x1275
+
+struct grub_ieee1275_note
+{
+ Elf32_Nhdr header;
+ char name[ALIGN_UP(sizeof (GRUB_IEEE1275_NOTE_NAME), 4)];
+ struct grub_ieee1275_note_desc descriptor;
+};
+
+#define GRUB_XEN_NOTE_NAME "Xen"
+
+struct fixup_block_list
+{
+ struct fixup_block_list *next;
+ int state;
+ struct grub_pe32_fixup_block b;
+};
+
+#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof))
+
+struct section_metadata
+{
+ Elf_Half num_sections;
+ Elf_Shdr *sections;
+ Elf_Addr *addrs;
+ Elf_Addr *vaddrs;
+ Elf_Half section_entsize;
+ Elf_Shdr *symtab;
+ const char *strtab;
+};
+
+static int
+is_relocatable (const struct grub_install_image_target_desc *image_target)
+{
+ return image_target->id == IMAGE_EFI || image_target->id == IMAGE_UBOOT
+ || (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_ARM);
+}
+
+#ifdef MKIMAGE_ELF32
+
+/*
+ * R_ARM_THM_CALL/THM_JUMP24
+ *
+ * Relocate Thumb (T32) instruction set relative branches:
+ * B.W, BL and BLX
+ */
+static grub_err_t
+grub_arm_reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr)
+{
+ grub_int32_t offset;
+
+ offset = grub_arm_thm_call_get_offset (target);
+
+ grub_dprintf ("dl", " sym_addr = 0x%08x", sym_addr);
+
+ offset += sym_addr;
+
+ grub_dprintf("dl", " BL*: target=%p, sym_addr=0x%08x, offset=%d\n",
+ target, sym_addr, offset);
+
+ /* Keep traditional (pre-Thumb2) limits on blx. In any case if the kernel
+ is bigger than 2M (currently under 150K) then we probably have a problem
+ somewhere else. */
+ if (offset < -0x200000 || offset >= 0x200000)
+ return grub_error (GRUB_ERR_BAD_MODULE,
+ "THM_CALL Relocation out of range.");
+
+ grub_dprintf ("dl", " relative destination = %p",
+ (char *) target + offset);
+
+ return grub_arm_thm_call_set_offset (target, offset);
+}
+
+/*
+ * R_ARM_THM_JUMP19
+ *
+ * Relocate conditional Thumb (T32) B<c>.W
+ */
+static grub_err_t
+grub_arm_reloc_thm_jump19 (grub_uint16_t *target, Elf32_Addr sym_addr)
+{
+ grub_int32_t offset;
+
+ if (!(sym_addr & 1))
+ return grub_error (GRUB_ERR_BAD_MODULE,
+ "Relocation targeting wrong execution state");
+
+ offset = grub_arm_thm_jump19_get_offset (target);
+
+ /* Adjust and re-truncate offset */
+ offset += sym_addr;
+
+ if (!grub_arm_thm_jump19_check_offset (offset))
+ return grub_error (GRUB_ERR_BAD_MODULE,
+ "THM_JUMP19 Relocation out of range.");
+
+ grub_arm_thm_jump19_set_offset (target, offset);
+
+ return GRUB_ERR_NONE;
+}
+
+/*
+ * R_ARM_JUMP24
+ *
+ * Relocate ARM (A32) B
+ */
+static grub_err_t
+grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr sym_addr)
+{
+ grub_int32_t offset;
+
+ if (sym_addr & 1)
+ return grub_error (GRUB_ERR_BAD_MODULE,
+ "Relocation targeting wrong execution state");
+
+ offset = grub_arm_jump24_get_offset (target);
+ offset += sym_addr;
+
+ if (!grub_arm_jump24_check_offset (offset))
+ return grub_error (GRUB_ERR_BAD_MODULE,
+ "JUMP24 Relocation out of range.");
+
+
+ grub_arm_jump24_set_offset (target, offset);
+
+ return GRUB_ERR_NONE;
+}
+
+#endif
+
+void
+SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc *image_target,
+ int note, char **core_img, size_t *core_size,
+ Elf_Addr target_addr,
+ struct grub_mkimage_layout *layout)
+{
+ char *elf_img;
+ size_t program_size;
+ Elf_Ehdr *ehdr;
+ Elf_Phdr *phdr;
+ Elf_Shdr *shdr;
+ int header_size, footer_size = 0;
+ int phnum = 1;
+ int shnum = 4;
+ int string_size = sizeof (".text") + sizeof ("mods") + 1;
+
+ if (image_target->id != IMAGE_LOONGSON_ELF)
+ phnum += 2;
+
+ if (note)
+ {
+ phnum++;
+ footer_size += sizeof (struct grub_ieee1275_note);
+ }
+ if (image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH)
+ {
+ phnum++;
+ shnum++;
+ string_size += sizeof (".xen");
+ footer_size += (image_target->id == IMAGE_XEN) ? XEN_NOTE_SIZE : XEN_PVH_NOTE_SIZE;
+ }
+ header_size = ALIGN_UP (sizeof (*ehdr) + phnum * sizeof (*phdr)
+ + shnum * sizeof (*shdr) + string_size, layout->align);
+
+ program_size = ALIGN_ADDR (*core_size);
+
+ elf_img = xmalloc (program_size + header_size + footer_size);
+ memset (elf_img, 0, program_size + header_size + footer_size);
+ memcpy (elf_img + header_size, *core_img, *core_size);
+ ehdr = (void *) elf_img;
+ phdr = (void *) (elf_img + sizeof (*ehdr));
+ shdr = (void *) (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr));
+ memcpy (ehdr->e_ident, ELFMAG, SELFMAG);
+ ehdr->e_ident[EI_CLASS] = ELFCLASSXX;
+ if (!image_target->bigendian)
+ ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
+ else
+ ehdr->e_ident[EI_DATA] = ELFDATA2MSB;
+ ehdr->e_ident[EI_VERSION] = EV_CURRENT;
+ ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE;
+ ehdr->e_type = grub_host_to_target16 (ET_EXEC);
+ ehdr->e_machine = grub_host_to_target16 (image_target->elf_target);
+ ehdr->e_version = grub_host_to_target32 (EV_CURRENT);
+
+ ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr);
+ ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr));
+ ehdr->e_phnum = grub_host_to_target16 (phnum);
+
+ ehdr->e_shoff = grub_host_to_target32 ((grub_uint8_t *) shdr
+ - (grub_uint8_t *) ehdr);
+ if (image_target->id == IMAGE_LOONGSON_ELF)
+ ehdr->e_shentsize = grub_host_to_target16 (0);
+ else
+ ehdr->e_shentsize = grub_host_to_target16 (sizeof (Elf_Shdr));
+ ehdr->e_shnum = grub_host_to_target16 (shnum);
+ ehdr->e_shstrndx = grub_host_to_target16 (1);
+
+ ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr));
+
+ phdr->p_type = grub_host_to_target32 (PT_LOAD);
+ phdr->p_offset = grub_host_to_target32 (header_size);
+ phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X);
+
+ ehdr->e_entry = grub_host_to_target32 (target_addr);
+ phdr->p_vaddr = grub_host_to_target32 (target_addr);
+ phdr->p_paddr = grub_host_to_target32 (target_addr);
+ phdr->p_align = grub_host_to_target32 (layout->align > image_target->link_align ?
+ layout->align : image_target->link_align);
+ if (image_target->id == IMAGE_LOONGSON_ELF)
+ ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER
+ | EF_MIPS_PIC | EF_MIPS_CPIC);
+ else
+ ehdr->e_flags = 0;
+ if (image_target->id == IMAGE_LOONGSON_ELF)
+ {
+ phdr->p_filesz = grub_host_to_target32 (*core_size);
+ phdr->p_memsz = grub_host_to_target32 (*core_size);
+ }
+ else
+ {
+ grub_uint32_t target_addr_mods;
+ phdr->p_filesz = grub_host_to_target32 (layout->kernel_size);
+ if (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_ARM)
+ phdr->p_memsz = grub_host_to_target32 (layout->kernel_size);
+ else
+ phdr->p_memsz = grub_host_to_target32 (layout->kernel_size + layout->bss_size);
+
+ phdr++;
+ phdr->p_type = grub_host_to_target32 (PT_GNU_STACK);
+ phdr->p_offset = grub_host_to_target32 (header_size + layout->kernel_size);
+ phdr->p_paddr = phdr->p_vaddr = phdr->p_filesz = phdr->p_memsz = 0;
+ phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X);
+ phdr->p_align = grub_host_to_target32 (image_target->link_align);
+
+ phdr++;
+ phdr->p_type = grub_host_to_target32 (PT_LOAD);
+ phdr->p_offset = grub_host_to_target32 (header_size + layout->kernel_size);
+ phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X);
+ phdr->p_filesz = phdr->p_memsz
+ = grub_host_to_target32 (*core_size - layout->kernel_size);
+
+ if (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_386)
+ target_addr_mods = GRUB_KERNEL_I386_COREBOOT_MODULES_ADDR;
+ else if (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_ARM)
+ target_addr_mods = ALIGN_UP (target_addr + layout->end
+ + image_target->mod_gap,
+ image_target->mod_align);
+ else
+ target_addr_mods = ALIGN_UP (target_addr + layout->kernel_size + layout->bss_size
+ + image_target->mod_gap,
+ image_target->mod_align);
+ phdr->p_vaddr = grub_host_to_target_addr (target_addr_mods);
+ phdr->p_paddr = grub_host_to_target_addr (target_addr_mods);
+ phdr->p_align = grub_host_to_target32 (image_target->link_align);
+ }
+
+ if (image_target->id == IMAGE_XEN)
+ {
+ char *note_start = (elf_img + program_size + header_size);
+ Elf_Nhdr *note_ptr;
+ char *ptr = (char *) note_start;
+
+ grub_util_info ("adding XEN NOTE segment");
+
+ /* Guest OS. */
+ note_ptr = (Elf_Nhdr *) ptr;
+ note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
+ note_ptr->n_descsz = grub_host_to_target32 (sizeof (PACKAGE_NAME));
+ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_GUEST_OS);
+ ptr += sizeof (Elf_Nhdr);
+ memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
+ ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
+ memcpy (ptr, PACKAGE_NAME, sizeof (PACKAGE_NAME));
+ ptr += ALIGN_UP (sizeof (PACKAGE_NAME), 4);
+
+ /* Loader. */
+ note_ptr = (Elf_Nhdr *) ptr;
+ note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
+ note_ptr->n_descsz = grub_host_to_target32 (sizeof ("generic"));
+ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_LOADER);
+ ptr += sizeof (Elf_Nhdr);
+ memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
+ ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
+ memcpy (ptr, "generic", sizeof ("generic"));
+ ptr += ALIGN_UP (sizeof ("generic"), 4);
+
+ /* Version. */
+ note_ptr = (Elf_Nhdr *) ptr;
+ note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
+ note_ptr->n_descsz = grub_host_to_target32 (sizeof ("xen-3.0"));
+ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_XEN_VERSION);
+ ptr += sizeof (Elf_Nhdr);
+ memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
+ ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
+ memcpy (ptr, "xen-3.0", sizeof ("xen-3.0"));
+ ptr += ALIGN_UP (sizeof ("xen-3.0"), 4);
+
+ /* Entry. */
+ note_ptr = (Elf_Nhdr *) ptr;
+ note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
+ note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof);
+ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_ENTRY);
+ ptr += sizeof (Elf_Nhdr);
+ memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
+ ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
+ memset (ptr, 0, image_target->voidp_sizeof);
+ ptr += image_target->voidp_sizeof;
+
+ /* Virt base. */
+ note_ptr = (Elf_Nhdr *) ptr;
+ note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
+ note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof);
+ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_VIRT_BASE);
+ ptr += sizeof (Elf_Nhdr);
+ memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
+ ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
+ memset (ptr, 0, image_target->voidp_sizeof);
+ ptr += image_target->voidp_sizeof;
+
+ /* PAE. */
+ if (image_target->elf_target == EM_386)
+ {
+ note_ptr = (Elf_Nhdr *) ptr;
+ note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
+ note_ptr->n_descsz = grub_host_to_target32 (sizeof ("yes,bimodal"));
+ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_PAE_MODE);
+ ptr += sizeof (Elf_Nhdr);
+ memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
+ ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
+ memcpy (ptr, "yes", sizeof ("yes"));
+ ptr += ALIGN_UP (sizeof ("yes"), 4);
+ }
+
+ assert (XEN_NOTE_SIZE == (ptr - note_start));
+
+ phdr++;
+ phdr->p_type = grub_host_to_target32 (PT_NOTE);
+ phdr->p_flags = grub_host_to_target32 (PF_R);
+ phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof);
+ phdr->p_vaddr = 0;
+ phdr->p_paddr = 0;
+ phdr->p_filesz = grub_host_to_target32 (XEN_NOTE_SIZE);
+ phdr->p_memsz = 0;
+ phdr->p_offset = grub_host_to_target32 (header_size + program_size);
+ }
+
+ if (image_target->id == IMAGE_XEN_PVH)
+ {
+ char *note_start = (elf_img + program_size + header_size);
+ Elf_Nhdr *note_ptr;
+ char *ptr = (char *) note_start;
+
+ grub_util_info ("adding XEN NOTE segment");
+
+ /* Phys32 Entry. */
+ note_ptr = (Elf_Nhdr *) ptr;
+ note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
+ note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof);
+ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_PHYS32_ENTRY);
+ ptr += sizeof (Elf_Nhdr);
+ memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
+ ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
+ memset (ptr, 0, image_target->voidp_sizeof);
+ *(grub_uint32_t *) ptr = GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR;
+ ptr += image_target->voidp_sizeof;
+
+ assert (XEN_PVH_NOTE_SIZE == (ptr - note_start));
+
+ phdr++;
+ phdr->p_type = grub_host_to_target32 (PT_NOTE);
+ phdr->p_flags = grub_host_to_target32 (PF_R);
+ phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof);
+ phdr->p_vaddr = 0;
+ phdr->p_paddr = 0;
+ phdr->p_filesz = grub_host_to_target32 (XEN_PVH_NOTE_SIZE);
+ phdr->p_memsz = 0;
+ phdr->p_offset = grub_host_to_target32 (header_size + program_size);
+ }
+
+ if (note)
+ {
+ int note_size = sizeof (struct grub_ieee1275_note);
+ struct grub_ieee1275_note *note_ptr = (struct grub_ieee1275_note *)
+ (elf_img + program_size + header_size);
+
+ grub_util_info ("adding CHRP NOTE segment");
+
+ note_ptr->header.n_namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME));
+ note_ptr->header.n_descsz = grub_host_to_target32 (note_size);
+ note_ptr->header.n_type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE);
+ strcpy (note_ptr->name, GRUB_IEEE1275_NOTE_NAME);
+ note_ptr->descriptor.real_mode = grub_host_to_target32 (0xffffffff);
+ note_ptr->descriptor.real_base = grub_host_to_target32 (0x00c00000);
+ note_ptr->descriptor.real_size = grub_host_to_target32 (0xffffffff);
+ note_ptr->descriptor.virt_base = grub_host_to_target32 (0xffffffff);
+ note_ptr->descriptor.virt_size = grub_host_to_target32 (0xffffffff);
+ note_ptr->descriptor.load_base = grub_host_to_target32 (0x00004000);
+
+ phdr++;
+ phdr->p_type = grub_host_to_target32 (PT_NOTE);
+ phdr->p_flags = grub_host_to_target32 (PF_R);
+ phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof);
+ phdr->p_vaddr = 0;
+ phdr->p_paddr = 0;
+ phdr->p_filesz = grub_host_to_target32 (note_size);
+ phdr->p_memsz = 0;
+ phdr->p_offset = grub_host_to_target32 (header_size + program_size);
+ }
+
+ {
+ char *str_start = (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr)
+ + shnum * sizeof (*shdr));
+ char *ptr = str_start + 1;
+
+ shdr++;
+
+ shdr->sh_name = grub_host_to_target32 (0);
+ shdr->sh_type = grub_host_to_target32 (SHT_STRTAB);
+ shdr->sh_addr = grub_host_to_target_addr (0);
+ shdr->sh_offset = grub_host_to_target_addr (str_start - elf_img);
+ shdr->sh_size = grub_host_to_target32 (string_size);
+ shdr->sh_link = grub_host_to_target32 (0);
+ shdr->sh_info = grub_host_to_target32 (0);
+ shdr->sh_addralign = grub_host_to_target32 (layout->align);
+ shdr->sh_entsize = grub_host_to_target32 (0);
+ shdr++;
+
+ memcpy (ptr, ".text", sizeof (".text"));
+
+ shdr->sh_name = grub_host_to_target32 (ptr - str_start);
+ ptr += sizeof (".text");
+ shdr->sh_type = grub_host_to_target32 (SHT_PROGBITS);
+ shdr->sh_addr = grub_host_to_target_addr (target_addr);
+ shdr->sh_offset = grub_host_to_target_addr (header_size);
+ shdr->sh_size = grub_host_to_target32 (layout->kernel_size);
+ shdr->sh_link = grub_host_to_target32 (0);
+ shdr->sh_info = grub_host_to_target32 (0);
+ shdr->sh_addralign = grub_host_to_target32 (layout->align);
+ shdr->sh_entsize = grub_host_to_target32 (0);
+ shdr++;
+
+ memcpy (ptr, "mods", sizeof ("mods"));
+ shdr->sh_name = grub_host_to_target32 (ptr - str_start);
+ ptr += sizeof ("mods");
+ shdr->sh_type = grub_host_to_target32 (SHT_PROGBITS);
+ shdr->sh_addr = grub_host_to_target_addr (target_addr + layout->kernel_size);
+ shdr->sh_offset = grub_host_to_target_addr (header_size + layout->kernel_size);
+ shdr->sh_size = grub_host_to_target32 (*core_size - layout->kernel_size);
+ shdr->sh_link = grub_host_to_target32 (0);
+ shdr->sh_info = grub_host_to_target32 (0);
+ shdr->sh_addralign = grub_host_to_target32 (image_target->voidp_sizeof);
+ shdr->sh_entsize = grub_host_to_target32 (0);
+ shdr++;
+
+ if (image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH)
+ {
+ memcpy (ptr, ".xen", sizeof (".xen"));
+ shdr->sh_name = grub_host_to_target32 (ptr - str_start);
+ ptr += sizeof (".xen");
+ shdr->sh_type = grub_host_to_target32 (SHT_PROGBITS);
+ shdr->sh_addr = grub_host_to_target_addr (target_addr + layout->kernel_size);
+ shdr->sh_offset = grub_host_to_target_addr (program_size + header_size);
+ if (image_target->id == IMAGE_XEN)
+ shdr->sh_size = grub_host_to_target32 (XEN_NOTE_SIZE);
+ else
+ shdr->sh_size = grub_host_to_target32 (XEN_PVH_NOTE_SIZE);
+ shdr->sh_link = grub_host_to_target32 (0);
+ shdr->sh_info = grub_host_to_target32 (0);
+ shdr->sh_addralign = grub_host_to_target32 (image_target->voidp_sizeof);
+ shdr->sh_entsize = grub_host_to_target32 (0);
+ shdr++;
+ }
+ }
+
+ free (*core_img);
+ *core_img = elf_img;
+ *core_size = program_size + header_size + footer_size;
+}
+
+/* Relocate symbols; note that this function overwrites the symbol table.
+ Return the address of a start symbol. */
+static Elf_Addr
+SUFFIX (relocate_symbols) (Elf_Ehdr *e, struct section_metadata *smd,
+ void *jumpers, Elf_Addr jumpers_addr,
+ Elf_Addr bss_start, Elf_Addr end,
+ const struct grub_install_image_target_desc *image_target)
+{
+ Elf_Word symtab_size, sym_size, num_syms;
+ Elf_Off symtab_offset;
+ Elf_Addr start_address = (Elf_Addr) -1;
+ Elf_Sym *sym;
+ Elf_Word i;
+ Elf_Shdr *symtab_section;
+ const char *symtab;
+ grub_uint64_t *jptr = jumpers;
+
+ symtab_section = (Elf_Shdr *) ((char *) smd->sections
+ + grub_target_to_host32 (smd->symtab->sh_link)
+ * smd->section_entsize);
+ symtab = (char *) e + grub_target_to_host (symtab_section->sh_offset);
+
+ symtab_size = grub_target_to_host (smd->symtab->sh_size);
+ sym_size = grub_target_to_host (smd->symtab->sh_entsize);
+ symtab_offset = grub_target_to_host (smd->symtab->sh_offset);
+ num_syms = symtab_size / sym_size;
+
+ for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset);
+ i < num_syms;
+ i++, sym = (Elf_Sym *) ((char *) sym + sym_size))
+ {
+ Elf_Section cur_index;
+ const char *name;
+
+ name = symtab + grub_target_to_host32 (sym->st_name);
+
+ cur_index = grub_target_to_host16 (sym->st_shndx);
+ if (cur_index == STN_ABS)
+ {
+ continue;
+ }
+ else if (cur_index == STN_UNDEF)
+ {
+ if (sym->st_name && grub_strcmp (name, "__bss_start") == 0)
+ sym->st_value = bss_start;
+ else if (sym->st_name && grub_strcmp (name, "_end") == 0)
+ sym->st_value = end;
+ else if (sym->st_name)
+ grub_util_error ("undefined symbol %s", name);
+ else
+ continue;
+ }
+ else if (cur_index >= smd->num_sections)
+ grub_util_error ("section %d does not exist", cur_index);
+ else
+ {
+ sym->st_value = (grub_target_to_host (sym->st_value)
+ + smd->vaddrs[cur_index]);
+ }
+
+ if (image_target->elf_target == EM_IA_64 && ELF_ST_TYPE (sym->st_info)
+ == STT_FUNC)
+ {
+ *jptr = grub_host_to_target64 (sym->st_value);
+ sym->st_value = (char *) jptr - (char *) jumpers + jumpers_addr;
+ jptr++;
+ *jptr = 0;
+ jptr++;
+ }
+ grub_util_info ("locating %s at 0x%" GRUB_HOST_PRIxLONG_LONG
+ " (0x%" GRUB_HOST_PRIxLONG_LONG ")", name,
+ (unsigned long long) sym->st_value,
+ (unsigned long long) smd->vaddrs[cur_index]);
+
+ if (start_address == (Elf_Addr)-1)
+ if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0)
+ start_address = sym->st_value;
+ }
+
+ return start_address;
+}
+
+/* Return the address of a symbol at the index I in the section S. */
+static Elf_Addr
+SUFFIX (get_symbol_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i,
+ const struct grub_install_image_target_desc *image_target)
+{
+ Elf_Sym *sym;
+
+ sym = (Elf_Sym *) ((char *) e
+ + grub_target_to_host (s->sh_offset)
+ + i * grub_target_to_host (s->sh_entsize));
+ return sym->st_value;
+}
+
+/* Return the address of a modified value. */
+static Elf_Addr *
+SUFFIX (get_target_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset,
+ const struct grub_install_image_target_desc *image_target)
+{
+ return (Elf_Addr *) ((char *) e + grub_target_to_host (s->sh_offset) + offset);
+}
+
+#ifdef MKIMAGE_ELF64
+static Elf_Addr
+SUFFIX (count_funcs) (Elf_Ehdr *e, Elf_Shdr *symtab_section,
+ const struct grub_install_image_target_desc *image_target)
+{
+ Elf_Word symtab_size, sym_size, num_syms;
+ Elf_Off symtab_offset;
+ Elf_Sym *sym;
+ Elf_Word i;
+ int ret = 0;
+
+ symtab_size = grub_target_to_host (symtab_section->sh_size);
+ sym_size = grub_target_to_host (symtab_section->sh_entsize);
+ symtab_offset = grub_target_to_host (symtab_section->sh_offset);
+ num_syms = symtab_size / sym_size;
+
+ for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset);
+ i < num_syms;
+ i++, sym = (Elf_Sym *) ((char *) sym + sym_size))
+ if (ELF_ST_TYPE (sym->st_info) == STT_FUNC)
+ ret++;
+
+ return ret;
+}
+#endif
+
+#ifdef MKIMAGE_ELF32
+/* Deal with relocation information. This function relocates addresses
+ within the virtual address space starting from 0. So only relative
+ addresses can be fully resolved. Absolute addresses must be relocated
+ again by a PE32 relocator when loaded. */
+static grub_size_t
+arm_get_trampoline_size (Elf_Ehdr *e,
+ Elf_Shdr *sections,
+ Elf_Half section_entsize,
+ Elf_Half num_sections,
+ const struct grub_install_image_target_desc *image_target)
+{
+ Elf_Half i;
+ Elf_Shdr *s;
+ grub_size_t ret = 0;
+
+ for (i = 0, s = sections;
+ i < num_sections;
+ i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
+ if ((s->sh_type == grub_host_to_target32 (SHT_REL)) ||
+ (s->sh_type == grub_host_to_target32 (SHT_RELA)))
+ {
+ Elf_Rela *r;
+ Elf_Word rtab_size, r_size, num_rs;
+ Elf_Off rtab_offset;
+ Elf_Shdr *symtab_section;
+ Elf_Word j;
+
+ symtab_section = (Elf_Shdr *) ((char *) sections
+ + (grub_target_to_host32 (s->sh_link)
+ * section_entsize));
+
+ rtab_size = grub_target_to_host (s->sh_size);
+ r_size = grub_target_to_host (s->sh_entsize);
+ rtab_offset = grub_target_to_host (s->sh_offset);
+ num_rs = rtab_size / r_size;
+
+ for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset);
+ j < num_rs;
+ j++, r = (Elf_Rela *) ((char *) r + r_size))
+ {
+ Elf_Addr info;
+ Elf_Addr sym_addr;
+
+ info = grub_target_to_host (r->r_info);
+ sym_addr = SUFFIX (get_symbol_address) (e, symtab_section,
+ ELF_R_SYM (info), image_target);
+
+ sym_addr += (s->sh_type == grub_target_to_host32 (SHT_RELA)) ?
+ grub_target_to_host (r->r_addend) : 0;
+
+ switch (ELF_R_TYPE (info))
+ {
+ case R_ARM_ABS32:
+ case R_ARM_V4BX:
+ break;
+ case R_ARM_THM_CALL:
+ case R_ARM_THM_JUMP24:
+ case R_ARM_THM_JUMP19:
+ if (!(sym_addr & 1))
+ ret += 8;
+ break;
+
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
+ if (sym_addr & 1)
+ ret += 16;
+ break;
+
+ default:
+ grub_util_error (_("relocation 0x%x is not implemented yet"),
+ (unsigned int) ELF_R_TYPE (info));
+ break;
+ }
+ }
+ }
+ return ret;
+}
+#endif
+
+static int
+SUFFIX (is_kept_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target);
+static int
+SUFFIX (is_kept_reloc_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target,
+ struct section_metadata *smd);
+
+/* Deal with relocation information. This function relocates addresses
+ within the virtual address space starting from 0. So only relative
+ addresses can be fully resolved. Absolute addresses must be relocated
+ again by a PE32 relocator when loaded. */
+static void
+SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd,
+ char *pe_target, Elf_Addr tramp_off, Elf_Addr got_off,
+ const struct grub_install_image_target_desc *image_target)
+{
+ Elf_Half i;
+ Elf_Shdr *s;
+#ifdef MKIMAGE_ELF64
+ struct grub_ia64_trampoline *tr = (void *) (pe_target + tramp_off);
+ grub_uint64_t *gpptr = (void *) (pe_target + got_off);
+ unsigned unmatched_adr_got_page = 0;
+#define MASK19 ((1 << 19) - 1)
+#else
+ grub_uint32_t *tr = (void *) (pe_target + tramp_off);
+#endif
+
+ for (i = 0, s = smd->sections;
+ i < smd->num_sections;
+ i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
+ if ((s->sh_type == grub_host_to_target32 (SHT_REL)) ||
+ (s->sh_type == grub_host_to_target32 (SHT_RELA)))
+ {
+ Elf_Rela *r;
+ Elf_Word rtab_size, r_size, num_rs;
+ Elf_Off rtab_offset;
+ Elf_Word target_section_index;
+ Elf_Addr target_section_addr;
+ Elf_Shdr *target_section;
+ Elf_Word j;
+
+ if (!SUFFIX (is_kept_section) (s, image_target) &&
+ !SUFFIX (is_kept_reloc_section) (s, image_target, smd))
+ {
+ grub_util_info ("not translating relocations for omitted section %s",
+ smd->strtab + grub_le_to_cpu32 (s->sh_name));
+ continue;
+ }
+
+ target_section_index = grub_target_to_host32 (s->sh_info);
+ target_section_addr = smd->addrs[target_section_index];
+ target_section = (Elf_Shdr *) ((char *) smd->sections
+ + (target_section_index
+ * smd->section_entsize));
+
+ grub_util_info ("dealing with the relocation section %s for %s",
+ smd->strtab + grub_target_to_host32 (s->sh_name),
+ smd->strtab + grub_target_to_host32 (target_section->sh_name));
+
+ rtab_size = grub_target_to_host (s->sh_size);
+ r_size = grub_target_to_host (s->sh_entsize);
+ rtab_offset = grub_target_to_host (s->sh_offset);
+ num_rs = rtab_size / r_size;
+
+ for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset);
+ j < num_rs;
+ j++, r = (Elf_Rela *) ((char *) r + r_size))
+ {
+ Elf_Addr info;
+ Elf_Addr offset;
+ Elf_Addr sym_addr;
+ Elf_Addr *target;
+ Elf_Addr addend;
+
+ offset = grub_target_to_host (r->r_offset);
+ target = SUFFIX (get_target_address) (e, target_section,
+ offset, image_target);
+ if (image_target->elf_target == EM_MIPS && image_target->voidp_sizeof == 8)
+ info = ((grub_uint64_t) r->r_info << 32) |
+ (grub_uint32_t) grub_be_to_cpu64 (r->r_info);
+ else
+ info = grub_target_to_host (r->r_info);
+ sym_addr = SUFFIX (get_symbol_address) (e, smd->symtab,
+ ELF_R_SYM (info), image_target);
+
+ addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ?
+ grub_target_to_host (r->r_addend) : 0;
+
+ switch (image_target->elf_target)
+ {
+ case EM_386:
+ switch (ELF_R_TYPE (info))
+ {
+ case R_386_NONE:
+ break;
+
+ case R_386_32:
+ /* This is absolute. */
+ *target = grub_host_to_target32 (grub_target_to_host32 (*target)
+ + addend + sym_addr);
+ grub_util_info ("relocating an R_386_32 entry to 0x%"
+ GRUB_HOST_PRIxLONG_LONG " at the offset 0x%"
+ GRUB_HOST_PRIxLONG_LONG,
+ (unsigned long long) *target,
+ (unsigned long long) offset);
+ break;
+
+ case R_386_PC32:
+ /* This is relative. */
+ *target = grub_host_to_target32 (grub_target_to_host32 (*target)
+ + addend + sym_addr
+ - target_section_addr - offset
+ - image_target->vaddr_offset);
+ grub_util_info ("relocating an R_386_PC32 entry to 0x%"
+ GRUB_HOST_PRIxLONG_LONG " at the offset 0x%"
+ GRUB_HOST_PRIxLONG_LONG,
+ (unsigned long long) *target,
+ (unsigned long long) offset);
+ break;
+ default:
+ grub_util_error (_("relocation 0x%x is not implemented yet"),
+ (unsigned int) ELF_R_TYPE (info));
+ break;
+ }
+ break;
+#ifdef MKIMAGE_ELF64
+ case EM_X86_64:
+ switch (ELF_R_TYPE (info))
+ {
+
+ case R_X86_64_NONE:
+ break;
+
+ case R_X86_64_64:
+ *target = grub_host_to_target64 (grub_target_to_host64 (*target)
+ + addend + sym_addr);
+ grub_util_info ("relocating an R_X86_64_64 entry to 0x%"
+ GRUB_HOST_PRIxLONG_LONG " at the offset 0x%"
+ GRUB_HOST_PRIxLONG_LONG,
+ (unsigned long long) *target,
+ (unsigned long long) offset);
+ break;
+
+ case R_X86_64_PC32:
+ case R_X86_64_PLT32:
+ {
+ grub_uint32_t *t32 = (grub_uint32_t *) target;
+ *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32)
+ + addend + sym_addr
+ - target_section_addr - offset
+ - image_target->vaddr_offset);
+ grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%"
+ GRUB_HOST_PRIxLONG_LONG,
+ *t32, (unsigned long long) offset);
+ break;
+ }
+
+ case R_X86_64_PC64:
+ {
+ *target = grub_host_to_target64 (grub_target_to_host64 (*target)
+ + addend + sym_addr
+ - target_section_addr - offset
+ - image_target->vaddr_offset);
+ grub_util_info ("relocating an R_X86_64_PC64 entry to 0x%"
+ GRUB_HOST_PRIxLONG_LONG " at the offset 0x%"
+ GRUB_HOST_PRIxLONG_LONG,
+ (unsigned long long) *target,
+ (unsigned long long) offset);
+ break;
+ }
+
+ case R_X86_64_32:
+ case R_X86_64_32S:
+ {
+ grub_uint32_t *t32 = (grub_uint32_t *) target;
+ *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32)
+ + addend + sym_addr);
+ grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%"
+ GRUB_HOST_PRIxLONG_LONG,
+ *t32, (unsigned long long) offset);
+ break;
+ }
+
+ default:
+ grub_util_error (_("relocation 0x%x is not implemented yet"),
+ (unsigned int) ELF_R_TYPE (info));
+ break;
+ }
+ break;
+ case EM_IA_64:
+ switch (ELF_R_TYPE (info))
+ {
+ case R_IA64_PCREL21B:
+ {
+ grub_uint64_t noff;
+ grub_ia64_make_trampoline (tr, addend + sym_addr);
+ noff = ((char *) tr - (char *) pe_target
+ - target_section_addr - (offset & ~3)) >> 4;
+ tr++;
+ if (noff & ~MASK19)
+ grub_util_error ("trampoline offset too big (%"
+ GRUB_HOST_PRIxLONG_LONG ")",
+ (unsigned long long) noff);
+ grub_ia64_add_value_to_slot_20b ((grub_addr_t) target, noff);
+ }
+ break;
+
+ case R_IA64_LTOFF22X:
+ case R_IA64_LTOFF22:
+ {
+ Elf_Sym *sym;
+
+ sym = (Elf_Sym *) ((char *) e
+ + grub_target_to_host (smd->symtab->sh_offset)
+ + ELF_R_SYM (info) * grub_target_to_host (smd->symtab->sh_entsize));
+ if (ELF_ST_TYPE (sym->st_info) == STT_FUNC)
+ sym_addr = grub_target_to_host64 (*(grub_uint64_t *) (pe_target
+ + sym->st_value
+ - image_target->vaddr_offset));
+ }
+ /* FALLTHROUGH */
+ case R_IA64_LTOFF_FPTR22:
+ *gpptr = grub_host_to_target64 (addend + sym_addr);
+ grub_ia64_add_value_to_slot_21 ((grub_addr_t) target,
+ (char *) gpptr - (char *) pe_target
+ + image_target->vaddr_offset);
+ gpptr++;
+ break;
+
+ case R_IA64_GPREL22:
+ grub_ia64_add_value_to_slot_21 ((grub_addr_t) target,
+ addend + sym_addr);
+ break;
+ case R_IA64_GPREL64I:
+ grub_ia64_set_immu64 ((grub_addr_t) target,
+ addend + sym_addr);
+ break;
+ case R_IA64_PCREL64LSB:
+ *target = grub_host_to_target64 (grub_target_to_host64 (*target)
+ + addend + sym_addr
+ - target_section_addr - offset
+ - image_target->vaddr_offset);
+ break;
+
+ case R_IA64_SEGREL64LSB:
+ *target = grub_host_to_target64 (grub_target_to_host64 (*target)
+ + addend + sym_addr - target_section_addr);
+ break;
+ case R_IA64_DIR64LSB:
+ case R_IA64_FPTR64LSB:
+ *target = grub_host_to_target64 (grub_target_to_host64 (*target)
+ + addend + sym_addr);
+ grub_util_info ("relocating a direct entry to 0x%"
+ GRUB_HOST_PRIxLONG_LONG " at the offset 0x%"
+ GRUB_HOST_PRIxLONG_LONG,
+ (unsigned long long)
+ grub_target_to_host64 (*target),
+ (unsigned long long) offset);
+ break;
+
+ /* We treat LTOFF22X as LTOFF22, so we can ignore LDXMOV. */
+ case R_IA64_LDXMOV:
+ break;
+
+ default:
+ grub_util_error (_("relocation 0x%x is not implemented yet"),
+ (unsigned int) ELF_R_TYPE (info));
+ break;
+ }
+ break;
+ case EM_AARCH64:
+ {
+ sym_addr += addend;
+ switch (ELF_R_TYPE (info))
+ {
+ case R_AARCH64_ABS64:
+ {
+ *target = grub_host_to_target64 (grub_target_to_host64 (*target) + sym_addr);
+ }
+ break;
+ case R_AARCH64_PREL32:
+ {
+ grub_uint32_t *t32 = (grub_uint32_t *) target;
+ *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32)
+ + sym_addr
+ - target_section_addr - offset
+ - image_target->vaddr_offset);
+ grub_util_info ("relocating an R_AARCH64_PREL32 entry to 0x%x at the offset 0x%"
+ GRUB_HOST_PRIxLONG_LONG,
+ *t32, (unsigned long long) offset);
+ break;
+ }
+ case R_AARCH64_ADD_ABS_LO12_NC:
+ grub_arm64_set_abs_lo12 ((grub_uint32_t *) target,
+ sym_addr);
+ break;
+ case R_AARCH64_LDST64_ABS_LO12_NC:
+ grub_arm64_set_abs_lo12_ldst64 ((grub_uint32_t *) target,
+ sym_addr);
+ break;
+ case R_AARCH64_JUMP26:
+ case R_AARCH64_CALL26:
+ {
+ sym_addr -= offset;
+ sym_addr -= target_section_addr + image_target->vaddr_offset;
+ if (!grub_arm_64_check_xxxx26_offset (sym_addr))
+ grub_util_error ("%s", "CALL26 Relocation out of range");
+
+ grub_arm64_set_xxxx26_offset((grub_uint32_t *)target,
+ sym_addr);
+ }
+ break;
+ case R_AARCH64_ADR_GOT_PAGE:
+ {
+ Elf64_Rela *rel2;
+ grub_int64_t gpoffset = (((char *) gpptr - (char *) pe_target + image_target->vaddr_offset) & ~0xfffULL)
+ - ((offset + target_section_addr + image_target->vaddr_offset) & ~0xfffULL);
+ unsigned k;
+ *gpptr = grub_host_to_target64 (sym_addr);
+ unmatched_adr_got_page++;
+ if (!grub_arm64_check_hi21_signed (gpoffset))
+ grub_util_error ("HI21 out of range");
+ grub_arm64_set_hi21((grub_uint32_t *)target,
+ gpoffset);
+ for (k = 0, rel2 = (Elf_Rela *) ((char *) r + r_size);
+ k < num_rs;
+ k++, rel2 = (Elf_Rela *) ((char *) rel2 + r_size))
+ if (ELF_R_SYM (rel2->r_info)
+ == ELF_R_SYM (r->r_info)
+ && r->r_addend == rel2->r_addend
+ && ELF_R_TYPE (rel2->r_info) == R_AARCH64_LD64_GOT_LO12_NC)
+ {
+ grub_arm64_set_abs_lo12_ldst64 ((grub_uint32_t *) SUFFIX (get_target_address) (e, target_section,
+ grub_target_to_host (rel2->r_offset), image_target),
+ ((char *) gpptr - (char *) pe_target + image_target->vaddr_offset));
+ break;
+ }
+ if (k >= num_rs)
+ grub_util_error ("ADR_GOT_PAGE without matching LD64_GOT_LO12_NC");
+ gpptr++;
+ }
+ break;
+ case R_AARCH64_LD64_GOT_LO12_NC:
+ if (unmatched_adr_got_page == 0)
+ grub_util_error ("LD64_GOT_LO12_NC without matching ADR_GOT_PAGE");
+ unmatched_adr_got_page--;
+ break;
+ case R_AARCH64_ADR_PREL_PG_HI21:
+ {
+ sym_addr &= ~0xfffULL;
+ sym_addr -= (offset + target_section_addr + image_target->vaddr_offset) & ~0xfffULL;
+ if (!grub_arm64_check_hi21_signed (sym_addr))
+ grub_util_error ("%s", "CALL26 Relocation out of range");
+
+ grub_arm64_set_hi21((grub_uint32_t *)target,
+ sym_addr);
+ }
+ break;
+ default:
+ grub_util_error (_("relocation 0x%x is not implemented yet"),
+ (unsigned int) ELF_R_TYPE (info));
+ break;
+ }
+ break;
+ }
+ case EM_MIPS:
+ {
+ sym_addr += addend;
+ switch (ELF_R_TYPE (info))
+ {
+ case R_MIPS_NONE:
+ break;
+ case R_MIPS_64:
+ {
+ *target = grub_host_to_target64 (grub_target_to_host64 (*target) + sym_addr);
+ }
+ break;
+ case R_MIPS_32:
+ {
+ grub_uint32_t *t32 = (grub_uint32_t *) target;
+ *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + sym_addr);
+ }
+ break;
+ case R_MIPS_26:
+ {
+ grub_uint32_t *t32 = (grub_uint32_t *) target;
+ grub_addr_t addr = grub_host_to_target64 (sym_addr);
+ *t32 = ((*t32) & 0xfc000000U) | ((addr >> 2) & 0x3ffffffUL);
+ }
+ break;
+ case R_MIPS_LO16:
+ {
+ grub_int16_t *t16 = (grub_int16_t *) target;
+ grub_addr_t addr = grub_host_to_target64 (sym_addr);
+ *t16 = (grub_int16_t) addr;
+ }
+ break;
+ case R_MIPS_HI16:
+ {
+ grub_int16_t *t16 = (grub_int16_t *) target;
+ grub_addr_t addr = grub_host_to_target64 (sym_addr);
+ *t16 = (grub_int16_t) ((addr + 0x8000UL) >> 16);
+ }
+ break;
+ case R_MIPS_HIGHER:
+ {
+ grub_int16_t *t16 = (grub_int16_t *) target;
+ grub_addr_t addr = grub_host_to_target64 (sym_addr);
+ *t16 = (grub_int16_t) ((addr + 0x80008000UL) >> 32);
+ }
+ break;
+ case R_MIPS_HIGHEST:
+ {
+ grub_uint16_t *t16 = (grub_uint16_t *) target;
+ grub_addr_t addr = grub_host_to_target64 (sym_addr);
+ *t16 = (grub_uint16_t) ((addr + 0x800080008000UL) >> 48);
+ }
+ break;
+ default:
+ grub_util_error (_("relocation 0x%x is not implemented yet"),
+ (unsigned int) ELF_R_TYPE (info));
+ break;
+ }
+ break;
+ }
+#endif
+#if defined(MKIMAGE_ELF32)
+ case EM_ARM:
+ {
+ sym_addr += addend;
+ sym_addr -= image_target->vaddr_offset;
+ switch (ELF_R_TYPE (info))
+ {
+ case R_ARM_ABS32:
+ {
+ grub_util_info (" ABS32:\toffset=%d\t(0x%08x)",
+ (int) sym_addr, (int) sym_addr);
+ /* Data will be naturally aligned */
+ if (image_target->id == IMAGE_EFI)
+ sym_addr += GRUB_PE32_SECTION_ALIGNMENT;
+ *target = grub_host_to_target32 (grub_target_to_host32 (*target) + sym_addr);
+ }
+ break;
+ /* Happens when compiled with -march=armv4.
+ Since currently we need at least armv5, keep bx as-is.
+ */
+ case R_ARM_V4BX:
+ break;
+ case R_ARM_THM_CALL:
+ case R_ARM_THM_JUMP24:
+ case R_ARM_THM_JUMP19:
+ {
+ grub_err_t err;
+ Elf_Sym *sym;
+ grub_util_info (" THM_JUMP24:\ttarget=0x%08lx\toffset=(0x%08x)",
+ (unsigned long) ((char *) target
+ - (char *) e),
+ sym_addr);
+ sym = (Elf_Sym *) ((char *) e
+ + grub_target_to_host (smd->symtab->sh_offset)
+ + ELF_R_SYM (info) * grub_target_to_host (smd->symtab->sh_entsize));
+ if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
+ sym_addr |= 1;
+ if (!(sym_addr & 1))
+ {
+ grub_uint32_t tr_addr;
+ grub_int32_t new_offset;
+ tr_addr = (char *) tr - (char *) pe_target
+ - target_section_addr;
+ new_offset = sym_addr - tr_addr - 12;
+
+ if (!grub_arm_jump24_check_offset (new_offset))
+ return grub_util_error ("jump24 relocation out of range");
+
+ tr[0] = grub_host_to_target32 (0x46c04778); /* bx pc; nop */
+ tr[1] = grub_host_to_target32 (((new_offset >> 2) & 0xffffff) | 0xea000000); /* b new_offset */
+ tr += 2;
+ sym_addr = tr_addr | 1;
+ }
+ sym_addr -= offset;
+ /* Thumb instructions can be 16-bit aligned */
+ if (ELF_R_TYPE (info) == R_ARM_THM_JUMP19)
+ err = grub_arm_reloc_thm_jump19 ((grub_uint16_t *) target, sym_addr);
+ else
+ err = grub_arm_reloc_thm_call ((grub_uint16_t *) target,
+ sym_addr);
+ if (err)
+ grub_util_error ("%s", grub_errmsg);
+ }
+ break;
+
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
+ {
+ grub_err_t err;
+ grub_util_info (" JUMP24:\ttarget=0x%08lx\toffset=(0x%08x)", (unsigned long) ((char *) target - (char *) e), sym_addr);
+ if (sym_addr & 1)
+ {
+ grub_uint32_t tr_addr;
+ grub_int32_t new_offset;
+ tr_addr = (char *) tr - (char *) pe_target
+ - target_section_addr;
+ new_offset = sym_addr - tr_addr - 12;
+
+ /* There is no immediate version of bx, only register one... */
+ tr[0] = grub_host_to_target32 (0xe59fc004); /* ldr ip, [pc, #4] */
+ tr[1] = grub_host_to_target32 (0xe08cc00f); /* add ip, ip, pc */
+ tr[2] = grub_host_to_target32 (0xe12fff1c); /* bx ip */
+ tr[3] = grub_host_to_target32 (new_offset | 1);
+ tr += 4;
+ sym_addr = tr_addr;
+ }
+ sym_addr -= offset;
+ err = grub_arm_reloc_jump24 (target,
+ sym_addr);
+ if (err)
+ grub_util_error ("%s", grub_errmsg);
+ }
+ break;
+
+ default:
+ grub_util_error (_("relocation 0x%x is not implemented yet"),
+ (unsigned int) ELF_R_TYPE (info));
+ break;
+ }
+ break;
+ }
+#endif /* MKIMAGE_ELF32 */
+ case EM_RISCV:
+ {
+ grub_uint64_t *t64 = (grub_uint64_t *) target;
+ grub_uint32_t *t32 = (grub_uint32_t *) target;
+ grub_uint16_t *t16 = (grub_uint16_t *) target;
+ grub_uint8_t *t8 = (grub_uint8_t *) target;
+ grub_int64_t off = (long)sym_addr - target_section_addr - offset
+ - image_target->vaddr_offset;
+
+ /*
+ * Instructions and instruction encoding are documented in the RISC-V
+ * specification. This file is based on version 2.2:
+ *
+ * https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-spec-v2.2.pdf
+ */
+
+ sym_addr += addend;
+
+ switch (ELF_R_TYPE (info))
+ {
+ case R_RISCV_ADD8:
+ *t8 = *t8 + sym_addr;
+ break;
+ case R_RISCV_ADD16:
+ *t16 = grub_host_to_target16 (grub_target_to_host16 (*t16) + sym_addr);
+ break;
+ case R_RISCV_32:
+ case R_RISCV_ADD32:
+ *t32 = grub_host_to_target32 (grub_target_to_host32 (*t32) + sym_addr);
+ break;
+ case R_RISCV_64:
+ case R_RISCV_ADD64:
+ *t64 = grub_host_to_target64 (grub_target_to_host64 (*t64) + sym_addr);
+ break;
+
+ case R_RISCV_SUB8:
+ *t8 = sym_addr - *t8;
+ break;
+ case R_RISCV_SUB16:
+ *t16 = grub_host_to_target16 (grub_target_to_host16 (*t16) - sym_addr);
+ break;
+ case R_RISCV_SUB32:
+ *t32 = grub_host_to_target32 (grub_target_to_host32 (*t32) - sym_addr);
+ break;
+ case R_RISCV_SUB64:
+ *t64 = grub_host_to_target64 (grub_target_to_host64 (*t64) - sym_addr);
+ break;
+ case R_RISCV_BRANCH:
+ {
+ grub_uint32_t imm12 = (off & 0x1000) << (31 - 12);
+ grub_uint32_t imm11 = (off & 0x800) >> (11 - 7);
+ grub_uint32_t imm10_5 = (off & 0x7e0) << (30 - 10);
+ grub_uint32_t imm4_1 = (off & 0x1e) << (11 - 4);
+ *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0x1fff07f)
+ | imm12 | imm11 | imm10_5 | imm4_1);
+ }
+ break;
+ case R_RISCV_JAL:
+ {
+ grub_uint32_t imm20 = (off & 0x100000) << (31 - 20);
+ grub_uint32_t imm19_12 = (off & 0xff000);
+ grub_uint32_t imm11 = (off & 0x800) << (20 - 11);
+ grub_uint32_t imm10_1 = (off & 0x7fe) << (30 - 10);
+ *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfff)
+ | imm20 | imm19_12 | imm11 | imm10_1);
+ }
+ break;
+ case R_RISCV_CALL:
+ {
+ grub_uint32_t hi20, lo12;
+
+ if (off != (grub_int32_t)off)
+ grub_util_error ("target %lx not reachable from pc=%lx", (long)sym_addr, (long)((char *)target - (char *)e));
+
+ hi20 = (off + 0x800) & 0xfffff000;
+ lo12 = (off - hi20) & 0xfff;
+ t32[0] = grub_host_to_target32 ((grub_target_to_host32 (t32[0]) & 0xfff) | hi20);
+ t32[1] = grub_host_to_target32 ((grub_target_to_host32 (t32[1]) & 0xfffff) | (lo12 << 20));
+ }
+ break;
+ case R_RISCV_RVC_BRANCH:
+ {
+ grub_uint16_t imm8 = (off & 0x100) << (12 - 8);
+ grub_uint16_t imm7_6 = (off & 0xc0) >> (6 - 5);
+ grub_uint16_t imm5 = (off & 0x20) >> (5 - 2);
+ grub_uint16_t imm4_3 = (off & 0x18) << (12 - 5);
+ grub_uint16_t imm2_1 = (off & 0x6) << (12 - 10);
+ *t16 = grub_host_to_target16 ((grub_target_to_host16 (*t16) & 0xe383)
+ | imm8 | imm7_6 | imm5 | imm4_3 | imm2_1);
+ }
+ break;
+ case R_RISCV_RVC_JUMP:
+ {
+ grub_uint16_t imm11 = (off & 0x800) << (12 - 11);
+ grub_uint16_t imm10 = (off & 0x400) >> (10 - 8);
+ grub_uint16_t imm9_8 = (off & 0x300) << (12 - 11);
+ grub_uint16_t imm7 = (off & 0x80) >> (7 - 6);
+ grub_uint16_t imm6 = (off & 0x40) << (12 - 11);
+ grub_uint16_t imm5 = (off & 0x20) >> (5 - 2);
+ grub_uint16_t imm4 = (off & 0x10) << (12 - 5);
+ grub_uint16_t imm3_1 = (off & 0xe) << (12 - 10);
+ *t16 = grub_host_to_target16 ((grub_target_to_host16 (*t16) & 0xe003)
+ | imm11 | imm10 | imm9_8 | imm7 | imm6
+ | imm5 | imm4 | imm3_1);
+ }
+ break;
+ case R_RISCV_PCREL_HI20:
+ {
+ grub_int32_t hi20;
+
+ if (off != (grub_int32_t)off)
+ grub_util_error ("target %lx not reachable from pc=%lx", (long)sym_addr, (long)((char *)target - (char *)e));
+
+ hi20 = (off + 0x800) & 0xfffff000;
+ *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfff) | hi20);
+ }
+ break;
+ case R_RISCV_PCREL_LO12_I:
+ case R_RISCV_PCREL_LO12_S:
+ {
+ Elf_Rela *rel2;
+ Elf_Word k;
+ /* Search backwards for matching HI20 reloc. */
+ for (k = j, rel2 = (Elf_Rela *) ((char *) r - r_size);
+ k > 0;
+ k--, rel2 = (Elf_Rela *) ((char *) rel2 - r_size))
+ {
+ Elf_Addr rel2_info;
+ Elf_Addr rel2_offset;
+ Elf_Addr rel2_sym_addr;
+ Elf_Addr rel2_addend;
+ Elf_Addr rel2_loc;
+ grub_int64_t rel2_off;
+
+ rel2_offset = grub_target_to_host (rel2->r_offset);
+ rel2_info = grub_target_to_host (rel2->r_info);
+ rel2_loc = target_section_addr + rel2_offset + image_target->vaddr_offset;
+
+ if (ELF_R_TYPE (rel2_info) == R_RISCV_PCREL_HI20
+ && rel2_loc == sym_addr)
+ {
+ rel2_sym_addr = SUFFIX (get_symbol_address)
+ (e, smd->symtab, ELF_R_SYM (rel2_info),
+ image_target);
+ rel2_addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ?
+ grub_target_to_host (rel2->r_addend) : 0;
+ rel2_off = rel2_sym_addr + rel2_addend - rel2_loc;
+ off = rel2_off - ((rel2_off + 0x800) & 0xfffff000);
+
+ if (ELF_R_TYPE (info) == R_RISCV_PCREL_LO12_I)
+ *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfffff) | (off & 0xfff) << 20);
+ else
+ {
+ grub_uint32_t imm11_5 = (off & 0xfe0) << (31 - 11);
+ grub_uint32_t imm4_0 = (off & 0x1f) << (11 - 4);
+ *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0x1fff07f) | imm11_5 | imm4_0);
+ }
+ break;
+ }
+ }
+ if (k == 0)
+ grub_util_error ("cannot find matching HI20 relocation");
+ }
+ break;
+ case R_RISCV_HI20:
+ *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfff) | (((grub_int32_t) sym_addr + 0x800) & 0xfffff000));
+ break;
+ case R_RISCV_LO12_I:
+ {
+ grub_int32_t lo12 = (grub_int32_t) sym_addr - (((grub_int32_t) sym_addr + 0x800) & 0xfffff000);
+ *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfffff) | ((lo12 & 0xfff) << 20));
+ }
+ break;
+ case R_RISCV_LO12_S:
+ {
+ grub_int32_t lo12 = (grub_int32_t) sym_addr - (((grub_int32_t) sym_addr + 0x800) & 0xfffff000);
+ grub_uint32_t imm11_5 = (lo12 & 0xfe0) << (31 - 11);
+ grub_uint32_t imm4_0 = (lo12 & 0x1f) << (11 - 4);
+ *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0x1fff07f) | imm11_5 | imm4_0);
+ }
+ break;
+ case R_RISCV_RELAX:
+ break;
+ default:
+ grub_util_error (_("relocation 0x%x is not implemented yet"),
+ (unsigned int) ELF_R_TYPE (info));
+ break;
+ }
+ break;
+ }
+ default:
+ grub_util_error ("unknown architecture type %d",
+ image_target->elf_target);
+ }
+ }
+ }
+}
+
+/* Add a PE32's fixup entry for a relocation. Return the resulting address
+ after having written to the file OUT. */
+static Elf_Addr
+add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type,
+ Elf_Addr addr, int flush, Elf_Addr current_address,
+ const struct grub_install_image_target_desc *image_target)
+{
+ struct grub_pe32_fixup_block *b;
+
+ b = &((*cblock)->b);
+
+ /* First, check if it is necessary to write out the current block. */
+ if ((*cblock)->state)
+ {
+ if (flush || (type && (addr < b->page_rva || b->page_rva + 0x1000 <= addr)))
+ {
+ grub_uint32_t size;
+
+ if (flush)
+ {
+ /* Add as much padding as necessary to align the address
+ with a section boundary. */
+ Elf_Addr next_address;
+ unsigned padding_size;
+ size_t cur_index;
+
+ next_address = current_address + b->block_size;
+ padding_size = ((ALIGN_UP (next_address, image_target->section_align)
+ - next_address)
+ >> 1);
+ cur_index = ((b->block_size - sizeof (*b)) >> 1);
+ grub_util_info ("adding %d padding fixup entries", padding_size);
+ while (padding_size--)
+ {
+ b->entries[cur_index++] = 0;
+ b->block_size += 2;
+ }
+ }
+ else while (b->block_size & (8 - 1))
+ {
+ /* If not aligned with a 32-bit boundary, add
+ a padding entry. */
+ size_t cur_index;
+
+ grub_util_info ("adding a padding fixup entry");
+ cur_index = ((b->block_size - sizeof (*b)) >> 1);
+ b->entries[cur_index] = 0;
+ b->block_size += 2;
+ }
+
+ /* Flush it. */
+ grub_util_info ("writing %d bytes of a fixup block starting at 0x%x",
+ b->block_size, b->page_rva);
+ size = b->block_size;
+ current_address += size;
+ b->page_rva = grub_host_to_target32 (b->page_rva);
+ b->block_size = grub_host_to_target32 (b->block_size);
+ (*cblock)->next = xmalloc (sizeof (**cblock) + 2 * 0x1000);
+ memset ((*cblock)->next, 0, sizeof (**cblock) + 2 * 0x1000);
+ *cblock = (*cblock)->next;
+ }
+ }
+
+ b = &((*cblock)->b);
+
+ if (! flush)
+ {
+ grub_uint16_t entry;
+ size_t cur_index;
+
+ /* If not allocated yet, allocate a block with enough entries. */
+ if (! (*cblock)->state)
+ {
+ (*cblock)->state = 1;
+
+ /* The spec does not mention the requirement of a Page RVA.
+ Here, align the address with a 4K boundary for safety. */
+ if (type)
+ b->page_rva = (addr & ~(0x1000 - 1));
+ b->block_size = sizeof (*b);
+ }
+
+ /* Sanity check. */
+ if (b->block_size >= sizeof (*b) + 2 * 0x1000)
+ grub_util_error ("too many fixup entries");
+
+ /* Add a new entry. */
+ cur_index = ((b->block_size - sizeof (*b)) >> 1);
+ entry = GRUB_PE32_FIXUP_ENTRY (type, type ? (addr - b->page_rva) : addr);
+ b->entries[cur_index] = grub_host_to_target16 (entry);
+ b->block_size += 2;
+ }
+
+ return current_address;
+}
+
+struct raw_reloc
+{
+ struct raw_reloc *next;
+ grub_uint32_t offset;
+ enum raw_reloc_type {
+ RAW_RELOC_NONE = -1,
+ RAW_RELOC_32 = 0,
+ RAW_RELOC_MAX = 1,
+ } type;
+};
+
+struct translate_context
+{
+ /* PE */
+ struct fixup_block_list *lst, *lst0;
+ Elf_Addr current_address;
+
+ /* Raw */
+ struct raw_reloc *raw_relocs;
+};
+
+static void
+translate_reloc_start (struct translate_context *ctx,
+ const struct grub_install_image_target_desc *image_target)
+{
+ grub_memset (ctx, 0, sizeof (*ctx));
+ if (image_target->id == IMAGE_EFI)
+ {
+ ctx->lst = ctx->lst0 = xmalloc (sizeof (*ctx->lst) + 2 * 0x1000);
+ memset (ctx->lst, 0, sizeof (*ctx->lst) + 2 * 0x1000);
+ ctx->current_address = 0;
+ }
+}
+
+static void
+translate_relocation_pe (struct translate_context *ctx,
+ Elf_Addr addr,
+ Elf_Addr info,
+ Elf_Addr sym_addr,
+ Elf_Addr addend,
+ const struct grub_install_image_target_desc *image_target)
+{
+ /* Necessary to relocate only absolute addresses. */
+ switch (image_target->elf_target)
+ {
+ case EM_386:
+ if (ELF_R_TYPE (info) == R_386_32)
+ {
+ grub_util_info ("adding a relocation entry for 0x%"
+ GRUB_HOST_PRIxLONG_LONG,
+ (unsigned long long) addr);
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_HIGHLOW,
+ addr, 0, ctx->current_address,
+ image_target);
+ }
+ break;
+ case EM_X86_64:
+ if ((ELF_R_TYPE (info) == R_X86_64_32) ||
+ (ELF_R_TYPE (info) == R_X86_64_32S))
+ {
+ grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)");
+ }
+ else if (ELF_R_TYPE (info) == R_X86_64_64)
+ {
+ grub_util_info ("adding a relocation entry for 0x%"
+ GRUB_HOST_PRIxLONG_LONG,
+ (unsigned long long) addr);
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_DIR64,
+ addr,
+ 0, ctx->current_address,
+ image_target);
+ }
+ break;
+ case EM_IA_64:
+ switch (ELF_R_TYPE (info))
+ {
+ case R_IA64_PCREL64LSB:
+ case R_IA64_LDXMOV:
+ case R_IA64_PCREL21B:
+ case R_IA64_LTOFF_FPTR22:
+ case R_IA64_LTOFF22X:
+ case R_IA64_LTOFF22:
+ case R_IA64_GPREL22:
+ case R_IA64_GPREL64I:
+ case R_IA64_SEGREL64LSB:
+ break;
+
+ case R_IA64_FPTR64LSB:
+ case R_IA64_DIR64LSB:
+#if 1
+ {
+ grub_util_info ("adding a relocation entry for 0x%"
+ GRUB_HOST_PRIxLONG_LONG,
+ (unsigned long long) addr);
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_DIR64,
+ addr,
+ 0, ctx->current_address,
+ image_target);
+ }
+#endif
+ break;
+ default:
+ grub_util_error (_("relocation 0x%x is not implemented yet"),
+ (unsigned int) ELF_R_TYPE (info));
+ break;
+ }
+ break;
+ case EM_AARCH64:
+ switch (ELF_R_TYPE (info))
+ {
+ case R_AARCH64_ABS64:
+ {
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_DIR64,
+ addr, 0, ctx->current_address,
+ image_target);
+ }
+ break;
+ /* Relative relocations do not require fixup entries. */
+ case R_AARCH64_CALL26:
+ case R_AARCH64_JUMP26:
+ case R_AARCH64_PREL32:
+ break;
+ /* Page-relative relocations do not require fixup entries. */
+ case R_AARCH64_ADR_PREL_PG_HI21:
+ /* We page-align the whole kernel, so no need
+ for fixup entries.
+ */
+ case R_AARCH64_ADD_ABS_LO12_NC:
+ case R_AARCH64_LDST64_ABS_LO12_NC:
+ break;
+
+ /* GOT is relocated separately. */
+ case R_AARCH64_ADR_GOT_PAGE:
+ case R_AARCH64_LD64_GOT_LO12_NC:
+ break;
+
+ default:
+ grub_util_error (_("relocation 0x%x is not implemented yet"),
+ (unsigned int) ELF_R_TYPE (info));
+ break;
+ }
+ break;
+#if defined(MKIMAGE_ELF64)
+ case EM_MIPS:
+ switch (ELF_R_TYPE (info))
+ {
+ case R_MIPS_64:
+ {
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_DIR64,
+ addr, 0, ctx->current_address,
+ image_target);
+ }
+ break;
+ case R_MIPS_32:
+#if 0
+ {
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_HIGHLOW,
+ addr, 0, ctx->current_address,
+ image_target);
+ }
+#endif
+ break;
+ case R_MIPS_26:
+ {
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_MIPS_JMPADDR,
+ addr, 0, ctx->current_address,
+ image_target);
+ }
+ break;
+ case R_MIPS_LO16:
+ {
+ Elf_Addr target = sym_addr + addend;
+
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_MIPS_LOW,
+ addr, 0, ctx->current_address,
+ image_target);
+ /* Hi */
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst, 0,
+ (grub_int16_t) ((target & 0x8000UL) >> 16),
+ 0, ctx->current_address,
+ image_target);
+ /* Higher */
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst, 0,
+ (grub_int16_t) ((target & 0x80008000UL) >> 32),
+ 0, ctx->current_address,
+ image_target);
+ /* Highest */
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst, 0,
+ (grub_uint16_t) ((target & 0x800080008000UL) >> 48),
+ 0, ctx->current_address,
+ image_target);
+ }
+ break;
+ case R_MIPS_HI16:
+ {
+ Elf_Addr target = sym_addr + addend;
+
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_MIPS_HIGH,
+ addr, 0, ctx->current_address,
+ image_target);
+ /* Lo */
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst, 0,
+ (grub_int16_t) target,
+ 0, ctx->current_address,
+ image_target);
+ /* Higher */
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst, 0,
+ (grub_int16_t) ((target & 0x80008000UL) >> 32),
+ 0, ctx->current_address,
+ image_target);
+ /* Highest */
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst, 0,
+ (grub_uint16_t) ((target & 0x800080008000UL) >> 48),
+ 0, ctx->current_address,
+ image_target);
+ }
+ break;
+ case R_MIPS_HIGHER:
+ {
+ Elf_Addr target = sym_addr + addend;
+
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_MIPS_HIGHER,
+ addr, 0, ctx->current_address,
+ image_target);
+ /* Lo */
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst, 0,
+ (grub_int16_t) target,
+ 0, ctx->current_address,
+ image_target);
+ /* Hi */
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst, 0,
+ (grub_int16_t) ((target & 0x8000UL) >> 16),
+ 0, ctx->current_address,
+ image_target);
+ /* Highest */
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst, 0,
+ (grub_uint16_t) ((target & 0x800080008000UL) >> 48),
+ 0, ctx->current_address,
+ image_target);
+ }
+ break;
+ case R_MIPS_HIGHEST:
+ {
+ Elf_Addr target = sym_addr + addend;
+
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_MIPS_HIGHEST,
+ addr, 0, ctx->current_address,
+ image_target);
+ /* Lo */
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst, 0,
+ (grub_int16_t) target,
+ 0, ctx->current_address,
+ image_target);
+ /* Hi */
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst, 0,
+ (grub_int16_t) ((target & 0x8000UL) >> 16),
+ 0, ctx->current_address,
+ image_target);
+ /* Higher */
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst, 0,
+ (grub_int16_t) ((target & 0x80008000UL) >> 32),
+ 0, ctx->current_address,
+ image_target);
+ }
+ break;
+ default:
+ grub_util_error (_("relocation 0x%x is not implemented yet"),
+ (unsigned int) ELF_R_TYPE (info));
+ break;
+ }
+ break;
+#endif
+#if defined(MKIMAGE_ELF32)
+ case EM_ARM:
+ switch (ELF_R_TYPE (info))
+ {
+ case R_ARM_V4BX:
+ /* Relative relocations do not require fixup entries. */
+ case R_ARM_JUMP24:
+ case R_ARM_THM_CALL:
+ case R_ARM_THM_JUMP19:
+ case R_ARM_THM_JUMP24:
+ case R_ARM_CALL:
+ {
+ grub_util_info (" %s: not adding fixup: 0x%08x : 0x%08x", __FUNCTION__, (unsigned int) addr, (unsigned int) ctx->current_address);
+ }
+ break;
+ /* Create fixup entry for PE/COFF loader */
+ case R_ARM_ABS32:
+ {
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_HIGHLOW,
+ addr, 0, ctx->current_address,
+ image_target);
+ }
+ break;
+ default:
+ grub_util_error (_("relocation 0x%x is not implemented yet"),
+ (unsigned int) ELF_R_TYPE (info));
+ break;
+ }
+ break;
+#endif /* defined(MKIMAGE_ELF32) */
+ case EM_RISCV:
+ switch (ELF_R_TYPE (info))
+ {
+ case R_RISCV_32:
+ {
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_HIGHLOW,
+ addr, 0, ctx->current_address,
+ image_target);
+ }
+ break;
+ case R_RISCV_64:
+ {
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_DIR64,
+ addr, 0, ctx->current_address,
+ image_target);
+ }
+ break;
+ /* Relative relocations do not require fixup entries. */
+ case R_RISCV_BRANCH:
+ case R_RISCV_JAL:
+ case R_RISCV_CALL:
+ case R_RISCV_PCREL_HI20:
+ case R_RISCV_PCREL_LO12_I:
+ case R_RISCV_PCREL_LO12_S:
+ case R_RISCV_RVC_BRANCH:
+ case R_RISCV_RVC_JUMP:
+ case R_RISCV_ADD32:
+ case R_RISCV_SUB32:
+ grub_util_info (" %s: not adding fixup: 0x%08x : 0x%08x", __FUNCTION__, (unsigned int) addr, (unsigned int) ctx->current_address);
+ break;
+ case R_RISCV_HI20:
+ {
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_RISCV_HI20,
+ addr, 0, ctx->current_address,
+ image_target);
+ }
+ break;
+ case R_RISCV_LO12_I:
+ {
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_RISCV_LOW12I,
+ addr, 0, ctx->current_address,
+ image_target);
+ }
+ break;
+ case R_RISCV_LO12_S:
+ {
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_RISCV_LOW12S,
+ addr, 0, ctx->current_address,
+ image_target);
+ }
+ break;
+ case R_RISCV_RELAX:
+ break;
+ default:
+ grub_util_error (_("relocation 0x%x is not implemented yet"),
+ (unsigned int) ELF_R_TYPE (info));
+ break;
+ }
+ break;
+ default:
+ grub_util_error ("unknown machine type 0x%x", image_target->elf_target);
+ }
+}
+
+static enum raw_reloc_type
+classify_raw_reloc (Elf_Addr info,
+ const struct grub_install_image_target_desc *image_target)
+{
+ /* Necessary to relocate only absolute addresses. */
+ switch (image_target->elf_target)
+ {
+ case EM_ARM:
+ switch (ELF_R_TYPE (info))
+ {
+ case R_ARM_V4BX:
+ case R_ARM_JUMP24:
+ case R_ARM_THM_CALL:
+ case R_ARM_THM_JUMP19:
+ case R_ARM_THM_JUMP24:
+ case R_ARM_CALL:
+ return RAW_RELOC_NONE;
+ case R_ARM_ABS32:
+ return RAW_RELOC_32;
+ default:
+ grub_util_error (_("relocation 0x%x is not implemented yet"),
+ (unsigned int) ELF_R_TYPE (info));
+ break;
+ }
+ break;
+ default:
+ grub_util_error ("unknown machine type 0x%x", image_target->elf_target);
+ }
+}
+
+static void
+translate_relocation_raw (struct translate_context *ctx,
+ Elf_Addr addr,
+ Elf_Addr info,
+ const struct grub_install_image_target_desc *image_target)
+{
+ enum raw_reloc_type class = classify_raw_reloc (info, image_target);
+ struct raw_reloc *rel;
+ if (class == RAW_RELOC_NONE)
+ return;
+ rel = xmalloc (sizeof (*rel));
+ rel->next = ctx->raw_relocs;
+ rel->type = class;
+ rel->offset = addr;
+ ctx->raw_relocs = rel;
+}
+
+static void
+translate_relocation (struct translate_context *ctx,
+ Elf_Addr addr,
+ Elf_Addr info,
+ Elf_Addr sym_addr,
+ Elf_Addr addend,
+ const struct grub_install_image_target_desc *image_target)
+{
+ if (image_target->id == IMAGE_EFI)
+ translate_relocation_pe (ctx, addr, info, sym_addr, addend, image_target);
+ else
+ translate_relocation_raw (ctx, addr, info, image_target);
+}
+
+static void
+finish_reloc_translation_pe (struct translate_context *ctx, struct grub_mkimage_layout *layout,
+ const struct grub_install_image_target_desc *image_target)
+{
+ ctx->current_address = add_fixup_entry (&ctx->lst, 0, 0, 1, ctx->current_address, image_target);
+
+ {
+ grub_uint8_t *ptr;
+ layout->reloc_section = ptr = xmalloc (ctx->current_address);
+ for (ctx->lst = ctx->lst0; ctx->lst; ctx->lst = ctx->lst->next)
+ if (ctx->lst->state)
+ {
+ memcpy (ptr, &ctx->lst->b, grub_target_to_host32 (ctx->lst->b.block_size));
+ ptr += grub_target_to_host32 (ctx->lst->b.block_size);
+ }
+ assert ((ctx->current_address + (grub_uint8_t *) layout->reloc_section) == ptr);
+ }
+
+ for (ctx->lst = ctx->lst0; ctx->lst; )
+ {
+ struct fixup_block_list *next;
+ next = ctx->lst->next;
+ free (ctx->lst);
+ ctx->lst = next;
+ }
+
+ layout->reloc_size = ctx->current_address;
+ if (image_target->elf_target == EM_ARM && layout->reloc_size > GRUB_KERNEL_ARM_STACK_SIZE)
+ grub_util_error ("Reloc section (%d) is bigger than stack size (%d). "
+ "This breaks assembly assumptions. Please increase stack size",
+ (int) layout->reloc_size,
+ (int) GRUB_KERNEL_ARM_STACK_SIZE);
+}
+
+/*
+ Layout:
+ <type 0 relocations>
+ <fffffffe>
+ <type 1 relocations>
+ <fffffffe>
+ ...
+ <type n relocations>
+ <ffffffff>
+ each relocation starts with 32-bit offset. Rest depends on relocation.
+ mkimage stops when it sees first unknown type or end marker.
+ This allows images to be created with mismatched mkimage and
+ kernel as long as no relocations are present in kernel that mkimage
+ isn't aware of (in which case mkimage aborts).
+ This also allows simple assembly to do the relocs.
+*/
+
+#define RAW_SEPARATOR 0xfffffffe
+#define RAW_END_MARKER 0xffffffff
+
+static void
+finish_reloc_translation_raw (struct translate_context *ctx, struct grub_mkimage_layout *layout,
+ const struct grub_install_image_target_desc *image_target)
+{
+ size_t count = 0, sz;
+ enum raw_reloc_type highest = RAW_RELOC_NONE;
+ enum raw_reloc_type curtype;
+ struct raw_reloc *cur;
+ grub_uint32_t *p;
+ if (!ctx->raw_relocs)
+ {
+ layout->reloc_section = p = xmalloc (sizeof (grub_uint32_t));
+ p[0] = RAW_END_MARKER;
+ layout->reloc_size = sizeof (grub_uint32_t);
+ return;
+ }
+ for (cur = ctx->raw_relocs; cur; cur = cur->next)
+ {
+ count++;
+ if (cur->type > highest)
+ highest = cur->type;
+ }
+ /* highest separators, count relocations and one end marker. */
+ sz = (highest + count + 1) * sizeof (grub_uint32_t);
+ layout->reloc_section = p = xmalloc (sz);
+ for (curtype = 0; curtype <= highest; curtype++)
+ {
+ /* Support for special cases would go here. */
+ for (cur = ctx->raw_relocs; cur; cur = cur->next)
+ if (cur->type == curtype)
+ {
+ *p++ = cur->offset;
+ }
+ *p++ = RAW_SEPARATOR;
+ }
+ *--p = RAW_END_MARKER;
+ layout->reloc_size = sz;
+}
+
+static void
+finish_reloc_translation (struct translate_context *ctx, struct grub_mkimage_layout *layout,
+ const struct grub_install_image_target_desc *image_target)
+{
+ if (image_target->id == IMAGE_EFI)
+ finish_reloc_translation_pe (ctx, layout, image_target);
+ else
+ finish_reloc_translation_raw (ctx, layout, image_target);
+}
+
+
+static void
+create_u64_fixups (struct translate_context *ctx,
+ Elf_Addr jumpers, grub_size_t njumpers,
+ const struct grub_install_image_target_desc *image_target)
+{
+ unsigned i;
+ assert (image_target->id == IMAGE_EFI);
+ for (i = 0; i < njumpers; i++)
+ ctx->current_address = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_DIR64,
+ jumpers + 8 * i,
+ 0, ctx->current_address,
+ image_target);
+}
+
+/* Make a .reloc section. */
+static void
+make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout,
+ struct section_metadata *smd,
+ const struct grub_install_image_target_desc *image_target)
+{
+ unsigned i;
+ Elf_Shdr *s;
+ struct translate_context ctx;
+
+ translate_reloc_start (&ctx, image_target);
+
+ for (i = 0, s = smd->sections; i < smd->num_sections;
+ i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
+ if ((grub_target_to_host32 (s->sh_type) == SHT_REL) ||
+ (grub_target_to_host32 (s->sh_type) == SHT_RELA))
+ {
+ Elf_Rela *r;
+ Elf_Word rtab_size, r_size, num_rs;
+ Elf_Off rtab_offset;
+ Elf_Shdr *symtab_section;
+ Elf_Addr section_address;
+ Elf_Word j;
+
+ if (!SUFFIX (is_kept_reloc_section) (s, image_target, smd))
+ {
+ grub_util_info ("not translating the skipped relocation section %s",
+ smd->strtab + grub_le_to_cpu32 (s->sh_name));
+ continue;
+ }
+
+ symtab_section = (Elf_Shdr *) ((char *) smd->sections
+ + (grub_target_to_host32 (s->sh_link)
+ * smd->section_entsize));
+
+ grub_util_info ("translating the relocation section %s",
+ smd->strtab + grub_le_to_cpu32 (s->sh_name));
+
+ rtab_size = grub_target_to_host (s->sh_size);
+ r_size = grub_target_to_host (s->sh_entsize);
+ rtab_offset = grub_target_to_host (s->sh_offset);
+ num_rs = rtab_size / r_size;
+
+ section_address = smd->vaddrs[grub_le_to_cpu32 (s->sh_info)];
+
+ for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset);
+ j < num_rs;
+ j++, r = (Elf_Rela *) ((char *) r + r_size))
+ {
+ Elf_Addr info;
+ Elf_Addr offset;
+ Elf_Addr addr;
+ Elf_Addr sym_addr;
+ Elf_Addr addend;
+
+ offset = grub_target_to_host (r->r_offset);
+ if (image_target->elf_target == EM_MIPS && image_target->voidp_sizeof == 8)
+ info = ((grub_uint64_t) r->r_info << 32) |
+ (grub_uint32_t) grub_be_to_cpu64 (r->r_info);
+ else
+ info = grub_target_to_host (r->r_info);
+
+ sym_addr = SUFFIX (get_symbol_address) (e, symtab_section,
+ ELF_R_SYM (info), image_target);
+ addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ?
+ grub_target_to_host (r->r_addend) : 0;
+ addr = section_address + offset;
+
+ translate_relocation (&ctx, addr, info, sym_addr, addend, image_target);
+ }
+ }
+
+ if (image_target->elf_target == EM_IA_64)
+ create_u64_fixups (&ctx,
+ layout->ia64jmp_off
+ + image_target->vaddr_offset,
+ 2 * layout->ia64jmpnum,
+ image_target);
+ if (image_target->elf_target == EM_IA_64 || image_target->elf_target == EM_AARCH64)
+ create_u64_fixups (&ctx,
+ layout->got_off
+ + image_target->vaddr_offset,
+ (layout->got_size / 8),
+ image_target);
+
+ finish_reloc_translation (&ctx, layout, image_target);
+}
+
+/* Determine if this section is a text section. Return false if this
+ section is not allocated. */
+static int
+SUFFIX (is_text_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target)
+{
+ if (!is_relocatable (image_target)
+ && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS)
+ return 0;
+ return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC))
+ == (SHF_EXECINSTR | SHF_ALLOC));
+}
+
+/* Determine if this section is a data section. */
+static int
+SUFFIX (is_data_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target)
+{
+ if (!is_relocatable (image_target)
+ && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS)
+ return 0;
+ return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC))
+ == SHF_ALLOC) && !(grub_target_to_host32 (s->sh_type) == SHT_NOBITS);
+}
+
+static int
+SUFFIX (is_bss_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target)
+{
+ if (!is_relocatable (image_target))
+ return 0;
+ return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC))
+ == SHF_ALLOC) && (grub_target_to_host32 (s->sh_type) == SHT_NOBITS);
+}
+
+/* Determine if a section is going to be in the final output */
+static int
+SUFFIX (is_kept_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target)
+{
+ /* We keep .text and .data */
+ if (SUFFIX (is_text_section) (s, image_target)
+ || SUFFIX (is_data_section) (s, image_target))
+ return 1;
+
+ /*
+ * And we keep .bss if we're producing PE binaries or the target doesn't
+ * have a relocating loader. Platforms other than EFI and U-boot shouldn't
+ * have .bss in their binaries as we build with -Wl,-Ttext.
+ */
+ if (SUFFIX (is_bss_section) (s, image_target)
+ && (image_target->id == IMAGE_EFI || !is_relocatable (image_target)))
+ return 1;
+
+ /* Otherwise this is not a section we're keeping in the final output. */
+ return 0;
+}
+
+static int
+SUFFIX (is_kept_reloc_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target,
+ struct section_metadata *smd)
+{
+ int i;
+ int r = 0;
+ const char *name = smd->strtab + grub_host_to_target32 (s->sh_name);
+
+ if (!strncmp (name, ".rela.", 6))
+ name += 5;
+ else if (!strncmp (name, ".rel.", 5))
+ name += 4;
+ else
+ return 1;
+
+ for (i = 0, s = smd->sections; i < smd->num_sections;
+ i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
+ {
+ const char *sname = smd->strtab + grub_host_to_target32 (s->sh_name);
+ if (strcmp (sname, name))
+ continue;
+
+ return SUFFIX (is_kept_section) (s, image_target);
+ }
+
+ return r;
+}
+
+/* Return if the ELF header is valid. */
+static int
+SUFFIX (check_elf_header) (Elf_Ehdr *e, size_t size, const struct grub_install_image_target_desc *image_target)
+{
+ if (size < sizeof (*e)
+ || e->e_ident[EI_MAG0] != ELFMAG0
+ || e->e_ident[EI_MAG1] != ELFMAG1
+ || e->e_ident[EI_MAG2] != ELFMAG2
+ || e->e_ident[EI_MAG3] != ELFMAG3
+ || e->e_ident[EI_VERSION] != EV_CURRENT
+ || e->e_ident[EI_CLASS] != ELFCLASSXX
+ || e->e_version != grub_host_to_target32 (EV_CURRENT))
+ return 0;
+
+ return 1;
+}
+
+static Elf_Addr
+SUFFIX (put_section) (Elf_Shdr *s, int i,
+ Elf_Addr current_address,
+ struct section_metadata *smd,
+ const struct grub_install_image_target_desc *image_target)
+{
+ Elf_Word align = grub_host_to_target_addr (s->sh_addralign);
+ const char *name = smd->strtab + grub_host_to_target32 (s->sh_name);
+
+ if (align)
+ current_address = ALIGN_UP (current_address + image_target->vaddr_offset,
+ align)
+ - image_target->vaddr_offset;
+
+ grub_util_info ("locating the section %s at 0x%"
+ GRUB_HOST_PRIxLONG_LONG,
+ name, (unsigned long long) current_address);
+ if (!is_relocatable (image_target))
+ current_address = grub_host_to_target_addr (s->sh_addr)
+ - image_target->link_addr;
+ smd->addrs[i] = current_address;
+ current_address += grub_host_to_target_addr (s->sh_size);
+ return current_address;
+}
+
+/*
+ * Locate section addresses by merging code sections and data sections
+ * into .text and .data, respectively.
+ */
+static void
+SUFFIX (locate_sections) (Elf_Ehdr *e, const char *kernel_path,
+ struct section_metadata *smd,
+ struct grub_mkimage_layout *layout,
+ const struct grub_install_image_target_desc *image_target)
+{
+ int i;
+ Elf_Shdr *s;
+
+ layout->align = 1;
+ /* Page-aligning simplifies relocation handling. */
+ if (image_target->elf_target == EM_AARCH64)
+ layout->align = 4096;
+
+ layout->kernel_size = 0;
+
+ for (i = 0, s = smd->sections;
+ i < smd->num_sections;
+ i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
+ if ((grub_target_to_host (s->sh_flags) & SHF_ALLOC)
+ && grub_host_to_target32 (s->sh_addralign) > layout->align)
+ layout->align = grub_host_to_target32 (s->sh_addralign);
+
+ /* .text */
+ for (i = 0, s = smd->sections;
+ i < smd->num_sections;
+ i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
+ if (SUFFIX (is_text_section) (s, image_target))
+ {
+ layout->kernel_size = SUFFIX (put_section) (s, i, layout->kernel_size,
+ smd, image_target);
+ if (!is_relocatable (image_target) &&
+ grub_host_to_target_addr (s->sh_addr) != image_target->link_addr)
+ {
+ char *msg
+ = grub_xasprintf (_("`%s' is miscompiled: its start address is 0x%llx"
+ " instead of 0x%llx: ld.gold bug?"),
+ kernel_path,
+ (unsigned long long) grub_host_to_target_addr (s->sh_addr),
+ (unsigned long long) image_target->link_addr);
+ grub_util_error ("%s", msg);
+ }
+ }
+
+#ifdef MKIMAGE_ELF32
+ if (image_target->elf_target == EM_ARM)
+ {
+ grub_size_t tramp;
+
+ layout->kernel_size = ALIGN_UP (layout->kernel_size, 16);
+
+ tramp = arm_get_trampoline_size (e, smd->sections, smd->section_entsize,
+ smd->num_sections, image_target);
+
+ layout->tramp_off = layout->kernel_size;
+ layout->kernel_size += ALIGN_UP (tramp, 16);
+ }
+#endif
+
+ layout->kernel_size = ALIGN_UP (layout->kernel_size + image_target->vaddr_offset,
+ image_target->section_align)
+ - image_target->vaddr_offset;
+ layout->exec_size = layout->kernel_size;
+
+ /* .data */
+ for (i = 0, s = smd->sections;
+ i < smd->num_sections;
+ i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
+ if (SUFFIX (is_data_section) (s, image_target))
+ layout->kernel_size = SUFFIX (put_section) (s, i, layout->kernel_size, smd,
+ image_target);
+
+ layout->bss_start = layout->kernel_size;
+ layout->end = layout->kernel_size;
+
+ /* .bss */
+ for (i = 0, s = smd->sections;
+ i < smd->num_sections;
+ i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
+ {
+ if (SUFFIX (is_bss_section) (s, image_target))
+ layout->end = SUFFIX (put_section) (s, i, layout->end, smd, image_target);
+
+ /*
+ * This must to be in the last time this function passes through the loop.
+ */
+ smd->vaddrs[i] = smd->addrs[i] + image_target->vaddr_offset;
+ }
+
+ layout->end = ALIGN_UP (layout->end + image_target->vaddr_offset,
+ image_target->section_align) - image_target->vaddr_offset;
+ /* Explicitly initialize BSS
+ when producing PE32 to avoid a bug in EFI implementations.
+ Platforms other than EFI and U-boot shouldn't have .bss in
+ their binaries as we build with -Wl,-Ttext.
+ */
+ if (image_target->id == IMAGE_EFI || !is_relocatable (image_target))
+ layout->kernel_size = layout->end;
+}
+
+char *
+SUFFIX (grub_mkimage_load_image) (const char *kernel_path,
+ size_t total_module_size,
+ struct grub_mkimage_layout *layout,
+ const struct grub_install_image_target_desc *image_target)
+{
+ char *kernel_img, *out_img;
+ struct section_metadata smd = { 0, 0, 0, 0, 0, 0, 0 };
+ Elf_Ehdr *e;
+ int i;
+ Elf_Shdr *s;
+ Elf_Off section_offset;
+ grub_size_t kernel_size;
+
+ grub_memset (layout, 0, sizeof (*layout));
+
+ layout->start_address = 0;
+
+ kernel_size = grub_util_get_image_size (kernel_path);
+ kernel_img = xmalloc (kernel_size);
+ grub_util_load_image (kernel_path, kernel_img);
+
+ e = (Elf_Ehdr *) kernel_img;
+ if (! SUFFIX (check_elf_header) (e, kernel_size, image_target))
+ grub_util_error ("invalid ELF header");
+
+ section_offset = grub_target_to_host (e->e_shoff);
+ smd.section_entsize = grub_target_to_host16 (e->e_shentsize);
+ smd.num_sections = grub_target_to_host16 (e->e_shnum);
+
+ if (kernel_size < section_offset
+ + (grub_uint32_t) smd.section_entsize * smd.num_sections)
+ grub_util_error (_("premature end of file %s"), kernel_path);
+
+ smd.sections = (Elf_Shdr *) (kernel_img + section_offset);
+
+ /* Relocate sections then symbols in the virtual address space. */
+ s = (Elf_Shdr *) ((char *) smd.sections
+ + grub_host_to_target16 (e->e_shstrndx) * smd.section_entsize);
+ smd.strtab = (char *) e + grub_host_to_target_addr (s->sh_offset);
+
+ smd.addrs = xmalloc (sizeof (*smd.addrs) * smd.num_sections);
+ memset (smd.addrs, 0, sizeof (*smd.addrs) * smd.num_sections);
+ smd.vaddrs = xmalloc (sizeof (*smd.vaddrs) * smd.num_sections);
+ memset (smd.vaddrs, 0, sizeof (*smd.vaddrs) * smd.num_sections);
+
+ SUFFIX (locate_sections) (e, kernel_path, &smd, layout, image_target);
+
+ if (!is_relocatable (image_target))
+ {
+ Elf_Addr current_address = layout->kernel_size;
+
+ for (i = 0, s = smd.sections;
+ i < smd.num_sections;
+ i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize))
+ if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS)
+ {
+ Elf_Word sec_align = grub_host_to_target_addr (s->sh_addralign);
+ const char *name = smd.strtab + grub_host_to_target32 (s->sh_name);
+
+ if (sec_align)
+ current_address = ALIGN_UP (current_address
+ + image_target->vaddr_offset,
+ sec_align)
+ - image_target->vaddr_offset;
+
+ grub_util_info ("locating the section %s at 0x%"
+ GRUB_HOST_PRIxLONG_LONG,
+ name, (unsigned long long) current_address);
+ if (!is_relocatable (image_target))
+ current_address = grub_host_to_target_addr (s->sh_addr)
+ - image_target->link_addr;
+
+ smd.vaddrs[i] = current_address
+ + image_target->vaddr_offset;
+ current_address += grub_host_to_target_addr (s->sh_size);
+ }
+ current_address = ALIGN_UP (current_address + image_target->vaddr_offset,
+ image_target->section_align)
+ - image_target->vaddr_offset;
+ layout->bss_size = current_address - layout->kernel_size;
+ }
+ else
+ layout->bss_size = 0;
+
+ if (image_target->id == IMAGE_SPARC64_AOUT
+ || image_target->id == IMAGE_SPARC64_RAW
+ || image_target->id == IMAGE_UBOOT
+ || image_target->id == IMAGE_COREBOOT
+ || image_target->id == IMAGE_SPARC64_CDCORE)
+ layout->kernel_size = ALIGN_UP (layout->kernel_size, image_target->mod_align);
+
+ if (is_relocatable (image_target))
+ {
+ smd.symtab = NULL;
+ for (i = 0, s = smd.sections;
+ i < smd.num_sections;
+ i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize))
+ if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB))
+ {
+ smd.symtab = s;
+ break;
+ }
+ if (! smd.symtab)
+ grub_util_error ("%s", _("no symbol table"));
+#ifdef MKIMAGE_ELF64
+ if (image_target->elf_target == EM_IA_64)
+ {
+ grub_size_t tramp;
+
+ layout->kernel_size = ALIGN_UP (layout->kernel_size, 16);
+
+ grub_ia64_dl_get_tramp_got_size (e, &tramp, &layout->got_size);
+
+ layout->tramp_off = layout->kernel_size;
+ layout->kernel_size += ALIGN_UP (tramp, 16);
+
+ layout->ia64jmp_off = layout->kernel_size;
+ layout->ia64jmpnum = SUFFIX (count_funcs) (e, smd.symtab,
+ image_target);
+ layout->kernel_size += 16 * layout->ia64jmpnum;
+
+ layout->got_off = layout->kernel_size;
+ layout->kernel_size += ALIGN_UP (layout->got_size, 16);
+ }
+ if (image_target->elf_target == EM_AARCH64)
+ {
+ grub_size_t tramp;
+
+ layout->kernel_size = ALIGN_UP (layout->kernel_size, 16);
+
+ grub_arm64_dl_get_tramp_got_size (e, &tramp, &layout->got_size);
+
+ layout->got_off = layout->kernel_size;
+ layout->kernel_size += ALIGN_UP (layout->got_size, 16);
+ }
+#endif
+ }
+ else
+ {
+ layout->reloc_size = 0;
+ layout->reloc_section = NULL;
+ }
+
+ out_img = xmalloc (layout->kernel_size + total_module_size);
+ memset (out_img, 0, layout->kernel_size + total_module_size);
+
+ if (is_relocatable (image_target))
+ {
+ layout->start_address = SUFFIX (relocate_symbols) (e, &smd,
+ (char *) out_img + layout->ia64jmp_off,
+ layout->ia64jmp_off + image_target->vaddr_offset,
+ layout->bss_start, layout->end, image_target);
+
+ if (layout->start_address == (Elf_Addr) -1)
+ grub_util_error ("start symbol is not defined");
+
+ /* Resolve addrs in the virtual address space. */
+ SUFFIX (relocate_addrs) (e, &smd, out_img, layout->tramp_off,
+ layout->got_off, image_target);
+
+ make_reloc_section (e, layout, &smd, image_target);
+ if (image_target->id != IMAGE_EFI)
+ {
+ out_img = xrealloc (out_img, layout->kernel_size + total_module_size
+ + ALIGN_UP (layout->reloc_size, image_target->mod_align));
+ memcpy (out_img + layout->kernel_size, layout->reloc_section, layout->reloc_size);
+ memset (out_img + layout->kernel_size + layout->reloc_size, 0,
+ total_module_size + ALIGN_UP (layout->reloc_size, image_target->mod_align) - layout->reloc_size);
+ layout->kernel_size += ALIGN_UP (layout->reloc_size, image_target->mod_align);
+ }
+ }
+
+ for (i = 0, s = smd.sections;
+ i < smd.num_sections;
+ i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize))
+ if (SUFFIX (is_kept_section) (s, image_target))
+ {
+ if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS)
+ memset (out_img + smd.addrs[i], 0,
+ grub_host_to_target_addr (s->sh_size));
+ else
+ memcpy (out_img + smd.addrs[i],
+ kernel_img + grub_host_to_target_addr (s->sh_offset),
+ grub_host_to_target_addr (s->sh_size));
+ }
+ free (kernel_img);
+
+ free (smd.vaddrs);
+ smd.vaddrs = NULL;
+ free (smd.addrs);
+ smd.addrs = NULL;
+
+ return out_img;
+}
--- /dev/null
+/*
+ * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <config.h>
+
+#include <grub/util/install.h>
+#include <grub/emu/config.h>
+#include <grub/util/misc.h>
+
+#include <string.h>
+#include <errno.h>
+
+#pragma GCC diagnostic ignored "-Wmissing-prototypes"
+#pragma GCC diagnostic ignored "-Wmissing-declarations"
+#include <argp.h>
+#pragma GCC diagnostic error "-Wmissing-prototypes"
+#pragma GCC diagnostic error "-Wmissing-declarations"
+
+static char *rootdir = NULL, *subdir = NULL;
+static char *debug_image = NULL;
+
+enum
+ {
+ OPTION_NET_DIRECTORY = 0x301,
+ OPTION_SUBDIR,
+ OPTION_DEBUG,
+ OPTION_DEBUG_IMAGE
+ };
+
+static struct argp_option options[] = {
+ GRUB_INSTALL_OPTIONS,
+ {"net-directory", OPTION_NET_DIRECTORY, N_("DIR"),
+ 0, N_("root directory of TFTP server"), 2},
+ {"subdir", OPTION_SUBDIR, N_("DIR"),
+ 0, N_("relative subdirectory on network server"), 2},
+ {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2},
+ {"debug-image", OPTION_DEBUG_IMAGE, N_("STRING"), OPTION_HIDDEN, 0, 2},
+ {0, 0, 0, 0, 0, 0}
+};
+
+static error_t
+argp_parser (int key, char *arg, struct argp_state *state)
+{
+ if (grub_install_parse (key, arg))
+ return 0;
+ switch (key)
+ {
+ case OPTION_NET_DIRECTORY:
+ free (rootdir);
+ rootdir = xstrdup (arg);
+ return 0;
+ case OPTION_SUBDIR:
+ free (subdir);
+ subdir = xstrdup (arg);
+ return 0;
+ /* This is an undocumented feature... */
+ case OPTION_DEBUG:
+ verbosity++;
+ return 0;
+ case OPTION_DEBUG_IMAGE:
+ free (debug_image);
+ debug_image = xstrdup (arg);
+ return 0;
+
+ case ARGP_KEY_ARG:
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+}
+
+
+struct argp argp = {
+ options, argp_parser, NULL,
+ "\v"N_("Prepares GRUB network boot images at net_directory/subdir "
+ "assuming net_directory being TFTP root."),
+ NULL, grub_install_help_filter, NULL
+};
+
+static char *base;
+
+static const struct
+{
+ const char *mkimage_target;
+ const char *netmodule;
+ const char *ext;
+} targets[GRUB_INSTALL_PLATFORM_MAX] =
+ {
+ [GRUB_INSTALL_PLATFORM_I386_PC] = { "i386-pc-pxe", "pxe", ".0" },
+ [GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64-ieee1275-aout", "ofnet", ".img" },
+ [GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386-ieee1275", "ofnet", ".elf" },
+ [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc-ieee1275", "ofnet", ".elf" },
+ [GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386-efi", "efinet", ".efi" },
+ [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64-efi", "efinet", ".efi" },
+ [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64-efi", "efinet", ".efi" },
+ [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm-efi", "efinet", ".efi" },
+ [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64-efi", "efinet", ".efi" },
+ [GRUB_INSTALL_PLATFORM_MIPS64EL_EFI] = { "mips64el-efi", "efinet", ".efi" },
+ [GRUB_INSTALL_PLATFORM_RISCV32_EFI] = { "riscv32-efi", "efinet", ".efi" },
+ [GRUB_INSTALL_PLATFORM_RISCV64_EFI] = { "riscv64-efi", "efinet", ".efi" },
+ };
+
+static void
+process_input_dir (const char *input_dir, enum grub_install_plat platform)
+{
+ char *platsub = grub_install_get_platform_name (platform);
+ char *grubdir = grub_util_path_concat (3, rootdir, subdir, platsub);
+ char *load_cfg = grub_util_path_concat (2, grubdir, "load.cfg");
+ char *prefix;
+ char *output;
+ char *grub_cfg;
+ FILE *cfg;
+
+ grub_install_copy_files (input_dir, base, platform);
+ grub_util_unlink (load_cfg);
+
+ if (debug_image)
+ {
+ FILE *f = grub_util_fopen (load_cfg, "wb");
+ if (!f)
+ grub_util_error (_("cannot open `%s': %s"), load_cfg,
+ strerror (errno));
+ fprintf (f, "set debug='%s'\n", debug_image);
+ fclose (f);
+ }
+ else
+ {
+ free (load_cfg);
+ load_cfg = 0;
+ }
+
+ prefix = xasprintf ("/%s", subdir);
+ if (!targets[platform].mkimage_target)
+ grub_util_error (_("unsupported platform %s"), platsub);
+
+ grub_cfg = grub_util_path_concat (2, grubdir, "grub.cfg");
+ cfg = grub_util_fopen (grub_cfg, "wb");
+ if (!cfg)
+ grub_util_error (_("cannot open `%s': %s"), grub_cfg,
+ strerror (errno));
+ fprintf (cfg, "source %s/grub.cfg", subdir);
+ fclose (cfg);
+
+ grub_install_push_module (targets[platform].netmodule);
+
+ output = grub_util_path_concat_ext (2, grubdir, "core", targets[platform].ext);
+ grub_install_make_image_wrap (input_dir, prefix, output,
+ 0, load_cfg,
+ targets[platform].mkimage_target, 0);
+ grub_install_pop_module ();
+
+ /* TRANSLATORS: First %s is replaced by platform name. Second one by filename. */
+ printf (_("Netboot directory for %s created. Configure your DHCP server to point to %s\n"),
+ platsub, output);
+
+ free (platsub);
+ free (output);
+ free (prefix);
+ free (grub_cfg);
+ free (grubdir);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ const char *pkglibdir;
+
+ grub_util_host_init (&argc, &argv);
+ grub_util_disable_fd_syncs ();
+ rootdir = xstrdup ("/srv/tftp");
+ pkglibdir = grub_util_get_pkglibdir ();
+
+ subdir = grub_util_path_concat (2, GRUB_BOOT_DIR_NAME, GRUB_DIR_NAME);
+
+ argp_parse (&argp, argc, argv, 0, 0, 0);
+
+ base = grub_util_path_concat (2, rootdir, subdir);
+ /* Create the GRUB directory if it is not present. */
+
+ grub_install_mkdir_p (base);
+
+ grub_install_push_module ("tftp");
+
+ if (!grub_install_source_directory)
+ {
+ enum grub_install_plat plat;
+
+ for (plat = 0; plat < GRUB_INSTALL_PLATFORM_MAX; plat++)
+ if (targets[plat].mkimage_target)
+ {
+ char *platdir = grub_util_path_concat (2, pkglibdir,
+ grub_install_get_platform_name (plat));
+
+ grub_util_info ("Looking for `%s'", platdir);
+
+ if (!grub_util_is_directory (platdir))
+ {
+ free (platdir);
+ continue;
+ }
+ process_input_dir (platdir, plat);
+ }
+ }
+ else
+ {
+ enum grub_install_plat plat;
+ plat = grub_install_get_target (grub_install_source_directory);
+ process_input_dir (grub_install_source_directory, plat);
+ }
+ return 0;
+}
--- /dev/null
+/*
+ * Make GRUB rescue image
+ *
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <grub/util/install.h>
+#include <grub/util/misc.h>
+#include <grub/emu/exec.h>
+#include <grub/emu/config.h>
+#include <grub/emu/hostdisk.h>
+#pragma GCC diagnostic ignored "-Wmissing-prototypes"
+#pragma GCC diagnostic ignored "-Wmissing-declarations"
+#include <argp.h>
+#pragma GCC diagnostic error "-Wmissing-prototypes"
+#pragma GCC diagnostic error "-Wmissing-declarations"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <string.h>
+#include <time.h>
+
+static char *source_dirs[GRUB_INSTALL_PLATFORM_MAX];
+static char *rom_directory;
+static char *label_font;
+static char *label_color;
+static char *label_bgcolor;
+static char *product_name;
+static char *product_version;
+static char *output_image;
+static char *xorriso;
+static char *boot_grub;
+static int xorriso_argc;
+static int xorriso_arg_alloc;
+static char **xorriso_argv;
+static char *iso_uuid;
+static char *iso9660_dir;
+
+static void
+xorriso_push (const char *val)
+{
+ if (xorriso_arg_alloc <= xorriso_argc + 1)
+ {
+ xorriso_arg_alloc = 2 * (4 + xorriso_argc);
+ xorriso_argv = xrealloc (xorriso_argv,
+ sizeof (xorriso_argv[0])
+ * xorriso_arg_alloc);
+ }
+ xorriso_argv[xorriso_argc++] = xstrdup (val);
+}
+
+static void
+xorriso_link (const char *from, const char *to)
+{
+ char *tof = grub_util_path_concat (2, iso9660_dir, to);
+ char *val = xasprintf ("%s=%s", from, tof);
+ xorriso_push (val);
+ free (val);
+ free (tof);
+}
+
+enum
+ {
+ OPTION_OUTPUT = 'o',
+ OPTION_ROM_DIRECTORY = 0x301,
+ OPTION_XORRISO,
+ OPTION_GLUE_EFI,
+ OPTION_RENDER_LABEL,
+ OPTION_LABEL_FONT,
+ OPTION_LABEL_COLOR,
+ OPTION_LABEL_BGCOLOR,
+ OPTION_PRODUCT_NAME,
+ OPTION_PRODUCT_VERSION,
+ OPTION_SPARC_BOOT,
+ OPTION_ARCS_BOOT
+ };
+
+static struct argp_option options[] = {
+ GRUB_INSTALL_OPTIONS,
+ {"output", 'o', N_("FILE"),
+ 0, N_("save output in FILE [required]"), 2},
+ {"rom-directory", OPTION_ROM_DIRECTORY, N_("DIR"),
+ 0, N_("save ROM images in DIR [optional]"), 2},
+ {"xorriso", OPTION_XORRISO, N_("FILE"),
+ /* TRANSLATORS: xorriso is a program for creating ISOs and burning CDs. */
+ 0, N_("use FILE as xorriso [optional]"), 2},
+ {"grub-glue-efi", OPTION_GLUE_EFI, N_("FILE"), OPTION_HIDDEN, 0, 2},
+ {"grub-render-label", OPTION_RENDER_LABEL, N_("FILE"), OPTION_HIDDEN, 0, 2},
+ {"label-font", OPTION_LABEL_FONT, N_("FILE"), 0, N_("use FILE as font for label"), 2},
+ {"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2},
+ {"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2},
+ {"product-name", OPTION_PRODUCT_NAME, N_("STRING"), 0, N_("use STRING as product name"), 2},
+ {"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2},
+ {"sparc-boot", OPTION_SPARC_BOOT, 0, 0, N_("enable sparc boot. Disables HFS+, APM, ARCS and boot as disk image for i386-pc"), 2},
+ {"arcs-boot", OPTION_ARCS_BOOT, 0, 0, N_("enable ARCS (big-endian mips machines, mostly SGI) boot. Disables HFS+, APM, sparc64 and boot as disk image for i386-pc"), 2},
+ {0, 0, 0, 0, 0, 0}
+};
+
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+
+static char *
+help_filter (int key, const char *text, void *input __attribute__ ((unused)))
+{
+ switch (key)
+ {
+ case ARGP_KEY_HELP_PRE_DOC:
+ /* TRANSLATORS: it generates one single image which is bootable through any method. */
+ return strdup (_("Make GRUB CD-ROM, disk, pendrive and floppy bootable image."));
+ case ARGP_KEY_HELP_POST_DOC:
+ {
+ char *p1, *out;
+
+ p1 = xasprintf (_("Generates a bootable CD/USB/floppy image. Arguments other than options to this program"
+ " are passed to xorriso, and indicate source files, source directories, or any of the "
+ "mkisofs options listed by the output of `%s'."), "xorriso -as mkisofs -help");
+ out = xasprintf ("%s\n\n%s\n\n%s", p1,
+ _("Option -- switches to native xorriso command mode."),
+ _("Mail xorriso support requests to <bug-xorriso@gnu.org>."));
+ free (p1);
+ return out;
+ }
+ default:
+ return grub_install_help_filter (key, text, input);
+ }
+}
+
+#pragma GCC diagnostic error "-Wformat-nonliteral"
+
+enum {
+ SYS_AREA_AUTO,
+ SYS_AREA_COMMON,
+ SYS_AREA_SPARC,
+ SYS_AREA_ARCS
+} system_area = SYS_AREA_AUTO;
+
+static error_t
+argp_parser (int key, char *arg, struct argp_state *state)
+{
+ if (grub_install_parse (key, arg))
+ return 0;
+ switch (key)
+ {
+ case OPTION_OUTPUT:
+ free (output_image);
+ output_image = xstrdup (arg);
+ return 0;
+ case OPTION_ROM_DIRECTORY:
+ free (rom_directory);
+ rom_directory = xstrdup (arg);
+ return 0;
+
+ /*
+ FIXME:
+ # Intentionally undocumented
+ --grub-mkimage-extra)
+ mkimage_extra_arg="$mkimage_extra_arg `argument $option "$@"`"; shift ;;
+ --grub-mkimage-extra=*)
+ mkimage_extra_arg="$mkimage_extra_arg `echo "$option" | sed 's/--grub-mkimage-extra=//'`" ;;
+ */
+ case OPTION_SPARC_BOOT:
+ system_area = SYS_AREA_SPARC;
+ return 0;
+ case OPTION_ARCS_BOOT:
+ system_area = SYS_AREA_ARCS;
+ return 0;
+ case OPTION_PRODUCT_NAME:
+ free (product_name);
+ product_name = xstrdup (arg);
+ return 0;
+ case OPTION_PRODUCT_VERSION:
+ free (product_version);
+ product_version = xstrdup (arg);
+ return 0;
+ /* Accept and ignore for compatibility. */
+ case OPTION_GLUE_EFI:
+ case OPTION_RENDER_LABEL:
+ return 0;
+ case OPTION_LABEL_FONT:
+ free (label_font);
+ label_font = xstrdup (arg);
+ return 0;
+
+ case OPTION_LABEL_COLOR:
+ free (label_color);
+ label_color = xstrdup (arg);
+ return 0;
+
+ case OPTION_LABEL_BGCOLOR:
+ free (label_bgcolor);
+ label_bgcolor = xstrdup (arg);
+ return 0;
+
+ case OPTION_XORRISO:
+ free (xorriso);
+ xorriso = xstrdup (arg);
+ return 0;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+}
+
+struct argp argp = {
+ options, argp_parser, N_("[OPTION] SOURCE..."),
+ NULL, NULL, help_filter, NULL
+};
+
+static void
+write_part (FILE *f, const char *srcdir)
+{
+ FILE *in;
+ char *inname = grub_util_path_concat (2, srcdir, "partmap.lst");
+ char buf[260];
+ in = grub_util_fopen (inname, "rb");
+ if (!in)
+ return;
+ while (fgets (buf, 256, in))
+ {
+ char *ptr;
+ for (ptr = buf + strlen (buf) - 1;
+ ptr >= buf && (*ptr == '\n' || *ptr == '\r');
+ ptr--);
+ ptr[1] = '\0';
+ fprintf (f, "insmod %s\n", buf);
+ }
+ fclose (in);
+}
+
+static void
+make_image_abs (enum grub_install_plat plat,
+ const char *mkimage_target,
+ const char *output)
+{
+ char *load_cfg;
+ FILE *load_cfg_f;
+
+ if (!source_dirs[plat])
+ return;
+
+ grub_util_info (N_("enabling %s support ..."),
+ mkimage_target);
+
+ load_cfg = grub_util_make_temporary_file ();
+
+ load_cfg_f = grub_util_fopen (load_cfg, "wb");
+ fprintf (load_cfg_f, "search --fs-uuid --set=root %s\n", iso_uuid);
+ fprintf (load_cfg_f, "set prefix=(${root})/boot/grub\n");
+
+ write_part (load_cfg_f, source_dirs[plat]);
+ fclose (load_cfg_f);
+
+ grub_install_push_module ("search");
+ grub_install_push_module ("iso9660");
+ grub_install_make_image_wrap (source_dirs[plat], "/boot/grub", output,
+ 0, load_cfg,
+ mkimage_target, 0);
+ grub_install_pop_module ();
+ grub_install_pop_module ();
+ grub_util_unlink (load_cfg);
+}
+
+static void
+make_image (enum grub_install_plat plat,
+ const char *mkimage_target,
+ const char *output_sub)
+{
+ char *out = grub_util_path_concat (2, boot_grub, output_sub);
+ make_image_abs (plat, mkimage_target, out);
+ free (out);
+}
+
+static void
+make_image_fwdisk_abs (enum grub_install_plat plat,
+ const char *mkimage_target,
+ const char *output)
+{
+ char *load_cfg;
+ FILE *load_cfg_f;
+
+ if (!source_dirs[plat])
+ return;
+
+ grub_util_info (N_("enabling %s support ..."),
+ mkimage_target);
+
+ load_cfg = grub_util_make_temporary_file ();
+
+ load_cfg_f = grub_util_fopen (load_cfg, "wb");
+ write_part (load_cfg_f, source_dirs[plat]);
+ fclose (load_cfg_f);
+
+ grub_install_push_module ("iso9660");
+ grub_install_make_image_wrap (source_dirs[plat], "()/boot/grub", output,
+ 0, load_cfg, mkimage_target, 0);
+ grub_install_pop_module ();
+ grub_util_unlink (load_cfg);
+}
+
+static int
+check_xorriso (const char *val)
+{
+ const char *argv[5];
+ int fd;
+ pid_t pid;
+ FILE *mdadm;
+ char *buf = NULL;
+ size_t len = 0;
+ int ret = 0;
+ int wstatus = 0;
+
+ argv[0] = xorriso;
+ argv[1] = "-as";
+ argv[2] = "mkisofs";
+ argv[3] = "-help";
+ argv[4] = NULL;
+
+ pid = grub_util_exec_pipe_stderr (argv, &fd);
+
+ if (!pid)
+ return 0;
+
+ /* Parent. Read mdadm's output. */
+ mdadm = fdopen (fd, "r");
+ if (! mdadm)
+ return 0;
+
+ while (getline (&buf, &len, mdadm) > 0)
+ {
+ if (grub_strstr (buf, val))
+ ret = 1;
+ }
+
+ close (fd);
+ waitpid (pid, &wstatus, 0);
+ free (buf);
+ if (!WIFEXITED (wstatus) || WEXITSTATUS(wstatus) != 0)
+ return 0;
+ return ret;
+}
+
+static void
+make_image_fwdisk (enum grub_install_plat plat,
+ const char *mkimage_target,
+ const char *output_sub)
+{
+ char *out = grub_util_path_concat (2, boot_grub, output_sub);
+ make_image_fwdisk_abs (plat, mkimage_target, out);
+ free (out);
+}
+
+static int
+option_is_end (const struct argp_option *opt)
+{
+ return !opt->key && !opt->name && !opt->doc && !opt->group;
+}
+
+
+static int
+args_to_eat (const char *arg)
+{
+ int j;
+
+ if (arg[0] != '-')
+ return 0;
+
+ if (arg[1] == '-')
+ {
+ for (j = 0; !option_is_end(&options[j]); j++)
+ {
+ size_t len = strlen (options[j].name);
+ if (strncmp (arg + 2, options[j].name, len) == 0)
+ {
+ if (arg[2 + len] == '=')
+ return 1;
+ if (arg[2 + len] == '\0' && options[j].arg)
+ return 2;
+ if (arg[2 + len] == '\0')
+ return 1;
+ }
+ }
+ if (strcmp (arg, "--help") == 0)
+ return 1;
+ if (strcmp (arg, "--usage") == 0)
+ return 1;
+ if (strcmp (arg, "--version") == 0)
+ return 1;
+ return 0;
+ }
+ if (arg[2] && arg[3])
+ return 0;
+ for (j = 0; !option_is_end(&options[j]); j++)
+ {
+ if (options[j].key > 0 && options[j].key < 128 && arg[1] == options[j].key)
+ {
+ if (options[j].arg)
+ return 2;
+ return 1;
+ }
+ if (arg[1] == '?')
+ return 1;
+ }
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ char *romdir;
+ char *sysarea_img = NULL;
+ const char *pkgdatadir;
+ int argp_argc;
+ char **argp_argv;
+ int xorriso_tail_argc;
+ char **xorriso_tail_argv;
+ int rv;
+
+ grub_util_host_init (&argc, &argv);
+ grub_util_disable_fd_syncs ();
+
+ pkgdatadir = grub_util_get_pkgdatadir ();
+
+ product_name = xstrdup (PACKAGE_NAME);
+ product_version = xstrdup (PACKAGE_VERSION);
+ xorriso = xstrdup ("xorriso");
+ label_font = grub_util_path_concat (2, pkgdatadir, "unicode.pf2");
+
+ argp_argv = xmalloc (sizeof (argp_argv[0]) * argc);
+ xorriso_tail_argv = xmalloc (sizeof (argp_argv[0]) * argc);
+
+ xorriso_tail_argc = 0;
+ /* Program name */
+ argp_argv[0] = argv[0];
+ argp_argc = 1;
+
+ /* argp doesn't allow us to catch unknwon arguments,
+ so catch them before passing to argp
+ */
+ {
+ int i;
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], "-output") == 0) {
+ argp_argv[argp_argc++] = (char *) "--output";
+ i++;
+ argp_argv[argp_argc++] = argv[i];
+ continue;
+ }
+ switch (args_to_eat (argv[i]))
+ {
+ case 2:
+ argp_argv[argp_argc++] = argv[i++];
+ /* Fallthrough */
+ case 1:
+ argp_argv[argp_argc++] = argv[i];
+ break;
+ case 0:
+ xorriso_tail_argv[xorriso_tail_argc++] = argv[i];
+ break;
+ }
+ }
+ }
+
+ argp_parse (&argp, argp_argc, argp_argv, 0, 0, 0);
+
+ if (!output_image)
+ grub_util_error ("%s", _("output file must be specified"));
+
+ if (!check_xorriso ("graft-points")) {
+ grub_util_error ("%s", _("xorriso not found"));
+ }
+
+ grub_init_all ();
+ grub_hostfs_init ();
+ grub_host_init ();
+
+ xorriso_push (xorriso);
+ xorriso_push ("-as");
+ xorriso_push ("mkisofs");
+ xorriso_push ("-graft-points");
+
+ iso9660_dir = grub_util_make_temporary_dir ();
+ grub_util_info ("temporary iso9660 dir is `%s'", iso9660_dir);
+ boot_grub = grub_util_path_concat (3, iso9660_dir, "boot", "grub");
+ grub_install_mkdir_p (boot_grub);
+ romdir = grub_util_path_concat (2, boot_grub, "roms");
+ grub_util_mkdir (romdir);
+
+ if (!grub_install_source_directory)
+ {
+ const char *pkglibdir = grub_util_get_pkglibdir ();
+ enum grub_install_plat plat;
+
+ for (plat = 0; plat < GRUB_INSTALL_PLATFORM_MAX; plat++)
+ {
+ char *platdir = grub_util_path_concat (2, pkglibdir,
+ grub_install_get_platform_name (plat));
+
+ if (!grub_util_is_directory (platdir))
+ {
+ free (platdir);
+ continue;
+ }
+ source_dirs[plat] = platdir;
+ grub_install_copy_files (platdir,
+ boot_grub, plat);
+ }
+ }
+ else
+ {
+ enum grub_install_plat plat;
+ plat = grub_install_get_target (grub_install_source_directory);
+ grub_install_copy_files (grub_install_source_directory,
+ boot_grub, plat);
+ source_dirs[plat] = xstrdup (grub_install_source_directory);
+ }
+ if (system_area == SYS_AREA_AUTO || grub_install_source_directory)
+ {
+ if (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC]
+ || source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275]
+ || source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_MIPS64EL_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_RISCV32_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_RISCV64_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI])
+ system_area = SYS_AREA_COMMON;
+ else if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275])
+ system_area = SYS_AREA_SPARC;
+ else if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC])
+ system_area = SYS_AREA_ARCS;
+ }
+
+ /* obtain date-based UUID. */
+ {
+ time_t tim;
+ struct tm *tmm;
+ tim = time (NULL);
+ tmm = gmtime (&tim);
+ iso_uuid = xmalloc (55);
+ grub_snprintf (iso_uuid, 50,
+ "%04d-%02d-%02d-%02d-%02d-%02d-00",
+ tmm->tm_year + 1900,
+ tmm->tm_mon + 1,
+ tmm->tm_mday,
+ tmm->tm_hour,
+ tmm->tm_min,
+ tmm->tm_sec);
+ }
+ {
+ char *uuid_out = xmalloc (strlen (iso_uuid) + 1 + 40);
+ char *optr;
+ const char *iptr;
+ optr = grub_stpcpy (uuid_out, "--modification-date=");
+ for (iptr = iso_uuid; *iptr; iptr++)
+ if (*iptr != '-')
+ *optr++ = *iptr;
+ *optr = '\0';
+ xorriso_push (uuid_out);
+ free (uuid_out);
+ }
+
+ /* build BIOS core.img. */
+ if (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC])
+ {
+ char *load_cfg;
+ FILE *load_cfg_f;
+ char *output = grub_util_path_concat (3, boot_grub, "i386-pc", "eltorito.img");
+ load_cfg = grub_util_make_temporary_file ();
+
+ grub_util_info (N_("enabling %s support ..."), "BIOS");
+ load_cfg_f = grub_util_fopen (load_cfg, "wb");
+ write_part (load_cfg_f, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC]);
+ fclose (load_cfg_f);
+
+ grub_install_push_module ("biosdisk");
+ grub_install_push_module ("iso9660");
+ grub_install_make_image_wrap (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC],
+ "/boot/grub", output,
+ 0, load_cfg,
+ "i386-pc-eltorito", 0);
+
+ xorriso_push ("-b");
+ xorriso_push ("boot/grub/i386-pc/eltorito.img");
+ xorriso_push ("-no-emul-boot");
+ xorriso_push ("-boot-load-size");
+ xorriso_push ("4");
+ xorriso_push ("-boot-info-table");
+ if (system_area == SYS_AREA_COMMON)
+ {
+ if (check_xorriso ("grub2-boot-info"))
+ {
+ char *boot_hybrid = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC],
+ "boot_hybrid.img");
+ xorriso_push ("--grub2-boot-info");
+ xorriso_push ("--grub2-mbr");
+ xorriso_push (boot_hybrid);
+ }
+ else
+ {
+ FILE *sa, *bi;
+ size_t sz;
+ char buf[512];
+ char *bin = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC],
+ "boot.img");
+ grub_util_warn ("%s", _("Your xorriso doesn't support `--grub2-boot-info'. Some features are disabled. Please use xorriso 1.2.9 or later."));
+ sysarea_img = grub_util_make_temporary_file ();
+ sa = grub_util_fopen (sysarea_img, "wb");
+ if (!sa)
+ grub_util_error (_("cannot open `%s': %s"), sysarea_img,
+ strerror (errno));
+ bi = grub_util_fopen (bin, "rb");
+ if (!bi)
+ grub_util_error (_("cannot open `%s': %s"), bin,
+ strerror (errno));
+ if (fread (buf, 1, 512, bi) != 512)
+ grub_util_error (_("cannot read `%s': %s"), bin,
+ strerror (errno));
+ fclose (bi);
+ fwrite (buf, 1, 512, sa);
+
+ grub_install_make_image_wrap_file (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC],
+ "/boot/grub", sa, sysarea_img,
+ 0, load_cfg,
+ "i386-pc", 0);
+ sz = ftello (sa);
+ fflush (sa);
+ grub_util_fd_sync (fileno (sa));
+ fclose (sa);
+
+ if (sz > 32768)
+ {
+ grub_util_warn ("%s", _("Your xorriso doesn't support `--grub2-boot-info'. Your core image is too big. Boot as disk is disabled. Please use xorriso 1.2.9 or later."));
+ }
+ else
+ {
+ xorriso_push ("-G");
+ xorriso_push (sysarea_img);
+ }
+ }
+ }
+ grub_install_pop_module ();
+ grub_install_pop_module ();
+ grub_util_unlink (load_cfg);
+ }
+
+ /** build multiboot core.img */
+ grub_install_push_module ("pata");
+ grub_install_push_module ("ahci");
+ grub_install_push_module ("at_keyboard");
+ make_image (GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, "i386-multiboot", "i386-multiboot/core.elf");
+ grub_install_pop_module ();
+ grub_install_pop_module ();
+ grub_install_pop_module ();
+
+ make_image_fwdisk (GRUB_INSTALL_PLATFORM_I386_IEEE1275, "i386-ieee1275", "ofwx86.elf");
+
+ char *core_services = NULL;
+
+ if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275])
+ {
+ char *mach_ker, *sv, *label, *label_text;
+ FILE *f;
+ core_services = grub_util_path_concat (4, iso9660_dir, "System", "Library", "CoreServices");
+ grub_install_mkdir_p (core_services);
+
+ mach_ker = grub_util_path_concat (2, iso9660_dir, "mach_kernel");
+ f = grub_util_fopen (mach_ker, "wb");
+ fclose (f);
+ free (mach_ker);
+
+ sv = grub_util_path_concat (2, core_services, "SystemVersion.plist");
+ f = grub_util_fopen (sv, "wb");
+ fprintf (f, "<plist version=\"1.0\">\n"
+ "<dict>\n"
+ " <key>ProductBuildVersion</key>\n"
+ " <string></string>\n"
+ " <key>ProductName</key>\n"
+ " <string>%s</string>\n"
+ " <key>ProductVersion</key>\n"
+ " <string>%s</string>\n"
+ "</dict>\n"
+ "</plist>\n", product_name, product_version);
+ fclose (f);
+ free (sv);
+ label = grub_util_path_concat (2, core_services, ".disk_label");
+ char *label_string = xasprintf ("%s %s", product_name, product_version);
+ grub_util_render_label (label_font, label_bgcolor ? : "white",
+ label_color ? : "black", label_string, label);
+ free (label);
+ label_text = grub_util_path_concat (2, core_services, ".disk_label.contentDetails");
+ f = grub_util_fopen (label_text, "wb");
+ fprintf (f, "%s\n", label_string);
+ fclose (f);
+ free (label_string);
+ free (label_text);
+ if (system_area == SYS_AREA_COMMON)
+ {
+ xorriso_push ("-hfsplus");
+ xorriso_push ("-apm-block-size");
+ xorriso_push ("2048");
+ xorriso_push ("-hfsplus-file-creator-type");
+ xorriso_push ("chrp");
+ xorriso_push ("tbxj");
+ xorriso_push ("/System/Library/CoreServices/.disk_label");
+
+ if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI])
+ {
+ xorriso_push ("-hfs-bless-by");
+ xorriso_push ("i");
+ xorriso_push ("/System/Library/CoreServices/boot.efi");
+ }
+ }
+ }
+
+ if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_MIPS64EL_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_RISCV32_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_RISCV64_EFI])
+ {
+ char *efidir = grub_util_make_temporary_dir ();
+ char *efidir_efi = grub_util_path_concat (2, efidir, "efi");
+ char *efidir_efi_boot = grub_util_path_concat (3, efidir, "efi", "boot");
+ char *imgname, *img32, *img64, *img_mac = NULL;
+ char *efiimgfat;
+ grub_install_mkdir_p (efidir_efi_boot);
+
+ grub_install_push_module ("part_gpt");
+ grub_install_push_module ("part_msdos");
+
+ imgname = grub_util_path_concat (2, efidir_efi_boot, "bootia64.efi");
+ make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_IA64_EFI, "ia64-efi", imgname);
+ free (imgname);
+
+ grub_install_push_module ("part_apple");
+ img64 = grub_util_path_concat (2, efidir_efi_boot, "bootx64.efi");
+ make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_X86_64_EFI, "x86_64-efi", img64);
+ grub_install_pop_module ();
+
+ grub_install_push_module ("part_apple");
+ img32 = grub_util_path_concat (2, efidir_efi_boot, "bootia32.efi");
+ make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_I386_EFI, "i386-efi", img32);
+ grub_install_pop_module ();
+
+ imgname = grub_util_path_concat (2, efidir_efi_boot, "bootarm.efi");
+ make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_ARM_EFI, "arm-efi", imgname);
+ free (imgname);
+
+ imgname = grub_util_path_concat (2, efidir_efi_boot, "bootaa64.efi");
+ make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_ARM64_EFI, "arm64-efi",
+ imgname);
+ free (imgname);
+
+ imgname = grub_util_path_concat (2, efidir_efi_boot, "bootmips64el.efi");
+ make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_MIPS64EL_EFI, "mips64el-efi",
+ imgname);
+ free (imgname);
+
+ imgname = grub_util_path_concat (2, efidir_efi_boot, "bootriscv32.efi");
+ make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_RISCV32_EFI, "riscv32-efi",
+ imgname);
+ free (imgname);
+
+ imgname = grub_util_path_concat (2, efidir_efi_boot, "bootriscv64.efi");
+ make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_RISCV64_EFI, "riscv64-efi",
+ imgname);
+ free (imgname);
+
+ if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI])
+ {
+ imgname = grub_util_path_concat (2, efidir_efi_boot, "boot.efi");
+ /* For old macs. Suggested by Peter Jones. */
+ grub_install_copy_file (img32, imgname, 1);
+ }
+
+ if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
+ || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI])
+ img_mac = grub_util_path_concat (2, core_services, "boot.efi");
+
+ if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
+ && source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI])
+ grub_util_glue_efi (img32, img64, img_mac);
+ else if (source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI])
+ grub_install_copy_file (img64, img_mac, 1);
+ else if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI])
+ grub_install_copy_file (img32, img_mac, 1);
+
+ free (img_mac);
+ free (img32);
+ free (img64);
+ free (efidir_efi_boot);
+
+ efiimgfat = grub_util_path_concat (2, iso9660_dir, "efi.img");
+ rv = grub_util_exec ((const char * []) { "mformat", "-C", "-f", "2880", "-L", "16", "-i",
+ efiimgfat, "::", NULL });
+ if (rv != 0)
+ grub_util_error ("`%s` invocation failed\n", "mformat");
+ rv = grub_util_exec ((const char * []) { "mcopy", "-s", "-i", efiimgfat, efidir_efi, "::/", NULL });
+ if (rv != 0)
+ grub_util_error ("`%s` invocation failed\n", "mcopy");
+ xorriso_push ("--efi-boot");
+ xorriso_push ("efi.img");
+ xorriso_push ("-efi-boot-part");
+ xorriso_push ("--efi-boot-image");
+
+ grub_util_unlink_recursive (efidir);
+ free (efiimgfat);
+ free (efidir_efi);
+ free (efidir);
+ grub_install_pop_module ();
+ grub_install_pop_module ();
+ }
+
+ grub_install_push_module ("part_apple");
+ make_image_fwdisk (GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, "powerpc-ieee1275", "powerpc-ieee1275/core.elf");
+ grub_install_pop_module ();
+
+ if (source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275])
+ {
+ char *grub_chrp = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275],
+ "grub.chrp");
+ char *bisrc = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275],
+ "bootinfo.txt");
+ char *bootx = grub_util_path_concat (2, core_services, "BootX");
+ char *ppc_chrp = grub_util_path_concat (3, iso9660_dir, "ppc", "chrp");
+ char *bitgt = grub_util_path_concat (3, iso9660_dir, "ppc", "bootinfo.txt");
+ grub_install_copy_file (grub_chrp, bootx, 1);
+ grub_install_mkdir_p (ppc_chrp);
+ grub_install_copy_file (bisrc, bitgt, 1);
+ xorriso_link ("/System/Library/CoreServices/grub.elf", "/boot/grub/powerpc-ieee1275/core.elf");
+ xorriso_link ("/boot/grub/powerpc.elf", "/boot/grub/powerpc-ieee1275/core.elf");
+ /* FIXME: add PreP */
+ if (system_area == SYS_AREA_COMMON)
+ {
+ xorriso_push ("-hfsplus-file-creator-type");
+ xorriso_push ("chrp");
+ xorriso_push ("tbxi");
+ xorriso_push ("/System/Library/CoreServices/BootX");
+ xorriso_push ("-hfs-bless-by");
+ xorriso_push ("p");
+ xorriso_push ("/System/Library/CoreServices");
+ }
+ xorriso_push ("-sysid");
+ xorriso_push ("PPC");
+ }
+
+ make_image_fwdisk (GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275,
+ "sparc64-ieee1275-cdcore", "sparc64-ieee1275/core.img");
+
+ if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275]
+ && system_area == SYS_AREA_SPARC)
+ {
+ char *cdboot;
+ FILE *in, *out;
+ char buf[512];
+ sysarea_img = grub_util_make_temporary_file ();
+ cdboot = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275],
+ "cdboot.img");
+ in = grub_util_fopen (cdboot, "rb");
+ if (!in)
+ grub_util_error (_("cannot open `%s': %s"), cdboot,
+ strerror (errno));
+ out = grub_util_fopen (sysarea_img, "wb");
+ if (!out)
+ grub_util_error (_("cannot open `%s': %s"), sysarea_img,
+ strerror (errno));
+ memset (buf, 0, 512);
+ fwrite (buf, 1, 512, out);
+ if (fread (buf, 1, 512, in) != 512)
+ grub_util_error (_("cannot read `%s': %s"), cdboot,
+ strerror (errno));
+ fwrite (buf, 1, 512, out);
+ fclose (in);
+ fclose (out);
+ xorriso_push ("-G");
+ xorriso_push (sysarea_img);
+ xorriso_push ("-B");
+ xorriso_push (",");
+ xorriso_push ("--grub2-sparc-core");
+ xorriso_push ("/boot/grub/sparc64-ieee1275/core.img");
+ }
+
+ make_image_fwdisk (GRUB_INSTALL_PLATFORM_MIPS_ARC, "mips-arc", "mips-arc/core.img");
+
+ if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC])
+ {
+ xorriso_link ("/boot/grub/mips-arc/grub", "/boot/grub/mips-arc/core.img");
+ xorriso_link ("/boot/grub/mips-arc/sashARCS", "/boot/grub/mips-arc/core.img");
+ xorriso_link ("/boot/grub/mips-arc/sash", "/boot/grub/mips-arc/core.img");
+ }
+ if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC] && system_area == SYS_AREA_ARCS)
+ {
+ xorriso_push ("-mips-boot");
+ xorriso_push ("/boot/grub/mips-arc/sashARCS");
+ xorriso_push ("-mips-boot");
+ xorriso_push ("/boot/grub/mips-arc/sash");
+ xorriso_push ("-mips-boot");
+ xorriso_push ("/boot/grub/mips-arc/grub");
+ }
+
+ make_image_fwdisk (GRUB_INSTALL_PLATFORM_MIPSEL_ARC, "mipsel-arc", "arc.exe");
+
+ grub_install_push_module ("pata");
+ make_image (GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "mipsel-qemu_mips-elf", "roms/mipsel-qemu_mips.elf");
+
+ make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-loongson-elf", "loongson.elf");
+
+ make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-yeeloong-flash", "mipsel-yeeloong.bin");
+ make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-fuloong2f-flash", "mipsel-fuloong2f.bin");
+
+ make_image (GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "mips-qemu_mips-elf", "roms/mips-qemu_mips.elf");
+
+ grub_install_push_module ("at_keyboard");
+
+ make_image (GRUB_INSTALL_PLATFORM_I386_QEMU, "i386-qemu", "roms/qemu.img");
+
+ grub_install_push_module ("ahci");
+
+ make_image (GRUB_INSTALL_PLATFORM_I386_COREBOOT, "i386-coreboot", "roms/coreboot.elf");
+ grub_install_pop_module ();
+ grub_install_pop_module ();
+ grub_install_pop_module ();
+
+ if (rom_directory)
+ {
+ const struct
+ {
+ enum grub_install_plat plat;
+ const char *from, *to;
+ } roms[] =
+ {
+ {GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "roms/mipsel-qemu_mips.elf", "mipsel-qemu_mips.elf"},
+ {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "loongson.elf", "mipsel-loongson.elf"},
+ {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "roms/mipsel-yeeloong.bin", "mipsel-yeeloong.bin"},
+ {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "roms/mipsel-fulong.bin", "mipsel-fulong.bin"},
+ {GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "roms/mips-qemu_mips.elf", "mips-qemu_mips.elf"},
+ {GRUB_INSTALL_PLATFORM_I386_QEMU, "roms/qemu.img", "qemu.img"},
+ {GRUB_INSTALL_PLATFORM_I386_COREBOOT, "roms/coreboot.elf", "coreboot.elf"},
+ };
+ grub_size_t i;
+ for (i = 0; i < ARRAY_SIZE (roms); i++)
+ {
+ char *from = grub_util_path_concat (2, boot_grub, roms[i].from);
+ char *to = grub_util_path_concat (2, rom_directory, roms[i].to);
+ grub_install_copy_file (from, to, 0);
+ }
+ }
+
+ xorriso_push ("--protective-msdos-label");
+ xorriso_push ("-o");
+ xorriso_push (output_image);
+ xorriso_push ("-r");
+ xorriso_push (iso9660_dir);
+ xorriso_push ("--sort-weight");
+ xorriso_push ("0");
+ xorriso_push ("/");
+ xorriso_push ("--sort-weight");
+ xorriso_push ("1");
+ xorriso_push ("/boot");
+ int i;
+ for (i = 0; i < xorriso_tail_argc; i++)
+ xorriso_push (xorriso_tail_argv[i]);
+
+ xorriso_argv[xorriso_argc] = NULL;
+
+ rv = grub_util_exec ((const char *const *)xorriso_argv);
+ if (rv != 0)
+ grub_util_error ("`%s` invocation failed\n", "xorriso");
+
+ grub_util_unlink_recursive (iso9660_dir);
+
+ if (sysarea_img)
+ grub_util_unlink (sysarea_img);
+
+ free (core_services);
+ free (romdir);
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+
+#include <grub/elf.h>
+#include <grub/module_verifier.h>
+#include <grub/misc.h>
+#include <grub/util/misc.h>
+
+struct grub_module_verifier_arch archs[] = {
+ { "i386", 4, 0, EM_386, GRUB_MODULE_VERIFY_SUPPORTS_REL, (int[]){
+ R_386_32,
+ R_386_PC32,
+ -1
+ } },
+ { "x86_64", 8, 0, EM_X86_64, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
+ R_X86_64_64,
+ R_X86_64_PC64,
+ /* R_X86_64_32, R_X86_64_32S are supported but shouldn't be used because of their limited range. */
+ -1
+ }, (int[]){
+ R_X86_64_PC32,
+ R_X86_64_PLT32,
+ -1
+ }
+ },
+ { "powerpc", 4, 1, EM_PPC, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
+ GRUB_ELF_R_PPC_ADDR16_LO,
+ GRUB_ELF_R_PPC_REL24, /* It has limited range but GRUB adds trampolines when necessarry. */
+ GRUB_ELF_R_PPC_ADDR16_HA,
+ GRUB_ELF_R_PPC_ADDR32,
+ GRUB_ELF_R_PPC_REL32,
+ GRUB_ELF_R_PPC_PLTREL24,
+ -1
+ } },
+ { "sparc64", 8, 1, EM_SPARCV9, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
+ R_SPARC_WDISP30, /* It has limited range but GRUB adds trampolines when necessarry. */
+ R_SPARC_HH22,
+ R_SPARC_HM10,
+ R_SPARC_LM22,
+ R_SPARC_LO10,
+ R_SPARC_64,
+ R_SPARC_OLO10,
+ /* Following 2 relocations have limited range but unfortunately
+ clang generates them, as it doesn't implement mcmodel=large properly.
+ At least our heap and core are under 4G, so it's not a problem
+ usually. */
+ R_SPARC_HI22,
+ R_SPARC_32,
+ -1
+ } },
+ { "ia64", 8, 0, EM_IA_64, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
+ R_IA64_PCREL21B, /* We should verify that it's pointing either
+ to a function or to a section in the same module.
+ Checking that external symbol is a function is
+ non-trivial and I have never seen this relocation used
+ for anything else, so assume that it always points to a
+ function.
+ */
+ R_IA64_SEGREL64LSB,
+ R_IA64_FPTR64LSB,
+ R_IA64_DIR64LSB,
+ R_IA64_PCREL64LSB,
+ R_IA64_LTOFF22X,
+ R_IA64_LTOFF22,
+ R_IA64_GPREL64I,
+ R_IA64_LTOFF_FPTR22,
+ R_IA64_LDXMOV,
+ -1
+ }, (int[]){
+ R_IA64_GPREL22,
+ -1
+ } },
+ { "mipsel", 4, 0, EM_MIPS, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
+ R_MIPS_HI16,
+ R_MIPS_LO16,
+ R_MIPS_32,
+ R_MIPS_GPREL32,
+ R_MIPS_26,
+ R_MIPS_GOT16,
+ R_MIPS_CALL16,
+ R_MIPS_JALR,
+ -1
+ } },
+ { "mips", 4, 1, EM_MIPS, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
+ R_MIPS_HI16,
+ R_MIPS_LO16,
+ R_MIPS_32,
+ R_MIPS_GPREL32,
+ R_MIPS_26,
+ R_MIPS_GOT16,
+ R_MIPS_CALL16,
+ R_MIPS_JALR,
+ -1
+ } },
+ { "arm", 4, 0, EM_ARM, GRUB_MODULE_VERIFY_SUPPORTS_REL, (int[]){
+ /* Some relocations are range-limited but trampolines are added when necessarry. */
+ R_ARM_ABS32,
+ R_ARM_CALL,
+ R_ARM_JUMP24,
+ R_ARM_THM_CALL,
+ R_ARM_THM_JUMP24,
+ R_ARM_V4BX,
+ R_ARM_THM_MOVW_ABS_NC,
+ R_ARM_THM_MOVT_ABS,
+ R_ARM_THM_JUMP19,
+ -1
+ } },
+ { "arm64", 8, 0, EM_AARCH64, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
+ R_AARCH64_ABS64,
+ R_AARCH64_CALL26,
+ R_AARCH64_JUMP26,
+ R_AARCH64_ADR_GOT_PAGE,
+ R_AARCH64_LD64_GOT_LO12_NC,
+ -1
+ }, (int[]){
+ R_AARCH64_ADR_PREL_PG_HI21,
+ R_AARCH64_ADD_ABS_LO12_NC,
+ R_AARCH64_LDST64_ABS_LO12_NC,
+ R_AARCH64_PREL32,
+ -1
+ } },
+ { "mips64el", 8, 0, EM_MIPS, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
+ R_MIPS_64,
+ R_MIPS_32,
+ R_MIPS_26,
+ R_MIPS_LO16,
+ R_MIPS_HI16,
+ R_MIPS_HIGHER,
+ R_MIPS_HIGHEST,
+ -1
+ }, (int[]){
+ -1
+ }
+ },
+ { "riscv32", 4, 0, EM_RISCV, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
+ R_RISCV_32,
+ R_RISCV_64,
+ R_RISCV_ADD8,
+ R_RISCV_ADD16,
+ R_RISCV_ADD32,
+ R_RISCV_ADD64,
+ R_RISCV_SUB8,
+ R_RISCV_SUB16,
+ R_RISCV_SUB32,
+ R_RISCV_SUB64,
+ R_RISCV_ALIGN,
+ R_RISCV_BRANCH,
+ R_RISCV_CALL,
+ R_RISCV_CALL_PLT,
+ R_RISCV_GOT_HI20,
+ R_RISCV_HI20,
+ R_RISCV_JAL,
+ R_RISCV_LO12_I,
+ R_RISCV_LO12_S,
+ R_RISCV_PCREL_HI20,
+ R_RISCV_PCREL_LO12_I,
+ R_RISCV_PCREL_LO12_S,
+ R_RISCV_RELAX,
+ R_RISCV_RVC_BRANCH,
+ R_RISCV_RVC_JUMP,
+ -1
+ } },
+ { "riscv64", 8, 0, EM_RISCV, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
+ R_RISCV_32,
+ R_RISCV_64,
+ R_RISCV_ADD8,
+ R_RISCV_ADD16,
+ R_RISCV_ADD32,
+ R_RISCV_ADD64,
+ R_RISCV_SUB8,
+ R_RISCV_SUB16,
+ R_RISCV_SUB32,
+ R_RISCV_SUB64,
+ R_RISCV_ALIGN,
+ R_RISCV_BRANCH,
+ R_RISCV_CALL,
+ R_RISCV_CALL_PLT,
+ R_RISCV_GOT_HI20,
+ R_RISCV_HI20,
+ R_RISCV_JAL,
+ R_RISCV_LO12_I,
+ R_RISCV_LO12_S,
+ R_RISCV_PCREL_HI20,
+ R_RISCV_PCREL_LO12_I,
+ R_RISCV_PCREL_LO12_S,
+ R_RISCV_RELAX,
+ R_RISCV_RVC_BRANCH,
+ R_RISCV_RVC_JUMP,
+ -1
+ }
+ },
+};
+
+struct platform_whitelist {
+ const char *arch;
+ const char *platform;
+ const char **whitelist_empty;
+};
+
+static struct platform_whitelist whitelists[] = {
+ {"i386", "xen", (const char *[]) {"all_video", 0}},
+ {"i386", "xen_pvh", (const char *[]) {"all_video", 0}},
+ {"x86_64", "xen", (const char *[]) {"all_video", 0}},
+ {"sparc64", "ieee1275", (const char *[]) {"all_video", 0}},
+
+ /* video is compiled-in on MIPS. */
+ {"mipsel", "loongson", (const char *[]) {"all_video", 0}},
+ {"mipsel", "qemu_mips", (const char *[]) {"all_video", 0}},
+ {"mipsel", "arc", (const char *[]) {"all_video", 0}},
+ {"mips", "qemu_mips", (const char *[]) {"all_video", 0}},
+ {"mips", "arc", (const char *[]) {"all_video", 0}},
+};
+
+
+int
+main (int argc, char **argv)
+{
+ size_t module_size;
+ unsigned arch, whitelist;
+ const char **whitelist_empty = 0;
+ char *module_img;
+ if (argc != 4) {
+ fprintf (stderr, "usage: %s FILE ARCH PLATFORM\n", argv[0]);
+ return 1;
+ }
+
+ for (arch = 0; arch < ARRAY_SIZE(archs); arch++)
+ if (strcmp(archs[arch].name, argv[2]) == 0)
+ break;
+ if (arch == ARRAY_SIZE(archs))
+ grub_util_error("%s: unknown arch: %s", argv[1], argv[2]);
+
+ for (whitelist = 0; whitelist < ARRAY_SIZE(whitelists); whitelist++)
+ if (strcmp(whitelists[whitelist].arch, argv[2]) == 0
+ && strcmp(whitelists[whitelist].platform, argv[3]) == 0)
+ break;
+ if (whitelist != ARRAY_SIZE(whitelists))
+ whitelist_empty = whitelists[whitelist].whitelist_empty;
+
+ module_size = grub_util_get_image_size (argv[1]);
+ module_img = grub_util_read_image (argv[1]);
+ if (archs[arch].voidp_sizeof == 8)
+ grub_module_verify64(argv[1], module_img, module_size, &archs[arch], whitelist_empty);
+ else
+ grub_module_verify32(argv[1], module_img, module_size, &archs[arch], whitelist_empty);
+ return 0;
+}
--- /dev/null
+#include <string.h>
+
+#include <grub/elf.h>
+#include <grub/module_verifier.h>
+#include <grub/util/misc.h>
+
+#if defined(MODULEVERIFIER_ELF32)
+# define SUFFIX(x) x ## 32
+# define ELFCLASSXX ELFCLASS32
+# define Elf_Ehdr Elf32_Ehdr
+# define Elf_Phdr Elf32_Phdr
+# define Elf_Nhdr Elf32_Nhdr
+# define Elf_Addr Elf32_Addr
+# define Elf_Sym Elf32_Sym
+# define Elf_Off Elf32_Off
+# define Elf_Shdr Elf32_Shdr
+# define Elf_Rela Elf32_Rela
+# define Elf_Rel Elf32_Rel
+# define Elf_Word Elf32_Word
+# define Elf_Half Elf32_Half
+# define Elf_Section Elf32_Section
+# define ELF_R_SYM(val) ELF32_R_SYM(val)
+# define ELF_R_TYPE(val) ELF32_R_TYPE(val)
+# define ELF_ST_TYPE(val) ELF32_ST_TYPE(val)
+#elif defined(MODULEVERIFIER_ELF64)
+# define SUFFIX(x) x ## 64
+# define ELFCLASSXX ELFCLASS64
+# define Elf_Ehdr Elf64_Ehdr
+# define Elf_Phdr Elf64_Phdr
+# define Elf_Nhdr Elf64_Nhdr
+# define Elf_Addr Elf64_Addr
+# define Elf_Sym Elf64_Sym
+# define Elf_Off Elf64_Off
+# define Elf_Shdr Elf64_Shdr
+# define Elf_Rela Elf64_Rela
+# define Elf_Rel Elf64_Rel
+# define Elf_Word Elf64_Word
+# define Elf_Half Elf64_Half
+# define Elf_Section Elf64_Section
+# define ELF_R_SYM(val) ELF64_R_SYM(val)
+# define ELF_R_TYPE(val) ELF64_R_TYPE(val)
+# define ELF_ST_TYPE(val) ELF64_ST_TYPE(val)
+#else
+#error "I'm confused"
+#endif
+
+#define grub_target_to_host32(x) (grub_target_to_host32_real (arch, (x)))
+#define grub_host_to_target32(x) (grub_host_to_target32_real (arch, (x)))
+#define grub_target_to_host64(x) (grub_target_to_host64_real (arch, (x)))
+#define grub_host_to_target64(x) (grub_host_to_target64_real (arch, (x)))
+#define grub_host_to_target_addr(x) (grub_host_to_target_addr_real (arch, (x)))
+#define grub_target_to_host16(x) (grub_target_to_host16_real (arch, (x)))
+#define grub_host_to_target16(x) (grub_host_to_target16_real (arch, (x)))
+#define grub_target_to_host(val) grub_target_to_host_real(arch, (val))
+
+static inline grub_uint32_t
+grub_target_to_host32_real (const struct grub_module_verifier_arch *arch,
+ grub_uint32_t in)
+{
+ if (arch->bigendian)
+ return grub_be_to_cpu32 (in);
+ else
+ return grub_le_to_cpu32 (in);
+}
+
+static inline grub_uint64_t
+grub_target_to_host64_real (const struct grub_module_verifier_arch *arch,
+ grub_uint64_t in)
+{
+ if (arch->bigendian)
+ return grub_be_to_cpu64 (in);
+ else
+ return grub_le_to_cpu64 (in);
+}
+
+static inline grub_uint64_t
+grub_host_to_target64_real (const struct grub_module_verifier_arch *arch,
+ grub_uint64_t in)
+{
+ if (arch->bigendian)
+ return grub_cpu_to_be64 (in);
+ else
+ return grub_cpu_to_le64 (in);
+}
+
+static inline grub_uint32_t
+grub_host_to_target32_real (const struct grub_module_verifier_arch *arch,
+ grub_uint32_t in)
+{
+ if (arch->bigendian)
+ return grub_cpu_to_be32 (in);
+ else
+ return grub_cpu_to_le32 (in);
+}
+
+static inline grub_uint16_t
+grub_target_to_host16_real (const struct grub_module_verifier_arch *arch,
+ grub_uint16_t in)
+{
+ if (arch->bigendian)
+ return grub_be_to_cpu16 (in);
+ else
+ return grub_le_to_cpu16 (in);
+}
+
+static inline grub_uint16_t
+grub_host_to_target16_real (const struct grub_module_verifier_arch *arch,
+ grub_uint16_t in)
+{
+ if (arch->bigendian)
+ return grub_cpu_to_be16 (in);
+ else
+ return grub_cpu_to_le16 (in);
+}
+
+static inline grub_uint64_t
+grub_host_to_target_addr_real (const struct grub_module_verifier_arch *arch, grub_uint64_t in)
+{
+ if (arch->voidp_sizeof == 8)
+ return grub_host_to_target64_real (arch, in);
+ else
+ return grub_host_to_target32_real (arch, in);
+}
+
+static inline grub_uint64_t
+grub_target_to_host_real (const struct grub_module_verifier_arch *arch, grub_uint64_t in)
+{
+ if (arch->voidp_sizeof == 8)
+ return grub_target_to_host64_real (arch, in);
+ else
+ return grub_target_to_host32_real (arch, in);
+}
+
+
+static Elf_Shdr *
+find_section (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, const char *name)
+{
+ Elf_Shdr *s;
+ const char *str;
+ unsigned i;
+
+ s = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff) + grub_target_to_host16 (e->e_shstrndx) * grub_target_to_host16 (e->e_shentsize));
+ str = (char *) e + grub_target_to_host (s->sh_offset);
+
+ for (i = 0, s = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff));
+ i < grub_target_to_host16 (e->e_shnum);
+ i++, s = (Elf_Shdr *) ((char *) s + grub_target_to_host16 (e->e_shentsize)))
+ if (strcmp (str + grub_target_to_host32 (s->sh_name), name) == 0)
+ return s;
+ return NULL;
+}
+
+static void
+check_license (const char * const filename,
+ const struct grub_module_verifier_arch *arch, Elf_Ehdr *e)
+{
+ Elf_Shdr *s = find_section (arch, e, ".module_license");
+ if (s && (strcmp ((char *) e + grub_target_to_host(s->sh_offset), "LICENSE=GPLv3") == 0
+ || strcmp ((char *) e + grub_target_to_host(s->sh_offset), "LICENSE=GPLv3+") == 0
+ || strcmp ((char *) e + grub_target_to_host(s->sh_offset), "LICENSE=GPLv2+") == 0))
+ return;
+ grub_util_error ("%s: incompatible license", filename);
+}
+
+static Elf_Sym *
+get_symtab (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, Elf_Word *size, Elf_Word *entsize)
+{
+ unsigned i;
+ Elf_Shdr *s, *sections;
+ Elf_Sym *sym;
+
+ sections = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff));
+ for (i = 0, s = sections;
+ i < grub_target_to_host16 (e->e_shnum);
+ i++, s = (Elf_Shdr *) ((char *) s + grub_target_to_host16 (e->e_shentsize)))
+ if (grub_target_to_host32 (s->sh_type) == SHT_SYMTAB)
+ break;
+
+ if (i == grub_target_to_host16 (e->e_shnum))
+ return NULL;
+
+ sym = (Elf_Sym *) ((char *) e + grub_target_to_host (s->sh_offset));
+ *size = grub_target_to_host (s->sh_size);
+ *entsize = grub_target_to_host (s->sh_entsize);
+ return sym;
+}
+
+static int
+is_whitelisted (const char *modname, const char **whitelist)
+{
+ const char **ptr;
+ if (!whitelist)
+ return 0;
+ if (!modname)
+ return 0;
+ for (ptr = whitelist; *ptr; ptr++)
+ if (strcmp (modname, *ptr) == 0)
+ return 1;
+ return 0;
+}
+
+static void
+check_symbols (const struct grub_module_verifier_arch *arch,
+ Elf_Ehdr *e, const char *modname,
+ const char **whitelist_empty)
+{
+ Elf_Sym *sym;
+ Elf_Word size, entsize;
+ unsigned i;
+
+ /* Module without symbol table and without .moddeps section is useless
+ at boot time, so catch it early to prevent build errors */
+ sym = get_symtab (arch, e, &size, &entsize);
+ if (!sym)
+ {
+ Elf_Shdr *s;
+
+ /* However some modules are dependencies-only,
+ e.g. insmod all_video pulls in all video drivers.
+ Some platforms e.g. xen have no video drivers, so
+ the module does nothing. */
+ if (is_whitelisted (modname, whitelist_empty))
+ return;
+
+ s = find_section (arch, e, ".moddeps");
+
+ if (!s)
+ grub_util_error ("%s: no symbol table and no .moddeps section", modname);
+
+ if (!s->sh_size)
+ grub_util_error ("%s: no symbol table and empty .moddeps section", modname);
+
+ return;
+ }
+
+ for (i = 0;
+ i < size / entsize;
+ i++, sym = (Elf_Sym *) ((char *) sym + entsize))
+ {
+ unsigned char type = ELF_ST_TYPE (sym->st_info);
+
+ switch (type)
+ {
+ case STT_NOTYPE:
+ case STT_OBJECT:
+ case STT_FUNC:
+ case STT_SECTION:
+ case STT_FILE:
+ break;
+
+ default:
+ return grub_util_error ("%s: unknown symbol type `%d'", modname, (int) type);
+ }
+ }
+}
+
+static int
+is_symbol_local(Elf_Sym *sym)
+{
+ switch (ELF_ST_TYPE (sym->st_info))
+ {
+ case STT_NOTYPE:
+ case STT_OBJECT:
+ if (sym->st_name != 0 && sym->st_shndx == 0)
+ return 0;
+ return 1;
+
+ case STT_FUNC:
+ case STT_SECTION:
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+static void
+section_check_relocations (const char * const modname,
+ const struct grub_module_verifier_arch *arch, void *ehdr,
+ Elf_Shdr *s, size_t target_seg_size)
+{
+ Elf_Rel *rel, *max;
+ Elf_Sym *symtab;
+ Elf_Word symtabsize, symtabentsize;
+
+ symtab = get_symtab (arch, ehdr, &symtabsize, &symtabentsize);
+ if (!symtab)
+ grub_util_error ("%s: relocation without symbol table", modname);
+
+ for (rel = (Elf_Rel *) ((char *) ehdr + grub_target_to_host (s->sh_offset)),
+ max = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_size));
+ rel < max;
+ rel = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_entsize)))
+ {
+ Elf_Sym *sym;
+ unsigned i;
+
+ if (target_seg_size < grub_target_to_host (rel->r_offset))
+ grub_util_error ("%s: reloc offset is out of the segment", modname);
+
+ grub_size_t r_info;
+ if (arch->machine == EM_MIPS && arch->voidp_sizeof == 8)
+ r_info = ((grub_uint64_t) rel->r_info << 32) |
+ (grub_uint32_t) grub_be_to_cpu64 (rel->r_info);
+ else
+ r_info = grub_target_to_host (rel->r_info);
+
+ grub_uint32_t type = ELF_R_TYPE (r_info);
+
+ if (arch->machine == EM_SPARCV9)
+ type &= 0xff;
+
+ for (i = 0; arch->supported_relocations[i] != -1; i++)
+ if (type == arch->supported_relocations[i])
+ break;
+ if (arch->supported_relocations[i] != -1)
+ continue;
+ if (!arch->short_relocations)
+ grub_util_error ("%s: unsupported relocation 0x%x", modname, type);
+ for (i = 0; arch->short_relocations[i] != -1; i++)
+ if (type == arch->short_relocations[i])
+ break;
+ if (arch->short_relocations[i] == -1)
+ grub_util_error ("%s: unsupported relocation 0x%x", modname, type);
+ sym = (Elf_Sym *) ((char *) symtab + symtabentsize * ELF_R_SYM (r_info));
+
+ if (is_symbol_local (sym))
+ continue;
+ grub_util_error ("%s: relocation 0x%x is not module-local", modname, type);
+ }
+#if defined(MODULEVERIFIER_ELF64)
+ if (arch->machine == EM_AARCH64)
+ {
+ unsigned unmatched_adr_got_page = 0;
+ Elf_Rela *rel2;
+ for (rel = (Elf_Rel *) ((char *) ehdr + grub_target_to_host (s->sh_offset)),
+ max = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_size));
+ rel < max;
+ rel = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_entsize)))
+ {
+ switch (ELF_R_TYPE (grub_target_to_host (rel->r_info)))
+ {
+ case R_AARCH64_ADR_GOT_PAGE:
+ unmatched_adr_got_page++;
+ for (rel2 = (Elf_Rela *) ((char *) rel + grub_target_to_host (s->sh_entsize));
+ rel2 < (Elf_Rela *) max;
+ rel2 = (Elf_Rela *) ((char *) rel2 + grub_target_to_host (s->sh_entsize)))
+ if (ELF_R_SYM (rel2->r_info)
+ == ELF_R_SYM (rel->r_info)
+ && ((Elf_Rela *) rel)->r_addend == rel2->r_addend
+ && ELF_R_TYPE (rel2->r_info) == R_AARCH64_LD64_GOT_LO12_NC)
+ break;
+ if (rel2 >= (Elf_Rela *) max)
+ grub_util_error ("%s: ADR_GOT_PAGE without matching LD64_GOT_LO12_NC", modname);
+ break;
+ case R_AARCH64_LD64_GOT_LO12_NC:
+ if (unmatched_adr_got_page == 0)
+ grub_util_error ("%s: LD64_GOT_LO12_NC without matching ADR_GOT_PAGE", modname);
+ unmatched_adr_got_page--;
+ break;
+ }
+ }
+ }
+#endif
+}
+
+static void
+check_relocations (const char * const modname,
+ const struct grub_module_verifier_arch *arch, Elf_Ehdr *e)
+{
+ Elf_Shdr *s;
+ unsigned i;
+
+ for (i = 0, s = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff));
+ i < grub_target_to_host16 (e->e_shnum);
+ i++, s = (Elf_Shdr *) ((char *) s + grub_target_to_host16 (e->e_shentsize)))
+ if (grub_target_to_host32 (s->sh_type) == SHT_REL || grub_target_to_host32 (s->sh_type) == SHT_RELA)
+ {
+ Elf_Shdr *ts;
+
+ if (grub_target_to_host32 (s->sh_type) == SHT_REL && !(arch->flags & GRUB_MODULE_VERIFY_SUPPORTS_REL))
+ grub_util_error ("%s: unsupported SHT_REL", modname);
+ if (grub_target_to_host32 (s->sh_type) == SHT_RELA && !(arch->flags & GRUB_MODULE_VERIFY_SUPPORTS_RELA))
+ grub_util_error ("%s: unsupported SHT_RELA", modname);
+
+ /* Find the target segment. */
+ if (grub_target_to_host32 (s->sh_info) >= grub_target_to_host16 (e->e_shnum))
+ grub_util_error ("%s: orphaned reloc section", modname);
+ ts = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff) + grub_target_to_host32 (s->sh_info) * grub_target_to_host16 (e->e_shentsize));
+
+ section_check_relocations (modname, arch, e, s, grub_target_to_host (ts->sh_size));
+ }
+}
+
+void
+SUFFIX(grub_module_verify) (const char * const filename,
+ void *module_img, size_t size,
+ const struct grub_module_verifier_arch *arch,
+ const char **whitelist_empty)
+{
+ Elf_Ehdr *e = module_img;
+
+ /* Check the header size. */
+ if (size < sizeof (Elf_Ehdr))
+ grub_util_error ("%s: ELF header smaller than expected", filename);
+
+ /* Check the magic numbers. */
+ if (e->e_ident[EI_MAG0] != ELFMAG0
+ || e->e_ident[EI_MAG1] != ELFMAG1
+ || e->e_ident[EI_MAG2] != ELFMAG2
+ || e->e_ident[EI_MAG3] != ELFMAG3
+ || e->e_ident[EI_VERSION] != EV_CURRENT
+ || grub_target_to_host32 (e->e_version) != EV_CURRENT)
+ grub_util_error ("%s: invalid arch-independent ELF magic", filename);
+
+ if (e->e_ident[EI_CLASS] != ELFCLASSXX
+ || e->e_ident[EI_DATA] != (arch->bigendian ? ELFDATA2MSB : ELFDATA2LSB)
+ || grub_target_to_host16 (e->e_machine) != arch->machine)
+ grub_util_error ("%s: invalid arch-dependent ELF magic", filename);
+
+ if (grub_target_to_host16 (e->e_type) != ET_REL)
+ {
+ grub_util_error ("%s: this ELF file is not of the right type", filename);
+ }
+
+ /* Make sure that every section is within the core. */
+ if (size < grub_target_to_host (e->e_shoff)
+ + (grub_uint32_t) grub_target_to_host16 (e->e_shentsize) * grub_target_to_host16(e->e_shnum))
+ {
+ grub_util_error ("%s: ELF sections outside core", filename);
+ }
+
+ check_license (filename, arch, e);
+
+ Elf_Shdr *s;
+ const char *modname;
+
+ s = find_section (arch, e, ".modname");
+ if (!s)
+ grub_util_error ("%s: no module name found", filename);
+
+ modname = (const char *) e + grub_target_to_host (s->sh_offset);
+
+ check_symbols(arch, e, modname, whitelist_empty);
+ check_relocations(modname, arch, e);
+}
--- /dev/null
+/* grub-mkimage.c - make a bootable image */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/elf.h>
+#include <grub/aout.h>
+#include <grub/i18n.h>
+#include <grub/kernel.h>
+#include <grub/disk.h>
+#include <grub/emu/misc.h>
+#include <grub/util/misc.h>
+#include <grub/util/resolve.h>
+#include <grub/misc.h>
+#include <grub/offsets.h>
+#include <grub/crypto.h>
+#include <grub/dl.h>
+#include <time.h>
+#include <multiboot.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <grub/efi/pe32.h>
+#include <grub/uboot/image.h>
+#include <grub/arm/reloc.h>
+#include <grub/arm64/reloc.h>
+#include <grub/ia64/reloc.h>
+#include <grub/osdep/hostfile.h>
+#include <grub/util/install.h>
+#include <grub/util/mkimage.h>
+
+#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof))
+
+#ifdef USE_LIBLZMA
+#include <lzma.h>
+#endif
+
+#pragma GCC diagnostic ignored "-Wcast-align"
+
+#define TARGET_NO_FIELD 0xffffffff
+
+/* use 2015-01-01T00:00:00+0000 as a stock timestamp */
+#define STABLE_EMBEDDING_TIMESTAMP 1420070400
+
+#define EFI32_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE \
+ + GRUB_PE32_SIGNATURE_SIZE \
+ + sizeof (struct grub_pe32_coff_header) \
+ + sizeof (struct grub_pe32_optional_header) \
+ + 4 * sizeof (struct grub_pe32_section_table), \
+ GRUB_PE32_FILE_ALIGNMENT)
+
+#define EFI64_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE \
+ + GRUB_PE32_SIGNATURE_SIZE \
+ + sizeof (struct grub_pe32_coff_header) \
+ + sizeof (struct grub_pe64_optional_header) \
+ + 4 * sizeof (struct grub_pe32_section_table), \
+ GRUB_PE32_FILE_ALIGNMENT)
+
+static const struct grub_install_image_target_desc image_targets[] =
+ {
+ {
+ .dirname = "i386-coreboot",
+ .names = { "i386-coreboot", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_COREBOOT,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .reloc_table_offset = TARGET_NO_FIELD,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR,
+ .elf_target = EM_386,
+ .link_align = 4,
+ .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP,
+ .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN
+ },
+ {
+ .dirname = "i386-multiboot",
+ .names = { "i386-multiboot", NULL},
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_COREBOOT,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR,
+ .elf_target = EM_386,
+ .link_align = 4,
+ .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP,
+ .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN
+ },
+ {
+ .dirname = "i386-pc",
+ .names = { "i386-pc", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_I386_PC,
+ .flags = PLATFORM_FLAGS_DECOMPRESSORS,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR,
+ .default_compression = GRUB_COMPRESSION_LZMA
+ },
+ {
+ .dirname = "i386-xen_pvh",
+ .names = { "i386-xen_pvh", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_XEN_PVH,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .elf_target = EM_386,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR,
+ .mod_align = GRUB_KERNEL_I386_XEN_PVH_MOD_ALIGN,
+ .link_align = 4
+ },
+ {
+ .dirname = "i386-pc",
+ .names = { "i386-pc-pxe", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_I386_PC_PXE,
+ .flags = PLATFORM_FLAGS_DECOMPRESSORS,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR,
+ .default_compression = GRUB_COMPRESSION_LZMA
+ },
+ {
+ .dirname = "i386-pc",
+ .names = { "i386-pc-eltorito", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_I386_PC_ELTORITO,
+ .flags = PLATFORM_FLAGS_DECOMPRESSORS,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR,
+ .default_compression = GRUB_COMPRESSION_LZMA
+ },
+ {
+ .dirname = "i386-efi",
+ .names = { "i386-efi", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_EFI,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = GRUB_PE32_SECTION_ALIGNMENT,
+ .vaddr_offset = EFI32_HEADER_SIZE,
+ .pe_target = GRUB_PE32_MACHINE_I386,
+ .elf_target = EM_386,
+ },
+ {
+ .dirname = "i386-ieee1275",
+ .names = { "i386-ieee1275", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_I386_IEEE1275,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_I386_IEEE1275_LINK_ADDR,
+ .elf_target = EM_386,
+ .mod_gap = GRUB_KERNEL_I386_IEEE1275_MOD_GAP,
+ .mod_align = GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN,
+ .link_align = 4,
+ },
+ {
+ .dirname = "i386-qemu",
+ .names = { "i386-qemu", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_QEMU,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_I386_QEMU_LINK_ADDR
+ },
+ {
+ .dirname = "x86_64-efi",
+ .names = { "x86_64-efi", NULL },
+ .voidp_sizeof = 8,
+ .bigendian = 0,
+ .id = IMAGE_EFI,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = GRUB_PE32_SECTION_ALIGNMENT,
+ .vaddr_offset = EFI64_HEADER_SIZE,
+ .pe_target = GRUB_PE32_MACHINE_X86_64,
+ .elf_target = EM_X86_64,
+ },
+ {
+ .dirname = "i386-xen",
+ .names = { "i386-xen", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_XEN,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = 0,
+ .elf_target = EM_386,
+ .mod_gap = GRUB_KERNEL_I386_XEN_MOD_GAP,
+ .mod_align = GRUB_KERNEL_I386_XEN_MOD_ALIGN,
+ .link_align = 4
+ },
+ {
+ .dirname = "x86_64-xen",
+ .names = { "x86_64-xen", NULL },
+ .voidp_sizeof = 8,
+ .bigendian = 0,
+ .id = IMAGE_XEN,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = 0,
+ .elf_target = EM_X86_64,
+ .mod_gap = GRUB_KERNEL_X86_64_XEN_MOD_GAP,
+ .mod_align = GRUB_KERNEL_X86_64_XEN_MOD_ALIGN,
+ .link_align = 8
+ },
+ {
+ .dirname = "mipsel-loongson",
+ .names = { "mipsel-yeeloong-flash", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_YEELOONG_FLASH,
+ .flags = PLATFORM_FLAGS_DECOMPRESSORS,
+ .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE,
+ .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR,
+ .elf_target = EM_MIPS,
+ .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN,
+ .default_compression = GRUB_COMPRESSION_NONE
+ },
+ {
+ .dirname = "mipsel-loongson",
+ .names = { "mipsel-fuloong2f-flash", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_FULOONG2F_FLASH,
+ .flags = PLATFORM_FLAGS_DECOMPRESSORS,
+ .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE,
+ .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR,
+ .elf_target = EM_MIPS,
+ .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN,
+ .default_compression = GRUB_COMPRESSION_NONE
+ },
+ {
+ .dirname = "mipsel-loongson",
+ .names = { "mipsel-loongson-elf", "mipsel-yeeloong-elf",
+ "mipsel-fuloong2f-elf", "mipsel-fuloong2e-elf",
+ "mipsel-fuloong-elf", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_LOONGSON_ELF,
+ .flags = PLATFORM_FLAGS_DECOMPRESSORS,
+ .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE,
+ .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR,
+ .elf_target = EM_MIPS,
+ .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN,
+ .default_compression = GRUB_COMPRESSION_NONE
+ },
+ {
+ .dirname = "powerpc-ieee1275",
+ .names = { "powerpc-ieee1275", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 1,
+ .id = IMAGE_PPC,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR,
+ .elf_target = EM_PPC,
+ .mod_gap = GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP,
+ .mod_align = GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN,
+ .link_align = 4
+ },
+ {
+ .dirname = "sparc64-ieee1275",
+ .names = { "sparc64-ieee1275-raw", NULL },
+ .voidp_sizeof = 8,
+ .bigendian = 1,
+ .id = IMAGE_SPARC64_RAW,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR,
+ .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN,
+ },
+ {
+ .dirname = "sparc64-ieee1275",
+ .names = { "sparc64-ieee1275-cdcore", NULL },
+ .voidp_sizeof = 8,
+ .bigendian = 1,
+ .id = IMAGE_SPARC64_CDCORE,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR,
+ .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN,
+ },
+ {
+ .dirname = "sparc64-ieee1275",
+ .names = { "sparc64-ieee1275-aout", NULL },
+ .voidp_sizeof = 8,
+ .bigendian = 1,
+ .id = IMAGE_SPARC64_AOUT,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR,
+ .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN,
+ },
+ {
+ .dirname = "ia64-efi",
+ .names = {"ia64-efi", NULL},
+ .voidp_sizeof = 8,
+ .bigendian = 0,
+ .id = IMAGE_EFI,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = GRUB_PE32_SECTION_ALIGNMENT,
+ .vaddr_offset = EFI64_HEADER_SIZE,
+ .pe_target = GRUB_PE32_MACHINE_IA64,
+ .elf_target = EM_IA_64,
+ },
+ {
+ .dirname = "mips-arc",
+ .names = {"mips-arc", NULL},
+ .voidp_sizeof = 4,
+ .bigendian = 1,
+ .id = IMAGE_MIPS_ARC,
+ .flags = PLATFORM_FLAGS_DECOMPRESSORS,
+ .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE,
+ .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_MIPS_ARC_LINK_ADDR,
+ .elf_target = EM_MIPS,
+ .link_align = GRUB_KERNEL_MIPS_ARC_LINK_ALIGN,
+ .default_compression = GRUB_COMPRESSION_NONE
+ },
+ {
+ .dirname = "mipsel-arc",
+ .names = {"mipsel-arc", NULL},
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_MIPS_ARC,
+ .flags = PLATFORM_FLAGS_DECOMPRESSORS,
+ .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE,
+ .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_MIPSEL_ARC_LINK_ADDR,
+ .elf_target = EM_MIPS,
+ .link_align = GRUB_KERNEL_MIPS_ARC_LINK_ALIGN,
+ .default_compression = GRUB_COMPRESSION_NONE
+ },
+ {
+ .dirname = "mipsel-qemu_mips",
+ .names = { "mipsel-qemu_mips-elf", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_LOONGSON_ELF,
+ .flags = PLATFORM_FLAGS_DECOMPRESSORS,
+ .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE,
+ .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR,
+ .elf_target = EM_MIPS,
+ .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN,
+ .default_compression = GRUB_COMPRESSION_NONE
+ },
+ {
+ .dirname = "mips-qemu_mips",
+ .names = { "mips-qemu_mips-flash", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 1,
+ .id = IMAGE_QEMU_MIPS_FLASH,
+ .flags = PLATFORM_FLAGS_DECOMPRESSORS,
+ .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE,
+ .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR,
+ .elf_target = EM_MIPS,
+ .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN,
+ .default_compression = GRUB_COMPRESSION_NONE
+ },
+ {
+ .dirname = "mipsel-qemu_mips",
+ .names = { "mipsel-qemu_mips-flash", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_QEMU_MIPS_FLASH,
+ .flags = PLATFORM_FLAGS_DECOMPRESSORS,
+ .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE,
+ .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR,
+ .elf_target = EM_MIPS,
+ .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN,
+ .default_compression = GRUB_COMPRESSION_NONE
+ },
+ {
+ .dirname = "mips-qemu_mips",
+ .names = { "mips-qemu_mips-elf", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 1,
+ .id = IMAGE_LOONGSON_ELF,
+ .flags = PLATFORM_FLAGS_DECOMPRESSORS,
+ .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE,
+ .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR,
+ .elf_target = EM_MIPS,
+ .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN,
+ .default_compression = GRUB_COMPRESSION_NONE
+ },
+ {
+ .dirname = "arm-uboot",
+ .names = { "arm-uboot", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_UBOOT,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = GRUB_KERNEL_ARM_UBOOT_TOTAL_MODULE_SIZE,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN,
+ .vaddr_offset = 0,
+ .elf_target = EM_ARM,
+ .mod_gap = GRUB_KERNEL_ARM_UBOOT_MOD_GAP,
+ .mod_align = GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN,
+ .link_align = 4
+ },
+ /* For coreboot versions that don't support self-relocating images. */
+ {
+ .dirname = "arm-coreboot-vexpress",
+ .names = { "arm-coreboot-vexpress", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_COREBOOT,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = GRUB_KERNEL_ARM_COREBOOT_TOTAL_MODULE_SIZE,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN,
+ .vaddr_offset = 0,
+ .elf_target = EM_ARM,
+ .mod_gap = GRUB_KERNEL_ARM_COREBOOT_MOD_GAP,
+ .mod_align = GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN,
+ .link_align = 4,
+ .link_addr = 0x62000000,
+ },
+ {
+ .dirname = "arm-coreboot-veyron",
+ .names = { "arm-coreboot-veyron", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_COREBOOT,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = GRUB_KERNEL_ARM_COREBOOT_TOTAL_MODULE_SIZE,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN,
+ .vaddr_offset = 0,
+ .elf_target = EM_ARM,
+ .mod_gap = GRUB_KERNEL_ARM_COREBOOT_MOD_GAP,
+ .mod_align = GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN,
+ .link_align = 4,
+ .link_addr = 0x43000000,
+ },
+ {
+ .dirname = "arm-efi",
+ .names = { "arm-efi", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_EFI,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = GRUB_PE32_SECTION_ALIGNMENT,
+ .vaddr_offset = EFI32_HEADER_SIZE,
+ .pe_target = GRUB_PE32_MACHINE_ARMTHUMB_MIXED,
+ .elf_target = EM_ARM,
+ },
+ {
+ .dirname = "arm64-efi",
+ .names = { "arm64-efi", NULL },
+ .voidp_sizeof = 8,
+ .bigendian = 0,
+ .id = IMAGE_EFI,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = GRUB_PE32_SECTION_ALIGNMENT,
+ .vaddr_offset = EFI64_HEADER_SIZE,
+ .pe_target = GRUB_PE32_MACHINE_ARM64,
+ .elf_target = EM_AARCH64,
+ },
+ {
+ .dirname = "mips64el-efi",
+ .names = { "mips64el-efi", NULL },
+ .voidp_sizeof = 8,
+ .bigendian = 0,
+ .id = IMAGE_EFI,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = GRUB_PE32_SECTION_ALIGNMENT,
+ .vaddr_offset = EFI64_HEADER_SIZE,
+ .pe_target = GRUB_PE32_MACHINE_MIPS,
+ .elf_target = EM_MIPS,
+ },
+ {
+ .dirname = "riscv32-efi",
+ .names = { "riscv32-efi", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_EFI,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = GRUB_PE32_SECTION_ALIGNMENT,
+ .vaddr_offset = EFI32_HEADER_SIZE,
+ .pe_target = GRUB_PE32_MACHINE_RISCV32,
+ .elf_target = EM_RISCV,
+ },
+ {
+ .dirname = "riscv64-efi",
+ .names = { "riscv64-efi", NULL },
+ .voidp_sizeof = 8,
+ .bigendian = 0,
+ .id = IMAGE_EFI,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .section_align = GRUB_PE32_SECTION_ALIGNMENT,
+ .vaddr_offset = EFI64_HEADER_SIZE,
+ .pe_target = GRUB_PE32_MACHINE_RISCV64,
+ .elf_target = EM_RISCV,
+ },
+ };
+
+#include <grub/lib/LzmaEnc.h>
+
+static void *SzAlloc(void *p __attribute__ ((unused)), size_t size) { return xmalloc(size); }
+static void SzFree(void *p __attribute__ ((unused)), void *address) { free(address); }
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+static void
+compress_kernel_lzma (char *kernel_img, size_t kernel_size,
+ char **core_img, size_t *core_size)
+{
+ CLzmaEncProps props;
+ unsigned char out_props[5];
+ size_t out_props_size = 5;
+
+ LzmaEncProps_Init(&props);
+ props.dictSize = 1 << 16;
+ props.lc = 3;
+ props.lp = 0;
+ props.pb = 2;
+ props.numThreads = 1;
+
+ *core_img = xmalloc (kernel_size);
+
+ *core_size = kernel_size;
+ if (LzmaEncode ((unsigned char *) *core_img, core_size,
+ (unsigned char *) kernel_img,
+ kernel_size,
+ &props, out_props, &out_props_size,
+ 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK)
+ grub_util_error ("%s", _("cannot compress the kernel image"));
+}
+
+#ifdef USE_LIBLZMA
+static void
+compress_kernel_xz (char *kernel_img, size_t kernel_size,
+ char **core_img, size_t *core_size)
+{
+ lzma_stream strm = LZMA_STREAM_INIT;
+ lzma_ret xzret;
+ lzma_options_lzma lzopts = {
+ .dict_size = 1 << 16,
+ .preset_dict = NULL,
+ .preset_dict_size = 0,
+ .lc = 3,
+ .lp = 0,
+ .pb = 2,
+ .mode = LZMA_MODE_NORMAL,
+ .nice_len = 64,
+ .mf = LZMA_MF_BT4,
+ .depth = 0,
+ };
+ lzma_filter fltrs[] = {
+ { .id = LZMA_FILTER_LZMA2, .options = &lzopts},
+ { .id = LZMA_VLI_UNKNOWN, .options = NULL}
+ };
+
+ xzret = lzma_stream_encoder (&strm, fltrs, LZMA_CHECK_NONE);
+ if (xzret != LZMA_OK)
+ grub_util_error ("%s", _("cannot compress the kernel image"));
+
+ *core_img = xmalloc (kernel_size);
+
+ *core_size = kernel_size;
+ strm.next_in = (unsigned char *) kernel_img;
+ strm.avail_in = kernel_size;
+ strm.next_out = (unsigned char *) *core_img;
+ strm.avail_out = *core_size;
+
+ while (1)
+ {
+ xzret = lzma_code (&strm, LZMA_FINISH);
+ if (xzret == LZMA_OK)
+ continue;
+ if (xzret == LZMA_STREAM_END)
+ break;
+ grub_util_error ("%s", _("cannot compress the kernel image"));
+ }
+
+ *core_size -= strm.avail_out;
+}
+#endif
+
+static void
+compress_kernel (const struct grub_install_image_target_desc *image_target, char *kernel_img,
+ size_t kernel_size, char **core_img, size_t *core_size,
+ grub_compression_t comp)
+{
+ if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS
+ && (comp == GRUB_COMPRESSION_LZMA))
+ {
+ compress_kernel_lzma (kernel_img, kernel_size, core_img,
+ core_size);
+ return;
+ }
+
+#ifdef USE_LIBLZMA
+ if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS
+ && (comp == GRUB_COMPRESSION_XZ))
+ {
+ compress_kernel_xz (kernel_img, kernel_size, core_img,
+ core_size);
+ return;
+ }
+#endif
+
+ if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS
+ && (comp != GRUB_COMPRESSION_NONE))
+ grub_util_error (_("unknown compression %d"), comp);
+
+ *core_img = xmalloc (kernel_size);
+ memcpy (*core_img, kernel_img, kernel_size);
+ *core_size = kernel_size;
+}
+
+const struct grub_install_image_target_desc *
+grub_install_get_image_target (const char *arg)
+{
+ unsigned i, j;
+ for (i = 0; i < ARRAY_SIZE (image_targets); i++)
+ for (j = 0; j < ARRAY_SIZE (image_targets[i].names) &&
+ image_targets[i].names[j]; j++)
+ if (strcmp (arg, image_targets[i].names[j]) == 0)
+ return &image_targets[i];
+ return NULL;
+}
+
+const char *
+grub_util_get_target_dirname (const struct grub_install_image_target_desc *t)
+{
+ return t->dirname;
+}
+
+const char *
+grub_util_get_target_name (const struct grub_install_image_target_desc *t)
+{
+ return t->names[0];
+}
+
+char *
+grub_install_get_image_targets_string (void)
+{
+ int format_len = 0;
+ char *formats;
+ char *ptr;
+ unsigned i;
+ for (i = 0; i < ARRAY_SIZE (image_targets); i++)
+ format_len += strlen (image_targets[i].names[0]) + 2;
+ ptr = formats = xmalloc (format_len);
+ for (i = 0; i < ARRAY_SIZE (image_targets); i++)
+ {
+ strcpy (ptr, image_targets[i].names[0]);
+ ptr += strlen (image_targets[i].names[0]);
+ *ptr++ = ',';
+ *ptr++ = ' ';
+ }
+ ptr[-2] = 0;
+
+ return formats;
+}
+
+void
+grub_install_generate_image (const char *dir, const char *prefix,
+ FILE *out, const char *outname, char *mods[],
+ char *memdisk_path, char **pubkey_paths,
+ size_t npubkeys, char *config_path,
+ const struct grub_install_image_target_desc *image_target,
+ int note, grub_compression_t comp, const char *dtb_path)
+{
+ char *kernel_img, *core_img;
+ size_t total_module_size, core_size;
+ size_t memdisk_size = 0, config_size = 0;
+ size_t prefix_size = 0, dtb_size = 0;
+ char *kernel_path;
+ size_t offset;
+ struct grub_util_path_list *path_list, *p;
+ size_t decompress_size = 0;
+ struct grub_mkimage_layout layout;
+
+ if (comp == GRUB_COMPRESSION_AUTO)
+ comp = image_target->default_compression;
+
+ if (image_target->id == IMAGE_I386_PC
+ || image_target->id == IMAGE_I386_PC_PXE
+ || image_target->id == IMAGE_I386_PC_ELTORITO)
+ comp = GRUB_COMPRESSION_LZMA;
+
+ path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
+
+ kernel_path = grub_util_get_path (dir, "kernel.img");
+
+ if (image_target->voidp_sizeof == 8)
+ total_module_size = sizeof (struct grub_module_info64);
+ else
+ total_module_size = sizeof (struct grub_module_info32);
+
+ {
+ size_t i;
+ for (i = 0; i < npubkeys; i++)
+ {
+ size_t curs;
+ curs = ALIGN_ADDR (grub_util_get_image_size (pubkey_paths[i]));
+ grub_util_info ("the size of public key %u is 0x%"
+ GRUB_HOST_PRIxLONG_LONG,
+ (unsigned) i, (unsigned long long) curs);
+ total_module_size += curs + sizeof (struct grub_module_header);
+ }
+ }
+
+ if (memdisk_path)
+ {
+ memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512);
+ grub_util_info ("the size of memory disk is 0x%" GRUB_HOST_PRIxLONG_LONG,
+ (unsigned long long) memdisk_size);
+ total_module_size += memdisk_size + sizeof (struct grub_module_header);
+ }
+
+ if (dtb_path)
+ {
+ dtb_size = ALIGN_ADDR(grub_util_get_image_size (dtb_path));
+ total_module_size += dtb_size + sizeof (struct grub_module_header);
+ }
+
+ if (config_path)
+ {
+ config_size = ALIGN_ADDR (grub_util_get_image_size (config_path) + 1);
+ grub_util_info ("the size of config file is 0x%" GRUB_HOST_PRIxLONG_LONG,
+ (unsigned long long) config_size);
+ total_module_size += config_size + sizeof (struct grub_module_header);
+ }
+
+ if (prefix)
+ {
+ prefix_size = ALIGN_ADDR (strlen (prefix) + 1);
+ total_module_size += prefix_size + sizeof (struct grub_module_header);
+ }
+
+ for (p = path_list; p; p = p->next)
+ total_module_size += (ALIGN_ADDR (grub_util_get_image_size (p->name))
+ + sizeof (struct grub_module_header));
+
+ grub_util_info ("the total module size is 0x%" GRUB_HOST_PRIxLONG_LONG,
+ (unsigned long long) total_module_size);
+
+ if (image_target->voidp_sizeof == 4)
+ kernel_img = grub_mkimage_load_image32 (kernel_path, total_module_size,
+ &layout, image_target);
+ else
+ kernel_img = grub_mkimage_load_image64 (kernel_path, total_module_size,
+ &layout, image_target);
+ if ((image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH) &&
+ layout.align < 4096)
+ layout.align = 4096;
+
+ if ((image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
+ && (image_target->total_module_size != TARGET_NO_FIELD))
+ *((grub_uint32_t *) (kernel_img + image_target->total_module_size))
+ = grub_host_to_target32 (total_module_size);
+
+ if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
+ {
+ memmove (kernel_img + total_module_size, kernel_img, layout.kernel_size);
+ memset (kernel_img, 0, total_module_size);
+ }
+
+ if (image_target->voidp_sizeof == 8)
+ {
+ /* Fill in the grub_module_info structure. */
+ struct grub_module_info64 *modinfo;
+ if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
+ modinfo = (struct grub_module_info64 *) kernel_img;
+ else
+ modinfo = (struct grub_module_info64 *) (kernel_img + layout.kernel_size);
+ modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC);
+ modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info64));
+ modinfo->size = grub_host_to_target_addr (total_module_size);
+ if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
+ offset = sizeof (struct grub_module_info64);
+ else
+ offset = layout.kernel_size + sizeof (struct grub_module_info64);
+ }
+ else
+ {
+ /* Fill in the grub_module_info structure. */
+ struct grub_module_info32 *modinfo;
+ if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
+ modinfo = (struct grub_module_info32 *) kernel_img;
+ else
+ modinfo = (struct grub_module_info32 *) (kernel_img + layout.kernel_size);
+ modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC);
+ modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info32));
+ modinfo->size = grub_host_to_target_addr (total_module_size);
+ if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
+ offset = sizeof (struct grub_module_info32);
+ else
+ offset = layout.kernel_size + sizeof (struct grub_module_info32);
+ }
+
+ for (p = path_list; p; p = p->next)
+ {
+ struct grub_module_header *header;
+ size_t mod_size;
+
+ mod_size = ALIGN_ADDR (grub_util_get_image_size (p->name));
+
+ header = (struct grub_module_header *) (kernel_img + offset);
+ header->type = grub_host_to_target32 (OBJ_TYPE_ELF);
+ header->size = grub_host_to_target32 (mod_size + sizeof (*header));
+ offset += sizeof (*header);
+
+ grub_util_load_image (p->name, kernel_img + offset);
+ offset += mod_size;
+ }
+
+ {
+ size_t i;
+ for (i = 0; i < npubkeys; i++)
+ {
+ size_t curs;
+ struct grub_module_header *header;
+
+ curs = grub_util_get_image_size (pubkey_paths[i]);
+
+ header = (struct grub_module_header *) (kernel_img + offset);
+ header->type = grub_host_to_target32 (OBJ_TYPE_PUBKEY);
+ header->size = grub_host_to_target32 (curs + sizeof (*header));
+ offset += sizeof (*header);
+
+ grub_util_load_image (pubkey_paths[i], kernel_img + offset);
+ offset += ALIGN_ADDR (curs);
+ }
+ }
+
+ if (memdisk_path)
+ {
+ struct grub_module_header *header;
+
+ header = (struct grub_module_header *) (kernel_img + offset);
+ header->type = grub_host_to_target32 (OBJ_TYPE_MEMDISK);
+ header->size = grub_host_to_target32 (memdisk_size + sizeof (*header));
+ offset += sizeof (*header);
+
+ grub_util_load_image (memdisk_path, kernel_img + offset);
+ offset += memdisk_size;
+ }
+
+ if (dtb_path)
+ {
+ struct grub_module_header *header;
+
+ header = (struct grub_module_header *) (kernel_img + offset);
+ header->type = grub_host_to_target32 (OBJ_TYPE_DTB);
+ header->size = grub_host_to_target32 (dtb_size + sizeof (*header));
+ offset += sizeof (*header);
+
+ grub_util_load_image (dtb_path, kernel_img + offset);
+ offset += dtb_size;
+ }
+
+ if (config_path)
+ {
+ struct grub_module_header *header;
+
+ header = (struct grub_module_header *) (kernel_img + offset);
+ header->type = grub_host_to_target32 (OBJ_TYPE_CONFIG);
+ header->size = grub_host_to_target32 (config_size + sizeof (*header));
+ offset += sizeof (*header);
+
+ grub_util_load_image (config_path, kernel_img + offset);
+ offset += config_size;
+ }
+
+ if (prefix)
+ {
+ struct grub_module_header *header;
+
+ header = (struct grub_module_header *) (kernel_img + offset);
+ header->type = grub_host_to_target32 (OBJ_TYPE_PREFIX);
+ header->size = grub_host_to_target32 (prefix_size + sizeof (*header));
+ offset += sizeof (*header);
+
+ grub_strcpy (kernel_img + offset, prefix);
+ offset += prefix_size;
+ }
+
+ grub_util_info ("kernel_img=%p, kernel_size=0x%" GRUB_HOST_PRIxLONG_LONG,
+ kernel_img,
+ (unsigned long long) layout.kernel_size);
+ compress_kernel (image_target, kernel_img, layout.kernel_size + total_module_size,
+ &core_img, &core_size, comp);
+ free (kernel_img);
+
+ grub_util_info ("the core size is 0x%" GRUB_HOST_PRIxLONG_LONG,
+ (unsigned long long) core_size);
+
+ if (!(image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
+ && image_target->total_module_size != TARGET_NO_FIELD)
+ *((grub_uint32_t *) (core_img + image_target->total_module_size))
+ = grub_host_to_target32 (total_module_size);
+
+ if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
+ {
+ char *full_img;
+ size_t full_size;
+ char *decompress_path, *decompress_img;
+ const char *name;
+
+ switch (comp)
+ {
+ case GRUB_COMPRESSION_XZ:
+ name = "xz_decompress.img";
+ break;
+ case GRUB_COMPRESSION_LZMA:
+ name = "lzma_decompress.img";
+ break;
+ case GRUB_COMPRESSION_NONE:
+ name = "none_decompress.img";
+ break;
+ default:
+ grub_util_error (_("unknown compression %d"), comp);
+ }
+
+ decompress_path = grub_util_get_path (dir, name);
+ decompress_size = grub_util_get_image_size (decompress_path);
+ decompress_img = grub_util_read_image (decompress_path);
+
+ if ((image_target->id == IMAGE_I386_PC
+ || image_target->id == IMAGE_I386_PC_PXE
+ || image_target->id == IMAGE_I386_PC_ELTORITO)
+ && decompress_size > GRUB_KERNEL_I386_PC_LINK_ADDR - 0x8200)
+ grub_util_error ("%s", _("Decompressor is too big"));
+
+ if (image_target->decompressor_compressed_size != TARGET_NO_FIELD)
+ *((grub_uint32_t *) (decompress_img
+ + image_target->decompressor_compressed_size))
+ = grub_host_to_target32 (core_size);
+
+ if (image_target->decompressor_uncompressed_size != TARGET_NO_FIELD)
+ *((grub_uint32_t *) (decompress_img
+ + image_target->decompressor_uncompressed_size))
+ = grub_host_to_target32 (layout.kernel_size + total_module_size);
+
+ if (image_target->decompressor_uncompressed_addr != TARGET_NO_FIELD)
+ {
+ if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
+ *((grub_uint32_t *) (decompress_img + image_target->decompressor_uncompressed_addr))
+ = grub_host_to_target_addr (image_target->link_addr - total_module_size);
+ else
+ *((grub_uint32_t *) (decompress_img + image_target->decompressor_uncompressed_addr))
+ = grub_host_to_target_addr (image_target->link_addr);
+ }
+ full_size = core_size + decompress_size;
+
+ full_img = xmalloc (full_size);
+
+ memcpy (full_img, decompress_img, decompress_size);
+
+ memcpy (full_img + decompress_size, core_img, core_size);
+
+ free (core_img);
+ core_img = full_img;
+ core_size = full_size;
+ free (decompress_img);
+ free (decompress_path);
+ }
+
+ switch (image_target->id)
+ {
+ case IMAGE_I386_PC:
+ case IMAGE_I386_PC_PXE:
+ case IMAGE_I386_PC_ELTORITO:
+ if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > 0x78000
+ || (core_size > (0xffff << GRUB_DISK_SECTOR_BITS))
+ || (layout.kernel_size + layout.bss_size
+ + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000))
+ grub_util_error (_("core image is too big (0x%x > 0x%x)"),
+ GRUB_KERNEL_I386_PC_LINK_ADDR + (unsigned) core_size,
+ 0x78000);
+ /* fallthrough */
+ case IMAGE_COREBOOT:
+ case IMAGE_QEMU:
+ if (image_target->elf_target != EM_ARM && layout.kernel_size + layout.bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000)
+ grub_util_error (_("kernel image is too big (0x%x > 0x%x)"),
+ (unsigned) layout.kernel_size + (unsigned) layout.bss_size
+ + GRUB_KERNEL_I386_PC_LINK_ADDR,
+ 0x68000);
+ break;
+ case IMAGE_LOONGSON_ELF:
+ case IMAGE_YEELOONG_FLASH:
+ case IMAGE_FULOONG2F_FLASH:
+ case IMAGE_EFI:
+ case IMAGE_MIPS_ARC:
+ case IMAGE_QEMU_MIPS_FLASH:
+ case IMAGE_XEN:
+ case IMAGE_XEN_PVH:
+ break;
+ case IMAGE_SPARC64_AOUT:
+ case IMAGE_SPARC64_RAW:
+ case IMAGE_SPARC64_CDCORE:
+ case IMAGE_I386_IEEE1275:
+ case IMAGE_PPC:
+ case IMAGE_UBOOT:
+ break;
+ }
+
+ switch (image_target->id)
+ {
+ case IMAGE_I386_PC:
+ case IMAGE_I386_PC_PXE:
+ case IMAGE_I386_PC_ELTORITO:
+ {
+ unsigned num;
+ char *boot_path, *boot_img;
+ size_t boot_size;
+
+ num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS);
+ if (image_target->id == IMAGE_I386_PC_PXE)
+ {
+ char *pxeboot_path, *pxeboot_img;
+ size_t pxeboot_size;
+ grub_uint32_t *ptr;
+
+ pxeboot_path = grub_util_get_path (dir, "pxeboot.img");
+ pxeboot_size = grub_util_get_image_size (pxeboot_path);
+ pxeboot_img = grub_util_read_image (pxeboot_path);
+
+ grub_util_write_image (pxeboot_img, pxeboot_size, out,
+ outname);
+ free (pxeboot_img);
+ free (pxeboot_path);
+
+ /* Remove Multiboot header to avoid confusing ipxe. */
+ for (ptr = (grub_uint32_t *) core_img;
+ ptr < (grub_uint32_t *) (core_img + MULTIBOOT_SEARCH); ptr++)
+ if (*ptr == grub_host_to_target32 (MULTIBOOT_HEADER_MAGIC)
+ && grub_target_to_host32 (ptr[0])
+ + grub_target_to_host32 (ptr[1])
+ + grub_target_to_host32 (ptr[2]) == 0)
+ {
+ *ptr = 0;
+ break;
+ }
+ }
+
+ if (image_target->id == IMAGE_I386_PC_ELTORITO)
+ {
+ char *eltorito_path, *eltorito_img;
+ size_t eltorito_size;
+
+ eltorito_path = grub_util_get_path (dir, "cdboot.img");
+ eltorito_size = grub_util_get_image_size (eltorito_path);
+ eltorito_img = grub_util_read_image (eltorito_path);
+
+ grub_util_write_image (eltorito_img, eltorito_size, out,
+ outname);
+ free (eltorito_img);
+ free (eltorito_path);
+ }
+
+ boot_path = grub_util_get_path (dir, "diskboot.img");
+ boot_size = grub_util_get_image_size (boot_path);
+ if (boot_size != GRUB_DISK_SECTOR_SIZE)
+ grub_util_error (_("diskboot.img size must be %u bytes"),
+ GRUB_DISK_SECTOR_SIZE);
+
+ boot_img = grub_util_read_image (boot_path);
+
+ {
+ struct grub_pc_bios_boot_blocklist *block;
+ block = (struct grub_pc_bios_boot_blocklist *) (boot_img
+ + GRUB_DISK_SECTOR_SIZE
+ - sizeof (*block));
+ block->len = grub_host_to_target16 (num);
+
+ /* This is filled elsewhere. Verify it just in case. */
+ assert (block->segment
+ == grub_host_to_target16 (GRUB_BOOT_I386_PC_KERNEL_SEG
+ + (GRUB_DISK_SECTOR_SIZE >> 4)));
+ }
+
+ grub_util_write_image (boot_img, boot_size, out, outname);
+ free (boot_img);
+ free (boot_path);
+ }
+ break;
+ case IMAGE_EFI:
+ {
+ void *pe_img;
+ grub_uint8_t *header;
+ void *sections;
+ size_t pe_size;
+ struct grub_pe32_coff_header *c;
+ struct grub_pe32_section_table *text_section, *data_section;
+ struct grub_pe32_section_table *mods_section, *reloc_section;
+ static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB;
+ int header_size;
+ int reloc_addr;
+
+ if (image_target->voidp_sizeof == 4)
+ header_size = EFI32_HEADER_SIZE;
+ else
+ header_size = EFI64_HEADER_SIZE;
+
+ reloc_addr = ALIGN_UP (header_size + core_size,
+ GRUB_PE32_FILE_ALIGNMENT);
+
+ pe_size = ALIGN_UP (reloc_addr + layout.reloc_size,
+ GRUB_PE32_FILE_ALIGNMENT);
+ pe_img = xmalloc (reloc_addr + layout.reloc_size);
+ memset (pe_img, 0, header_size);
+ memcpy ((char *) pe_img + header_size, core_img, core_size);
+ memset ((char *) pe_img + header_size + core_size, 0, reloc_addr - (header_size + core_size));
+ memcpy ((char *) pe_img + reloc_addr, layout.reloc_section, layout.reloc_size);
+ header = pe_img;
+
+ /* The magic. */
+ memcpy (header, stub, GRUB_PE32_MSDOS_STUB_SIZE);
+ memcpy (header + GRUB_PE32_MSDOS_STUB_SIZE, "PE\0\0",
+ GRUB_PE32_SIGNATURE_SIZE);
+
+ /* The COFF file header. */
+ c = (struct grub_pe32_coff_header *) (header + GRUB_PE32_MSDOS_STUB_SIZE
+ + GRUB_PE32_SIGNATURE_SIZE);
+ c->machine = grub_host_to_target16 (image_target->pe_target);
+
+ c->num_sections = grub_host_to_target16 (4);
+ c->time = grub_host_to_target32 (STABLE_EMBEDDING_TIMESTAMP);
+ c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE
+ | GRUB_PE32_LINE_NUMS_STRIPPED
+ | ((image_target->voidp_sizeof == 4)
+ ? GRUB_PE32_32BIT_MACHINE
+ : 0)
+ | GRUB_PE32_LOCAL_SYMS_STRIPPED
+ | GRUB_PE32_DEBUG_STRIPPED);
+
+ /* The PE Optional header. */
+ if (image_target->voidp_sizeof == 4)
+ {
+ struct grub_pe32_optional_header *o;
+
+ c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header));
+
+ o = (struct grub_pe32_optional_header *)
+ (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE
+ + sizeof (struct grub_pe32_coff_header));
+ o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC);
+ o->code_size = grub_host_to_target32 (layout.exec_size);
+ o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size
+ - header_size);
+ o->bss_size = grub_cpu_to_le32 (layout.bss_size);
+ o->entry_addr = grub_cpu_to_le32 (layout.start_address);
+ o->code_base = grub_cpu_to_le32 (header_size);
+
+ o->data_base = grub_host_to_target32 (header_size + layout.exec_size);
+
+ o->image_base = 0;
+ o->section_alignment = grub_host_to_target32 (image_target->section_align);
+ o->file_alignment = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT);
+ o->image_size = grub_host_to_target32 (pe_size);
+ o->header_size = grub_host_to_target32 (header_size);
+ o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION);
+
+ /* Do these really matter? */
+ o->stack_reserve_size = grub_host_to_target32 (0x10000);
+ o->stack_commit_size = grub_host_to_target32 (0x10000);
+ o->heap_reserve_size = grub_host_to_target32 (0x10000);
+ o->heap_commit_size = grub_host_to_target32 (0x10000);
+
+ o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
+
+ o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr);
+ o->base_relocation_table.size = grub_host_to_target32 (layout.reloc_size);
+ sections = o + 1;
+ }
+ else
+ {
+ struct grub_pe64_optional_header *o;
+
+ c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header));
+
+ o = (struct grub_pe64_optional_header *)
+ (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE
+ + sizeof (struct grub_pe32_coff_header));
+ o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC);
+ o->code_size = grub_host_to_target32 (layout.exec_size);
+ o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size
+ - header_size);
+ o->bss_size = grub_cpu_to_le32 (layout.bss_size);
+ o->entry_addr = grub_cpu_to_le32 (layout.start_address);
+ o->code_base = grub_cpu_to_le32 (header_size);
+ o->image_base = 0;
+ o->section_alignment = grub_host_to_target32 (image_target->section_align);
+ o->file_alignment = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT);
+ o->image_size = grub_host_to_target32 (pe_size);
+ o->header_size = grub_host_to_target32 (header_size);
+ o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION);
+
+ /* Do these really matter? */
+ o->stack_reserve_size = grub_host_to_target64 (0x10000);
+ o->stack_commit_size = grub_host_to_target64 (0x10000);
+ o->heap_reserve_size = grub_host_to_target64 (0x10000);
+ o->heap_commit_size = grub_host_to_target64 (0x10000);
+
+ o->num_data_directories
+ = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
+
+ o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr);
+ o->base_relocation_table.size = grub_host_to_target32 (layout.reloc_size);
+ sections = o + 1;
+ }
+ /* The sections. */
+ text_section = sections;
+ strcpy (text_section->name, ".text");
+ text_section->virtual_size = grub_cpu_to_le32 (layout.exec_size);
+ text_section->virtual_address = grub_cpu_to_le32 (header_size);
+ text_section->raw_data_size = grub_cpu_to_le32 (layout.exec_size);
+ text_section->raw_data_offset = grub_cpu_to_le32 (header_size);
+ text_section->characteristics = grub_cpu_to_le32_compile_time (
+ GRUB_PE32_SCN_CNT_CODE
+ | GRUB_PE32_SCN_MEM_EXECUTE
+ | GRUB_PE32_SCN_MEM_READ);
+
+ data_section = text_section + 1;
+ strcpy (data_section->name, ".data");
+ data_section->virtual_size = grub_cpu_to_le32 (layout.kernel_size - layout.exec_size);
+ data_section->virtual_address = grub_cpu_to_le32 (header_size + layout.exec_size);
+ data_section->raw_data_size = grub_cpu_to_le32 (layout.kernel_size - layout.exec_size);
+ data_section->raw_data_offset = grub_cpu_to_le32 (header_size + layout.exec_size);
+ data_section->characteristics
+ = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
+ | GRUB_PE32_SCN_MEM_READ
+ | GRUB_PE32_SCN_MEM_WRITE);
+
+#if 0
+ bss_section = data_section + 1;
+ strcpy (bss_section->name, ".bss");
+ bss_section->virtual_size = grub_cpu_to_le32 (layout.bss_size);
+ bss_section->virtual_address = grub_cpu_to_le32 (header_size + layout.kernel_size);
+ bss_section->raw_data_size = 0;
+ bss_section->raw_data_offset = 0;
+ bss_section->characteristics
+ = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_MEM_READ
+ | GRUB_PE32_SCN_MEM_WRITE
+ | GRUB_PE32_SCN_ALIGN_64BYTES
+ | GRUB_PE32_SCN_CNT_INITIALIZED_DATA
+ | 0x80);
+#endif
+
+ mods_section = data_section + 1;
+ strcpy (mods_section->name, "mods");
+ mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - layout.kernel_size - header_size);
+ mods_section->virtual_address = grub_cpu_to_le32 (header_size + layout.kernel_size + layout.bss_size);
+ mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - layout.kernel_size - header_size);
+ mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + layout.kernel_size);
+ mods_section->characteristics
+ = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
+ | GRUB_PE32_SCN_MEM_READ
+ | GRUB_PE32_SCN_MEM_WRITE);
+
+ reloc_section = mods_section + 1;
+ strcpy (reloc_section->name, ".reloc");
+ reloc_section->virtual_size = grub_cpu_to_le32 (layout.reloc_size);
+ reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + layout.bss_size);
+ reloc_section->raw_data_size = grub_cpu_to_le32 (layout.reloc_size);
+ reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr);
+ reloc_section->characteristics
+ = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
+ | GRUB_PE32_SCN_MEM_DISCARDABLE
+ | GRUB_PE32_SCN_MEM_READ);
+ free (core_img);
+ core_img = pe_img;
+ core_size = pe_size;
+ }
+ break;
+ case IMAGE_QEMU:
+ {
+ char *rom_img;
+ size_t rom_size;
+ char *boot_path, *boot_img;
+ size_t boot_size;
+
+ boot_path = grub_util_get_path (dir, "boot.img");
+ boot_size = grub_util_get_image_size (boot_path);
+ boot_img = grub_util_read_image (boot_path);
+
+ /* Rom sizes must be 64k-aligned. */
+ rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024);
+
+ rom_img = xmalloc (rom_size);
+ memset (rom_img, 0, rom_size);
+
+ *((grub_int32_t *) (core_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR))
+ = grub_host_to_target32 ((grub_uint32_t) -rom_size);
+
+ memcpy (rom_img, core_img, core_size);
+
+ *((grub_int32_t *) (boot_img + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR))
+ = grub_host_to_target32 ((grub_uint32_t) -rom_size);
+
+ memcpy (rom_img + rom_size - boot_size, boot_img, boot_size);
+
+ free (core_img);
+ core_img = rom_img;
+ core_size = rom_size;
+
+ free (boot_img);
+ free (boot_path);
+ }
+ break;
+ case IMAGE_SPARC64_AOUT:
+ {
+ void *aout_img;
+ size_t aout_size;
+ struct grub_aout32_header *aout_head;
+
+ aout_size = core_size + sizeof (*aout_head);
+ aout_img = xmalloc (aout_size);
+ aout_head = aout_img;
+ grub_memset (aout_head, 0, sizeof (*aout_head));
+ aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16)
+ | AOUT32_OMAGIC);
+ aout_head->a_text = grub_host_to_target32 (core_size);
+ aout_head->a_entry
+ = grub_host_to_target32 (GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS);
+ memcpy ((char *) aout_img + sizeof (*aout_head), core_img, core_size);
+
+ free (core_img);
+ core_img = aout_img;
+ core_size = aout_size;
+ }
+ break;
+ case IMAGE_SPARC64_RAW:
+ {
+ unsigned int num;
+ char *boot_path, *boot_img;
+ size_t boot_size;
+
+ num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS);
+ num <<= GRUB_DISK_SECTOR_BITS;
+
+ boot_path = grub_util_get_path (dir, "diskboot.img");
+ boot_size = grub_util_get_image_size (boot_path);
+ if (boot_size != GRUB_DISK_SECTOR_SIZE)
+ grub_util_error (_("diskboot.img size must be %u bytes"),
+ GRUB_DISK_SECTOR_SIZE);
+
+ boot_img = grub_util_read_image (boot_path);
+
+ *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE
+ - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE + 8))
+ = grub_host_to_target32 (num);
+
+ grub_util_write_image (boot_img, boot_size, out, outname);
+ free (boot_img);
+ free (boot_path);
+ }
+ break;
+ case IMAGE_SPARC64_CDCORE:
+ break;
+ case IMAGE_YEELOONG_FLASH:
+ case IMAGE_FULOONG2F_FLASH:
+ {
+ char *rom_img;
+ size_t rom_size;
+ char *boot_path, *boot_img;
+ size_t boot_size;
+ /* fwstart.img is the only part which can't be tested by using *-elf
+ target. Check it against the checksum. */
+ const grub_uint8_t yeeloong_fwstart_good_hash[512 / 8] =
+ {
+ 0x5f, 0x67, 0x46, 0x57, 0x31, 0x30, 0xc5, 0x0a,
+ 0xe9, 0x98, 0x18, 0xc9, 0xf3, 0xca, 0x45, 0xa5,
+ 0x75, 0x64, 0x6b, 0xbb, 0x24, 0xcd, 0xb4, 0xbc,
+ 0xf2, 0x3e, 0x23, 0xf9, 0xc2, 0x6a, 0x8c, 0xde,
+ 0x3b, 0x94, 0x9c, 0xcc, 0xa5, 0xa7, 0x58, 0xb1,
+ 0xbe, 0x8b, 0x3d, 0x73, 0x98, 0x18, 0x7e, 0x68,
+ 0x5e, 0x5f, 0x23, 0x7d, 0x7a, 0xe8, 0x51, 0xf7,
+ 0x1a, 0xaf, 0x2f, 0x54, 0x11, 0x2e, 0x5c, 0x25
+ };
+ const grub_uint8_t fuloong2f_fwstart_good_hash[512 / 8] =
+ {
+ 0x76, 0x9b, 0xad, 0x6e, 0xa2, 0x39, 0x47, 0x62,
+ 0x1f, 0xc9, 0x3a, 0x6d, 0x05, 0x5c, 0x43, 0x5c,
+ 0x29, 0x4a, 0x7e, 0x08, 0x2a, 0x31, 0x8f, 0x5d,
+ 0x02, 0x84, 0xa0, 0x85, 0xf2, 0xd1, 0xb9, 0x53,
+ 0xa2, 0xbc, 0xf2, 0xe1, 0x39, 0x1e, 0x51, 0xb5,
+ 0xaf, 0xec, 0x9e, 0xf2, 0xf1, 0xf3, 0x0a, 0x2f,
+ 0xe6, 0xf1, 0x08, 0x89, 0xbe, 0xbc, 0x73, 0xab,
+ 0x46, 0x50, 0xd6, 0x21, 0xce, 0x8e, 0x24, 0xa7
+ };
+ const grub_uint8_t *fwstart_good_hash;
+ grub_uint8_t fwstart_hash[512 / 8];
+
+ if (image_target->id == IMAGE_FULOONG2F_FLASH)
+ {
+ fwstart_good_hash = fuloong2f_fwstart_good_hash;
+ boot_path = grub_util_get_path (dir, "fwstart_fuloong2f.img");
+ }
+ else
+ {
+ fwstart_good_hash = yeeloong_fwstart_good_hash;
+ boot_path = grub_util_get_path (dir, "fwstart.img");
+ }
+
+ boot_size = grub_util_get_image_size (boot_path);
+ boot_img = grub_util_read_image (boot_path);
+
+ grub_crypto_hash (GRUB_MD_SHA512, fwstart_hash, boot_img, boot_size);
+
+ if (grub_memcmp (fwstart_hash, fwstart_good_hash,
+ GRUB_MD_SHA512->mdlen) != 0)
+ /* TRANSLATORS: fwstart.img may still be good, just it wasn't checked. */
+ grub_util_warn ("%s",
+ _("fwstart.img doesn't match the known good version. "
+ "proceed at your own risk"));
+
+ if (core_size + boot_size > 512 * 1024)
+ grub_util_error ("%s", _("firmware image is too big"));
+ rom_size = 512 * 1024;
+
+ rom_img = xmalloc (rom_size);
+ memset (rom_img, 0, rom_size);
+
+ memcpy (rom_img, boot_img, boot_size);
+
+ memcpy (rom_img + boot_size, core_img, core_size);
+
+ memset (rom_img + boot_size + core_size, 0,
+ rom_size - (boot_size + core_size));
+
+ free (core_img);
+ core_img = rom_img;
+ core_size = rom_size;
+ free (boot_img);
+ free (boot_path);
+ }
+ break;
+ case IMAGE_QEMU_MIPS_FLASH:
+ {
+ char *rom_img;
+ size_t rom_size;
+
+ if (core_size > 512 * 1024)
+ grub_util_error ("%s", _("firmware image is too big"));
+ rom_size = 512 * 1024;
+
+ rom_img = xmalloc (rom_size);
+ memset (rom_img, 0, rom_size);
+
+ memcpy (rom_img, core_img, core_size);
+
+ memset (rom_img + core_size, 0,
+ rom_size - core_size);
+
+ free (core_img);
+ core_img = rom_img;
+ core_size = rom_size;
+ }
+ break;
+
+ case IMAGE_UBOOT:
+ {
+ struct grub_uboot_image_header *hdr;
+
+ hdr = xmalloc (core_size + sizeof (struct grub_uboot_image_header));
+ memcpy (hdr + 1, core_img, core_size);
+
+ memset (hdr, 0, sizeof (*hdr));
+ hdr->ih_magic = grub_cpu_to_be32_compile_time (GRUB_UBOOT_IH_MAGIC);
+ hdr->ih_time = grub_cpu_to_be32 (STABLE_EMBEDDING_TIMESTAMP);
+ hdr->ih_size = grub_cpu_to_be32 (core_size);
+ hdr->ih_load = 0;
+ hdr->ih_ep = 0;
+ hdr->ih_type = GRUB_UBOOT_IH_TYPE_KERNEL_NOLOAD;
+ hdr->ih_os = GRUB_UBOOT_IH_OS_LINUX;
+ hdr->ih_arch = GRUB_UBOOT_IH_ARCH_ARM;
+ hdr->ih_comp = GRUB_UBOOT_IH_COMP_NONE;
+
+ grub_crypto_hash (GRUB_MD_CRC32, &hdr->ih_dcrc, hdr + 1, core_size);
+ grub_crypto_hash (GRUB_MD_CRC32, &hdr->ih_hcrc, hdr, sizeof (*hdr));
+
+ free (core_img);
+ core_img = (char *) hdr;
+ core_size += sizeof (struct grub_uboot_image_header);
+ }
+ break;
+
+ case IMAGE_MIPS_ARC:
+ {
+ char *ecoff_img;
+ struct ecoff_header {
+ grub_uint16_t magic;
+ grub_uint16_t nsec;
+ grub_uint32_t time;
+ grub_uint32_t syms;
+ grub_uint32_t nsyms;
+ grub_uint16_t opt;
+ grub_uint16_t flags;
+ grub_uint16_t magic2;
+ grub_uint16_t version;
+ grub_uint32_t textsize;
+ grub_uint32_t datasize;
+ grub_uint32_t bsssize;
+ grub_uint32_t entry;
+ grub_uint32_t text_start;
+ grub_uint32_t data_start;
+ grub_uint32_t bss_start;
+ grub_uint32_t gprmask;
+ grub_uint32_t cprmask[4];
+ grub_uint32_t gp_value;
+ };
+ struct ecoff_section
+ {
+ char name[8];
+ grub_uint32_t paddr;
+ grub_uint32_t vaddr;
+ grub_uint32_t size;
+ grub_uint32_t file_offset;
+ grub_uint32_t reloc;
+ grub_uint32_t gp;
+ grub_uint16_t nreloc;
+ grub_uint16_t ngp;
+ grub_uint32_t flags;
+ };
+ struct ecoff_header *head;
+ struct ecoff_section *section;
+ grub_uint32_t target_addr;
+ size_t program_size;
+
+ program_size = ALIGN_ADDR (core_size);
+ if (comp == GRUB_COMPRESSION_NONE)
+ target_addr = (image_target->link_addr - decompress_size);
+ else
+ target_addr = ALIGN_UP (image_target->link_addr
+ + layout.kernel_size + total_module_size, 32);
+
+ ecoff_img = xmalloc (program_size + sizeof (*head) + sizeof (*section));
+ grub_memset (ecoff_img, 0, program_size + sizeof (*head) + sizeof (*section));
+ head = (void *) ecoff_img;
+ section = (void *) (head + 1);
+ head->magic = image_target->bigendian ? grub_host_to_target16 (0x160)
+ : grub_host_to_target16 (0x166);
+ head->nsec = grub_host_to_target16 (1);
+ head->time = grub_host_to_target32 (0);
+ head->opt = grub_host_to_target16 (0x38);
+ head->flags = image_target->bigendian
+ ? grub_host_to_target16 (0x207)
+ : grub_host_to_target16 (0x103);
+ head->magic2 = grub_host_to_target16 (0x107);
+ head->textsize = grub_host_to_target32 (program_size);
+ head->entry = grub_host_to_target32 (target_addr);
+ head->text_start = grub_host_to_target32 (target_addr);
+ head->data_start = grub_host_to_target32 (target_addr + program_size);
+ grub_memcpy (section->name, ".text", sizeof (".text") - 1);
+ section->vaddr = grub_host_to_target32 (target_addr);
+ section->size = grub_host_to_target32 (program_size);
+ section->file_offset = grub_host_to_target32 (sizeof (*head) + sizeof (*section));
+ if (!image_target->bigendian)
+ {
+ section->paddr = grub_host_to_target32 (0xaa60);
+ section->flags = grub_host_to_target32 (0x20);
+ }
+ memcpy (section + 1, core_img, core_size);
+ free (core_img);
+ core_img = ecoff_img;
+ core_size = program_size + sizeof (*head) + sizeof (*section);
+ }
+ break;
+ case IMAGE_LOONGSON_ELF:
+ case IMAGE_PPC:
+ case IMAGE_XEN:
+ case IMAGE_XEN_PVH:
+ case IMAGE_COREBOOT:
+ case IMAGE_I386_IEEE1275:
+ {
+ grub_uint64_t target_addr;
+ if (image_target->id == IMAGE_LOONGSON_ELF)
+ {
+ if (comp == GRUB_COMPRESSION_NONE)
+ target_addr = (image_target->link_addr - decompress_size);
+ else
+ target_addr = ALIGN_UP (image_target->link_addr
+ + layout.kernel_size + total_module_size, 32);
+ }
+ else
+ target_addr = image_target->link_addr;
+ if (image_target->voidp_sizeof == 4)
+ grub_mkimage_generate_elf32 (image_target, note, &core_img, &core_size,
+ target_addr, &layout);
+ else
+ grub_mkimage_generate_elf64 (image_target, note, &core_img, &core_size,
+ target_addr, &layout);
+ }
+ break;
+ }
+
+ grub_util_write_image (core_img, core_size, out, outname);
+ free (core_img);
+ free (kernel_path);
+ free (layout.reloc_section);
+
+ grub_util_free_path_list (path_list);
+}
sh install.sh arm64
+#build for mips64el EFI
+#http://ftp.loongnix.org/os/loongnix-server/1.7/os/Source/SPackages/grub2-2.02-0.40.lns7.14.loongnix.src.rpm
+make distclean
+./autogen.sh
+./configure --prefix=/home/share/Ventoy/GRUB2/INSTALL/ \
+--target=mips64el --with-platform=efi \
+--host=x86_64-linux-gnu \
+HOST_CC=x86_64-linux-gnu-gcc \
+BUILD_CC=gcc \
+TARGET_CC="mips-linux-gnu-gcc -mabi=64 -Wno-error=cast-align -Wno-error=misleading-indentation" \
+TARGET_OBJCOPY=mips-linux-gnu-objcopy \
+TARGET_STRIP=mips-linux-gnu-strip TARGET_NM=mips-linux-gnu-nm \
+TARGET_RANLIB=mips-linux-gnu-ranlib
+make -j 16 || exit 1
+sh install.sh mips64el
+
+
# build for i386-pc
echo '======== build grub2 for i386-pc ==============='
export SLEEP=$BUSYBOX_PATH/sleep
export HEAD=$BUSYBOX_PATH/head
-if [ -e $BUSYBOX_PATH/32h ]; then
- if [ -e $BUSYBOX_PATH/64h ]; then
- #this is arm64
- $BUSYBOX_PATH/xzminidecaa64 < $BUSYBOX_PATH/busyboxaa64.xz > $BUSYBOX_PATH/busybox
- $BUSYBOX_PATH/vtchmodaa64 $BUSYBOX_PATH/busybox
+if [ -e $BUSYBOX_PATH/busyboxaa64.xz ]; then
+ export VTOY_ARCH=aarch64
+elif [ -e $BUSYBOX_PATH/busyboxm64e.xz ]; then
+ export VTOY_ARCH=mips64el
+else
+ if [ -e $BUSYBOX_PATH/32h ]; then
+ export VTOY_ARCH=x86_64
+ else
+ export VTOY_ARCH=i386
+ fi
+fi
+
+echo $VTOY_ARCH > $VTOY_PATH/ventoy_arch
+
+
+if [ "$VTOY_ARCH" = "aarch64" ]; then
+ $BUSYBOX_PATH/xzminidecaa64 < $BUSYBOX_PATH/busyboxaa64.xz > $BUSYBOX_PATH/busybox
+ $BUSYBOX_PATH/vtchmodaa64 $BUSYBOX_PATH/busybox
+elif [ "$VTOY_ARCH" = "mips64el" ]; then
+ $BUSYBOX_PATH/xzminidecm64e < $BUSYBOX_PATH/busyboxm64e.xz > $BUSYBOX_PATH/busybox
+ $BUSYBOX_PATH/vtchmodm64e $BUSYBOX_PATH/busybox
+elif [ "$VTOY_ARCH" = "x86_64" ]; then
+ $BUSYBOX_PATH/xzminidec64 < $BUSYBOX_PATH/busybox64.xz > $BUSYBOX_PATH/busybox
+ if [ -s $BUSYBOX_PATH/busybox ]; then
+ $BUSYBOX_PATH/vtchmod64 $BUSYBOX_PATH/busybox
else
- #this is x86_64
- $BUSYBOX_PATH/xzminidec64 < $BUSYBOX_PATH/busybox64.xz > $BUSYBOX_PATH/busybox
- if [ -s $BUSYBOX_PATH/busybox ]; then
- $BUSYBOX_PATH/vtchmod64 $BUSYBOX_PATH/busybox
- else
- $BUSYBOX_PATH/xzminidec64_musl < $BUSYBOX_PATH/busybox64.xz > $BUSYBOX_PATH/busybox
- $BUSYBOX_PATH/vtchmod64_musl $BUSYBOX_PATH/busybox
- fi
+ $BUSYBOX_PATH/xzminidec64_musl < $BUSYBOX_PATH/busybox64.xz > $BUSYBOX_PATH/busybox
+ $BUSYBOX_PATH/vtchmod64_musl $BUSYBOX_PATH/busybox
fi
else
$BUSYBOX_PATH/xzminidec32 < $BUSYBOX_PATH/busybox32.xz > $BUSYBOX_PATH/busybox
xz -d -c loop.cpio.xz | cpio -idm 2>>$VTLOG
fi
-if [ -e $BUSYBOX_PATH/32h ]; then
- if [ -e $BUSYBOX_PATH/64h ]; then
- echo "Use ARM64 busybox toolkit ..." >>$VTLOG
- echo aarch64 > $VTOY_PATH/ventoy_arch
- ln -s $BUSYBOX_PATH/xzminidecaa64 $BUSYBOX_PATH/xzminidec
- ln -s $VTOY_PATH/tool/dmsetupaa64 $VTOY_PATH/tool/dmsetup
- ln -s $VTOY_PATH/tool/lunzipaa64 $VTOY_PATH/tool/lunzip
-
- rm -f $VTOY_PATH/tool/lz4cat $VTOY_PATH/tool/zstdcat
- ln -s $VTOY_PATH/tool/lz4cataa64 $VTOY_PATH/tool/lz4cat
- ln -s $VTOY_PATH/tool/zstdcataa64 $VTOY_PATH/tool/zstdcat
-
- else
- echo "Use x86_64 busybox toolkit ..." >>$VTLOG
- echo x86_64 > $VTOY_PATH/ventoy_arch
- ln -s $BUSYBOX_PATH/xzminidec64 $BUSYBOX_PATH/xzminidec
- ln -s $VTOY_PATH/tool/dmsetup64 $VTOY_PATH/tool/dmsetup
- ln -s $VTOY_PATH/tool/lunzip64 $VTOY_PATH/tool/lunzip
-
- rm -f $VTOY_PATH/tool/lz4cat $VTOY_PATH/tool/zstdcat
- ln -s $VTOY_PATH/tool/lz4cat64 $VTOY_PATH/tool/lz4cat
- ln -s $VTOY_PATH/tool/zstdcat64 $VTOY_PATH/tool/zstdcat
- fi
-else
+
+if [ "$VTOY_ARCH" = "x86_64" ]; then
+ echo "Use x86_64 busybox toolkit ..." >>$VTLOG
+ ln -s $BUSYBOX_PATH/xzminidec64 $BUSYBOX_PATH/xzminidec
+ ln -s $VTOY_PATH/tool/dmsetup64 $VTOY_PATH/tool/dmsetup
+ ln -s $VTOY_PATH/tool/lunzip64 $VTOY_PATH/tool/lunzip
+
+ rm -f $VTOY_PATH/tool/lz4cat $VTOY_PATH/tool/zstdcat
+ ln -s $VTOY_PATH/tool/lz4cat64 $VTOY_PATH/tool/lz4cat
+ ln -s $VTOY_PATH/tool/zstdcat64 $VTOY_PATH/tool/zstdcat
+elif [ "$VTOY_ARCH" = "i386" ]; then
echo "Use i386 busybox toolkit ..." >>$VTLOG
- echo i386 > $VTOY_PATH/ventoy_arch
ln -s $BUSYBOX_PATH/xzminidec32 $BUSYBOX_PATH/xzminidec
ln -s $VTOY_PATH/tool/dmsetup32 $VTOY_PATH/tool/dmsetup
ln -s $VTOY_PATH/tool/lunzip32 $VTOY_PATH/tool/lunzip
+
+elif [ "$VTOY_ARCH" = "mips64el" ]; then
+ echo "Use MIPS64 busybox toolkit ..." >>$VTLOG
+ ln -s $BUSYBOX_PATH/xzminidecm64e $BUSYBOX_PATH/xzminidec
+ ln -s $VTOY_PATH/tool/dmsetupm64e $VTOY_PATH/tool/dmsetup
+
+ # TBD
+ #ln -s $VTOY_PATH/tool/lunzipm64e $VTOY_PATH/tool/lunzip
+
+ rm -f $VTOY_PATH/tool/lz4cat $VTOY_PATH/tool/zstdcat
+ ln -s $VTOY_PATH/tool/lz4catm64e $VTOY_PATH/tool/lz4cat
+
+ # TBD
+ #ln -s $VTOY_PATH/tool/zstdcataa64 $VTOY_PATH/tool/zstdcat
+
+elif [ "$VTOY_ARCH" = "aarch64" ]; then
+ echo "Use ARM64 busybox toolkit ..." >>$VTLOG
+ ln -s $BUSYBOX_PATH/xzminidecaa64 $BUSYBOX_PATH/xzminidec
+ ln -s $VTOY_PATH/tool/dmsetupaa64 $VTOY_PATH/tool/dmsetup
+ ln -s $VTOY_PATH/tool/lunzipaa64 $VTOY_PATH/tool/lunzip
+
+ rm -f $VTOY_PATH/tool/lz4cat $VTOY_PATH/tool/zstdcat
+ ln -s $VTOY_PATH/tool/lz4cataa64 $VTOY_PATH/tool/lz4cat
+ ln -s $VTOY_PATH/tool/zstdcataa64 $VTOY_PATH/tool/zstdcat
+else
+ echo "Unknown busybox toolkit ..." >>$VTLOG
fi
rm -f *.xz
done
$BUSYBOX_PATH/cp -a $VTOY_PATH/tool/vtoy_fuse_iso_aa64 $VTOY_PATH/tool/vtoy_fuse_iso
- $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/unsquashfs_aa64 $VTOY_PATH/tool/vtoy_unsquashfs
+ $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/unsquashfs_aa64 $VTOY_PATH/tool/vtoy_unsquashfs
+elif $GREP -q mips64el $VTOY_PATH/ventoy_arch; then
+ for vtdir in $(ls $VTOY_PATH/tool/vtoytool/); do
+ echo "try $VTOY_PATH/tool/vtoytool/$vtdir/ ..." >> $VTLOG
+ if $VTOY_PATH/tool/vtoytool/$vtdir/vtoytool_m64e --install 2>>$VTLOG; then
+ echo "vtoytool_m64e OK" >> $VTLOG
+ break
+ fi
+ done
+
+ # TBD
+ #$BUSYBOX_PATH/cp -a $VTOY_PATH/tool/vtoy_fuse_iso_aa64 $VTOY_PATH/tool/vtoy_fuse_iso
+ #$BUSYBOX_PATH/cp -a $VTOY_PATH/tool/unsquashfs_aa64 $VTOY_PATH/tool/vtoy_unsquashfs
else
for vtdir in $(ls $VTOY_PATH/tool/vtoytool/); do
echo "try $VTOY_PATH/tool/vtoytool/$vtdir/ ..." >> $VTLOG
VENTOY_PATH=$PWD/../
-rm -f ventoy.cpio
+if [ -d cpio_tmp ]; then
+ rm -rf cpio_tmp
+fi
+
+
+############### cpio ############
chmod -R 777 cpio
+rm -f ventoy.cpio ventoy_x86.cpio ventoy_arm64.cpio ventoy_mips64.cpio
cp -a cpio cpio_tmp
cd ventoy
+find ./loop | cpio -o -H newc>loop.cpio
+xz loop.cpio
+rm -rf loop
+
+xz ventoy_chain.sh
+xz ventoy_loop.sh
+
+find ./hook | cpio -o -H newc>hook.cpio
+xz hook.cpio
+rm -rf hook
+cd ..
+
+find .| cpio -o -H newc>../ventoy.cpio
+
+cd ..
+rm -rf cpio_tmp
-cp -a $VENTOY_PATH/DMSETUP/dmsetup* tool/
-cp -a $VENTOY_PATH/SQUASHFS/unsquashfs_* tool/
-cp -a $VENTOY_PATH/FUSEISO/vtoy_fuse_iso_* tool/
+
+
+
+########## cpio_x86 ##############
+chmod -R 777 cpio_x86
+cp -a cpio_x86 cpio_tmp
+
+cd cpio_tmp/ventoy
+
+cp -a $VENTOY_PATH/DMSETUP/dmsetup32 tool/
+cp -a $VENTOY_PATH/DMSETUP/dmsetup64 tool/
+cp -a $VENTOY_PATH/SQUASHFS/unsquashfs_32 tool/
+cp -a $VENTOY_PATH/SQUASHFS/unsquashfs_64 tool/
+cp -a $VENTOY_PATH/FUSEISO/vtoy_fuse_iso_32 tool/
+cp -a $VENTOY_PATH/FUSEISO/vtoy_fuse_iso_64 tool/
cp -a $VENTOY_PATH/VtoyTool/vtoytool tool/
-cp -a $VENTOY_PATH/VBLADE/vblade-master/vblade_* tool/
+rm -f tool/vtoytool/00/vtoytool_aa64
+rm -f tool/vtoytool/00/vtoytool_m64e
+cp -a $VENTOY_PATH/VBLADE/vblade-master/vblade_32 tool/
+cp -a $VENTOY_PATH/VBLADE/vblade-master/vblade_64 tool/
cp -a $VENTOY_PATH/LZIP/lunzip32 tool/
cp -a $VENTOY_PATH/LZIP/lunzip64 tool/
-cp -a $VENTOY_PATH/LZIP/lunzipaa64 tool/
-
chmod -R 777 ./tool
xz tool.cpio
rm -rf tool
-find ./loop | cpio -o -H newc>loop.cpio
-xz loop.cpio
-rm -rf loop
+cd ..
+find .| cpio -o -H newc>../ventoy_x86.cpio
-xz ventoy_chain.sh
-xz ventoy_loop.sh
+cd ..
+rm -rf cpio_tmp
+
+
+########## cpio_arm64 ##############
+chmod -R 777 cpio_arm64
+cp -a cpio_arm64 cpio_tmp
+cp -a cpio_x86/ventoy/tool/*.sh cpio_tmp/ventoy/tool/
+
+cd cpio_tmp/ventoy
+
+cp -a $VENTOY_PATH/DMSETUP/dmsetupaa64 tool/
+cp -a $VENTOY_PATH/SQUASHFS/unsquashfs_aa64 tool/
+cp -a $VENTOY_PATH/FUSEISO/vtoy_fuse_iso_aa64 tool/
+cp -a $VENTOY_PATH/VtoyTool/vtoytool tool/
+rm -f tool/vtoytool/00/vtoytool_32
+rm -f tool/vtoytool/00/vtoytool_64
+rm -f tool/vtoytool/00/vtoytool_m64e
+cp -a $VENTOY_PATH/VBLADE/vblade-master/vblade_aa64 tool/
+
+cp -a $VENTOY_PATH/LZIP/lunzipaa64 tool/
+
+chmod -R 777 ./tool
+
+find ./tool | cpio -o -H newc>tool.cpio
+xz tool.cpio
+rm -rf tool
-find ./hook | cpio -o -H newc>hook.cpio
-xz hook.cpio
-rm -rf hook
cd ..
+find .| cpio -o -H newc>../ventoy_arm64.cpio
+
+cd ..
+rm -rf cpio_tmp
-find .| cpio -o -H newc>../ventoy.cpio
+
+
+########## cpio_mips64 ##############
+chmod -R 777 cpio_mips64
+cp -a cpio_mips64 cpio_tmp
+cp -a cpio_x86/ventoy/tool/*.sh cpio_tmp/ventoy/tool/
+
+cd cpio_tmp/ventoy
+
+cp -a $VENTOY_PATH/DMSETUP/dmsetupm64e tool/
+# cp -a $VENTOY_PATH/SQUASHFS/unsquashfs_m64e tool/
+# cp -a $VENTOY_PATH/FUSEISO/vtoy_fuse_iso_m64e tool/
+cp -a $VENTOY_PATH/VtoyTool/vtoytool tool/
+rm -f tool/vtoytool/00/vtoytool_32
+rm -f tool/vtoytool/00/vtoytool_64
+rm -f tool/vtoytool/00/vtoytool_aa64
+# cp -a $VENTOY_PATH/VBLADE/vblade-master/vblade_m64e tool/
+
+# cp -a $VENTOY_PATH/LZIP/lunzipaa64 tool/
+
+chmod -R 777 ./tool
+
+find ./tool | cpio -o -H newc>tool.cpio
+xz tool.cpio
+rm -rf tool
+
+cd ..
+find .| cpio -o -H newc>../ventoy_mips64.cpio
cd ..
rm -rf cpio_tmp
+
+
+
echo '======== SUCCESS ============='
-rm -f $VENTOY_PATH/INSTALL/ventoy/ventoy.cpio
-cp -a ventoy.cpio $VENTOY_PATH/INSTALL/ventoy/
+rm -f $VENTOY_PATH/INSTALL/ventoy/ventoy*.cpio
+cp -a ventoy*.cpio $VENTOY_PATH/INSTALL/ventoy/
echo "prepare_env ..."
sh prepare_env.sh
-export PATH=$PATH:/opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin:/opt/aarch64--uclibc--stable-2020.08-1/bin
+export PATH=$PATH:/opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin:/opt/aarch64--uclibc--stable-2020.08-1/bin:/opt/mips-loongson-gcc7.3-linux-gnu/2019.06-29/bin/:/opt/mips64el-linux-musl-gcc730/bin/
echo "build grub2 ..."
wget -q -O $VTOY_PATH/EDK2/edk2-edk2-stable201911.zip https://codeload.github.com/tianocore/edk2/zip/edk2-stable201911
wget -q -P /opt/ https://releases.linaro.org/components/toolchain/binaries/7.4-2019.02/aarch64-linux-gnu/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz
wget -q -P /opt/ https://toolchains.bootlin.com/downloads/releases/toolchains/aarch64/tarballs/aarch64--uclibc--stable-2020.08-1.tar.bz2
+wget -q -P /opt/ http://ftp.loongnix.org/toolchain/gcc/release/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz
sh all_in_one.sh CI
loopback loop "$1$2"
fi
- vt_load_cpio ${vtoy_path}/ventoy.cpio "$2" "$1" "busybox=$ventoy_busybox_ver"
+ vt_load_cpio $vtoy_path "$2" "$1" "busybox=$ventoy_busybox_ver"
vt_linux_clear_initrd
if [ -n "$vtoy_chain_mem_addr" ]; then
ventoy_acpi_param ${vtoy_chain_mem_addr} 2048
- ventoy_cli_console
- chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi fallback env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
- boot
+ ventoy_cli_console
+ if [ "$VTOY_EFI_ARCH" != "mips" ]; then
+ chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi fallback env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
+ boot
+ fi
+
# fallback
set vtback_root=$root
vt_push_last_entry
vt_set_boot_opt rdinit=/vtoy/vtoy
set root=(loop)
+ set vtback_cfg_find=0
for cfg in "/boot/grub/grub.cfg" "/EFI/BOOT/grub.cfg" "/EFI/debian/grub.cfg" "EFI/boot/grub.cfg" "efi/boot/grub.cfg" "/grub/grub.cfg" "EFI/BOOT/BOOTX64.conf"; do
if [ -e "$cfg" ]; then
+ set vtback_cfg_find=1
configfile "$cfg"
break
fi
done
+ if [ "$vtback_cfg_find" = "0" ]; then
+ echo " "
+ echo "No bootfile found for UEFI!"
+ echo "Maybe the image does not support $VTOY_EFI_ARCH UEFI"
+ echo " "
+ sleep 30
+ fi
+
vt_unset_boot_opt
set root=$vtback_root
set theme=$vtback_theme
vt_pop_last_entry
ventoy_gui_console
-
- echo "No bootfile found for UEFI!"
- echo "Maybe the image does not support $VTOY_EFI_ARCH UEFI"
- echo " "
else
echo "chain empty failed"
ventoy_pause
loopback loop "$1$2"
fi
- vt_load_cpio $vtoy_path/ventoy.cpio "$2" "$1" "busybox=$ventoy_busybox_ver"
+ vt_load_cpio $vtoy_path "$2" "$1" "busybox=$ventoy_busybox_ver"
vt_linux_clear_initrd
loopback loop "${1}${2}"
vt_img_sector "${1}${2}"
- vt_load_cpio $vtoy_path/ventoy.cpio "$2" "$1" "busybox=$ventoy_busybox_ver"
+ vt_load_cpio $vtoy_path "$2" "$1" "busybox=$ventoy_busybox_ver"
vt_trailer_cpio "$1" "$2" noinit
ventoy_debug_pause
if [ "$VTOY_EFI_ARCH" = "aa64" ]; then
set ventoy_busybox_ver=a64
+ elif [ "$VTOY_EFI_ARCH" = "mips" ]; then
+ set ventoy_busybox_ver=m64
else
set ventoy_busybox_ver=32
function ventoy_img_easyos {
- vt_load_cpio $vtoy_path/ventoy.cpio "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
loopback easysfs (vtimghd,1)/easy.sfs
}
function ventoy_img_volumio {
- vt_load_cpio $vtoy_path/ventoy.cpio "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
ventoy_debug_pause
function ventoy_img_openelec {
elec_ver=$1
- vt_load_cpio $vtoy_path/ventoy.cpio "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
loopback vtloopex $vtoy_efi_part/ventoy/vtloopex.cpio
function ventoy_img_freedombox {
- vt_load_cpio $vtoy_path/ventoy.cpio "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
vt_get_lib_module_ver (vtimghd,1) /lib/modules/ vt_module_ver
}
function ventoy_img_paldo {
- vt_load_cpio $vtoy_path/ventoy.cpio "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
ventoy_debug_pause
}
function ventoy_img_ubos {
- vt_load_cpio $vtoy_path/ventoy.cpio "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
vt_get_lib_module_ver (vtimghd,3) /lib/modules/ vt_module_ver
}
function ventoy_img_recalbox {
- vt_load_cpio $vtoy_path/ventoy.cpio "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
ventoy_debug_pause
}
function ventoy_img_batocera {
- vt_load_cpio $vtoy_path/ventoy.cpio "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
+ vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
ventoy_debug_pause
elif [ "$grub_cpu" = "arm64" ]; then
set VTOY_EFI_ARCH=aa64
set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION AA64 www.ventoy.net"
+ elif [ "$grub_cpu" = "mips64el" ]; then
+ set VTOY_EFI_ARCH=mips
+ set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION MIPS www.ventoy.net"
else
set VTOY_EFI_ARCH=x64
set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION UEFI www.ventoy.net"
if [ "$libsuffix" = "aa64" ]; then
aarch64-linux-gnu-strip V2D$libsuffix
+ elif [ "$libsuffix" = "m64e" ]; then
+ mips-linux-gnu-strip V2D$libsuffix
else
strip V2D$libsuffix
fi
build_func "gcc" '64' 'x86_64'
build_func "gcc -m32" '32' 'i386'
build_func "aarch64-linux-gnu-gcc" 'aa64' 'aarch64'
+build_func "mips-linux-gnu-gcc -mips64r2 -mabi=64" 'm64e' 'mips64el'
--- /dev/null
+#
+# Makefile
+#
+# Author: Lasse Collin <lasse.collin@tukaani.org>
+#
+# This file has been put into the public domain.
+# You can do whatever you want with this file.
+#
+
+CC = /opt/mips64el-linux-musl-gcc730/bin/mips64el-linux-musl-gcc -mips64r2 -mabi=64 -Os -static -std=gnu89
+BCJ_CPPFLAGS = -DXZ_DEC_X86 -DXZ_DEC_POWERPC -DXZ_DEC_IA64 \
+ -DXZ_DEC_ARM -DXZ_DEC_ARMTHUMB -DXZ_DEC_SPARC
+CPPFLAGS = -DXZ_USE_CRC64 -DXZ_DEC_ANY_CHECK
+CFLAGS = -ggdb3 -O2 -pedantic -Wall -Wextra
+RM = rm -f
+VPATH = ../linux/include/linux ../linux/lib/xz
+COMMON_SRCS = xz_crc32.c xz_crc64.c xz_dec_stream.c xz_dec_lzma2.c xz_dec_bcj.c
+COMMON_OBJS = $(COMMON_SRCS:.c=.o)
+XZMINIDEC_OBJS = xzminidec.o
+BYTETEST_OBJS = bytetest.o
+BUFTEST_OBJS = buftest.o
+BOOTTEST_OBJS = boottest.o
+XZ_HEADERS = xz.h xz_private.h xz_stream.h xz_lzma2.h xz_config.h
+PROGRAMS = xzminidec bytetest buftest boottest
+
+ALL_CPPFLAGS = -I../linux/include/linux -I. $(BCJ_CPPFLAGS) $(CPPFLAGS)
+
+all: $(PROGRAMS)
+
+%.o: %.c $(XZ_HEADERS)
+ $(CC) $(ALL_CPPFLAGS) $(CFLAGS) -c -o $@ $<
+
+xzminidec: $(COMMON_OBJS) $(XZMINIDEC_OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(COMMON_OBJS) $(XZMINIDEC_OBJS)
+
+bytetest: $(COMMON_OBJS) $(BYTETEST_OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(COMMON_OBJS) $(BYTETEST_OBJS)
+
+buftest: $(COMMON_OBJS) $(BUFTEST_OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(COMMON_OBJS) $(BUFTEST_OBJS)
+
+boottest: $(BOOTTEST_OBJS) $(COMMON_SRCS)
+ $(CC) $(ALL_CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(BOOTTEST_OBJS)
+
+.PHONY: clean
+clean:
+ -$(RM) $(COMMON_OBJS) $(XZMINIDEC_OBJS) $(BUFTEST_OBJS) \
+ $(BOOTTEST_OBJS) $(PROGRAMS)
aarch64-buildroot-linux-uclibc-gcc -Os -static -D_FILE_OFFSET_BITS=64 *.c BabyISO/*.c -IBabyISO -Wall -DBUILD_VTOY_TOOL -o vtoytool_aa64
+mips64el-linux-musl-gcc -mips64r2 -mabi=64 -Os -static -D_FILE_OFFSET_BITS=64 *.c BabyISO/*.c -IBabyISO -Wall -DBUILD_VTOY_TOOL -o vtoytool_m64e
+
#gcc -D_FILE_OFFSET_BITS=64 -static -Wall -DBUILD_VTOY_TOOL *.c BabyISO/*.c -IBabyISO -o vtoytool_64
#gcc -D_FILE_OFFSET_BITS=64 -Wall -DBUILD_VTOY_TOOL -m32 *.c BabyISO/*.c -IBabyISO -o vtoytool_32
-if [ -e vtoytool_64 ] && [ -e vtoytool_32 ] && [ -e vtoytool_aa64 ]; then
+if [ -e vtoytool_64 ] && [ -e vtoytool_32 ] && [ -e vtoytool_aa64 ] && [ -e vtoytool_m64e ]; then
echo -e '\n############### SUCCESS ###############\n'
aarch64-buildroot-linux-uclibc-strip --strip-all vtoytool_aa64
+ mips64el-linux-musl-strip --strip-all vtoytool_m64e
+ mv vtoytool_m64e vtoytool/00/
mv vtoytool_aa64 vtoytool/00/
mv vtoytool_64 vtoytool/00/
mv vtoytool_32 vtoytool/00/
#endif
#ifndef USE_DIET_C
+#ifndef __mips__
typedef unsigned long long uint64_t;
+#endif
typedef unsigned int uint32_t;
#endif
#define IS_DIGIT(x) ((x) >= '0' && (x) <= '9')
#ifndef USE_DIET_C
+#ifndef __mips__
typedef unsigned long long uint64_t;
+#endif
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
rm -f vtoyfat_64
rm -f vtoyfat_32
rm -f vtoyfat_aa64
+rm -f vtoyfat_m64e
+
gcc -O2 -D_FILE_OFFSET_BITS=64 vtoyfat_linux.c -Ifat_io_lib/include fat_io_lib/lib/libfat_io_64.a -o vtoyfat_64
gcc -m32 -O2 -D_FILE_OFFSET_BITS=64 vtoyfat_linux.c -Ifat_io_lib/include fat_io_lib/lib/libfat_io_32.a -o vtoyfat_32
aarch64-buildroot-linux-uclibc-gcc -static -O2 -D_FILE_OFFSET_BITS=64 vtoyfat_linux.c -Ifat_io_lib/include fat_io_lib/lib/libfat_io_aa64.a -o vtoyfat_aa64
+mips64el-linux-musl-gcc -mips64r2 -mabi=64 -static -O2 -D_FILE_OFFSET_BITS=64 vtoyfat_linux.c -Ifat_io_lib/include fat_io_lib/lib/libfat_io_m64e.a -o vtoyfat_m64e
+
-if [ -e vtoyfat_64 ] && [ -e vtoyfat_32 ] && [ -e vtoyfat_aa64 ]; then
+if [ -e vtoyfat_64 ] && [ -e vtoyfat_32 ] && [ -e vtoyfat_aa64 ] && [ -e vtoyfat_m64e ]; then
echo -e "\n===== success $name =======\n"
strip --strip-all vtoyfat_32
strip --strip-all vtoyfat_64
aarch64-buildroot-linux-uclibc-strip --strip-all vtoyfat_aa64
+ mips64el-linux-musl-strip --strip-all vtoyfat_m64e
[ -d ../INSTALL/tool/i386/ ] && mv vtoyfat_32 ../INSTALL/tool/i386/vtoyfat
[ -d ../INSTALL/tool/x86_64/ ] && mv vtoyfat_64 ../INSTALL/tool/x86_64/vtoyfat
[ -d ../INSTALL/tool/aarch64/ ] && mv vtoyfat_aa64 ../INSTALL/tool/aarch64/vtoyfat
+ [ -d ../INSTALL/tool/mips64el/ ] && mv vtoyfat_m64e ../INSTALL/tool/mips64el/vtoyfat
else
echo -e "\n===== failed =======\n"
exit 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
/opt/diet32/bin/diet -Os gcc -D_FILE_OFFSET_BITS=64 -m32 vtoygpt.c crc32.c -o vtoygpt_32
aarch64-buildroot-linux-uclibc-gcc -Os -static -D_FILE_OFFSET_BITS=64 vtoygpt.c crc32.c -o vtoygpt_aa64
+mips64el-linux-musl-gcc -mips64r2 -mabi=64 -static -Os -D_FILE_OFFSET_BITS=64 vtoygpt.c crc32.c -o vtoygpt_m64e
+
#gcc -D_FILE_OFFSET_BITS=64 -static -Wall vtoygpt.c -o vtoytool_64
#gcc -D_FILE_OFFSET_BITS=64 -Wall -m32 vtoygpt.c -o vtoytool_32
-if [ -e vtoygpt_64 ] && [ -e vtoygpt_32 ] && [ -e vtoygpt_aa64 ]; then
+if [ -e vtoygpt_64 ] && [ -e vtoygpt_32 ] && [ -e vtoygpt_aa64 ] && [ -e vtoygpt_m64e ]; then
echo -e '\n############### SUCCESS ###############\n'
mv vtoygpt_64 ../INSTALL/tool/x86_64/vtoygpt
mv vtoygpt_32 ../INSTALL/tool/i386/vtoygpt
aarch64-buildroot-linux-uclibc-strip --strip-all vtoygpt_aa64
mv vtoygpt_aa64 ../INSTALL/tool/aarch64/vtoygpt
+
+ mips64el-linux-musl-strip --strip-all vtoygpt_m64e
+ mv vtoygpt_m64e ../INSTALL/tool/mips64el/vtoygpt
+
else
echo -e '\n############### FAILED ################\n'
exit 1