The internal of the command handling is heavily modified, and a new command help is added.

This commit is contained in:
okuji 1999-09-05 05:54:33 +00:00
parent 20d2c3d284
commit 6608e1b9e2
13 changed files with 2026 additions and 1004 deletions

View file

@ -1,3 +1,85 @@
1999-09-05 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
The internal of the command handling is heavily modified, and
a new command "help" is added.
* stage1/stage1.S: Set the number of sectors for Stage 2 to 110.
* stage1/stage1_lba.S: Likewise.
* stage2/builtins.c: New file.
* stage2/Makefile.am (libgrub_a_SOURCES): Added builtins.c.
(stage2_exec_SOURCES): Likewise.
* stage2/boot.c (load_image): Return kernel_t instead int.
(bsd_boot): Change the type of the first argument to kernel_t.
* stage2/char_io.c (get_cmdline): Do not accept the argument
COMMANDS and accept the argument COMPLETION.
Print completions only if COMPLETION is non-zero.
Print the list of short docs when the command is completed.
* stage2/cmdline.c [GRUB_UTIL]: Do not include apic.h and
smp-imps.h.
(fallback): Deleted.
(password): Likewise.
(debug): Likewise.
(normal_color): Likewise.
(highlight_color): Likewise.
(print_cmdline_message): New function.
(commands): Deleted.
(debug_fs_print_func): Likewise.
(installaddr): Likewise.
(installlist): Likewise.
(installsect): Likewise.
(debug_fs_blocklist_func): Likewise.
(find_command): New function.
(init_cmdline): Initialize the data for the command-line
interface. The function to print the message is moved to
print_cmdline_message.
(enter_cmdline): Rewritten from scratch. Now deal with only the
pure command-line and the function to deal with a menu entry is
moved to run_script.
(run_script): New function.
* stage2/shared.h (PASSWORD_BUF): New macro.
(PASSWORD_BUFLEN): Likewise.
(CMDLINE_BUF): Likewise.
(CMDLINE_BUFLEN): Likewise.
(MENU_BUF): Likewise.
(MENU_BUFLEN): Likewise.
(fallback): Deleted.
(fallback_entry): Declared.
(default_entry): Likewise.
(BUILTIN_CMDLINE): New macro.
(BUILTIN_MENU): Likewise.
(BUILTIN_TITLE): Likewise.
(struct builtin): New tag.
(builtin_table): Declared.
(cmdline_t): Deleted.
(kernel_t): New type.
(kernel_type): Declared.
(grub_timeout): Likewise.
(init_builtins): Likewise.
(init_config): Likewise.
(find_command): Likewise.
(print_cmdline_message): Likewise.
(run_script): Likewise.
[!STAGE1_5] (bsd_boot): Deleted.
[!STAGE1_5] (load_image): Likewise.
[!STAGE1_5] (load_module): Likewise.
[!STAGE1_5] (load_initrd): Likewise.
* stage2/size_test: Set the maximum size of Stage 2 to 56320.
* stage2/stage2.c (grub_timeout): Deleted.
(menu_t): Likewise.
(run_menu): Changed the return type to void.
Use FALLBACK_ENTRY instead of FALLBACK.
Do not check the return value of enter_cmdline.
(run_menu) [GRUB_UTIL]: Call stop instead of returning
MENU_ABORT.
(cmain): Set MENU_ENTRIES to MENU_BUF.
Call init_config instead of clearing the variables directly.
Use CMDLINE_BUF for the command-line buffer instead of the
stack.
Adapted the analysis routine for the configuration file to the
new builtin commands interface.
Run enter_cmdline forever.
If run_menu returns, restart the loop.
1999-09-04 Pavel Roskin <pavel_roskin@geocities.com>
* docs/menu.lst: More meaningful examples. Not using (0x80,0)

3
NEWS
View file

