Unify sparc init with other ieee1275.

* grub-core/Makefile.core.def (kernel): Use kern/ieee1275/init.c
	instead of kern/sparc64/ieee1275/init.c.
	* grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options)
	[__sparc__]: Set GRUB_IEEE1275_FLAG_NO_PARTITION_0.
	* grub-core/kern/ieee1275/init.c [__sparc__]: Include
	grub/machine/kernel.h.
	(grub_ieee1275_original_stack) [__sparc__]: New variable.
	(grub_claim_heap) [__sparc__]: Use sparc version.
	(grub_machine_init): Moved args parsing to
	(grub_parse_cmdline): ...this.
	* grub-core/kern/sparc64/ieee1275/init.c: Removed.
	* include/grub/offsets.h (GRUB_KERNEL_SPARC64_IEEE1275_MOD_GAP):
	New definition.
	(GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN): Likewise.

	Move BOOTP to separate file.

	* grub-core/Makefile.core.def (net): Add net/bootp.c.
	* grub-core/net/net.c: Move all BOOTP functions to
	* grub-core/net/bootp.c: ... here.

	Use frame interface on PXE.

	* grub-core/Makefile.core.def (pxecmd): Removed.
	(pxe): Use net/drivers/i386/pc/pxe.c rather than net/i386/pc/pxe.c.
	* grub-core/commands/i386/pc/pxecmd.c: Removed.
	* grub-core/i386/pc/pxe.c: Moved from here ...
	* grub-core/net/i386/pc/pxe.c: ... here. Rewritten.
	* grub-core/net/net.c (grub_net_open_real): Handle old pxe syntax.
	* include/grub/i386/pc/pxe.h (grub_pxe_unload): Removed.

	EFI network support.

	* grub-core/Makefile.core.def (efinet): New module.
	* grub-core/disk/efi/efidisk.c (compare_device_paths): Moved from
	here...
	* grub-core/kern/efi/efi.c (grub_efi_compare_device_paths): ... here.
	All users updated.
	* grub-core/kern/efi/init.c (grub_efi_net_config): New variable.
	(grub_machine_get_bootlocation): Call grub_efi_net_config if needed.
	* grub-core/kern/x86_64/efi/callwrap.S (efi_wrap_7): New function.
	* grub-core/net/drivers/efi/efinet.c: New file.
	* include/grub/efi/efi.h (grub_efi_compare_device_paths): New proto.
	(grub_efi_net_config): New extern var.

	Various cleanups and bugfixes.

	* grub-core/disk/efi/efidisk.c (grub_efidisk_open): Fix off-by-one
	error.
	(grub_efidisk_get_device_name): Unify similar codepaths. Accept whole
	disk declared as partition.
	* grub-core/disk/ieee1275/ofdisk.c (grub_ofdisk_open): Fix memory
	leak on failure.
	* grub-core/kern/dl.c (grub_dl_load_file): Fix memory leak.
	* grub-core/kern/mm.c (grub_debug_malloc): Don't use unsupported %zx.
	(grub_debug_zalloc): Likewise.
	(grub_debug_realloc): Likewise.
	(grub_debug_memalign): Likewise.
	* grub-core/net/arp.c (grub_net_arp_receive): IPv4 is 4-byte wide.
	Check that target is IPv4.
	* grub-core/net/drivers/ieee1275/ofnet.c (grub_ofnet_findcards): Use
	local-mac-address as fallback.
	* grub-core/net/ethernet.c (grub_net_recv_ethernet_packet): Prevent
	memory leak.
	* grub-core/net/ip.c (ipchksum): Rename to ...
	(grub_net_ip_chksum): ... this. All users updated.
	(grub_net_recv_ip_packets): Special handling for DHCP.
	* util/grub-mkimage.c (generate_image): Zero-out aout header.

	Unify prefix handling

	* grub-core/kern/efi/init.c (grub_efi_set_prefix): Revamped into ...
	(grub_machine_get_bootlocation): ... this.
	* grub-core/kern/emu/main.c (grub_machine_set_prefix): Revamped into ...
	(grub_machine_get_bootlocation): ... this.
	(grub_prefix): New variable.
	(prefix): Removed.
	(root_dev): New variable.
	(dir): Likewise.
	(main): Use new variables.
	* grub-core/kern/i386/coreboot/init.c (grub_machine_set_prefix):
	Revamped into ...
	(grub_machine_get_bootlocation): ... this.
	* grub-core/kern/i386/efi/init.c (grub_machine_set_prefix): Removed.
	* grub-core/kern/i386/pc/init.c (make_install_device): Revamped into ...
	(grub_machine_get_bootlocation): ... this.
	(grub_machine_set_prefix): Removed.
	* grub-core/kern/ia64/efi/init.c (grub_machine_set_prefix): Removed.
	* grub-core/kern/ieee1275/init.c (grub_machine_set_prefix):
	Revamped into ...
	(grub_machine_get_bootlocation): ... this.
	* grub-core/kern/main.c (grub_set_root_dev): Revamped into ...
	(grub_set_prefix_and_root): ... this. All users updated.
	* grub-core/kern/mips/init.c (grub_machine_set_prefix):
	Revamped into ...
	(grub_machine_get_bootlocation): ... this.
	* include/grub/kernel.h (grub_machine_set_prefix): Removed.
	(grub_machine_get_bootlocation): New proto.
	* include/grub/i386/pc/kernel.h (grub_pc_net_config): New var.

	Less intrusive and more reliable seek on network implementation.

	* grub-core/kern/file.c (grub_file_net_seek): Removed.
	(grub_file_seek): Don't call grub_file_net_seek.
	* grub-core/net/net.c (grub_net_fs_read): Renamed to ...
	(grub_net_fs_read_real): .. this.
	(grub_net_seek_real): Use net->offset.
	(grub_net_fs_read): Seek if necessary.

	Unify IEEE1275 netwotk config with the other platforms.

	* grub-core/kern/ieee1275/init.c (grub_ieee1275_net_config):
	New variable.
	(grub_machine_get_bootlocation): Support network.
	* grub-core/kern/ieee1275/openfw.c (grub_ieee1275_parse_args):
	Support type and device parsing.
	(grub_ieee1275_get_device_type): New function.
	* grub-core/net/drivers/ieee1275/ofnet.c (grub_getbootp_real): Revamped
	into ...
	(grub_ieee1275_net_config_real): ... this.
	(grub_ofnet_probecards): Removed.
	* grub-core/Makefile.am (KERNEL_HEADER_FILES): Remove ofnet.h.
	* include/grub/ieee1275/ofnet.h: Removed.
	* include/grub/ieee1275/ieee1275.h (grub_ieee1275_net_config): NEw
	extern var.
	(grub_ieee1275_get_device_type): New function.

	Unify network device closing across platforms and make more robust.

	* grub-core/kern/ieee1275/init.c (grub_machine_fini): Don't call
	grub_grubnet_fini.
	* grub-core/net/ethernet.c (send_ethernet_packet): Open card if it isn't
	already.
	* grub-core/net/net.c (grub_net_network_level_interface_register):
	Update num_ifaces.
	(grub_net_card_unregister): Close all interfaces.
	(receive_packets): Don't poll if no iterfaces are registered.
	Open if necessary.
	(grub_net_fini_hw): New function.
	(grub_net_restore_hw): Likewise.
	(fini_hnd): New variable.
	(GRUB_MOD_INIT): Register preboot hook.
	(GRUB_MOD_FINI): Run and unregister preboot hook.

	Poll network cards when idle.

	* grub-core/kern/term.c (grub_net_poll_cards_idle): New variable.
	(grub_checkkey): Call grub_net_poll_cards_idle if it's not NULL.
	* grub-core/net/net.c (receive_packets): Save last poll time.
	(grub_net_poll_cards_idle_real): New function.
	(GRUB_MOD_INIT): Register grub_net_poll_cards_idle.
	(GRUB_MOD_FINI): Unregister grub_net_poll_cards_idle.
	* include/grub/kernel.h (grub_poll_cards_idle): New extern variable.

	Rename ofnet interfaces.

	* grub-core/net/drivers/ieee1275/ofnet.c (find_alias): New function.
	(grub_ofnet_findcards): Use ofnet_%s names.

	* util/grub-mknetdir.in: Support for EFI and IEEE1275.

	Cleanup socket opening.

	* grub-core/net/net.c (grub_net_fs_open): Rewritten.
	(grub_net_fs_close): Likewise.
	(grub_net_fs_read_real): Use eof member.
	* include/grub/net/udp.h (+grub_net_udp_open): New proto.
	(+grub_net_udp_close): New inline function.

	* include/grub/net/tftp.h: Moved to the top of ...
	* grub-core/net/tftp.c: ... here.
	* include/grub/net/ip.h: Moved mostly to the top of ...
	* grub-core/net/ip.c: ... here.
	* include/grub/net/ethernet.h: Moved mostly to the top of ...
	* grub-core/net/ethernet.c: ... here.

	* grub-core/kern/device.c (grub_device_close): Free device->net->server.

	* grub-core/commands/probe.c (grub_cmd_probe): Use protocol name for
	FS name.

	* include/grub/net/ip.h (ipv4_ini): Removed.
	(ipv4_fini): Likewise.

	* include/grub/net/ip.h (grub_net_recv_ip_packets): New proto.
	(grub_net_send_ip_packets): Likewise.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-07-06 20:05:26 +02:00
