merge with mainline

This commit is contained in:
BVK Chaitanya 2010-07-12 17:03:01 +05:30
commit 05df19acd5
170 changed files with 34663 additions and 3738 deletions

View file

@ -28,6 +28,7 @@
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <dirent.h>
#include <grub/util/misc.h>
#include <grub/util/deviceiter.h>
@ -345,18 +346,37 @@ get_xvd_disk_name (char *name, int unit)
}
#endif
/* Check if DEVICE can be read. If an error occurs, return zero,
otherwise return non-zero. */
static int
check_device (const char *device)
static struct seen_device
{
struct seen_device *next;
const char *name;
} *seen;
/* Check if DEVICE can be read. Skip any DEVICE that we have already seen.
If an error occurs, return zero, otherwise return non-zero. */
static int
check_device_readable_unique (const char *device)
{
char *real_device;
char buf[512];
FILE *fp;
struct seen_device *seen_elt;
/* If DEVICE is empty, just return error. */
if (*device == 0)
return 0;
/* Have we seen this device already? */
real_device = canonicalize_file_name (device);
if (! real_device)
return 0;
if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), real_device))
{
grub_dprintf ("deviceiter", "Already seen %s (%s)\n",
device, real_device);
goto fail;
}
fp = fopen (device, "r");
if (! fp)
{
@ -379,7 +399,7 @@ check_device (const char *device)
break;
}
/* Error opening the device. */
return 0;
goto fail;
}
/* Make sure CD-ROMs don't get assigned a BIOS disk number
@ -387,7 +407,7 @@ check_device (const char *device)
#ifdef __linux__
# ifdef CDROM_GET_CAPABILITY
if (ioctl (fileno (fp), CDROM_GET_CAPABILITY, 0) >= 0)
return 0;
goto fail;
# else /* ! CDROM_GET_CAPABILITY */
/* Check if DEVICE is a CD-ROM drive by the HDIO_GETGEO ioctl. */
{
@ -395,14 +415,14 @@ check_device (const char *device)
struct stat st;
if (fstat (fileno (fp), &st))
return 0;
goto fail;
/* If it is a block device and isn't a floppy, check if HDIO_GETGEO
succeeds. */
if (S_ISBLK (st.st_mode)
&& MAJOR (st.st_rdev) != FLOPPY_MAJOR
&& ioctl (fileno (fp), HDIO_GETGEO, &hdg))
return 0;
goto fail;
}
# endif /* ! CDROM_GET_CAPABILITY */
#endif /* __linux__ */
@ -410,7 +430,7 @@ check_device (const char *device)
#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
# ifdef CDIOCCLRDEBUG
if (ioctl (fileno (fp), CDIOCCLRDEBUG, 0) >= 0)
return 0;
goto fail;
# endif /* CDIOCCLRDEBUG */
#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */
@ -418,21 +438,43 @@ check_device (const char *device)
if (fread (buf, 1, 512, fp) != 512)
{
fclose (fp);
return 0;
goto fail;
}
/* Remember that we've seen this device. */
seen_elt = xmalloc (sizeof (*seen_elt));
seen_elt->name = real_device; /* steal memory */
grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt));
fclose (fp);
return 1;
fail:
free (real_device);
return 0;
}
static void
clear_seen_devices (void)
{
while (seen)
{
struct seen_device *seen_elt = seen;
seen = seen->next;
free (seen_elt);
}
seen = NULL;
}
#ifdef __linux__
# ifdef HAVE_DEVICE_MAPPER
struct dmraid_seen
/* Like strcmp, but doesn't require a cast for use as a qsort comparator. */
static int
compare_file_names (const void *a, const void *b)
{
struct dmraid_seen *next;
const char *name;
};
# endif /* HAVE_DEVICE_MAPPER */
const char *left = *(const char **) a;
const char *right = *(const char **) b;
return strcmp (left, right);
}
#endif /* __linux__ */
void
@ -441,6 +483,8 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
{
int i;
clear_seen_devices ();
/* Floppies. */
for (i = 0; i < floppy_disks; i++)
{
@ -450,13 +494,70 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
get_floppy_disk_name (name, i);
if (stat (name, &st) < 0)
break;
/* In floppies, write the map, whether check_device succeeds
or not, because the user just may not insert floppies. */
/* In floppies, write the map, whether check_device_readable_unique
succeeds or not, because the user just may not insert floppies. */
if (hook (name, 1))
return;
goto out;
}
#ifdef __linux__
{
DIR *dir = opendir ("/dev/disk/by-id");
if (dir)
{
struct dirent *entry;
char **names;
size_t names_len = 0, names_max = 1024, i;
names = xmalloc (names_max * sizeof (*names));
/* Dump all the directory entries into names, resizing if
necessary. */
for (entry = readdir (dir); entry; entry = readdir (dir))
{
/* Skip partition entries. */
if (strstr (entry->d_name, "-part"))
continue;
/* Skip device-mapper entries; we'll handle the ones we want
later. */
if (strncmp (entry->d_name, "dm-", sizeof ("dm-") - 1) == 0)
continue;
/* Skip RAID entries; they are handled by upper layers. */
if (strncmp (entry->d_name, "md-", sizeof ("md-") - 1) == 0)
continue;
if (names_len >= names_max)
{
names_max *= 2;
names = xrealloc (names, names_max * sizeof (*names));
}
names[names_len++] = xasprintf (entry->d_name);
}
/* /dev/disk/by-id/ usually has a few alternative identifications of
devices (e.g. ATA vs. SATA). check_device_readable_unique will
ensure that we only get one for any given disk, but sort the list
so that the choice of which one we get is stable. */
qsort (names, names_len, sizeof (*names), &compare_file_names);
closedir (dir);
/* Now add all the devices in sorted order. */
for (i = 0; i < names_len; ++i)
{
char *path = xasprintf ("/dev/disk/by-id/%s", names[i]);
if (check_device_readable_unique (path))
{
if (hook (path, 0))
goto out;
}
free (path);
free (names[i]);
}
free (names);
}
}
if (have_devfs ())
{
i = 0;
@ -476,10 +577,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
{
strcat (name, "/disc");
if (hook (name, 0))
return;
goto out;
}
}
return;
goto out;
}
#endif /* __linux__ */
@ -489,10 +590,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
char name[16];
get_ide_disk_name (name, i);
if (check_device (name))
if (check_device_readable_unique (name))
{
if (hook (name, 0))
return;
goto out;
}
}
@ -503,10 +604,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
char name[16];
get_virtio_disk_name (name, i);
if (check_device (name))
if (check_device_readable_unique (name))
{
if (hook (name, 0))
return;
goto out;
}
}
@ -516,10 +617,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
char name[20];
get_ataraid_disk_name (name, i);
if (check_device (name))
if (check_device_readable_unique (name))
{
if (hook (name, 0))
return;
goto out;
}
}
@ -529,10 +630,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
char name[16];
get_xvd_disk_name (name, i);
if (check_device (name))
if (check_device_readable_unique (name))
{
if (hook (name, 0))
return;
goto out;
}
}
#endif /* __linux__ */
@ -543,10 +644,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
char name[16];
get_scsi_disk_name (name, i);
if (check_device (name))
if (check_device_readable_unique (name))
{
if (hook (name, 0))
return;
goto out;
}
}
@ -566,10 +667,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
char name[24];
get_dac960_disk_name (name, controller, drive);
if (check_device (name))
if (check_device_readable_unique (name))
{
if (hook (name, 0))
return;
goto out;
}
}
}
@ -587,10 +688,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
char name[24];
get_acceleraid_disk_name (name, controller, drive);
if (check_device (name))
if (check_device_readable_unique (name))
{
if (hook (name, 0))
return;
goto out;
}
}
}
@ -608,10 +709,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
char name[24];
get_cciss_disk_name (name, controller, drive);
if (check_device (name))
if (check_device_readable_unique (name))
{
if (hook (name, 0))
return;
goto out;
}
}
}
@ -629,10 +730,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
char name[24];
get_ida_disk_name (name, controller, drive);
if (check_device (name))
if (check_device_readable_unique (name))
{
if (hook (name, 0))
return;
goto out;
}
}
}
@ -647,10 +748,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
char name[24];
get_i2o_disk_name (name, unit);
if (check_device (name))
if (check_device_readable_unique (name))
{
if (hook (name, 0))
return;
goto out;
}
}
}
@ -661,10 +762,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
char name[16];
get_mmc_disk_name (name, i);
if (check_device (name))
if (check_device_readable_unique (name))
{
if (hook (name, 0))
return;
goto out;
}
}
@ -685,7 +786,6 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
unsigned int next = 0;
void *top_handle, *second_handle;
struct dm_tree_node *root, *top, *second;
struct dmraid_seen *seen = NULL;
/* Build DM tree for all devices. */
tree = dm_tree_create ();
@ -721,7 +821,6 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
{
const char *node_name, *node_uuid;
char *name;
struct dmraid_seen *seen_elt;
node_name = dm_tree_node_get_name (second);
dmraid_check (node_name, "dm_tree_node_get_name failed\n");
@ -733,40 +832,21 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
goto dmraid_next_child;
}
/* Have we already seen this node? There are typically very few
DM-RAID disks, so a list should be fast enough. */
if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), node_name))
{
grub_dprintf ("deviceiter", "Already seen DM device %s\n",
node_name);
goto dmraid_next_child;
}
name = xasprintf ("/dev/mapper/%s", node_name);
if (check_device (name))
if (check_device_readable_unique (name))
{
if (hook (name, 0))
{
free (name);
while (seen)
{
struct dmraid_seen *seen_elt = seen;
seen = seen->next;
free (seen_elt);
}
if (task)
dm_task_destroy (task);
if (tree)
dm_tree_free (tree);
return;
goto out;
}
}
free (name);
seen_elt = xmalloc (sizeof *seen_elt);
seen_elt->name = node_name;
grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt));
dmraid_next_child:
second = dm_tree_next_child (&second_handle, top, 1);
}
@ -774,12 +854,6 @@ dmraid_next_child:
}
dmraid_end:
while (seen)
{
struct dmraid_seen *seen_elt = seen;
seen = seen->next;
free (seen_elt);
}
if (task)
dm_task_destroy (task);
if (tree)
@ -787,5 +861,8 @@ dmraid_end:
}
# endif /* HAVE_DEVICE_MAPPER */
#endif /* __linux__ */
out:
clear_seen_devices ();
}

View file

