[Top][All Lists]
[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
- normal mode chainloader,
Tomas Ebenlendr <=
Re: normal mode chainloader, Tomas Ebenlendr, 2004/06/22