commit abee94edf9
53 changed files with 2820 additions and 2174 deletions

View file

@ -79,7 +79,7 @@ grub_device_close (grub_device_t device)
if (device->net)
{
grub_free (device->net->name);
grub_free (device->net->server);
grub_free (device->net);
}

View file

@ -688,11 +688,9 @@ grub_dl_load_file (const char *filename)
grub_file_close (file);
mod = grub_dl_load_core (core, size);
grub_free (core);
if (! mod)
{
grub_free (core);
return 0;
}
return 0;
mod->ref_count--;
return mod;

View file

@ -746,3 +746,51 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp)
dp = (grub_efi_device_path_t *) ((char *) dp + len);
}
}
/* Compare device paths. */
int
grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
const grub_efi_device_path_t *dp2)
{
if (! dp1 || ! dp2)
/* Return non-zero. */
return 1;
while (1)
{
grub_efi_uint8_t type1, type2;
grub_efi_uint8_t subtype1, subtype2;
grub_efi_uint16_t len1, len2;
int ret;
type1 = GRUB_EFI_DEVICE_PATH_TYPE (dp1);
type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2);
if (type1 != type2)
return (int) type2 - (int) type1;
subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1);
subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2);
if (subtype1 != subtype2)
return (int) subtype1 - (int) subtype2;
len1 = GRUB_EFI_DEVICE_PATH_LENGTH (dp1);
len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2);
if (len1 != len2)
return (int) len1 - (int) len2;
ret = grub_memcmp (dp1, dp2, len1);
if (ret != 0)
return ret;
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1))
break;
dp1 = (grub_efi_device_path_t *) ((char *) dp1 + len1);
dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);
}
return 0;
}

