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> 1999-09-04 Pavel Roskin <pavel_roskin@geocities.com>
* docs/menu.lst: More meaningful examples. Not using (0x80,0) * 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". * New commands "hide" and "unhide".
* The character `=' after a command is not necessary any longer, but it * The character `=' after a command is not necessary any longer, but it
is supported for backward compatibility. 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: New in 0.5.92 - 1999-07-26:
* Bug fixes (i.e. Stage 1.5 can work fine again). * Bug fixes (i.e. Stage 1.5 can work fine again).

View file

@ -398,7 +398,7 @@ lastlist:
#else #else
.long 1 /* this is the sector start parameter, in logical .long 1 /* this is the sector start parameter, in logical
sectors from the start of the disk, sector 0 */ 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 .word 0x0800 /* this is the segment of the starting address
to load the data into */ to load the data into */
#endif #endif

View file

@ -345,7 +345,7 @@ lastlist:
#else #else
.long 1 /* this is the sector start parameter, in logical .long 1 /* this is the sector start parameter, in logical
sectors from the start of the disk, sector 0 */ 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 .word 0x0800 /* this is the segment of the starting address
to load the data into */ to load the data into */
#endif #endif

View file

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

View file

@ -94,9 +94,9 @@ INCLUDES = -I$(top_srcdir)/stage1
# The library for /sbin/grub. # The library for /sbin/grub.
noinst_LIBRARIES = libgrub.a noinst_LIBRARIES = libgrub.a
libgrub_a_SOURCES = boot.c common.c char_io.c cmdline.c disk_io.c \ libgrub_a_SOURCES = boot.c builtins.c common.c char_io.c cmdline.c \
gunzip.c fsys_ffs.c fsys_ext2fs.c fsys_fat.c fsys_minix.c \ disk_io.c gunzip.c fsys_ffs.c fsys_ext2fs.c fsys_fat.c \
stage2.c fsys_minix.c stage2.c
libgrub_a_CFLAGS = $(GRUB_CFLAGS) -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 \ libgrub_a_CFLAGS = $(GRUB_CFLAGS) -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 \
-DFSYS_FAT=1 -DFSYS_FFS=1 -DFSYS_MINIX=1 -fwritable-strings -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! # asm.S absolutely needs to come first!
# For stage2 target. # For stage2 target.
stage2_exec_SOURCES = asm.S boot.c common.c char_io.c cmdline.c \ stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c common.c \
disk_io.c gunzip.c stage2.c bios.c smp-imps.c fsys_ext2fs.c \ char_io.c cmdline.c disk_io.c gunzip.c fsys_ext2fs.c \
fsys_fat.c fsys_ffs.c fsys_minix.c fsys_fat.c fsys_ffs.c fsys_minix.c smp-imps.c stage2.c
stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
stage2_exec_LDFLAGS = $(STAGE2_LINK) stage2_exec_LDFLAGS = $(STAGE2_LINK)
@ -176,10 +176,11 @@ LDFLAGS = @LDFLAGS@
LIBS = @LIBS@ LIBS = @LIBS@
libgrub_a_AR = $(AR) cru libgrub_a_AR = $(AR) cru
libgrub_a_LIBADD = libgrub_a_LIBADD =
am_libgrub_a_OBJECTS = libgrub_a-boot.o libgrub_a-common.o \ am_libgrub_a_OBJECTS = libgrub_a-boot.o libgrub_a-builtins.o \
libgrub_a-char_io.o libgrub_a-cmdline.o libgrub_a-disk_io.o \ libgrub_a-common.o libgrub_a-char_io.o libgrub_a-cmdline.o \
libgrub_a-gunzip.o libgrub_a-fsys_ffs.o libgrub_a-fsys_ext2fs.o \ libgrub_a-disk_io.o libgrub_a-gunzip.o libgrub_a-fsys_ffs.o \
libgrub_a-fsys_fat.o libgrub_a-fsys_minix.o libgrub_a-stage2.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) libgrub_a_OBJECTS = $(am_libgrub_a_OBJECTS)
AR = ar AR = ar
PROGRAMS = $(noinst_PROGRAMS) 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_OBJECTS = $(am_minix_stage1_5_exec_OBJECTS)
minix_stage1_5_exec_LDADD = $(LDADD) minix_stage1_5_exec_LDADD = $(LDADD)
minix_stage1_5_exec_DEPENDENCIES = minix_stage1_5_exec_DEPENDENCIES =
am_stage2_exec_OBJECTS = stage2_exec-asm.o stage2_exec-boot.o \ am_stage2_exec_OBJECTS = stage2_exec-asm.o stage2_exec-bios.o \
stage2_exec-common.o stage2_exec-char_io.o stage2_exec-cmdline.o \ stage2_exec-boot.o stage2_exec-builtins.o stage2_exec-common.o \
stage2_exec-disk_io.o stage2_exec-gunzip.o stage2_exec-stage2.o \ stage2_exec-char_io.o stage2_exec-cmdline.o stage2_exec-disk_io.o \
stage2_exec-bios.o stage2_exec-smp-imps.o stage2_exec-fsys_ext2fs.o \ stage2_exec-gunzip.o stage2_exec-fsys_ext2fs.o stage2_exec-fsys_fat.o \
stage2_exec-fsys_fat.o stage2_exec-fsys_ffs.o stage2_exec-fsys_minix.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_OBJECTS = $(am_stage2_exec_OBJECTS)
stage2_exec_LDADD = $(LDADD) stage2_exec_LDADD = $(LDADD)
stage2_exec_DEPENDENCIES = stage2_exec_DEPENDENCIES =
@ -239,10 +241,11 @@ DIST_COMMON = $(noinst_HEADERS) Makefile.am Makefile.in compile
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
GZIP_ENV = --best GZIP_ENV = --best
DEP_FILES = .deps/asm.P .deps/bios.P .deps/boot.P .deps/char_io.P \ DEP_FILES = .deps/asm.P .deps/bios.P .deps/boot.P .deps/builtins.P \
.deps/cmdline.P .deps/common.P .deps/disk_io.P .deps/fsys_ext2fs.P \ .deps/char_io.P .deps/cmdline.P .deps/common.P .deps/disk_io.P \
.deps/fsys_fat.P .deps/fsys_ffs.P .deps/fsys_minix.P .deps/gunzip.P \ .deps/fsys_ext2fs.P .deps/fsys_fat.P .deps/fsys_ffs.P \
.deps/smp-imps.P .deps/stage1_5.P .deps/stage2.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) 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) 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: maintainer-clean-compile:
libgrub_a-boot.o: boot.c libgrub_a-boot.o: boot.c
libgrub_a-builtins.o: builtins.c
libgrub_a-common.o: common.c libgrub_a-common.o: common.c
libgrub_a-char_io.o: char_io.c libgrub_a-char_io.o: char_io.c
libgrub_a-cmdline.o: cmdline.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) $(LINK) $(minix_stage1_5_exec_LDFLAGS) $(minix_stage1_5_exec_OBJECTS) $(minix_stage1_5_exec_LDADD) $(LIBS)
stage2_exec-asm.o: asm.S stage2_exec-asm.o: asm.S
$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o stage2_exec-asm.o $< $(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-boot.o: boot.c
stage2_exec-builtins.o: builtins.c
stage2_exec-common.o: common.c stage2_exec-common.o: common.c
stage2_exec-char_io.o: char_io.c stage2_exec-char_io.o: char_io.c
stage2_exec-cmdline.o: cmdline.c stage2_exec-cmdline.o: cmdline.c
stage2_exec-disk_io.o: disk_io.c stage2_exec-disk_io.o: disk_io.c
stage2_exec-gunzip.o: gunzip.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_ext2fs.o: fsys_ext2fs.c
stage2_exec-fsys_fat.o: fsys_fat.c stage2_exec-fsys_fat.o: fsys_fat.c
stage2_exec-fsys_ffs.o: fsys_ffs.c stage2_exec-fsys_ffs.o: fsys_ffs.c
stage2_exec-fsys_minix.o: fsys_minix.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) stage2.exec: $(stage2_exec_OBJECTS) $(stage2_exec_DEPENDENCIES)
@rm -f stage2.exec @rm -f stage2.exec
@ -493,6 +498,25 @@ libgrub_a-boot.lo: boot.c
>> .deps/$(*D)/$(*F).P; \ >> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp 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 libgrub_a-common.o: common.c
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o $@ $<'; \ @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 $@ $< $(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; \ >> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp 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 stage2_exec-boot.o: boot.c
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \ @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 $@ $< $(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; \ >> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp 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 stage2_exec-common.o: common.c
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \ @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 $@ $< $(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; \ >> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp 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 stage2_exec-fsys_ext2fs.o: fsys_ext2fs.c
@echo '$(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stage2_exec_CFLAGS) $(CFLAGS) -c -o $@ $<'; \ @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 $@ $< $(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/$$/ :/' \ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*D)/$(*F).P; \ >> .deps/$(*D)/$(*F).P; \
rm -f .deps/$(*D)/$(*F).pp 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) check-TESTS: $(TESTS)
@failed=0; all=0; xfail=0; xpass=0; \ @failed=0; all=0; xfail=0; xpass=0; \
srcdir=$(srcdir); export srcdir; \ 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. * of the gory details of loading in a bootable image and the modules.
*/ */
int kernel_t
load_image (char *kernel, char *arg) 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; unsigned long flags = 0, text_len = 0, data_len = 0, bss_len = 0;
char *str = 0, *str2 = 0; char *str = 0, *str2 = 0;
union union
@ -60,14 +61,14 @@ load_image (char *kernel, char *arg)
pu.aout = (struct exec *) buffer; pu.aout = (struct exec *) buffer;
if (!grub_open (kernel)) if (!grub_open (kernel))
return 0; return KERNEL_TYPE_NONE;
if (!(len = grub_read (buffer, MULTIBOOT_SEARCH)) || len < 32) if (!(len = grub_read (buffer, MULTIBOOT_SEARCH)) || len < 32)
{ {
if (!errnum) if (!errnum)
errnum = ERR_EXEC_FORMAT; errnum = ERR_EXEC_FORMAT;
return 0; return KERNEL_TYPE_NONE;
} }
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
@ -78,20 +79,21 @@ load_image (char *kernel, char *arg)
if (flags & MULTIBOOT_UNSUPPORTED) if (flags & MULTIBOOT_UNSUPPORTED)
{ {
errnum = ERR_BOOT_FEATURES; errnum = ERR_BOOT_FEATURES;
return 0; return KERNEL_TYPE_NONE;
} }
type = 'm'; type = KERNEL_TYPE_MULTIBOOT;
str2 = "Multiboot"; str2 = "Multiboot";
break; break;
} }
} }
/* ELF loading supported if multiboot and FreeBSD. */ /* 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) && len > sizeof (Elf32_Ehdr)
&& BOOTABLE_I386_ELF ((*((Elf32_Ehdr *) buffer)))) && BOOTABLE_I386_ELF ((*((Elf32_Ehdr *) buffer))))
{ {
if (type == 'm') if (type == KERNEL_TYPE_MULTIBOOT)
entry_addr = (entry_func) pu.elf->e_entry; entry_addr = (entry_func) pu.elf->e_entry;
else else
entry_addr = (entry_func) (pu.elf->e_entry & 0xFFFFFF); entry_addr = (entry_func) (pu.elf->e_entry & 0xFFFFFF);
@ -107,10 +109,10 @@ load_image (char *kernel, char *arg)
errnum = ERR_EXEC_FORMAT; errnum = ERR_EXEC_FORMAT;
str = "elf"; str = "elf";
if (! type) if (type == KERNEL_TYPE_NONE)
{ {
str2 = "FreeBSD"; str2 = "FreeBSD";
type = 'f'; type = KERNEL_TYPE_FREEBSD;
} }
} }
else if (flags & MULTIBOOT_AOUT_KLUDGE) else if (flags & MULTIBOOT_AOUT_KLUDGE)
@ -141,7 +143,7 @@ load_image (char *kernel, char *arg)
{ {
entry_addr = (entry_func) pu.aout->a_entry; 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 * 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) if (buffer[0] == 0xb && buffer[1] == 1)
{ {
type = 'f'; type = KERNEL_TYPE_FREEBSD;
entry_addr = (entry_func) (((int) entry_addr) & 0xFFFFFF); entry_addr = (entry_func) (((int) entry_addr) & 0xFFFFFF);
str2 = "FreeBSD"; str2 = "FreeBSD";
} }
else else
{ {
type = 'n'; type = KERNEL_TYPE_NETBSD;
entry_addr = (entry_func) (((int) entry_addr) & 0xF00000); entry_addr = (entry_func) (((int) entry_addr) & 0xF00000);
if (N_GETMAGIC ((*(pu.aout))) != NMAGIC) if (N_GETMAGIC ((*(pu.aout))) != NMAGIC)
align_4k = 0; align_4k = 0;
@ -200,7 +202,7 @@ load_image (char *kernel, char *arg)
{ {
printf (" linux 'zImage' kernel too big, try 'make bzImage'\n"); printf (" linux 'zImage' kernel too big, try 'make bzImage'\n");
errnum = ERR_WONT_FIT; errnum = ERR_WONT_FIT;
return 0; return KERNEL_TYPE_NONE;
} }
printf (" [Linux-%s, setup=0x%x, size=0x%x]\n", printf (" [Linux-%s, setup=0x%x, size=0x%x]\n",
@ -232,7 +234,7 @@ load_image (char *kernel, char *arg)
else else
/* ERRNUM is already set inside the function /* ERRNUM is already set inside the function
safe_parse_maxint. */ safe_parse_maxint. */
return 0; return KERNEL_TYPE_NONE;
/* Set the vid mode to VID_MODE. Note that this can work /* Set the vid mode to VID_MODE. Note that this can work
because i386 architecture is little-endian. */ because i386 architecture is little-endian. */
@ -275,7 +277,7 @@ load_image (char *kernel, char *arg)
cur_addr = LINUX_STAGING_AREA + text_len; cur_addr = LINUX_STAGING_AREA + text_len;
if (grub_read ((char *) LINUX_STAGING_AREA, text_len) >= (text_len - 16)) 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) else if (!errnum)
errnum = ERR_EXEC_FORMAT; errnum = ERR_EXEC_FORMAT;
} }
@ -287,7 +289,7 @@ load_image (char *kernel, char *arg)
/* return if error */ /* return if error */
if (errnum) if (errnum)
return 0; return KERNEL_TYPE_NONE;
/* fill the multiboot info structure */ /* fill the multiboot info structure */
mbi.cmdline = (int) arg; mbi.cmdline = (int) arg;
@ -419,7 +421,7 @@ load_image (char *kernel, char *arg)
filepos = phdr->p_offset; filepos = phdr->p_offset;
filesiz = phdr->p_filesz; filesiz = phdr->p_filesz;
if (type == 'f') if (type == KERNEL_TYPE_FREEBSD)
memaddr = RAW_ADDR (phdr->p_paddr & 0xFFFFFF); memaddr = RAW_ADDR (phdr->p_paddr & 0xFFFFFF);
else else
memaddr = RAW_ADDR (phdr->p_paddr); memaddr = RAW_ADDR (phdr->p_paddr);
@ -466,7 +468,7 @@ load_image (char *kernel, char *arg)
else else
{ {
putchar ('\n'); putchar ('\n');
type = 0; type = KERNEL_TYPE_NONE;
} }
return type; return type;
@ -543,7 +545,7 @@ bsd_boot_entry (int flags, int bootdev, int sym_start, int sym_end,
void void
bsd_boot (int type, int bootdev, char *arg) bsd_boot (kernel_t type, int bootdev, char *arg)
{ {
char *str; char *str;
int clval = 0, i; int clval = 0, i;
@ -588,7 +590,7 @@ bsd_boot (int type, int bootdev, char *arg)
str++; str++;
} }
if (type == 'f') if (type == KERNEL_TYPE_FREEBSD)
{ {
clval |= RB_BOOTINFO; 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. */ If ECHO_CHAR is nonzero, echo it instead of the typed character. */
int int
get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen, get_cmdline (char *prompt, char *cmdline, int maxlen,
int echo_char) int echo_char, int completion)
{ {
int ystart, yend, xend, lpos, c; int ystart, yend, xend, lpos, c;
int plen = 0; int plen = 0;
@ -160,7 +160,7 @@ get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen,
while (*str != 0) while (*str != 0)
{ {
putchar (echo_char ? echo_char : *str); putchar (echo_char ? echo_char : *str);
str ++; str++;
if (++xend > 78) if (++xend > 78)
{ {
xend = 0; xend = 0;
@ -259,45 +259,61 @@ get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen,
case 27: /* ESC immediately return 1 */ case 27: /* ESC immediately return 1 */
return 1; return 1;
case 9: /* TAB lists completions */ case 9: /* TAB lists completions */
{ if (completion)
int i, j = 0, llen_old = llen; {
int i, j = 0, llen_old = llen;
/* Find the first word. */ /* Find the first word. */
while (cmdline[j] == ' ') while (cmdline[j] == ' ')
j++; j++;
while (cmdline[j] && cmdline[j] != '=' && cmdline[j] != ' ') while (cmdline[j] && cmdline[j] != '=' && cmdline[j] != ' ')
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
c = cmdline[lpos]; use C. */
c = cmdline[lpos];
cl_kill_to_end (); cl_kill_to_end ();
/* goto part after line here */ /* goto part after line here */
yend = ((llen + plen) / 79) + ystart; yend = ((llen + plen) / 79) + ystart;
putchar ('\n'); putchar ('\n');
gotoxy (0, getxy () & 0xff); gotoxy (0, getxy () & 0xff);
if (lpos > j)
{
for (i = lpos; i > 0 && cmdline[i - 1] != ' '; i--);
if (i <= j)
i = j + 1;
/* print possible completions */
print_completions (cmdline + i);
/* if somebody in print_completions has added something,
account for that */
while (cmdline[lpos])
lpos++, llen_old++;
}
else if (commands)
printf (commands);
/* restore command-line */ if (lpos > j)
cmdline[lpos] = c; {
llen = llen_old; for (i = lpos; i > 0 && cmdline[i - 1] != ' '; i--);
cl_init (); if (i <= j)
} i = j + 1;
/* print possible completions */
print_completions (cmdline + i);
/* if somebody in print_completions has added something,
account for that */
while (cmdline[lpos])
lpos++, llen_old++;
}
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;
llen = llen_old;
cl_init ();
}
break; break;
case 1: /* C-a go to beginning of line */ case 1: /* C-a go to beginning of line */
lpos = 0; lpos = 0;

View file

@ -21,25 +21,6 @@
#include "shared.h" #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 /* Find the next word from CMDLINE and return the pointer. If
AFTER_EQUAL is non-zero, assume that the character `=' is treated as AFTER_EQUAL is non-zero, assume that the character `=' is treated as
a space. Caution: this assumption is for backward compatibility. */ a space. Caution: this assumption is for backward compatibility. */
@ -66,679 +47,149 @@ skip_to (int after_equal, char *cmdline)
void void
init_cmdline (void) print_cmdline_message (void)
{ {
printf (" [ Minimal BASH-like line editing is supported. For the first word, TAB printf (" [ Minimal BASH-like line editing is supported. For the first word, TAB
lists possible command completions. Anywhere else TAB lists the possible lists possible command completions. Anywhere else TAB lists the possible
completions of a device/filename. ESC at any time exits. ]\n"); completions of a device/filename. ESC at any time exits. ]\n");
} }
char commands[] = /* Find the builtin whose command name is COMMAND and return the
" Possible commands are: \"pause ...\", \"uppermem <kbytes>\", \"root <device>\", pointer. If not found, return 0. */
\"rootnoverify <device>\", \"chainloader <file>\", \"kernel <file> ...\", struct builtin *
\"testload <file>\", \"read <addr>\", \"displaymem\", \"impsprobe\", find_command (char *command)
\"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";
static void
debug_fs_print_func (int sector)
{ {
printf ("[%d]", sector); char *ptr;
} char c;
struct builtin **builtin;
static int installaddr, installlist, installsect; /* Find the first space and terminate the command name. */
ptr = command;
while (*ptr && *ptr != ' ' && *ptr != '=')
ptr++;
c = *ptr;
*ptr = 0;
static void /* Seek out the builtin whose command name is COMMAND. */
debug_fs_blocklist_func (int sector) for (builtin = builtin_table; *builtin != 0; builtin++)
{
if (debug)
printf("[%d]", sector);
if (*((unsigned long *)(installlist-4))
+ *((unsigned short *)installlist) != sector
|| installlist == BOOTSEC_LOCATION+STAGE1_FIRSTLIST+4)
{ {
installlist -= 8; if (grub_strcmp (command, (*builtin)->name) == 0)
if (*((unsigned long *)(installlist-8)))
errnum = ERR_WONT_FIT;
else
{ {
*((unsigned short *)(installlist+2)) = (installaddr >> 4); *ptr = c;
*((unsigned long *)(installlist-4)) = sector; return *builtin;
} }
} }
*((unsigned short *)installlist) += 1; /* Cannot find COMMAND. */
installsect = sector; errnum = ERR_UNRECOGNIZED;
installaddr += 512; *ptr = c;
return 0;
} }
static void
/* Run the command-line interface or execute a command from SCRIPT if init_cmdline (void)
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; /* Initialization. */
char *cur_heap = heap, *cur_entry = script, *old_entry;
char *mb_cmdline = (char *) MB_CMDLINE_BUF;
/* initialization */
saved_drive = boot_drive; saved_drive = boot_drive;
saved_partition = install_partition; saved_partition = install_partition;
current_drive = 0xFF; current_drive = 0xFF;
errnum = 0; errnum = 0;
/* restore memory probe state */ /* Restore memory probe state. */
mbi.mem_upper = saved_mem_upper; mbi.mem_upper = saved_mem_upper;
if (mbi.mmap_length) if (mbi.mmap_length)
mbi.flags |= MB_INFO_MEM_MAP; mbi.flags |= MB_INFO_MEM_MAP;
/* BSD and chainloading evil hacks !! */ init_builtins ();
bootdev = set_bootdev(0); }
if (!script) void
enter_cmdline (char *heap)
{
/* Initialize the data and print a message. */
init_cmdline ();
init_page ();
print_cmdline_message ();
while (1)
{ {
init_page(); struct builtin *builtin;
init_cmdline(); 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);
} }
}
restart: int
if (script) 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 (errnum)
{ {
if (fallback < 0) if (fallback_entry < 0)
goto returnit; return 1;
print_error();
if (password || errnum == ERR_BOOT_COMMAND)
{
printf("Press any key to continue...");
(void) getkey ();
returnit:
return CMDLINE_OK;
}
run_cmdline = 1; grub_printf ("Press any key to continue...");
if (!have_run_cmdline) (void) getkey ();
{ return 1;
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++));
/* copy to work area */
memmove (cur_heap, old_entry, ((int)cur_entry) - ((int)old_entry));
printf("%s\n", old_entry);
}
}
else
{
cur_heap[0] = 0;
print_error();
}
if (run_cmdline && get_cmdline (PACKAGE "> ", commands, cur_heap, 2048, 0))
return CMDLINE_ERROR;
if (substring ("boot", cur_heap) == 0 || (script && !*cur_heap))
{
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) old_entry = cur_entry;
while (*cur_entry++)
;
grub_memmove (heap, old_entry, (int) cur_entry - (int) old_entry);
grub_printf ("%s\n", old_entry);
if (! *heap)
{ {
errnum = ERR_BOOT_COMMAND; if (kernel_type == KERNEL_TYPE_NONE)
goto restart; return 0;
grub_memmove (heap, "boot", 5);
} }
/* this is the final possibility */ builtin = find_command (heap);
multi_boot((int)entry_addr, (int)(&mbi)); if (! builtin)
} continue;
/* get clipped command-line */ if (! (builtin->flags & BUILTIN_CMDLINE))
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; errnum = ERR_UNRECOGNIZED;
type = 0; continue;
}
}
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: arg = skip_to (1, heap);
(builtin->func) (arg, BUILTIN_CMDLINE);
/* 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;
} }

View file

@ -74,6 +74,19 @@ extern char *grub_scratch_mem;
#define MB_CMDLINE_BUF RAW_ADDR (0x2000) #define MB_CMDLINE_BUF RAW_ADDR (0x2000)
#define MB_CMDLINE_BUFLEN 0x6000 #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 * Linux setup parameters
*/ */
@ -327,7 +340,8 @@ extern char **device_map;
#ifndef STAGE1_5 #ifndef STAGE1_5
/* GUI interface variables. */ /* GUI interface variables. */
extern int fallback; extern int fallback_entry;
extern int default_entry;
extern char *password; extern char *password;
extern char commands[]; extern char commands[];
#endif #endif
@ -495,22 +509,43 @@ void stop_floppy (void);
/* Command-line interface functions. */ /* Command-line interface functions. */
#ifndef STAGE1_5 #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 typedef enum
{ {
CMDLINE_OK = 0, KERNEL_TYPE_NONE,
CMDLINE_ABORT, KERNEL_TYPE_MULTIBOOT,
CMDLINE_ERROR KERNEL_TYPE_LINUX,
} cmdline_t; 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 extern kernel_t kernel_type;
SCRIPT is not NULL. Return CMDLINE_OK if successful, CMDLINE_ABORT extern int grub_timeout;
if ``quit'' command is executed, and CMDLINE_ERROR if an error
occures or ESC is pushed. */ void init_builtins (void);
cmdline_t enter_cmdline (char *script, char *heap); 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 #endif
/* C library replacement functions with identical semantics. */ /* C library replacement functions with identical semantics. */
@ -528,8 +563,8 @@ int grub_strlen (const char *str);
void init_page (void); void init_page (void);
void print_error (void); void print_error (void);
char *convert_to_ascii (char *buf, int c,...); char *convert_to_ascii (char *buf, int c,...);
int get_cmdline (char *prompt, char *commands, char *cmdline, int get_cmdline (char *prompt, char *cmdline, int maxlen,
int maxlen, int echo_char); int echo_char, int completion);
int substring (char *s1, char *s2); int substring (char *s1, char *s2);
int get_based_digit (int c, int base); int get_based_digit (int c, int base);
int safe_parse_maxint (char **str_ptr, int *myint_ptr); 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. */ /* Copies the current partition data to the desired address. */
void copy_current_part_entry (char *buf); void copy_current_part_entry (char *buf);
void bsd_boot (int type, int bootdev, char *arg) __attribute__ ((noreturn)); #ifndef STAGE1_5
int load_image (char *kernel, char *arg); 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_module (char *module, char *arg);
int load_initrd (char *initrd); int load_initrd (char *initrd);
#endif
void init_bios_info (void); 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 # This limitation is arbitrary; If you want to make this larger, just
# modify Stage 1. # modify Stage 1.
check stage2 46080 check stage2 56320
# Success. # Success.
exit 0 exit 0

View file

@ -20,7 +20,7 @@
#include "shared.h" #include "shared.h"
static char * static char *
get_entry(char *list, int num, int nested) get_entry (char *list, int num, int nested)
{ {
int i; int i;
@ -38,16 +38,16 @@ get_entry(char *list, int num, int nested)
static void static void
print_entries(int y, int size, int first, char *menu_entries) print_entries (int y, int size, int first, char *menu_entries)
{ {
int i; int i;
gotoxy(77, y+1); gotoxy (77, y + 1);
if (first) if (first)
putchar(DISP_UP); putchar (DISP_UP);
else else
putchar(' '); putchar (' ');
menu_entries = get_entry (menu_entries, first, 0); menu_entries = get_entry (menu_entries, first, 0);
@ -55,37 +55,37 @@ print_entries(int y, int size, int first, char *menu_entries)
{ {
int j = 0; int j = 0;
gotoxy(3, y+i); gotoxy (3, y + i);
while (*menu_entries) while (*menu_entries)
{ {
if (j < 71) if (j < 71)
{ {
putchar(*menu_entries); putchar (*menu_entries);
j++; j++;
} }
menu_entries++; menu_entries++;
} }
if (*(menu_entries-1)) if (*(menu_entries - 1))
menu_entries++; menu_entries++;
for (; j < 71; j++) for (; j < 71; j++)
putchar(' '); putchar (' ');
} }
gotoxy(77, y+size); gotoxy (77, y + size);
if (*menu_entries) if (*menu_entries)
putchar(DISP_DOWN); putchar (DISP_DOWN);
else else
putchar(' '); putchar (' ');
} }
static void static void
print_border(int y, int size) print_border (int y, int size)
{ {
int i; int i;
@ -102,37 +102,37 @@ print_border(int y, int size)
} }
#endif #endif
gotoxy(1, y); gotoxy (1, y);
putchar(DISP_UL); putchar (DISP_UL);
for (i = 0; i < 73; i++) for (i = 0; i < 73; i++)
putchar(DISP_HORIZ); putchar (DISP_HORIZ);
putchar(DISP_UR); putchar (DISP_UR);
i = 1; i = 1;
while (1) while (1)
{ {
gotoxy(1, y+i); gotoxy (1, y + i);
if (i > size) if (i > size)
break; break;
putchar(DISP_VERT); putchar (DISP_VERT);
gotoxy(75, y+i); gotoxy (75, y + i);
putchar(DISP_VERT); putchar (DISP_VERT);
i++; i++;
} }
putchar(DISP_LL); putchar (DISP_LL);
for (i = 0; i < 73; i++) for (i = 0; i < 73; i++)
putchar(DISP_HORIZ); putchar (DISP_HORIZ);
putchar(DISP_LR); putchar (DISP_LR);
} }
static void static void
set_line(int y, int attr) set_line (int y, int attr)
{ {
int x; int x;
@ -165,18 +165,9 @@ set_line_highlight (int y)
#endif #endif
} }
static int grub_timeout; static void
run_menu (char *menu_entries, char *config_entries, int num_entries,
char *heap, int entryno)
typedef enum
{
MENU_OK = 0,
MENU_ABORT
} menu_t;
static menu_t
run_menu(char *menu_entries, char *config_entries, int num_entries,
char *heap, int entryno)
{ {
int c, time1, time2 = -1, first_entry = 0; int c, time1, time2 = -1, first_entry = 0;
char *cur_entry; char *cur_entry;
@ -188,38 +179,39 @@ run_menu(char *menu_entries, char *config_entries, int num_entries,
restart: restart:
while (entryno > 11) while (entryno > 11)
{ {
first_entry++; entryno--; first_entry++;
entryno--;
} }
init_page(); init_page ();
#ifndef GRUB_UTIL #ifndef GRUB_UTIL
nocursor(); nocursor ();
#endif #endif
print_border(3, 12); print_border (3, 12);
printf("\n printf ("\n
Use the \x18 and \x19 keys for selecting which entry is highlighted.\n"); Use the \x18 and \x19 keys for selecting which entry is highlighted.\n");
if (password) if (password)
{ {
printf(" Press enter to boot the selected OS or \'p\' to enter a printf (" Press enter to boot the selected OS or \'p\' to enter a
password to unlock the next set of features."); password to unlock the next set of features.");
} }
else else
{ {
if (config_entries) if (config_entries)
printf(" Press enter to boot the selected OS, \'e\' to edit the printf (" Press enter to boot the selected OS, \'e\' to edit the
commands before booting, or \'c\' for a command-line."); commands before booting, or \'c\' for a command-line.");
else else
printf( printf (
" Press \'b\' to boot, \'e\' to edit the selected command in the " Press \'b\' to boot, \'e\' to edit the selected command in the
boot sequence, \'c\' for a command-line, \'o\' to open a new line boot sequence, \'c\' for a command-line, \'o\' to open a new line
after (\'O\' for before) the selected line, \'d\' to remove the after (\'O\' for before) the selected line, \'d\' to remove the
selected line, or escape to go back to the main menu."); selected line, or escape to go back to the main menu.");
} }
print_entries(3, 12, first_entry, menu_entries); print_entries (3, 12, first_entry, menu_entries);
/* highlight initial line */ /* highlight initial line */
set_line_highlight (4 + entryno); set_line_highlight (4 + entryno);
@ -242,58 +234,58 @@ restart:
/* else not booting yet! */ /* else not booting yet! */
time2 = time1; time2 = time1;
gotoxy(3, 22); gotoxy (3, 22);
printf("The highlighted entry will be booted automatically in %d seconds. ", grub_timeout); printf ("The highlighted entry will be booted automatically in %d seconds. ", grub_timeout);
gotoxy(74, 4+entryno); gotoxy (74, 4 + entryno);
grub_timeout --; grub_timeout--;
} }
if (checkkey() != -1) if (checkkey () != -1)
{ {
c = getkey(); c = getkey ();
if (grub_timeout >= 0) if (grub_timeout >= 0)
{ {
gotoxy(3, 22); gotoxy (3, 22);
printf(" "); printf (" ");
grub_timeout = -1; grub_timeout = -1;
fallback = -1; fallback_entry = -1;
gotoxy(74, 4+entryno); gotoxy (74, 4 + entryno);
} }
if ((c == KEY_UP) || (ASCII_CHAR(c) == 16)) if ((c == KEY_UP) || (ASCII_CHAR (c) == 16))
{ {
if (entryno > 0) if (entryno > 0)
{ {
set_line_normal (4 + entryno); set_line_normal (4 + entryno);
entryno --; entryno--;
set_line_highlight (4 + entryno); set_line_highlight (4 + entryno);
} }
else if (first_entry > 0) else if (first_entry > 0)
{ {
first_entry --; first_entry--;
print_entries(3, 12, first_entry, menu_entries); print_entries (3, 12, first_entry, menu_entries);
set_line_highlight (4); set_line_highlight (4);
} }
} }
if (((c == KEY_DOWN) || (ASCII_CHAR(c) == 14)) if (((c == KEY_DOWN) || (ASCII_CHAR (c) == 14))
&& (first_entry+entryno+1) < num_entries) && (first_entry + entryno + 1) < num_entries)
{ {
if (entryno < 11) if (entryno < 11)
{ {
set_line_normal (4 + entryno); set_line_normal (4 + entryno);
entryno ++; entryno++;
set_line_highlight (4 + entryno); set_line_highlight (4 + entryno);
} }
else if (num_entries > 12+first_entry) else if (num_entries > 12 + first_entry)
{ {
first_entry ++; first_entry++;
print_entries (3, 12, first_entry, menu_entries); print_entries (3, 12, first_entry, menu_entries);
set_line_highlight (15); set_line_highlight (15);
} }
} }
c = ASCII_CHAR(c); c = ASCII_CHAR (c);
if (config_entries) if (config_entries)
{ {
@ -313,12 +305,14 @@ restart:
c = 'O'; 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') if (c == 'O')
{ {
memmove (cur_entry + 2, cur_entry, memmove (cur_entry + 2, cur_entry,
((int)heap) - ((int)cur_entry)); ((int) heap) - ((int) cur_entry));
cur_entry[0] = ' '; cur_entry[0] = ' ';
cur_entry[1] = 0; cur_entry[1] = 0;
@ -330,25 +324,27 @@ restart:
else if (num_entries > 0) else if (num_entries > 0)
{ {
char *ptr = get_entry(menu_entries, char *ptr = get_entry(menu_entries,
first_entry+entryno+1, 0); first_entry + entryno + 1,
memmove (cur_entry, ptr, ((int)heap) - ((int)ptr)); 0);
heap -= (((int)ptr) - ((int)cur_entry));
memmove (cur_entry, ptr, ((int) heap) - ((int) ptr));
heap -= (((int) ptr) - ((int) cur_entry));
num_entries--; num_entries--;
if (entryno >= num_entries) if (entryno >= num_entries)
entryno--; entryno--;
if (first_entry && num_entries < 12+first_entry) if (first_entry && num_entries < 12 + first_entry)
first_entry--; first_entry--;
} }
print_entries(3, 12, first_entry, menu_entries); print_entries (3, 12, first_entry, menu_entries);
set_line_highlight (4 + entryno); set_line_highlight (4 + entryno);
} }
cur_entry = menu_entries; cur_entry = menu_entries;
if (c == 27) if (c == 27)
return MENU_OK; return;
if (c == 'b') if (c == 'b')
break; break;
} }
@ -361,14 +357,14 @@ restart:
char entered[32]; char entered[32];
char *pptr = password; char *pptr = password;
gotoxy(1, 21); gotoxy (1, 21);
/* Wipe out the previously entered password */ /* Wipe out the previously entered password */
memset (entered, 0, sizeof (entered)); memset (entered, 0, sizeof (entered));
get_cmdline (" Password: ", NULL, entered, 31, '*'); get_cmdline (" Password: ", entered, 31, '*', 0);
while (! isspace (*pptr) && *pptr) while (! isspace (*pptr) && *pptr)
pptr ++; pptr++;
/* Make sure that PASSWORD is NUL-terminated. */ /* Make sure that PASSWORD is NUL-terminated. */
*pptr++ = 0; *pptr++ = 0;
@ -377,13 +373,14 @@ restart:
{ {
char *new_file = config_file; char *new_file = config_file;
while (isspace (*pptr)) while (isspace (*pptr))
pptr ++; pptr++;
while ((*(new_file ++) = *(pptr ++)) != 0); while ((*(new_file++) = *(pptr++)) != 0)
return MENU_OK; ;
return;
} }
else else
{ {
printf("Failed!\n Press any key to continue..."); printf ("Failed!\n Press any key to continue...");
getkey (); getkey ();
goto restart; goto restart;
} }
@ -399,15 +396,17 @@ restart:
if (config_entries) if (config_entries)
{ {
new_heap = heap; new_heap = heap;
cur_entry = get_entry(config_entries, cur_entry = get_entry (config_entries,
first_entry+entryno, 1); first_entry + entryno,
1);
} }
else else
{ {
/* safe area! */ /* safe area! */
new_heap = heap + NEW_HEAPSIZE + 1; new_heap = heap + NEW_HEAPSIZE + 1;
cur_entry = get_entry(menu_entries, cur_entry = get_entry (menu_entries,
first_entry+entryno, 0); first_entry + entryno,
0);
} }
do do
@ -422,11 +421,11 @@ restart:
*(new_heap++) = 0; *(new_heap++) = 0;
if (config_entries) if (config_entries)
run_menu(heap, NULL, num_entries, new_heap, 0); run_menu (heap, NULL, num_entries, new_heap, 0);
else else
{ {
cls(); cls ();
init_cmdline(); print_cmdline_message ();
new_heap = heap + NEW_HEAPSIZE + 1; new_heap = heap + NEW_HEAPSIZE + 1;
@ -434,13 +433,14 @@ restart:
saved_partition = install_partition; saved_partition = install_partition;
current_drive = 0xFF; current_drive = 0xFF;
if (! get_cmdline(PACKAGE " edit> ", commands, new_heap, if (! get_cmdline (PACKAGE " edit> ", new_heap,
NEW_HEAPSIZE + 1, 0)) NEW_HEAPSIZE + 1, 0, 1))
{ {
int j = 0; int j = 0;
/* get length of new command */ /* get length of new command */
while (new_heap[j++]); while (new_heap[j++])
;
if (j < 2) if (j < 2)
{ {
@ -451,7 +451,7 @@ restart:
/* align rest of commands properly */ /* align rest of commands properly */
memmove (cur_entry + j, cur_entry + i, memmove (cur_entry + j, cur_entry + i,
((int)heap) - (((int)cur_entry) + i)); ((int) heap) - (((int) cur_entry) + i));
/* copy command to correct area */ /* copy command to correct area */
memmove (cur_entry, new_heap, j); memmove (cur_entry, new_heap, j);
@ -464,18 +464,16 @@ restart:
} }
if (c == 'c') if (c == 'c')
{ {
/* Call the command-line interface, and if it aborts enter_cmdline (heap);
(by ``quit'' command), then return. */
if (enter_cmdline (NULL, heap) == CMDLINE_ABORT)
return MENU_ABORT;
goto restart; goto restart;
} }
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
if (c == 'q') if (c == 'q')
{ {
/* The same as ``quit''. */ /* The same as ``quit''. */
return MENU_ABORT; #ifdef GRUB_UTIL
stop ();
#endif
} }
#endif #endif
} }
@ -486,47 +484,45 @@ restart:
* Attempt to boot an entry. * Attempt to boot an entry.
*/ */
do while (1)
{ {
cls(); cls ();
if (config_entries) if (config_entries)
printf(" Booting \'%s\'\n\n", printf (" Booting \'%s\'\n\n",
get_entry(menu_entries, first_entry+entryno, 0)); get_entry (menu_entries, first_entry + entryno, 0));
else else
printf(" Booting command-list\n\n"); printf (" Booting command-list\n\n");
if (!cur_entry) if (! cur_entry)
cur_entry = get_entry(config_entries, first_entry+entryno, 1); 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)
break; {
/* Both the entry and the fallback failed, so wait for
input. */
grub_printf (" Press any key to continue...");
(void) getkey ();
break;
}
else else
{ {
cur_entry = NULL; cur_entry = NULL;
first_entry = 0; first_entry = 0;
entryno = fallback; entryno = fallback_entry;
fallback = -1; 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; goto restart;
} }
static int static int
get_line_from_config(char *cmdline, int maxlen) get_line_from_config (char *cmdline, int maxlen)
{ {
int pos = 0, literal = 0, comment = 0; int pos = 0, literal = 0, comment = 0;
char c; /* since we're loading it a byte at a time! */ char c; /* since we're loading it a byte at a time! */
@ -551,7 +547,7 @@ get_line_from_config(char *cmdline, int maxlen)
if (c == '\n') if (c == '\n')
comment = 0; comment = 0;
} }
else if (!pos) else if (! pos)
{ {
if (c == '#') if (c == '#')
comment = 1; comment = 1;
@ -574,27 +570,24 @@ get_line_from_config(char *cmdline, int maxlen)
} }
/* This is the starting function in C. */
void void
cmain(void) cmain (void)
{ {
int config_len, menu_len, num_entries, default_entry; int config_len, menu_len, num_entries;
char *config_entries, *menu_entries; char *config_entries, *menu_entries;
/* Never return. */
for (;;) for (;;)
{ {
config_len = 0; config_len = 0;
menu_len = 0; menu_len = 0;
num_entries = 0; num_entries = 0;
default_entry = 0; config_entries = (char *) (mbi.mmap_addr + mbi.mmap_length);
normal_color = A_NORMAL; menu_entries = (char *) MENU_BUF;
highlight_color = A_REVERSE; init_config ();
config_entries = (char *)(mbi.mmap_addr + mbi.mmap_length);
menu_entries = (char *)(BUFFERADDR + (32 * 1024));
password = NULL; fallback = -1; grub_timeout = -1;
/* /* Here load the configuration file. */
* Here load the configuration file.
*/
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
if (use_config_file && grub_open (config_file)) if (use_config_file && grub_open (config_file))
@ -602,17 +595,31 @@ cmain(void)
if (grub_open (config_file)) if (grub_open (config_file))
#endif #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; 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)) 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) if (state > 1)
{ {
/* The next title is found. */
num_entries++; num_entries++;
config_entries[config_len++] = 0; config_entries[config_len++] = 0;
prev_menu_len = menu_len; prev_menu_len = menu_len;
@ -620,61 +627,46 @@ cmain(void)
} }
else else
{ {
/* The first title is found. */
menu_len = prev_menu_len; menu_len = prev_menu_len;
config_len = prev_config_len; config_len = prev_config_len;
} }
/* Reset the state. */
state = 1; state = 1;
/* copy title into menu area */ /* Copy title into menu area. */
while ((menu_entries[menu_len++] = *(ptr++)) != 0); ptr = skip_to (1, cmdline);
while ((menu_entries[menu_len++] = *(ptr++)) != 0)
;
} }
else if (!state) else if (! state)
{ {
if (substring ("timeout", cmdline) < 1) /* Run a command found is possible. */
safe_parse_maxint (&ptr, &grub_timeout); if (builtin->flags & BUILTIN_MENU)
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)
{ {
char *normal; char *arg = skip_to (1, cmdline);
char *highlight; (builtin->func) (arg, BUILTIN_MENU);
errnum = 0;
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) else
{ /* Ignored. */
password = config_entries; continue;
while ((*(config_entries++) = *(ptr++)) != 0);
}
errnum = 0;
} }
else else
{ {
int i = 0; char *ptr = cmdline;
state++; state++;
/* Copy config file data to config area. */
/* copy config file data to config area */ while ((config_entries[config_len++] = *ptr++) != 0)
while ((config_entries[config_len++] = cmdline[i++]) != 0); ;
} }
} }
if (state > 1) if (state > 1)
{ {
/* Finish the last entry. */
num_entries++; num_entries++;
config_entries[config_len++] = 0; config_entries[config_len++] = 0;
} }
@ -686,7 +678,7 @@ cmain(void)
menu_entries[menu_len++] = 0; menu_entries[menu_len++] = 0;
config_entries[config_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; menu_entries = config_entries + config_len;
} }
@ -695,17 +687,14 @@ cmain(void)
/* If no acceptable config file, goto command-line, starting /* If no acceptable config file, goto command-line, starting
heap from where the config entries would have been stored heap from where the config entries would have been stored
if there were any. */ if there were any. */
while (enter_cmdline (NULL, config_entries) != CMDLINE_ABORT) while (1)
; enter_cmdline (config_entries);
return;
} }
else else
{ {
/* Run menu interface. */ /* Run menu interface. */
if (run_menu(menu_entries, config_entries, num_entries, run_menu (menu_entries, config_entries, num_entries,
menu_entries+menu_len, default_entry) == MENU_ABORT) menu_entries + menu_len, default_entry);
return;
} }
} }
} }