All of lore.kernel.org
 help / color / mirror / Atom feed
From: adrian15 <adrian15sgd@gmail.com>
To: The development of GRUB 2 <grub-devel@gnu.org>
Subject: map command draft #2
Date: Sun, 17 Jun 2007 13:14:16 +0200	[thread overview]
Message-ID: <46751788.8020706@gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 5234 bytes --]

I attach the patch that makes grub2 to have a map command.
The map command only modifies a vector. If we want true map in grub2 we
need to hook some functions so that some bios calls ocurr.

Meanwhile I think how to do it... here there is my patch and some
questions and suggestions.


> diff -urN grub2_2007_05_31_original/commands/i386/pc/map.c grub2_2007_05_31_map/commands/i386/pc/map.c
> --- grub2_2007_05_31_original/commands/i386/pc/map.c	1970-01-01 01:00:00.000000000 +0100
> +++ grub2_2007_05_31_map/commands/i386/pc/map.c	2007-06-17 05:40:39.000000000 +0200
> @@ -0,0 +1,108 @@
> +/* map.c - Define map array  */
> +
> +#include <grub/normal.h>
> +#include <grub/dl.h>
> +#include <grub/arg.h>
> +#include <grub/disk.h>
> +#include <grub/term.h>
> +#include <grub/misc.h>
> +#include <grub/device.h>
> +#include <grub/file.h>
I am including file.h because it includes the function:
grub_file_get_device_name
I think an equivalent function such as:
grub_disk_get_device_name
should be defined in disk.h and implemented where it corresponds to be
implemented.
> +
> +/* The size of the drive map.  */
> +#define DRIVE_MAP_SIZE		16
Is there any bios that supports more than 16 hard disks?
> +/* The BIOS drive map.  */
> +static unsigned short bios_drive_map[DRIVE_MAP_SIZE + 1];
> +
> +int real_map_func (unsigned long to, unsigned long from) {
> +int i;
> +  /* Search for an empty slot in BIOS_DRIVE_MAP.  */
> +  for (i = 0; i < DRIVE_MAP_SIZE; i++)
> +    {
> +      /* Perhaps the user wants to override the map.  */
> +      if ((bios_drive_map[i] & 0xff) == from)
> +	break;
> +      
> +      if (! bios_drive_map[i])
> +	break;
> +    }
> +
> +  if (i == DRIVE_MAP_SIZE)
> +    {
> +      return GRUB_ERR_OUT_OF_RANGE;
> +    }
> +
> +  if (to == from)
> +    /* If TO is equal to FROM, delete the entry.  */
> +    grub_memmove ((char *) &bios_drive_map[i], (char *) &bios_drive_map[i + 1],
> +		  sizeof (unsigned short) * (DRIVE_MAP_SIZE - i));
> +  else
> +    bios_drive_map[i] = from | (to << 8);
> +  
> +  return 0;
> +
> +
> +}
The above code was copy-pasted from grub legacy. Do you think it can be
improved?
> +
> +
> +
> +static grub_err_t
> +grub_cmd_map (struct grub_arg_list *state __attribute__ ((unused)),
> +	       int argc, char **args)
> +{
> +  grub_disk_t map_disk_to,map_disk_from;
> +
> +/* TODO: Check map arguments from grub2 engine */  
> +  if (argc != 2)
> +    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Two devices required");
> +  map_disk_to = grub_disk_open (grub_file_get_device_name(args[0]));
> +  if (! map_disk_to)
> +    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Unknown TO disk");
> +/* This was a marco_g suggestion but it does not make sense to me.
> +  if (grub_strcmp(map_disk_to->name,"biosdisk"))
> +    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "TO disk is not a bios disk.");
> +*/
marco_g ... if I try to grub_printf the disk_to-> name it says hd0. It
does not say "biosdisk" as you have told me.
I am bit confused.
> +  map_disk_from = grub_disk_open (grub_file_get_device_name(args[1]));
> +  if (! map_disk_from)
> +    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Unknown FROM disk");
> +/* This was a marco_g suggestion but it does not make sense to me.
> +  if (grub_strcmp(map_disk_from->name,"biosdisk"))
> +    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "FROM disk is not a bios disk.");
> +*/
Idem for marco_g.

Should I add a function that checks the validity of a hard disk and
asignts it to a grub_disk_t variable and call it twice in order to make
the code smaller ?
> +
> +
> +  return (real_map_func(map_disk_to->id,map_disk_from->id));
> +  
> +}
> +
> +\f
> +GRUB_MOD_INIT(map)
> +{
> +  (void)mod;			/* To stop warning. */
> +  grub_register_command ("map", grub_cmd_map, GRUB_COMMAND_FLAG_BOTH,
> +			 "map TODEVICE FROMDEVICE", "Map a drive to another", 0);
> +}
> +
> +GRUB_MOD_FINI(map)
> +{
> +  grub_unregister_command ("map");
> +}
> diff -urN grub2_2007_05_31_original/conf/i386-pc.rmk grub2_2007_05_31_map/conf/i386-pc.rmk
> --- grub2_2007_05_31_original/conf/i386-pc.rmk	2007-06-11 11:53:27.000000000 +0200
> +++ grub2_2007_05_31_map/conf/i386-pc.rmk	2007-06-14 12:38:00.000000000 +0200
> @@ -1,5 +1,7 @@
>  # -*- makefile -*-
>  
> +
> +
>  COMMON_ASFLAGS = -nostdinc -fno-builtin -m32
>  COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32
>  COMMON_LDFLAGS = -m32 -nostdlib
> @@ -121,7 +123,7 @@
>  pkgdata_MODULES = _chain.mod _linux.mod linux.mod normal.mod \
>  	_multiboot.mod chain.mod multiboot.mod reboot.mod halt.mod	\
>  	vbe.mod vbetest.mod vbeinfo.mod video.mod gfxterm.mod \
> -	videotest.mod play.mod bitmap.mod tga.mod cpuid.mod
> +	videotest.mod map.mod play.mod bitmap.mod tga.mod cpuid.mod
>  
>  # For _chain.mod.
>  _chain_mod_SOURCES = loader/i386/pc/chainloader.c
> @@ -195,6 +197,11 @@
>  vbetest_mod_CFLAGS = $(COMMON_CFLAGS)
>  vbetest_mod_LDFLAGS = $(COMMON_LDFLAGS)
>  
> +# For map.mod.
> +map_mod_SOURCES = commands/i386/pc/map.c
> +map_mod_CFLAGS = $(COMMON_CFLAGS)
> +map_mod_LDFLAGS = $(COMMON_LDFLAGS)
> +
>  # For play.mod.
>  play_mod_SOURCES = commands/i386/pc/play.c
>  play_mod_CFLAGS = $(COMMON_CFLAGS)