View file

@ -42,84 +42,28 @@ grub_efi_init (void)
grub_efidisk_init ();
}
void (*grub_efi_net_config) (grub_efi_handle_t hnd,
char **device,
char **path);
void
grub_efi_set_prefix (void)
grub_machine_get_bootlocation (char **device, char **path)
{
grub_efi_loaded_image_t *image = NULL;
char *device = NULL;
char *path = NULL;
char *p;
{
char *pptr = NULL;
if (grub_prefix[0] == '(')
{
pptr = grub_strrchr (grub_prefix, ')');
if (pptr)
{
device = grub_strndup (grub_prefix + 1, pptr - grub_prefix - 1);
pptr++;
}
}
if (!pptr)
pptr = grub_prefix;
if (pptr[0])
path = grub_strdup (pptr);
}
image = grub_efi_get_loaded_image (grub_efi_image_handle);
if (!image)
return;
*device = grub_efidisk_get_device_name (image->device_handle);
*path = grub_efi_get_filename (image->file_path);
if (!*device && grub_efi_net_config)
grub_efi_net_config (image->device_handle, device, path);
if ((!device || device[0] == ',' || !device[0]) || !path)
image = grub_efi_get_loaded_image (grub_efi_image_handle);
if (image)
{
if (!device)
device = grub_efidisk_get_device_name (image->device_handle);
else if (device[0] == ',' || !device[0])
{
/* We have a partition, but still need to fill in the drive. */
char *image_device, *comma, *new_device;
image_device = grub_efidisk_get_device_name (image->device_handle);
comma = grub_strchr (image_device, ',');
if (comma)
{
char *drive = grub_strndup (image_device, comma - image_device);
new_device = grub_xasprintf ("%s%s", drive, device);
grub_free (drive);
}
else
new_device = grub_xasprintf ("%s%s", image_device, device);
grub_free (image_device);
grub_free (device);
device = new_device;
}
}
if (image && !path)
{
char *p;
path = grub_efi_get_filename (image->file_path);
/* Get the directory. */
p = grub_strrchr (path, '/');
if (p)
*p = '\0';
}
if (device && path)
{
char *prefix;
prefix = grub_xasprintf ("(%s)%s", device, path);
if (prefix)
{
grub_env_set ("prefix", prefix);
grub_free (prefix);
}
}
grub_free (device);
grub_free (path);
/* Get the directory. */
p = grub_strrchr (*path, '/');
if (p)
*p = '\0';
}
void

View file

