All of lore.kernel.org
 help / color / mirror / Atom feed
* normal mode chainloader
@ 2004-06-21 18:00 Tomas Ebenlendr
  2004-06-22  9:00 ` Marco Gerards
  0 siblings, 1 reply; 37+ messages in thread
From: Tomas Ebenlendr @ 2004-06-21 18:00 UTC (permalink / raw)
  To: grub-devel


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  <ebik@ucw.cz>

	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




^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2004-11-22 15:29 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-06-21 18:00 normal mode chainloader Tomas Ebenlendr
2004-06-22  9:00 ` Marco Gerards
2004-06-22 11:33   ` Tomas Ebenlendr
2004-06-22 19:52     ` Marco Gerards
2004-06-23  7:10       ` Tomas Ebenlendr
2004-06-23 10:34         ` Yoshinori K. Okuji
2004-06-23 10:40           ` Tomas Ebenlendr
2004-06-22 11:41   ` Tomas Ebenlendr
2004-06-22 20:25     ` Marco Gerards
2004-06-23  7:29       ` Tomas Ebenlendr
2004-06-23 10:55         ` Marco Gerards
2004-06-23 17:20           ` Jeroen Dekkers
2004-06-23  8:11       ` Copyright crap Was: " Tomas Ebenlendr
2004-06-23  8:59         ` Jeroen Dekkers
2004-06-23 10:43           ` Tomas Ebenlendr
2004-06-23 11:58       ` Tomas Ebenlendr
2004-06-23 16:49         ` Marco Gerards
2004-06-24  8:44           ` Tomas Ebenlendr
2004-06-24 15:26             ` Marco Gerards
2004-06-24 16:51               ` Tomas Ebenlendr
2004-07-01 10:54                 ` Marco Gerards
2004-07-01 11:17                   ` Yoshinori K. Okuji
2004-07-01 11:53                     ` Tomas Ebenlendr
2004-07-01 13:30                       ` Marco Gerards
2004-07-01 16:03                         ` history, autoloading was: " Tomas Ebenlendr
2004-09-10 22:05                         ` Marco Gerards
2004-09-12 12:46         ` Marco Gerards
2004-09-17 18:48           ` Tomas Ebenlendr
2004-09-17 18:53             ` M. Gerards
2004-09-17 19:32               ` Tomas Ebenlendr
2004-09-17 19:38                 ` M. Gerards
2004-09-20  6:58                   ` Tomas Ebenlendr
2004-09-21  8:22                     ` Module loading - grub-emu, bug in kern/dl.c Tomas Ebenlendr
2004-11-17 15:43                       ` Marco Gerards
2004-11-17 20:30                         ` Tomas Ebenlendr
2004-11-17 20:45                           ` Marco Gerards
2004-11-22 15:18                         ` Timothy Baldwin

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.