@ -33,12 +33,6 @@
#define DEFAULT_ENVBLK_SIZE 1024
void
grub_putchar (int c)
{
putchar (c);
}
void
grub_refresh (void)
{
@ -51,6 +45,14 @@ grub_getkey (void)
return 0;
}
void
grub_xputs_real (const char *str)
{
fputs (str, stdout);
}
void (*grub_xputs) (const char *str) = grub_xputs_real;
char *
grub_env_get (const char *name __attribute__ ((unused)))
{

View file

@ -43,12 +43,14 @@
#include "progname.h"
void
grub_putchar (int c)
void
grub_xputs_real (const char *str)
{
putchar (c);
fputs (str, stdout);
}
void (*grub_xputs) (const char *str) = grub_xputs_real;
int
grub_getkey (void)
{

View file

@ -50,6 +50,7 @@ no_floppy=
force_lba=
recheck=no
debug=no
debug_image=
if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then
disk_module=biosdisk
@ -103,8 +104,23 @@ Report bugs to <bug-grub@gnu.org>.
EOF
}
argument () {
opt=$1
shift
if test $# -eq 0; then
echo "$0: option requires an argument -- '$opt'" 1>&2
exit 1
fi
echo $1
}
# Check the arguments.
for option in "$@"; do
while test $# -gt 0
do
option=$1
shift
case "$option" in
-h | --help)
usage
@ -112,33 +128,67 @@ for option in "$@"; do
-v | --version)
echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
exit 0 ;;
--modules)
modules=`argument $option "$@"`; shift;;
--modules=*)
modules=`echo "$option" | sed 's/--modules=//'` ;;
--font)
font=`argument $option "$@"`; shift;;
--font=*)
font=`echo "$option" | sed 's/--font=//'` ;;
--root-directory)
rootdir=`argument $option "$@"`; shift;;
--root-directory=*)
rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
--grub-setup)
grub_setup=`argument $option "$@"`; shift;;
--grub-setup=*)
grub_setup=`echo "$option" | sed 's/--grub-setup=//'` ;;
--grub-mkimage)
grub_mkimage=`argument $option "$@"`; shift;;
--grub-mkimage=*)
grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;;
--grub-mkdevicemap)
grub_mkdevicemap=`argument $option "$@"`; shift;;
--grub-mkdevicemap=*)
grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;;
--grub-probe)
grub_probe=`argument $option "$@"`; shift;;
--grub-probe=*)
grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;;
--no-floppy)
no_floppy="--no-floppy" ;;
--recheck)
recheck=yes ;;
--disk-module)
if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then
disk_module=`argument $option "$@"`; shift;
fi ;;
--disk-module=*)
if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then
disk_module=`echo "$option" | sed 's/--disk-module=//'`
fi ;;
# This is an undocumented feature...
--debug)
debug=yes ;;
--debug-image)
debug_image=`argument $option "$@"`; shift;;
--debug-image=*)
debug_image=`echo "$option" | sed 's/--debug-image=//'` ;;
-f | --force)
setup_force="--force" ;;
-*)
echo "Unrecognized option \`$option'" 1>&2
usage
@ -305,6 +355,13 @@ fi
prefix_drive=
config_opt=
rm -f ${grubdir}/load.cfg
if [ "x${debug_image}" != x ]; then
echo "set debug='${debug_image}'" >> ${grubdir}/load.cfg
config_opt="-c ${grubdir}/load.cfg "
fi
if [ "x${devabstraction_module}" = "x" ] ; then
if [ x"${install_device}" != x ]; then
if echo "${install_device}" | grep -qx "(.*)" ; then
@ -312,12 +369,12 @@ if [ "x${devabstraction_module}" = "x" ] ; then
else
install_drive="`$grub_probe --target=drive --device ${install_device}`" || exit 1
fi
install_drive="`echo ${install_drive} | sed -e s/,[0-9]*[a-z]*//g`"
install_drive="`echo ${install_drive} | sed -e s/,[a-z0-9,]*//g`"
fi
grub_drive="`$grub_probe --target=drive --device ${grub_device}`" || exit 1
# Strip partition number
grub_drive="`echo ${grub_drive} | sed -e s/,[0-9]*[a-z]*//g`"
grub_drive="`echo ${grub_drive} | sed -e s/,[a-z0-9,]*//g`"
if [ "$disk_module" = ata ] ; then
# generic method (used on coreboot and ata mod)
uuid="`$grub_probe --target=fs_uuid --device ${grub_device}`"
@ -325,7 +382,7 @@ if [ "x${devabstraction_module}" = "x" ] ; then
echo "UUID needed with ata mod, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
exit 1
fi
echo "search.fs_uuid ${uuid} root " > ${grubdir}/load.cfg
echo "search.fs_uuid ${uuid} root " >> ${grubdir}/load.cfg
echo 'set prefix=($root)'"${relative_grubdir}" >> ${grubdir}/load.cfg
config_opt="-c ${grubdir}/load.cfg "
modules="$modules search_fs_uuid"
@ -335,7 +392,7 @@ if [ "x${devabstraction_module}" = "x" ] ; then
echo "You attempted a cross-disk install, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
exit 1
fi
echo "search.fs_uuid ${uuid} root " > ${grubdir}/load.cfg
echo "search.fs_uuid ${uuid} root " >> ${grubdir}/load.cfg
echo 'set prefix=($root)'"${relative_grubdir}" >> ${grubdir}/load.cfg
config_opt="-c ${grubdir}/load.cfg "
modules="$modules search_fs_uuid"

View file

@ -1,7 +1,8 @@
#! /bin/sh -e
#! /bin/sh
set -e
# Generate grub.cfg by inspecting /boot contents.
# Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -52,14 +53,23 @@ Report bugs to <bug-grub@gnu.org>.
EOF
}
argument () {
opt=$1
shift
if test $# -eq 0; then
echo "$0: option requires an argument -- '$opt'" 1>&2
exit 1
fi
echo $1
}
# Check the arguments.
next_grub_cfg=false
for option in "$@"; do
if $next_grub_cfg; then
grub_cfg=$option
next_grub_cfg=false
continue
fi
while test $# -gt 0
do
option=$1
shift
case "$option" in
-h | --help)
usage
@ -67,9 +77,8 @@ for option in "$@"; do
-v | --version)
echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
exit 0 ;;
-o)
next_grub_cfg=:
;;
-o | --output)
grub_cfg=`argument $option "$@"`; shift;;
--output=*)
grub_cfg=`echo "$option" | sed 's/--output=//'`
;;
@ -78,13 +87,9 @@ for option in "$@"; do
usage
exit 1
;;
# Explicitly ignore non-option arguments, for compatibility.
esac
done
if $next_grub_cfg; then
echo "Missing argument to \`-o'" 1>&2
usage
exit 1
fi
. ${libdir}/grub/grub-mkconfig_lib
@ -92,11 +97,11 @@ case "$host_os" in
netbsd* | openbsd*)
# Because /boot is used for the boot block in NetBSD and OpenBSD, use /grub
# instead of /boot/grub.
grub_prefix=`echo /grub | sed ${transform}`
GRUB_PREFIX=`echo /grub | sed ${transform}`
;;
*)
# Use /boot/grub by default.
grub_prefix=`echo /boot/grub | sed ${transform}`
GRUB_PREFIX=`echo /boot/grub | sed ${transform}`
;;
esac
@ -137,9 +142,9 @@ else
exit 1
fi
mkdir -p ${grub_prefix}
mkdir -p ${GRUB_PREFIX}
if test -e ${grub_prefix}/device.map ; then : ; else
if test -e ${GRUB_PREFIX}/device.map ; then : ; else
${grub_mkdevicemap}
fi
@ -174,17 +179,14 @@ fi
for x in ${GRUB_TERMINAL_OUTPUT}; do
if [ "x${x}" = "xgfxterm" ]; then
# If this platform supports gfxterm, try to use it.
if ! test -e ${grub_prefix}/gfxterm.mod ; then
if ! test -e ${GRUB_PREFIX}/gfxterm.mod ; then
if [ "x$termoutdefault" != "x1" ]; then
echo "gfxterm isn't available on your platform" >&2 ; exit 1
fi
GRUB_TERMINAL_OUTPUT=
break;
fi
# FIXME: this should do something smarter than just loading first
# video backend.
GRUB_VIDEO_BACKEND=$(head -n 1 ${grub_prefix}/video.lst || true)
if [ -z "${GRUB_VIDEO_BACKEND}" ] ; then
if [ ! -s "${GRUB_PREFIX}/video.lst" ] ; then
if [ "x$termoutdefault" != "x1" ]; then
echo "No suitable backend could be found for gfxterm." >&2 ; exit 1
fi
@ -242,7 +244,7 @@ export GRUB_DEVICE \
GRUB_FS \
GRUB_FONT_PATH \
GRUB_PRELOAD_MODULES \
GRUB_VIDEO_BACKEND
GRUB_PREFIX
# These are optional, user-defined variables.
export GRUB_DEFAULT \
@ -256,6 +258,8 @@ export GRUB_DEFAULT \
GRUB_DISTRIBUTOR \
GRUB_CMDLINE_LINUX \
GRUB_CMDLINE_LINUX_DEFAULT \
GRUB_CMDLINE_XEN \
GRUB_CMDLINE_XEN_DEFAULT \
GRUB_CMDLINE_NETBSD \
GRUB_CMDLINE_NETBSD_DEFAULT \
GRUB_TERMINAL_INPUT \
@ -264,13 +268,15 @@ export GRUB_DEFAULT \
GRUB_DISABLE_LINUX_UUID \
GRUB_DISABLE_LINUX_RECOVERY \
GRUB_DISABLE_NETBSD_RECOVERY \
GRUB_VIDEO_BACKEND \
GRUB_GFXMODE \
GRUB_BACKGROUND \
GRUB_THEME \
GRUB_GFXPAYLOAD_LINUX \
GRUB_DISABLE_OS_PROBER \
GRUB_INIT_TUNE \
GRUB_SAVEDEFAULT
GRUB_SAVEDEFAULT \
GRUB_BADRAM
if test "x${grub_cfg}" != "x"; then
rm -f ${grub_cfg}.new

View file

@ -128,6 +128,7 @@ grub_file_is_not_garbage ()
if test -f "$1" ; then
case "$1" in
*.dpkg-*) return 1 ;; # debian dpkg
README*) return 1 ;; # documentation
esac
else
return 1
@ -189,3 +190,15 @@ version_find_latest ()
gettext_quoted () {
$gettext "$@" | sed "s/'/'\\\\''/g"
}
uses_abstraction () {
device=$1
abstraction="`${grub_probe} --device ${device} --target=abstraction`"
for module in ${abstraction}; do
if test "x${module}" = "x$2"; then
return 0
fi
done
return 1
}

View file

