diff options
author | Keith M Wesolowski <wesolows@foobazco.org> | 2013-02-08 22:37:19 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2014-03-28 11:04:07 -0700 |
commit | a5602e1bdcf9570fa24684b54cf57a3f22e05ae1 (patch) | |
tree | c6ecd94ff972601c5d1af7e355fbf28fabb70502 | |
parent | c58b352673e88983cd2b8a388a8c7625f35e2f18 (diff) | |
download | illumos-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.solaris | 54 | ||||
-rw-r--r-- | usr/src/grub/grub-0.97/stage2/asm.S | 3 | ||||
-rw-r--r-- | usr/src/grub/grub-0.97/stage2/builtins.c | 493 | ||||
-rw-r--r-- | usr/src/grub/grub-0.97/stage2/char_io.c | 17 | ||||
-rw-r--r-- | usr/src/grub/grub-0.97/stage2/common.c | 3 | ||||
-rw-r--r-- | usr/src/grub/grub-0.97/stage2/cpu.h | 9 | ||||
-rw-r--r-- | usr/src/grub/grub-0.97/stage2/expand.c | 465 | ||||
-rw-r--r-- | usr/src/grub/grub-0.97/stage2/expand.h | 31 | ||||
-rw-r--r-- | usr/src/grub/grub-0.97/stage2/serial.c | 71 | ||||
-rw-r--r-- | usr/src/grub/grub-0.97/stage2/shared.h | 4 | ||||
-rw-r--r-- | usr/src/grub/grub-0.97/stage2/stage2.c | 45 | ||||
-rw-r--r-- | usr/src/grub/grub-0.97/stage2/term.h | 8 | ||||
-rw-r--r-- | usr/src/pkg/manifests/source-system-grub.mf | 2 |
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 |