grub-devel
[Top][All Lists]
Advanced

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

grub-setup on unmounted fs


From: Tomas Ebenlendr
Subject: grub-setup on unmounted fs
Date: Sat, 12 Jun 2004 03:28:57 +0200
User-agent: Mutt/1.5.6i

I'm lazy to modify my /etc/fstab whenever I change bochs floppy image
(I'm lazy to do 'su root'), so I find solution how test grub without
need 'root' account and /etc/fstab entry:

I patched grub-setup so that it can 'install' grub on unmounted
filesystem when files are on them. I copy files to this fs by mtools.

Here is grub-setup.c patch (diff -u). It implements option '-X' (direct
access to disk) which reads boot.img and core.img by grub filesystem and
writes first two sectors of core.img by direct writing these sectors to
disk. (because grub_disk_write() exists and works)

--- grub2_src/util/i386/pc/grub-setup.c 2004-04-04 15:46:03.000000000 +0200
+++ grub2_work/util/i386/pc/grub-setup.c        2004-06-11 21:34:39.000000000 
+0200
@@ -73,10 +73,64 @@
 {
 }
 
+
+/* direct access wrapper - only solution for not mounted root device
+ *   You can use mtools for access to fat filesystem as ordinar user,
+ *   especially if the filesystem is floppy image, you haven't to
+ *   mount it.*/
+void
+grub_dawrap_init(const char * root, int direct_access)
+{
+  if (direct_access)
+    if (grub_device_set_root(root))
+      grub_util_error ("%s", grub_errmsg);
+}
+
+size_t
+grub_dawrap_get_image_size(const char * path, int direct_access)
+{
+  grub_file_t file;
+  size_t size;
+
+  if (direct_access)
+    {
+      /* Read the boot image by our filesystem.  */
+      file=grub_file_open(path);
+      if (!file)
+       grub_util_error("Cannot open image %s: %s",path,grub_errmsg);
+      size=grub_file_size(file);
+      grub_file_close(file);
+      return size;
+    }
+  else
+    return grub_util_get_image_size(path);
+}
+
+char *
+grub_dawrap_read_image(const char * path, size_t size, int direct_access)
+{
+  grub_file_t file;
+  char * image;
+  if (direct_access)
+    {
+      file=grub_file_open(path);
+      if (!file)
+       grub_util_error("Cannot open image %s: %s",path,grub_errmsg);
+      image = (char *) xmalloc (size);
+      if ((signed) size != grub_file_read(file, image, size))
+       grub_util_error("Cannot read image %s: %s",path,grub_errmsg);
+      grub_file_close(file);
+      return image;
+    }
+  else
+    return grub_util_read_image(path);
+}
+/* -------- */
+
 static void
 setup (const char *prefix, const char *dir,
        const char *boot_file, const char *core_file,
-       const char *root, const char *dest)
+       const char *root, const char *dest, int direct_access)
 {
   char *boot_path, *core_path;
   char *boot_img, *core_img;
@@ -155,23 +209,25 @@
       last_length = length;
       current_segment += GRUB_DISK_SECTOR_SIZE >> 4;
     }
-  
-  /* Read the boot image by the OS service.  */
+
+  /* Read the boot image */
+  grub_dawrap_init(root, direct_access);
   boot_path = grub_util_get_path (dir, boot_file);
-  boot_size = grub_util_get_image_size (boot_path);
+  boot_size = grub_dawrap_get_image_size (boot_path, direct_access);
   if (boot_size != GRUB_DISK_SECTOR_SIZE)
     grub_util_error ("The size of `%s' is not %d",
                     boot_path, GRUB_DISK_SECTOR_SIZE);
-  boot_img = grub_util_read_image (boot_path);
+  boot_img = grub_dawrap_read_image(boot_path, boot_size, direct_access);
   free (boot_path);
 
+
   /* Set the addresses of BOOT_DRIVE and KERNEL_SECTOR.  */
   boot_drive = (grub_uint8_t *) (boot_img + GRUB_BOOT_MACHINE_BOOT_DRIVE);
   kernel_sector = (grub_uint32_t *) (boot_img
                                     + GRUB_BOOT_MACHINE_KERNEL_SECTOR);
   
   core_path = grub_util_get_path (dir, core_file);
-  core_size = grub_util_get_image_size (core_path);
+  core_size = grub_dawrap_get_image_size (core_path, direct_access);
   core_sectors = ((core_size + GRUB_DISK_SECTOR_SIZE - 1)
                  >> GRUB_DISK_SECTOR_BITS);
   if (core_size < GRUB_DISK_SECTOR_SIZE)
@@ -179,7 +235,7 @@
   else if (core_size > 0xFFFF * GRUB_DISK_SECTOR_SIZE)
     grub_util_error ("The size of `%s' is too large", core_path);
   