Is it important that I also copy-paste the rmk files modifications or not?

adrian15



[-- Attachment #2: map_draft_2.patch --]
[-- Type: text/x-patch, Size: 4749 bytes --]

diff -urN grub2_2007_05_31_original/commands/i386/pc/map.c grub2_2007_05_31_map/commands/i386/pc/map.c
--- grub2_2007_05_31_original/commands/i386/pc/map.c	1970-01-01 01:00:00.000000000 +0100
+++ grub2_2007_05_31_map/commands/i386/pc/map.c	2007-06-17 05:56:15.000000000 +0200
@@ -0,0 +1,107 @@
+/* map.c - Define drives map array  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005  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 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/arg.h>
+#include <grub/disk.h>
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/device.h>
+#include <grub/file.h>
+
+/* The size of the drive map.  */
+#define DRIVE_MAP_SIZE		16
+/* The BIOS drive map.  */
+static unsigned short bios_drive_map[DRIVE_MAP_SIZE + 1];
+
+int real_map_func (unsigned long to, unsigned long from) {
+int i;
+  /* Search for an empty slot in BIOS_DRIVE_MAP.  */
+  for (i = 0; i < DRIVE_MAP_SIZE; i++)
+    {
+      /* Perhaps the user wants to override the map.  */
+      if ((bios_drive_map[i] & 0xff) == from)
+	break;
+      
+      if (! bios_drive_map[i])
+	break;
+    }
+
+  if (i == DRIVE_MAP_SIZE)
+    {
+      return GRUB_ERR_OUT_OF_RANGE;
+    }
+
+  if (to == from)
+    /* If TO is equal to FROM, delete the entry.  */
+    grub_memmove ((char *) &bios_drive_map[i], (char *) &bios_drive_map[i + 1],
+		  sizeof (unsigned short) * (DRIVE_MAP_SIZE - i));
+  else
+    bios_drive_map[i] = from | (to << 8);
+  
+  return 0;
+
+
+}
+
+
+
+static grub_err_t
+grub_cmd_map (struct grub_arg_list *state __attribute__ ((unused)),
+	       int argc, char **args)
+{
+  grub_disk_t map_disk_to,map_disk_from;
+
+/* TODO: Check map arguments from grub2 engine */  
+  if (argc != 2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Two devices required");
+  map_disk_to = grub_disk_open (grub_file_get_device_name(args[0]));
+  if (! map_disk_to)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Unknown TO disk");
+/* This was a marco_g suggestion but it does not make sense to me.
+  if (grub_strcmp(map_disk_to->name,"biosdisk"))
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "TO disk is not a bios disk.");
+*/
+  map_disk_from = grub_disk_open (grub_file_get_device_name(args[1]));
+  if (! map_disk_from)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Unknown FROM disk");
+/* This was a marco_g suggestion but it does not make sense to me.
+  if (grub_strcmp(map_disk_from->name,"biosdisk"))
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "FROM disk is not a bios disk.");
+*/
+
+
+  return (real_map_func(map_disk_to->id,map_disk_from->id));
+  
+}
+
+\f
+GRUB_MOD_INIT(map)
+{
+  (void)mod;			/* To stop warning. */
+  grub_register_command ("map", grub_cmd_map, GRUB_COMMAND_FLAG_BOTH,
+			 "map TODEVICE FROMDEVICE", "Map a drive to another", 0);
+}
+
+GRUB_MOD_FINI(map)
+{
+  grub_unregister_command ("map");
+}

diff -urN grub2_2007_05_31_original/conf/i386-pc.rmk grub2_2007_05_31_map/conf/i386-pc.rmk
--- grub2_2007_05_31_original/conf/i386-pc.rmk	2007-06-11 11:53:27.000000000 +0200
+++ grub2_2007_05_31_map/conf/i386-pc.rmk	2007-06-14 12:38:00.000000000 +0200
@@ -1,5 +1,7 @@
 # -*- makefile -*-
 
+
+
 COMMON_ASFLAGS = -nostdinc -fno-builtin -m32
 COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32
 COMMON_LDFLAGS = -m32 -nostdlib
@@ -121,7 +123,7 @@
 pkgdata_MODULES = _chain.mod _linux.mod linux.mod normal.mod \
 	_multiboot.mod chain.mod multiboot.mod reboot.mod halt.mod	\
 	vbe.mod vbetest.mod vbeinfo.mod video.mod gfxterm.mod \
-	videotest.mod play.mod bitmap.mod tga.mod cpuid.mod
+	videotest.mod map.mod play.mod bitmap.mod tga.mod cpuid.mod
 
 # For _chain.mod.
 _chain_mod_SOURCES = loader/i386/pc/chainloader.c
@@ -195,6 +197,11 @@
 vbetest_mod_CFLAGS = $(COMMON_CFLAGS)
 vbetest_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For map.mod.
+map_mod_SOURCES = commands/i386/pc/map.c
+map_mod_CFLAGS = $(COMMON_CFLAGS)
+map_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For play.mod.
 play_mod_SOURCES = commands/i386/pc/play.c
 play_mod_CFLAGS = $(COMMON_CFLAGS)


                 reply	other threads:[~2007-06-17 11:14 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=46751788.8020706@gmail.com \
    --to=adrian15sgd@gmail.com \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.