grub-devel
[Top][All Lists]
Advanced

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

normal mode chainloader


From: Tomas Ebenlendr
Subject: normal mode chainloader
Date: Mon, 21 Jun 2004 20:00:05 +0200
User-agent: Mutt/1.5.6i

Here is patch that implements command chainloader in normal mode. It may be
done wrong way, but it is something to talk about. I successfully tested it
on bochs. (In fact it is so simple, that it must work.). I added an artifical
symbol to boot.mod to get dependency of normal mode loader commands on the
boot command.

P.S. Being offline is good. Result is one e-mail instead of 5 mails or more
as I did before.

P.P.S. I saw somewhere (in archive) that I should probably subscribe
        something for FSF. I don't understand this legal stuff, I
        subscribe anything good for this piece of sw if needed.
        (But I have no electronic signature yet :-(, I didn't need any.)

Notes on architecture dependent files:
        I dislike how architecture dependent files (headers, conf/*.rmk)
        are copied or cut&pasted between architectures. In fact my opinion
        is that body of function may be architecture dependent, then it
        should be in architecture dir. But the interface (the prototype of
        the function) is architecture independent and so it shouldn't be
        in architecture dir (now I'm talking about loader.h).

        I didn't touched this because I want to know your opinion.
        (Try diff -rup include/grub/{i386/pc;powerpc/ieee1275} )

        Files are same probably because powerpc is not too far from
        ibm-pc. But I think they shouldn't be copied. They should be
        somehow shared. (Ok, it is not easy to find `name' for common
        code (directory), but I think that same files should be linked
        and nearly same files should include common part.)

        Folowing patch modifies only i386/pc architecture, but I think
        that exactly same changes should be done in powerpc files.

Changelog:
2004-06-21  Tomas Ebenlendr  <address@hidden>

        Added normal mode command `chainloader' as module chain.mod,
        which depends on normal.mod and _chain.mod. There is also added
        dependency to boot.mod because of semantic dependency of these
        commands.

        * commands/boot.c: Add symbol grub_boot_dependency, used for
        semantic dependency of commands.
        * conf/i386-pc.rmk: Add i386/pc/chainloader_normal.c as
        chain.mod.
        * include/grub/boot_cmd.h: New file. The semantic dependency
        of loader commands and boot command.
        * include/grub/i386/pc/chainloader.h: New file. Exports
        body of chainloader command.
        * include/grub/i386/pc/loader.h: added FIXME, deleted prototype
        of rescue command chainloader.
        * loader/i386/pc/chainloader.c (grub_rescue_cmd_chainloader):
        all but arguments parsing moved to ...
        (grub_chainloader_cmd): ... this.
        * loader/i386/pc/chainloader_normal.c: New file. Defines the
        command chainloader.


diff -rupN -x CVS grub2_x/commands/boot.c grub2_work/commands/boot.c
--- grub2_x/commands/boot.c     2004-06-05 00:20:17.000000000 +0200
+++ grub2_work/commands/boot.c  2004-06-21 01:42:05.000000000 +0200
@@ -24,6 +24,8 @@
 #include <grub/misc.h>
 #include <grub/loader.h>
 
+int grub_boot_dependency;
+
 static grub_err_t
 grub_cmd_boot (struct grub_arg_list *state __attribute__ ((unused)),
               int argc, char **args __attribute__ ((unused)))
@@ -54,6 +56,8 @@ grub_boot_fini (void)
 GRUB_MOD_INIT
 {
   (void)mod;                   /* To stop warning. */
+  grub_boot_dependency = 1; /* To let be loader commands dependent on this 
command
+                              (don't let gcc optimize off this symbol) */
   grub_register_command ("boot", grub_cmd_boot, GRUB_COMMAND_FLAG_BOTH,
                         "boot", "Boot an operating system", 0);
 }
diff -rupN -x CVS grub2_x/conf/i386-pc.mk grub2_work/conf/i386-pc.mk
--- grub2_x/conf/i386-pc.mk     2004-06-05 00:20:17.000000000 +0200
+++ grub2_work/conf/i386-pc.mk  2004-06-21 01:16:47.000000000 +0200
@@ -717,7 +717,7 @@ genmoddep-util_genmoddep.d: util/genmodd
 
 # Modules.
 pkgdata_MODULES = _chain.mod _linux.mod fat.mod ufs.mod ext2.mod minix.mod 
normal.mod hello.mod \
-        vga.mod font.mod _multiboot.mod ls.mod boot.mod cmp.mod cat.mod 
terminal.mod
+        vga.mod font.mod _multiboot.mod ls.mod boot.mod cmp.mod cat.mod 
terminal.mod chain.mod
 
 # For _chain.mod.
 _chain_mod_SOURCES = loader/i386/pc/chainloader.c
@@ -758,6 +758,45 @@ _chain_mod-loader_i386_pc_chainloader.d:
 
 _chain_mod_CFLAGS = $(COMMON_CFLAGS)
 
+# For chain.mod.
+chain_mod_SOURCES = loader/i386/pc/chainloader_normal.c
+CLEANFILES += chain.mod mod-chain.o mod-chain.c pre-chain.o 
chain_mod-loader_i386_pc_chainloader_normal.o def-chain.lst und-chain.lst
+MOSTLYCLEANFILES += chain_mod-loader_i386_pc_chainloader_normal.d
+DEFSYMFILES += def-chain.lst
+UNDSYMFILES += und-chain.lst
+
+chain.mod: pre-chain.o mod-chain.o
+       -rm -f $@
+       $(LD) -r -o $@ $^
+       $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R 
.comment $@
+
+pre-chain.o: chain_mod-loader_i386_pc_chainloader_normal.o
+       -rm -f $@
+       $(LD) -r -o $@ $^
+
+mod-chain.o: mod-chain.c
+       $(CC) $(CPPFLAGS) $(CFLAGS) $(chain_mod_CFLAGS) -c -o $@ $<
+
+mod-chain.c: moddep.lst genmodsrc.sh
+       sh $(srcdir)/genmodsrc.sh 'chain' $< > $@ || (rm -f $@; exit 1)
+
+def-chain.lst: pre-chain.o
+       $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 chain/' > $@
+
+und-chain.lst: pre-chain.o
+       echo 'chain' > $@
+       $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+chain_mod-loader_i386_pc_chainloader_normal.o: 
loader/i386/pc/chainloader_normal.c
+       $(CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(CPPFLAGS) $(CFLAGS) 
$(chain_mod_CFLAGS) -c -o $@ $<
+
+chain_mod-loader_i386_pc_chainloader_normal.d: 
loader/i386/pc/chainloader_normal.c
+       set -e;           $(CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc 
$(CPPFLAGS) $(CFLAGS) $(chain_mod_CFLAGS) -M $<       | sed 
's,chainloader_normal\.o[ :]*,chain_mod-loader_i386_pc_chainloader_normal.o $@ 
: ,g' > $@;        [ -s $@ ] || rm -f $@
+
+-include chain_mod-loader_i386_pc_chainloader_normal.d
+
+chain_mod_CFLAGS = $(COMMON_CFLAGS)
+
 # For fat.mod.
 fat_mod_SOURCES = fs/fat.c
 CLEANFILES += fat.mod mod-fat.o mod-fat.c pre-fat.o fat_mod-fs_fat.o 
def-fat.lst und-fat.lst
diff -rupN -x CVS grub2_x/conf/i386-pc.rmk grub2_work/conf/i386-pc.rmk
--- grub2_x/conf/i386-pc.rmk    2004-06-05 00:20:17.000000000 +0200
+++ grub2_work/conf/i386-pc.rmk 2004-06-21 01:16:12.000000000 +0200
@@ -74,12 +74,16 @@ genmoddep_SOURCES = util/genmoddep.c
 
 # Modules.
 pkgdata_MODULES = _chain.mod _linux.mod fat.mod ufs.mod ext2.mod minix.mod 
normal.mod hello.mod \
-        vga.mod font.mod _multiboot.mod ls.mod boot.mod cmp.mod cat.mod 
terminal.mod
+        vga.mod font.mod _multiboot.mod ls.mod boot.mod cmp.mod cat.mod 
terminal.mod chain.mod
 
 # For _chain.mod.
 _chain_mod_SOURCES = loader/i386/pc/chainloader.c
 _chain_mod_CFLAGS = $(COMMON_CFLAGS)
 
+# For chain.mod.
+chain_mod_SOURCES = loader/i386/pc/chainloader_normal.c
+chain_mod_CFLAGS = $(COMMON_CFLAGS)
+
 # For fat.mod.
 fat_mod_SOURCES = fs/fat.c
 fat_mod_CFLAGS = $(COMMON_CFLAGS)
diff -rupN -x CVS grub2_x/include/grub/boot_cmd.h 
grub2_work/include/grub/boot_cmd.h
--- grub2_x/include/grub/boot_cmd.h     1970-01-01 01:00:00.000000000 +0100
+++ grub2_work/include/grub/boot_cmd.h  2004-06-21 01:33:53.000000000 +0200
@@ -0,0 +1,26 @@
+/* This file is intended as command dependency */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002  Free Software Foundation, Inc.
+ *
+ *  This program 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GRUB_BOOT_CMD_HEADER
+#define GRUB_BOOT_CMD_HEADER   1
+
+extern int EXPORT_VAR(grub_boot_dependency);
+
+#endif /* ! GRUB_BOOT_CMD_HEADER */
diff -rupN -x CVS grub2_x/include/grub/i386/pc/chainloader.h 
grub2_work/include/grub/i386/pc/chainloader.h
--- grub2_x/include/grub/i386/pc/chainloader.h  1970-01-01 01:00:00.000000000 
+0100
+++ grub2_work/include/grub/i386/pc/chainloader.h       2004-06-21 
01:19:52.000000000 +0200
@@ -0,0 +1,34 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004  Free Software Foundation, Inc.
+ *
+ *  This program 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GRUB_CHAINLOADER_MACHINE_HEADER
+#define GRUB_CHAINLOADER_MACHINE_HEADER        1
+
+#include <grub/dl.h>
+
+/* common function for normal and rescue mode commands*/
+typedef enum
+  {
+    GRUB_CHAINLOADER_FORCE = 0x1
+  }
+grub_chainloader_flags_t;
+
+void EXPORT_FUNC(grub_chainloader_cmd) (const char * 
file,grub_chainloader_flags_t flags);
+
+#endif /* ! GRUB_CHAINLOADER_MACHINE_HEADER */
diff -rupN -x CVS grub2_x/include/grub/i386/pc/loader.h 
grub2_work/include/grub/i386/pc/loader.h
--- grub2_x/include/grub/i386/pc/loader.h       2004-06-05 00:20:17.000000000 
+0200
+++ grub2_work/include/grub/i386/pc/loader.h    2004-06-21 01:50:48.000000000 
+0200
@@ -41,7 +41,8 @@ void EXPORT_FUNC(grub_multiboot_real_boo
 
 /* It is necessary to export these functions, because normal mode commands
    reuse rescue mode commands.  */
-void grub_rescue_cmd_chainloader (int argc, char *argv[]);
+/* FIXME these commands should be divided to argument parsing and real work, 
and moved to
+ * respective headers*/
 void grub_rescue_cmd_linux (int argc, char *argv[]);
 void grub_rescue_cmd_initrd (int argc, char *argv[]);
 void grub_rescue_cmd_multiboot (int argc, char *argv[]);
diff -rupN -x CVS grub2_x/loader/i386/pc/chainloader.c 
grub2_work/loader/i386/pc/chainloader.c
--- grub2_x/loader/i386/pc/chainloader.c        2004-06-05 00:20:18.000000000 
+0200
+++ grub2_work/loader/i386/pc/chainloader.c     2004-06-21 00:41:54.000000000 
+0200
@@ -20,6 +20,7 @@
 
 #include <grub/loader.h>
 #include <grub/machine/loader.h>
+#include <grub/machine/chainloader.h>
 #include <grub/file.h>
 #include <grub/err.h>
 #include <grub/device.h>
@@ -82,28 +83,15 @@ grub_chainloader_unload (void)
 }
 
 void
-grub_rescue_cmd_chainloader (int argc, char *argv[])
+grub_chainloader_cmd(const char * filename, grub_chainloader_flags_t flags)
 {
   grub_file_t file = 0;
   grub_uint16_t signature;
-  int force = 0;
 
   grub_dl_ref (my_mod);
   
-  if (argc > 0 && grub_strcmp (argv[0], "--force") == 0)
-    {
-      force = 1;
-      argc--;
-      argv++;
-    }
 
-  if (argc == 0)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
-      goto fail;
-    }
-
-  file = grub_file_open (argv[0]);
+  file = grub_file_open (filename);
   if (! file)
     goto fail;
 
@@ -119,7 +107,7 @@ grub_rescue_cmd_chainloader (int argc, c
 
   /* Check the signature.  */
   signature = *((grub_uint16_t *) (0x7C00 + GRUB_DISK_SECTOR_SIZE - 2));
-  if (signature != grub_le_to_cpu16 (0xaa55) && ! force)
+  if (signature != grub_le_to_cpu16 (0xaa55) && ! (flags & 
GRUB_CHAINLOADER_FORCE) )
     {
       grub_error (GRUB_ERR_BAD_OS, "invalid signature");
       goto fail;
@@ -137,6 +125,25 @@ grub_rescue_cmd_chainloader (int argc, c
   grub_dl_unref (my_mod);
 }
 
+static void
+grub_rescue_cmd_chainloader (int argc, char *argv[])
+{
+  grub_chainloader_flags_t flags = 0;
+
+  if (argc > 0 && grub_strcmp (argv[0], "--force") == 0)
+    {
+      flags |= GRUB_CHAINLOADER_FORCE;
+      argc--;
+      argv++;
+    }
+
+  if (argc == 0)
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
+  else
+    grub_chainloader_cmd(argv[0],flags);
+}
+
+
 static const char loader_name[] = "chainloader";
 
 GRUB_MOD_INIT
diff -rupN -x CVS grub2_x/loader/i386/pc/chainloader_normal.c 
grub2_work/loader/i386/pc/chainloader_normal.c
--- grub2_x/loader/i386/pc/chainloader_normal.c 1970-01-01 01:00:00.000000000 
+0100
+++ grub2_work/loader/i386/pc/chainloader_normal.c      2004-06-21 
01:42:45.000000000 +0200
@@ -0,0 +1,57 @@
+/* chainloader_normal.c - boot another boot loader */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004  Free Software Foundation, Inc.
+ *
+ *  This program 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/machine/chainloader.h>
+#include <grub/err.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/boot_cmd.h>
+
+static const struct grub_arg_option options[] =
+  {
+    {"force", 'f', 0, "Skip bootsector magic number test.", 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static grub_err_t
+chainloader_command (struct grub_arg_list *state,
+                    int argc, char **args)
+{
+  grub_chainloader_flags_t flags = state[0].set ? GRUB_CHAINLOADER_FORCE : 0 ;
+  if (argc == 0)
+    grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
+  else
+    grub_chainloader_cmd(args[0],flags);
+  return grub_errno;
+}
+
+GRUB_MOD_INIT
+{
+  (void)mod; /*To stop warning */
+  grub_boot_dependency = 1; /* To be dependent on boot command
+                              (don't let gcc optimize off this symbol) */
+  grub_register_command ("chainloader", chainloader_command, 
GRUB_COMMAND_FLAG_BOTH,
+                        "chainloader [options] FILE", "Prepare to boot another 
boot loader", options);
+}
+
+GRUB_MOD_FINI
+{
+  grub_unregister_command ("chainloader");
+}
-- 
                                 Tomas 'ebi' Ebenlendr
                                 http://get.to/ebik
                                 PF 2004.47027429923





reply via email to

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