-  core_img = grub_util_read_image (core_path);
+  core_img = grub_dawrap_read_image (core_path, core_size, direct_access);
   free (core_path);
 
   /* Have FIRST_BLOCK to point to the first blocklist.  */
@@ -409,17 +465,25 @@
     *install_dos_part = *install_bsd_part = grub_cpu_to_le32 (-1);
   
   strcpy (install_prefix, prefix);
-  
-  /* Write the first two sectors of the core image onto the disk.  */
-  core_path = grub_util_get_path (dir, core_file);
-  grub_util_info ("opening the core image `%s'", core_path);
-  fp = fopen (core_path, "r+b");
-  if (! fp)
-    grub_util_error ("Cannot open `%s'", core_path);
 
-  grub_util_write_image (core_img, GRUB_DISK_SECTOR_SIZE * 2, fp);
-  fclose (fp);
-  free (core_path);
+  /* Write the first two sectors of the core image onto the disk.  */
+  if (direct_access)
+    {
+      grub_disk_write(root_dev->disk, first_sector, 0, 
GRUB_DISK_SECTOR_SIZE,core_img);
+      grub_disk_write(root_dev->disk, grub_le_to_cpu16(first_block->start), 0, 
GRUB_DISK_SECTOR_SIZE,core_img+GRUB_DISK_SECTOR_SIZE);
+    }
+  else
+    {
+      core_path = grub_util_get_path (dir, core_file);
+      grub_util_info ("opening the core image `%s'", core_path);
+      fp = fopen (core_path, "r+b");
+      if (! fp)
+       grub_util_error ("Cannot open `%s'", core_path);
+
+      grub_util_write_image (core_img, GRUB_DISK_SECTOR_SIZE * 2, fp);
+      fclose (fp);
+      free (core_path);
+    }
 
   /* Write the boot image onto the disk.  */
   if (grub_disk_write (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, boot_img))
@@ -444,6 +508,7 @@
     {"device-map", required_argument, 0, 'm'},
     {"root-device", required_argument, 0, 'r'},
     {"help", no_argument, 0, 'h'},
+    {"direct-access", no_argument, 0, 'X'},
     {"version", no_argument, 0, 'V'},
     {"verbose", no_argument, 0, 'v'},
     {0, 0, 0, 0}
@@ -466,6 +531,7 @@
   -d, --directory=DIR     use GRUB files in the directory DIR [default=%s]\n\
   -m, --device-map=FILE   use FILE as the device map [default=%s]\n\
   -r, --root-device=DEV   use DEV as the root device [default=guessed]\n\
+  -X, --direct-access     use direct access to disk (dangerous; use for not 
mounted disk images)\n\
   -h, --help              display this message and exit\n\
   -V, --version           print version information and exit\n\
   -v, --verbose           print verbose messages\n\
@@ -500,13 +566,14 @@
   char *root_dev = 0;
   char *prefix;
   char *dest_dev;
+  int direct_access = 0;
   
   progname = "grub-setup";
 
   /* Check for options.  */
   while (1)
     {
-      int c = getopt_long (argc, argv, "b:c:d:m:r:hVv", options, 0);
+      int c = getopt_long (argc, argv, "b:c:d:m:r:XhVv", options, 0);
 
       if (c == -1)
        break;
@@ -547,6 +614,10 @@
 
            root_dev = xstrdup (optarg);
            break;
+
+         case 'X':
+           direct_access = 1;
+           break;
            
          case 'h':
            usage (0);
@@ -587,7 +658,10 @@
       usage (1);
     }
 
-  prefix = grub_get_prefix (dir ? : DEFAULT_DIRECTORY);
+  if (direct_access)
+    prefix = dir;
+  else
+    prefix = grub_get_prefix (dir ? : DEFAULT_DIRECTORY);
   
   /* Initialize the emulated biosdisk driver.  */
   grub_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP);
@@ -623,7 +697,7 @@
         dir ? : DEFAULT_DIRECTORY,
         boot_file ? : DEFAULT_BOOT_FILE,
         core_file ? : DEFAULT_CORE_FILE,
-        root_dev, dest_dev);
+        root_dev, dest_dev, direct_access);
 
   /* Free resources.  */
   grub_ext2_fini ();
----------------- end of patch ----------------

here is my .mtoolsrc:
drive b: file="/home/ebik/.bochs/dos_floppy.img" exclusive

Bochs is set to have this image in drive a: and to boot from it.

./device.map is set to hve (fd0) as this drive. I'm installing grub with
following command:
    mcopy <files> b:/<grub-dir>
    grub-setup -X -r '(fd0)' -d <grub-dir> -m ./device-map '(fd0)'

Where <grub-dir> is absolute path provided that '/' is the root directory of
'(fd0)' (root device).
In <files> are included modules as well as boot.img and core.img.
-- 
                                 Tomas 'ebi' Ebenlendr
                                 http://get.to/ebik
                                 PF 2004.44571148932





reply via email to

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