diff --git a/ChangeLog b/ChangeLog index 6496b924c..4c84761c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2004-09-17 Marco Gerards + + Add `linux.mod' and `multiboot.mod' so linux and multiboot kernels + can be loaded from normal mode. + + * conf/i386-pc.rmk (pkgdata_MODULES): Add `linux.mod' and + `multiboot.mod'. + (linux_mod_SOURCES, linux_mod_CFLAGS, multiboot_mod_SOURCES) + (multiboot_mod_CFLAGS): New variables. + * loader/i386/pc/linux_normal.c: New file. + * loader/i386/pc/multiboot_normal.c: Likewise. + + * loader/i386/pc/linux.c (grub_rescue_cmd_initrd): Don't use the + attribute `unused'. + + * fs/ext2.c (grub_ext2_iterate_dir): Fix typos in inode type. Use + `fdiro' to read the mode information from instead of `diro'. + + * fs/fshelp.c (grub_fshelp_find_file): Set type to foundtype after + looking up a symlink. + + * include/grub/normal.h (GRUB_COMMAND_FLAG_NO_ARG_PARSE): New + macro. + * normal/command.c (grub_command_execute): Don't parse the + arguments when `GRUB_COMMAND_FLAG_NO_ARG_PARSE' is set in the + flags of the command. + + * normal/menu.c (grub_menu_run): Fix typo. + 2004-09-14 Hollis Blanchard * kern/powerpc/ieee1275/init.c (abort): Trap into Open Firmware. diff --git a/conf/i386-pc.mk b/conf/i386-pc.mk index 828df9de0..80b8145cc 100644 --- a/conf/i386-pc.mk +++ b/conf/i386-pc.mk @@ -786,9 +786,9 @@ genmoddep-util_genmoddep.d: util/genmoddep.c # Modules. -pkgdata_MODULES = _chain.mod _linux.mod fat.mod ufs.mod ext2.mod minix.mod \ +pkgdata_MODULES = _chain.mod _linux.mod linux.mod fat.mod ufs.mod ext2.mod minix.mod \ hfs.mod jfs.mod normal.mod hello.mod vga.mod font.mod _multiboot.mod ls.mod \ - boot.mod cmp.mod cat.mod terminal.mod fshelp.mod chain.mod + boot.mod cmp.mod cat.mod terminal.mod fshelp.mod chain.mod multiboot.mod # For _chain.mod. _chain_mod_SOURCES = loader/i386/pc/chainloader.c @@ -1179,6 +1179,45 @@ _linux_mod-loader_i386_pc_linux.d: loader/i386/pc/linux.c -include _linux_mod-loader_i386_pc_linux.d _linux_mod_CFLAGS = $(COMMON_CFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/i386/pc/linux_normal.c +CLEANFILES += linux.mod mod-linux.o mod-linux.c pre-linux.o linux_mod-loader_i386_pc_linux_normal.o def-linux.lst und-linux.lst +MOSTLYCLEANFILES += linux_mod-loader_i386_pc_linux_normal.d +DEFSYMFILES += def-linux.lst +UNDSYMFILES += und-linux.lst + +linux.mod: pre-linux.o mod-linux.o + -rm -f $@ + $(LD) -r -o $@ $^ + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@ + +pre-linux.o: linux_mod-loader_i386_pc_linux_normal.o + -rm -f $@ + $(LD) -r -o $@ $^ + +mod-linux.o: mod-linux.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(linux_mod_CFLAGS) -c -o $@ $< + +mod-linux.c: moddep.lst genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'linux' $< > $@ || (rm -f $@; exit 1) + +def-linux.lst: pre-linux.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 linux/' > $@ + +und-linux.lst: pre-linux.o + echo 'linux' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +linux_mod-loader_i386_pc_linux_normal.o: loader/i386/pc/linux_normal.c + $(CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(CPPFLAGS) $(CFLAGS) $(linux_mod_CFLAGS) -c -o $@ $< + +linux_mod-loader_i386_pc_linux_normal.d: loader/i386/pc/linux_normal.c + set -e; $(CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(CPPFLAGS) $(CFLAGS) $(linux_mod_CFLAGS) -M $< | sed 's,linux_normal\.o[ :]*,linux_mod-loader_i386_pc_linux_normal.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include linux_mod-loader_i386_pc_linux_normal.d + +linux_mod_CFLAGS = $(COMMON_CFLAGS) # For normal.mod. normal_mod_SOURCES = normal/cmdline.c normal/command.c normal/main.c \ @@ -1611,6 +1650,45 @@ _multiboot_mod-loader_i386_pc_multiboot.d: loader/i386/pc/multiboot.c -include _multiboot_mod-loader_i386_pc_multiboot.d _multiboot_mod_CFLAGS = $(COMMON_CFLAGS) + +# For multiboot.mod. +multiboot_mod_SOURCES = loader/i386/pc/multiboot_normal.c +CLEANFILES += multiboot.mod mod-multiboot.o mod-multiboot.c pre-multiboot.o multiboot_mod-loader_i386_pc_multiboot_normal.o def-multiboot.lst und-multiboot.lst +MOSTLYCLEANFILES += multiboot_mod-loader_i386_pc_multiboot_normal.d +DEFSYMFILES += def-multiboot.lst +UNDSYMFILES += und-multiboot.lst + +multiboot.mod: pre-multiboot.o mod-multiboot.o + -rm -f $@ + $(LD) -r -o $@ $^ + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@ + +pre-multiboot.o: multiboot_mod-loader_i386_pc_multiboot_normal.o + -rm -f $@ + $(LD) -r -o $@ $^ + +mod-multiboot.o: mod-multiboot.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(multiboot_mod_CFLAGS) -c -o $@ $< + +mod-multiboot.c: moddep.lst genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'multiboot' $< > $@ || (rm -f $@; exit 1) + +def-multiboot.lst: pre-multiboot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 multiboot/' > $@ + +und-multiboot.lst: pre-multiboot.o + echo 'multiboot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +multiboot_mod-loader_i386_pc_multiboot_normal.o: loader/i386/pc/multiboot_normal.c + $(CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(CPPFLAGS) $(CFLAGS) $(multiboot_mod_CFLAGS) -c -o $@ $< + +multiboot_mod-loader_i386_pc_multiboot_normal.d: loader/i386/pc/multiboot_normal.c + set -e; $(CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(CPPFLAGS) $(CFLAGS) $(multiboot_mod_CFLAGS) -M $< | sed 's,multiboot_normal\.o[ :]*,multiboot_mod-loader_i386_pc_multiboot_normal.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include multiboot_mod-loader_i386_pc_multiboot_normal.d + +multiboot_mod_CFLAGS = $(COMMON_CFLAGS) CLEANFILES += moddep.lst pkgdata_DATA += moddep.lst moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 1e5d20af5..41f562f69 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -78,9 +78,9 @@ grub_emu_LDFLAGS = -lncurses genmoddep_SOURCES = util/genmoddep.c # Modules. -pkgdata_MODULES = _chain.mod _linux.mod fat.mod ufs.mod ext2.mod minix.mod \ +pkgdata_MODULES = _chain.mod _linux.mod linux.mod fat.mod ufs.mod ext2.mod minix.mod \ hfs.mod jfs.mod normal.mod hello.mod vga.mod font.mod _multiboot.mod ls.mod \ - boot.mod cmp.mod cat.mod terminal.mod fshelp.mod chain.mod + boot.mod cmp.mod cat.mod terminal.mod fshelp.mod chain.mod multiboot.mod # For _chain.mod. _chain_mod_SOURCES = loader/i386/pc/chainloader.c @@ -121,6 +121,10 @@ jfs_mod_CFLAGS = $(COMMON_CFLAGS) # For _linux.mod. _linux_mod_SOURCES = loader/i386/pc/linux.c _linux_mod_CFLAGS = $(COMMON_CFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/i386/pc/linux_normal.c +linux_mod_CFLAGS = $(COMMON_CFLAGS) # For normal.mod. normal_mod_SOURCES = normal/cmdline.c normal/command.c normal/main.c \ @@ -163,3 +167,7 @@ font_mod_CFLAGS = $(COMMON_CFLAGS) # For _multiboot.mod. _multiboot_mod_SOURCES = loader/i386/pc/multiboot.c _multiboot_mod_CFLAGS = $(COMMON_CFLAGS) + +# For multiboot.mod. +multiboot_mod_SOURCES = loader/i386/pc/multiboot_normal.c +multiboot_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/fs/ext2.c b/fs/ext2.c index c82eb17bf..056f38ac1 100644 --- a/fs/ext2.c +++ b/fs/ext2.c @@ -451,14 +451,14 @@ grub_ext2_iterate_dir (grub_fshelp_node_t dir, fdiro->inode_read = 1; - if ((grub_le_to_cpu16 (diro->inode.mode) + if ((grub_le_to_cpu16 (fdiro->inode.mode) & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY) type = GRUB_FSHELP_DIR; - else if ((grub_le_to_cpu16 (diro->inode.mode) - & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY) + else if ((grub_le_to_cpu16 (fdiro->inode.mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK) type = GRUB_FSHELP_SYMLINK; - else if ((grub_le_to_cpu16 (diro->inode.mode) - & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY) + else if ((grub_le_to_cpu16 (fdiro->inode.mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_REG) type = GRUB_FSHELP_REG; } diff --git a/fs/fshelp.c b/fs/fshelp.c index 45f8f9d56..bc838d223 100644 --- a/fs/fshelp.c +++ b/fs/fshelp.c @@ -171,6 +171,7 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, /* Lookup the node the symlink points to. */ find_file (symlink, oldnode, &currnode); + type = foundtype; grub_free (symlink); if (grub_errno) diff --git a/include/grub/normal.h b/include/grub/normal.h index 665fb85c8..ee53daa10 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -39,6 +39,8 @@ #define GRUB_COMMAND_FLAG_TITLE 0x4 /* Don't print the command on booting. */ #define GRUB_COMMAND_FLAG_NO_ECHO 0x8 +/* Don't print the command on booting. */ +#define GRUB_COMMAND_FLAG_NO_ARG_PARSE 0x10 /* The command description. */ struct grub_command diff --git a/loader/i386/pc/linux.c b/loader/i386/pc/linux.c index 5f2276c49..50369cebb 100644 --- a/loader/i386/pc/linux.c +++ b/loader/i386/pc/linux.c @@ -290,8 +290,7 @@ grub_rescue_cmd_linux (int argc, char *argv[]) } void -grub_rescue_cmd_initrd (int argc __attribute__ ((unused)), - char *argv[] __attribute__ ((unused))) +grub_rescue_cmd_initrd (int argc, char *argv[]) { grub_file_t file = 0; grub_ssize_t size; diff --git a/loader/i386/pc/linux_normal.c b/loader/i386/pc/linux_normal.c new file mode 100644 index 000000000..00e9cea95 --- /dev/null +++ b/loader/i386/pc/linux_normal.c @@ -0,0 +1,61 @@ +/* linux_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 +#include +#include +#include + +static grub_err_t +grub_normal_linux_command (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_linux (argc, args); + return grub_errno; +} + + +static grub_err_t +grub_normal_initrd_command (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_initrd (argc, args); + return grub_errno; +} + +GRUB_MOD_INIT +{ + (void) mod; /* To stop warning. */ + grub_register_command ("linux", grub_normal_linux_command, + GRUB_COMMAND_FLAG_BOTH, + "linux FILE [ARGS...]", + "Load linux", 0); + + grub_register_command ("initrd", grub_normal_initrd_command, + GRUB_COMMAND_FLAG_BOTH, + "initrd FILE", + "Load initrd", 0); +} + +GRUB_MOD_FINI +{ + grub_unregister_command ("linux"); + grub_unregister_command ("initrd"); +} diff --git a/loader/i386/pc/multiboot_normal.c b/loader/i386/pc/multiboot_normal.c new file mode 100644 index 000000000..38605742c --- /dev/null +++ b/loader/i386/pc/multiboot_normal.c @@ -0,0 +1,61 @@ +/* multiboot_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 +#include +#include +#include + +static grub_err_t +grub_normal_cmd_multiboot (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_multiboot (argc, args); + return grub_errno; +} + + +static grub_err_t +grub_normal_cmd_module (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_module (argc, args); + return grub_errno; +} + +GRUB_MOD_INIT +{ + (void) mod; /* To stop warning. */ + grub_register_command ("multiboot", grub_normal_cmd_multiboot, + GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, + "multiboot FILE [ARGS...]", + "Load a multiboot kernel", 0); + + grub_register_command ("module", grub_normal_cmd_module, + GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, + "multiboot FILE [ARGS...]", + "Load a multiboot module", 0); +} + +GRUB_MOD_FINI +{ + grub_unregister_command ("multiboot"); + grub_unregister_command ("module"); +} diff --git a/normal/command.c b/normal/command.c index d26392759..e6c397ce9 100644 --- a/normal/command.c +++ b/normal/command.c @@ -160,8 +160,14 @@ grub_command_execute (char *cmdline) state = grub_malloc (sizeof (struct grub_arg_list) * maxargs); grub_memset (state, 0, sizeof (struct grub_arg_list) * maxargs); - if (grub_arg_parse (cmd, num, &args[1], state, &arglist, &numargs)) - ret = (cmd->func) (state, numargs, arglist); + if (! (cmd->flags & GRUB_COMMAND_FLAG_NO_ARG_PARSE)) + { + if (grub_arg_parse (cmd, num, &args[1], state, &arglist, &numargs)) + ret = (cmd->func) (state, numargs, arglist); + } + else + ret = (cmd->func) (state, num, &args[1]); + grub_free (state); if (pager && (! grub_strcmp (pager, "1"))) diff --git a/normal/menu.c b/normal/menu.c index f001b11ab..5d720adda 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -357,7 +357,7 @@ grub_menu_run (grub_menu_t menu, int nested) run_menu_entry (e); /* Deal with a fallback entry. */ - /* FIXME: Mutiple fallback entries like GRUB Legacy. */ + /* FIXME: Multiple fallback entries like GRUB Legacy. */ if (menu->fallback_entry >= 0) { grub_print_error ();