mirror of
https://git.savannah.gnu.org/git/grub.git
synced 2026-10-28 18:19:23 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7f405abb3 |
No files matched your search
@@ -1,21 +1,3 @@
|
||||
2013-10-26 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Consolidate cpuid code.
|
||||
|
||||
2013-10-26 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Move cpuid code to cpuid.h and TSC code to tsc.c.
|
||||
|
||||
2013-10-26 Grégoire Sutre <gregoire.sutre@gmail.com>
|
||||
|
||||
* util/grub.d/00_header.in: Don't use LANG if it's not set.
|
||||
|
||||
2013-10-26 Grégoire Sutre <gregoire.sutre@gmail.com>
|
||||
|
||||
* util/grub-mkconfig.in: Replace $0 with $self.
|
||||
* util/grub-reboot.in: Likewise.
|
||||
* util/grub-set-default.in: Likewise.
|
||||
|
||||
2013-10-26 BVK Chaitanya <bvk.groups@gmail.com>
|
||||
|
||||
* docs/osdetect.cfg: New file.
|
||||
|
||||
@@ -146,7 +146,6 @@ library = {
|
||||
common = grub-core/partmap/sunpc.c;
|
||||
common = grub-core/partmap/bsdlabel.c;
|
||||
common = grub-core/partmap/dfly.c;
|
||||
common = grub-core/partmap/dasd.c;
|
||||
common = grub-core/script/function.c;
|
||||
common = grub-core/script/lexer.c;
|
||||
common = grub-core/script/main.c;
|
||||
|
||||
@@ -90,7 +90,6 @@ case "$target_cpu" in
|
||||
i[[3456]]86) target_cpu=i386 ;;
|
||||
amd64) target_cpu=x86_64 ;;
|
||||
sparc) target_cpu=sparc64 ;;
|
||||
s390x) target_cpu=s390 ;;
|
||||
mipsel|mips64el)
|
||||
target_cpu=mipsel;
|
||||
machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPSEL=1";
|
||||
@@ -123,7 +122,6 @@ if test "x$with_platform" = x; then
|
||||
mips-*) platform=arc ;;
|
||||
ia64-*) platform=efi ;;
|
||||
arm-*) platform=uboot ;;
|
||||
s390-* | s390x-*) platform=mainframe ;;
|
||||
*) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;;
|
||||
esac
|
||||
else
|
||||
@@ -161,7 +159,6 @@ case "$target_cpu"-"$platform" in
|
||||
mipsel-loongson) ;;
|
||||
arm-uboot) ;;
|
||||
arm-efi) ;;
|
||||
s390-mainframe) ;;
|
||||
*-emu) ;;
|
||||
*) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
|
||||
esac
|
||||
@@ -1334,7 +1331,6 @@ AM_CONDITIONAL([COND_mips_qemu_mips], [test "(" x$target_cpu = xmips -o x$target
|
||||
AM_CONDITIONAL([COND_mips_arc], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xarc])
|
||||
AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275])
|
||||
AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275])
|
||||
AM_CONDITIONAL([COND_s390_mainframe], [test x$target_cpu = xs390 -a x$platform = xmainframe])
|
||||
AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips -o x$target_cpu = xmipsel])
|
||||
AM_CONDITIONAL([COND_mipsel], [test x$target_cpu = xmipsel])
|
||||
AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips])
|
||||
|
||||
@@ -23,7 +23,7 @@ GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
|
||||
"i386_multiboot", "i386_ieee1275", "x86_64_efi",
|
||||
"mips_loongson", "sparc64_ieee1275",
|
||||
"powerpc_ieee1275", "mips_arc", "ia64_efi",
|
||||
"mips_qemu_mips", "arm_uboot", "arm_efi", "s390_mainframe" ]
|
||||
"mips_qemu_mips", "arm_uboot", "arm_efi" ]
|
||||
|
||||
GROUPS = {}
|
||||
|
||||
@@ -37,7 +37,6 @@ GROUPS["mips"] = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ]
|
||||
GROUPS["sparc64"] = [ "sparc64_ieee1275" ]
|
||||
GROUPS["powerpc"] = [ "powerpc_ieee1275" ]
|
||||
GROUPS["arm"] = [ "arm_uboot", "arm_efi" ]
|
||||
GROUPS["s390"] = [ "s390_mainframe" ]
|
||||
|
||||
# Groups based on firmware
|
||||
GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi" ]
|
||||
|
||||
@@ -78,7 +78,6 @@ kernel = {
|
||||
sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400';
|
||||
mips_arc_ldflags = '-Wl,-Ttext,$(TARGET_LINK_ADDR)';
|
||||
mips_qemu_mips_ldflags = '-Wl,-Ttext,0x80200000';
|
||||
s390_mainframe_ldflags = '-Wl,-Ttext,0x8000';
|
||||
|
||||
mips_arc_cppflags = '-DGRUB_DECOMPRESSOR_LINK_ADDR=$(TARGET_DECOMPRESSOR_LINK_ADDR)';
|
||||
mips_loongson_cppflags = '-DUSE_ASCII_FALLBACK';
|
||||
@@ -1738,11 +1737,6 @@ module = {
|
||||
common = partmap/dfly.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = part_dasd;
|
||||
common = partmap/dasd.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = msdospart;
|
||||
common = parttool/msdospart.c;
|
||||
@@ -2146,3 +2140,8 @@ module = {
|
||||
name = progress;
|
||||
common = lib/progress.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = crypto_devmapper;
|
||||
common = disk/devmapper.c;
|
||||
};
|
||||
@@ -29,6 +29,11 @@
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
#define cpuid(num,a,b,c,d) \
|
||||
asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
|
||||
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
|
||||
: "0" (num))
|
||||
|
||||
static const struct grub_arg_option options[] =
|
||||
{
|
||||
/* TRANSLATORS: "(default)" at the end means that this option is used if
|
||||
@@ -73,18 +78,18 @@ GRUB_MOD_INIT(cpuid)
|
||||
goto done;
|
||||
|
||||
/* Check the highest input value for eax. */
|
||||
grub_cpuid (0, eax, ebx, ecx, edx);
|
||||
cpuid (0, eax, ebx, ecx, edx);
|
||||
/* We only look at the first four characters. */
|
||||
max_level = eax;
|
||||
if (max_level == 0)
|
||||
goto done;
|
||||
|
||||
grub_cpuid (0x80000000, eax, ebx, ecx, edx);
|
||||
cpuid (0x80000000, eax, ebx, ecx, edx);
|
||||
ext_level = eax;
|
||||
if (ext_level < 0x80000000)
|
||||
goto done;
|
||||
|
||||
grub_cpuid (0x80000001, eax, ebx, ecx, edx);
|
||||
cpuid (0x80000001, eax, ebx, ecx, edx);
|
||||
grub_cpuid_has_longmode = !!(edx & bit_LM);
|
||||
done:
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
* devmapper.c - Device mapper (w/ crypto support)
|
||||
*
|
||||
* Copyright (C) 2007 Simon Peter <dn.tlp@gmx.net>
|
||||
* Thanks to Raoul Boenisch <jkl345@gmx.net> for the initial idea.
|
||||
*/
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2003,2007 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/types.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/normal.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/crypto.h>
|
||||
|
||||
#define DEFAULT_HASH "ripemd160"
|
||||
#define DEFAULT_CIPHER "aes-cbc"
|
||||
#define MAX_KEYSIZE 64
|
||||
#define MAX_PASSPHRASE 256
|
||||
|
||||
#define MIN(a, b) (a < b ? a : b)
|
||||
|
||||
struct grub_crypto
|
||||
{
|
||||
char *devname, *source_devname;
|
||||
int has_partitions;
|
||||
grub_crypto_cipher_handle_t cipher;
|
||||
grub_disk_t srcdisk;
|
||||
int keysize;
|
||||
|
||||
struct grub_crypto *next;
|
||||
};
|
||||
|
||||
typedef struct grub_crypto *grub_crypto_t;
|
||||
|
||||
struct crypto_private
|
||||
{
|
||||
grub_crypto_t crypto;
|
||||
grub_disk_t srcdisk;
|
||||
};
|
||||
|
||||
typedef struct crypto_private *crypto_private_t;
|
||||
|
||||
static grub_crypto_t crypto_list = NULL;
|
||||
|
||||
/* Delete a registered crypto device. */
|
||||
static grub_err_t
|
||||
delete_crypto (const char *name)
|
||||
{
|
||||
grub_crypto_t dev, *prev;
|
||||
|
||||
/* Search for the device */
|
||||
for (dev = crypto_list, prev = &crypto_list; dev;
|
||||
prev = &dev->next, dev = dev->next)
|
||||
if (grub_strcmp (dev->devname, name) == 0)
|
||||
break;
|
||||
|
||||
if (!dev)
|
||||
return grub_error (GRUB_ERR_BAD_DEVICE, "Device not found");
|
||||
|
||||
/* Remove the device from the list */
|
||||
*prev = dev->next;
|
||||
grub_free (dev->devname);
|
||||
grub_free (dev->source_devname);
|
||||
grub_crypto_cipher_close (dev->cipher);
|
||||
grub_free (dev);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* Hashes a passphrase into a key and stores it with cipher. */
|
||||
static gcry_err_code_t
|
||||
set_passphrase (grub_crypto_t dev, const gcry_md_spec_t *hashparams,
|
||||
const char *passphrase)
|
||||
{
|
||||
grub_uint8_t hash[MAX_KEYSIZE * 2], *key = hash;
|
||||
char *p;
|
||||
unsigned int round, i, size = dev->keysize;
|
||||
unsigned int len;
|
||||
|
||||
/* Need no passphrase if there's no key */
|
||||
if (size == 0)
|
||||
return GPG_ERR_INV_KEYLEN;
|
||||
|
||||
/* Hack to support the "none" hash */
|
||||
if (hashparams)
|
||||
len = hashparams->mdlen;
|
||||
else
|
||||
len = grub_strlen (passphrase);
|
||||
|
||||
if (size > MAX_KEYSIZE || len > MAX_KEYSIZE)
|
||||
return GPG_ERR_INV_KEYLEN;
|
||||
|
||||
p = grub_malloc (grub_strlen (passphrase) + 2 + size / len);
|
||||
if (!p)
|
||||
return grub_errno;
|
||||
|
||||
for (round = 0; size; round++, key += len, size -= len)
|
||||
{
|
||||
/* hack from hashalot to avoid null bytes in key */
|
||||
for (i = 0; i < round; i++)
|
||||
p[i] = 'A';
|
||||
|
||||
grub_strcpy (p + i, passphrase);
|
||||
|
||||
if (len > size)
|
||||
len = size;
|
||||
|
||||
grub_crypto_hash (hashparams, key, p, grub_strlen (p));
|
||||
}
|
||||
|
||||
return grub_crypto_cipher_set_key (dev->cipher, hash, size);
|
||||
}
|
||||
|
||||
/***** GRUB command line interface *****************************************/
|
||||
|
||||
|
||||
static const struct grub_arg_option options[] = {
|
||||
{"delete", 'd', 0, "delete the crypto device entry", 0, ARG_TYPE_NONE},
|
||||
{"partitions", 'p', 0, "set that the device has partitions", 0,
|
||||
ARG_TYPE_NONE},
|
||||
{"cipher", 'c', 0, "set cipher (default=" DEFAULT_CIPHER ")", 0,
|
||||
ARG_TYPE_STRING},
|
||||
{"hash", 'h', 0, "set hash function (default=" DEFAULT_HASH ")", 0,
|
||||
ARG_TYPE_STRING},
|
||||
{"passphrase", 'P', 0, "set decryption passphrase", 0, ARG_TYPE_STRING},
|
||||
{"keysize", 'k', 0, "set key size (default is cipher specific)", 0,
|
||||
ARG_TYPE_INT},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_devmap (grub_extcmd_t cmd, int argc, char **args)
|
||||
{
|
||||
grub_disk_t disk;
|
||||
grub_crypto_t newdev;
|
||||
const char *cipher, *hash;
|
||||
const gcry_md_spec_t *hashparams;
|
||||
grub_err_t err = GRUB_ERR_NONE;
|
||||
char *passphrase = "";
|
||||
/* char cmdphrase[MAX_PASSPHRASE]; */
|
||||
const gcry_cipher_spec_t *ciph;
|
||||
struct grub_arg_list *state = cmd->state;
|
||||
|
||||
if (argc < 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Device name required");
|
||||
|
||||
/* Check whether delete is requested */
|
||||
if (state[0].set)
|
||||
return delete_crypto (args[0]);
|
||||
|
||||
if (argc < 2)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Source device name required");
|
||||
|
||||
/*** Create device is requested ***/
|
||||
|
||||
/* Choke on already existing devices */
|
||||
for (newdev = crypto_list; newdev != NULL; newdev = newdev->next)
|
||||
if (grub_strcmp (newdev->devname, args[0]) == 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Device already exists");
|
||||
|
||||
/* Check whether source device can be opened */
|
||||
disk = grub_disk_open (args[1]);
|
||||
if (!disk)
|
||||
return grub_errno;
|
||||
grub_disk_close (disk);
|
||||
|
||||
/* Parse remaining options */
|
||||
if (state[2].set)
|
||||
cipher = state[2].arg;
|
||||
else
|
||||
cipher = DEFAULT_CIPHER;
|
||||
if (state[3].set)
|
||||
hash = state[3].arg;
|
||||
else
|
||||
hash = DEFAULT_HASH;
|
||||
|
||||
/* Create new device entry */
|
||||
newdev = grub_malloc (sizeof (struct grub_crypto));
|
||||
if (!newdev)
|
||||
return grub_errno;
|
||||
newdev->devname = grub_strdup (args[0]);
|
||||
if (!newdev->devname)
|
||||
{
|
||||
grub_free (newdev);
|
||||
return grub_errno;
|
||||
}
|
||||
newdev->source_devname = grub_strdup (args[1]);
|
||||
if (!newdev->source_devname)
|
||||
{
|
||||
grub_free (newdev->devname);
|
||||
grub_free (newdev);
|
||||
return grub_errno;
|
||||
}
|
||||
newdev->has_partitions = state[1].set;
|
||||
ciph = grub_crypto_lookup_cipher_by_name (cipher);
|
||||
if (!ciph)
|
||||
{
|
||||
grub_free (newdev->source_devname);
|
||||
grub_free (newdev->devname);
|
||||
grub_free (newdev);
|
||||
return grub_error (GRUB_ERR_CIPHER_NOT_FOUND, "Unknown cipher %s", hash);
|
||||
}
|
||||
newdev->cipher = grub_crypto_cipher_open (ciph);
|
||||
if (!newdev->cipher)
|
||||
{
|
||||
grub_free (newdev->source_devname);
|
||||
grub_free (newdev->devname);
|
||||
grub_free (newdev);
|
||||
return grub_errno;
|
||||
}
|
||||
hashparams = grub_crypto_lookup_md_by_name (hash);
|
||||
if (!hashparams)
|
||||
{
|
||||
grub_free (newdev->source_devname);
|
||||
grub_free (newdev->devname);
|
||||
grub_free (newdev);
|
||||
grub_crypto_cipher_close (newdev->cipher);
|
||||
return grub_error (GRUB_ERR_CIPHER_NOT_FOUND, "Unknown digest %s", hash);
|
||||
}
|
||||
newdev->srcdisk = NULL;
|
||||
if (state[5].set)
|
||||
newdev->keysize = grub_strtoul (state[5].arg, NULL, 10);
|
||||
else
|
||||
newdev->keysize = 16;
|
||||
|
||||
/* Get passphrase */
|
||||
if (state[4].set) /* Passphrase supplied on commandline */
|
||||
passphrase = state[4].arg;
|
||||
else
|
||||
{
|
||||
#if 1
|
||||
return 0;
|
||||
#else
|
||||
if (grub_strcmp (cipher, "none"))
|
||||
{
|
||||
grub_cmdline_get ("Passphrase: ", cmdphrase, MAX_PASSPHRASE, '*',
|
||||
0);
|
||||
passphrase = cmdphrase;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
err = set_passphrase (newdev, hashparams, passphrase);
|
||||
if (err)
|
||||
{
|
||||
grub_crypto_cipher_close (newdev->cipher);
|
||||
grub_free (newdev->source_devname);
|
||||
grub_free (newdev->devname);
|
||||
grub_free (newdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Add new entry to list and return */
|
||||
newdev->next = crypto_list;
|
||||
crypto_list = newdev;
|
||||
|
||||
/* Error conditions */
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/***** GRUB disk device interface ******************************************/
|
||||
|
||||
static int
|
||||
grub_crypto_iterate (int (*hook) (const char *name))
|
||||
{
|
||||
grub_crypto_t i;
|
||||
|
||||
for (i = crypto_list; i != NULL; i = i->next)
|
||||
if (hook (i->devname))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_crypto_open (const char *name, grub_disk_t disk)
|
||||
{
|
||||
grub_crypto_t dev;
|
||||
crypto_private_t private;
|
||||
|
||||
for (dev = crypto_list; dev != NULL; dev = dev->next)
|
||||
if (grub_strcmp (dev->devname, name) == 0)
|
||||
break;
|
||||
|
||||
if (!dev)
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device");
|
||||
|
||||
/* Setup crypto private structure */
|
||||
if (!(private = grub_malloc (sizeof (struct crypto_private))))
|
||||
return grub_errno;
|
||||
private->crypto = dev;
|
||||
|
||||
/* Open underlying device */
|
||||
private->srcdisk = grub_disk_open (dev->source_devname);
|
||||
if (!private->srcdisk)
|
||||
{
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
/* Populate requested disk */
|
||||
disk->total_sectors = grub_disk_get_size (private->srcdisk);
|
||||
disk->id = (int) dev;
|
||||
disk->has_partitions = dev->has_partitions;
|
||||
disk->data = private;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_crypto_close (grub_disk_t disk)
|
||||
{
|
||||
crypto_private_t private = (crypto_private_t) disk->data;
|
||||
|
||||
grub_disk_close (private->srcdisk);
|
||||
grub_free (private);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_crypto_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||
grub_size_t size, char *buf)
|
||||
{
|
||||
crypto_private_t private = (crypto_private_t) disk->data;
|
||||
grub_err_t err;
|
||||
grub_crypto_cipher_handle_t cipher = private->crypto->cipher;
|
||||
grub_size_t i;
|
||||
|
||||
/* Read sectors from underlying disk */
|
||||
err =
|
||||
grub_disk_read (private->srcdisk, sector, 0,
|
||||
size << GRUB_DISK_SECTOR_BITS, buf);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Decrypt sectors */
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
grub_disk_addr_t s = grub_cpu_to_le64 (sector + i);
|
||||
grub_uint8_t iv[cipher->cipher->blocksize];
|
||||
gcry_err_code_t gcry_err;
|
||||
|
||||
/* Set IV from raw sector number (plain mode) */
|
||||
grub_memset (iv, 0, cipher->cipher->blocksize);
|
||||
grub_memcpy (iv, &s,
|
||||
MIN (sizeof (grub_disk_addr_t),
|
||||
cipher->cipher->blocksize));
|
||||
|
||||
gcry_err = grub_crypto_cbc_decrypt (cipher,
|
||||
buf + (i << GRUB_DISK_SECTOR_BITS),
|
||||
buf + (i << GRUB_DISK_SECTOR_BITS),
|
||||
GRUB_DISK_SECTOR_SIZE, iv);
|
||||
if (gcry_err)
|
||||
return grub_crypto_gcry_error (gcry_err);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_crypto_write (grub_disk_t disk __attribute ((unused)),
|
||||
grub_disk_addr_t sector __attribute ((unused)),
|
||||
grub_size_t size __attribute ((unused)),
|
||||
const char *buf __attribute ((unused)))
|
||||
{
|
||||
return GRUB_ERR_NOT_IMPLEMENTED_YET;
|
||||
}
|
||||
|
||||
static struct grub_disk_dev grub_crypto_dev = {
|
||||
.name = "crypto",
|
||||
.id = GRUB_DISK_DEVICE_DEVMAP_ID,
|
||||
.iterate = grub_crypto_iterate,
|
||||
.open = grub_crypto_open,
|
||||
.close = grub_crypto_close,
|
||||
.read = grub_crypto_read,
|
||||
.write = grub_crypto_write,
|
||||
.next = 0
|
||||
};
|
||||
|
||||
/***** GRUB module (de-)initialization *************************************/
|
||||
|
||||
static grub_extcmd_t cmd;
|
||||
|
||||
GRUB_MOD_INIT (devmapper)
|
||||
{
|
||||
cmd = grub_register_extcmd ("devmap", grub_cmd_devmap, GRUB_COMMAND_FLAG_BOTH,
|
||||
"devmap [OPTIONS...] [DEVICE] [SRC-DEV]",
|
||||
"Map one device onto another (w/ cryptography support).",
|
||||
options);
|
||||
grub_disk_dev_register (&grub_crypto_dev);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI (devmapper)
|
||||
{
|
||||
grub_unregister_extcmd (cmd);
|
||||
grub_disk_dev_unregister (&grub_crypto_dev);
|
||||
}
|
||||
@@ -18,10 +18,42 @@
|
||||
|
||||
#include <grub/efiemu/efiemu.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/i386/cpuid.h>
|
||||
|
||||
#define cpuid(num,a,b,c,d) \
|
||||
asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
|
||||
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
|
||||
: "0" (num))
|
||||
|
||||
#define bit_LM (1 << 29)
|
||||
|
||||
const char *
|
||||
grub_efiemu_get_default_core_name (void)
|
||||
{
|
||||
return grub_cpuid_has_longmode ? "efiemu64.o" : "efiemu32.o";
|
||||
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
unsigned int max_level;
|
||||
unsigned int ext_level;
|
||||
|
||||
/* See if we can use cpuid. */
|
||||
asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
|
||||
"pushl %0; popfl; pushfl; popl %0; popfl"
|
||||
: "=&r" (eax), "=&r" (ebx)
|
||||
: "i" (0x00200000));
|
||||
if (((eax ^ ebx) & 0x00200000) == 0)
|
||||
return "efiemu32.o";
|
||||
|
||||
/* Check the highest input value for eax. */
|
||||
cpuid (0, eax, ebx, ecx, edx);
|
||||
/* We only look at the first four characters. */
|
||||
max_level = eax;
|
||||
if (max_level == 0)
|
||||
return "efiemu32.o";
|
||||
|
||||
cpuid (0x80000000, eax, ebx, ecx, edx);
|
||||
ext_level = eax;
|
||||
if (ext_level < 0x80000000)
|
||||
return "efiemu32.o";
|
||||
|
||||
cpuid (0x80000001, eax, ebx, ecx, edx);
|
||||
return (edx & bit_LM) ? "efiemu64.o" : "efiemu32.o";
|
||||
}
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <grub/time.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/i386/tsc.h>
|
||||
#include <grub/i386/cpuid.h>
|
||||
#include <grub/i386/pit.h>
|
||||
#include <grub/cpu/io.h>
|
||||
|
||||
@@ -36,35 +35,6 @@ static grub_uint64_t tsc_boot_time;
|
||||
in 32-bit. */
|
||||
grub_uint32_t grub_tsc_rate;
|
||||
|
||||
/* Read the TSC value, which increments with each CPU clock cycle. */
|
||||
static __inline grub_uint64_t
|
||||
grub_get_tsc (void)
|
||||
{
|
||||
grub_uint32_t lo, hi;
|
||||
grub_uint32_t a,b,c,d;
|
||||
|
||||
/* The CPUID instruction is a 'serializing' instruction, and
|
||||
avoids out-of-order execution of the RDTSC instruction. */
|
||||
grub_cpuid (0,a,b,c,d);
|
||||
/* Read TSC value. We cannot use "=A", since this would use
|
||||
%rax on x86_64. */
|
||||
__asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi));
|
||||
|
||||
return (((grub_uint64_t) hi) << 32) | lo;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
grub_cpu_is_tsc_supported (void)
|
||||
{
|
||||
grub_uint32_t a,b,c,d;
|
||||
if (! grub_cpu_is_cpuid_supported ())
|
||||
return 0;
|
||||
|
||||
grub_cpuid(1,a,b,c,d);
|
||||
|
||||
return (d & (1 << 4)) != 0;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_pit_wait (grub_uint16_t tics)
|
||||
{
|
||||
@@ -93,7 +63,7 @@ grub_pit_wait (grub_uint16_t tics)
|
||||
GRUB_PIT_SPEAKER_PORT);
|
||||
}
|
||||
|
||||
static grub_uint64_t
|
||||
grub_uint64_t
|
||||
grub_tsc_get_time_ms (void)
|
||||
{
|
||||
grub_uint64_t a = grub_get_tsc () - tsc_boot_time;
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <grub/loader.h>
|
||||
#include <grub/autoefi.h>
|
||||
#include <grub/i386/tsc.h>
|
||||
#include <grub/i386/cpuid.h>
|
||||
#include <grub/efi/api.h>
|
||||
#include <grub/i386/pit.h>
|
||||
#include <grub/misc.h>
|
||||
@@ -126,22 +125,66 @@ guessfsb (void)
|
||||
{
|
||||
const grub_uint64_t sane_value = 100000000;
|
||||
grub_uint32_t manufacturer[3], max_cpuid, capabilities, msrlow;
|
||||
grub_uint32_t a, b, d;
|
||||
|
||||
if (! grub_cpu_is_cpuid_supported ())
|
||||
return sane_value;
|
||||
|
||||
grub_cpuid (0, max_cpuid, manufacturer[0], manufacturer[2], manufacturer[1]);
|
||||
#ifdef __APPLE__
|
||||
asm volatile ("movl $0, %%eax\n"
|
||||
#ifdef __x86_64__
|
||||
"push %%rbx\n"
|
||||
#else
|
||||
"push %%ebx\n"
|
||||
#endif
|
||||
"cpuid\n"
|
||||
#ifdef __x86_64__
|
||||
"pop %%rbx\n"
|
||||
#else
|
||||
"pop %%ebx\n"
|
||||
#endif
|
||||
: "=a" (max_cpuid),
|
||||
"=d" (manufacturer[1]), "=c" (manufacturer[2]));
|
||||
|
||||
/* Only Intel for now is done. */
|
||||
if (grub_memcmp (manufacturer + 1, "ineIntel", 12) != 0)
|
||||
return sane_value;
|
||||
|
||||
#else
|
||||
asm volatile ("movl $0, %%eax\n"
|
||||
"cpuid"
|
||||
: "=a" (max_cpuid), "=b" (manufacturer[0]),
|
||||
"=d" (manufacturer[1]), "=c" (manufacturer[2]));
|
||||
|
||||
/* Only Intel for now is done. */
|
||||
if (grub_memcmp (manufacturer, "GenuineIntel", 12) != 0)
|
||||
return sane_value;
|
||||
#endif
|
||||
|
||||
/* Check Speedstep. */
|
||||
if (max_cpuid < 1)
|
||||
return sane_value;
|
||||
|
||||
grub_cpuid (1, a, b, capabilities, d);
|
||||
#ifdef __APPLE__
|
||||
asm volatile ("movl $1, %%eax\n"
|
||||
#ifdef __x86_64__
|
||||
"push %%rbx\n"
|
||||
#else
|
||||
"push %%ebx\n"
|
||||
#endif
|
||||
"cpuid\n"
|
||||
#ifdef __x86_64__
|
||||
"pop %%rbx\n"
|
||||
#else
|
||||
"pop %%ebx\n"
|
||||
#endif
|
||||
: "=c" (capabilities):
|
||||
: "%rax", "%rdx");
|
||||
#else
|
||||
asm volatile ("movl $1, %%eax\n"
|
||||
"cpuid"
|
||||
: "=c" (capabilities):
|
||||
: "%rax", "%rbx", "%rdx");
|
||||
#endif
|
||||
|
||||
if (! (capabilities & (1 << 7)))
|
||||
return sane_value;
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/partition.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static struct grub_partition_map grub_dasd_partition_map;
|
||||
|
||||
struct addr
|
||||
{
|
||||
grub_uint16_t cyl;
|
||||
grub_uint16_t head;
|
||||
grub_uint8_t sec;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct anchor
|
||||
{
|
||||
grub_uint8_t unused1[4];
|
||||
grub_uint8_t magic[4];
|
||||
grub_uint8_t unused2[7];
|
||||
struct addr vtoc_addr;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* VOL1 in EBCDIC. */
|
||||
#define ANCHOR_MAGIC "\xe5\xd6\xd3\xf1"
|
||||
|
||||
struct grub_disk_addr_t
|
||||
address_to_block (const struct addr *a)
|
||||
{
|
||||
return a->cyl * + a->head * + a->sec;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
dasd_partition_map_iterate (grub_disk_t disk,
|
||||
int (*hook) (grub_disk_t disk,
|
||||
const grub_partition_t partition))
|
||||
{
|
||||
grub_err_t err;
|
||||
grub_partition_t p;
|
||||
struct anchor anchor;
|
||||
|
||||
err = grub_disk_read (disk, 2 * 8, 0, sizeof (anchor), &anchor);
|
||||
if (err)
|
||||
return err;
|
||||
if (grub_memcmp (anchor.magic, ANCHOR_MAGIC, sizeof (ANCHOR_MAGIC) - 1) != 0)
|
||||
return grub_error (GRUB_ERR_BAD_PART_TABLE,
|
||||
"not a dasd partition table");
|
||||
|
||||
p = (grub_partition_t) grub_zalloc (sizeof (struct grub_partition));
|
||||
if (! p)
|
||||
return grub_errno;
|
||||
p->partmap = &grub_dasd_partition_map;
|
||||
|
||||
p->start = 0x18 << 3;
|
||||
p->len = disk->total_sectors - p->start;
|
||||
p->number = 0;
|
||||
if (hook (disk, p))
|
||||
{
|
||||
grub_free (p);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_free (p);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* Partition map type. */
|
||||
static struct grub_partition_map grub_dasd_partition_map =
|
||||
{
|
||||
.name = "dasd",
|
||||
.iterate = dasd_partition_map_iterate,
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT(part_dasd)
|
||||
{
|
||||
grub_partition_map_register (&grub_dasd_partition_map);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(part_dasd)
|
||||
{
|
||||
grub_partition_map_unregister (&grub_dasd_partition_map);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <grub/video.h>
|
||||
#include <grub/i386/pc/int.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/cpu/cpuid.h>
|
||||
#include <grub/cpu/tsc.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -58,6 +58,11 @@ real2pm (grub_vbe_farptr_t ptr)
|
||||
+ ((unsigned long) ptr & 0x0000FFFF));
|
||||
}
|
||||
|
||||
#define cpuid(num,a,b,c,d) \
|
||||
asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
|
||||
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
|
||||
: "0" (num))
|
||||
|
||||
#define rdmsr(num,a,d) \
|
||||
asm volatile ("rdmsr" : "=a" (a), "=d" (d) : "c" (num))
|
||||
|
||||
@@ -131,7 +136,7 @@ grub_vbe_enable_mtrr (grub_uint8_t *base, grub_size_t size)
|
||||
if (! grub_cpu_is_cpuid_supported ())
|
||||
return;
|
||||
|
||||
grub_cpuid (1, eax, ebx, ecx, edx);
|
||||
cpuid (1, eax, ebx, ecx, edx);
|
||||
features = edx;
|
||||
if (! (features & 0x00001000)) /* MTRR */
|
||||
return;
|
||||
@@ -142,11 +147,11 @@ grub_vbe_enable_mtrr (grub_uint8_t *base, grub_size_t size)
|
||||
return;
|
||||
var_mtrrs = (mtrrcap & 0xFF);
|
||||
|
||||
grub_cpuid (0x80000000, eax, ebx, ecx, edx);
|
||||
cpuid (0x80000000, eax, ebx, ecx, edx);
|
||||
max_extended_cpuid = eax;
|
||||
if (max_extended_cpuid >= 0x80000008)
|
||||
{
|
||||
grub_cpuid (0x80000008, eax, ebx, ecx, edx);
|
||||
cpuid (0x80000008, eax, ebx, ecx, edx);
|
||||
maxphyaddr = (eax & 0xFF);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -48,6 +48,7 @@ enum grub_disk_dev_id
|
||||
GRUB_DISK_DEVICE_PROCFS_ID,
|
||||
GRUB_DISK_DEVICE_CBFSDISK_ID,
|
||||
GRUB_DISK_DEVICE_UBOOTDISK_ID,
|
||||
GRUB_DISK_DEVICE_DEVMAP_ID
|
||||
};
|
||||
|
||||
struct grub_disk;
|
||||
|
||||
@@ -21,64 +21,4 @@
|
||||
|
||||
extern unsigned char grub_cpuid_has_longmode;
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
static __inline int
|
||||
grub_cpu_is_cpuid_supported (void)
|
||||
{
|
||||
grub_uint64_t id_supported;
|
||||
|
||||
__asm__ ("pushfq\n\t"
|
||||
"popq %%rax /* Get EFLAGS into EAX */\n\t"
|
||||
"movq %%rax, %%rcx /* Save original flags in ECX */\n\t"
|
||||
"xorq $0x200000, %%rax /* Flip ID bit in EFLAGS */\n\t"
|
||||
"pushq %%rax /* Store modified EFLAGS on stack */\n\t"
|
||||
"popfq /* Replace current EFLAGS */\n\t"
|
||||
"pushfq /* Read back the EFLAGS */\n\t"
|
||||
"popq %%rax /* Get EFLAGS into EAX */\n\t"
|
||||
"xorq %%rcx, %%rax /* Check if flag could be modified */\n\t"
|
||||
: "=a" (id_supported)
|
||||
: /* No inputs. */
|
||||
: /* Clobbered: */ "%rcx");
|
||||
|
||||
return id_supported != 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static __inline int
|
||||
grub_cpu_is_cpuid_supported (void)
|
||||
{
|
||||
grub_uint32_t id_supported;
|
||||
|
||||
__asm__ ("pushfl\n\t"
|
||||
"popl %%eax /* Get EFLAGS into EAX */\n\t"
|
||||
"movl %%eax, %%ecx /* Save original flags in ECX */\n\t"
|
||||
"xorl $0x200000, %%eax /* Flip ID bit in EFLAGS */\n\t"
|
||||
"pushl %%eax /* Store modified EFLAGS on stack */\n\t"
|
||||
"popfl /* Replace current EFLAGS */\n\t"
|
||||
"pushfl /* Read back the EFLAGS */\n\t"
|
||||
"popl %%eax /* Get EFLAGS into EAX */\n\t"
|
||||
"xorl %%ecx, %%eax /* Check if flag could be modified */\n\t"
|
||||
: "=a" (id_supported)
|
||||
: /* No inputs. */
|
||||
: /* Clobbered: */ "%rcx");
|
||||
|
||||
return id_supported != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __PIC__
|
||||
#define grub_cpuid(num,a,b,c,d) \
|
||||
asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
|
||||
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
|
||||
: "0" (num))
|
||||
#else
|
||||
#define grub_cpuid(num,a,b,c,d) \
|
||||
asm volatile ("cpuid" \
|
||||
: "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
|
||||
: "0" (num))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -21,7 +21,122 @@
|
||||
|
||||
#include <grub/types.h>
|
||||
|
||||
/* Read the TSC value, which increments with each CPU clock cycle. */
|
||||
static __inline grub_uint64_t
|
||||
grub_get_tsc (void)
|
||||
{
|
||||
grub_uint32_t lo, hi;
|
||||
|
||||
/* The CPUID instruction is a 'serializing' instruction, and
|
||||
avoids out-of-order execution of the RDTSC instruction. */
|
||||
#ifdef __APPLE__
|
||||
__asm__ __volatile__ ("xorl %%eax, %%eax\n\t"
|
||||
#ifdef __x86_64__
|
||||
"push %%rbx\n"
|
||||
#else
|
||||
"push %%ebx\n"
|
||||
#endif
|
||||
"cpuid\n"
|
||||
#ifdef __x86_64__
|
||||
"pop %%rbx\n"
|
||||
#else
|
||||
"pop %%ebx\n"
|
||||
#endif
|
||||
:::"%rax", "%rcx", "%rdx");
|
||||
#else
|
||||
__asm__ __volatile__ ("xorl %%eax, %%eax\n\t"
|
||||
"cpuid":::"%rax", "%rbx", "%rcx", "%rdx");
|
||||
#endif
|
||||
/* Read TSC value. We cannot use "=A", since this would use
|
||||
%rax on x86_64. */
|
||||
__asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi));
|
||||
|
||||
return (((grub_uint64_t) hi) << 32) | lo;
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
static __inline int
|
||||
grub_cpu_is_cpuid_supported (void)
|
||||
{
|
||||
grub_uint64_t id_supported;
|
||||
|
||||
__asm__ ("pushfq\n\t"
|
||||
"popq %%rax /* Get EFLAGS into EAX */\n\t"
|
||||
"movq %%rax, %%rcx /* Save original flags in ECX */\n\t"
|
||||
"xorq $0x200000, %%rax /* Flip ID bit in EFLAGS */\n\t"
|
||||
"pushq %%rax /* Store modified EFLAGS on stack */\n\t"
|
||||
"popfq /* Replace current EFLAGS */\n\t"
|
||||
"pushfq /* Read back the EFLAGS */\n\t"
|
||||
"popq %%rax /* Get EFLAGS into EAX */\n\t"
|
||||
"xorq %%rcx, %%rax /* Check if flag could be modified */\n\t"
|
||||
: "=a" (id_supported)
|
||||
: /* No inputs. */
|
||||
: /* Clobbered: */ "%rcx");
|
||||
|
||||
return id_supported != 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static __inline int
|
||||
grub_cpu_is_cpuid_supported (void)
|
||||
{
|
||||
grub_uint32_t id_supported;
|
||||
|
||||
__asm__ ("pushfl\n\t"
|
||||
"popl %%eax /* Get EFLAGS into EAX */\n\t"
|
||||
"movl %%eax, %%ecx /* Save original flags in ECX */\n\t"
|
||||
"xorl $0x200000, %%eax /* Flip ID bit in EFLAGS */\n\t"
|
||||
"pushl %%eax /* Store modified EFLAGS on stack */\n\t"
|
||||
"popfl /* Replace current EFLAGS */\n\t"
|
||||
"pushfl /* Read back the EFLAGS */\n\t"
|
||||
"popl %%eax /* Get EFLAGS into EAX */\n\t"
|
||||
"xorl %%ecx, %%eax /* Check if flag could be modified */\n\t"
|
||||
: "=a" (id_supported)
|
||||
: /* No inputs. */
|
||||
: /* Clobbered: */ "%rcx");
|
||||
|
||||
return id_supported != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static __inline int
|
||||
grub_cpu_is_tsc_supported (void)
|
||||
{
|
||||
if (! grub_cpu_is_cpuid_supported ())
|
||||
return 0;
|
||||
|
||||
grub_uint32_t features;
|
||||
#ifdef __APPLE__
|
||||
__asm__ ("movl $1, %%eax\n\t"
|
||||
#ifdef __x86_64__
|
||||
"push %%rbx\n"
|
||||
#else
|
||||
"push %%ebx\n"
|
||||
#endif
|
||||
"cpuid\n"
|
||||
#ifdef __x86_64__
|
||||
"pop %%rbx\n"
|
||||
#else
|
||||
"pop %%ebx\n"
|
||||
#endif
|
||||
: "=d" (features)
|
||||
: /* No inputs. */
|
||||
: /* Clobbered: */ "%rax", "%rcx");
|
||||
#else
|
||||
__asm__ ("movl $1, %%eax\n\t"
|
||||
"cpuid\n"
|
||||
: "=d" (features)
|
||||
: /* No inputs. */
|
||||
: /* Clobbered: */ "%rax", "%rbx", "%rcx");
|
||||
#endif
|
||||
return (features & (1 << 4)) != 0;
|
||||
}
|
||||
|
||||
void grub_tsc_init (void);
|
||||
grub_uint64_t grub_tsc_get_time_ms (void);
|
||||
/* In ms per 2^32 ticks. */
|
||||
extern grub_uint32_t EXPORT_VAR(grub_tsc_rate);
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ argument () {
|
||||
shift
|
||||
|
||||
if test $# -eq 0; then
|
||||
gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2
|
||||
gettext_printf "%s: option requires an argument -- \`%s'\n" "$0" "$opt" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
echo $1
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ argument () {
|
||||
shift
|
||||
|
||||
if test $# -eq 0; then
|
||||
gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2
|
||||
gettext_printf "%s: option requires an argument -- \`%s'\n" "$0" "$opt" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
echo $1
|
||||
|
||||
@@ -63,7 +63,7 @@ argument () {
|
||||
shift
|
||||
|
||||
if test $# -eq 0; then
|
||||
gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2
|
||||
gettext_printf "%s: option requires an argument -- \`%s'\n" "$0" "$opt" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
echo $1
|
||||
|
||||
@@ -191,7 +191,7 @@ EOF
|
||||
EOF
|
||||
|
||||
# Gettext variables and module
|
||||
if [ "x${LANG}" != "xC" ] && [ "x${LANG}" != "x" ]; then
|
||||
if [ "x${LANG}" != "xC" ] ; then
|
||||
cat << EOF
|
||||
set locale_dir=\$prefix/locale
|
||||
set lang=${grub_lang}
|
||||
|
||||
Reference in new issue
Block a user