@ -39,12 +39,14 @@
#include "progname.h"
void
grub_putchar (int c)
void
grub_xputs_real (const char *str)
{
putchar (c);
fputs (str, stdout);
}
void (*grub_xputs) (const char *str) = grub_xputs_real;
int
grub_getkey (void)
{

View file

@ -19,8 +19,11 @@
#include <config.h>
#include <grub/types.h>
#include <grub/util/misc.h>
#include <grub/misc.h>
#include <grub/i18n.h>
#include <grub/fontformat.h>
#include <grub/font.h>
#include <grub/unicode.h>
#include <stdio.h>
#include <stdlib.h>
@ -29,8 +32,16 @@
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_TRUETYPE_TAGS_H
#include FT_TRUETYPE_TABLES_H
#include <freetype/ftsynth.h>
#undef __FTERRORS_H__
#define FT_ERROR_START_LIST const char *ft_errmsgs[] = {
#define FT_ERRORDEF(e, v, s) [e] = s,
#define FT_ERROR_END_LIST };
#include FT_ERRORS_H
#include "progname.h"
#define GRUB_FONT_DEFAULT_SIZE 16
@ -47,13 +58,14 @@ struct grub_glyph_info
int y_ofs;
int device_width;
int bitmap_size;
grub_uint8_t bitmap[0];
grub_uint8_t *bitmap;
};
enum file_formats
{
PF2,
ASCII_BITMAPS
ASCII_BITMAPS,
WIDTH_SPEC
};
#define GRUB_FONT_FLAG_BOLD 1
@ -75,7 +87,9 @@ struct grub_font_info
int flags;
int num_range;
grub_uint32_t *ranges;
struct grub_glyph_info *glyph;
struct grub_glyph_info *glyphs_unsorted;
struct grub_glyph_info *glyphs_sorted;
int num_glyphs;
};
static struct option options[] =
@ -95,6 +109,7 @@ static struct option options[] =
{"version", no_argument, 0, 'V'},
{"verbose", no_argument, 0, 'v'},
{"ascii-bitmaps", no_argument, 0, 0x102},
{"width-spec", no_argument, 0, 0x103},
{0, 0, 0, 0}
};
@ -111,6 +126,7 @@ Usage: %s [OPTIONS] FONT_FILES\n\
\nOptions:\n\
-o, --output=FILE_NAME set output file name\n\
--ascii-bitmaps save only the ASCII bitmaps\n\
--width-spec create width summary file\n\
-i, --index=N set face index\n\
-r, --range=A-B[,C-D] set font range\n\
-n, --name=S set font family name\n\
@ -146,16 +162,18 @@ add_pixel (grub_uint8_t **data, int *mask, int not_blank)
*mask >>= 1;
}
void
add_char (struct grub_font_info *font_info, FT_Face face,
grub_uint32_t char_code)
static void
add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face,
grub_uint32_t char_code, int nocut)
{
struct grub_glyph_info *glyph_info, **p_glyph;
struct grub_glyph_info *glyph_info;
int width, height;
int cuttop, cutbottom, cutleft, cutright;
grub_uint8_t *data;
int mask, i, j, bitmap_size;
FT_GlyphSlot glyph;
int flag = FT_LOAD_RENDER | FT_LOAD_MONOCHROME;
FT_Error err;
if (font_info->flags & GRUB_FONT_FLAG_NOBITMAP)
flag |= FT_LOAD_NO_BITMAP;
@ -165,39 +183,99 @@ add_char (struct grub_font_info *font_info, FT_Face face,
else if (font_info->flags & GRUB_FONT_FLAG_FORCEHINT)
flag |= FT_LOAD_FORCE_AUTOHINT;
if (FT_Load_Char (face, char_code, flag))
return;
err = FT_Load_Glyph (face, glyph_idx, flag);
if (err)
{
printf ("Freetype Error %d loading glyph 0x%x for U+0x%x%s",
err, glyph_idx, char_code & GRUB_FONT_CODE_CHAR_MASK,
char_code & GRUB_FONT_CODE_RIGHT_JOINED
? ((char_code & GRUB_FONT_CODE_LEFT_JOINED) ? " (medial)":
" (leftmost)")
: ((char_code & GRUB_FONT_CODE_LEFT_JOINED) ? " (rightmost)":
""));
if (err > 0 && err < (signed) ARRAY_SIZE (ft_errmsgs))
printf (": %s\n", ft_errmsgs[err]);
else
printf ("\n");
return;
}
glyph = face->glyph;
if (font_info->flags & GRUB_FONT_FLAG_BOLD)
FT_GlyphSlot_Embolden (glyph);
p_glyph = &font_info->glyph;
while ((*p_glyph) && ((*p_glyph)->char_code > char_code))
if (glyph->next)
printf ("%x\n", char_code);
if (nocut)
cuttop = cutbottom = cutleft = cutright = 0;
else
{
p_glyph = &(*p_glyph)->next;
for (cuttop = 0; cuttop < glyph->bitmap.rows; cuttop++)
{
for (j = 0; j < glyph->bitmap.width; j++)
if (glyph->bitmap.buffer[j / 8 + cuttop * glyph->bitmap.pitch]
& (1 << (7 - (j & 7))))
break;
if (j != glyph->bitmap.width)
break;
}
for (cutbottom = glyph->bitmap.rows - 1; cutbottom >= 0; cutbottom--)
{
for (j = 0; j < glyph->bitmap.width; j++)
if (glyph->bitmap.buffer[j / 8 + cutbottom * glyph->bitmap.pitch]
& (1 << (7 - (j & 7))))
break;
if (j != glyph->bitmap.width)
break;
}
cutbottom = glyph->bitmap.rows - 1 - cutbottom;
if (cutbottom + cuttop >= glyph->bitmap.rows)
cutbottom = 0;
for (cutleft = 0; cutleft < glyph->bitmap.width; cutleft++)
{
for (j = 0; j < glyph->bitmap.rows; j++)
if (glyph->bitmap.buffer[cutleft / 8 + j * glyph->bitmap.pitch]
& (1 << (7 - (cutleft & 7))))
break;
if (j != glyph->bitmap.rows)
break;
}
for (cutright = glyph->bitmap.width - 1; cutright >= 0; cutright--)
{
for (j = 0; j < glyph->bitmap.rows; j++)
if (glyph->bitmap.buffer[cutright / 8 + j * glyph->bitmap.pitch]
& (1 << (7 - (cutright & 7))))
break;
if (j != glyph->bitmap.rows)
break;
}
cutright = glyph->bitmap.width - 1 - cutright;
if (cutright + cutleft >= glyph->bitmap.width)
cutright = 0;
}
/* Ignore duplicated glyph. */
if ((*p_glyph) && ((*p_glyph)->char_code == char_code))
return;
width = glyph->bitmap.width;
height = glyph->bitmap.rows;
width = glyph->bitmap.width - cutleft - cutright;
height = glyph->bitmap.rows - cutbottom - cuttop;
bitmap_size = ((width * height + 7) / 8);
glyph_info = xmalloc (sizeof (struct grub_glyph_info) + bitmap_size);
glyph_info = xmalloc (sizeof (struct grub_glyph_info));
glyph_info->bitmap = xmalloc (bitmap_size);
glyph_info->bitmap_size = bitmap_size;
glyph_info->next = *p_glyph;
*p_glyph = glyph_info;
glyph_info->next = font_info->glyphs_unsorted;
font_info->glyphs_unsorted = glyph_info;
font_info->num_glyphs++;
glyph_info->char_code = char_code;
glyph_info->width = width;
glyph_info->height = height;
glyph_info->x_ofs = glyph->bitmap_left;
glyph_info->y_ofs = glyph->bitmap_top - height;
glyph_info->x_ofs = glyph->bitmap_left + cutleft;
glyph_info->y_ofs = glyph->bitmap_top - height - cuttop;
glyph_info->device_width = glyph->metrics.horiAdvance / 64;
if (width > font_info->max_width)
@ -214,16 +292,388 @@ add_char (struct grub_font_info *font_info, FT_Face face,
mask = 0;
data = &glyph_info->bitmap[0] - 1;
for (j = 0; j < height; j++)
for (i = 0; i < width; i++)
for (j = cuttop; j < height + cuttop; j++)
for (i = cutleft; i < width + cutleft; i++)
add_pixel (&data, &mask,
glyph->bitmap.buffer[i / 8 + j * glyph->bitmap.pitch] &
(1 << (7 - (i & 7))));
}
void
add_font (struct grub_font_info *font_info, FT_Face face)
struct glyph_replace *subst_rightjoin, *subst_leftjoin, *subst_medijoin;
struct glyph_replace
{
struct glyph_replace *next;
grub_uint32_t from, to;
};
/* TODO: sort glyph_replace and use binary search if necessary. */
static void
add_char (struct grub_font_info *font_info, FT_Face face,
grub_uint32_t char_code, int nocut)
{
FT_UInt glyph_idx;
struct glyph_replace *cur;
glyph_idx = FT_Get_Char_Index (face, char_code);
if (!glyph_idx)
return;
add_glyph (font_info, glyph_idx, face, char_code, nocut);
for (cur = subst_rightjoin; cur; cur = cur->next)
if (cur->from == glyph_idx)
{
add_glyph (font_info, cur->to, face,
char_code | GRUB_FONT_CODE_RIGHT_JOINED, nocut);
break;
}
if (!cur && char_code >= GRUB_UNICODE_ARABIC_START
&& char_code < GRUB_UNICODE_ARABIC_END)
{
int i;
for (i = 0; grub_unicode_arabic_shapes[i].code; i++)
if (grub_unicode_arabic_shapes[i].code == char_code
&& grub_unicode_arabic_shapes[i].right_linked)
{
FT_UInt idx2;
idx2 = FT_Get_Char_Index (face, grub_unicode_arabic_shapes[i]
.right_linked);
if (idx2)
add_glyph (font_info, idx2, face,
char_code | GRUB_FONT_CODE_RIGHT_JOINED, nocut);
break;
}
}
for (cur = subst_leftjoin; cur; cur = cur->next)
if (cur->from == glyph_idx)
{
add_glyph (font_info, cur->to, face,
char_code | GRUB_FONT_CODE_LEFT_JOINED, nocut);
break;
}
if (!cur && char_code >= GRUB_UNICODE_ARABIC_START
&& char_code < GRUB_UNICODE_ARABIC_END)
{
int i;
for (i = 0; grub_unicode_arabic_shapes[i].code; i++)
if (grub_unicode_arabic_shapes[i].code == char_code
&& grub_unicode_arabic_shapes[i].left_linked)
{
FT_UInt idx2;
idx2 = FT_Get_Char_Index (face, grub_unicode_arabic_shapes[i]
.left_linked);
if (idx2)
add_glyph (font_info, idx2, face,
char_code | GRUB_FONT_CODE_LEFT_JOINED, nocut);
break;
}
}
for (cur = subst_medijoin; cur; cur = cur->next)
if (cur->from == glyph_idx)
{
add_glyph (font_info, cur->to, face,
char_code | GRUB_FONT_CODE_LEFT_JOINED
| GRUB_FONT_CODE_RIGHT_JOINED, nocut);
break;
}
if (!cur && char_code >= GRUB_UNICODE_ARABIC_START
&& char_code < GRUB_UNICODE_ARABIC_END)
{
int i;
for (i = 0; grub_unicode_arabic_shapes[i].code; i++)
if (grub_unicode_arabic_shapes[i].code == char_code
&& grub_unicode_arabic_shapes[i].both_linked)
{
FT_UInt idx2;
idx2 = FT_Get_Char_Index (face, grub_unicode_arabic_shapes[i]
.both_linked);
if (idx2)
add_glyph (font_info, idx2, face,
char_code | GRUB_FONT_CODE_LEFT_JOINED
| GRUB_FONT_CODE_RIGHT_JOINED, nocut);
break;
}
}
}
struct gsub_header
{
grub_uint32_t version;
grub_uint16_t scripts_off;
grub_uint16_t features_off;
grub_uint16_t lookups_off;
} __attribute__ ((packed));
struct gsub_features
{
grub_uint16_t count;
struct
{
#define FEATURE_FINA 0x66696e61
#define FEATURE_INIT 0x696e6974
#define FEATURE_MEDI 0x6d656469
#define FEATURE_AALT 0x61616c74
#define FEATURE_LIGA 0x6c696761
#define FEATURE_RLIG 0x726c6967
grub_uint32_t feature_tag;
grub_uint16_t offset;
} __attribute__ ((packed)) features[0];
} __attribute__ ((packed));
struct gsub_feature
{
grub_uint16_t params;
grub_uint16_t lookupcount;
grub_uint16_t lookupindices[0];
} __attribute__ ((packed));
struct gsub_lookup_list
{
grub_uint16_t count;
grub_uint16_t offsets[0];
} __attribute__ ((packed));
struct gsub_lookup
{
grub_uint16_t type;
grub_uint16_t flag;
grub_uint16_t subtablecount;
grub_uint16_t subtables[0];
} __attribute__ ((packed));
struct gsub_substitution
{
grub_uint16_t type;
grub_uint16_t coverage_off;
union
{
grub_int16_t delta;
struct
{
grub_int16_t count;
grub_uint16_t repl[0];
};
};
} __attribute__ ((packed));
struct gsub_coverage_list
{
grub_uint16_t type;
grub_uint16_t count;
grub_uint16_t glyphs[0];
} __attribute__ ((packed));
struct gsub_coverage_ranges
{
grub_uint16_t type;
grub_uint16_t count;
struct
{
grub_uint16_t start;
grub_uint16_t end;
grub_uint16_t start_index;
} __attribute__ ((packed)) ranges[0];
} __attribute__ ((packed));
#define GSUB_SINGLE_SUBSTITUTION 1
#define GSUB_SUBSTITUTION_DELTA 1
#define GSUB_SUBSTITUTION_MAP 2
#define GSUB_COVERAGE_LIST 1
#define GSUB_COVERAGE_RANGE 2
#define GSUB_RTL_CHAR 1
static void
add_subst (grub_uint32_t from, grub_uint32_t to, struct glyph_replace **target)
{
struct glyph_replace *new = xmalloc (sizeof (*new));
new->next = *target;
new->from = from;
new->to = to;
*target = new;
}
static void
process_cursive (struct gsub_feature *feature,
struct gsub_lookup_list *lookups,
grub_uint32_t feattag)
{
int j, k;
int i;
struct glyph_replace **target;
struct gsub_substitution *sub;
auto inline void subst (grub_uint32_t glyph);
void subst (grub_uint32_t glyph)
{
grub_uint16_t substtype;
substtype = grub_be_to_cpu16 (sub->type);
if (substtype == GSUB_SUBSTITUTION_DELTA)
add_subst (glyph, glyph + grub_be_to_cpu16 (sub->delta), target);
else if (i >= grub_be_to_cpu16 (sub->count))
printf ("Out of range substitution (%d, %d)\n", i,
grub_be_to_cpu16 (sub->count));
else
add_subst (glyph, grub_be_to_cpu16 (sub->repl[i++]), target);
}
for (j = 0; j < grub_be_to_cpu16 (feature->lookupcount); j++)
{
int lookup_index = grub_be_to_cpu16 (feature->lookupindices[j]);
struct gsub_lookup *lookup;
if (lookup_index >= grub_be_to_cpu16 (lookups->count))
{
printf ("Out of range lookup: %d\n", lookup_index);
continue;
}
lookup = (struct gsub_lookup *)
((grub_uint8_t *) lookups
+ grub_be_to_cpu16 (lookups->offsets[lookup_index]));
if (grub_be_to_cpu16 (lookup->type) != GSUB_SINGLE_SUBSTITUTION)
{
printf ("Unsupported substitution type: %d\n",
grub_be_to_cpu16 (lookup->type));
continue;
}
if (grub_be_to_cpu16 (lookup->flag) & ~GSUB_RTL_CHAR)
{
printf ("Unsupported substitution flag: 0x%x\n",
grub_be_to_cpu16 (lookup->flag));
}
switch (feattag)
{
case FEATURE_INIT:
if (grub_be_to_cpu16 (lookup->flag) & GSUB_RTL_CHAR)
target = &subst_leftjoin;
else
target = &subst_rightjoin;
break;
case FEATURE_FINA:
if (grub_be_to_cpu16 (lookup->flag) & GSUB_RTL_CHAR)
target = &subst_rightjoin;
else
target = &subst_leftjoin;
break;
case FEATURE_MEDI:
target = &subst_medijoin;
break;
}
for (k = 0; k < grub_be_to_cpu16 (lookup->subtablecount); k++)
{
sub = (struct gsub_substitution *)
((grub_uint8_t *) lookup + grub_be_to_cpu16 (lookup->subtables[k]));
grub_uint16_t substtype;
substtype = grub_be_to_cpu16 (sub->type);
if (substtype != GSUB_SUBSTITUTION_MAP
&& substtype != GSUB_SUBSTITUTION_DELTA)
{
printf ("Unsupported substitution specification: %d\n",
substtype);
continue;
}
void *coverage = (grub_uint8_t *) sub
+ grub_be_to_cpu16 (sub->coverage_off);
grub_uint32_t covertype;
covertype = grub_be_to_cpu16 (*(grub_uint16_t * __attribute__ ((packed))) coverage);
i = 0;
if (covertype == GSUB_COVERAGE_LIST)
{
struct gsub_coverage_list *cover = coverage;
int l;
for (l = 0; l < grub_be_to_cpu16 (cover->count); l++)
subst (grub_be_to_cpu16 (cover->glyphs[l]));
}
else if (covertype == GSUB_COVERAGE_RANGE)
{
struct gsub_coverage_ranges *cover = coverage;
int l, m;
for (l = 0; l < grub_be_to_cpu16 (cover->count); l++)
for (m = grub_be_to_cpu16 (cover->ranges[l].start);
m <= grub_be_to_cpu16 (cover->ranges[l].end); m++)
subst (m);
}
else
printf ("Unsupported coverage specification: %d\n", covertype);
}
}
}
void
add_font (struct grub_font_info *font_info, FT_Face face, int nocut)
{
struct gsub_header *gsub = NULL;
FT_ULong gsub_len = 0;
if (!FT_Load_Sfnt_Table (face, TTAG_GSUB, 0, NULL, &gsub_len))
{
gsub = xmalloc (gsub_len);
if (FT_Load_Sfnt_Table (face, TTAG_GSUB, 0, (void *) gsub, &gsub_len))
{
free (gsub);
gsub = NULL;
gsub_len = 0;
}
}
if (gsub)
{
struct gsub_features *features
= (struct gsub_features *) (((grub_uint8_t *) gsub)
+ grub_be_to_cpu16 (gsub->features_off));
struct gsub_lookup_list *lookups
= (struct gsub_lookup_list *) (((grub_uint8_t *) gsub)
+ grub_be_to_cpu16 (gsub->lookups_off));
int i;
int nfeatures = grub_be_to_cpu16 (features->count);
for (i = 0; i < nfeatures; i++)
{
struct gsub_feature *feature = (struct gsub_feature *)
((grub_uint8_t *) features
+ grub_be_to_cpu16 (features->features[i].offset));
grub_uint32_t feattag
= grub_be_to_cpu32 (features->features[i].feature_tag);
if (feature->params)
printf ("WARNING: unsupported feature parameters: %x\n",
grub_be_to_cpu16 (feature->params));
switch (feattag)
{
/* Used for retrieving all possible variants. Useless in grub. */
case FEATURE_AALT:
break;
/* FIXME: Add ligature support. */
case FEATURE_LIGA:
case FEATURE_RLIG:
break;
/* Cursive form variants. */
case FEATURE_FINA:
case FEATURE_INIT:
case FEATURE_MEDI:
process_cursive (feature, lookups, feattag);
break;
default:
{
char str[5];
int j;
memcpy (str, &features->features[i].feature_tag,
sizeof (features->features[i].feature_tag));
str[4] = 0;
for (j = 0; j < 4; j++)
if (!grub_isgraph (str[j]))
str[j] = '?';
printf ("Unknown gsub feature 0x%x (%s)\n", feattag, str);
}
}
}
}
if (font_info->num_range)
{
int i;
@ -232,7 +682,7 @@ add_font (struct grub_font_info *font_info, FT_Face face)
for (i = 0; i < font_info->num_range; i++)
for (j = font_info->ranges[i * 2]; j <= font_info->ranges[i * 2 + 1];
j++)
add_char (font_info, face, j);
add_char (font_info, face, j, nocut);
}
else
{
@ -241,7 +691,7 @@ add_font (struct grub_font_info *font_info, FT_Face face)
for (char_code = FT_Get_First_Char (face, &glyph_index);
glyph_index;
char_code = FT_Get_Next_Char (face, char_code, &glyph_index))
add_char (font_info, face, char_code);
add_char (font_info, face, char_code, nocut);
}
}
@ -281,7 +731,8 @@ print_glyphs (struct grub_font_info *font_info)
struct grub_glyph_info *glyph;
char line[512];
for (glyph = font_info->glyph, num = 0; glyph; glyph = glyph->next, num++)
for (glyph = font_info->glyphs_sorted, num = 0; num < font_info->num_glyphs;
glyph++, num++)
{
int x, y, xmax, xmin, ymax, ymin;
grub_uint8_t *bitmap, mask;
@ -357,7 +808,8 @@ write_font_ascii_bitmap (struct grub_font_info *font_info, char *output_file)
grub_util_error ("Can\'t write to file %s.", output_file);
int correct_size;
for (glyph = font_info->glyph, num = 0; glyph; glyph = glyph->next, num++)
for (glyph = font_info->glyphs_sorted, num = 0; num < font_info->num_glyphs;
glyph++, num++)
{
correct_size = 1;
if (glyph->width != 8 || glyph->height != 16)
@ -377,14 +829,38 @@ write_font_ascii_bitmap (struct grub_font_info *font_info, char *output_file)
fclose (file);
}
void
write_font_width_spec (struct grub_font_info *font_info, char *output_file)
{
FILE *file;
struct grub_glyph_info *glyph;
grub_uint8_t *out;
out = xmalloc (8192);
memset (out, 0, 8192);
file = fopen (output_file, "wb");
if (! file)
grub_util_error ("Can\'t write to file %s.", output_file);
for (glyph = font_info->glyphs_sorted;
glyph < font_info->glyphs_sorted + font_info->num_glyphs; glyph++)
if (glyph->width > 12)
out[glyph->char_code >> 3] |= (1 << (glyph->char_code & 7));
fwrite (out, 8192, 1, file);
fclose (file);
free (out);
}
void
write_font_pf2 (struct grub_font_info *font_info, char *output_file)
{
FILE *file;
grub_uint32_t leng, data;
char style_name[20], *font_name;
struct grub_glyph_info *cur, *pre;
int num, offset;
int offset;
struct grub_glyph_info *cur;
file = fopen (output_file, "wb");
if (! file)
@ -468,33 +944,18 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file)
printf ("Font descent: %d\n", font_info->desc);
}
num = 0;
pre = 0;
cur = font_info->glyph;
while (cur)
{
struct grub_glyph_info *nxt;
nxt = cur->next;
cur->next = pre;
pre = cur;
cur = nxt;
num++;
}
font_info->glyph = pre;
if (font_verbosity > 0)
printf ("Number of glyph: %d\n", num);
printf ("Number of glyph: %d\n", font_info->num_glyphs);
leng = grub_cpu_to_be32 (num * 9);
leng = grub_cpu_to_be32 (font_info->num_glyphs * 9);
grub_util_write_image (FONT_FORMAT_SECTION_NAMES_CHAR_INDEX,
sizeof(FONT_FORMAT_SECTION_NAMES_CHAR_INDEX) - 1,
file);
grub_util_write_image ((char *) &leng, 4, file);
offset += 8 + num * 9 + 8;
offset += 8 + font_info->num_glyphs * 9 + 8;
for (cur = font_info->glyph; cur; cur = cur->next)
for (cur = font_info->glyphs_sorted;
cur < font_info->glyphs_sorted + font_info->num_glyphs; cur++)
{
data = grub_cpu_to_be32 (cur->char_code);
grub_util_write_image ((char *) &data, 4, file);
@ -510,7 +971,8 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file)
sizeof(FONT_FORMAT_SECTION_NAMES_DATA) - 1, file);
grub_util_write_image ((char *) &leng, 4, file);
for (cur = font_info->glyph; cur; cur = cur->next)
for (cur = font_info->glyphs_sorted;
cur < font_info->glyphs_sorted + font_info->num_glyphs; cur++)
{
data = grub_cpu_to_be16 (cur->width);
grub_util_write_image ((char *) &data, 2, file);
@ -645,6 +1107,10 @@ main (int argc, char *argv[])
file_format = ASCII_BITMAPS;
break;
case 0x103:
file_format = WIDTH_SPEC;
break;
default:
usage (1);
break;
@ -703,16 +1169,56 @@ main (int argc, char *argv[])
font_info.size = size;
FT_Set_Pixel_Sizes (ft_face, size, size);
add_font (&font_info, ft_face);
add_font (&font_info, ft_face, file_format != PF2);
FT_Done_Face (ft_face);
}
FT_Done_FreeType (ft_lib);
if (file_format == PF2)
write_font_pf2 (&font_info, output_file);
else if (file_format == ASCII_BITMAPS)
write_font_ascii_bitmap (&font_info, output_file);
{
int counter[65537];
struct grub_glyph_info *tmp, *cur;
int i;
memset (counter, 0, sizeof (counter));
for (cur = font_info.glyphs_unsorted; cur; cur = cur->next)
counter[(cur->char_code & 0xffff) + 1]++;
for (i = 0; i < 0x10000; i++)
counter[i+1] += counter[i];
tmp = xmalloc (font_info.num_glyphs
* sizeof (tmp[0]));
for (cur = font_info.glyphs_unsorted; cur; cur = cur->next)
tmp[counter[(cur->char_code & 0xffff)]++] = *cur;
memset (counter, 0, sizeof (counter));
for (cur = tmp; cur < tmp + font_info.num_glyphs; cur++)
counter[((cur->char_code & 0xffff0000) >> 16) + 1]++;
for (i = 0; i < 0x10000; i++)
counter[i+1] += counter[i];
font_info.glyphs_sorted = xmalloc (font_info.num_glyphs
* sizeof (font_info.glyphs_sorted[0]));
for (cur = tmp; cur < tmp + font_info.num_glyphs; cur++)
font_info.glyphs_sorted[counter[(cur->char_code & 0xffff0000) >> 16]++]
= *cur;
free (tmp);
}
switch (file_format)
{
case PF2:
write_font_pf2 (&font_info, output_file);
break;
case ASCII_BITMAPS:
write_font_ascii_bitmap (&font_info, output_file);
break;
case WIDTH_SPEC:
write_font_width_spec (&font_info, output_file);
break;
}
if (font_verbosity > 1)
print_glyphs (&font_info);

View file

@ -53,7 +53,7 @@ struct image_target_desc
enum {
IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT,
IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275,
IMAGE_YEELOONG_ELF, IMAGE_QEMU, IMAGE_PPC
IMAGE_YEELOONG_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH
} id;
enum
{
@ -223,6 +223,26 @@ struct image_target_desc image_targets[] =
.install_dos_part = TARGET_NO_FIELD,
.install_bsd_part = TARGET_NO_FIELD,
},
{
.name = "mipsel-yeeloong-flash",
.voidp_sizeof = 4,
.bigendian = 0,
.id = IMAGE_YEELOONG_FLASH,
.flags = PLATFORM_FLAGS_NONE,
.prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX,
.data_end = GRUB_KERNEL_MIPS_YEELOONG_DATA_END,
.raw_size = GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE,
.total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE,
.compressed_size = GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE,
.kernel_image_size = GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = TARGET_NO_FIELD,
.install_bsd_part = TARGET_NO_FIELD,
.link_addr = GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR,
.elf_target = EM_MIPS,
.link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN
},
{
.name = "mipsel-yeeloong-elf",
.voidp_sizeof = 4,
@ -984,6 +1004,34 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
free (boot_path);
}
break;
case IMAGE_YEELOONG_FLASH:
{
char *rom_img;
size_t rom_size;
char *boot_path, *boot_img;
size_t boot_size;
boot_path = grub_util_get_path (dir, "fwstart.img");
boot_size = grub_util_get_image_size (boot_path);
boot_img = grub_util_read_image (boot_path);
rom_size = ALIGN_UP (core_size + boot_size, 512 * 1024);
rom_img = xmalloc (rom_size);
memset (rom_img, 0, rom_size);
memcpy (rom_img, boot_img, boot_size);
memcpy (rom_img + boot_size, core_img, core_size);
memset (rom_img + boot_size + core_size, 0,
rom_size - (boot_size + core_size));
free (core_img);
core_img = rom_img;
core_size = rom_size;
}
break;
case IMAGE_YEELOONG_ELF:
case IMAGE_PPC:
case IMAGE_COREBOOT:

View file

@ -1,4 +1,5 @@
#! /bin/sh -e
#! /bin/sh
set -e
# Make GRUB rescue image
# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
@ -42,6 +43,8 @@ rom_directory=
override_dir=
grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
xorriso=xorriso
# Usage: usage
# Print the usage.
usage () {
@ -51,19 +54,38 @@ Make GRUB rescue image.
-h, --help print this message and exit
-v, --version print the version information and exit
--output=FILE save output in FILE [required]
-o, --output=FILE save output in FILE [required]
--modules=MODULES pre-load specified modules MODULES
--rom-directory=DIR save rom images in DIR [optional]
--xorriso=FILE use FILE as xorriso [optional]
--grub-mkimage=FILE use FILE as grub-mkimage
$self generates a bootable rescue image with specified source files or directories.
$self generates a bootable rescue image with specified source files, source
directories, or mkisofs options listed by: xorriso -as mkisofs -help
Option -- switches to native xorriso command mode. or directories.
Report bugs to <bug-grub@gnu.org>.
Mail xorriso support requests to <bug-xorriso@gnu.org>.
EOF
}
argument () {
opt=$1
shift
if test $# -eq 0; then
echo "$0: option requires an argument -- '$opt'" 1>&2
exit 1
fi
echo $1
}
# Check the arguments.
for option in "$@"; do
while test $# -gt 0
do
option=$1
shift
case "$option" in
-h | --help)
usage
@ -71,27 +93,47 @@ for option in "$@"; do
-v | --version)
echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
exit 0 ;;
--modules)
modules=`argument $option "$@"`; shift ;;
--modules=*)
modules=`echo "$option" | sed 's/--modules=//'` ;;
-o | --output)
output_image=`argument $option "$@"`; shift ;;
--output=*)
output_image=`echo "$option" | sed 's/--output=//'` ;;
--rom-directory)
rom_directory=`argument $option "$@"`; shift ;;
--rom-directory=*)
rom_directory=`echo "$option" | sed 's/--rom-directory=//'` ;;
# Intentionally undocumented
--override-directory)
override_dir=`argument $option "$@"`
shift
PATH=${override_dir}:$PATH
export PATH
;;
--override-directory=*)
override_dir=`echo "${option}/" | sed 's/--override-directory=//'`
PATH=${override_dir}:$PATH
export PATH
;;
--grub-mkimage)
grub_mkimage=`argument $option "$@"`; shift ;;
--grub-mkimage=*)
grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;;
-*)
echo "Unrecognized option \`$option'" 1>&2
usage
exit 1
;;
--xorriso)
xorriso=`argument $option "$@"`; shift ;;
--xorriso=*)
xorriso=`echo "${option}/" | sed 's/--xorriso=//'` ;;
*)
source="${source} ${option}" ;;
source="${source} ${option} $@"; break ;;
esac
done
@ -158,22 +200,21 @@ make_image ()
memdisk_dir=`mktemp -d "$MKTEMP_TEMPLATE"`
mkdir -p ${memdisk_dir}/boot/grub
modules="$(cat ${source_directory}/partmap.lst) ${modules}"
cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg
search --fs-uuid --set ${iso_uuid}
set prefix=(\${root})/boot/grub/${platform}
source \$prefix/grub.cfg
EOF
(for i in ${modules} ; do
(for i in $(cat ${source_directory}/partmap.lst) ${modules} ; do
echo "insmod $i"
done ; \
echo "source /boot/grub/grub.cfg") \
> ${iso9660_dir}/boot/grub/${platform}/grub.cfg
tar -C ${memdisk_dir} -cf ${memdisk_img} boot
(cd "${memdisk_dir}"; tar -cf - boot) > "${memdisk_img}"
rm -rf ${memdisk_dir}
$grub_mkimage -O ${platform} -d "${source_directory}" -m "${memdisk_img}" -o "$3" --prefix='(memdisk)/boot/grub' \
search iso9660 configfile normal sh memdisk tar $4
search iso9660 configfile normal memdisk tar $4
rm -rf ${memdisk_img}
}
@ -231,8 +272,7 @@ if test -e "${pc_dir}" ; then
rm -f ${core_img}
modules="$(cat ${pc_dir}/partmap.lst) ${modules}"
(for i in ${modules} ; do
(for i in $(cat ${pc_dir}/partmap.lst) ${modules} ; do
echo "insmod $i"
done ; \
echo "source /boot/grub/grub.cfg") \
@ -269,7 +309,7 @@ if [ -e "${iso9660_dir}/boot/coreboot.elf" ] && [ -d "${rom_directory}" ]; then
fi
# build iso image
xorriso -pathspecs on -as mkisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source}
"${xorriso}" -as mkisofs -graft-points ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} --sort-weight 0 / --sort-weight 1 /boot ${source}
rm -rf ${iso9660_dir}
rm -f ${embed_img}