@ -49,7 +49,7 @@
static jmp_buf main_env;
/* Store the prefix specified by an argument. */
static char *prefix = NULL;
static char *root_dev = NULL, *dir = NULL;
int grub_no_autoload;
@ -71,11 +71,10 @@ grub_machine_init (void)
}
void
grub_machine_set_prefix (void)
grub_machine_get_bootlocation (char **device, char **path)
{
grub_env_set ("prefix", prefix);
free (prefix);
prefix = 0;
*device = root_dev;
*path = dir;
}
void
@ -84,6 +83,8 @@ grub_machine_fini (void)
grub_console_fini ();
}
char grub_prefix[64] = "";
static struct option options[] =
@ -132,22 +133,24 @@ void grub_emu_init (void);
int
main (int argc, char *argv[])
{
char *root_dev = 0;
char *dir = DEFAULT_DIRECTORY;
char *dev_map = DEFAULT_DEVICE_MAP;
volatile int hold = 0;
int opt;
set_program_name (argv[0]);
dir = xstrdup (DEFAULT_DIRECTORY);
while ((opt = getopt_long (argc, argv, "r:d:m:vH:hV", options, 0)) != -1)
switch (opt)
{
case 'r':
root_dev = optarg;
free (root_dev);
root_dev = xstrdup (optarg);
break;
case 'd':
dir = optarg;
free (dir);
dir = xstrdup (optarg);
break;
case 'm':
dev_map = optarg;
@ -219,9 +222,6 @@ main (int argc, char *argv[])
dir = xstrdup (dir);
else
dir = grub_make_system_path_relative_to_its_root (dir);
prefix = xmalloc (strlen (root_dev) + 2 + strlen (dir) + 1);
sprintf (prefix, "(%s)%s", root_dev, dir);
free (dir);
/* Start GRUB! */
if (setjmp (main_env) == 0)

View file

@ -25,7 +25,6 @@
#include <grub/fs.h>
#include <grub/device.h>
grub_err_t (*grub_file_net_seek) (struct grub_file *file, grub_off_t offset) = NULL;
void (*EXPORT_VAR (grub_grubnet_fini)) (void);
grub_file_filter_t grub_file_filters_all[GRUB_FILE_FILTER_MAX];
@ -183,9 +182,6 @@ grub_file_seek (grub_file_t file, grub_off_t offset)
return -1;
}
if (file->device->net && grub_file_net_seek)
grub_file_net_seek (file, offset);
old = file->offset;
file->offset = offset;

View file

@ -107,10 +107,9 @@ grub_machine_init (void)
}
void
grub_machine_set_prefix (void)
grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
char **path __attribute__ ((unused)))
{
/* Initialize the prefix. */
grub_env_set ("prefix", grub_prefix);
}
void

View file

@ -39,9 +39,3 @@ grub_machine_fini (void)
{
grub_efi_fini ();
}
void
grub_machine_set_prefix (void)
{
grub_efi_set_prefix ();
}

View file