@ -10,6 +10,9 @@ New in 0.5.93:
* New commands "hide" and "unhide".
* The character `=' after a command is not necessary any longer, but it
is supported for backward compatibility.
* The command "help" displays helpful information about builtin
commands.
* The command "geometry" displays the information of a drive specified.
New in 0.5.92 - 1999-07-26:
* Bug fixes (i.e. Stage 1.5 can work fine again).

View file

@ -398,7 +398,7 @@ lastlist:
#else
.long 1 /* this is the sector start parameter, in logical
sectors from the start of the disk, sector 0 */
.word 90 /* this is the number of sectors to read */
.word 110 /* this is the number of sectors to read */
.word 0x0800 /* this is the segment of the starting address
to load the data into */
#endif

View file

@ -345,7 +345,7 @@ lastlist:
#else
.long 1 /* this is the sector start parameter, in logical
sectors from the start of the disk, sector 0 */
.word 90 /* this is the number of sectors to read */
.word 110 /* this is the number of sectors to read */
.word 0x0800 /* this is the segment of the starting address
to load the data into */
#endif

View file

@ -13,9 +13,9 @@ INCLUDES = -I$(top_srcdir)/stage1
# The library for /sbin/grub.
noinst_LIBRARIES = libgrub.a
libgrub_a_SOURCES = boot.c common.c char_io.c cmdline.c disk_io.c \
gunzip.c fsys_ffs.c fsys_ext2fs.c fsys_fat.c fsys_minix.c \
stage2.c
libgrub_a_SOURCES = boot.c builtins.c common.c char_io.c cmdline.c \
disk_io.c gunzip.c fsys_ffs.c fsys_ext2fs.c fsys_fat.c \
fsys_minix.c stage2.c
libgrub_a_CFLAGS = $(GRUB_CFLAGS) -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 \
-DFSYS_FAT=1 -DFSYS_FFS=1 -DFSYS_MINIX=1 -fwritable-strings
@ -37,9 +37,9 @@ STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1 \
# asm.S absolutely needs to come first!
# For stage2 target.
stage2_exec_SOURCES = asm.S boot.c common.c char_io.c cmdline.c \
disk_io.c gunzip.c stage2.c bios.c smp-imps.c fsys_ext2fs.c \
fsys_fat.c fsys_ffs.c fsys_minix.c
stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c common.c \
char_io.c cmdline.c disk_io.c gunzip.c fsys_ext2fs.c \
fsys_fat.c fsys_ffs.c fsys_minix.c smp-imps.c stage2.c
stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
stage2_exec_LDFLAGS = $(STAGE2_LINK)

View file

@ -94,9 +94,9 @@ INCLUDES = -I$(top_srcdir)/stage1
# The library for /sbin/grub.
noinst_LIBRARIES = libgrub.a
libgrub_a_SOURCES = boot.c common.c char_io.c cmdline.c disk_io.c \
gunzip.c fsys_ffs.c fsys_ext2fs.c fsys_fat.c fsys_minix.c \
stage2.c
libgrub_a_SOURCES = boot.c builtins.c common.c char_io.c cmdline.c \
disk_io.c gunzip.c fsys_ffs.c fsys_ext2fs.c fsys_fat.c \
fsys_minix.c stage2.c
libgrub_a_CFLAGS = $(GRUB_CFLAGS) -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 \
-DFSYS_FAT=1 -DFSYS_FFS=1 -DFSYS_MINIX=1 -fwritable-strings
@ -123,9 +123,9 @@ STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1 \
# asm.S absolutely needs to come first!
# For stage2 target.
stage2_exec_SOURCES = asm.S boot.c common.c char_io.c cmdline.c \
disk_io.c gunzip.c stage2.c bios.c smp-imps.c fsys_ext2fs.c \
fsys_fat.c fsys_ffs.c fsys_minix.c
stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c common.c \
char_io.c cmdline.c disk_io.c gunzip.c fsys_ext2fs.c \
fsys_fat.c fsys_ffs.c fsys_minix.c smp-imps.c stage2.c
stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
stage2_exec_LDFLAGS = $(STAGE2_LINK)
@ -176,10 +176,11 @@ LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libgrub_a_AR = $(AR) cru
libgrub_a_LIBADD =
am_libgrub_a_OBJECTS = libgrub_a-boot.o libgrub_a-common.o \
libgrub_a-char_io.o libgrub_a-cmdline.o libgrub_a-disk_io.o \
libgrub_a-gunzip.o libgrub_a-fsys_ffs.o libgrub_a-fsys_ext2fs.o \
libgrub_a-fsys_fat.o libgrub_a-fsys_minix.o libgrub_a-stage2.o
am_libgrub_a_OBJECTS = libgrub_a-boot.o libgrub_a-builtins.o \
libgrub_a-common.o libgrub_a-char_io.o libgrub_a-cmdline.o \
libgrub_a-disk_io.o libgrub_a-gunzip.o libgrub_a-fsys_ffs.o \
libgrub_a-fsys_ext2fs.o libgrub_a-fsys_fat.o libgrub_a-fsys_minix.o \
libgrub_a-stage2.o
libgrub_a_OBJECTS = $(am_libgrub_a_OBJECTS)
AR = ar
PROGRAMS = $(noinst_PROGRAMS)
@ -212,11 +213,12 @@ minix_stage1_5_exec-fsys_minix.o minix_stage1_5_exec-bios.o
minix_stage1_5_exec_OBJECTS = $(am_minix_stage1_5_exec_OBJECTS)
minix_stage1_5_exec_LDADD = $(LDADD)
minix_stage1_5_exec_DEPENDENCIES =
am_stage2_exec_OBJECTS = stage2_exec-asm.o stage2_exec-boot.o \
stage2_exec-common.o stage2_exec-char_io.o stage2_exec-cmdline.o \
stage2_exec-disk_io.o stage2_exec-gunzip.o stage2_exec-stage2.o \
stage2_exec-bios.o stage2_exec-smp-imps.o stage2_exec-fsys_ext2fs.o \
stage2_exec-fsys_fat.o stage2_exec-fsys_ffs.o stage2_exec-fsys_minix.o
am_stage2_exec_OBJECTS = stage2_exec-asm.o stage2_exec-bios.o \
stage2_exec-boot.o stage2_exec-builtins.o stage2_exec-common.o \
stage2_exec-char_io.o stage2_exec-cmdline.o stage2_exec-disk_io.o \
stage2_exec-gunzip.o stage2_exec-fsys_ext2fs.o stage2_exec-fsys_fat.o \
stage2_exec-fsys_ffs.o stage2_exec-fsys_minix.o stage2_exec-smp-imps.o \
stage2_exec-stage2.o
stage2_exec_OBJECTS = $(am_stage2_exec_OBJECTS)
stage2_exec_LDADD = $(LDADD)
stage2_exec_DEPENDENCIES =
@ -239,10 +241,11 @@ DIST_COMMON = $(noinst_HEADERS) Makefile.am Makefile.in compile
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
GZIP_ENV = --best
DEP_FILES = .deps/asm.P .deps/bios.P .deps/boot.P .deps/char_io.P \
.deps/cmdline.P .deps/common.P .deps/disk_io.P .deps/fsys_ext2fs.P \
.deps/fsys_fat.P .deps/fsys_ffs.P .deps/fsys_minix.P .deps/gunzip.P \
.deps/smp-imps.P .deps/stage1_5.P .deps/stage2.P
DEP_FILES = .deps/asm.P .deps/bios.P .deps/boot.P .deps/builtins.P \
.deps/char_io.P .deps/cmdline.P .deps/common.P .deps/disk_io.P \
.deps/fsys_ext2fs.P .deps/fsys_fat.P .deps/fsys_ffs.P \
.deps/fsys_minix.P .deps/gunzip.P .deps/smp-imps.P .deps/stage1_5.P \
.deps/stage2.P
SOURCES = $(libgrub_a_SOURCES) $(e2fs_stage1_5_exec_SOURCES) $(fat_stage1_5_exec_SOURCES) $(ffs_stage1_5_exec_SOURCES) $(minix_stage1_5_exec_SOURCES) $(stage2_exec_SOURCES)
OBJECTS = $(am_libgrub_a_OBJECTS) $(am_e2fs_stage1_5_exec_OBJECTS) $(am_fat_stage1_5_exec_OBJECTS) $(am_ffs_stage1_5_exec_OBJECTS) $(am_minix_stage1_5_exec_OBJECTS) $(am_stage2_exec_OBJECTS)
@ -276,6 +279,7 @@ distclean-compile:
maintainer-clean-compile:
libgrub_a-boot.o: boot.c
libgrub_a-builtins.o: builtins.c
libgrub_a-common.o: common.c
libgrub_a-char_io.o: char_io.c
libgrub_a-cmdline.o: cmdline.c
@ -350,19 +354,20 @@ minix_stage1_5.exec: $(minix_stage1_5_exec_OBJECTS) $(minix_stage1_5_exec_DEPEND
$(LINK) $(minix_stage1_5_exec_LDFLAGS) $(minix_stage1_5_exec_OBJECTS) $(minix_stage1_5_exec_LDADD) $(LIBS)
stage2_exec-asm.o: asm.S
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o stage2_exec-asm.o $<
stage2_exec-bios.o: bios.c
stage2_exec-boot.o: boot.c
stage2_exec-builtins.o: builtins.c
stage2_exec-common.o: common.c
stage2_exec-char_io.o: char_io.c
stage2_exec-cmdline.o: cmdline.c
stage2_exec-disk_io.o: disk_io.c
stage2_exec-gunzip.o: gunzip.c
stage2_exec-stage2.o: stage2.c
stage2_exec-bios.o: bios.c
stage2_exec-smp-imps.o: smp-imps.c
stage2_exec-fsys_ext2fs.o: fsys_ext2fs.c
stage2_exec-fsys_fat.o: fsys_fat.c
stage2_exec-fsys_ffs.o: fsys_ffs.c
stage2_exec-fsys_minix.o: fsys_minix.c
stage2_exec-smp-imps.o: smp-imps.c
stage2_exec-stage2.o: stage2.c
stage2.exec: $(stage2_exec_OBJECTS) $(stage2_exec_DEPENDENCIES)
@rm -f stage2.exec
@ -493,6 +498,25 @@ libgrub_a-boot.lo: boot.c
>> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp
libgrub_a-builtins.o: builtins.c
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm .deps/$(*D)/$(*F).pp
libgrub_a-builtins.lo: builtins.c
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp
libgrub_a-common.o: common.c
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@ -1139,6 +1163,25 @@ minix_stage1_5_exec-bios.lo: bios.c
>> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp
stage2_exec-bios.o: bios.c
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm .deps/$(*D)/$(*F).pp
stage2_exec-bios.lo: bios.c
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp
stage2_exec-boot.o: boot.c
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@ -1158,6 +1201,25 @@ stage2_exec-boot.lo: boot.c
>> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp
stage2_exec-builtins.o: builtins.c
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm .deps/$(*D)/$(*F).pp
stage2_exec-builtins.lo: builtins.c
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp
stage2_exec-common.o: common.c
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@ -1253,63 +1315,6 @@ stage2_exec-gunzip.lo: gunzip.c
>> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp
stage2_exec-stage2.o: stage2.c
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm .deps/$(*D)/$(*F).pp
stage2_exec-stage2.lo: stage2.c
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp
stage2_exec-bios.o: bios.c
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm .deps/$(*D)/$(*F).pp
stage2_exec-bios.lo: bios.c
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp
stage2_exec-smp-imps.o: smp-imps.c
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm .deps/$(*D)/$(*F).pp
stage2_exec-smp-imps.lo: smp-imps.c
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp
stage2_exec-fsys_ext2fs.o: fsys_ext2fs.c
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@ -1385,6 +1390,44 @@ stage2_exec-fsys_minix.lo: fsys_minix.c
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp
stage2_exec-smp-imps.o: smp-imps.c
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm .deps/$(*D)/$(*F).pp
stage2_exec-smp-imps.lo: smp-imps.c
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp
stage2_exec-stage2.o: stage2.c
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@-cp .deps/$(*D)/$(*F).pp .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm .deps/$(*D)/$(*F).pp
stage2_exec-stage2.lo: stage2.c
@echo '$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -Wp,-MD,.deps/$(*D)/$(*F).pp -c -o $@ $<
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
< .deps/$(*D)/$(*F).pp > .deps/$(*D)/$(*F).P; \
tr ' ' '\012' < .deps/$(*D)/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp
check-TESTS: $(TESTS)
@failed=0; all=0; xfail=0; xpass=0; \
srcdir=$(srcdir); export srcdir; \

View file

@ -38,10 +38,11 @@ static struct mod_list mll[99];
* of the gory details of loading in a bootable image and the modules.
*/
int
kernel_t
load_image (char *kernel, char *arg)
{
int len, i, exec_type = 0, align_4k = 1, type = 0;
int len, i, exec_type = 0, align_4k = 1;
kernel_t type = KERNEL_TYPE_NONE;
unsigned long flags = 0, text_len = 0, data_len = 0, bss_len = 0;
char *str = 0, *str2 = 0;
union
@ -60,14 +61,14 @@ load_image (char *kernel, char *arg)
pu.aout = (struct exec *) buffer;
if (!grub_open (kernel))
return 0;
return KERNEL_TYPE_NONE;
if (!(len = grub_read (buffer, MULTIBOOT_SEARCH)) || len < 32)
{
if (!errnum)
errnum = ERR_EXEC_FORMAT;
return 0;
return KERNEL_TYPE_NONE;
}
for (i = 0; i < len; i++)
@ -78,20 +79,21 @@ load_image (char *kernel, char *arg)
if (flags & MULTIBOOT_UNSUPPORTED)
{
errnum = ERR_BOOT_FEATURES;
return 0;
return KERNEL_TYPE_NONE;
}
type = 'm';
type = KERNEL_TYPE_MULTIBOOT;
str2 = "Multiboot";
break;
}
}
/* ELF loading supported if multiboot and FreeBSD. */
if ((type == 'm' || grub_strcmp (pu.elf->e_ident + EI_BRAND, "FreeBSD") == 0)
if ((type == KERNEL_TYPE_MULTIBOOT
|| grub_strcmp (pu.elf->e_ident + EI_BRAND, "FreeBSD") == 0)
&& len > sizeof (Elf32_Ehdr)
&& BOOTABLE_I386_ELF ((*((Elf32_Ehdr *) buffer))))
{
if (type == 'm')
if (type == KERNEL_TYPE_MULTIBOOT)
entry_addr = (entry_func) pu.elf->e_entry;
else
entry_addr = (entry_func) (pu.elf->e_entry & 0xFFFFFF);
@ -107,10 +109,10 @@ load_image (char *kernel, char *arg)
errnum = ERR_EXEC_FORMAT;
str = "elf";
if (! type)
if (type == KERNEL_TYPE_NONE)
{
str2 = "FreeBSD";
type = 'f';
type = KERNEL_TYPE_FREEBSD;
}
}
else if (flags & MULTIBOOT_AOUT_KLUDGE)
@ -141,7 +143,7 @@ load_image (char *kernel, char *arg)
{
entry_addr = (entry_func) pu.aout->a_entry;
if (!type)
if (type == KERNEL_TYPE_NONE)
{
/*
* If it doesn't have a Multiboot header, then presume
@ -156,13 +158,13 @@ load_image (char *kernel, char *arg)
*/
if (buffer[0] == 0xb && buffer[1] == 1)
{
type = 'f';
type = KERNEL_TYPE_FREEBSD;
entry_addr = (entry_func) (((int) entry_addr) & 0xFFFFFF);
str2 = "FreeBSD";
}
else
{
type = 'n';
type = KERNEL_TYPE_NETBSD;
entry_addr = (entry_func) (((int) entry_addr) & 0xF00000);
if (N_GETMAGIC ((*(pu.aout))) != NMAGIC)
align_4k = 0;
@ -200,7 +202,7 @@ load_image (char *kernel, char *arg)
{
printf (" linux 'zImage' kernel too big, try 'make bzImage'\n");
errnum = ERR_WONT_FIT;
return 0;
return KERNEL_TYPE_NONE;
}
printf (" [Linux-%s, setup=0x%x, size=0x%x]\n",
@ -232,7 +234,7 @@ load_image (char *kernel, char *arg)
else
/* ERRNUM is already set inside the function
safe_parse_maxint. */
return 0;
return KERNEL_TYPE_NONE;
/* Set the vid mode to VID_MODE. Note that this can work
because i386 architecture is little-endian. */
@ -275,7 +277,7 @@ load_image (char *kernel, char *arg)
cur_addr = LINUX_STAGING_AREA + text_len;
if (grub_read ((char *) LINUX_STAGING_AREA, text_len) >= (text_len - 16))
return (big_linux ? 'L' : 'l');
return (big_linux ? KERNEL_TYPE_BIG_LINUX : KERNEL_TYPE_LINUX);
else if (!errnum)
errnum = ERR_EXEC_FORMAT;
}
@ -287,7 +289,7 @@ load_image (char *kernel, char *arg)
/* return if error */
if (errnum)
return 0;
return KERNEL_TYPE_NONE;
/* fill the multiboot info structure */
mbi.cmdline = (int) arg;
@ -419,7 +421,7 @@ load_image (char *kernel, char *arg)
filepos = phdr->p_offset;
filesiz = phdr->p_filesz;
if (type == 'f')
if (type == KERNEL_TYPE_FREEBSD)
memaddr = RAW_ADDR (phdr->p_paddr & 0xFFFFFF);
else
memaddr = RAW_ADDR (phdr->p_paddr);
@ -466,7 +468,7 @@ load_image (char *kernel, char *arg)
else
{
putchar ('\n');
type = 0;
type = KERNEL_TYPE_NONE;
}
return type;
@ -543,7 +545,7 @@ bsd_boot_entry (int flags, int bootdev, int sym_start, int sym_end,
void
bsd_boot (int type, int bootdev, char *arg)
bsd_boot (kernel_t type, int bootdev, char *arg)
{
char *str;
int clval = 0, i;
@ -588,7 +590,7 @@ bsd_boot (int type, int bootdev, char *arg)
str++;
}
if (type == 'f')
if (type == KERNEL_TYPE_FREEBSD)
{
clval |= RB_BOOTINFO;

1398
stage2/builtins.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -147,8 +147,8 @@ init_page (void)
If ECHO_CHAR is nonzero, echo it instead of the typed character. */
int
get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen,
int echo_char)
get_cmdline (char *prompt, char *cmdline, int maxlen,
int echo_char, int completion)
{
int ystart, yend, xend, lpos, c;
int plen = 0;
@ -259,6 +259,7 @@ get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen,
case 27: /* ESC immediately return 1 */
return 1;
case 9: /* TAB lists completions */
if (completion)
{
int i, j = 0, llen_old = llen;
@ -268,7 +269,8 @@ get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen,
while (cmdline[j] && cmdline[j] != '=' && cmdline[j] != ' ')
j++;
/* since the command line cannot have a '\n', we're OK to use c */
/* Since the command line cannot have a '\n', we're OK to
use C. */
c = cmdline[lpos];
cl_kill_to_end ();
@ -278,6 +280,7 @@ get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen,
putchar ('\n');
gotoxy (0, getxy () & 0xff);
if (lpos > j)
{
for (i = lpos; i > 0 && cmdline[i - 1] != ' '; i--);
@ -290,8 +293,21 @@ get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen,
while (cmdline[lpos])
lpos++, llen_old++;
}
else if (commands)
printf (commands);
else
{
/* Print the command list. */
struct builtin **builtin;
for (builtin = builtin_table; *builtin != 0; builtin++)
{
/* Do not print the name if it cannot be run in
the command-line interface. */
if (! ((*builtin)->flags & BUILTIN_CMDLINE))
continue;
grub_printf ("%s ", (*builtin)->name);
}
}
/* restore command-line */
cmdline[lpos] = c;

View file

@ -21,25 +21,6 @@
#include "shared.h"
#ifndef GRUB_UTIL
# include "apic.h"
# include "smp-imps.h"
#endif
/*
* These are used for determining if the command-line should ask the user
* to correct errors during scripts.
*/
int fallback;
char *password;
/* True when the debug mode is turned on, and false when it is turned off. */
int debug = 0;
/* Color settings */
int normal_color;
int highlight_color;
/* Find the next word from CMDLINE and return the pointer. If
AFTER_EQUAL is non-zero, assume that the character `=' is treated as
a space. Caution: this assumption is for backward compatibility. */
@ -66,679 +47,149 @@ skip_to (int after_equal, char *cmdline)
void
init_cmdline (void)
print_cmdline_message (void)
{
printf (" [ Minimal BASH-like line editing is supported. For the first word, TAB
lists possible command completions. Anywhere else TAB lists the possible
completions of a device/filename. ESC at any time exits. ]\n");
}
char commands[] =
" Possible commands are: \"pause ...\", \"uppermem <kbytes>\", \"root <device>\",
\"rootnoverify <device>\", \"chainloader <file>\", \"kernel <file> ...\",
\"testload <file>\", \"read <addr>\", \"displaymem\", \"impsprobe\",
\"geometry <drive>\", \"hide <device>\", \"unhide <device>\",
\"fstest\", \"debug\", \"module <file> ...\", \"modulenounzip <file> ...\",
\"color <normal> [<highlight>]\", \"makeactive\", \"boot\", \"quit\" and
\"install <stage1_file> [d] <dest_dev> <file> <addr> [p] [<config_file>]\"\n";
/* Find the builtin whose command name is COMMAND and return the
pointer. If not found, return 0. */
struct builtin *
find_command (char *command)
{
char *ptr;
char c;
struct builtin **builtin;
/* Find the first space and terminate the command name. */
ptr = command;
while (*ptr && *ptr != ' ' && *ptr != '=')
ptr++;
c = *ptr;
*ptr = 0;
/* Seek out the builtin whose command name is COMMAND. */
for (builtin = builtin_table; *builtin != 0; builtin++)
{
if (grub_strcmp (command, (*builtin)->name) == 0)
{
*ptr = c;
return *builtin;
}
}
/* Cannot find COMMAND. */
errnum = ERR_UNRECOGNIZED;
*ptr = c;
return 0;
}
static void
debug_fs_print_func (int sector)
init_cmdline (void)
{
printf ("[%d]", sector);
}
static int installaddr, installlist, installsect;
static void
debug_fs_blocklist_func (int sector)
{
if (debug)
printf("[%d]", sector);
if (*((unsigned long *)(installlist-4))
+ *((unsigned short *)installlist) != sector
|| installlist == BOOTSEC_LOCATION+STAGE1_FIRSTLIST+4)
{
installlist -= 8;
if (*((unsigned long *)(installlist-8)))
errnum = ERR_WONT_FIT;
else
{
*((unsigned short *)(installlist+2)) = (installaddr >> 4);
*((unsigned long *)(installlist-4)) = sector;
}
}
*((unsigned short *)installlist) += 1;
installsect = sector;
installaddr += 512;
}
/* Run the command-line interface or execute a command from SCRIPT if
SCRIPT is not NULL. Return CMDLINE_OK if successful, CMDLINE_ABORT
if ``quit'' command is executed, and CMDLINE_ERROR if an error
occures or ESC is pushed. */
cmdline_t
enter_cmdline (char *script, char *heap)
{
int bootdev, cmd_len, type = 0, run_cmdline = 1, have_run_cmdline = 0;
char *cur_heap = heap, *cur_entry = script, *old_entry;
char *mb_cmdline = (char *) MB_CMDLINE_BUF;
/* initialization */
/* Initialization. */
saved_drive = boot_drive;
saved_partition = install_partition;
current_drive = 0xFF;
errnum = 0;
/* restore memory probe state */
/* Restore memory probe state. */
mbi.mem_upper = saved_mem_upper;
if (mbi.mmap_length)
mbi.flags |= MB_INFO_MEM_MAP;
/* BSD and chainloading evil hacks !! */
bootdev = set_bootdev(0);
if (!script)
{
init_page();
init_cmdline();
init_builtins ();
}
restart:
if (script)
void
enter_cmdline (char *heap)
{
/* Initialize the data and print a message. */
init_cmdline ();
init_page ();
print_cmdline_message ();
while (1)
{
struct builtin *builtin;
char *arg;
*heap = 0;
print_error ();
/* Get the command-line with the minimal BASH-like interface. */
if (get_cmdline (PACKAGE "> ", heap, 2048, 0, 1))
return;
builtin = find_command (heap);
if (! builtin)
continue;
if (! (builtin->flags & BUILTIN_CMDLINE))
{
errnum = ERR_UNRECOGNIZED;
continue;
}
arg = skip_to (1, heap);
(builtin->func) (arg, BUILTIN_CMDLINE);
}
}
int
run_script (char *script, char *heap)
{
char *old_entry;
char *cur_entry = script;
/* Initialize the data. */
init_cmdline ();
while (1)
{
struct builtin *builtin;
char *arg;
print_error ();
if (errnum)
{
if (fallback < 0)
goto returnit;
print_error();
if (password || errnum == ERR_BOOT_COMMAND)
{
printf("Press any key to continue...");
if (fallback_entry < 0)
return 1;
grub_printf ("Press any key to continue...");
(void) getkey ();
returnit:
return CMDLINE_OK;
return 1;
}
run_cmdline = 1;
if (!have_run_cmdline)
{
have_run_cmdline = 1;
putchar('\n');
init_cmdline();
}
}
else
{
run_cmdline = 0;
/* update position in the boot script */
old_entry = cur_entry;
while (*(cur_entry++));
while (*cur_entry++)
;
/* copy to work area */
memmove (cur_heap, old_entry, ((int)cur_entry) - ((int)old_entry));
grub_memmove (heap, old_entry, (int) cur_entry - (int) old_entry);
grub_printf ("%s\n", old_entry);
printf("%s\n", old_entry);
}
}
else
if (! *heap)
{
cur_heap[0] = 0;
print_error();
if (kernel_type == KERNEL_TYPE_NONE)
return 0;
grub_memmove (heap, "boot", 5);
}
if (run_cmdline && get_cmdline (PACKAGE "> ", commands, cur_heap, 2048, 0))
return CMDLINE_ERROR;
builtin = find_command (heap);
if (! builtin)
continue;
if (substring ("boot", cur_heap) == 0 || (script && !*cur_heap))
if (! (builtin->flags & BUILTIN_CMDLINE))
{
if ((type == 'f') | (type == 'n'))
bsd_boot (type, bootdev, (char *) MB_CMDLINE_BUF);
if (type == 'l')
linux_boot ();
if (type == 'L')
big_linux_boot ();
if (type == 'c')
{
gateA20 (0);
boot_drive = saved_drive;
chain_stage1 (0, BOOTSEC_LOCATION, BOOTSEC_LOCATION-16);
}
if (!type)
{
errnum = ERR_BOOT_COMMAND;
goto restart;
}
/* this is the final possibility */
multi_boot((int)entry_addr, (int)(&mbi));
}
/* get clipped command-line */
cur_cmdline = skip_to(1, cur_heap);
cmd_len = 0;
while (cur_cmdline[cmd_len++]);
if (substring("chainloader", cur_heap) < 1)
{
if (grub_open (cur_cmdline) &&
(grub_read ((char *) BOOTSEC_LOCATION, SECTOR_SIZE) == SECTOR_SIZE) &&
(*((unsigned short *) (BOOTSEC_LOCATION+BOOTSEC_SIG_OFFSET))
== BOOTSEC_SIGNATURE))
type = 'c';
else if (!errnum)
{
errnum = ERR_EXEC_FORMAT;
type = 0;
}
}
else if (substring("pause", cur_heap) < 1)
{
if (ASCII_CHAR (getkey ()) == 27)
return CMDLINE_ERROR;
}
else if (substring("uppermem", cur_heap) < 1)
{
if (safe_parse_maxint(&cur_cmdline, (int *)&(mbi.mem_upper)))
mbi.flags &= ~MB_INFO_MEM_MAP;
}
else if (substring("root", cur_heap) < 1)
{
int hdbias = 0;
char *next_cmd = set_device (cur_cmdline);
if (next_cmd)
{
char *biasptr = skip_to (0, next_cmd);
/* this will respond to any "rootn<XXX>" command,
but that's OK */
if (!errnum && (cur_heap[4] == 'n' || open_device()
|| errnum == ERR_FSYS_MOUNT))
{
errnum = 0;
saved_partition = current_partition;
saved_drive = current_drive;
if (cur_heap[4] != 'n')
{
/* BSD and chainloading evil hacks !! */
safe_parse_maxint(&biasptr, &hdbias);
errnum = 0;
bootdev = set_bootdev(hdbias);
print_fsys_type();
}
else
current_drive = -1;
}
}
}
else if (substring ("kernel", cur_heap) < 1)
{
/* Reset MB_CMDLINE. */
mb_cmdline = (char *) MB_CMDLINE_BUF;
if (cmd_len + 1 > MB_CMDLINE_BUFLEN)
errnum = ERR_WONT_FIT;
else
{
/* Copy the command-line to MB_CMDLINE. */
grub_memmove (mb_cmdline, cur_cmdline, cmd_len + 1);
if ((type = load_image (cur_cmdline, mb_cmdline)) != 0)
mb_cmdline += cmd_len + 1;
}
}
else if (substring ("module", cur_heap) < 1)
{
if (type == 'm')
{
#ifndef NO_DECOMPRESSION
/* this will respond to any "modulen<XXX>" command,
but that's OK */
if (cur_heap[6] == 'n')
no_decompression = 1;
#endif /* NO_DECOMPRESSION */
if (mb_cmdline + cmd_len + 1
> (char *) MB_CMDLINE_BUF + MB_CMDLINE_BUFLEN)
errnum = ERR_WONT_FIT;
else
{
/* Copy the command-line to MB_CMDLINE. */
grub_memmove (mb_cmdline, cur_cmdline, cmd_len + 1);
if (load_module (cur_cmdline, mb_cmdline))
mb_cmdline += cmd_len + 1;
}
#ifndef NO_DECOMPRESSION
no_decompression = 0;
#endif /* NO_DECOMPRESSION */
}
else if (type == 'L' || type == 'l')
{
load_initrd (cur_cmdline);
}
else
errnum = ERR_NEED_MB_KERNEL;
}
else if (substring("initrd", cur_heap) < 1)
{
if (type == 'L' || type == 'l')
{
load_initrd (cur_cmdline);
}
else
errnum = ERR_NEED_LX_KERNEL;
}
else if (substring("install", cur_heap) < 1)
{
char *stage1_file = cur_cmdline, *dest_dev, *file, *addr;
char buffer[SECTOR_SIZE], old_sect[SECTOR_SIZE];
int new_drive = 0xFF;
dest_dev = skip_to(0, stage1_file);
if (*dest_dev == 'd')
{
new_drive = 0;
dest_dev = skip_to(0, dest_dev);
}
file = skip_to (0, dest_dev);
addr = skip_to (0, file);
if (safe_parse_maxint (&addr, &installaddr) &&
grub_open (stage1_file) &&
grub_read (buffer, SECTOR_SIZE) == SECTOR_SIZE &&
set_device (dest_dev) && open_partition () &&
devread (0, 0, SECTOR_SIZE, old_sect))
{
int dest_drive = current_drive;
struct geometry dest_geom = buf_geom;
int dest_sector = part_start, i;
#ifndef NO_DECOMPRESSION
no_decompression = 1;
#endif
/* copy possible DOS BPB, 59 bytes at byte offset 3 */
memmove (buffer+BOOTSEC_BPB_OFFSET, old_sect+BOOTSEC_BPB_OFFSET,
BOOTSEC_BPB_LENGTH);
/* if for a hard disk, copy possible MBR/extended part table */
if ((dest_drive & 0x80) && current_partition == 0xFFFFFF)
memmove (buffer+BOOTSEC_PART_OFFSET, old_sect+BOOTSEC_PART_OFFSET,
BOOTSEC_PART_LENGTH);
if (*((short *)(buffer+STAGE1_VER_MAJ_OFFS)) != COMPAT_VERSION
|| (*((unsigned short *) (buffer+BOOTSEC_SIG_OFFSET))
!= BOOTSEC_SIGNATURE)
|| (!(dest_drive & 0x80)
&& (*((unsigned char *) (buffer+BOOTSEC_PART_OFFSET)) == 0x80
|| buffer[BOOTSEC_PART_OFFSET] == 0)))
{
errnum = ERR_BAD_VERSION;
}
else if (grub_open (file))
{
/* If STAGE1_FILE is the LBA version, do a sanity check. */
if (buffer[STAGE1_ID_OFFSET] == STAGE1_ID_LBA)
{
/* The geometry of the drive in which FILE is located. */
struct geometry load_geom;
/* Check if CURRENT_DRIVE is a floppy disk. */
if (! (current_drive & 0x80))
{
errnum = ERR_DEV_VALUES;
goto install_failure;
}
/* Get the geometry of CURRENT_DRIVE. */
if (get_diskinfo (current_drive, &load_geom))
{
errnum = ERR_NO_DISK;
goto install_failure;
}
#ifdef GRUB_UTIL
/* XXX Can we determine if LBA is supported in
/sbin/grub as well? */
grub_printf ("Warning: make sure that the access mode for "
"(hd%d) is LBA.\n", current_drive - 0x80);
#else
/* Check if LBA is supported. */
if (! (load_geom.flags & BIOSDISK_FLAG_LBA_EXTENSION))
{
errnum = ERR_DEV_VALUES;
goto install_failure;
}
#endif
}
if (!new_drive)
new_drive = current_drive;
memmove ((char*)BOOTSEC_LOCATION, buffer, SECTOR_SIZE);
*((unsigned char *)(BOOTSEC_LOCATION+STAGE1_FIRSTLIST))
= new_drive;
*((unsigned short *)(BOOTSEC_LOCATION+STAGE1_INSTALLADDR))
= installaddr;
i = BOOTSEC_LOCATION+STAGE1_FIRSTLIST-4;
while (*((unsigned long *)i))
{
if (i < BOOTSEC_LOCATION+STAGE1_FIRSTLIST-256
|| (*((int *)(i-4)) & 0x80000000)
|| *((unsigned short *)i) >= 0xA00
|| *((short *) (i+2)) == 0)
{
errnum = ERR_BAD_VERSION;
break;
}
*((int *)i) = 0;
*((int *)(i-4)) = 0;
i -= 8;
}
installlist = BOOTSEC_LOCATION+STAGE1_FIRSTLIST+4;
debug_fs = debug_fs_blocklist_func;
if (!errnum &&
grub_read ((char *) SCRATCHADDR, SECTOR_SIZE) == SECTOR_SIZE)
{
if (*((short *)(SCRATCHADDR+STAGE2_VER_MAJ_OFFS))
!= COMPAT_VERSION)
errnum = ERR_BAD_VERSION;
else
{
int write_stage2_sect = 0, stage2_sect = installsect;
char *ptr;
ptr = skip_to(0, addr);
if (*ptr == 'p')
{
write_stage2_sect++;
*((long *)(SCRATCHADDR+STAGE2_INSTALLPART))
= current_partition;
ptr = skip_to(0, ptr);
}
if (*ptr)
{
char *str
= ((char *) (SCRATCHADDR+STAGE2_VER_STR_OFFS));
write_stage2_sect++;
while (*(str++)); /* find string */
while ((*(str++) = *(ptr++)) != 0); /* do copy */
}
grub_read ((char *) RAW_ADDR (0x100000), -1);
buf_track = -1;
if (!errnum
&& (biosdisk(BIOSDISK_WRITE,
dest_drive, &dest_geom,
dest_sector, 1, (BOOTSEC_LOCATION>>4))
|| (write_stage2_sect
&& biosdisk(BIOSDISK_WRITE,
current_drive, &buf_geom,
stage2_sect, 1, SCRATCHSEG))))
errnum = ERR_WRITE;
}
}
debug_fs = NULL;
}
#ifndef NO_DECOMPRESSION
no_decompression = 0;
#endif
}
install_failure:
/* Error running the install script, so drop to command line. */
if (script)
{
fallback = -1;
return CMDLINE_ERROR;
}
}
else if (substring("testload", cur_heap) < 1)
{
type = 0;
if (grub_open (cur_cmdline))
{
int i;
debug_fs = debug_fs_print_func;
/*
* Perform filesystem test on the specified file.
*/
/* read whole file first */
printf("Whole file: ");
grub_read ((char *) RAW_ADDR (0x100000), -1);
/* now compare two sections of the file read differently */
for (i = 0; i < 0x10ac0; i++)
{
*((unsigned char *) RAW_ADDR (0x200000+i)) = 0;
*((unsigned char *) RAW_ADDR (0x300000+i)) = 1;
}
/* first partial read */
printf("\nPartial read 1: ");
filepos = 0;
grub_read ((char *) RAW_ADDR (0x200000), 0x7);
grub_read ((char *) RAW_ADDR (0x200007), 0x100);
grub_read ((char *) RAW_ADDR (0x200107), 0x10);
grub_read ((char *) RAW_ADDR (0x200117), 0x999);
grub_read ((char *) RAW_ADDR (0x200ab0), 0x10);
grub_read ((char *) RAW_ADDR (0x200ac0), 0x10000);
/* second partial read */
printf("\nPartial read 2: ");
filepos = 0;
grub_read ((char *) RAW_ADDR (0x300000), 0x10000);
grub_read ((char *) RAW_ADDR (0x310000), 0x10);
grub_read ((char *) RAW_ADDR (0x310010), 0x7);
grub_read ((char *) RAW_ADDR (0x310017), 0x10);
grub_read ((char *) RAW_ADDR (0x310027), 0x999);
grub_read ((char *) RAW_ADDR (0x3109c0), 0x100);
printf ("\nHeader1 = 0x%x, next = 0x%x, next = 0x%x, next = 0x%x\n",
*((int *) RAW_ADDR (0x200000)),
*((int *) RAW_ADDR (0x200004)),
*((int *) RAW_ADDR (0x200008)),
*((int *) RAW_ADDR (0x20000c)));
printf ("Header2 = 0x%x, next = 0x%x, next = 0x%x, next = 0x%x\n",
*((int *) RAW_ADDR (0x300000)),
*((int *) RAW_ADDR (0x300004)),
*((int *) RAW_ADDR (0x300008)),
*((int *) RAW_ADDR (0x30000c)));
for (i = 0; i < 0x10ac0 && *((unsigned char *) RAW_ADDR (0x200000+i))
== *((unsigned char *) RAW_ADDR (0x300000+i)); i++);
printf("Max is 0x10ac0: i=0x%x, filepos=0x%x\n", i, filepos);
debug_fs = NULL;
}
}
else if (substring ("read", cur_heap) < 1)
{
int myaddr;
if (safe_parse_maxint (&cur_cmdline, &myaddr))
printf ("Address 0x%x: Value 0x%x",
myaddr, *((unsigned *) RAW_ADDR (myaddr)));
}
else if (substring ("fstest", cur_heap) == 0)
{
if (debug_fs)
{
debug_fs = NULL;
printf (" Filesystem tracing is now off\n");
}
else
{
debug_fs = debug_fs_print_func;
printf (" Filesystem tracing is now on\n");
}
}
else if (substring ("impsprobe", cur_heap) == 0)
{
#ifndef GRUB_UTIL
if (!imps_probe ())
#endif
printf (" No MPS information found or probe failed\n");
}
else if (substring ("displaymem", cur_heap) == 0)
{
if (get_eisamemsize () != -1)
printf (" EISA Memory BIOS Interface is present\n");
if (get_mmap_entry ((void *) SCRATCHADDR, 0) != 0 ||
*((int *) SCRATCHADDR) != 0)
printf (" Address Map BIOS Interface is present\n");
printf (" Lower memory: %uK, Upper memory (to first chipset hole): %uK\n",
mbi.mem_lower, mbi.mem_upper);
if (mbi.flags & MB_INFO_MEM_MAP)
{
struct AddrRangeDesc *map = (struct AddrRangeDesc *) mbi.mmap_addr;
int end_addr = mbi.mmap_addr + mbi.mmap_length;
printf (" [Address Range Descriptor entries immediately follow (values are 64-bit)]\n");
while (end_addr > (int) map)
{
char *str;
if (map->Type == MB_ARD_MEMORY)
str = "Usable RAM";
else
str = "Reserved";
printf (" %s: Base Address: 0x%x X 4GB + 0x%x,
Length: %u X 4GB + %u bytes\n",
str, map->BaseAddrHigh, map->BaseAddrLow,
map->LengthHigh, map->LengthLow);
map = ((struct AddrRangeDesc *) (((int) map) + 4 + map->size));
}
}
}
else if (substring ("makeactive", cur_heap) == 0)
make_saved_active();
else if (substring ("debug", cur_heap) == 0)
{
if (debug)
{
debug = 0;
grub_printf (" Debug mode is turned off\n");
}
else
{
debug = 1;
grub_printf (" Debug mode is turned on\n");
}
}
else if (substring ("color", cur_heap) < 1)
{
char *normal;
char *highlight;
normal = cur_cmdline;
highlight = skip_to (0, normal);
if (safe_parse_maxint (&normal, &normal_color))
{
/* The second argument is optional, so set highlight_color
to inverted NORMAL_COLOR. */
if (*highlight == 0
|| ! safe_parse_maxint (&highlight, &highlight_color))
highlight_color = ((normal_color >> 4)
| ((normal_color & 0xf) << 4));
}
}
else if (substring ("quit", cur_heap) < 1)
{
#ifdef GRUB_UTIL
return CMDLINE_ABORT;
#else
grub_printf (" The quit command is ignored in Stage2\n");
#endif
}
else if (substring ("geometry", cur_heap) < 1)
{
set_device (cur_cmdline);
if (! errnum)
{
struct geometry geom;
if (get_diskinfo (current_drive, &geom))
errnum = ERR_NO_DISK;
else
{
char *msg;
#ifdef GRUB_UTIL
msg = device_map[current_drive];
#else
if (geom.flags & BIOSDISK_FLAG_LBA_EXTENSION)
msg = "LBA";
else
msg = "CHS";
#endif
grub_printf ("drive 0x%x: C/H/S = %d/%d/%d, "
"The number of sectors = %d, %s\n",
current_drive,
geom.cylinders, geom.heads, geom.sectors,
geom.total_sectors, msg);
}
}
}
else if (substring ("hide", cur_heap) < 1)
{
set_device (cur_cmdline);
if (! errnum)
{
saved_partition = current_partition;
saved_drive = current_drive;
hide_partition ();
}
}
else if (substring ("unhide", cur_heap) < 1)
{
set_device (cur_cmdline);
if (! errnum)
{
saved_partition = current_partition;
saved_drive = current_drive;
unhide_partition ();
}
}
else if (*cur_heap && *cur_heap != ' ')
errnum = ERR_UNRECOGNIZED;
goto restart;
continue;
}
arg = skip_to (1, heap);
(builtin->func) (arg, BUILTIN_CMDLINE);
}
}

