grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] sparc64: add bios boot partition support


From: Eric Snowberg
Subject: [PATCH] sparc64: add bios boot partition support
Date: Mon, 4 Mar 2019 17:34:01 -0800

Add BIOS Boot Partition support for sparc64 platforms.  This will work a
little different than x86.  With GPT, both the OBP "load" and "boot" commands
are partition aware and neither command can see the partition table.  Therefore
the entire boot-loader is stored within the BIOS Boot Partition and nothing
is stored within the bootstrap code area of MBR.

To use it, the end user will issue the boot command with the path pointing to
the BIOS Boot Partition.

For example with the disk below:

Model: Unknown (unknown)
Disk /dev/nvme1n1: 1600GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start   End     Size    File system  Name  Flags
1      1049kB  1075MB  1074MB   ext3
2      1075MB  1076MB  1049kB                     bios_grub
3      1076MB  1600GB  1599GB                     lvm

To boot grub2 from OBP, you would use:

boot 
/address@hidden/address@hidden/address@hidden/address@hidden/address@hidden/address@hidden:b

Signed-off-by: Eric Snowberg <address@hidden>
---
 util/setup.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 67 insertions(+), 9 deletions(-)

diff --git a/util/setup.c b/util/setup.c
index 9c1e1b7..7a1db9e 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,21 @@ 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 +568,35 @@ 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 +606,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 +637,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 "
@@ -797,6 +851,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);
 
-- 
1.7.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]