@ -45,52 +45,41 @@ struct mem_region
static struct mem_region mem_regions[MAX_REGIONS];
static int num_regions;
static char *
make_install_device (void)
void (*grub_pc_net_config) (char **device, char **path);
void
grub_machine_get_bootlocation (char **device, char **path)
{
char *ptr;
/* No hardcoded root partition - make it from the boot drive and the
partition number encoded at the install time. */
if (grub_boot_drive == GRUB_BOOT_MACHINE_PXE_DL)
{
if (grub_pc_net_config)
grub_pc_net_config (device, path);
return;
}
/* XXX: This should be enough. */
char dev[100], *ptr = dev;
#define DEV_SIZE 100
*device = grub_malloc (DEV_SIZE);
ptr = *device;
grub_snprintf (*device, DEV_SIZE,
"%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f',
grub_boot_drive & 0x7f);
ptr += grub_strlen (ptr);
if (grub_prefix[0] != '(')
{
/* No hardcoded root partition - make it from the boot drive and the
partition number encoded at the install time. */
if (grub_boot_drive == GRUB_BOOT_MACHINE_PXE_DL)
{
grub_strcpy (dev, "(pxe");
ptr += sizeof ("(pxe") - 1;
}
else
{
grub_snprintf (dev, sizeof (dev),
"(%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f',
grub_boot_drive & 0x7f);
ptr += grub_strlen (ptr);
if (grub_install_dos_part >= 0)
grub_snprintf (ptr, DEV_SIZE - (ptr - *device),
",%u", grub_install_dos_part + 1);
ptr += grub_strlen (ptr);
if (grub_install_dos_part >= 0)
grub_snprintf (ptr, sizeof (dev) - (ptr - dev),
",%u", grub_install_dos_part + 1);
ptr += grub_strlen (ptr);
if (grub_install_bsd_part >= 0)
grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%u",
grub_install_bsd_part + 1);
ptr += grub_strlen (ptr);
}
grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ")%s", grub_prefix);
grub_strcpy (grub_prefix, dev);
}
else if (grub_prefix[1] == ',' || grub_prefix[1] == ')')
{
/* We have a prefix, but still need to fill in the boot drive. */
grub_snprintf (dev, sizeof (dev),
"(%cd%u%s", (grub_boot_drive & 0x80) ? 'h' : 'f',
grub_boot_drive & 0x7f, grub_prefix + 1);
grub_strcpy (grub_prefix, dev);
}
return grub_prefix;
if (grub_install_bsd_part >= 0)
grub_snprintf (ptr, DEV_SIZE - (ptr - *device), ",%u",
grub_install_bsd_part + 1);
ptr += grub_strlen (ptr);
*ptr = 0;
}
/* Add a memory region. */
@ -211,13 +200,6 @@ grub_machine_init (void)
grub_tsc_init ();
}
void
grub_machine_set_prefix (void)
{
/* Initialize the prefix. */
grub_env_set ("prefix", make_install_device ());
}
void
grub_machine_fini (void)
{

View file

@ -40,12 +40,6 @@ grub_machine_fini (void)
grub_efi_fini ();
}
void
grub_machine_set_prefix (void)
{
grub_efi_set_prefix ();
}
void
grub_arch_sync_caches (void *address, grub_size_t len)
{

View file

@ -60,6 +60,10 @@ grub_ieee1275_find_options (void)
int is_olpc = 0;
int is_qemu = 0;
#ifdef __sparc__
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
#endif
grub_ieee1275_finddevice ("/", &root);
grub_ieee1275_finddevice ("/options", &options);
grub_ieee1275_finddevice ("/openprom", &openprom);

View file

@ -31,10 +31,12 @@
#include <grub/ieee1275/console.h>
#include <grub/ieee1275/ofdisk.h>
#include <grub/ieee1275/ieee1275.h>
#include <grub/ieee1275/ofnet.h>
#include <grub/net.h>
#include <grub/offsets.h>
#include <grub/memory.h>
#ifdef __sparc__
#include <grub/machine/kernel.h>
#endif
/* The minimal heap size we can live with. */
#define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024)
@ -49,6 +51,10 @@
extern char _start[];
extern char _end[];
#ifdef __sparc__
grub_addr_t grub_ieee1275_original_stack;
#endif
void
grub_exit (void)
{
@ -70,52 +76,51 @@ grub_translate_ieee1275_path (char *filepath)
}
}
void (*grub_ieee1275_net_config) (const char *dev,
char **device,
char **path);
void
grub_machine_set_prefix (void)
grub_machine_get_bootlocation (char **device, char **path)
{
char bootpath[64]; /* XXX check length */
char *filename;
char *prefix;
grub_bootp_t bootp_pckt;
char addr[GRUB_NET_MAX_STR_ADDR_LEN];
/* Set the net prefix when possible. */
if (grub_getbootp && (bootp_pckt = grub_getbootp()))
{
grub_uint32_t n = bootp_pckt->siaddr;
grub_snprintf (addr, GRUB_NET_MAX_STR_ADDR_LEN, "%d.%d.%d.%d",
((n >> 24) & 0xff), ((n >> 16) & 0xff),
((n >> 8) & 0xff), ((n >> 0) & 0xff));
prefix = grub_xasprintf ("(tftp,%s)%s", addr,grub_prefix);
grub_env_set ("prefix", prefix);
grub_free (prefix);
return;
}
if (grub_prefix[0])
{
grub_env_set ("prefix", grub_prefix);
/* Prefix is hardcoded in the core image. */
return;
}
char *type;
if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath,
sizeof (bootpath), 0))
{
/* Should never happen. */
grub_printf ("/chosen/bootpath property missing!\n");
grub_env_set ("prefix", "");
return;
}
/* Transform an OF device path to a GRUB path. */
prefix = grub_ieee1275_encode_devname (bootpath);
type = grub_ieee1275_get_device_type (bootpath);
if (type && grub_strcmp (type, "network") == 0)
{
char *dev, *canon;
char *ptr;
dev = grub_ieee1275_get_aliasdevname (bootpath);
canon = grub_ieee1275_canonicalise_devname (dev);
ptr = canon + grub_strlen (canon) - 1;
while (ptr > canon && (*ptr == ',' || *ptr == ':'))
ptr--;
ptr++;
*ptr = 0;
if (grub_ieee1275_net_config)
grub_ieee1275_net_config (canon, device, path);
grub_free (dev);
grub_free (canon);
}
else
*device = grub_ieee1275_encode_devname (bootpath);
grub_free (type);
filename = grub_ieee1275_get_filename (bootpath);
if (filename)
{
char *newprefix;
char *lastslash = grub_strrchr (filename, '\\');
/* Truncate at last directory. */
@ -124,23 +129,22 @@ grub_machine_set_prefix (void)
*lastslash = '\0';
grub_translate_ieee1275_path (filename);
newprefix = grub_xasprintf ("%s%s", prefix, filename);
if (newprefix)
{
grub_free (prefix);
prefix = newprefix;
}
*path = filename;
}
}
grub_env_set ("prefix", prefix);
grub_free (filename);
grub_free (prefix);
}
/* Claim some available memory in the first /memory node. */
static void grub_claim_heap (void)
#ifdef __sparc__
static void
grub_claim_heap (void)
{
grub_mm_init_region ((void *) (grub_modules_get_end ()
+ GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000);
}
#else
static void
grub_claim_heap (void)
{
unsigned long total = 0;
@ -208,23 +212,14 @@ static void grub_claim_heap (void)
else
grub_machine_mmap_iterate (heap_init);
}
#endif
static grub_uint64_t ieee1275_get_time_ms (void);
void
grub_machine_init (void)
static void
grub_parse_cmdline (void)
{
char args[256];
grub_ssize_t actual;
char args[256];
grub_ieee1275_init ();
grub_console_init_early ();
grub_claim_heap ();
grub_console_init_lately ();
grub_ofdisk_init ();
/* Process commandline. */
if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args,
sizeof args, &actual) == 0
&& actual > 1)
@ -257,6 +252,21 @@ grub_machine_init (void)
}
}
}
}
static grub_uint64_t ieee1275_get_time_ms (void);
void
grub_machine_init (void)
{
grub_ieee1275_init ();
grub_console_init_early ();
grub_claim_heap ();
grub_console_init_lately ();
grub_ofdisk_init ();
grub_parse_cmdline ();
grub_install_get_time_ms (ieee1275_get_time_ms);
}
@ -264,8 +274,6 @@ grub_machine_init (void)
void
grub_machine_fini (void)
{
if (grub_grubnet_fini)
grub_grubnet_fini ();
grub_ofdisk_fini ();
grub_console_fini ();
}