View file

@ -59,12 +59,14 @@ enum {
int print = PRINT_FS;
static unsigned int argument_is_device = 0;
void
grub_putchar (int c)
void
grub_xputs_real (const char *str)
{
putchar (c);
fputs (str, stdout);
}
void (*grub_xputs) (const char *str) = grub_xputs_real;
int
grub_getkey (void)
{

View file

@ -48,8 +48,23 @@ Report bugs to <bug-grub@gnu.org>.
EOF
}
argument () {
opt=$1
shift
if test $# -eq 0; then
echo "$0: option requires an argument -- '$opt'" 1>&2
exit 1
fi
echo $1
}
# Check the arguments.
for option in "$@"; do
while test $# -gt 0
do
option=$1
shift
case "$option" in
-h | --help)
usage
@ -57,8 +72,12 @@ for option in "$@"; do
-v | --version)
echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
exit 0 ;;
--root-directory)
rootdir=`argument $option "$@"`; shift ;;
--root-directory=*)
rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
-*)
echo "Unrecognized option \`$option'" 1>&2
usage

View file

@ -37,12 +37,14 @@
#include "progname.h"
void
grub_putchar (int c)
void
grub_xputs_real (const char *str)
{
putchar (c);
fputs (str, stdout);
}
void (*grub_xputs) (const char *str) = grub_xputs_real;
int
grub_getkey (void)
{

View file

@ -48,8 +48,23 @@ Report bugs to <bug-grub@gnu.org>.
EOF
}
argument () {
opt=$1
shift
if test $# -eq 0; then
echo "$0: option requires an argument -- '$opt'" 1>&2
exit 1
fi
echo $1
}
# Check the arguments.
for option in "$@"; do
while test $# -gt 0
do
option=$1
shift
case "$option" in
-h | --help)
usage
@ -57,8 +72,12 @@ for option in "$@"; do
-v | --version)
echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
exit 0 ;;
--root-directory)
rootdir=`argument $option "$@"`; shift ;;
--root-directory=*)
rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
-*)
echo "Unrecognized option \`$option'" 1>&2
usage

