summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith M Wesolowski <wesolows@foobazco.org>2013-02-08 22:37:19 +0000
committerRobert Mustacchi <rm@joyent.com>2014-03-28 11:04:07 -0700
commita5602e1bdcf9570fa24684b54cf57a3f22e05ae1 (patch)
treec6ecd94ff972601c5d1af7e355fbf28fabb70502
parentc58b352673e88983cd2b8a388a8c7625f35e2f18 (diff)
downloadillumos-joyent-a5602e1bdcf9570fa24684b54cf57a3f22e05ae1.tar.gz
4656 want grub composite console
4657 want grub support for cross-menu OS console variable 4658 uninitialised variable trashes command line on coal Reviewed by: Dan McDonald <danmcd@omniti.com> Approved by: Garrett D'Amore <garrett@damore.org>
-rw-r--r--usr/src/grub/grub-0.97/stage2/Makefile.solaris54
-rw-r--r--usr/src/grub/grub-0.97/stage2/asm.S3
-rw-r--r--usr/src/grub/grub-0.97/stage2/builtins.c493
-rw-r--r--usr/src/grub/grub-0.97/stage2/char_io.c17
-rw-r--r--usr/src/grub/grub-0.97/stage2/common.c3
-rw-r--r--usr/src/grub/grub-0.97/stage2/cpu.h9
-rw-r--r--usr/src/grub/grub-0.97/stage2/expand.c465
-rw-r--r--usr/src/grub/grub-0.97/stage2/expand.h31
-rw-r--r--usr/src/grub/grub-0.97/stage2/serial.c71
-rw-r--r--usr/src/grub/grub-0.97/stage2/shared.h4
-rw-r--r--usr/src/grub/grub-0.97/stage2/stage2.c45
-rw-r--r--usr/src/grub/grub-0.97/stage2/term.h8
-rw-r--r--usr/src/pkg/manifests/source-system-grub.mf2
13 files changed, 754 insertions, 451 deletions
diff --git a/usr/src/grub/grub-0.97/stage2/Makefile.solaris b/usr/src/grub/grub-0.97/stage2/Makefile.solaris
index 94b168f43d..bb737888cd 100644
--- a/usr/src/grub/grub-0.97/stage2/Makefile.solaris
+++ b/usr/src/grub/grub-0.97/stage2/Makefile.solaris
@@ -65,6 +65,7 @@ LIBGRUB_OBJS = libgrub_a-boot.o \
libgrub_a-cmdline.o \
libgrub_a-common.o \
libgrub_a-disk_io.o \
+ libgrub_a-expand.o \
libgrub_a-fsys_ext2fs.o \
libgrub_a-fsys_fat.o \
libgrub_a-fsys_ffs.o \
@@ -155,6 +156,7 @@ DISKLESS_OBJS = diskless_exec-bios.o \
diskless_exec-common.o \
diskless_exec-console.o \
diskless_exec-disk_io.o \
+ diskless_exec-expand.o \
diskless_exec-fsys_ext2fs.o \
diskless_exec-fsys_fat.o \
diskless_exec-fsys_ffs.o \
@@ -198,8 +200,8 @@ $(DISKLESS_OBJS) := CFLAGS = $(BASE_CFLAGS) $(STAGE2_CFLAGS) \
E2FS_STAGE1_5_DATA = e2fs_stage1_5
E2FS_STAGE1_5_EXEC = e2fs_stage1_5.exec
-E2FS_STAGE1_5_ASMOBJS = e2fs_stage1_5_exec-asm.o \
- e2fs_stage1_5_exec-start.o
+E2FS_STAGE1_5_ASMOBJS = e2fs_stage1_5_exec-start.o \
+ e2fs_stage1_5_exec-asm.o
E2FS_STAGE1_5_OBJS = e2fs_stage1_5_exec-bios.o \
e2fs_stage1_5_exec-char_io.o \
@@ -222,8 +224,8 @@ $(E2FS_STAGE1_5_OBJS) := CFLAGS = $(BASE_CFLAGS) $(STAGE1_5_CFLAGS) \
FAT_STAGE1_5_DATA = fat_stage1_5
FAT_STAGE1_5_EXEC = fat_stage1_5.exec
-FAT_STAGE1_5_ASMOBJS = fat_stage1_5_exec-asm.o \
- fat_stage1_5_exec-start.o
+FAT_STAGE1_5_ASMOBJS = fat_stage1_5_exec-start.o \
+ fat_stage1_5_exec-asm.o
FAT_STAGE1_5_OBJS = fat_stage1_5_exec-bios.o \
fat_stage1_5_exec-char_io.o \
@@ -246,8 +248,8 @@ $(FAT_STAGE1_5_OBJS) := CFLAGS = $(BASE_CFLAGS) $(STAGE1_5_CFLAGS) \
FFS_STAGE1_5_DATA = ffs_stage1_5
FFS_STAGE1_5_EXEC = ffs_stage1_5.exec
-FFS_STAGE1_5_ASMOBJS = ffs_stage1_5_exec-asm.o \
- ffs_stage1_5_exec-start.o
+FFS_STAGE1_5_ASMOBJS = ffs_stage1_5_exec-start.o \
+ ffs_stage1_5_exec-asm.o
FFS_STAGE1_5_OBJS = ffs_stage1_5_exec-bios.o \
ffs_stage1_5_exec-char_io.o \
@@ -270,8 +272,8 @@ $(FFS_STAGE1_5_OBJS) := CFLAGS = $(BASE_CFLAGS) $(STAGE1_5_CFLAGS) \
ISO9660_STAGE1_5_DATA = iso9660_stage1_5
ISO9660_STAGE1_5_EXEC = iso9660_stage1_5.exec
-ISO9660_STAGE1_5_ASMOBJS = iso9660_stage1_5_exec-asm.o \
- iso9660_stage1_5_exec-start_eltorito.o
+ISO9660_STAGE1_5_ASMOBJS = iso9660_stage1_5_exec-start_eltorito.o \
+ iso9660_stage1_5_exec-asm.o
ISO9660_STAGE1_5_OBJS = iso9660_stage1_5_exec-bios.o \
iso9660_stage1_5_exec-char_io.o \
@@ -295,8 +297,8 @@ $(ISO9660_STAGE1_5_OBJS) := CFLAGS = $(BASE_CFLAGS) $(STAGE1_5_CFLAGS) \
JFS_STAGE1_5_DATA = jfs_stage1_5
JFS_STAGE1_5_EXEC = jfs_stage1_5.exec
-JFS_STAGE1_5_ASMOBJS = jfs_stage1_5_exec-asm.o \
- jfs_stage1_5_exec-start.o
+JFS_STAGE1_5_ASMOBJS = jfs_stage1_5_exec-start.o \
+ jfs_stage1_5_exec-asm.o
JFS_STAGE1_5_OBJS = jfs_stage1_5_exec-bios.o \
jfs_stage1_5_exec-char_io.o \
@@ -319,8 +321,8 @@ $(JFS_STAGE1_5_OBJS) := CFLAGS = $(BASE_CFLAGS) $(STAGE1_5_CFLAGS) \
MINIX_STAGE1_5_DATA = minix_stage1_5
MINIX_STAGE1_5_EXEC = minix_stage1_5.exec
-MINIX_STAGE1_5_ASMOBJS = minix_stage1_5_exec-asm.o \
- minix_stage1_5_exec-start.o
+MINIX_STAGE1_5_ASMOBJS = minix_stage1_5_exec-start.o \
+ minix_stage1_5_exec-asm.o
MINIX_STAGE1_5_OBJS = minix_stage1_5_exec-bios.o \
minix_stage1_5_exec-char_io.o \
@@ -367,6 +369,7 @@ PRE_STAGE2_OBJS = pre_stage2_exec-bios.o \
pre_stage2_exec-common.o \
pre_stage2_exec-console.o \
pre_stage2_exec-disk_io.o \
+ pre_stage2_exec-expand.o \
pre_stage2_exec-fsys_ext2fs.o \
pre_stage2_exec-fsys_fat.o \
pre_stage2_exec-fsys_ffs.o \
@@ -423,8 +426,8 @@ $(PXELOADER_ASMOBJS) := CCASFLAGS = $(BASE_CCASFLAGS) $(STAGE2_CFLAGS)
REISERFS_STAGE1_5_DATA = reiserfs_stage1_5
REISERFS_STAGE1_5_EXEC = reiserfs_stage1_5.exec
-REISERFS_STAGE1_5_ASMOBJS = reiserfs_stage1_5_exec-asm.o \
- reiserfs_stage1_5_exec-start.o
+REISERFS_STAGE1_5_ASMOBJS = reiserfs_stage1_5_exec-start.o \
+ reiserfs_stage1_5_exec-asm.o
REISERFS_STAGE1_5_OBJS = reiserfs_stage1_5_exec-bios.o \
reiserfs_stage1_5_exec-char_io.o \
@@ -478,8 +481,8 @@ $(START_ELTORITO_ASMOBJS) := CCASFLAGS = $(BASE_CCASFLAGS) $(STAGE2_CFLAGS)
UFS2_STAGE1_5_DATA = ufs2_stage1_5
UFS2_STAGE1_5_EXEC = ufs2_stage1_5.exec
-UFS2_STAGE1_5_ASMOBJS = ufs2_stage1_5_exec-asm.o \
- ufs2_stage1_5_exec-start.o
+UFS2_STAGE1_5_ASMOBJS = ufs2_stage1_5_exec-start.o \
+ ufs2_stage1_5_exec-asm.o
UFS2_STAGE1_5_OBJS = ufs2_stage1_5_exec-bios.o \
ufs2_stage1_5_exec-char_io.o \
@@ -502,8 +505,8 @@ $(UFS2_STAGE1_5_OBJS) := CFLAGS = $(BASE_CFLAGS) $(STAGE1_5_CFLAGS) \
UFS_STAGE1_5_DATA = ufs_stage1_5
UFS_STAGE1_5_EXEC = ufs_stage1_5.exec
-UFS_STAGE1_5_ASMOBJS = ufs_stage1_5_exec-asm.o \
- ufs_stage1_5_exec-start.o
+UFS_STAGE1_5_ASMOBJS = ufs_stage1_5_exec-start.o \
+ ufs_stage1_5_exec-asm.o
UFS_STAGE1_5_OBJS = ufs_stage1_5_exec-bios.o \
ufs_stage1_5_exec-char_io.o \
@@ -526,8 +529,8 @@ $(UFS_STAGE1_5_OBJS) := CFLAGS = $(BASE_CFLAGS) $(STAGE1_5_CFLAGS) \
ZFS_STAGE1_5_DATA = zfs_stage1_5
ZFS_STAGE1_5_EXEC = zfs_stage1_5.exec
-ZFS_STAGE1_5_ASMOBJS = zfs_stage1_5_exec-asm.o \
- zfs_stage1_5_exec-start.o
+ZFS_STAGE1_5_ASMOBJS = zfs_stage1_5_exec-start.o \
+ zfs_stage1_5_exec-asm.o
ZFS_STAGE1_5_OBJS = zfs_stage1_5_exec-bios.o \
zfs_stage1_5_exec-char_io.o \
@@ -554,8 +557,8 @@ $(ZFS_STAGE1_5_OBJS) := CFLAGS = $(BASE_CFLAGS) $(STAGE1_5_CFLAGS) \
VSTAFS_STAGE1_5_DATA = vstafs_stage1_5
VSTAFS_STAGE1_5_EXEC = vstafs_stage1_5.exec
-VSTAFS_STAGE1_5_ASMOBJS = vstafs_stage1_5_exec-asm.o \
- vstafs_stage1_5_exec-start.o
+VSTAFS_STAGE1_5_ASMOBJS = vstafs_stage1_5_exec-start.o \
+ vstafs_stage1_5_exec-asm.o
VSTAFS_STAGE1_5_OBJS = vstafs_stage1_5_exec-bios.o \
vstafs_stage1_5_exec-char_io.o \
@@ -578,8 +581,8 @@ $(VSTAFS_STAGE1_5_OBJS) := CFLAGS = $(BASE_CFLAGS) $(STAGE1_5_CFLAGS) \
XFS_STAGE1_5_DATA = xfs_stage1_5
XFS_STAGE1_5_EXEC = xfs_stage1_5.exec
-XFS_STAGE1_5_ASMOBJS = xfs_stage1_5_exec-asm.o \
- xfs_stage1_5_exec-start.o
+XFS_STAGE1_5_ASMOBJS = xfs_stage1_5_exec-start.o \
+ xfs_stage1_5_exec-asm.o
XFS_STAGE1_5_OBJS = xfs_stage1_5_exec-bios.o \
xfs_stage1_5_exec-char_io.o \
@@ -607,7 +610,8 @@ SRC_DIR = $(ROOT_SRC)/stage2
SRC_ZFSINC_DIR = $(SRC_DIR)/zfs-include
SRC_FILES = Makefile.am Makefile.in apic.h apm.S asm.S bios.c boot.c \
builtins.c char_io.c cmdline.c common.c console.c defs.h \
- dir.h disk_inode.h disk_inode_ffs.h disk_io.c fat.h \
+ dir.h disk_inode.h disk_inode_ffs.h disk_io.c expand.c \
+ expand.h fat.h \
filesys.h freebsd.h fs.h fsys_ext2fs.c fsys_fat.c \
fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
zfs_sha256.c zfs_lzjb.c zfs_lz4.c zfs_fletcher.c fsys_zfs.c \
diff --git a/usr/src/grub/grub-0.97/stage2/asm.S b/usr/src/grub/grub-0.97/stage2/asm.S
index 3e9986c0df..5d6faf7010 100644
--- a/usr/src/grub/grub-0.97/stage2/asm.S
+++ b/usr/src/grub/grub-0.97/stage2/asm.S
@@ -2664,8 +2664,8 @@ ENTRY(get_target_operating_mode)
movw $0xec00, %ax
movw $0x03, %bx
int $0x15
-/* XXX still need to pass back return */
+ setc %al
movw %ax, %cx
DATA32 call EXT_C(real_to_prot)
@@ -2673,6 +2673,7 @@ ENTRY(get_target_operating_mode)
xorl %eax, %eax
movw %cx, %ax
+ movl %eax, 0x1c(%esp)
popa
ret
diff --git a/usr/src/grub/grub-0.97/stage2/builtins.c b/usr/src/grub/grub-0.97/stage2/builtins.c
index af4a6f28bb..6213dc8d1c 100644
--- a/usr/src/grub/grub-0.97/stage2/builtins.c
+++ b/usr/src/grub/grub-0.97/stage2/builtins.c
@@ -49,6 +49,7 @@
#endif
#include <cpu.h>
+#include <expand.h>
/* The type of kernel loaded. */
kernel_t kernel_type;
@@ -86,7 +87,7 @@ static int configfile_func (char *arg, int flags);
static void solaris_config_file (void);
#endif
-static unsigned int min_mem64 = 0;
+unsigned int min_mem64 = 0;
#if defined(__sun) && !defined(GRUB_UTIL)
extern void __enable_execute_stack (void *);
@@ -2791,117 +2792,6 @@ static struct builtin builtin_ioprobe =
};
-/*
- * To boot from a ZFS root filesystem, the kernel$ or module$ commands
- * must include "-B $ZFS-BOOTFS" to expand to the zfs-bootfs, bootpath,
- * and diskdevid boot property values for passing to the kernel:
- *
- * e.g.
- * kernel$ /platform/i86pc/kernel/$ISADIR/unix -B $ZFS-BOOTFS,console=ttya
- *
- * $ZFS-BOOTFS is expanded to
- *
- * zfs-bootfs=<rootpool-name/zfs-rootfilesystem-object-num>,
- * bootpath=<device phys path>,
- * diskdevid=<device id>
- *
- * if both bootpath and diskdevid can be found.
- * e.g
- * zfs-bootfs=rpool/85,
- * bootpath="/pci@0,0/pci1022,7450@a/pci17c2,10@4/sd@0,0:a",
- * diskdevid="id1,sd@SSEAGATE_ST336607LC______3JA0LNHE0000741326W6/a"
- */
-static int
-expand_dollar_bootfs(char *in, char *out)
-{
- char *token, *tmpout = out;
- int outlen, blen;
- int postcomma = 0;
-
- /* no op if this is not zfs */
- if (is_zfs_mount == 0)
- return (0);
-
- if (current_bootpath[0] == '\0' && current_devid[0] == '\0') {
- errnum = ERR_NO_BOOTPATH;
- return (1);
- }
-
- outlen = strlen(in);
- blen = current_bootfs_obj == 0 ? strlen(current_rootpool) :
- strlen(current_rootpool) + 11;
-
- out[0] = '\0';
- while (token = strstr(in, "$ZFS-BOOTFS")) {
-
- if ((outlen += blen) >= MAX_CMDLINE) {
- errnum = ERR_WONT_FIT;
- return (1);
- }
-
- token[0] = '\0';
- grub_sprintf(tmpout, "%s", in);
- token[0] = '$';
- in = token + 11; /* skip over $ZFS-BOOTFS */
- tmpout = out + strlen(out);
-
- /* Note: %u only fits 32 bit integer; */
- if (current_bootfs_obj > 0)
- grub_sprintf(tmpout, "zfs-bootfs=%s/%u",
- current_rootpool, current_bootfs_obj);
- else
- grub_sprintf(tmpout, "zfs-bootfs=%s",
- current_rootpool);
- tmpout = out + strlen(out);
- }
-
- /*
- * Check to see if 'zfs-bootfs' was explicitly specified on the command
- * line so that we can insert the 'bootpath' property.
- */
- if ((tmpout == out) && (token = strstr(in, "zfs-bootfs")) != NULL) {
- token[0] = '\0';
- grub_strcpy(tmpout, in);
- token[0] = 'z';
- in = token;
-
- tmpout = out + strlen(out);
- postcomma = 1;
- }
-
- /*
- * Set the 'bootpath' property if a ZFS dataset was specified, either
- * through '$ZFS-BOOTFS' or an explicit 'zfs-bootfs' setting.
- */
- if (tmpout != out) {
- if (current_bootpath[0] != '\0') {
- if ((outlen += 12 + strlen(current_bootpath))
- >= MAX_CMDLINE) {
- errnum = ERR_WONT_FIT;
- return (1);
- }
- grub_sprintf(tmpout,
- postcomma ? "bootpath=\"%s\"," : ",bootpath=\"%s\"",
- current_bootpath);
- tmpout = out + strlen(out);
- }
-
- if (current_devid[0] != '\0') {
- if ((outlen += 13 + strlen(current_devid))
- >= MAX_CMDLINE) {
- errnum = ERR_WONT_FIT;
- return (1);
- }
- grub_sprintf(tmpout,
- postcomma ? "diskdevid=\"%s\"," : ",diskdevid=\"%s\"",
- current_devid);
- }
- }
-
- strncat(out, in, MAX_CMDLINE);
- return (0);
-}
-
/* kernel */
static int
kernel_func (char *arg, int flags)
@@ -3007,288 +2897,41 @@ static struct builtin builtin_min_mem64 =
"even on 64-bit capable hardware."
};
-int
-check_min_mem64()
-{
- if (min_mem64 == 0)
- return (1);
-
- if ((mbi.mem_upper / 10240) * 11 >= min_mem64)
- return (1);
-
- return (0);
-}
-
-static int detect_target_operating_mode();
-
-int
-amd64_config_cpu(void)
-{
- struct amd64_cpuid_regs __vcr, *vcr = &__vcr;
- uint32_t maxeax;
- uint32_t max_maxeax = 0x100;
- char vendor[13];
- int isamd64 = 0;
- uint32_t stdfeatures = 0, xtdfeatures = 0;
- uint64_t efer;
-
- /*
- * This check may seem silly, but if the C preprocesor symbol __amd64
- * is #defined during compilation, something that may outwardly seem
- * like a good idea, uts/common/sys/isa_defs.h will #define _LP64,
- * which will cause uts/common/sys/int_types.h to typedef uint64_t as
- * an unsigned long - which is only 4 bytes in size when using a 32-bit
- * compiler.
- *
- * If that happens, all the page table translation routines will fail
- * horribly, so check the size of uint64_t just to insure some degree
- * of sanity in future operations.
- */
- /*LINTED [sizeof result is invarient]*/
- if (sizeof (uint64_t) != 8)
- prom_panic("grub compiled improperly, unable to boot "
- "64-bit AMD64 executables");
-
- /*
- * If the CPU doesn't support the CPUID instruction, it's definitely
- * not an AMD64.
- */
- if (amd64_cpuid_supported() == 0)
- return (0);
-
- amd64_cpuid_insn(0, vcr);
-
- maxeax = vcr->r_eax;
- {
- /*LINTED [vendor string from cpuid data]*/
- uint32_t *iptr = (uint32_t *)vendor;
-
- *iptr++ = vcr->r_ebx;
- *iptr++ = vcr->r_edx;
- *iptr++ = vcr->r_ecx;
-
- vendor[12] = '\0';
- }
-
- if (maxeax > max_maxeax) {
- grub_printf("cpu: warning, maxeax was 0x%x -> 0x%x\n",
- maxeax, max_maxeax);
- maxeax = max_maxeax;
- }
-
- if (maxeax < 1)
- return (0); /* no additional functions, not an AMD64 */
- else {
- uint_t family, model, step;
-
- amd64_cpuid_insn(1, vcr);
-
- /*
- * All AMD64/IA32e processors technically SHOULD report
- * themselves as being in family 0xf, but for some reason
- * Simics doesn't, and this may change in the future, so
- * don't error out if it's not true.
- */
- if ((family = BITX(vcr->r_eax, 11, 8)) == 0xf)
- family += BITX(vcr->r_eax, 27, 20);
-
- if ((model = BITX(vcr->r_eax, 7, 4)) == 0xf)
- model += BITX(vcr->r_eax, 19, 16) << 4;
- step = BITX(vcr->r_eax, 3, 0);
-
- grub_printf("cpu: '%s' family %d model %d step %d\n",
- vendor, family, model, step);
- stdfeatures = vcr->r_edx;
- }
-
- amd64_cpuid_insn(0x80000000, vcr);
-
- if (vcr->r_eax & 0x80000000) {
- uint32_t xmaxeax = vcr->r_eax;
- const uint32_t max_xmaxeax = 0x80000100;
-
- if (xmaxeax > max_xmaxeax) {
- grub_printf("amd64: warning, xmaxeax was "
- "0x%x -> 0x%x\n", xmaxeax, max_xmaxeax);
- xmaxeax = max_xmaxeax;
- }
-
- if (xmaxeax >= 0x80000001) {
- amd64_cpuid_insn(0x80000001, vcr);
- xtdfeatures = vcr->r_edx;
- }
- }
-
- if (BITX(xtdfeatures, 29, 29)) /* long mode */
- isamd64++;
- else
- grub_printf("amd64: CPU does NOT support long mode\n");
-
- if (!BITX(stdfeatures, 0, 0)) {
- grub_printf("amd64: CPU does NOT support FPU\n");
- isamd64--;
- }
-
- if (!BITX(stdfeatures, 4, 4)) {
- grub_printf("amd64: CPU does NOT support TSC\n");
- isamd64--;
- }
-
- if (!BITX(stdfeatures, 5, 5)) {
- grub_printf("amd64: CPU does NOT support MSRs\n");
- isamd64--;
- }
-
- if (!BITX(stdfeatures, 6, 6)) {
- grub_printf("amd64: CPU does NOT support PAE\n");
- isamd64--;
- }
-
- if (!BITX(stdfeatures, 8, 8)) {
- grub_printf("amd64: CPU does NOT support CX8\n");
- isamd64--;
- }
-
- if (!BITX(stdfeatures, 13, 13)) {
- grub_printf("amd64: CPU does NOT support PGE\n");
- isamd64--;
- }
-
- if (!BITX(stdfeatures, 19, 19)) {
- grub_printf("amd64: CPU does NOT support CLFSH\n");
- isamd64--;
- }
-
- if (!BITX(stdfeatures, 23, 23)) {
- grub_printf("amd64: CPU does NOT support MMX\n");
- isamd64--;
- }
-
- if (!BITX(stdfeatures, 24, 24)) {
- grub_printf("amd64: CPU does NOT support FXSR\n");
- isamd64--;
- }
-
- if (!BITX(stdfeatures, 25, 25)) {
- grub_printf("amd64: CPU does NOT support SSE\n");
- isamd64--;
- }
-
- if (!BITX(stdfeatures, 26, 26)) {
- grub_printf("amd64: CPU does NOT support SSE2\n");
- isamd64--;
- }
-
- if (isamd64 < 1) {
- grub_printf("amd64: CPU does not support amd64 executables.\n");
- return (0);
- }
-
- amd64_rdmsr(MSR_AMD_EFER, &efer);
- if (efer & AMD_EFER_SCE)
- grub_printf("amd64: EFER_SCE (syscall/sysret) already "
- "enabled\n");
- if (efer & AMD_EFER_NXE)
- grub_printf("amd64: EFER_NXE (no-exec prot) already enabled\n");
- if (efer & AMD_EFER_LME)
- grub_printf("amd64: EFER_LME (long mode) already enabled\n");
-
- return (detect_target_operating_mode());
-}
-
-static int
-detect_target_operating_mode()
-{
- int ret, ah;
-
- ah = get_target_operating_mode();
-
- ah = ah >> 8;
-
- /* XXX still need to pass back the return from the call */
- ret = 0;
-
- if (ah == 0x86 && (ret & CB) != 0) {
- grub_printf("[BIOS 'Detect Target Operating Mode' "
- "callback unsupported on this platform]\n");
- return (1); /* unsupported, ignore */
- }
-
- if (ah == 0x0 && (ret & CB) == 0) {
- grub_printf("[BIOS accepted mixed-mode target setting!]\n");
- return (1); /* told the bios what we're up to */
- }
-
- if (ah == 0 && ret & CB) {
- grub_printf("fatal: BIOS reports this machine CANNOT run in "
- "mixed 32/64-bit mode!\n");
- return (0);
- }
-
- grub_printf("warning: BIOS Detect Target Operating Mode callback "
- "confused.\n %%ax >> 8 = 0x%x, carry = %d\n", ah,
- ret & CB ? 1 : 0);
-
- return (1);
-}
-
-
-int
-isamd64()
-{
- static int ret = -1;
-
- if (ret == -1)
- ret = amd64_config_cpu();
-
- return (ret);
-}
-
-static void
-expand_arch (char *arg, char *newarg)
-{
- char *index;
-
- newarg[0] = '\0';
-
- while ((index = strstr(arg, "$ISADIR")) != NULL) {
-
- index[0] = '\0';
- strncat(newarg, arg, MAX_CMDLINE);
- index[0] = '$';
-
- if (isamd64() && check_min_mem64())
- strncat(newarg, "amd64", MAX_CMDLINE);
-
- arg = index + 7;
- }
-
- strncat(newarg, arg, MAX_CMDLINE);
- return;
-}
-
-/* kernel$ */
static int
kernel_dollar_func (char *arg, int flags)
{
- char newarg[MAX_CMDLINE]; /* everything boils down to MAX_CMDLINE */
+ int err;
+ char newarg[MAX_CMDLINE];
+ /*
+ * We're going to expand the arguments twice. The first expansion, which
+ * occurs without the benefit of knowing the ZFS object ID of the filesystem
+ * we're booting from (if we're booting from ZFS, of course), must be
+ * sufficient to find and read the kernel. The second expansion will
+ * then overwrite the command line actually set in the multiboot header with
+ * the newly-expanded one. Since $ZFS-BOOTFS expands differently after
+ * zfs_open() has been called (kernel_func() -> load_image() -> grub_open() ->
+ * zfs_open()), we need to do the second expansion so that the kernel is
+ * given the right object ID argument. Note that the pointer to the
+ * command line set in the multiboot header is always MB_CMDLINE_BUF.
+ */
grub_printf("loading '%s' ...\n", arg);
- expand_arch(arg, newarg);
+ if ((err = expand_string(arg, newarg, MAX_CMDLINE)) != 0) {
+ errnum = err;
+ return (1);
+ }
- if (kernel_func(newarg, flags))
- return (1);
+ if ((err = kernel_func(newarg, flags)) != 0)
+ return (err);
mb_cmdline = (char *)MB_CMDLINE_BUF;
- if (expand_dollar_bootfs(newarg, mb_cmdline)) {
- grub_printf("cannot expand $ZFS-BOOTFS for dataset %s\n",
- current_bootfs);
- return (1);
+ if ((err = expand_string(arg, mb_cmdline, MAX_CMDLINE)) != 0) {
+ errnum = err;
+ return (1);
}
- grub_printf("'%s' is loaded\n", mb_cmdline);
+ grub_printf("loading '%s' ...\n", mb_cmdline);
mb_cmdline += grub_strlen(mb_cmdline) + 1;
-
return (0);
}
@@ -3298,7 +2941,8 @@ static struct builtin builtin_kernel_dollar =
kernel_dollar_func,
BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
"kernel$ [--no-mem-option] [--type=TYPE] FILE [ARG ...]",
- " Just like kernel, but with $ISADIR expansion."
+ " Just like kernel, but with variable expansion, including the legacy"
+ " (and nonconforming) variables $ISADIR and $ZFS-BOOTFS."
};
@@ -3521,25 +3165,26 @@ static struct builtin builtin_module =
static int
module_dollar_func (char *arg, int flags)
{
- char newarg[MAX_CMDLINE]; /* everything boils down to MAX_CMDLINE */
- char *cmdline_sav;
+ char newarg[MAX_CMDLINE];
+ char *cmdline_sav = mb_cmdline;
+ int err;
grub_printf("loading '%s' ...\n", arg);
- expand_arch(arg, newarg);
+ if ((err = expand_string(arg, newarg, MAX_CMDLINE)) != 0) {
+ errnum = err;
+ return (1);
+ }
- cmdline_sav = (char *)mb_cmdline;
- if (module_func(newarg, flags))
- return (1);
+ if ((err = module_func(newarg, flags)) != 0)
+ return (err);
- if (expand_dollar_bootfs(newarg, cmdline_sav)) {
- grub_printf("cannot expand $ZFS-BOOTFS for dataset %s\n",
- current_bootfs);
- return (1);
+ if ((err = expand_string(arg, cmdline_sav, MAX_CMDLINE)) != 0) {
+ errnum = err;
+ return (1);
}
- grub_printf("'%s' is loaded\n", (char *)cmdline_sav);
+ grub_printf("loading '%s' ...\n", cmdline_sav);
mb_cmdline += grub_strlen(cmdline_sav) + 1;
-
return (0);
}
@@ -5289,11 +4934,14 @@ static struct builtin builtin_terminal =
"terminal",
terminal_func,
BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
- "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules] [graphics]",
+ "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules] [graphics] [composite]",
"Select a terminal. When multiple terminals are specified, wait until"
" you push any key to continue. If both console and serial are specified,"
" the terminal to which you input a key first will be selected. If no"
- " argument is specified, print current setting. The option --dumb"
+ " argument is specified, print current setting. To accomodate systems"
+ " where console redirection may or may not be present, the composite"
+ " console will direct output to the serial and BIOS consoles, and accept"
+ " input from either one, without requiring selection. The option --dumb"
" specifies that your terminal is dumb, otherwise, vt100-compatibility"
" is assumed. If you specify --no-echo, input characters won't be echoed."
" If you specify --no-edit, the BASH-like editing feature will be disabled."
@@ -5815,6 +5463,54 @@ static struct builtin builtin_vbeprobe =
"Probe VBE information. If the mode number MODE is specified, show only"
" the information about only the mode."
};
+
+static int
+variable_func(char *arg, int flags)
+{
+ char name[EV_NAMELEN];
+ char *val;
+ int err;
+
+ if (*arg == '\0') {
+ dump_variables();
+ return (0);
+ }
+
+ if ((val = grub_strchr(arg, ' ')) != NULL) {
+ if (val - arg >= sizeof (name)) {
+ errnum = ERR_WONT_FIT;
+ return (1);
+ }
+ (void) grub_memcpy(name, arg, (val - arg));
+ name[val - arg] = '\0';
+ val = skip_to(0, arg);
+ } else {
+ if (grub_strlen(arg) >= sizeof (name)) {
+ errnum = ERR_WONT_FIT;
+ return (1);
+ }
+ (void) grub_strcpy(name, arg);
+ }
+
+ if ((err = set_variable(name, val)) != 0) {
+ errnum = err;
+ return (1);
+ }
+
+ return (0);
+}
+
+static struct builtin builtin_variable =
+{
+ "variable",
+ variable_func,
+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_SCRIPT | BUILTIN_HELP_LIST,
+ "variable NAME [VALUE]",
+ "Set the variable NAME to VALUE, or to the empty string if no value is"
+ " given. NAME must contain no spaces. There is no quoting mechanism"
+ " and nested variable references are not allowed. Variable values may"
+ " be substituted into the kernel$ and module$ commands using ${NAME}."
+};
/* The table of builtin commands. Sorted in dictionary order. */
@@ -5922,6 +5618,7 @@ struct builtin *builtin_table[] =
&builtin_title,
&builtin_unhide,
&builtin_uppermem,
+ &builtin_variable,
&builtin_vbeprobe,
&builtin_verbose,
0
diff --git a/usr/src/grub/grub-0.97/stage2/char_io.c b/usr/src/grub/grub-0.97/stage2/char_io.c
index d73bc71001..f29164712e 100644
--- a/usr/src/grub/grub-0.97/stage2/char_io.c
+++ b/usr/src/grub/grub-0.97/stage2/char_io.c
@@ -21,7 +21,6 @@
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include <shared.h>
#include <term.h>
@@ -71,6 +70,22 @@ struct term_entry term_table[] =
0,
0
},
+ {
+ "composite",
+ TERM_NEED_INIT,
+ 24,
+ composite_putchar,
+ composite_checkkey,
+ composite_getkey,
+ serial_getxy,
+ composite_gotoxy,
+ composite_cls,
+ composite_setcolorstate,
+ console_setcolor,
+ console_setcursor,
+ 0,
+ 0
+ },
#endif /* SUPPORT_SERIAL */
#ifdef SUPPORT_HERCULES
{
diff --git a/usr/src/grub/grub-0.97/stage2/common.c b/usr/src/grub/grub-0.97/stage2/common.c
index b4bb696641..3ca5340206 100644
--- a/usr/src/grub/grub-0.97/stage2/common.c
+++ b/usr/src/grub/grub-0.97/stage2/common.c
@@ -99,7 +99,8 @@ char *err_list[] =
[ERR_NEWER_VERSION] = "Newer on-disk pool version",
[ERR_NOTXPM] = "Image not in XPM graphics format",
[ERR_TOOMANYCOLORS] = "Image cannot use more than 14 colors",
- [ERR_CORRUPTXPM] = "File contains corrupt XPM image data"
+ [ERR_CORRUPTXPM] = "File contains corrupt XPM image data",
+ [ERR_NOVAR] = "Unknown variable reference",
};
diff --git a/usr/src/grub/grub-0.97/stage2/cpu.h b/usr/src/grub/grub-0.97/stage2/cpu.h
index 34180727d9..0b45295e9b 100644
--- a/usr/src/grub/grub-0.97/stage2/cpu.h
+++ b/usr/src/grub/grub-0.97/stage2/cpu.h
@@ -24,12 +24,12 @@
#ifndef _AMD64_CPU
#define _AMD64_CPU
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
+#include <shared.h>
+
typedef unsigned int uint_t;
typedef unsigned long ulong_t;
@@ -37,11 +37,6 @@ typedef unsigned long ulong_t;
#include <controlregs.h>
-#define CB 0x0001
-
-extern void amd64_flush_tlb(void);
-extern void amd64_flush_tlbentry(caddr_t);
-
extern ulong_t amd64_get_cr2(void);
extern ulong_t amd64_get_cr0(void);
extern ulong_t amd64_get_cr3(void);
diff --git a/usr/src/grub/grub-0.97/stage2/expand.c b/usr/src/grub/grub-0.97/stage2/expand.c
new file mode 100644
index 0000000000..43f8b1f0d7
--- /dev/null
+++ b/usr/src/grub/grub-0.97/stage2/expand.c
@@ -0,0 +1,465 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
+ * Copyright (c) 2013 Joyent, Inc. All rights reserved.
+ *
+ * This program 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <expand.h>
+#include <shared.h>
+
+#ifdef SUPPORT_NETBOOT
+#include <grub.h>
+#endif
+
+#include <cpu.h>
+
+#define EVF_DEFINED 0x01
+#define EVF_VALUESET 0x02
+
+typedef struct variable {
+ char v_name[EV_NAMELEN];
+ unsigned int v_flags;
+ char v_value[220]; /* 256 - EV_NAMELEN - sizeof (fields) */
+} variable_t;
+
+static variable_t expvars[32];
+static const unsigned int nexpvars = 32;
+
+int
+set_variable(const char *name, const char *value)
+{
+ unsigned int i;
+ unsigned int avail = nexpvars;
+
+ if (strlen(name) >= sizeof (expvars[0].v_name))
+ return (ERR_WONT_FIT);
+
+ if (value != NULL && strlen(value) >= sizeof (expvars[0].v_value))
+ return (ERR_WONT_FIT);
+
+ for (i = 0; i < nexpvars; i++) {
+ if (expvars[i].v_flags & EVF_DEFINED) {
+ if (grub_strcmp(expvars[i].v_name, name) == 0)
+ break;
+ } else if (i < avail) {
+ avail = i;
+ }
+ }
+
+ if (i == nexpvars) {
+ if (avail == nexpvars)
+ return (ERR_WONT_FIT);
+
+ i = avail;
+ (void) grub_strcpy(expvars[i].v_name, name);
+ expvars[i].v_flags = EVF_DEFINED;
+ }
+
+ if (value != NULL) {
+ (void) grub_strcpy(expvars[i].v_value, value);
+ expvars[i].v_flags |= EVF_VALUESET;
+ } else {
+ expvars[i].v_flags &= ~EVF_VALUESET;
+ }
+
+ return (0);
+}
+
+const char *
+get_variable(const char *name)
+{
+ unsigned int i;
+
+ for (i = 0; i < nexpvars; i++) {
+ if (!(expvars[i].v_flags & EVF_DEFINED))
+ continue;
+ if (grub_strcmp(expvars[i].v_name, name) == 0) {
+ if (expvars[i].v_flags & EVF_VALUESET)
+ return (expvars[i].v_value);
+ return ("");
+ }
+ }
+
+ return (NULL);
+}
+
+static int
+detect_target_operating_mode(void)
+{
+ int ret, ah;
+
+ /*
+ * This function returns 16 bits. The upper 8 are the value of %ah
+ * after calling int 15/ec00. The lower 8 bits are zero if the BIOS
+ * call left CF clear, nonzero otherwise.
+ */
+ ret = get_target_operating_mode();
+ ah = ret & 0xff;
+ ret >>= 8;
+
+ if (ah == 0x86 && ret != 0) {
+ grub_printf("[BIOS 'Detect Target Operating Mode' "
+ "callback unsupported on this platform]\n");
+ return (1); /* unsupported, ignore */
+ }
+
+ if (ah == 0 && ret == 0) {
+ grub_printf("[BIOS accepted mixed-mode target setting!]\n");
+ return (1); /* told the bios what we're up to */
+ }
+
+ if (ah == 0 && ret != 0) {
+ grub_printf("fatal: BIOS reports this machine CANNOT run in "
+ "mixed 32/64-bit mode!\n");
+ return (0);
+ }
+
+ grub_printf("warning: BIOS Detect Target Operating Mode callback "
+ "confused.\n %%ax >> 8 = 0x%x, carry = %d\n", ah, ret);
+
+ return (1);
+}
+
+static int
+amd64_config_cpu(void)
+{
+ struct amd64_cpuid_regs __vcr, *vcr = &__vcr;
+ uint32_t maxeax;
+ uint32_t max_maxeax = 0x100;
+ char vendor[13];
+ int isamd64 = 0;
+ uint32_t stdfeatures = 0, xtdfeatures = 0;
+ uint64_t efer;
+
+ /*
+ * This check may seem silly, but if the C preprocesor symbol __amd64
+ * is #defined during compilation, something that may outwardly seem
+ * like a good idea, uts/common/sys/isa_defs.h will #define _LP64,
+ * which will cause uts/common/sys/int_types.h to typedef uint64_t as
+ * an unsigned long - which is only 4 bytes in size when using a 32-bit
+ * compiler.
+ *
+ * If that happens, all the page table translation routines will fail
+ * horribly, so check the size of uint64_t just to insure some degree
+ * of sanity in future operations.
+ */
+ /*LINTED [sizeof result is invarient]*/
+ if (sizeof (uint64_t) != 8)
+ prom_panic("grub compiled improperly, unable to boot "
+ "64-bit AMD64 executables");
+
+ /*
+ * If the CPU doesn't support the CPUID instruction, it's definitely
+ * not an AMD64.
+ */
+ if (amd64_cpuid_supported() == 0)
+ return (0);
+
+ amd64_cpuid_insn(0, vcr);
+
+ maxeax = vcr->r_eax;
+ {
+ /*LINTED [vendor string from cpuid data]*/
+ uint32_t *iptr = (uint32_t *)vendor;
+
+ *iptr++ = vcr->r_ebx;
+ *iptr++ = vcr->r_edx;
+ *iptr++ = vcr->r_ecx;
+
+ vendor[12] = '\0';
+ }
+
+ if (maxeax > max_maxeax) {
+ grub_printf("cpu: warning, maxeax was 0x%x -> 0x%x\n",
+ maxeax, max_maxeax);
+ maxeax = max_maxeax;
+ }
+
+ if (maxeax < 1)
+ return (0); /* no additional functions, not an AMD64 */
+ else {
+ uint_t family, model, step;
+
+ amd64_cpuid_insn(1, vcr);
+
+ /*
+ * All AMD64/IA32e processors technically SHOULD report
+ * themselves as being in family 0xf, but for some reason
+ * Simics doesn't, and this may change in the future, so
+ * don't error out if it's not true.
+ */
+ if ((family = BITX(vcr->r_eax, 11, 8)) == 0xf)
+ family += BITX(vcr->r_eax, 27, 20);
+
+ if ((model = BITX(vcr->r_eax, 7, 4)) == 0xf)
+ model += BITX(vcr->r_eax, 19, 16) << 4;
+ step = BITX(vcr->r_eax, 3, 0);
+
+ grub_printf("cpu: '%s' family %d model %d step %d\n",
+ vendor, family, model, step);
+ stdfeatures = vcr->r_edx;
+ }
+
+ amd64_cpuid_insn(0x80000000, vcr);
+
+ if (vcr->r_eax & 0x80000000) {
+ uint32_t xmaxeax = vcr->r_eax;
+ const uint32_t max_xmaxeax = 0x80000100;
+
+ if (xmaxeax > max_xmaxeax) {
+ grub_printf("amd64: warning, xmaxeax was "
+ "0x%x -> 0x%x\n", xmaxeax, max_xmaxeax);
+ xmaxeax = max_xmaxeax;
+ }
+
+ if (xmaxeax >= 0x80000001) {
+ amd64_cpuid_insn(0x80000001, vcr);
+ xtdfeatures = vcr->r_edx;
+ }
+ }
+
+ if (BITX(xtdfeatures, 29, 29)) /* long mode */
+ isamd64++;
+ else
+ grub_printf("amd64: CPU does NOT support long mode\n");
+
+ if (!BITX(stdfeatures, 0, 0)) {
+ grub_printf("amd64: CPU does NOT support FPU\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 4, 4)) {
+ grub_printf("amd64: CPU does NOT support TSC\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 5, 5)) {
+ grub_printf("amd64: CPU does NOT support MSRs\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 6, 6)) {
+ grub_printf("amd64: CPU does NOT support PAE\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 8, 8)) {
+ grub_printf("amd64: CPU does NOT support CX8\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 13, 13)) {
+ grub_printf("amd64: CPU does NOT support PGE\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 19, 19)) {
+ grub_printf("amd64: CPU does NOT support CLFSH\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 23, 23)) {
+ grub_printf("amd64: CPU does NOT support MMX\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 24, 24)) {
+ grub_printf("amd64: CPU does NOT support FXSR\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 25, 25)) {
+ grub_printf("amd64: CPU does NOT support SSE\n");
+ isamd64--;
+ }
+
+ if (!BITX(stdfeatures, 26, 26)) {
+ grub_printf("amd64: CPU does NOT support SSE2\n");
+ isamd64--;
+ }
+
+ if (isamd64 < 1) {
+ grub_printf("amd64: CPU does not support amd64 executables.\n");
+ return (0);
+ }
+
+ amd64_rdmsr(MSR_AMD_EFER, &efer);
+ if (efer & AMD_EFER_SCE)
+ grub_printf("amd64: EFER_SCE (syscall/sysret) already "
+ "enabled\n");
+ if (efer & AMD_EFER_NXE)
+ grub_printf("amd64: EFER_NXE (no-exec prot) already enabled\n");
+ if (efer & AMD_EFER_LME)
+ grub_printf("amd64: EFER_LME (long mode) already enabled\n");
+
+ return (detect_target_operating_mode());
+}
+
+static int
+isamd64()
+{
+ static int ret = -1;
+
+ if (ret == -1)
+ ret = amd64_config_cpu();
+
+ return (ret);
+}
+
+static int
+check_min_mem64(void)
+{
+ if (min_mem64 == 0)
+ return (1);
+
+ if ((mbi.mem_upper / 10240) * 11 >= min_mem64)
+ return (1);
+
+ return (0);
+}
+
+/*
+ * Given the nul-terminated input string s, expand all variable references
+ * within that string into the buffer pointed to by d, which must be of length
+ * not less than len bytes.
+ *
+ * We also expand the special case tokens "$ISADIR" and "$ZFS-BOOTFS" here.
+ *
+ * If the string will not fit, returns ERR_WONT_FIT.
+ * If a nonexistent variable is referenced, returns ERR_NOVAR.
+ * Otherwise, returns 0. The resulting string is nul-terminated. On error,
+ * the contents of the destination buffer are undefined.
+ */
+int
+expand_string(const char *s, char *d, unsigned int len)
+{
+ unsigned int i;
+ int vlen;
+ const char *p;
+ char *q;
+ const char *start;
+ char name[EV_NAMELEN];
+ const char *val;
+
+ for (p = s, q = d; *p != '\0' && q < d + len; ) {
+ /* Special case: $ISADIR */
+ if (grub_strncmp(p, "$ISADIR", 7) == 0) {
+ if (isamd64() && check_min_mem64()) {
+ if (q + 5 >= d + len)
+ return (ERR_WONT_FIT);
+ (void) grub_memcpy(q, "amd64", 5);
+ q += 5; /* amd64 */
+ }
+ p += 7; /* $ISADIR */
+ continue;
+ }
+ /* Special case: $ZFS-BOOTFS */
+ if (grub_strncmp(p, "$ZFS-BOOTFS", 11) == 0 &&
+ is_zfs_mount != 0) {
+ if (current_bootpath[0] == '\0' &&
+ current_devid[0] == '\0') {
+ return (ERR_NO_BOOTPATH);
+ }
+
+ /* zfs-bootfs=%s/%u */
+ vlen = (current_bootfs_obj > 0) ? 10 : 0;
+ vlen += 11;
+ vlen += strlen(current_rootpool);
+
+ /* ,bootpath=\"%s\" */
+ if (current_bootpath[0] != '\0')
+ vlen += 12 + strlen(current_bootpath);
+
+ /* ,diskdevid=\"%s\" */
+ if (current_devid[0] != '\0')
+ vlen += 13 + strlen(current_devid);
+
+ if (q + vlen >= d + len)
+ return (ERR_WONT_FIT);
+
+ if (current_bootfs_obj > 0) {
+ q += grub_sprintf(q, "zfs-bootfs=%s/%u",
+ current_rootpool, current_bootfs_obj);
+ } else {
+ q += grub_sprintf(q, "zfs-bootfs=%s",
+ current_rootpool);
+ }
+ if (current_bootpath[0] != '\0') {
+ q += grub_sprintf(q, ",bootpath=\"%s\"",
+ current_bootpath);
+ }
+ if (current_devid[0] != '\0') {
+ q += grub_sprintf(q, ",diskdevid=\"%s\"",
+ current_devid);
+ }
+
+ p += 11; /* $ZFS-BOOTFS */
+ continue;
+ }
+ if (*p == '$' && *(p + 1) == '{') {
+ start = p + 2;
+ for (p = start; *p != '\0' && *p != '}' &&
+ p - start < sizeof (name) - 1; p++) {
+ name[p - start] = *p;
+ }
+ /*
+ * Unterminated reference. Copy verbatim.
+ */
+ if (p - start >= sizeof (name) - 1 || *p != '}') {
+ p = start;
+ *q++ = '$';
+ *q++ = '{';
+ continue;
+ }
+
+ name[p - start] = '\0';
+ val = get_variable(name);
+ if (val == NULL)
+ return (ERR_NOVAR);
+
+ if ((vlen = grub_strlen(val)) >= q + len - d)
+ return (ERR_WONT_FIT);
+
+ (void) grub_memcpy(q, val, vlen);
+ q += vlen;
+ p++;
+ } else {
+ *q++ = *p++;
+ }
+ }
+
+ if (q >= d + len)
+ return (ERR_WONT_FIT);
+
+ *q = '\0';
+
+ return (0);
+}
+
+void
+dump_variables(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < nexpvars; i++) {
+ if (!(expvars[i].v_flags & EVF_DEFINED))
+ continue;
+ (void) grub_printf("[%u] '%s' => '%s'\n", i, expvars[i].v_name,
+ (expvars[i].v_flags & EVF_VALUESET) ?
+ expvars[i].v_value : "");
+ }
+}
diff --git a/usr/src/grub/grub-0.97/stage2/expand.h b/usr/src/grub/grub-0.97/stage2/expand.h
new file mode 100644
index 0000000000..ed8344e8af
--- /dev/null
+++ b/usr/src/grub/grub-0.97/stage2/expand.h
@@ -0,0 +1,31 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (c) 2013 Joyent, Inc. All rights reserved.
+ *
+ * This program 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _GRUB_EXPAND_H
+#define _GRUB_EXPAND_H
+
+#define EV_NAMELEN 32
+
+extern void init_variables(void);
+extern int set_variable(const char *, const char *);
+extern const char *get_variable(const char *);
+extern int expand_string(const char *, char *, unsigned int);
+extern void dump_variables(void);
+
+#endif
diff --git a/usr/src/grub/grub-0.97/stage2/serial.c b/usr/src/grub/grub-0.97/stage2/serial.c
index 16c376fa7d..4e120e000d 100644
--- a/usr/src/grub/grub-0.97/stage2/serial.c
+++ b/usr/src/grub/grub-0.97/stage2/serial.c
@@ -25,6 +25,9 @@
#include <term.h>
#include <terminfo.h>
+#define COMP_BS_SERIAL 0x01
+#define COMP_BS_BIOS 0x02
+
/* An input buffer. */
static char input_buf[8];
static int npending = 0;
@@ -33,6 +36,7 @@ static int serial_x;
static int serial_y;
static int keep_track = 1;
+static int composite_bitset = COMP_BS_SERIAL | COMP_BS_BIOS;
/* Hardware-dependent definitions. */
@@ -177,10 +181,10 @@ serial_hw_init (unsigned short port, unsigned int speed,
/* Get rid of TERM_NEED_INIT from the serial terminal. */
for (i = 0; term_table[i].name; i++)
- if (grub_strcmp (term_table[i].name, "serial") == 0)
+ if (grub_strcmp (term_table[i].name, "serial") == 0 ||
+ grub_strcmp (term_table[i].name, "composite") == 0)
{
term_table[i].flags &= ~TERM_NEED_INIT;
- break;
}
/* FIXME: should check if the serial terminal was found. */
@@ -402,8 +406,12 @@ serial_getxy (void)
void
serial_gotoxy (int x, int y)
{
+ int saved_cbs = composite_bitset;
+
keep_track = 0;
+ composite_bitset &= ~COMP_BS_BIOS;
ti_cursor_address (x, y);
+ composite_bitset = saved_cbs;
keep_track = 1;
serial_x = x;
@@ -413,8 +421,12 @@ serial_gotoxy (int x, int y)
void
serial_cls (void)
{
+ int saved_cbs = composite_bitset;
+
keep_track = 0;
+ composite_bitset &= ~COMP_BS_BIOS;
ti_clear_screen ();
+ composite_bitset = saved_cbs;
keep_track = 1;
serial_x = serial_y = 0;
@@ -423,12 +435,67 @@ serial_cls (void)
void
serial_setcolorstate (color_state state)
{
+ int saved_cbs = composite_bitset;
+
keep_track = 0;
+ composite_bitset &= ~COMP_BS_BIOS;
if (state == COLOR_STATE_HIGHLIGHT)
ti_enter_standout_mode ();
else
ti_exit_standout_mode ();
+ composite_bitset = saved_cbs;
keep_track = 1;
}
+void
+composite_putchar (int c)
+{
+ if (composite_bitset & COMP_BS_SERIAL)
+ serial_putchar (c);
+ if (composite_bitset & COMP_BS_BIOS)
+ console_putchar (c);
+}
+
+int
+composite_getkey (void)
+{
+ for (;;) {
+ if (serial_checkkey () != -1)
+ return (serial_getkey ());
+ if (console_checkkey () != -1)
+ return (console_getkey ());
+ }
+}
+
+int
+composite_checkkey (void)
+{
+ int ch;
+
+ if ((ch = serial_checkkey ()) != -1)
+ return (ch);
+ return (console_checkkey ());
+}
+
+void
+composite_gotoxy (int x, int y)
+{
+ serial_gotoxy (x, y);
+ console_gotoxy (x, y);
+}
+
+void
+composite_cls (void)
+{
+ serial_cls();
+ console_cls();
+}
+
+void
+composite_setcolorstate (color_state state)
+{
+ serial_setcolorstate (state);
+ console_setcolorstate (state);
+}
+
#endif /* SUPPORT_SERIAL */
diff --git a/usr/src/grub/grub-0.97/stage2/shared.h b/usr/src/grub/grub-0.97/stage2/shared.h
index 205715b021..cb41978ce3 100644
--- a/usr/src/grub/grub-0.97/stage2/shared.h
+++ b/usr/src/grub/grub-0.97/stage2/shared.h
@@ -579,7 +579,7 @@ typedef enum
ERR_NOTXPM,
ERR_TOOMANYCOLORS,
ERR_CORRUPTXPM,
-
+ ERR_NOVAR,
MAX_ERR_NUM
} grub_error_t;
@@ -639,6 +639,8 @@ extern int fallback_entryno;
extern int default_entry;
extern int current_entryno;
+extern unsigned int min_mem64;
+
/* The constants for password types. */
typedef enum
{
diff --git a/usr/src/grub/grub-0.97/stage2/stage2.c b/usr/src/grub/grub-0.97/stage2/stage2.c
index 896635b62d..017a8fa2d1 100644
--- a/usr/src/grub/grub-0.97/stage2/stage2.c
+++ b/usr/src/grub/grub-0.97/stage2/stage2.c
@@ -19,6 +19,9 @@
#include <shared.h>
#include <term.h>
+#include <expand.h>
+
+#define MENU_ROWS 12
grub_jmp_buf restart_env;
@@ -237,6 +240,7 @@ run_menu (char *menu_entries, char *config_entries, int num_entries,
int c, time1, time2 = -1, first_entry = 0;
char *cur_entry = 0;
struct term_entry *prev_term = NULL;
+ const char *console = NULL;
/*
* Main loop for menu UI.
@@ -247,7 +251,7 @@ restart:
invariant for TERM_DUMB: first_entry == 0 */
if (! (current_term->flags & TERM_DUMB))
{
- while (entryno > 11)
+ while (entryno > MENU_ROWS - 1)
{
first_entry++;
entryno--;
@@ -306,7 +310,7 @@ restart:
if (current_term->flags & TERM_DUMB)
print_entries_raw (num_entries, first_entry, menu_entries);
else
- print_border (3, 12);
+ print_border (3, MENU_ROWS);
grub_printf ("\n\
Use the %c and %c keys to select which entry is highlighted.\n",
@@ -332,10 +336,20 @@ restart:
selected line, or escape to go back to the main menu.");
}
+ /* The selected OS console is special; if it's in use, tell the user. */
+ console = get_variable("os_console");
+ if (console != NULL) {
+ printf("\n\n Selected OS console device is '%s'."
+ "\n To change OS console device, enter command-line mode"
+ "\n and use 'variable os_console <dev>', then Esc to return."
+ "\n Valid <dev> values are: ttya, ttyb, ttyc, ttyd, vga",
+ console);
+ }
+
if (current_term->flags & TERM_DUMB)
grub_printf ("\n\nThe selected entry is %d ", entryno);
else
- print_entries (3, 12, first_entry, entryno, menu_entries);
+ print_entries (3, MENU_ROWS, first_entry, entryno, menu_entries);
}
/* XX using RT clock now, need to initialize value */
@@ -425,7 +439,7 @@ restart:
else if (first_entry > 0)
{
first_entry--;
- print_entries (3, 12, first_entry, entryno,
+ print_entries (3, MENU_ROWS, first_entry, entryno,
menu_entries);
}
}
@@ -437,7 +451,7 @@ restart:
entryno++;
else
{
- if (entryno < 11)
+ if (entryno < MENU_ROWS - 1)
{
print_entry (4 + entryno, 0,
get_entry (menu_entries,
@@ -449,17 +463,17 @@ restart:
first_entry + entryno,
0));
}
- else if (num_entries > 12 + first_entry)
+ else if (num_entries > MENU_ROWS + first_entry)
{
first_entry++;
- print_entries (3, 12, first_entry, entryno, menu_entries);
+ print_entries (3, MENU_ROWS, first_entry, entryno, menu_entries);
}
}
}
else if (c == 7)
{
/* Page Up */
- first_entry -= 12;
+ first_entry -= MENU_ROWS;
if (first_entry < 0)
{
entryno += first_entry;
@@ -467,20 +481,20 @@ restart:
if (entryno < 0)
entryno = 0;
}
- print_entries (3, 12, first_entry, entryno, menu_entries);
+ print_entries (3, MENU_ROWS, first_entry, entryno, menu_entries);
}
else if (c == 3)
{
/* Page Down */
- first_entry += 12;
+ first_entry += MENU_ROWS;
if (first_entry + entryno + 1 >= num_entries)
{
- first_entry = num_entries - 12;
+ first_entry = num_entries - MENU_ROWS;
if (first_entry < 0)
first_entry = 0;
entryno = num_entries - first_entry - 1;
}
- print_entries (3, 12, first_entry, entryno, menu_entries);
+ print_entries (3, MENU_ROWS, first_entry, entryno, menu_entries);
}
if (config_entries)
@@ -503,7 +517,8 @@ restart:
{
/* But `o' differs from `O', since it may causes
the menu screen to scroll up. */
- if (entryno < 11 || (current_term->flags & TERM_DUMB))
+ if (entryno < MENU_ROWS - 1 ||
+ (current_term->flags & TERM_DUMB))
entryno++;
else
first_entry++;
@@ -541,7 +556,7 @@ restart:
if (entryno >= num_entries)
entryno--;
- if (first_entry && num_entries < 12 + first_entry)
+ if (first_entry && num_entries < MENU_ROWS + first_entry)
first_entry--;
}
@@ -553,7 +568,7 @@ restart:
grub_printf ("\n");
}
else
- print_entries (3, 12, first_entry, entryno, menu_entries);
+ print_entries (3, MENU_ROWS, first_entry, entryno, menu_entries);
}
cur_entry = menu_entries;
diff --git a/usr/src/grub/grub-0.97/stage2/term.h b/usr/src/grub/grub-0.97/stage2/term.h
index 8ed8b9dc86..65d4220669 100644
--- a/usr/src/grub/grub-0.97/stage2/term.h
+++ b/usr/src/grub/grub-0.97/stage2/term.h
@@ -119,6 +119,14 @@ int serial_getxy (void);
void serial_gotoxy (int x, int y);
void serial_cls (void);
void serial_setcolorstate (color_state state);
+
+void composite_putchar (int c);
+int composite_checkkey (void);
+int composite_getkey (void);
+int composite_getxy (void);
+void composite_gotoxy (int x, int y);
+void composite_cls (void);
+void composite_setcolorstate (color_state state);
#endif
#ifdef SUPPORT_HERCULES
diff --git a/usr/src/pkg/manifests/source-system-grub.mf b/usr/src/pkg/manifests/source-system-grub.mf
index a8e7717a79..ae62e92f51 100644
--- a/usr/src/pkg/manifests/source-system-grub.mf
+++ b/usr/src/pkg/manifests/source-system-grub.mf
@@ -208,6 +208,8 @@ file path=usr/share/src/grub/stage2/dir.h
file path=usr/share/src/grub/stage2/disk_inode.h
file path=usr/share/src/grub/stage2/disk_inode_ffs.h
file path=usr/share/src/grub/stage2/disk_io.c
+file path=usr/share/src/grub/stage2/expand.c
+file path=usr/share/src/grub/stage2/expand.h
file path=usr/share/src/grub/stage2/fat.h
file path=usr/share/src/grub/stage2/filesys.h
file path=usr/share/src/grub/stage2/freebsd.h