View file

@ -22,16 +22,14 @@
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/ieee1275/ieee1275.h>
#include <grub/ieee1275/ofnet.h>
#include <grub/net.h>
#include <grub/net/tftp.h>
grub_bootp_t (*grub_getbootp) (void);
enum grub_ieee1275_parse_type
{
GRUB_PARSE_FILENAME,
GRUB_PARSE_PARTITION,
GRUB_PARSE_DEVICE
GRUB_PARSE_DEVICE,
GRUB_PARSE_DEVICE_TYPE
};
/* Walk children of 'devpath', calling hook for each. */
@ -322,14 +320,9 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype)
{
char type[64]; /* XXX check size. */
char *device = grub_ieee1275_get_devname (path);
char *args = grub_ieee1275_get_devargs (path);
char *ret = 0;
grub_ieee1275_phandle_t dev;
if (!args)
/* Shouldn't happen. */
return 0;
/* We need to know what type of device it is in order to parse the full
file path properly. */
if (grub_ieee1275_finddevice (device, &dev))
@ -344,50 +337,86 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype)
goto fail;
}
if (!grub_strcmp ("block", type))
switch (ptype)
{
/* The syntax of the device arguments is defined in the CHRP and PReP
IEEE1275 bindings: "[partition][,[filename]]". */
char *comma = grub_strchr (args, ',');
case GRUB_PARSE_DEVICE:
ret = grub_strdup (device);
break;
case GRUB_PARSE_DEVICE_TYPE:
ret = grub_strdup (type);
break;
case GRUB_PARSE_FILENAME:
{
char *comma;
char *args;
if (ptype == GRUB_PARSE_FILENAME)
{
if (comma)
{
char *filepath = comma + 1;
if (grub_strcmp ("block", type) != 0)
goto unknown;
/* Make sure filepath has leading backslash. */
if (filepath[0] != '\\')
ret = grub_xasprintf ("\\%s", filepath);
else
ret = grub_strdup (filepath);
args = grub_ieee1275_get_devargs (path);
if (!args)
/* Shouldn't happen. */
return 0;
/* The syntax of the device arguments is defined in the CHRP and PReP
IEEE1275 bindings: "[partition][,[filename]]". */
comma = grub_strchr (args, ',');
if (comma)
{
char *filepath = comma + 1;
/* Make sure filepath has leading backslash. */
if (filepath[0] != '\\')
ret = grub_xasprintf ("\\%s", filepath);
else
ret = grub_strdup (filepath);
}
grub_free (args);
}
else if (ptype == GRUB_PARSE_PARTITION)
{
if (!comma)
ret = grub_strdup (args);
else
ret = grub_strndup (args, (grub_size_t)(comma - args));
}
}
break;
case GRUB_PARSE_PARTITION:
{
char *comma;
char *args;
else if (!grub_strcmp ("network", type))
{
if (ptype == GRUB_PARSE_DEVICE)
ret = grub_strdup(device);
}
else
{
if (grub_strcmp ("block", type) != 0)
goto unknown;
args = grub_ieee1275_get_devargs (path);
if (!args)
/* Shouldn't happen. */
return 0;
comma = grub_strchr (args, ',');
if (!comma)
ret = grub_strdup (args);
else
ret = grub_strndup (args, (grub_size_t)(comma - args));
/* Consistently provide numbered partitions to GRUB.
OpenBOOT traditionally uses alphabetical partition
specifiers. */
if (ret[0] >= 'a' && ret[0] <= 'z')
ret[0] = '1' + (ret[0] - 'a');
grub_free (args);
}
break;
default:
unknown:
grub_printf ("Unsupported type %s for device %s\n", type, device);
}
fail:
grub_free (device);
grub_free (args);
return ret;
}
char *
grub_ieee1275_get_device_type (const char *path)
{
return grub_ieee1275_parse_args (path, GRUB_PARSE_DEVICE_TYPE);
}
char *
grub_ieee1275_get_aliasdevname (const char *path)
{

View file

@ -129,27 +129,74 @@ grub_env_write_root (struct grub_env_var *var __attribute__ ((unused)),
return grub_strdup (val);
}
/* Set the root device according to the dl prefix. */
static void
grub_set_root_dev (void)
grub_set_prefix_and_root (void)
{
const char *prefix;
char *device = NULL;
char *path = NULL;
char *fwdevice = NULL;
char *fwpath = NULL;
grub_register_variable_hook ("root", 0, grub_env_write_root);
prefix = grub_env_get ("prefix");
{
char *pptr = NULL;
if (grub_prefix[0] == '(')
{
pptr = grub_strrchr (grub_prefix, ')');
if (pptr)
{
device = grub_strndup (grub_prefix + 1, pptr - grub_prefix - 1);
pptr++;
}
}
if (!pptr)
pptr = grub_prefix;
if (pptr[0])
path = grub_strdup (pptr);
}
if ((!device || device[0] == ',' || !device[0]) || !path)
grub_machine_get_bootlocation (&fwdevice, &fwpath);
if (prefix)
if (!device && fwdevice)
device = fwdevice;
else if (fwdevice && (device[0] == ',' || !device[0]))
{
char *dev;
/* We have a partition, but still need to fill in the drive. */
char *comma, *new_device;
dev = grub_file_get_device_name (prefix);
if (dev)
comma = grub_strchr (fwdevice, ',');
if (comma)
{
grub_env_set ("root", dev);
grub_free (dev);
char *drive = grub_strndup (fwdevice, comma - fwdevice);
new_device = grub_xasprintf ("%s%s", drive, device);
grub_free (drive);
}
else
new_device = grub_xasprintf ("%s%s", fwdevice, device);
grub_free (fwdevice);
grub_free (device);
device = new_device;
}
if (fwpath && !path)
path = fwpath;
if (device)
{
char *prefix;
prefix = grub_xasprintf ("(%s)%s", device, path ? : "");
if (prefix)
{
grub_env_set ("prefix", prefix);
grub_free (prefix);
}
grub_env_set ("root", device);
}
grub_free (device);
grub_free (path);
grub_print_error ();
}
/* Load the normal mode module and execute the normal mode if possible. */
@ -187,8 +234,7 @@ grub_main (void)
/* It is better to set the root device as soon as possible,
for convenience. */
grub_machine_set_prefix ();
grub_set_root_dev ();
grub_set_prefix_and_root ();
grub_env_export ("root");
grub_env_export ("prefix");

View file

@ -38,7 +38,7 @@ grub_get_rtc (void)
}
void
grub_machine_set_prefix (void)
grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
char **path __attribute__ ((unused)))
{
grub_env_set ("prefix", grub_prefix);
}