View file

@ -1,4 +1,5 @@
#! /bin/sh -e
#! /bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
@ -21,8 +22,7 @@ transform="@program_transform_name@"
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
grub_prefix=`echo /boot/grub | sed ${transform}`
locale_dir=`echo /boot/grub/locale | sed ${transform}`
locale_dir=`echo ${GRUB_PREFIX}/locale | sed ${transform}`
grub_lang=`echo $LANG | cut -d _ -f 1`
. ${libdir}/grub/grub-mkconfig_lib
@ -75,6 +75,24 @@ function savedefault {
save_env saved_entry
fi
}
function load_video {
EOF
if [ -n "${GRUB_VIDEO_BACKEND}" ]; then
cat <<EOF
insmod ${GRUB_VIDEO_BACKEND}
EOF
else
# Insert all available backends; GRUB will use the most appropriate.
for backend in $(cat "${GRUB_PREFIX}/video.lst"); do
cat <<EOF
insmod ${backend}
EOF
done
fi
cat <<EOF
}
EOF
serial=0;
@ -89,7 +107,7 @@ for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do
done
if [ "x$serial" = x1 ]; then
if ! test -e ${grub_prefix}/serial.mod ; then
if ! test -e ${GRUB_PREFIX}/serial.mod ; then
echo "Serial terminal not available on this platform." >&2 ; exit 1
fi
@ -107,59 +125,8 @@ if [ "x$gfxterm" = x1 ]; then
cat << EOF
if loadfont `make_system_path_relative_to_its_root "${GRUB_FONT_PATH}"` ; then
set gfxmode=${GRUB_GFXMODE}
load_video
insmod gfxterm
insmod ${GRUB_VIDEO_BACKEND}
EOF
if [ "x$GRUB_THEME" != x ] && [ -f "$GRUB_THEME" ] \
&& is_path_readable_by_grub "$GRUB_THEME"; then
echo "Found theme: $GRUB_THEME" >&2
prepare_grub_to_access_device `${grub_probe} --target=device "$GRUB_THEME"` | sed -e "s/^/ /"
cat << EOF
insmod gfxmenu
EOF
themedir="`dirname "$GRUB_THEME"`"
for x in "$themedir"/*.pf2 "$themedir"/f/*.pf2; do
if [ -f "$x" ]; then
cat << EOF
loadfont (\$root)`make_system_path_relative_to_its_root $x`
EOF
fi
done
if [ x"`echo "$themedir"/*.jpg`" != x"$themedir/*.jpg" ] || [ x"`echo "$themedir"/*.jpeg`" != x"$themedir/*.jpeg" ]; then
cat << EOF
insmod jpeg
EOF
fi
if [ x"`echo "$themedir"/*.png`" != x"$themedir/*.png" ]; then
cat << EOF
insmod png
EOF
fi
if [ x"`echo "$themedir"/*.tga`" != x"$themedir/*.tga" ]; then
cat << EOF
insmod tga
EOF
fi
cat << EOF
set theme=(\$root)`make_system_path_relative_to_its_root $GRUB_THEME`
EOF
elif [ "x$GRUB_BACKGROUND" != x ] && [ -f "$GRUB_BACKGROUND" ] \
&& is_path_readable_by_grub "$GRUB_BACKGROUND"; then
echo "Found background: $GRUB_BACKGROUND" >&2
case "$GRUB_BACKGROUND" in
*.png) reader=png ;;
*.tga) reader=tga ;;
*.jpg|*.jpeg) reader=jpeg ;;
*) echo "Unsupported image format" >&2; exit 1 ;;
esac
prepare_grub_to_access_device `${grub_probe} --target=device "$GRUB_BACKGROUND"` | sed -e "s/^/ /"
cat << EOF
insmod $reader
background_image -m stretch `make_system_path_relative_to_its_root "$GRUB_BACKGROUND"`
EOF
fi
cat << EOF
fi
EOF
fi
@ -194,6 +161,58 @@ EOF
;;
esac
if [ "x$gfxterm" = x1 ]; then
if [ "x$GRUB_THEME" != x ] && [ -f "$GRUB_THEME" ] \
&& is_path_readable_by_grub "$GRUB_THEME"; then
echo "Found theme: $GRUB_THEME" >&2
prepare_grub_to_access_device `${grub_probe} --target=device "$GRUB_THEME"`
cat << EOF
insmod gfxmenu
EOF
themedir="`dirname "$GRUB_THEME"`"
for x in "$themedir"/*.pf2 "$themedir"/f/*.pf2; do
if [ -f "$x" ]; then
cat << EOF
loadfont (\$root)`make_system_path_relative_to_its_root $x`
EOF
fi
done
if [ x"`echo "$themedir"/*.jpg`" != x"$themedir/*.jpg" ] || [ x"`echo "$themedir"/*.jpeg`" != x"$themedir/*.jpeg" ]; then
cat << EOF
insmod jpeg
EOF
fi
if [ x"`echo "$themedir"/*.png`" != x"$themedir/*.png" ]; then
cat << EOF
insmod png
EOF
fi
if [ x"`echo "$themedir"/*.tga`" != x"$themedir/*.tga" ]; then
cat << EOF
insmod tga
EOF
fi
cat << EOF
set theme=(\$root)`make_system_path_relative_to_its_root $GRUB_THEME`
EOF
elif [ "x$GRUB_BACKGROUND" != x ] && [ -f "$GRUB_BACKGROUND" ] \
&& is_path_readable_by_grub "$GRUB_BACKGROUND"; then
echo "Found background: $GRUB_BACKGROUND" >&2
case "$GRUB_BACKGROUND" in
*.png) reader=png ;;
*.tga) reader=tga ;;
*.jpg|*.jpeg) reader=jpeg ;;
*) echo "Unsupported image format" >&2; exit 1 ;;
esac
prepare_grub_to_access_device `${grub_probe} --target=device "$GRUB_BACKGROUND"`
cat << EOF
insmod $reader
background_image -m stretch `make_system_path_relative_to_its_root "$GRUB_BACKGROUND"`
EOF
fi
fi
# Gettext variables and module
if [ "x${LANG}" != "xC" ] && [ -d "${locale_dir}" ] ; then
prepare_grub_to_access_device $(${grub_probe} --target=device ${locale_dir})
@ -238,8 +257,9 @@ fi
# Play an initial tune
if [ "x${GRUB_INIT_TUNE}" != "x" ] ; then
cat << EOF
insmod play
play ${GRUB_INIT_TUNE}
EOF
echo "play ${GRUB_INIT_TUNE}"
fi
if [ "x${GRUB_BADRAM}" != "x" ] ; then
echo "badram ${GRUB_BADRAM}"
fi

View file

@ -1,4 +1,5 @@
#! /bin/sh -e
#! /bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.

View file

@ -1,4 +1,5 @@
#! /bin/sh -e
#! /bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.

View file

@ -1,4 +1,5 @@
#! /bin/sh -e
#! /bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
@ -43,7 +44,8 @@ case ${GRUB_DEVICE} in
esac
if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
|| ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" ; then
|| ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
|| uses_abstraction "${GRUB_DEVICE}" lvm; then
LINUX_ROOT_DEVICE=${GRUB_DEVICE}
else
LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
@ -66,6 +68,9 @@ linux_entry ()
# Use ELILO's generic "efifb" when it's known to be available.
# FIXME: We need an interface to select vesafb in case efifb can't be used.
if [ "x$GRUB_GFXPAYLOAD_LINUX" = x ]; then
cat << EOF
load_video
EOF
if grep -qx "CONFIG_FB_EFI=y" /boot/config-${version} 2> /dev/null \
&& grep -qx "CONFIG_VT_HW_CONSOLE_BINDING=y" /boot/config-${version} 2> /dev/null; then
cat << EOF
@ -114,8 +119,9 @@ while [ "x$list" != "x" ] ; do
initrd=
for i in "initrd.img-${version}" "initrd-${version}.img" \
"initrd-${version}" "initrd.img-${alt_version}" \
"initrd-${alt_version}.img" "initrd-${alt_version}"; do
"initrd-${version}" "initramfs-${version}.img" \
"initrd.img-${alt_version}" "initrd-${alt_version}.img" \
"initrd-${alt_version}" "initramfs-${alt_version}.img"; do
if test -e "${dirname}/${i}" ; then
initrd="$i"
break

View file

@ -1,4 +1,5 @@
#! /bin/sh -e
#! /bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.

View file

@ -1,4 +1,5 @@
#! /bin/sh -e
#! /bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2008,2009,2010 Free Software Foundation, Inc.

142
util/grub.d/20_linux_xen.in Normal file
View file

@ -0,0 +1,142 @@
#! /bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
prefix=@prefix@
exec_prefix=@exec_prefix@
bindir=@bindir@
libdir=@libdir@
. ${libdir}/grub/grub-mkconfig_lib
export TEXTDOMAIN=@PACKAGE@
export TEXTDOMAINDIR=@localedir@
CLASS="--class gnu-linux --class gnu --class os --class xen"
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
OS=GNU/Linux
else
OS="${GRUB_DISTRIBUTOR} GNU/Linux"
CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]' | cut -d' ' -f1) ${CLASS}"
fi
# loop-AES arranges things so that /dev/loop/X can be our root device, but
# the initrds that Linux uses don't like that.
case ${GRUB_DEVICE} in
/dev/loop/*|/dev/loop[0-9])
GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"`
;;
esac
if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
|| ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" ; then
LINUX_ROOT_DEVICE=${GRUB_DEVICE}
else
LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
fi
linux_entry ()
{
os="$1"
version="$2"
xen_version="$3"
recovery="$4"
args="$5"
xen_args="$6"
if ${recovery} ; then
title="$(gettext_quoted "%s, with Linux %s and XEN %s (recovery mode)")"
else
title="$(gettext_quoted "%s, with Linux %s and XEN %s")"
fi
printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}" "${xen_version}"
save_default_entry | sed -e "s/^/\t/"
if [ -z "${prepare_boot_cache}" ]; then
prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")"
fi
printf '%s\n' "${prepare_boot_cache}"
cat << EOF
echo '$(printf "$(gettext_quoted "Loading Linux %s ...")" ${version})'
multiboot ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args}
module ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args}
EOF
if test -n "${initrd}" ; then
cat << EOF
echo '$(gettext_quoted "Loading initial ramdisk ...")'
module ${rel_dirname}/${initrd}
EOF
fi
cat << EOF
}
EOF
}
linux_list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do
basename=$(basename $i)
version=$(echo $basename | sed -e "s,^[^0-9]*-,,g")
if grub_file_is_not_garbage "$i" && grep -qx "CONFIG_XEN_DOM0=y" /boot/config-${version} 2> /dev/null ; then echo -n "$i " ; fi
done`
xen_list=`for i in /boot/xen*; do
if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
done`
prepare_boot_cache=
while [ "x${xen_list}" != "x" ] ; do
list="${linux_list}"
current_xen=`version_find_latest $xen_list`
xen_basename=`basename ${current_xen}`
xen_dirname=`dirname ${current_xen}`
rel_xen_dirname=`make_system_path_relative_to_its_root $xen_dirname`
xen_version=`echo $xen_basename | sed -e "s,.gz$,,g;s,^xen-,,g"`
while [ "x$list" != "x" ] ; do
linux=`version_find_latest $list`
echo "Found linux image: $linux" >&2
basename=`basename $linux`
dirname=`dirname $linux`
rel_dirname=`make_system_path_relative_to_its_root $dirname`
version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
alt_version=`echo $version | sed -e "s,\.old$,,g"`
linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
initrd=
for i in "initrd.img-${version}" "initrd-${version}.img" \
"initrd-${version}" "initrd.img-${alt_version}" \
"initrd-${alt_version}.img" "initrd-${alt_version}"; do
if test -e "${dirname}/${i}" ; then
initrd="$i"
break
fi
done
if test -n "${initrd}" ; then
echo "Found initrd image: ${dirname}/${initrd}" >&2
else
# "UUID=" magic is parsed by initrds. Since there's no initrd, it can't work here.
linux_root_device_thisversion=${GRUB_DEVICE}
fi
linux_entry "${OS}" "${version}" "${xen_version}" false \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" "${GRUB_CMDLINE_XEN} ${GRUB_CMDLINE_XEN_DEFAULT}"
if [ "x${GRUB_DISABLE_LINUX_RECOVERY}" != "xtrue" ]; then
linux_entry "${OS}" "${version}" "${xen_version}" true \
"single ${GRUB_CMDLINE_LINUX}" "${GRUB_CMDLINE_XEN}"
fi
list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '`
done
xen_list=`echo $xen_list | tr ' ' '\n' | grep -vx $current_xen | tr '\n' ' '`
done

View file

@ -1,4 +1,5 @@
#! /bin/sh -e
#! /bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
@ -44,14 +45,14 @@ EOF
save_default_entry | sed -e "s/^/\t/"
prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"
cat << EOF
insmod ${GRUB_VIDEO_BACKEND}
load_video
set do_resume=0
if [ /var/vm/sleepimage -nt10 / ]; then
if xnu_resume /var/vm/sleepimage; then
set do_resume=1
fi
fi
if [ \$do_resume == 0 ]; then
if [ \$do_resume = 0 ]; then
xnu_uuid ${OSXUUID} uuid
if [ -f /Extra/DSDT.aml ]; then
acpi -e /Extra/DSDT.aml

7
util/grub.d/41_custom.in Normal file
View file

@ -0,0 +1,7 @@
#!/bin/sh
cat <<EOF
if [ -f \$prefix/custom.cfg ]; then
source \$prefix/custom.cfg;
fi
EOF

View file

@ -73,8 +73,23 @@ Report bugs to <bug-grub@gnu.org>.
EOF
}
argument () {
opt=$1
shift
if test $# -eq 0; then
echo "$0: option requires an argument -- '$opt'" 1>&2
exit 1
fi
echo $1
}
# Check the arguments.
for option in "$@"; do
while test $# -gt 0
do
option=$1
shift
case "$option" in
-h | --help)
usage
@ -82,16 +97,32 @@ for option in "$@"; do
-v | --version)
echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
exit 0 ;;
--modules)
modules=`argument $option "$@"`; shift ;;
--modules=*)
modules=`echo "$option" | sed 's/--modules=//'` ;;
--root-directory)
rootdir=`argument $option "$@"`; shift ;;
--root-directory=*)
rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
--grub-mkimage)
grub_mkimage=`argument $option "$@"`; shift ;;
--grub-mkimage=*)
grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;;
--grub-mkdevicemap)
grub_mkdevicemap=`argument $option "$@"`; shift ;;
--grub-mkdevicemap=*)
grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;;
--grub-probe)
grub_probe=`argument $option "$@"`; shift ;;
--grub-probe=*)
grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;;
--no-floppy)
no_floppy="--no-floppy" ;;
--recheck)
@ -205,7 +236,7 @@ fi
# this command is allowed to fail (--target=fs already grants us that the
# filesystem will be accessible).
partmap_module=
for x in `$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`; do
for x in `$grub_probe --target=partmap --device-map=${device_map} ${grubdir} 2> /dev/null`; do
partmap_module="$partmap_module part_$x";
done

View file

@ -64,12 +64,14 @@ static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_P
#define grub_host_to_target32(x) grub_cpu_to_le32(x)
#define grub_host_to_target64(x) grub_cpu_to_le64(x)
void
grub_putchar (int c)
void
grub_xputs_real (const char *str)
{
putchar (c);
fputs (str, stdout);
}
void (*grub_xputs) (const char *str) = grub_xputs_real;
int
grub_getkey (void)
{
@ -93,12 +95,15 @@ setup (const char *dir,
grub_uint16_t core_sectors;
grub_device_t root_dev, dest_dev;
const char *dest_partmap;
int multiple_partmaps;
grub_uint8_t *boot_drive;
grub_disk_addr_t *kernel_sector;
grub_uint16_t *boot_drive_check;
struct grub_boot_blocklist *first_block, *block;
grub_int32_t *install_dos_part, *install_bsd_part;
grub_int32_t dos_part, bsd_part;
char *install_prefix;
char *prefix = NULL;
char *tmp_img;
int i;
grub_disk_addr_t first_sector;
@ -230,6 +235,8 @@ setup (const char *dir,
+ GRUB_KERNEL_MACHINE_INSTALL_DOS_PART);
install_bsd_part = (grub_int32_t *) (core_img + GRUB_DISK_SECTOR_SIZE
+ GRUB_KERNEL_MACHINE_INSTALL_BSD_PART);
install_prefix = (char *) (core_img + GRUB_DISK_SECTOR_SIZE +
GRUB_KERNEL_MACHINE_PREFIX);
/* Open the root device and the destination device. */
root_dev = grub_device_open (root);
@ -305,6 +312,16 @@ setup (const char *dir,
dos_part = root_dev->disk->partition->number;
bsd_part = -1;
}
if (install_prefix[0] != '(')
{
char *root_part_name;
root_part_name =
grub_partition_get_name (root_dev->disk->partition);
prefix = xasprintf ("(,%s)%s", root_part_name, install_prefix);
free (root_part_name);
}
}
else
dos_part = bsd_part = -1;
@ -339,10 +356,17 @@ setup (const char *dir,
{
if (p->parent)
return 0;
dest_partmap = p->partmap->name;
return 1;
if (dest_partmap == NULL)
dest_partmap = p->partmap->name;
else if (strcmp (dest_partmap, p->partmap->name) != 0)
{
multiple_partmaps = 1;
return 1;
}
return 0;
}
dest_partmap = 0;
multiple_partmaps = 0;
grub_partition_iterate (dest_dev->disk, identify_partmap);
if (! dest_partmap)
@ -350,6 +374,11 @@ setup (const char *dir,
grub_util_warn (_("Attempting to install GRUB to a partitionless disk. This is a BAD idea."));
goto unable_to_embed;
}
if (multiple_partmaps)
{
grub_util_warn (_("Attempting to install GRUB to a disk with multiple partition labels. This is not supported yet."));
goto unable_to_embed;
}
if (strcmp (dest_partmap, "msdos") == 0)
grub_partition_iterate (dest_dev->disk, find_usable_region_msdos);
@ -381,6 +410,8 @@ setup (const char *dir,
*install_dos_part = grub_cpu_to_le32 (dos_part);
*install_bsd_part = grub_cpu_to_le32 (bsd_part);
if (prefix)
strcpy (install_prefix, prefix);
/* The first blocklist contains the whole sectors. */
first_block->start = grub_cpu_to_le64 (embed_region.start + 1);
@ -541,6 +572,8 @@ unable_to_embed:
*install_dos_part = grub_cpu_to_le32 (dos_part);
*install_bsd_part = grub_cpu_to_le32 (bsd_part);
if (prefix)
strcpy (install_prefix, prefix);
/* Write the first two sectors of the core image onto the disk. */
grub_util_info ("opening the core image `%s'", core_path);
@ -560,6 +593,7 @@ unable_to_embed:
/* Sync is a Good Thing. */
sync ();
free (prefix);
free (core_path);
free (core_img);
free (boot_img);
@ -593,6 +627,8 @@ Usage: %s [OPTION]... DEVICE\n\
\n\
Set up images to boot from DEVICE.\n\
DEVICE must be a GRUB device (e.g. `(hd0,1)').\n\
\n\
You should not normally run %s directly. Use grub-install instead.\n\
\n\
-b, --boot-image=FILE use FILE as the boot image [default=%s]\n\
-c, --core-image=FILE use FILE as the core image [default=%s]\n\
@ -607,7 +643,7 @@ DEVICE must be a GRUB device (e.g. `(hd0,1)').\n\
\n\
Report bugs to <%s>.\n\
"),
program_name,
program_name, program_name,
DEFAULT_BOOT_FILE, DEFAULT_CORE_FILE, DEFAULT_DIRECTORY,
DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT);

View file

@ -76,8 +76,23 @@ Report bugs to <bug-grub@gnu.org>.
EOF
}
argument () {
opt=$1
shift
if test $# -eq 0; then
echo "$0: option requires an argument -- '$opt'" 1>&2
exit 1
fi
echo $1
}
# Check the arguments.
for option in "$@"; do
while test $# -gt 0
do
option=$1
shift
case "$option" in
-h | --help)
usage
@ -85,16 +100,32 @@ for option in "$@"; do
-v | --version)
echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
exit 0 ;;
--modules)
modules=`argument $option "$@"`; shift ;;
--modules=*)
modules=`echo "$option" | sed 's/--modules=//'` ;;
--root-directory)
rootdir=`argument $option "$@"`; shift ;;
--root-directory=*)
rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
--grub-mkdevicemap)
grub_mkdevicemap=`argument $option "$@"`; shift ;;
--grub-mkdevicemap=*)
grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;;
--grub-mkimage)
grub_mkimage=`argument $option "$@"`; shift ;;
--grub-mkimage=*)
grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;;
--grub-probe)
grub_probe=`argument $option "$@"`; shift ;;
--grub-probe=*)
grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;;
--no-nvram)
update_nvram=no ;;
# This is an undocumented feature...

