diff --git a/util/setup.c b/util/setup.c index 8954dd479..92a5af9ba 100644 --- a/util/setup.c +++ b/util/setup.c @@ -205,7 +205,6 @@ save_blocklists (grub_disk_addr_t sector, unsigned offset, unsigned length, #endif } -#ifdef GRUB_SETUP_BIOS /* Context for setup/identify_partmap. */ struct identify_partmap_ctx { @@ -241,7 +240,6 @@ identify_partmap (grub_disk_t disk __attribute__ ((unused)), ctx->multiple_partmaps = 1; return 1; } -#endif #ifdef GRUB_SETUP_BIOS #define SETUP grub_util_bios_setup @@ -262,9 +260,7 @@ SETUP (const char *dir, char *boot_img, *core_img, *boot_path; char *root = 0; size_t boot_size, core_size; -#ifdef GRUB_SETUP_BIOS grub_uint16_t core_sectors; -#endif grub_device_t root_dev = 0, dest_dev, core_dev; grub_util_fd_t fp; struct blocklists bl; @@ -288,10 +284,8 @@ SETUP (const char *dir, core_path = grub_util_get_path (dir, core_file); core_size = grub_util_get_image_size (core_path); -#ifdef GRUB_SETUP_BIOS core_sectors = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); -#endif if (core_size < GRUB_DISK_SECTOR_SIZE) grub_util_error (_("the size of `%s' is too small"), core_path); #ifdef GRUB_SETUP_BIOS @@ -372,8 +366,8 @@ SETUP (const char *dir, if (grub_env_set ("root", root) != GRUB_ERR_NONE) grub_util_error ("%s", grub_errmsg); -#ifdef GRUB_SETUP_BIOS { +#ifdef GRUB_SETUP_BIOS char *tmp_img; grub_uint8_t *boot_drive_check; @@ -398,6 +392,7 @@ SETUP (const char *dir, boot_drive_check[0] = 0x90; boot_drive_check[1] = 0x90; } +#endif struct identify_partmap_ctx ctx = { .dest_partmap = NULL, @@ -413,6 +408,7 @@ SETUP (const char *dir, grub_partition_iterate (dest_dev->disk, identify_partmap, &ctx); +#ifdef GRUB_SETUP_BIOS /* Copy the partition table. */ if (ctx.dest_partmap || (!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk))) @@ -421,6 +417,7 @@ SETUP (const char *dir, GRUB_BOOT_MACHINE_PART_END - GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC); free (tmp_img); +#endif if (ctx.container && grub_strcmp (ctx.container->partmap->name, "msdos") == 0 @@ -508,10 +505,22 @@ SETUP (const char *dir, else maxsec = core_sectors; +#ifdef GRUB_SETUP_BIOS if (maxsec > ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR) >> GRUB_DISK_SECTOR_BITS)) maxsec = ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR) >> GRUB_DISK_SECTOR_BITS); +#endif + +#ifdef GRUB_SETUP_SPARC64 + /* + * On SPARC we need two extra. One is because we are combining the + * core.img with the boot.img. The other is because the boot sector + * starts at 1. + */ + nsec += 2; + maxsec += 2; +#endif if (is_ldm) err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec, @@ -560,9 +569,39 @@ SETUP (const char *dir, bl.block--; bl.block->start = 0; bl.block->len = 0; +#ifdef GRUB_SETUP_BIOS bl.block->segment = 0; +#endif +#ifdef GRUB_SETUP_SPARC64 + { + /* + * On SPARC, the block-list entries need to be based off the beginning + * of the parition, not the beginning of the disk. + */ + struct grub_boot_blocklist *block; + block = bl.first_block; + + while (block->len) + { + block->start -= bl.first_sector; + block--; + } + } + + /* + * Reserve space for the boot block since it can not be in the + * Parition table on SPARC. + */ + assert (bl.first_block->len > 2); + bl.first_block->start += 2; + bl.first_block->len -= 2; + write_rootdev (root_dev, boot_img, sectors[BOOT_SECTOR + 1] - bl.first_sector); +#endif + +#ifdef GRUB_SETUP_BIOS write_rootdev (root_dev, boot_img, bl.first_sector); +#endif /* Round up to the nearest sector boundary, and zero the extra memory */ core_img = xrealloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE); @@ -572,7 +611,7 @@ SETUP (const char *dir, bl.first_block = (struct grub_boot_blocklist *) (core_img + GRUB_DISK_SECTOR_SIZE - sizeof (*bl.block)); - +#if GRUB_SETUP_BIOS grub_size_t no_rs_length; no_rs_length = grub_target_to_host16 (grub_get_unaligned16 (core_img @@ -603,14 +642,34 @@ SETUP (const char *dir, grub_disk_write (dest_dev->disk, sectors[i], 0, GRUB_DISK_SECTOR_SIZE, core_img + i * GRUB_DISK_SECTOR_SIZE); +#endif +#ifdef GRUB_SETUP_SPARC64 + { + int isec = BOOT_SECTOR; + + /* Write the boot image onto the disk. */ + if (grub_disk_write (dest_dev->disk, sectors[isec++], 0, + GRUB_DISK_SECTOR_SIZE, boot_img)) + grub_util_error ("%s", grub_errmsg); + + /* Write the core image onto the disk. */ + for (i = 0 ; isec < nsec; i++, isec++) + { + if (grub_disk_write (dest_dev->disk, sectors[isec], 0, + GRUB_DISK_SECTOR_SIZE, + core_img + i * GRUB_DISK_SECTOR_SIZE)) + grub_util_error ("%s", grub_errmsg); + } + } + +#endif grub_free (sectors); goto finish; } unable_to_embed: -#endif if (dest_dev->disk->dev->id != root_dev->disk->dev->id) grub_util_error ("%s", _("embedding is not possible, but this is required for " @@ -799,6 +858,10 @@ unable_to_embed: 0, GRUB_DISK_SECTOR_SIZE, boot_img)) grub_util_error ("%s", grub_errmsg); +#ifdef GRUB_SETUP_SPARC64 + finish: +#endif + grub_util_biosdisk_flush (root_dev->disk); grub_util_biosdisk_flush (dest_dev->disk);