From ab6e2839e57058bcce6f5b0b093f0e58b6e25384 Mon Sep 17 00:00:00 2001 From: gord Date: Mon, 15 Mar 1999 02:08:13 +0000 Subject: [PATCH] Get /sbin/grub GUI working. --- ChangeLog | 34 +++ configure | 180 ++++++------- configure.in | 5 + docs/TODO | 8 +- grub/asmstub.c | 175 +++++++++++-- grub/main.c | 74 +++++- shared_src/asm.S | 4 +- shared_src/boot.c | 39 ++- shared_src/char_io.c | 69 ++--- shared_src/cmdline.c | 109 ++++---- shared_src/common.c | 13 +- shared_src/disk_io.c | 90 ++++--- shared_src/filesys.h | 44 +--- shared_src/fsys_ext2fs.c | 30 +-- shared_src/fsys_fat.c | 6 +- shared_src/fsys_ffs.c | 15 +- shared_src/gunzip.c | 22 +- shared_src/shared.h | 543 +++++++++++++++++++-------------------- shared_src/smp-imps.c | 3 +- shared_src/stage1_5.c | 2 +- shared_src/stage2.c | 70 ++--- 21 files changed, 889 insertions(+), 646 deletions(-) diff --git a/ChangeLog b/ChangeLog index 455f2e43e..37537f87b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,37 @@ +1999-03-14 Gordon Matzigkeit + + * shared_src/stage2.c (run_menu): Use A_REVERSE and A_NORMAL + constants instead of magic numbers. + + * shared_src/shared.h (A_REVERSE): Renamed from ATTR_INVERSE for + compatibility with curses. + (A_NORMAL): Renamed from ATTR_NORMAL. + + * shared_src/cmdline.c (enter_cmdline): Change prompt to "grub> ". + (enter_cmdline): Only abort the boot if we are in a script. + + * shared_src/stage2.c (run_menu): Change prompts to "grub edit> ". + + * shared_src/char_io.c (memcheck): Use RAW_ADDR to compute memory + locations. + (get_cmdline): Change the `goto next line' code to account for + newlines deleting to end of line under curses. + + * Innumerable cleanups to fix warnings. There are still too many + typecasts in the wrong places (int variables used to hold + pointers, then casted to a pointer type), but things look better. + + * configure.in (CPPFLAGS): Bump up GCC warnings to -Wall + -Wmissing-prototypes -Wunused. + + * shared_src/shared.h: Delete stupid declarations, and totally + rearrange for clarity. + (inb, outb): Move to cmdline.c, since it's only used there. + (print_possibilities, fsmax, fsys_table): Move definitions to + disk_io.c. + + * grub/asmstub.c: Fill in more stubs. + 1999-03-13 Gordon Matzigkeit * shared_src/gunzip.c (border): Rename to bitorder, to resolve diff --git a/configure b/configure index 4f31253dc..91710ab7b 100644 --- a/configure +++ b/configure @@ -892,74 +892,10 @@ fi -# Extract the first word of "${ac_tool_prefix}ld", so it can be a program name with args. -set dummy ${ac_tool_prefix}ld; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:899: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$LD"; then - ac_cv_prog_LD="$LD" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_LD="${ac_tool_prefix}ld" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_prog_LD" && ac_cv_prog_LD="ld" -fi -fi -LD="$ac_cv_prog_LD" -if test -n "$LD"; then - echo "$ac_t""$LD" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - - -# Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args. -set dummy ${ac_tool_prefix}objcopy; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:930: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_OBJCOPY'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$OBJCOPY"; then - ac_cv_prog_OBJCOPY="$OBJCOPY" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_OBJCOPY="${ac_tool_prefix}objcopy" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_prog_OBJCOPY" && ac_cv_prog_OBJCOPY="objcopy" -fi -fi -OBJCOPY="$ac_cv_prog_OBJCOPY" -if test -n "$OBJCOPY"; then - echo "$ac_t""$OBJCOPY" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - - - -# Defined in acinclude.m4. # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:963: checking for $ac_word" >&5 +echo "configure:899: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -988,7 +924,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:992: checking for $ac_word" >&5 +echo "configure:928: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1036,7 +972,7 @@ fi fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:1040: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:976: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -1046,11 +982,11 @@ ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:990: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -1070,12 +1006,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:1074: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:1010: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:1079: checking whether we are using GNU C" >&5 +echo "configure:1015: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1084,7 +1020,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1088: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1024: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1099,7 +1035,7 @@ if test $ac_cv_prog_gcc = yes; then ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1103: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:1039: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1127,8 +1063,76 @@ else fi +# Enforce coding standards. +CPPFLAGS="$CPPFLAGS -Wall -Wmissing-prototypes -Wunused" + +# Extract the first word of "${ac_tool_prefix}ld", so it can be a program name with args. +set dummy ${ac_tool_prefix}ld; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1073: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$LD"; then + ac_cv_prog_LD="$LD" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_LD="${ac_tool_prefix}ld" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_LD" && ac_cv_prog_LD="ld" +fi +fi +LD="$ac_cv_prog_LD" +if test -n "$LD"; then + echo "$ac_t""$LD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +# Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args. +set dummy ${ac_tool_prefix}objcopy; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1104: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_OBJCOPY'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$OBJCOPY"; then + ac_cv_prog_OBJCOPY="$OBJCOPY" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_OBJCOPY="${ac_tool_prefix}objcopy" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_OBJCOPY" && ac_cv_prog_OBJCOPY="objcopy" +fi +fi +OBJCOPY="$ac_cv_prog_OBJCOPY" +if test -n "$OBJCOPY"; then + echo "$ac_t""$OBJCOPY" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + + +# Defined in acinclude.m4. + echo $ac_n "checking symbol names produced by ${CC-cc}""... $ac_c" 1>&6 -echo "configure:1132: checking symbol names produced by ${CC-cc}" >&5 +echo "configure:1136: checking symbol names produced by ${CC-cc}" >&5 if eval "test \"`echo '$''{'grub_cv_asm_ext_c'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1141,7 +1145,7 @@ func (int *list) } EOF -if { ac_try='${CC-cc} -S conftest.c'; { (eval echo configure:1145: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.s; then : +if { ac_try='${CC-cc} -S conftest.c'; { (eval echo configure:1149: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.s; then : else { echo "configure: error: ${CC-cc} failed to produce assembly code" 1>&2; exit 1; } fi @@ -1169,7 +1173,7 @@ EOF echo $ac_n "checking whether ${OBJCOPY} works for absolute addresses""... $ac_c" 1>&6 -echo "configure:1173: checking whether ${OBJCOPY} works for absolute addresses" >&5 +echo "configure:1177: checking whether ${OBJCOPY} works for absolute addresses" >&5 if eval "test \"`echo '$''{'grub_cv_prog_objcopy_absolute'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1181,21 +1185,21 @@ blah (void) } EOF -if { (eval echo configure:1185: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.o; then : +if { (eval echo configure:1189: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.o; then : else { echo "configure: error: ${CC-cc} cannot compile C source code" 1>&2; exit 1; } fi grub_cv_prog_objcopy_absolute=yes for link_addr in 2000 8000 7C00; do - if { ac_try='${LD-ld} -N -Ttext $link_addr conftest.o -o conftest.exec'; { (eval echo configure:1191: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then : + if { ac_try='${LD-ld} -N -Ttext $link_addr conftest.o -o conftest.exec'; { (eval echo configure:1195: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then : else { echo "configure: error: ${LD-ld} cannot link at address $link_addr" 1>&2; exit 1; } fi - if { ac_try='${OBJCOPY-objcopy} -O binary conftest.exec conftest'; { (eval echo configure:1195: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then : + if { ac_try='${OBJCOPY-objcopy} -O binary conftest.exec conftest'; { (eval echo configure:1199: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then : else { echo "configure: error: ${OBJCOPY-objcopy} cannot create binary files" 1>&2; exit 1; } fi - if test ! -f conftest.old || { ac_try='cmp -s conftest.old conftest'; { (eval echo configure:1199: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then + if test ! -f conftest.old || { ac_try='cmp -s conftest.old conftest'; { (eval echo configure:1203: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then mv -f conftest conftest.old else grub_cv_prog_objcopy_absolute=no @@ -1212,7 +1216,7 @@ fi echo $ac_n "checking for .code16 addr32 assembler support""... $ac_c" 1>&6 -echo "configure:1216: checking for .code16 addr32 assembler support" >&5 +echo "configure:1220: checking for .code16 addr32 assembler support" >&5 if eval "test \"`echo '$''{'grub_cv_asm_addr32'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1222,7 +1226,7 @@ l1: addr32 movb %al, l1 EOF -if { ac_try='${CC-cc} -c conftest.s'; { (eval echo configure:1226: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.o; then +if { ac_try='${CC-cc} -c conftest.s'; { (eval echo configure:1230: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } && test -s conftest.o; then grub_cv_asm_addr32=yes else grub_cv_asm_addr32=no @@ -1238,7 +1242,7 @@ fi # Check for curses libraries if we are building /sbin/grub. if test -n "$sbingrub"; then echo $ac_n "checking for getch in -lncurses""... $ac_c" 1>&6 -echo "configure:1242: checking for getch in -lncurses" >&5 +echo "configure:1246: checking for getch in -lncurses" >&5 ac_lib_var=`echo ncurses'_'getch | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1246,7 +1250,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lncurses $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1265: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1280,7 +1284,7 @@ EOF else echo "$ac_t""no" 1>&6 echo $ac_n "checking for getch in -lcurses""... $ac_c" 1>&6 -echo "configure:1284: checking for getch in -lcurses" >&5 +echo "configure:1288: checking for getch in -lcurses" >&5 ac_lib_var=`echo curses'_'getch | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1288,7 +1292,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcurses $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1307: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else diff --git a/configure.in b/configure.in index 669ca53c4..2307236cd 100644 --- a/configure.in +++ b/configure.in @@ -49,6 +49,11 @@ AC_SUBST(stage2debug) # AC_CHECK_TOOL(CC, gcc) +AC_PROG_CC + +# Enforce coding standards. +CPPFLAGS="$CPPFLAGS -Wall -Wmissing-prototypes -Wunused" + AC_CHECK_TOOL(LD, ld) AC_CHECK_TOOL(OBJCOPY, objcopy) diff --git a/docs/TODO b/docs/TODO index d7db22b29..3c83eac77 100644 --- a/docs/TODO +++ b/docs/TODO @@ -1,5 +1,3 @@ -Get /sbin/grub to work. - Change partition syntax to correspond with BSD ``slice'' syntax (`(hd0,1a)' -> `/dev/hd0s2a'). @@ -9,10 +7,10 @@ type''. We need this for clean Hurd install floppies. Find out the size restrictions for FAT and ext2fs stage1.5 boot blocks. Enforce all arbitrary limits using the Makefiles. -Finish LBA and int13 extensions support. +Finish int13 extensions support. -Add a real scripting language, possibly retain backward compatibility -so that old config files can be used. +Add a real scripting language, possibly retaining backward +compatibility so that old config files can be used. Look at the network booting patches from L4. diff --git a/grub/asmstub.c b/grub/asmstub.c index 0e84bf3a9..14b50ab38 100644 --- a/grub/asmstub.c +++ b/grub/asmstub.c @@ -18,6 +18,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* Simulator entry point. */ +int grub_stage2 (void); + #include "shared.h" /* We want to prevent any circularararity in our stubs, as well as libc name clashes. */ @@ -45,15 +48,37 @@ unsigned long install_partition = 0x20000; unsigned long boot_drive = 0; char version_string[] = "0.5"; char config_file[] = "/boot/grub/menu.lst"; + +/* Emulation requirements. */ char *grub_scratch_mem = 0; +#define NUM_DISKS 256 +static FILE **disks = 0; + /* The main entry point into this mess. */ -void -start_stage2 (void) +int +grub_stage2 (void) { - grub_scratch_mem = memalign (16, EXTENDED_MEMSIZE); + /* These need to be static, because they survive our stack transitions. */ + static int status = 0; + static char *realstack; + int i; + char *scratch, *simstack; + + assert (grub_scratch_mem == 0); + scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15); + assert (scratch); + grub_scratch_mem = (char *) ((((int) scratch) >> 4) << 4); + + /* FIXME: simulate the memory holes using mprot, if available. */ + + assert (disks == 0); + disks = malloc (NUM_DISKS * sizeof (*disks)); + assert (disks); /* Check some invariants. */ + assert ((SCRATCHSEG << 4) == SCRATCHADDR); + assert ((BUFFERSEG << 4) == BUFFERADDR); assert (BUFFERADDR + BUFFERLEN == SCRATCHADDR); assert (FSYS_BUF % 16 == 0); assert (FSYS_BUF + FSYS_BUFLEN == BUFFERADDR); @@ -63,16 +88,65 @@ start_stage2 (void) initscr (); cbreak (); noecho (); + nonl (); scrollok (stdscr, TRUE); + keypad (stdscr, TRUE); #endif - init_bios_info (); + /* Make sure our stack lives in the simulated memory area. */ + simstack = (char *) RAW_ADDR (PROTSTACKINIT); +#ifdef SIMULATE_STACK + __asm __volatile ("movl %%esp, %0;" : "=d" (realstack)); + __asm __volatile ("movl %0, %%esp" :: "d" (simstack)); +#endif + + { + /* FIXME: Do a setjmp here for the stop command. */ + if (1) + { + /* Actually enter the generic stage2 code. */ + status = 0; + init_bios_info (); + } + else + { + /* Somebody aborted. */ + status = 1; + } + } + +#ifdef SIMULATE_STACK + /* Replace our stack before we use any local variables. */ + __asm __volatile ("movl %0, %%esp" :: "d" (realstack)); +#endif + +#ifdef HAVE_LIBCURSES + endwin (); +#endif + + /* Close off the file pointers we used. */ + for (i = 0; i < NUM_DISKS; i ++) + if (disks[i]) + fclose (disks[i]); + + /* Release memory. */ + free (disks); + disks = 0; + free (scratch); + grub_scratch_mem = 0; + + /* Ahh... at last we're ready to return to caller. */ + return status; } void stop (void) { +#ifdef HAVE_LIBCURSES + endwin (); +#endif + /* FIXME: If we don't exit, then we need to free our data areas. */ fprintf (stderr, "grub: aborting...\n"); exit (1); } @@ -124,11 +198,11 @@ gateA20 (int linear) } -void * +int get_code_end (void) { /* Just return a little area for simulation. */ - return malloc (1024); + return BOOTSEC_LOCATION + (60 * 1024); } @@ -159,21 +233,12 @@ get_eisamemsize (void) #define MMAR_DESC_TYPE_ACPI_RECLAIM 3 /* usable by OS after reading ACPI */ #define MMAR_DESC_TYPE_ACPI_NVS 4 /* required to save between NVS sessions */ -/* Memory map address range descriptor. */ -struct mmar_desc -{ - unsigned long desc_len; /* Size of this descriptor. */ - unsigned long long addr; /* Base address. */ - unsigned long long length; /* Length in bytes. */ - unsigned long type; /* Type of address range. */ -}; - /* Fetch the next entry in the memory map and return the continuation value. DESC is a pointer to the descriptor buffer, and CONT is the previous continuation value (0 to get the first entry in the map). */ int -get_mem_map (struct mmar_desc *desc, int cont) +get_mmap_entry (struct mmar_desc *desc, int cont) { if (! cont) { @@ -204,6 +269,9 @@ getrtsecs (void) void cls (void) { +#ifdef HAVE_LIBCURSES + clear (); +#endif } @@ -211,12 +279,22 @@ cls (void) int getxy (void) { + int y, x; +#ifdef HAVE_LIBCURSES + getyx (stdscr, y, x); +#else + y = x = 0; +#endif + return (x << 8) | (y & 0xff); } void gotoxy (int x, int y) { +#ifdef HAVE_LIBCURSES + move (y, x); +#endif } @@ -225,7 +303,11 @@ gotoxy (int x, int y) void grub_putchar (int c) { +#ifdef HAVE_LIBCURSES addch (c); +#else + putchar (c); +#endif } @@ -233,11 +315,15 @@ grub_putchar (int c) int getkey (void) { +#ifdef HAVE_LIBCURSES int c; nodelay (stdscr, FALSE); c = getch (); nodelay (stdscr, TRUE); return c; +#else + return getchar (); +#endif } @@ -245,7 +331,11 @@ getkey (void) int checkkey (void) { - getch (); +#ifdef HAVE_LIBCURSES + return getch (); +#else + return getchar (); +#endif } @@ -253,24 +343,71 @@ checkkey (void) void set_attrib (int attr) { +#ifdef HAVE_LIBCURSES + chgat (1, attr, 0, NULL); +#endif } -/* low-level disk I/O */ +/* Low-level disk I/O. Our stubbed version just returns a file + descriptor, not the actual geometry. */ int get_diskinfo (int drive) { -} + /* The unpartitioned device name: /dev/XdX */ + char devname[9]; + /* See if we have a cached device. */ + if (disks[drive]) + return (int) disks[drive]; + + /* Try opening the drive device. */ + strcpy (devname, "/dev/"); + if (drive & 0x80) + devname[5] = 'h'; + else + devname[5] = 'f'; + devname[6] = 'd'; + + /* Check to make sure we don't exceed /dev/hdz. */ + devname[7] = (drive & 0x7f) + 'a'; + if (devname[7] > 'z') + return 0; + devname[8] = '\0'; + + /* Open read/write, or read-only if that failed. */ + disks[drive] = fopen (devname, "r+"); + if (! disks[drive]) + disks[drive] = fopen (devname, "r"); + + return (int) disks[drive]; +} int biosdisk (int subfunc, int drive, int geometry, int sector, int nsec, int segment) { + char *buf; + FILE *fp; + + /* Get the file pointer from the geometry, and make sure it matches. */ + fp = (FILE *) geometry; + if (! fp || fp != disks[drive]) + return BIOSDISK_ERROR_GEOMETRY; + + /* Seek to the specified location. */ + if (fseek (fp, sector * SECTOR_SIZE, SEEK_SET)) + return -1; + + buf = (char *) (segment << 4); + if (fread (buf, nsec * SECTOR_SIZE, 1, fp) != 1) + return -1; + return 0; } void stop_floppy (void) { + /* NOTUSED */ } diff --git a/grub/main.c b/grub/main.c index 296b40b3c..47b7c747a 100644 --- a/grub/main.c +++ b/grub/main.c @@ -18,12 +18,78 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -extern void start_stage2 (void); +/* Simulator entry point. */ +int grub_stage2 (void); + +#include +#include + +char *program_name = 0; + +#define OPT_HELP -2 +#define OPT_VERSION -3 +#define OPTSTRING "" + +static struct option longopts[] = +{ + {"help", no_argument, 0, OPT_HELP}, + {"version", no_argument, 0, OPT_VERSION}, + {0}, +}; + + +static void +usage (int status) +{ + if (status) + fprintf (stderr, "Try ``%s --help'' for more information.\n", + program_name); + else + printf ("\ +Usage: %s [OPTION]...\n\ +\n\ +Enter the GRand Unified Bootloader command shell.\n\ +\n\ + --help display this message and exit\n\ + --version print version information and exit\n\ +", + program_name); + + exit (status); +} + int main (int argc, char **argv) { - /* Call the main entry point. */ - start_stage2 (); - exit (0); + int c; + program_name = argv[0]; + + /* Parse command-line options. */ + do + { + c = getopt_long (argc, argv, OPTSTRING, longopts, 0); + switch (c) + { + case EOF: + /* Fall through the bottom of the loop. */ + break; + + case OPT_HELP: + usage (0); + break; + + case OPT_VERSION: + printf ("GNU GRUB " VERSION "\n"); + exit (0); + break; + + default: + usage (1); + } + } + while (c != EOF); + + /* Transfer control to the stage2 simulator. */ + exit (grub_stage2 ()); } diff --git a/shared_src/asm.S b/shared_src/asm.S index a63b654a5..d2463d210 100644 --- a/shared_src/asm.S +++ b/shared_src/asm.S @@ -854,7 +854,7 @@ xnoteisa: /* * - * get_mem_map(addr, cont) : address and old continuation value (zero to + * get_mmap_entry(addr, cont) : address and old continuation value (zero to * start), for the Query System Address Map BIOS call. * * Sets the first 4-byte int value of "addr" to the size returned by @@ -865,7 +865,7 @@ xnoteisa: * NOTE: Currently hard-coded for a maximum buffer length of 1024. */ -ENTRY(get_mem_map) +ENTRY(get_mmap_entry) push %ebp push %ebx push %ecx diff --git a/shared_src/boot.c b/shared_src/boot.c index b34b5cc81..62bbe0fa6 100644 --- a/shared_src/boot.c +++ b/shared_src/boot.c @@ -1,6 +1,8 @@ +/* boot.c - load and bootstrap a kernel */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1996 Erich Boleyn + * Copyright (C) 1996 Erich Boleyn + * Copyright (C) 1999 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +20,6 @@ */ -#define _BOOT_C - #include "shared.h" #include "freebsd.h" @@ -41,9 +41,9 @@ static struct mod_list mll[99]; int load_image (void) { - int len, i, exec_type, align_4k = 1, type = 0; - unsigned long flags = 0, text_len, data_len, bss_len; - char *str, *str2; + int len, i, exec_type = 0, align_4k = 1, type = 0; + unsigned long flags = 0, text_len = 0, data_len = 0, bss_len = 0; + char *str = 0, *str2 = 0; union { struct multiboot_header *mb; @@ -59,10 +59,10 @@ load_image (void) buffer by default */ pu.aout = (struct exec *) buffer; - if (!open (cur_cmdline)) + if (!grub_open (cur_cmdline)) return 0; - if (!(len = read ((int) buffer, MULTIBOOT_SEARCH)) || len < 32) + if (!(len = grub_read (buffer, MULTIBOOT_SEARCH)) || len < 32) { if (!errnum) errnum = ERR_EXEC_FORMAT; @@ -101,8 +101,6 @@ load_image (void) || ((pu.elf->e_phoff + (pu.elf->e_phentsize * pu.elf->e_phnum)) >= len)) errnum = ERR_EXEC_FORMAT; - - exec_type = 0; str = "elf"; } else if (flags & MULTIBOOT_AOUT_KLUDGE) @@ -228,7 +226,7 @@ load_image (void) filepos = data_len + SECTOR_SIZE; cur_addr = LINUX_STAGING_AREA + text_len; - if (read (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'); else if (!errnum) errnum = ERR_EXEC_FORMAT; @@ -266,7 +264,7 @@ load_image (void) printf (", loadaddr=0x%x, text%s=0x%x", cur_addr, str, text_len); /* read text, then read data */ - if (read (cur_addr, text_len) == text_len) + if (grub_read ((char *) cur_addr, text_len) == text_len) { cur_addr += text_len; @@ -280,7 +278,8 @@ load_image (void) printf (", data=0x%x", data_len); - if (read (cur_addr, data_len) != data_len && !errnum) + if (grub_read ((char *) cur_addr, data_len) != data_len && + !errnum) errnum = ERR_EXEC_FORMAT; cur_addr += data_len; } @@ -310,12 +309,12 @@ load_image (void) printf (", symtab=0x%x", pu.aout->a_syms); - if (read (cur_addr, pu.aout->a_syms) == pu.aout->a_syms) + if (grub_read ((char *) cur_addr, pu.aout->a_syms) == pu.aout->a_syms) { cur_addr += pu.aout->a_syms; mbi.syms.a.tabsize = pu.aout->a_syms; - if (read ((int) (&i), sizeof (int)) == sizeof (int)) + if (grub_read ((char *) &i, sizeof (int)) == sizeof (int)) { *(((int *) cur_addr)++) = i; @@ -325,7 +324,7 @@ load_image (void) printf (", strtab=0x%x", i); - symtab_err = (read (cur_addr, i) != i); + symtab_err = (grub_read ((char *) cur_addr, i) != i); cur_addr += i; } else @@ -383,7 +382,7 @@ load_image (void) /* load the segment */ if (memcheck (memaddr, memsiz) - && read (memaddr, filesiz) == filesiz) + && grub_read ((char *) memaddr, filesiz) == filesiz) { if (memsiz > filesiz) bzero ((char *) (memaddr + filesiz), memsiz - filesiz); @@ -399,7 +398,7 @@ load_image (void) errnum = ERR_EXEC_FORMAT; else { - /* XXX load ELF symbols */ + /* FIXME: load ELF symbols */ } } } @@ -423,7 +422,7 @@ load_module (void) /* if we are supposed to load on 4K boundaries */ cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000; - if (!open (cur_cmdline) || !(len = read (cur_addr, -1))) + if (!grub_open (cur_cmdline) || !(len = grub_read ((char *) cur_addr, -1))) return 0; printf (" [Multiboot-module @ 0x%x, 0x%x bytes]\n", cur_addr, len); @@ -450,7 +449,7 @@ load_initrd (void) int len; long *ramdisk, moveto; - if (!open (cur_cmdline) || !(len = read (cur_addr, -1))) + if (!grub_open (cur_cmdline) || !(len = grub_read ((char *) cur_addr, -1))) return 0; moveto = ((mbi.mem_upper + 0x400) * 0x400 - len) & 0xfffff000; diff --git a/shared_src/char_io.c b/shared_src/char_io.c index 0c8ac47b5..5507485df 100644 --- a/shared_src/char_io.c +++ b/shared_src/char_io.c @@ -1,7 +1,8 @@ - +/* char_io.c - basic console input and output */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1996 Erich Boleyn + * Copyright (C) 1996 Erich Boleyn + * Copyright (C) 1999 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,8 +20,6 @@ */ -#define _CHAR_IO_C - #include "shared.h" @@ -88,7 +87,7 @@ printf (char *format,...) dataptr++; - while (c = *(format++)) + while ((c = *(format++)) != 0) { if (c != '%') putchar (c); @@ -113,7 +112,7 @@ printf (char *format,...) case 's': ptr = (char *) (*(dataptr++)); - while (c = *(ptr++)) + while ((c = *(ptr++)) != 0) putchar (c); break; } @@ -133,13 +132,12 @@ init_page (void) } -/* don't use this with a maxlen greater than 1600 or so! the problem - is that it depends on the whole thing fitting on the screen at once, - and the whole screen is about 2000 characters, minus the prompt... - so want to leave space for an error line, etc. - maxlen should be at least 1, and we shouldn't have a NULL prompt or - cmdline... the cmdline must be a valid string at the start */ - +/* Don't use this with a MAXLEN greater than 1600 or so! The problem + is that GET_CMDLINE depends on the everything fitting on the screen + at once. So, the whole screen is about 2000 characters, minus the + PROMPT, and space for error and status lines, etc. MAXLEN must be + at least 1, and PROMPT and CMDLINE must be valid strings (not NULL + or zero-length). */ int get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen) { @@ -147,8 +145,8 @@ get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen) int plen = 0; int llen = 0; - /* nested function definition for code simplicity XXX GCC only, I think */ - void cl_print (char *str) + /* nested function definition for code simplicity */ + static void cl_print (char *str) { while (*str != 0) { @@ -157,15 +155,15 @@ get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen) { xend = 0; putchar (' '); - if (yend == (getxy () & 0xFF)) + if (yend == (getxy () & 0xff)) ystart--; else yend++; } } } - /* nested function definition for code simplicity XXX GCC only, I think */ - void cl_setcpos (void) + /* nested function definition for code simplicity */ + static void cl_setcpos (void) { yend = ((lpos + plen) / 79) + ystart; xend = ((lpos + plen) % 79); @@ -173,13 +171,13 @@ get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen) } /* nested function definition for initial command-line printing */ - void cl_init () + static void cl_init () { /* distinguish us from other lines and error messages! */ putchar ('\n'); /* print full line and set position here */ - ystart = (getxy () & 0xFF); + ystart = (getxy () & 0xff); yend = ystart; xend = 0; cl_print (prompt); @@ -188,10 +186,10 @@ get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen) } /* nested function definition for erasing to the end of the line */ - void cl_kill_to_end () + static void cl_kill_to_end () { int i; - cmdline[lpos] = 0; + cmdline[lpos] = 0; for (i = lpos; i <= llen; i++) { if (i && ((i + plen) % 79) == 0) @@ -206,14 +204,13 @@ get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen) plen++; while (cmdline[llen]) llen++; - /* XXX limiting maxlen to 1600 */ - if (maxlen > 1600) + if (maxlen > MAX_CMDLINE) { - maxlen = 1600; - if (llen > 1599) + maxlen = MAX_CMDLINE; + if (llen >= MAX_CMDLINE) { - llen = 1599; - cmdline[1600] = 0; + llen = MAX_CMDLINE - 1; + cmdline[MAX_CMDLINE] = 0; } } lpos = llen; @@ -237,6 +234,8 @@ get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen) c = 5; break; case KEY_DC: + c = 4; + case KEY_BACKSPACE: c = 8; default: } @@ -261,8 +260,8 @@ get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen) /* goto part after line here */ yend = ((llen + plen) / 79) + ystart; - gotoxy (0, yend); putchar ('\n'); + gotoxy (0, getxy () & 0xff); if (lpos > j) { @@ -382,8 +381,8 @@ get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen) /* goto part after line here */ yend = ((llen + plen) / 79) + ystart; - gotoxy (0, yend); putchar ('\n'); + gotoxy (0, getxy () & 0xff); /* remove leading spaces */ /* use c and lpos as indexes now */ @@ -563,10 +562,12 @@ strstr (char *s1, char *s2) int memcheck (int start, int len) { - if ((start < 0x1000) || (start < 0x100000 - && (mbi.mem_lower * 1024) < (start + len)) - || (start >= 0x100000 - && (mbi.mem_upper * 1024) < ((start - 0x100000) + len))) + /* FIXME: fails when used with addresses on our stack. */ + if ((start < RAW_ADDR (0x1000)) || + (start < RAW_ADDR (0x100000) && + RAW_ADDR (mbi.mem_lower * 1024) < (start + len)) || + (start >= RAW_ADDR (0x100000) && + RAW_ADDR (mbi.mem_upper * 1024) < ((start - 0x100000) + len))) errnum = ERR_WONT_FIT; return (!errnum); diff --git a/shared_src/cmdline.c b/shared_src/cmdline.c index 12d47ca6c..dce7416b5 100644 --- a/shared_src/cmdline.c +++ b/shared_src/cmdline.c @@ -1,6 +1,8 @@ +/* cmdline.c - the device-independent GRUB text command line */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1996 Erich Boleyn + * Copyright (C) 1996 Erich Boleyn + * Copyright (C) 1999 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,8 +19,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define _CMDLINE_C - #include "shared.h" #ifdef DEBUG @@ -34,6 +34,22 @@ #define PHYS_TO_VIRTUAL(x) (x) #define VIRTUAL_TO_PHYS(x) (x) +static inline unsigned char +inb (unsigned short port) +{ + unsigned char data; + + __asm __volatile ("inb %1,%0":"=a" (data):"d" (port)); + return data; +} + +static inline void +outb (unsigned short port, unsigned char val) +{ + __asm __volatile ("outb %0,%1"::"a" (val), "d" (port)); +} + + __inline__ static void cmos_write_byte(int loc, int val) { @@ -139,12 +155,9 @@ debug_fs_blocklist_func(int sector) int -enter_cmdline(char *script, char *heap) +enter_cmdline (char *script, char *heap) { int bootdev, cmd_len, type = 0, run_cmdline = 1, have_run_cmdline = 0; -#ifdef DEBUG - int mptest = 0; -#endif /* DEBUG */ char *cur_heap = heap, *cur_entry = script, *old_entry; /* initialization */ @@ -178,7 +191,7 @@ restart: if (password || errnum == ERR_BOOT_COMMAND) { printf("Press any key to continue..."); - getc(); + (void) getc (); returnit: return 0; } @@ -211,7 +224,7 @@ returnit: print_error(); } - if (run_cmdline && get_cmdline("command> ", commands, cur_heap, 2048)) + if (run_cmdline && get_cmdline(PACKAGE "> ", commands, cur_heap, 2048)) return 1; if (substring("boot", cur_heap) == 0 || (script && !*cur_heap)) @@ -247,9 +260,9 @@ returnit: if (substring("chainloader", cur_heap) < 1) { - if (open(cur_cmdline) && (read(BOOTSEC_LOCATION, SECTOR_SIZE) - == SECTOR_SIZE) - && (*((unsigned short *) (BOOTSEC_LOCATION+BOOTSEC_SIG_OFFSET)) + 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) @@ -301,7 +314,7 @@ returnit: bcopy(cur_heap, heap, cmd_len + (((int)cur_cmdline) - ((int)cur_heap))); cur_cmdline = heap + (((int)cur_cmdline) - ((int)cur_heap)); cur_heap = heap; - if (type = load_image()) + if ((type = load_image()) != 0) cur_heap = cur_cmdline + cmd_len; } else if (substring("module", cur_heap) < 1) @@ -324,7 +337,7 @@ returnit: } else if (type == 'L' || type == 'l') { - load_initrd(); + load_initrd (); } else errnum = ERR_NEED_MB_KERNEL; @@ -333,16 +346,16 @@ returnit: { if (type == 'L' || type == 'l') { - load_initrd(); + load_initrd (); } else errnum = ERR_NEED_LX_KERNEL; } else if (substring("install", cur_heap) < 1) { - char *stage1_file = cur_cmdline, *dest_dev, *file, *addr, *config_file; + char *stage1_file = cur_cmdline, *dest_dev, *file, *addr; char buffer[SECTOR_SIZE], old_sect[SECTOR_SIZE]; - int i = BOOTSEC_LOCATION+STAGE1_FIRSTLIST-4, new_drive = 0xFF; + int new_drive = 0xFF; dest_dev = skip_to(0, stage1_file); if (*dest_dev == 'd') @@ -350,13 +363,14 @@ returnit: new_drive = 0; dest_dev = skip_to(0, dest_dev); } - file = skip_to(0, dest_dev); - addr = skip_to(0, file); + file = skip_to (0, dest_dev); + addr = skip_to (0, file); - if (safe_parse_maxint(&addr, &installaddr) && open(stage1_file) - && read((int)buffer, SECTOR_SIZE) == SECTOR_SIZE - && set_device(dest_dev) && open_partition() - && devread(0, 0, SECTOR_SIZE, (int)old_sect)) + 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, dest_geom = buf_geom; int dest_sector = part_start, i; @@ -383,7 +397,7 @@ returnit: { errnum = ERR_BAD_VERSION; } - else if (open(file)) + else if (grub_open (file)) { if (!new_drive) new_drive = current_drive; @@ -415,7 +429,8 @@ returnit: installlist = BOOTSEC_LOCATION+STAGE1_FIRSTLIST+4; debug_fs = debug_fs_blocklist_func; - if (!errnum && read(SCRATCHADDR, SECTOR_SIZE) == SECTOR_SIZE) + if (!errnum && + grub_read ((char *) SCRATCHADDR, SECTOR_SIZE) == SECTOR_SIZE) { if (*((long *)SCRATCHADDR) != 0x8070ea || (*((short *)(SCRATCHADDR+STAGE2_VER_MAJ_OFFS)) @@ -442,10 +457,10 @@ returnit: write_stage2_sect++; while (*(str++)); /* find string */ - while (*(str++) = *(ptr++)); /* do copy */ + while ((*(str++) = *(ptr++)) != 0); /* do copy */ } - read(0x100000, -1); + grub_read ((char *) 0x100000, -1); buf_track = -1; @@ -468,14 +483,19 @@ returnit: no_decompression = 0; #endif } - fallback = -1; - return 1; + + /* Error running the install script, so drop to command line. */ + if (script) + { + fallback = -1; + return 1; + } } #ifdef DEBUG else if (substring("testload", cur_heap) < 1) { type = 0; - if (open(cur_cmdline)) + if (grub_open (cur_cmdline)) { int i; @@ -488,7 +508,7 @@ returnit: /* read whole file first */ printf("Whole file: "); - read(0x100000, -1); + grub_read ((char *) 0x100000, -1); /* now compare two sections of the file read differently */ @@ -502,23 +522,23 @@ returnit: printf("\nPartial read 1: "); filepos = 0; - read(0x200000, 0x7); - read(0x200007, 0x100); - read(0x200107, 0x10); - read(0x200117, 0x999); - read(0x200ab0, 0x10); - read(0x200ac0, 0x10000); + grub_read ((char *) 0x200000, 0x7); + grub_read ((char *) 0x200007, 0x100); + grub_read ((char *) 0x200107, 0x10); + grub_read ((char *) 0x200117, 0x999); + grub_read ((char *) 0x200ab0, 0x10); + grub_read ((char *) 0x200ac0, 0x10000); /* second partial read */ printf("\nPartial read 2: "); filepos = 0; - read(0x300000, 0x10000); - read(0x310000, 0x10); - read(0x310010, 0x7); - read(0x310017, 0x10); - read(0x310027, 0x999); - read(0x3109c0, 0x100); + grub_read ((char *) 0x300000, 0x10000); + grub_read ((char *) 0x310000, 0x10); + grub_read ((char *) 0x310010, 0x7); + grub_read ((char *) 0x310017, 0x10); + grub_read ((char *) 0x310027, 0x999); + grub_read ((char *) 0x3109c0, 0x100); printf("\nHeader1 = 0x%x, next = 0x%x, next = 0x%x, next = 0x%x\n", *((int *)0x200000), *((int *)0x200004), *((int *)0x200008), @@ -564,7 +584,8 @@ returnit: { if (get_eisamemsize() != -1) printf(" EISA Memory BIOS Interface is present\n"); - if (get_mem_map(SCRATCHADDR, 0) != 0 || *((int *) SCRATCHADDR) != 0) + 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", diff --git a/shared_src/common.c b/shared_src/common.c index e89e4168d..31720a0e4 100644 --- a/shared_src/common.c +++ b/shared_src/common.c @@ -1,6 +1,8 @@ +/* common.c - miscellaneous shared variables and routines */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1996 Erich Boleyn + * Copyright (C) 1996 Erich Boleyn + * Copyright (C) 1999 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,11 +19,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define _COMMON_C - #include "shared.h" - /* * Shared BIOS/boot data. */ @@ -35,7 +34,7 @@ unsigned long saved_mem_upper; * Error code stuff. */ -int errnum = 0; +grub_error_t errnum = ERR_NONE; #ifndef STAGE1_5 @@ -93,7 +92,9 @@ static struct AddrRangeDesc fakemap[3] = void init_bios_info (void) { +#ifndef STAGE1_5 int cont, memtmp, addr; +#endif /* * Get information from BIOS on installed RAM. @@ -125,7 +126,7 @@ init_bios_info (void) do { - cont = get_mem_map (addr, cont); + cont = get_mmap_entry ((void *) addr, cont); /* If the returned buffer's base is zero, quit. */ if (!*((int *) addr)) diff --git a/shared_src/disk_io.c b/shared_src/disk_io.c index 7a7b21361..20f91a2ed 100644 --- a/shared_src/disk_io.c +++ b/shared_src/disk_io.c @@ -1,3 +1,4 @@ +/* disk_io.c - implement abstract BIOS disk input and output */ /* * GRUB -- GRand Unified Bootloader * Copyright (C) 1996 Erich Boleyn @@ -19,20 +20,35 @@ */ -#define _DISK_IO_C - #include "shared.h" #include "filesys.h" -/* XXX for evil hack */ -#include "freebsd.h" - #ifndef STAGE1_5 /* instrumentation variables */ void (*debug_fs) (int) = NULL; void (*debug_fs_func) (int) = NULL; -#endif /* STAGE1_5 */ + +int print_possibilities; +#endif + +int fsmax; +struct fsys_entry fsys_table[NUM_FSYS + 1] = +{ +# ifdef FSYS_FAT + {"fat", fat_mount, 0, fat_dir}, +# endif +# ifdef FSYS_EXT2FS + {"ext2fs", ext2fs_mount, ext2fs_read, ext2fs_dir}, +# endif + /* XX FFS should come last as it's superblock is commonly crossing tracks + on floppies from track 1 to 2, while others only use 1. */ +# ifdef FSYS_FFS + {"ffs", ffs_mount, ffs_read, ffs_dir}, +# endif + {0, 0, 0, 0} +}; + /* These have the same format as "boot_drive" and "install_partition", but are meant to be working values. */ @@ -43,7 +59,8 @@ unsigned long current_partition; * Global variables describing details of the filesystem */ -/* XXX BSD evil hack */ +/* FIXME: BSD evil hack */ +#include "freebsd.h" int bsd_evil_hack; /* filesystem type */ @@ -69,9 +86,9 @@ int filemax; int -rawread (int drive, int sector, int byte_offset, int byte_len, int addr) +rawread (int drive, int sector, int byte_offset, int byte_len, char *buf) { - int slen = (byte_offset + byte_len + 511) / SECTOR_SIZE; + int slen = (byte_offset + byte_len + SECTOR_SIZE - 1) / SECTOR_SIZE; if (byte_len <= 0) return 1; @@ -119,8 +136,9 @@ rawread (int drive, int sector, int byte_offset, int byte_len, int addr) bufaddr = BUFFERADDR + byte_offset; } - if (bios_err = biosdisk (BIOSDISK_READ, drive, buf_geom, - read_start, read_len, BUFFERSEG)) + bios_err = biosdisk (BIOSDISK_READ, drive, buf_geom, + read_start, read_len, BUFFERSEG); + if (bios_err) { buf_track = -1; @@ -161,9 +179,9 @@ rawread (int drive, int sector, int byte_offset, int byte_len, int addr) if (size > ((num_sect * SECTOR_SIZE) - byte_offset)) size = (num_sect * SECTOR_SIZE) - byte_offset; - bcopy ((char *) bufaddr, (char *) addr, size); + bcopy ((char *) bufaddr, buf, size); - addr += size; + buf += size; byte_len -= size; sector += num_sect; slen -= num_sect; @@ -175,7 +193,7 @@ rawread (int drive, int sector, int byte_offset, int byte_len, int addr) int -devread (int sector, int byte_offset, int byte_len, int addr) +devread (int sector, int byte_offset, int byte_len, char *buf) { /* * Check partition boundaries @@ -202,7 +220,7 @@ devread (int sector, int byte_offset, int byte_len, int addr) #endif /* !STAGE1_5 && DEBUG */ /* - * Call "rawread", which is very similar, but: + * Call RAWREAD, which is very similar, but: * * -- It takes an extra parameter, the drive number. * -- It requires that "sector" is relative to the beginning @@ -211,11 +229,12 @@ devread (int sector, int byte_offset, int byte_len, int addr) * sector. */ return rawread (current_drive, part_start + sector, byte_offset, - byte_len, addr); + byte_len, buf); } -int +#if !defined(STAGE1_5) || !defined(NO_BLOCK_FILES) +static int sane_partition (void) { if (!(current_partition & 0xFF000000uL) @@ -230,8 +249,10 @@ sane_partition (void) errnum = ERR_DEV_VALUES; return 0; } +#endif /* !defined(STAGE1_5) || !defined(NO_BLOCK_FILES) */ +#ifndef STAGE1_5 static void attempt_mount (void) { @@ -241,6 +262,7 @@ attempt_mount (void) if (fsys_type == NUM_FSYS && errnum == ERR_NONE) errnum = ERR_FSYS_MOUNT; } +#endif /* STAGE1_5 */ #ifndef STAGE1_5 @@ -257,7 +279,7 @@ make_saved_active (void) return 0; } - if (!rawread (saved_drive, 0, 0, SECTOR_SIZE, SCRATCHADDR)) + if (!rawread (saved_drive, 0, 0, SECTOR_SIZE, (char *) SCRATCHADDR)) return 0; if (PC_SLICE_FLAG (SCRATCHADDR, part) != PC_SLICE_FLAG_BOOTABLE) @@ -297,6 +319,7 @@ check_and_print_mount (void) #endif /* STAGE1_5 */ +#if !defined(STAGE1_5) || !defined(NO_BLOCK_FILES) static int check_BSD_parts (int flags) { @@ -310,7 +333,7 @@ check_BSD_parts (int flags) } if (!rawread (current_drive, part_start + BSD_LABEL_SECTOR, - 0, SECTOR_SIZE, (int) label_buf)) + 0, SECTOR_SIZE, label_buf)) return 0; if (BSD_LABEL_CHECK_MAG (label_buf)) @@ -319,7 +342,7 @@ check_BSD_parts (int flags) { if (BSD_PART_TYPE (label_buf, part_no)) { - /* XXX should do BAD144 sector remapping setup here */ + /* FIXME: should do BAD144 sector remapping setup here */ current_slice = ((BSD_PART_TYPE (label_buf, part_no) << 8) | PC_SLICE_TYPE_BSD); @@ -360,6 +383,7 @@ check_BSD_parts (int flags) errnum = ERR_BAD_PART_TABLE; return 0; } +#endif /* !defined(STAGE1_5) || !defined(NO_BLOCK_FILES) */ #if !defined(STAGE1_5) || !defined(NO_BLOCK_FILES) @@ -369,14 +393,14 @@ static int real_open_partition (int flags) { char mbr_buf[SECTOR_SIZE]; - int i, part_no, slice_no, ext = 0, part_offset = 0; + int i, part_no, slice_no, ext = 0; /* * The "rawread" is probably unnecessary here, but it is good to * know it works. */ if (!sane_partition () - || !rawread (current_drive, 0, 0, SECTOR_SIZE, (int) mbr_buf)) + || !rawread (current_drive, 0, 0, SECTOR_SIZE, mbr_buf)) return 0; bsd_evil_hack = 0; @@ -404,7 +428,7 @@ real_open_partition (int flags) while (slice_no < 255 && ext >= 0 && (part_no == 0xFF || slice_no <= part_no) && rawread (current_drive, part_offset, - 0, SECTOR_SIZE, (int) mbr_buf)) + 0, SECTOR_SIZE, mbr_buf)) { /* * If the table isn't valid, we can't continue @@ -512,7 +536,7 @@ real_open_partition (int flags) if (current_partition == 0xFFFFFF || current_partition == 0xFF00FF) { - current_partition == 0xFFFFFF; + current_partition = 0xFFFFFF; ext = -2; } } @@ -648,7 +672,7 @@ set_device (char *device) /* A Mach-style absolute partition name. */ ch = *device; - if (*device != 'f' && *device != 'h' || + if ((*device != 'f' && *device != 'h') || (device += 2, (*(device - 1) != 'd'))) errnum = ERR_DEV_FORMAT; else @@ -768,7 +792,7 @@ set_bootdev (int hdbias) else if ((saved_partition >> 16) == 0xFF) i = 0; - /* XXX extremely evil hack!!! */ + /* FIXME: extremely evil hack!!! */ j = 2; if (saved_drive & 0x80) j = bsd_evil_hack; @@ -927,7 +951,7 @@ print_completions (char *filename) */ int -open (char *filename) +grub_open (char *filename) { #ifndef NO_DECOMPRESSION compressed_file = 0; @@ -946,7 +970,7 @@ open (char *filename) block_file = 0; #endif /* NO_BLOCK_FILES */ - /* XXX to account for partial filesystem implementations! */ + /* This accounts for partial filesystem implementations. */ fsmax = MAXINT; if (*filename != '/') @@ -1039,7 +1063,7 @@ open (char *filename) int -read (int addr, int len) +grub_read (char *buf, int len) { /* Make sure "filepos" is a sane value */ if ((filepos < 0) | (filepos > filemax)) @@ -1060,7 +1084,7 @@ read (int addr, int len) #ifndef NO_DECOMPRESSION if (compressed_file) - return gunzip_read (addr, len); + return gunzip_read (buf, len); #endif /* NO_DECOMPRESSION */ #ifndef NO_BLOCK_FILES @@ -1109,7 +1133,7 @@ read (int addr, int len) /* read current block and put it in the right place in memory */ devread (BLK_BLKSTART (BLK_CUR_BLKLIST) + BLK_CUR_BLKNUM, - off, size, addr); + off, size, buf); #ifndef STAGE1_5 debug_fs_func = NULL; @@ -1118,7 +1142,7 @@ read (int addr, int len) len -= size; filepos += size; ret += size; - addr += size; + buf += size; } if (errnum) @@ -1134,7 +1158,7 @@ read (int addr, int len) return 0; } - return (*(fsys_table[fsys_type].read_func)) (addr, len); + return (*(fsys_table[fsys_type].read_func)) (buf, len); } diff --git a/shared_src/filesys.h b/shared_src/filesys.h index 8f0c5812b..a6489f852 100644 --- a/shared_src/filesys.h +++ b/shared_src/filesys.h @@ -1,7 +1,8 @@ - +/* filesys.h - abstract filesystem interface */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1996 Erich Boleyn + * Copyright (C) 1996 Erich Boleyn + * Copyright (C) 1999 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,7 +38,7 @@ #ifdef FSYS_FFS #define FSYS_FFS_NUM 1 int ffs_mount (void); -int ffs_read (int addr, int len); +int ffs_read (char *buf, int len); int ffs_dir (char *dirname); #else #define FSYS_FFS_NUM 0 @@ -58,7 +59,7 @@ int fat_dir (char *dirname); #ifdef FSYS_EXT2FS #define FSYS_EXT2FS_NUM 1 int ext2fs_mount (void); -int ext2fs_read (int addr, int len); +int ext2fs_read (char *buf, int len); int ext2fs_dir (char *dirname); #else #define FSYS_EXT2FS_NUM 0 @@ -86,44 +87,15 @@ struct fsys_entry { char *name; int (*mount_func) (void); - int (*read_func) (int addr, int len); + int (*read_func) (char *buf, int len); int (*dir_func) (char *dirname); }; #ifdef STAGE1_5 # define print_possibilities 0 -#endif - -#ifndef _DISK_IO_C - -# ifndef STAGE1_5 +#else extern int print_possibilities; -# endif +#endif extern int fsmax; extern struct fsys_entry fsys_table[NUM_FSYS + 1]; - -#else /* _DISK_IO_C */ - -# ifndef STAGE1_5 -int print_possibilities; -# endif - -int fsmax; -struct fsys_entry fsys_table[NUM_FSYS + 1] = -{ -# ifdef FSYS_FAT - {"fat", fat_mount, 0, fat_dir}, -# endif -# ifdef FSYS_EXT2FS - {"ext2fs", ext2fs_mount, ext2fs_read, ext2fs_dir}, -# endif - /* XX FFS should come last as it's superblock is commonly crossing tracks - on floppies from track 1 to 2, while others only use 1. */ -# ifdef FSYS_FFS - {"ffs", ffs_mount, ffs_read, ffs_dir}, -# endif - {0, 0, 0, 0} -}; - -#endif /* _DISK_IO_C */ diff --git a/shared_src/fsys_ext2fs.c b/shared_src/fsys_ext2fs.c index 05c27202c..b0828e24d 100644 --- a/shared_src/fsys_ext2fs.c +++ b/shared_src/fsys_ext2fs.c @@ -238,7 +238,7 @@ struct ext2_dir_entry * ffz = Find First Zero in word. Undefined if no zero exists, * so code should check against ~0UL first.. */ -__inline__ unsigned long +static __inline__ unsigned long ffz (unsigned long word) { __asm__ ("bsfl %1,%0" @@ -257,33 +257,31 @@ ext2fs_mount (void) && (current_slice != PC_SLICE_TYPE_EXT2FS) && (current_slice != (PC_SLICE_TYPE_BSD | (FS_OTHER << 8)))) || part_length < (SBLOCK + (sizeof (struct ext2_super_block) / DEV_BSIZE)) - || !devread (SBLOCK, 0, sizeof (struct ext2_super_block), (int) SUPERBLOCK) + || !devread (SBLOCK, 0, sizeof (struct ext2_super_block), + (char *) SUPERBLOCK) || SUPERBLOCK->s_magic != EXT2_SUPER_MAGIC) retval = 0; return retval; } -/* not part of the interface - takes a file system block number and reads it into area pointed - to by buffer */ -int +/* Takes a file system block number and reads it into BUFFER. */ +static int ext2_rdfsb (int fsblock, int buffer) { #ifdef E2DEBUG printf ("fsblock %d buffer %d\n", fsblock, buffer); #endif /* E2DEBUG */ return devread (fsblock * (EXT2_BLOCK_SIZE (SUPERBLOCK) / DEV_BSIZE), 0, - EXT2_BLOCK_SIZE (SUPERBLOCK), (int) buffer); + EXT2_BLOCK_SIZE (SUPERBLOCK), (char *) buffer); } /* from ext2/inode.c:ext2_bmap() */ -/* not part of interface - maps "logical block" (the file offset div blocksize) into - "physical blocks" (the location in the file system) via an inode */ -int +/* Maps LOGICAL_BLOCK (the file offset divided by the blocksize) into + a physical block (the location in the file system) via an inode. */ +static int ext2fs_block_map (int logical_block) { @@ -387,7 +385,7 @@ ext2fs_block_map (int logical_block) /* preconditions: all preconds of ext2fs_block_map */ int -ext2fs_read (int addr, int len) +ext2fs_read (char *buf, int len) { int logical_block; int offset; @@ -436,13 +434,13 @@ ext2fs_read (int addr, int len) #endif /* STAGE1_5 */ devread (map * (EXT2_BLOCK_SIZE (SUPERBLOCK) / DEV_BSIZE), - offset, size, addr); + offset, size, buf); #ifndef STAGE1_5 debug_fs_func = NULL; #endif /* STAGE1_5 */ - addr += size; + buf += size; len -= size; filepos += size; ret += size; @@ -592,7 +590,7 @@ ext2fs_dir (char *dirname) /* If we've got a symbolic link, then chase it. */ if (S_ISLNK (INODE->i_mode)) { - int len, remaining; + int len; if (++link_count > MAX_LINK_COUNT) { errnum = ERR_SYMLINK_LOOP; @@ -624,7 +622,7 @@ ext2fs_dir (char *dirname) if (INODE->i_blocks) { /* Read the necessary blocks, and reset the file pointer. */ - len = read ((int) linkbuf, filemax); + len = grub_read (linkbuf, filemax); filepos = 0; if (!len) return 0; diff --git a/shared_src/fsys_fat.c b/shared_src/fsys_fat.c index 1a72329ec..4567bb241 100644 --- a/shared_src/fsys_fat.c +++ b/shared_src/fsys_fat.c @@ -43,7 +43,7 @@ fat_mount (void) && (current_slice != PC_SLICE_TYPE_FAT16_LT32M) && (current_slice != PC_SLICE_TYPE_FAT16_GT32M) && (current_slice != (PC_SLICE_TYPE_BSD | (FS_MSDOS << 8)))) - || !devread (0, 0, SECTOR_SIZE, BPB) + || !devread (0, 0, SECTOR_SIZE, (char *) BPB) || FAT_BPB_BYTES_PER_SECTOR (BPB) != SECTOR_SIZE || FAT_BPB_SECT_PER_CLUST (BPB) < 1 || FAT_BPB_SECT_PER_CLUST (BPB) > 64 || (FAT_BPB_SECT_PER_CLUST (BPB) & (FAT_BPB_SECT_PER_CLUST (BPB) - 1)) @@ -112,7 +112,7 @@ fat_create_blocklist (int first_fat_entry) mapblock = ((new_mapblock < 6) ? 0 : ((new_mapblock - 6) & ~0x1FF)); if (!devread ((mapblock >> 9) + FAT_BPB_FAT_START (BPB), - 0, SECTOR_SIZE * 4, FAT_BUF)) + 0, SECTOR_SIZE * 4, (char *) FAT_BUF)) return 0; } @@ -196,7 +196,7 @@ loop: do { - if (read ((int) dir_buf, FAT_DIRENTRY_LENGTH) != FAT_DIRENTRY_LENGTH) + if (grub_read (dir_buf, FAT_DIRENTRY_LENGTH) != FAT_DIRENTRY_LENGTH) { if (!errnum) { diff --git a/shared_src/fsys_ffs.c b/shared_src/fsys_ffs.c index 1e7d1f4f3..5bcca5cb6 100644 --- a/shared_src/fsys_ffs.c +++ b/shared_src/fsys_ffs.c @@ -82,7 +82,7 @@ ffs_mount (void) if ((((current_drive & 0x80) || (current_slice != 0)) && current_slice != (PC_SLICE_TYPE_BSD | (FS_BSDFFS << 8))) || part_length < (SBLOCK + (SBSIZE / DEV_BSIZE)) - || !devread (SBLOCK, 0, SBSIZE, (int) SUPERBLOCK) + || !devread (SBLOCK, 0, SBSIZE, (char *) SUPERBLOCK) || SUPERBLOCK->fs_magic != FS_MAGIC) retval = 0; @@ -101,7 +101,7 @@ block_map (int file_block) if ((bnum = fsbtodb (SUPERBLOCK, INODE->i_ib[0])) != mapblock) { - if (!devread (bnum, 0, SUPERBLOCK->fs_bsize, MAPBUF)) + if (!devread (bnum, 0, SUPERBLOCK->fs_bsize, (char *)MAPBUF)) { mapblock = -1; errnum = ERR_FSYS_CORRUPT; @@ -116,7 +116,7 @@ block_map (int file_block) int -ffs_read (int addr, int len) +ffs_read (char *buf, int len) { int logno, off, size, map, ret = 0; @@ -138,13 +138,13 @@ ffs_read (int addr, int len) debug_fs_func = debug_fs; #endif /* STAGE1_5 */ - devread (fsbtodb (SUPERBLOCK, map), off, size, addr); + devread (fsbtodb (SUPERBLOCK, map), off, size, buf); #ifndef STAGE1_5 debug_fs_func = NULL; #endif /* STAGE1_5 */ - addr += size; + buf += size; len -= size; filepos += size; ret += size; @@ -170,7 +170,7 @@ loop: /* load current inode (defaults to the root inode) */ if (!devread (fsbtodb (SUPERBLOCK, itod (SUPERBLOCK, ino)), - 0, SUPERBLOCK->fs_bsize, FSYS_BUF)) + 0, SUPERBLOCK->fs_bsize, (char *) FSYS_BUF)) return 0; /* XXX what return value? */ bcopy ((void *) &(((struct dinode *) FSYS_BUF)[ino % (SUPERBLOCK->fs_inopb)]), @@ -232,7 +232,8 @@ loop: if ((map = block_map (block)) < 0 || !devread (fsbtodb (SUPERBLOCK, map), 0, - blksize (SUPERBLOCK, INODE, block), FSYS_BUF)) + blksize (SUPERBLOCK, INODE, block), + (char *) FSYS_BUF)) { errnum = ERR_FSYS_CORRUPT; *rest = ch; diff --git a/shared_src/gunzip.c b/shared_src/gunzip.c index 84c3cbb96..26c0f01eb 100644 --- a/shared_src/gunzip.c +++ b/shared_src/gunzip.c @@ -1,6 +1,7 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1996 Erich Boleyn + * Copyright (C) 1996 Erich Boleyn + * Copyright (C) 1999 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,7 +33,6 @@ /* You can do whatever you like with this source file, though I would prefer that if you modify it and redistribute it that you include comments to that effect with your name and the date. Thank you. - [The history has been moved to the file ChangeLog.] */ /* @@ -216,7 +216,7 @@ bad_field (int len) break; } } - while ((not_retval = read ((int) &ch, 1)) == 1); + while ((not_retval = grub_read (&ch, 1)) == 1); return (!not_retval); } @@ -276,7 +276,7 @@ gunzip_test_header (void) * (other than a real error with the disk) then we don't think it * is a compressed file, and simply mark it as such. */ - if (no_decompression || read ((int) buf, 10) != 10 + if (no_decompression || grub_read (buf, 10) != 10 || ((*((unsigned short *) buf) != GZIP_HDR_LE) & (*((unsigned short *) buf) != OLD_GZIP_HDR_LE))) { @@ -291,11 +291,12 @@ gunzip_test_header (void) */ if (buf[2] != DEFLATED || (buf[3] & UNSUPP_FLAGS) || ((buf[3] & EXTRA_FIELD) - && (read ((int) buf, 2) != 2 || bad_field (*((unsigned short *) buf)))) + && (grub_read (buf, 2) != 2 || + bad_field (*((unsigned short *) buf)))) || ((buf[3] & ORIG_NAME) && bad_field (-1)) || ((buf[3] & COMMENT) && bad_field (-1)) || ((gzip_data_offset = filepos), (filepos = filemax - 8), - (read ((int) buf, 8) != 8))) + (grub_read (buf, 8) != 8))) { if (!errnum) errnum = ERR_BAD_GZIP_HEADER; @@ -481,7 +482,7 @@ get_byte (void) if (filepos == gzip_data_offset || bufloc == INBUFSIZ) { bufloc = 0; - read ((int) inbuf, INBUFSIZ); + grub_read (inbuf, INBUFSIZ); } return inbuf[bufloc++]; @@ -1166,9 +1167,8 @@ initialize_tables (void) int -gunzip_read (int addr, int len) +gunzip_read (char *buf, int len) { - int size; /* last block flag */ int ret = 0; compressed_file = 0; @@ -1200,9 +1200,9 @@ gunzip_read (int addr, int len) if (size > len) size = len; - bcopy (srcaddr, (char *) addr, size); + bcopy (srcaddr, buf, size); - addr += size; + buf += size; len -= size; gzip_filepos += size; ret += size; diff --git a/shared_src/shared.h b/shared_src/shared.h index b514080a3..8c6a607ec 100644 --- a/shared_src/shared.h +++ b/shared_src/shared.h @@ -1,7 +1,8 @@ - +/* shared.h - definitions used in all GRUB-specific code */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1996 Erich Boleyn + * Copyright (C) 1996 Erich Boleyn + * Copyright (C) 1999 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -176,109 +177,18 @@ extern char *grub_scratch_mem; # define KEY_DOWN 0x5000 # define KEY_IC 0x5200 /* insert char */ # define KEY_DC 0x5300 /* delete char */ +# define KEY_BACKSPACE 0x0008 # define KEY_HOME 0x4700 # define KEY_END 0x4F00 # define KEY_NPAGE 0x4900 # define KEY_PPAGE 0x5100 +# define A_NORMAL 0x7 +# define A_REVERSE 0x70 #else # include #endif -/* Remap some names so that we don't conflict with libc. */ -#define bcopy grub_bcopy -#define bzero grub_bzero -#define isspace grub_isspace -#define open grub_open -#define printf grub_printf -#undef putchar -#define putchar grub_putchar -#define read grub_read -#define strncat grub_strncat -#define strstr grub_strstr -#define tolower grub_tolower - - -#ifndef ASM_FILE - - -/* - * Below this should be ONLY defines and other constructs for C code. - */ - - -static inline unsigned char -inb (unsigned short port) -{ - unsigned char data; - - __asm __volatile ("inb %1,%0":"=a" (data):"d" (port)); - return data; -} - -static inline void -outb (unsigned short port, unsigned char val) -{ - __asm __volatile ("outb %0,%1"::"a" (val), "d" (port)); -} - - -/* multiboot stuff */ - -#include "mb_header.h" -#include "mb_info.h" - -/* this function must be called somewhere... */ -void -cmain (void) -__attribute__ ((noreturn)); - -#undef NULL -#define NULL ((void *) 0) - - -/* - * From "asm.S" - */ - - extern unsigned long install_partition; - extern unsigned long boot_drive; - extern char version_string[]; - extern char config_file[]; - -void stop (void) __attribute__ ((noreturn)); - -/* calls for direct boot-loader chaining */ - void chain_stage1 (int segment, int offset, int part_table_addr) -__attribute__ ((noreturn)); - void chain_stage2 (int segment, int offset) __attribute__ ((noreturn)); - -/* do some funky stuff, then boot linux */ - void linux_boot (void) __attribute__ ((noreturn)); - -/* do some funky stuff, then boot bzImage linux */ - void big_linux_boot (void) __attribute__ ((noreturn)); - -/* booting a multiboot executable */ - void multi_boot (int start, int mbi) __attribute__ ((noreturn)); - -/* sets it to linear or wired A20 operation */ - void gateA20 (int linear); - -/* memory probe routines */ - int get_memsize (int type); - int get_eisamemsize (void); - int get_mmap_entry (int buf, int cont); - -/* low-level timing info */ - int getrtsecs (void); - -/* low-level character I/O */ - void cls (void); - int getxy (void); /* returns packed values, LSB+1 is x, LSB is y */ - void gotoxy (int x, int y); - -/* displays an ASCII character. IBM displays will translate some - characters to special graphical ones */ +/* Special graphics characters for IBM displays. */ #define DISP_UL 218 #define DISP_UR 191 #define DISP_LL 192 @@ -289,228 +199,301 @@ __attribute__ ((noreturn)); #define DISP_RIGHT 0x1a #define DISP_UP 0x18 #define DISP_DOWN 0x19 - void putchar (int c); -/* returns packed BIOS/ASCII code */ - int getkey (void); -/* returns 0 if non-ASCII character */ -#undef getc -#define getc() ASCII_CHAR(getkey()) - -/* like 'getkey', but doesn't wait, returns -1 if nothing available */ - int checkkey (void); - -/* sets text mode character attribute at the cursor position */ -#define ATTRIB_NORMAL 0x7 -#define ATTRIB_INVERSE 0x70 - void set_attrib (int attr); - -/* low-level disk I/O */ - int get_diskinfo (int drive); - int biosdisk (int read, int drive, int geometry, - int sector, int nsec, int segment); - void stop_floppy (void); +/* Remap some libc-API-compatible function names so that we can use + them alongside their libc counterparts. */ +#define bcopy grub_bcopy +#define bzero grub_bzero +#define isspace grub_isspace +#define printf grub_printf +#undef putchar +#define putchar grub_putchar +#define strncat grub_strncat +#define strstr grub_strstr +#define tolower grub_tolower +#ifndef ASM_FILE /* - * From "cmdline.c" + * Below this should be ONLY defines and other constructs for C code. */ -#ifndef _CMDLINE_C +/* multiboot stuff */ - extern int fallback; - extern char *password; - extern char commands[]; +#include "mb_header.h" +#include "mb_info.h" -#endif /* _CMDLINE_C */ +/* Memory map address range descriptor used by GET_MMAP_ENTRY. */ +struct mmar_desc +{ + unsigned long desc_len; /* Size of this descriptor. */ + unsigned long long addr; /* Base address. */ + unsigned long long length; /* Length in bytes. */ + unsigned long type; /* Type of address range. */ +}; - char *skip_to (int after_equal, char *cmdline); - void init_cmdline (void); - int enter_cmdline (char *script, char *heap); +#undef NULL +#define NULL ((void *) 0) +/* Error codes (descriptions are in common.c) */ +typedef enum +{ + ERR_NONE = 0, + ERR_BAD_FILENAME, + ERR_BAD_FILETYPE, + ERR_BAD_GZIP_DATA, + ERR_BAD_GZIP_HEADER, + ERR_BAD_PART_TABLE, + ERR_BAD_VERSION, + ERR_BELOW_1MB, + ERR_BOOT_COMMAND, + ERR_BOOT_FAILURE, + ERR_BOOT_FEATURES, + ERR_DEV_FORMAT, + ERR_DEV_VALUES, + ERR_EXEC_FORMAT, + ERR_FILELENGTH, + ERR_FILE_NOT_FOUND, + ERR_FSYS_CORRUPT, + ERR_FSYS_MOUNT, + ERR_GEOM, + ERR_NEED_LX_KERNEL, + ERR_NEED_MB_KERNEL, + ERR_NO_DISK, + ERR_NO_PART, + ERR_NUMBER_PARSING, + ERR_OUTSIDE_PART, + ERR_READ, + ERR_SYMLINK_LOOP, + ERR_UNRECOGNIZED, + ERR_WONT_FIT, + ERR_WRITE, -/* - * From "char_io.c" - */ + MAX_ERR_NUM +} grub_error_t; -#ifndef _CHAR_IO_C +extern unsigned long install_partition; +extern unsigned long boot_drive; +extern char version_string[]; +extern char config_file[]; - int special_attribute; +#ifndef STAGE1_5 +/* GUI interface variables. */ +extern int fallback; +extern char *password; +extern char commands[]; +#endif -#endif /* _CHAR_IO_C */ - - enum grub_error_t - { - ERR_NONE = 0, - ERR_BAD_FILENAME, - ERR_BAD_FILETYPE, - ERR_BAD_GZIP_DATA, - ERR_BAD_GZIP_HEADER, - ERR_BAD_PART_TABLE, - ERR_BAD_VERSION, - ERR_BELOW_1MB, - ERR_BOOT_COMMAND, - ERR_BOOT_FAILURE, - ERR_BOOT_FEATURES, - ERR_DEV_FORMAT, - ERR_DEV_VALUES, - ERR_EXEC_FORMAT, - ERR_FILELENGTH, - ERR_FILE_NOT_FOUND, - ERR_FSYS_CORRUPT, - ERR_FSYS_MOUNT, - ERR_GEOM, - ERR_NEED_LX_KERNEL, - ERR_NEED_MB_KERNEL, - ERR_NO_DISK, - ERR_NO_PART, - ERR_NUMBER_PARSING, - ERR_OUTSIDE_PART, - ERR_READ, - ERR_SYMLINK_LOOP, - ERR_UNRECOGNIZED, - ERR_WONT_FIT, - ERR_WRITE, - - MAX_ERR_NUM - }; - - void init_page (void); - void print_error (void); - char *convert_to_ascii (char *buf, int c,...); - void grub_printf (char *format,...); - int get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen); - int grub_tolower (int c); - int grub_isspace (int c); - int grub_strncat (char *s1, char *s2, int n); - int substring (char *s1, char *s2); - char *grub_strstr (char *s1, char *s2); - int bcopy (char *from, char *to, int len); - int bzero (char *start, int len); - int get_based_digit (int c, int base); - int safe_parse_maxint (char **str_ptr, int *myint_ptr); - int memcheck (int start, int len); - - -/* - * From "gunzip.c" - */ - -#ifndef _GUNZIP_C - - extern int no_decompression; - extern int compressed_file; - -#endif /* _GUNZIP_C */ - - int gunzip_test_header (void); - int gunzip_read (int addr, int len); - - -/* - * From "disk_io.c" - */ - -#ifndef _DISK_IO_C +#ifndef NO_DECOMPRESSION +extern int no_decompression; +extern int compressed_file; +#endif #ifndef STAGE1_5 /* instrumentation variables */ - extern void (*debug_fs) (int); - extern void (*debug_fs_func) (int); +extern void (*debug_fs) (int); +extern void (*debug_fs_func) (int); #endif /* STAGE1_5 */ - extern unsigned long current_drive; - extern unsigned long current_partition; +extern unsigned long current_drive; +extern unsigned long current_partition; - extern int fsys_type; +extern int fsys_type; #ifndef NO_BLOCK_FILES - extern int block_file; +extern int block_file; #endif /* NO_BLOCK_FILES */ - extern long part_start; - extern long part_length; +extern long part_start; +extern long part_length; - extern int current_slice; +extern int current_slice; - extern int buf_drive; - extern int buf_track; - extern int buf_geom; +extern int buf_drive; +extern int buf_track; +extern int buf_geom; /* these are the current file position and maximum file position */ - extern int filepos; - extern int filemax; - -#endif /* _DISK_IO_C */ - - int rawread (int drive, int sector, int byte_offset, int byte_len, int addr); - int devread (int sector, int byte_offset, int byte_len, int addr); - - char *set_device (char *device); /* this gets a device from the string and - places it into the global parameters */ - int open_device (void); - int make_saved_active (void); /* sets the active partition to the that - represented by the "saved_" parameters */ - - int grub_open (char *filename); - int grub_read (int addr, int len); /* if "length" is -1, read all the - remaining data in the file */ - int dir (char *dirname); /* list directory, printing all completions */ - - int set_bootdev (int hdbias); - void print_fsys_type (void); /* this prints stats on the currently - mounted filesystem */ - void print_completions (char *filename); /* this prints device and filename - completions */ - void copy_current_part_entry (int addr); /* copies the current partition data - to the desired address */ - - -/* - * From "boot.c" - */ - -/* for the entry address */ - typedef void - (*entry_func) (int, int, int, int, int, int) __attribute__ ((noreturn)); - -#ifndef _BOOT_C - - extern char *cur_cmdline; - extern entry_func entry_addr; - -#endif /* _BOOT_C */ - - void bsd_boot (int type, int bootdev) __attribute__ ((noreturn)); - int load_image (void); - int load_module (void); - - -/* - * From "common.c" - */ - - -#ifndef _COMMON_C +extern int filepos; +extern int filemax; /* * Common BIOS/boot data. */ - extern struct multiboot_info mbi; - extern unsigned long saved_drive; - extern unsigned long saved_partition; - extern unsigned long saved_mem_upper; +extern struct multiboot_info mbi; +extern unsigned long saved_drive; +extern unsigned long saved_partition; +extern unsigned long saved_mem_upper; /* * Error variables. */ - extern int errnum; - extern char *err_list[]; +extern grub_error_t errnum; +extern char *err_list[]; -#endif /* _COMMON_C */ +/* Simplify declaration of entry_addr. */ +typedef void (*entry_func) (int, int, int, int, int, int) + __attribute__ ((noreturn)); - void init_bios_info (void) __attribute__ ((noreturn)); +/* Maximum command line size. Before you blindly increase this value, + see the comment in char_io.c (get_cmdline). */ +#define MAX_CMDLINE 1600 +#define NEW_HEAPSIZE 1500 +extern char *cur_cmdline; +extern entry_func entry_addr; + +/* Enter the stage1.5/stage2 C code after the stack is set up. */ +void cmain (void) __attribute__ ((noreturn)); + +/* Halt the processor (called after an unrecoverable error). */ +void stop (void) __attribute__ ((noreturn)); + +/* calls for direct boot-loader chaining */ +void chain_stage1 (int segment, int offset, int part_table_addr) + __attribute__ ((noreturn)); +void chain_stage2 (int segment, int offset) __attribute__ ((noreturn)); + +/* do some funky stuff, then boot linux */ +void linux_boot (void) __attribute__ ((noreturn)); + +/* do some funky stuff, then boot bzImage linux */ +void big_linux_boot (void) __attribute__ ((noreturn)); + +/* booting a multiboot executable */ +void multi_boot (int start, int mbi) __attribute__ ((noreturn)); + +/* If LINEAR is nonzero, then set the Intel processor to linear mode. + Otherwise, bit 20 of all memory accesses is always forced to zero, + causing a wraparound effect for bugwards compatibility with the + 8086 CPU. */ +void gateA20 (int linear); + +/* memory probe routines */ +int get_memsize (int type); +int get_eisamemsize (void); + +/* Fetch the next entry in the memory map and return the continuation + value. DESC is a pointer to the descriptor buffer, and CONT is the + previous continuation value (0 to get the first entry in the + map). */ +int get_mmap_entry (struct mmar_desc *desc, int cont); + +/* Return the data area immediately following our code. */ +int get_code_end (void); + +/* low-level timing info */ +int getrtsecs (void); + +/* Clear the screen. */ +void cls (void); + +/* Get the current cursor position (where 0,0 is the top left hand + corner of the screen). Returns packed values, (RET >> 8) is x, + (RET & 0xff) is y. */ +int getxy (void); + +/* Set the cursor position. */ +void gotoxy (int x, int y); + +/* Displays an ASCII character. IBM displays will translate some + characters to special graphical ones (see the DISP_* constants). */ +void putchar (int c); + +/* Wait for a keypress, and return its packed BIOS/ASCII key code. + Use ASCII_CHAR(ret) to extract the ASCII code. */ +int getkey (void); + +/* returns 0 if non-ASCII character */ +#undef getc +#define getc() ASCII_CHAR (getkey ()) + +/* Like GETKEY, but doesn't block, and returns -1 if no keystroke is + available. */ +int checkkey (void); + +/* Sets text mode character attribute at the cursor position. See A_* + constants defined above. */ +void set_attrib (int attr); + +/* Low-level disk I/O */ +int get_diskinfo (int drive); +int biosdisk (int read, int drive, int geometry, + int sector, int nsec, int segment); +void stop_floppy (void); + +/* Command-line interface functions. */ +#ifndef STAGE1_5 +char *skip_to (int after_equal, char *cmdline); +void init_cmdline (void); +int enter_cmdline (char *script, char *heap); +#endif + +/* C library replacement functions with identical semantics. */ +void grub_printf (char *format,...); +int grub_tolower (int c); +int grub_isspace (int c); +int grub_strncat (char *s1, char *s2, int n); +int grub_bcopy (char *from, char *to, int len); +int grub_bzero (char *start, int len); +char *grub_strstr (char *s1, char *s2); + +/* misc */ +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 substring (char *s1, char *s2); +int get_based_digit (int c, int base); +int safe_parse_maxint (char **str_ptr, int *myint_ptr); +int memcheck (int start, int len); + +#ifndef NO_DECOMPRESSION +/* Compression support. */ +int gunzip_test_header (void); +int gunzip_read (char *buf, int len); +#endif /* NO_DECOMPRESSION */ + +int rawread (int drive, int sector, int byte_offset, int byte_len, char *buf); +int devread (int sector, int byte_offset, int byte_len, char *buf); + +/* Parse a device string and initialize the global parameters. */ +char *set_device (char *device); +int open_device (void); +int open_partition (void); + +/* Sets device to the one represented by the SAVED_* parameters. */ +int make_saved_active (void); + +/* Open a file or directory on the active device, using GRUB's + internal filesystem support. */ +int grub_open (char *filename); + +/* Read LEN bytes into BUF from the file that was opened with + GRUB_OPEN. If LEN is -1, read all the remaining data in the file */ +int grub_read (char *buf, int len); + +/* List the contents of the directory that was opened with GRUB_OPEN, + printing all completions. */ +int dir (char *dirname); + +int set_bootdev (int hdbias); + +/* Display statistics on the current active device. */ +void print_fsys_type (void); + +/* Display device and filename completions. */ +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) __attribute__ ((noreturn)); +int load_image (void); +int load_module (void); +int load_initrd (void); + +void init_bios_info (void) __attribute__ ((noreturn)); #endif /* ASM_FILE */ diff --git a/shared_src/smp-imps.c b/shared_src/smp-imps.c index a6e4151bf..8ef3fb894 100644 --- a/shared_src/smp-imps.c +++ b/shared_src/smp-imps.c @@ -227,8 +227,7 @@ get_checksum (unsigned start, int length) static int boot_cpu (imps_processor * proc) { - int apicid = proc->apic_id; - unsigned bootaddr, send_status, accept_status, cfg; + unsigned bootaddr, accept_status; unsigned bios_reset_vector = PHYS_TO_VIRTUAL (BIOS_RESET_VECTOR); /* %%%%% ESB */ diff --git a/shared_src/stage1_5.c b/shared_src/stage1_5.c index 8f9aaf7c9..01b541282 100644 --- a/shared_src/stage1_5.c +++ b/shared_src/stage1_5.c @@ -29,7 +29,7 @@ cmain (void) * Here load the true second-stage boot-loader. */ - if (open (config_file) && read (0x8000, -1)) + if (grub_open (config_file) && grub_read ((char *) 0x8000, -1)) chain_stage2 (0, 0x8000); /* diff --git a/shared_src/stage2.c b/shared_src/stage2.c index aad07a117..cd2798565 100644 --- a/shared_src/stage2.c +++ b/shared_src/stage2.c @@ -19,7 +19,7 @@ #include "../shared_src/shared.h" -char * +static char * get_entry(char *list, int num, int nested) { int i; @@ -37,7 +37,7 @@ get_entry(char *list, int num, int nested) } -void +static void print_entries(int y, int size, int first, char *menu_entries) { int i; @@ -84,7 +84,7 @@ print_entries(int y, int size, int first, char *menu_entries) } -void +static void print_border(int y, int size) { int i; @@ -118,15 +118,15 @@ print_border(int y, int size) putchar(DISP_LR); } -void +static void set_line(int y, int attr) { int x; for (x = 2; x < 75; x++) { - gotoxy(x, y); - set_attrib(attr); + gotoxy (x, y); + set_attrib (attr); } } @@ -134,7 +134,7 @@ set_line(int y, int attr) static int grub_timeout; -void +static void run_menu(char *menu_entries, char *config_entries, int num_entries, char *heap, int entryno) { @@ -179,7 +179,7 @@ restart: print_entries(3, 12, first_entry, menu_entries); /* invert initial line */ - set_line(4+entryno, 0x70); + set_line (4 + entryno, A_REVERSE); /* XX using RT clock now, need to initialize value */ while ((time1 = getrtsecs()) == 0xFF); @@ -222,15 +222,15 @@ restart: { if (entryno > 0) { - set_line(4+entryno, 0x7); - entryno--; - set_line(4+entryno, 0x70); + set_line (4 + entryno, A_NORMAL); + entryno --; + set_line (4 + entryno, A_REVERSE); } else if (first_entry > 0) { - first_entry--; + first_entry --; print_entries(3, 12, first_entry, menu_entries); - set_line(4, 0x70); + set_line (4, A_REVERSE); } } if (((c == KEY_DOWN) || (ASCII_CHAR(c) == 14)) @@ -238,15 +238,15 @@ restart: { if (entryno < 11) { - set_line(4+entryno, 0x7); - entryno++; - set_line(4+entryno, 0x70); + set_line (4 + entryno, A_NORMAL); + entryno ++; + set_line (4 + entryno, A_REVERSE); } else if (num_entries > 12+first_entry) { - first_entry++; - print_entries(3, 12, first_entry, menu_entries); - set_line(15, 0x70); + first_entry ++; + print_entries (3, 12, first_entry, menu_entries); + set_line (15, A_REVERSE); } } @@ -261,7 +261,7 @@ restart: { if ((c == 'd') || (c == 'o') || (c == 'O')) { - set_line(4+entryno, 0x7); + set_line (4 + entryno, A_NORMAL); /* insert after is almost exactly like insert before */ if (c == 'o') { @@ -323,7 +323,7 @@ restart: { char *new_file = config_file; while (isspace(*ptr)) ptr++; - while (*(new_file++) = *(ptr++)); + while ((*(new_file++) = *(ptr++)) != 0); return; } c = ASCII_CHAR(getkey()); @@ -350,14 +350,14 @@ restart: else { /* safe area! */ - new_heap = heap+1501; + new_heap = heap + NEW_HEAPSIZE + 1; cur_entry = get_entry(menu_entries, first_entry+entryno, 0); } do { - while (*(new_heap++) = cur_entry[i++]); + while ((*(new_heap++) = cur_entry[i++]) != 0); num_entries++; } while (config_entries && cur_entry[i]); @@ -373,13 +373,14 @@ restart: cls(); init_cmdline(); - new_heap = heap+1501; + new_heap = heap + NEW_HEAPSIZE + 1; saved_drive = boot_drive; saved_partition = install_partition; current_drive = 0xFF; - if (!get_cmdline("editing> ", commands, new_heap, 1501)) + if (!get_cmdline(PACKAGE " edit> ", commands, new_heap, + NEW_HEAPSIZE + 1)) { int j = 0; @@ -408,7 +409,7 @@ restart: } if (c == 'c') { - enter_cmdline(NULL, heap); + enter_cmdline (NULL, heap); goto restart; } } @@ -432,7 +433,7 @@ restart: if (!cur_entry) cur_entry = get_entry(config_entries, first_entry+entryno, 1); - if (!(c = enter_cmdline(cur_entry, heap))) + if (!(c = enter_cmdline (cur_entry, heap))) { if (fallback < 0) break; @@ -460,7 +461,7 @@ get_line_from_config(char *cmdline, int maxlen) int pos = 0, literal = 0, comment = 0; char c; /* since we're loading it a byte at a time! */ - while (read((int)&c, 1)) + while (grub_read (&c, 1)) { /* translate characters first! */ if (c == '\\') @@ -520,12 +521,12 @@ cmain(void) * Here load the configuration file. */ - if (open(config_file)) + if (grub_open (config_file)) { int state = 0, prev_config_len = 0, prev_menu_len = 0; char cmdline[1502], *ptr; - while (get_line_from_config(cmdline, 1500)) + while (get_line_from_config (cmdline, NEW_HEAPSIZE)) { ptr = skip_to(1, cmdline); @@ -547,7 +548,7 @@ cmain(void) state = 1; /* copy title into menu area */ - while (menu_entries[menu_len++] = *(ptr++)); + while ((menu_entries[menu_len++] = *(ptr++)) != 0); } else if (!state) { @@ -559,9 +560,8 @@ cmain(void) safe_parse_maxint(&ptr, &default_entry); if (substring("password", cmdline) < 1) { - char *ptrend = ptr; password = config_entries; - while (*(config_entries++) = *(ptr++)); + while ((*(config_entries++) = *(ptr++)) != 0); } errnum = 0; @@ -573,7 +573,7 @@ cmain(void) state++; /* copy config file data to config area */ - while (config_entries[config_len++] = cmdline[i++]); + while ((config_entries[config_len++] = cmdline[i++]) != 0); } } @@ -601,7 +601,7 @@ cmain(void) if (!num_entries) while (1) - enter_cmdline(NULL, config_entries); + enter_cmdline (NULL, config_entries); /* * Run menu interface (this shouldn't return!).