191
util/import_unicode.py Normal file
View file

@ -0,0 +1,191 @@
#*
#* GRUB -- GRand Unified Bootloader
#* Copyright (C) 2010 Free Software Foundation, Inc.
#*
#* GRUB is free software: you can redistribute it and/or modify
#* it under the terms of the GNU General Public License as published by
#* the Free Software Foundation, either version 3 of the License, or
#* (at your option) any later version.
#*
#* GRUB is distributed in the hope that it will be useful,
#* but WITHOUT ANY WARRANTY; without even the implied warranty of
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#* GNU General Public License for more details.
#*
#* You should have received a copy of the GNU General Public License
#* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
#*
import re
import sys
import os
import datetime
if len (sys.argv) < 3:
print ("Usage: %s SOURCE DESTINATION" % sys.argv[0])
exit (0)
infile = open (sys.argv[3], "r")
joining = {}
for line in infile:
line = re.sub ("#.*$", "", line)
line = line.replace ("\n", "")
line = line.replace (" ", "")
if len (line) == 0 or line[0] == '\n':
continue
sp = line.split (";")
curcode = int (sp[0], 16)
if sp[2] == "U":
joining[curcode] = "NONJOINING"
elif sp[2] == "L":
joining[curcode] = "LEFT"
elif sp[2] == "R":
joining[curcode] = "RIGHT"
elif sp[2] == "D":
joining[curcode] = "DUAL"
elif sp[2] == "C":
joining[curcode] = "CAUSING"
else:
print ("Unknown joining type '%s'" % sp[2])
exit (1)
infile.close ()
infile = open (sys.argv[1], "r")
outfile = open (sys.argv[4], "w")
outfile.write ("#include <grub/unicode.h>\n")
outfile.write ("\n")
outfile.write ("struct grub_unicode_compact_range grub_unicode_compact[] = {\n")
begincode = -2
lastcode = -2
lastbiditype = "X"
lastmirrortype = False
lastcombtype = -1
arabicsubst = {}
for line in infile:
sp = line.split (";")
curcode = int (sp[0], 16)
curcombtype = int (sp[3], 10)
curbiditype = sp[4]
curmirrortype = (sp[9] == "Y")
if curcombtype <= 255 and curcombtype >= 253:
print ("UnicodeData.txt uses combination type %d. Conflict." \
% curcombtype)
raise
if sp[2] != "Lu" and sp[2] != "Ll" and sp[2] != "Lt" and sp[2] != "Lm" \
and sp[2] != "Lo"\
and sp[2] != "Me" and sp[2] != "Mc" and sp[2] != "Mn" \
and sp[2] != "Nd" and sp[2] != "Nl" and sp[2] != "No" \
and sp[2] != "Pc" and sp[2] != "Pd" and sp[2] != "Ps" \
and sp[2] != "Pe" and sp[2] != "Pi" and sp[2] != "Pf" \
and sp[2] != "Po" \
and sp[2] != "Sm" and sp[2] != "Sc" and sp[2] != "Sk" \
and sp[2] != "So"\
and sp[2] != "Zs" and sp[2] != "Zl" and sp[2] != "Zp" \
and sp[2] != "Cc" and sp[2] != "Cf" and sp[2] != "Cs" \
and sp[2] != "Co":
print ("WARNING: Unknown type %s" % sp[2])
if curcombtype == 0 and sp[2] == "Me":
curcombtype = 253
if curcombtype == 0 and sp[2] == "Mc":
curcombtype = 254
if curcombtype == 0 and sp[2] == "Mn":
curcombtype = 255
if (curcombtype >= 2 and curcombtype <= 6) \
or (curcombtype >= 37 and curcombtype != 84 and curcombtype != 91 and curcombtype != 103 and curcombtype != 107 and curcombtype != 118 and curcombtype != 122 and curcombtype != 129 and curcombtype != 130 and curcombtype != 132 and curcombtype != 202 and \
curcombtype != 214 and curcombtype != 216 and \
curcombtype != 218 and curcombtype != 220 and \
curcombtype != 222 and curcombtype != 224 and curcombtype != 226 and curcombtype != 228 and \
curcombtype != 230 and curcombtype != 232 and curcombtype != 233 and \
curcombtype != 234 and \
curcombtype != 240 and curcombtype != 253 and \
curcombtype != 254 and curcombtype != 255):
print ("WARNING: Unknown combining type %d" % curcombtype)
if curcode in joining:
curjoin = joining[curcode]
elif sp[2] == "Me" or sp[2] == "Mn" or sp[2] == "Cf":
curjoin = "TRANSPARENT"
else:
curjoin = "NONJOINING"
if sp[1].startswith ("ARABIC LETTER "):
arabname = sp[1][len ("ARABIC LETTER "):]
form = 0
if arabname.endswith (" ISOLATED FORM"):
arabname = arabname[0:len (arabname) - len (" ISOLATED FORM")]
form = 1
if arabname.endswith (" FINAL FORM"):
arabname = arabname[0:len (arabname) - len (" FINAL FORM")]
form = 2
if arabname.endswith (" MEDIAL FORM"):
arabname = arabname[0:len (arabname) - len (" MEDIAL FORM")]
form = 3
if arabname.endswith (" INITIAL FORM"):
arabname = arabname[0:len (arabname) - len (" INITIAL FORM")]
form = 4
if arabname not in arabicsubst:
arabicsubst[arabname]={}
arabicsubst[arabname][form] = curcode;
if form == 0:
arabicsubst[arabname]['join'] = curjoin
if lastcode + 1 != curcode or curbiditype != lastbiditype \
or curcombtype != lastcombtype or curmirrortype != lastmirrortype \
or curjoin != lastjoin:
if begincode != -2 and (lastbiditype != "L" or lastcombtype != 0 or \
lastmirrortype):
outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d, GRUB_JOIN_TYPE_%s},\n" \
% (begincode, lastcode, lastbiditype, \
lastcombtype, lastmirrortype, \
lastjoin)))
begincode = curcode
lastcode = curcode
lastjoin = curjoin
lastbiditype = curbiditype
lastcombtype = curcombtype
lastmirrortype = curmirrortype
if lastbiditype != "L" or lastcombtype != 0 or lastmirrortype:
outfile.write (("{0x%x, 0x%x, GRUB_BIDI_TYPE_%s, %d, %d, GRUB_JOIN_TYPE_%s},\n" \
% (begincode, lastcode, lastbiditype, lastcombtype, \
lastmirrortype, lastjoin)))
outfile.write ("{0, 0, 0, 0, 0, 0},\n")
outfile.write ("};\n")
infile.close ()
infile = open (sys.argv[2], "r")
outfile.write ("struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[] = {\n")
for line in infile:
line = re.sub ("#.*$", "", line)
line = line.replace ("\n", "")
line = line.replace (" ", "")
if len (line) == 0 or line[0] == '\n':
continue
sp = line.split (";")
code1 = int (sp[0], 16)
code2 = int (sp[1], 16)
outfile.write ("{0x%x, 0x%x},\n" % (code1, code2))
outfile.write ("{0, 0},\n")
outfile.write ("};\n")
infile.close ()
outfile.write ("struct grub_unicode_arabic_shape grub_unicode_arabic_shapes[] = {\n ")
for x in arabicsubst:
try:
if arabicsubst[x]['join'] == "DUAL":
outfile.write ("{0x%x, 0x%x, 0x%x, 0x%x, 0x%x},\n " % (arabicsubst[x][0], arabicsubst[x][1], arabicsubst[x][2], arabicsubst[x][3], arabicsubst[x][4]))
elif arabicsubst[x]['join'] == "RIGHT":
outfile.write ("{0x%x, 0x%x, 0x%x, 0x%x, 0x%x},\n " % (arabicsubst[x][0], arabicsubst[x][1], arabicsubst[x][2], 0, 0))
elif arabicsubst[x]['join'] == "LEFT":
outfile.write ("{0x%x, 0x%x, 0x%x, 0x%x, 0x%x},\n " % (arabicsubst[x][0], arabicsubst[x][1], 0, 0, arabicsubst[x][4]))
except:
pass
outfile.write ("{0, 0, 0, 0, 0},\n")
outfile.write ("};\n")
outfile.close ()