View file

@ -74,6 +74,19 @@ extern char *grub_scratch_mem;
#define MB_CMDLINE_BUF RAW_ADDR (0x2000)
#define MB_CMDLINE_BUFLEN 0x6000
/* The buffer for the password. */
#define PASSWORD_BUF RAW_ADDR (0x78000)
#define PASSWORD_BUFLEN 0x200
/* The buffer for the command-line. */
#define CMDLINE_BUF (PASSWORD_BUF + PASSWORD_BUFLEN)
/* Make sure that this is larger than NEW_HEAPSIZE defined below. */
#define CMDLINE_BUFLEN 0x600
/* The buffer for the menu entries. */
#define MENU_BUF (CMDLINE_BUF + CMDLINE_BUFLEN)
#define MENU_BUFLEN (0x8000 + PASSWORD_BUF - MENU_BUF)
/*
* Linux setup parameters
*/
@ -327,7 +340,8 @@ extern char **device_map;
#ifndef STAGE1_5
/* GUI interface variables. */
extern int fallback;
extern int fallback_entry;
extern int default_entry;
extern char *password;
extern char commands[];
#endif
@ -495,22 +509,43 @@ void stop_floppy (void);
/* Command-line interface functions. */
#ifndef STAGE1_5
char *skip_to (int after_equal, char *cmdline);
void init_cmdline (void);
/* The constants for the return value of enter_cmdline. */
#define BUILTIN_CMDLINE 0x1
#define BUILTIN_MENU 0x2
#define BUILTIN_TITLE 0x4
struct builtin
{
char *name;
int (*func) (char *, int);
int flags;
char *short_doc;
char *long_doc;
};
extern struct builtin *builtin_table[];
typedef enum
{
CMDLINE_OK = 0,
CMDLINE_ABORT,
CMDLINE_ERROR
} cmdline_t;
KERNEL_TYPE_NONE,
KERNEL_TYPE_MULTIBOOT,
KERNEL_TYPE_LINUX,
KERNEL_TYPE_BIG_LINUX,
KERNEL_TYPE_FREEBSD,
KERNEL_TYPE_NETBSD,
KERNEL_TYPE_CHAINLOADER
} kernel_t;
/* Run the command-line interface or execute a command from SCRIPT if
SCRIPT is not NULL. Return CMDLINE_OK if successful, CMDLINE_ABORT
if ``quit'' command is executed, and CMDLINE_ERROR if an error
occures or ESC is pushed. */
cmdline_t enter_cmdline (char *script, char *heap);
extern kernel_t kernel_type;
extern int grub_timeout;
void init_builtins (void);
void init_config (void);
char *skip_to (int after_equal, char *cmdline);
struct builtin *find_command (char *command);
void print_cmdline_message (void);
void enter_cmdline (char *heap);
int run_script (char *script, char *heap);
#endif
/* C library replacement functions with identical semantics. */
@ -528,8 +563,8 @@ int grub_strlen (const char *str);
void init_page (void);
void print_error (void);
char *convert_to_ascii (char *buf, int c,...);
int get_cmdline (char *prompt, char *commands, char *cmdline,
int maxlen, int echo_char);
int get_cmdline (char *prompt, char *cmdline, int maxlen,
int echo_char, int completion);
int substring (char *s1, char *s2);
int get_based_digit (int c, int base);
int safe_parse_maxint (char **str_ptr, int *myint_ptr);
@ -582,10 +617,13 @@ void print_completions (char *filename);
/* Copies the current partition data to the desired address. */
void copy_current_part_entry (char *buf);
void bsd_boot (int type, int bootdev, char *arg) __attribute__ ((noreturn));
int load_image (char *kernel, char *arg);
#ifndef STAGE1_5
void bsd_boot (kernel_t type, int bootdev, char *arg)
__attribute__ ((noreturn));
kernel_t load_image (char *kernel, char *arg);
int load_module (char *module, char *arg);
int load_initrd (char *initrd);
#endif
void init_bios_info (void);

View file

@ -52,7 +52,7 @@ check minix_stage1_5 31744
# This limitation is arbitrary; If you want to make this larger, just
# modify Stage 1.
check stage2 46080
check stage2 56320
# Success.
exit 0

View file

@ -165,16 +165,7 @@ set_line_highlight (int y)
#endif
}
static int grub_timeout;
typedef enum
{
MENU_OK = 0,
MENU_ABORT
} menu_t;
static menu_t
static void
run_menu (char *menu_entries, char *config_entries, int num_entries,
char *heap, int entryno)
{
@ -188,7 +179,8 @@ run_menu(char *menu_entries, char *config_entries, int num_entries,
restart:
while (entryno > 11)
{
first_entry++; entryno--;
first_entry++;
entryno--;
}
init_page ();
@ -257,7 +249,7 @@ restart:
gotoxy (3, 22);
printf (" ");
grub_timeout = -1;
fallback = -1;
fallback_entry = -1;
gotoxy (74, 4 + entryno);
}
@ -313,7 +305,9 @@ restart:
c = 'O';
}
cur_entry = get_entry(menu_entries, first_entry+entryno, 0);
cur_entry = get_entry (menu_entries,
first_entry + entryno,
0);
if (c == 'O')
{
@ -330,7 +324,9 @@ restart:
else if (num_entries > 0)
{
char *ptr = get_entry(menu_entries,
first_entry+entryno+1, 0);
first_entry + entryno + 1,
0);
memmove (cur_entry, ptr, ((int) heap) - ((int) ptr));
heap -= (((int) ptr) - ((int) cur_entry));
@ -348,7 +344,7 @@ restart:
cur_entry = menu_entries;
if (c == 27)
return MENU_OK;
return;
if (c == 'b')
break;
}
@ -365,7 +361,7 @@ restart:
/* Wipe out the previously entered password */
memset (entered, 0, sizeof (entered));
get_cmdline (" Password: ", NULL, entered, 31, '*');
get_cmdline (" Password: ", entered, 31, '*', 0);
while (! isspace (*pptr) && *pptr)
pptr++;
@ -378,8 +374,9 @@ restart:
char *new_file = config_file;
while (isspace (*pptr))
pptr++;
while ((*(new_file ++) = *(pptr ++)) != 0);
return MENU_OK;
while ((*(new_file++) = *(pptr++)) != 0)
;
return;
}
else
{
@ -400,14 +397,16 @@ restart:
{
new_heap = heap;
cur_entry = get_entry (config_entries,
first_entry+entryno, 1);
first_entry + entryno,
1);
}
else
{
/* safe area! */
new_heap = heap + NEW_HEAPSIZE + 1;
cur_entry = get_entry (menu_entries,
first_entry+entryno, 0);
first_entry + entryno,
0);
}
do
@ -426,7 +425,7 @@ restart:
else
{
cls ();
init_cmdline();
print_cmdline_message ();
new_heap = heap + NEW_HEAPSIZE + 1;
@ -434,13 +433,14 @@ restart:
saved_partition = install_partition;
current_drive = 0xFF;
if (! get_cmdline(PACKAGE " edit> ", commands, new_heap,
NEW_HEAPSIZE + 1, 0))
if (! get_cmdline (PACKAGE " edit> ", new_heap,
NEW_HEAPSIZE + 1, 0, 1))
{
int j = 0;
/* get length of new command */
while (new_heap[j++]);
while (new_heap[j++])
;
if (j < 2)
{
@ -464,18 +464,16 @@ restart:
}
if (c == 'c')
{
/* Call the command-line interface, and if it aborts
(by ``quit'' command), then return. */
if (enter_cmdline (NULL, heap) == CMDLINE_ABORT)
return MENU_ABORT;
enter_cmdline (heap);
goto restart;
}
#ifdef GRUB_UTIL
if (c == 'q')
{
/* The same as ``quit''. */
return MENU_ABORT;
#ifdef GRUB_UTIL
stop ();
#endif
}
#endif
}
@ -486,7 +484,7 @@ restart:
* Attempt to boot an entry.
*/
do
while (1)
{
cls ();
@ -499,28 +497,26 @@ restart:
if (! cur_entry)
cur_entry = get_entry (config_entries, first_entry + entryno, 1);
if ((c = enter_cmdline (cur_entry, heap)) == CMDLINE_OK)
if (run_script (cur_entry, heap))
{
if (fallback < 0)
if (fallback_entry < 0)
{
/* Both the entry and the fallback failed, so wait for
input. */
grub_printf (" Press any key to continue...");
(void) getkey ();
break;
}
else
{
cur_entry = NULL;
first_entry = 0;
entryno = fallback;
fallback = -1;
entryno = fallback_entry;
fallback_entry = -1;
}
}
}
while (c == CMDLINE_OK);
/* If aborted, then return. */
if (c == CMDLINE_ABORT)
return MENU_ABORT;
/* Both the entry and the fallback failed, so wait for input. */
printf (" Press any key to continue...");
getkey ();
goto restart;
}
@ -574,27 +570,24 @@ get_line_from_config(char *cmdline, int maxlen)
}
/* This is the starting function in C. */
void
cmain (void)
{
int config_len, menu_len, num_entries, default_entry;
int config_len, menu_len, num_entries;
char *config_entries, *menu_entries;
/* Never return. */
for (;;)
{
config_len = 0;
menu_len = 0;
num_entries = 0;
default_entry = 0;
normal_color = A_NORMAL;
highlight_color = A_REVERSE;
config_entries = (char *) (mbi.mmap_addr + mbi.mmap_length);
menu_entries = (char *)(BUFFERADDR + (32 * 1024));
password = NULL; fallback = -1; grub_timeout = -1;
menu_entries = (char *) MENU_BUF;
init_config ();
/*
* Here load the configuration file.
*/
/* Here load the configuration file. */
#ifdef GRUB_UTIL
if (use_config_file && grub_open (config_file))
@ -602,17 +595,31 @@ cmain(void)
if (grub_open (config_file))
#endif
{
/* STATE 0: Before any title command.
STATE 1: In a title command.
STATE >1: In a entry after a title command. */
int state = 0, prev_config_len = 0, prev_menu_len = 0;
char cmdline[1502], *ptr;
char *cmdline;
cmdline = (char *) CMDLINE_BUF;
while (get_line_from_config (cmdline, NEW_HEAPSIZE))
{
ptr = skip_to(1, cmdline);
struct builtin *builtin;
if (substring("title", cmdline) < 1)
/* Get the pointer to the builtin structure. */
builtin = find_command (cmdline);
if (! builtin)
/* Unknown command. Just skip now. */
continue;
if (builtin->flags & BUILTIN_TITLE)
{
char *ptr;
/* the command "title" is specially treated. */
if (state > 1)
{
/* The next title is found. */
num_entries++;
config_entries[config_len++] = 0;
prev_menu_len = menu_len;
@ -620,61 +627,46 @@ cmain(void)
}
else
{
/* The first title is found. */
menu_len = prev_menu_len;
config_len = prev_config_len;
}
/* Reset the state. */
state = 1;
/* copy title into menu area */
while ((menu_entries[menu_len++] = *(ptr++)) != 0);
/* Copy title into menu area. */
ptr = skip_to (1, cmdline);
while ((menu_entries[menu_len++] = *(ptr++)) != 0)
;
}
else if (! state)
{
if (substring ("timeout", cmdline) < 1)
safe_parse_maxint (&ptr, &grub_timeout);
else if (substring ("fallback", cmdline) < 1)
safe_parse_maxint (&ptr, &fallback);
else if (substring ("default", cmdline) < 1)
safe_parse_maxint (&ptr, &default_entry);
else if (substring ("color", cmdline) < 1)
/* Run a command found is possible. */
if (builtin->flags & BUILTIN_MENU)
{
char *normal;
char *highlight;
normal = ptr;
highlight = skip_to (0, normal);
if (safe_parse_maxint (&normal, &normal_color))
{
if (*highlight == 0
|| ! safe_parse_maxint (&highlight,
&highlight_color))
highlight_color = ((normal_color >> 4)
| ((normal_color & 0xf) << 4));
}
}
else if (substring ("password", cmdline) < 1)
{
password = config_entries;
while ((*(config_entries++) = *(ptr++)) != 0);
}
char *arg = skip_to (1, cmdline);
(builtin->func) (arg, BUILTIN_MENU);
errnum = 0;
}
else
/* Ignored. */
continue;
}
else
{
int i = 0;
char *ptr = cmdline;
state++;
/* copy config file data to config area */
while ((config_entries[config_len++] = cmdline[i++]) != 0);
/* Copy config file data to config area. */
while ((config_entries[config_len++] = *ptr++) != 0)
;
}
}
if (state > 1)
{
/* Finish the last entry. */
num_entries++;
config_entries[config_len++] = 0;
}
@ -686,7 +678,7 @@ cmain(void)
menu_entries[menu_len++] = 0;
config_entries[config_len++] = 0;
memmove (config_entries + config_len, menu_entries, menu_len);
grub_memmove (config_entries + config_len, menu_entries, menu_len);
menu_entries = config_entries + config_len;
}
@ -695,17 +687,14 @@ cmain(void)
/* If no acceptable config file, goto command-line, starting
heap from where the config entries would have been stored
if there were any. */
while (enter_cmdline (NULL, config_entries) != CMDLINE_ABORT)
;
return;
while (1)
enter_cmdline (config_entries);
}
else
{
/* Run menu interface. */
if (run_menu(menu_entries, config_entries, num_entries,
menu_entries+menu_len, default_entry) == MENU_ABORT)
return;
run_menu (menu_entries, config_entries, num_entries,
menu_entries + menu_len, default_entry);
}
}
}