View file

@ -515,7 +515,7 @@ grub_debug_malloc (const char *file, int line, grub_size_t size)
void *ptr;
if (grub_mm_debug)
grub_printf ("%s:%d: malloc (0x%zx) = ", file, line, size);
grub_printf ("%s:%d: malloc (0x%" PRIxGRUB_SIZE ") = ", file, line, size);
ptr = grub_malloc (size);
if (grub_mm_debug)
grub_printf ("%p\n", ptr);
@ -528,7 +528,7 @@ grub_debug_zalloc (const char *file, int line, grub_size_t size)
void *ptr;
if (grub_mm_debug)
grub_printf ("%s:%d: zalloc (0x%zx) = ", file, line, size);
grub_printf ("%s:%d: zalloc (0x%" PRIxGRUB_SIZE ") = ", file, line, size);
ptr = grub_zalloc (size);
if (grub_mm_debug)
grub_printf ("%p\n", ptr);
@ -547,7 +547,7 @@ void *
grub_debug_realloc (const char *file, int line, void *ptr, grub_size_t size)
{
if (grub_mm_debug)
grub_printf ("%s:%d: realloc (%p, 0x%zx) = ", file, line, ptr, size);
grub_printf ("%s:%d: realloc (%p, 0x%" PRIxGRUB_SIZE ") = ", file, line, ptr, size);
ptr = grub_realloc (ptr, size);
if (grub_mm_debug)
grub_printf ("%p\n", ptr);
@ -561,8 +561,8 @@ grub_debug_memalign (const char *file, int line, grub_size_t align,
void *ptr;
if (grub_mm_debug)
grub_printf ("%s:%d: memalign (0x%zx, 0x%zx) = ",
file, line, align, size);
grub_printf ("%s:%d: memalign (0x%" PRIxGRUB_SIZE ", 0x%" PRIxGRUB_SIZE
") = ", file, line, align, size);
ptr = grub_memalign (align, size);
if (grub_mm_debug)
grub_printf ("%p\n", ptr);

View file

@ -1,174 +0,0 @@
/* init.c -- Initialize GRUB on SPARC64. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/kernel.h>
#include <grub/mm.h>
#include <grub/env.h>
#include <grub/err.h>
#include <grub/misc.h>
#include <grub/time.h>
#include <grub/machine/boot.h>
#include <grub/ieee1275/console.h>
#include <grub/machine/kernel.h>
#include <grub/machine/time.h>
#include <grub/ieee1275/ofdisk.h>
#include <grub/ieee1275/ieee1275.h>
grub_addr_t grub_ieee1275_original_stack;
void
grub_exit (void)
{
grub_ieee1275_exit ();
}
static grub_uint64_t
ieee1275_get_time_ms (void)
{
grub_uint32_t msecs = 0;
grub_ieee1275_milliseconds (&msecs);
return msecs;
}
grub_uint32_t
grub_get_rtc (void)
{
return ieee1275_get_time_ms ();
}
grub_addr_t
grub_arch_modules_addr (void)
{
extern char _end[];
return (grub_addr_t) _end;
}
void
grub_machine_set_prefix (void)
{
if (grub_prefix[0] != '(')
{
char bootpath[IEEE1275_MAX_PATH_LEN];
char *prefix, *path, *colon;
grub_ssize_t actual;
if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath",
&bootpath, sizeof (bootpath), &actual))
{
/* Should never happen. */
grub_printf ("/chosen/bootpath property missing!\n");
grub_env_set ("prefix", "");
return;
}
/* Transform an OF device path to a GRUB path. */
colon = grub_strchr (bootpath, ':');
if (colon)
{
char *part = colon + 1;
/* Consistently provide numbered partitions to GRUB.
OpenBOOT traditionally uses alphabetical partition
specifiers. */
if (part[0] >= 'a' && part[0] <= 'z')
part[0] = '1' + (part[0] - 'a');
}
prefix = grub_ieee1275_encode_devname (bootpath);
path = grub_xasprintf("%s%s", prefix, grub_prefix);
grub_strcpy (grub_prefix, path);
grub_free (path);
grub_free (prefix);
}
grub_env_set ("prefix", grub_prefix);
}
static void
grub_heap_init (void)
{
grub_mm_init_region ((void *) (grub_modules_get_end ()
+ GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000);
}
static void
grub_parse_cmdline (void)
{
grub_ssize_t actual;
char args[256];
if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args,
sizeof args, &actual) == 0
&& actual > 1)
{
int i = 0;
while (i < actual)
{
char *command = &args[i];
char *end;
char *val;
end = grub_strchr (command, ';');
if (end == 0)
i = actual; /* No more commands after this one. */
else
{
*end = '\0';
i += end - command + 1;
while (grub_isspace(args[i]))
i++;
}
/* Process command. */
val = grub_strchr (command, '=');
if (val)
{
*val = '\0';
grub_env_set (command, val + 1);
}
}
}
}
void
grub_machine_init (void)
{
grub_ieee1275_init ();
grub_console_init_early ();
grub_heap_init ();
grub_console_init_lately ();
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
grub_ofdisk_init ();
grub_parse_cmdline ();
grub_install_get_time_ms (ieee1275_get_time_ms);
}
void
grub_machine_fini (void)
{
grub_ofdisk_fini ();
grub_console_fini ();
}

View file

@ -29,6 +29,7 @@ struct grub_term_output *grub_term_outputs;
struct grub_term_input *grub_term_inputs;
void (*grub_term_poll_usb) (void) = NULL;
void (*grub_net_poll_cards_idle) (void) = NULL;
/* Put a Unicode character. */
static void
@ -91,6 +92,9 @@ grub_checkkey (void)
if (grub_term_poll_usb)
grub_term_poll_usb ();
if (grub_net_poll_cards_idle)
grub_net_poll_cards_idle ();
FOR_ACTIVE_TERM_INPUTS(term)
{
pending_key = term->getkey (term);

View file

@ -95,6 +95,20 @@ FUNCTION(efi_wrap_6)
addq $64, %rsp
ret
FUNCTION(efi_wrap_7)
subq $96, %rsp
mov 96+16(%rsp), %rax
mov %rax, 48(%rsp)
mov 96+8(%rsp), %rax
mov %rax, 40(%rsp)
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $96, %rsp
ret
FUNCTION(efi_wrap_10)
subq $96, %rsp
mov 96+40(%rsp), %rax