View file

@ -1,4 +1,5 @@
#! /bin/sh -e
#! /bin/sh
set -e
# Make GRUB rescue image
# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc.
@ -54,10 +55,25 @@ Report bugs to <bug-grub@gnu.org>.
EOF
}
argument () {
opt=$1
shift
if test $# -eq 0; then
echo "$0: option requires an argument -- '$opt'" 1>&2
exit 1
fi
echo $1
}
input_dir=${pkglibdir}
# Check the arguments.
for option in "$@"; do
while test $# -gt 0
do
option=$1
shift
case "$option" in
-h | --help)
usage
@ -65,12 +81,22 @@ for option in "$@"; do
-v | --version)
echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
exit 0 ;;
--modules)
modules=`argument $option "$@"`; shift ;;
--modules=*)
modules=`echo "$option" | sed 's/--modules=//'` ;;
--pkglibdir)
input_dir=`argument $option "$@"`; shift ;;
--pkglibdir=*)
input_dir=`echo "$option" | sed 's/--pkglibdir=//'` ;;
--grub-mkimage)
grub_mkimage=`argument $option "$@"`; shift ;;
--grub-mkimage=*)
grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;;
-*)
echo "Unrecognized option \`$option'" 1>&2
usage

View file

@ -90,12 +90,14 @@ struct boot_blocklist
grub_uint32_t len;
} __attribute__ ((packed));
void
grub_putchar (int c)
void
grub_xputs_real (const char *str)
{
putchar (c);
fputs (str, stdout);
}
void (*grub_xputs) (const char *str) = grub_xputs_real;
int
grub_getkey (void)
{
@ -407,6 +409,8 @@ Usage: %s [OPTION]... DEVICE\n\
\n\
Set up images to boot from DEVICE.\n\
DEVICE must be a GRUB device (e.g. `(hd0,1)').\n\
\n\
You should not normally run %s directly. Use grub-install instead.\n\
\n\
-b, --boot-image=FILE use FILE as the boot image [default=%s]\n\
-c, --core-image=FILE use FILE as the core image [default=%s]\n\
@ -418,7 +422,7 @@ DEVICE must be a GRUB device (e.g. `(hd0,1)').\n\
-v, --verbose print verbose messages\n\
\n\
Report bugs to <%s>.\n\
", program_name,
", program_name, program_name,
DEFAULT_BOOT_FILE, DEFAULT_CORE_FILE, DEFAULT_DIRECTORY,
DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT);