From a2c7db64f561821fd528614e68c4d92718210126 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 18 Jun 2008 09:36:47 +0100 Subject: Add PV-GRUB This fetches GRUB1 sources, applies the {graphical, print function, save default, and ext3_256byte} patches from debian, and applies a patch to make it work on x86_64 and port it to Mini-OS. By using libxc, PV-GRUB can then "kexec" the loaded kernel from inside the domain itself, hence permitting to avoid the security-concerned pygrub. Signed-off-by: Samuel Thibault --- stubdom/grub.patches/10graphics.diff | 2299 ++++++++++++++++++++++++ stubdom/grub.patches/20print_func.diff | 80 + stubdom/grub.patches/30savedefault.diff | 186 ++ stubdom/grub.patches/40ext3_256byte_inode.diff | 114 ++ stubdom/grub.patches/99minios | 1456 +++++++++++++++ 5 files changed, 4135 insertions(+) create mode 100644 stubdom/grub.patches/10graphics.diff create mode 100644 stubdom/grub.patches/20print_func.diff create mode 100644 stubdom/grub.patches/30savedefault.diff create mode 100644 stubdom/grub.patches/40ext3_256byte_inode.diff create mode 100644 stubdom/grub.patches/99minios (limited to 'stubdom/grub.patches') diff --git a/stubdom/grub.patches/10graphics.diff b/stubdom/grub.patches/10graphics.diff new file mode 100644 index 0000000000..d891c51353 --- /dev/null +++ b/stubdom/grub.patches/10graphics.diff @@ -0,0 +1,2299 @@ +diff -Naur grub-0.97.orig/configure.ac grub-0.97/configure.ac +--- grub-0.97.orig/configure.ac 2005-05-07 23:36:03.000000000 -0300 ++++ grub-0.97/configure.ac 2005-06-12 20:56:49.000000000 -0300 +@@ -595,6 +595,11 @@ + [ --enable-diskless enable diskless support]) + AM_CONDITIONAL(DISKLESS_SUPPORT, test "x$enable_diskless" = xyes) + ++dnl Graphical splashscreen support ++AC_ARG_ENABLE(graphics, ++ [ --disable-graphics disable graphics terminal support]) ++AM_CONDITIONAL(GRAPHICS_SUPPORT, test "x$enable_graphics" != xno) ++ + dnl Hercules terminal + AC_ARG_ENABLE(hercules, + [ --disable-hercules disable hercules terminal support]) +diff -Naur grub-0.97.orig/stage2/asm.S grub-0.97/stage2/asm.S +--- grub-0.97.orig/stage2/asm.S 2004-06-19 13:55:22.000000000 -0300 ++++ grub-0.97/stage2/asm.S 2005-06-13 14:05:31.000000000 -0300 +@@ -2216,7 +2216,304 @@ + pop %ebx + pop %ebp + ret +- ++ ++ ++/* graphics mode functions */ ++#ifdef SUPPORT_GRAPHICS ++VARIABLE(cursorX) ++.word 0 ++VARIABLE(cursorY) ++.word 0 ++VARIABLE(cursorCount) ++.word 0 ++VARIABLE(cursorBuf) ++.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ++ ++ ++/* ++ * set_int1c_handler(void) ++ */ ++ENTRY(set_int1c_handler) ++ pushl %edi ++ ++ /* save the original int1c handler */ ++ movl $0x70, %edi ++ movw (%edi), %ax ++ movw %ax, ABS(int1c_offset) ++ movw 2(%edi), %ax ++ movw %ax, ABS(int1c_segment) ++ ++ /* save the new int1c handler */ ++ movw $ABS(int1c_handler), %ax ++ movw %ax, (%edi) ++ xorw %ax, %ax ++ movw %ax, 2(%edi) ++ ++ popl %edi ++ ret ++ ++ ++/* ++ * unset_int1c_handler(void) ++ */ ++ENTRY(unset_int1c_handler) ++ pushl %edi ++ ++ /* check if int1c_handler is set */ ++ movl $0x70, %edi ++ movw $ABS(int1c_handler), %ax ++ cmpw %ax, (%edi) ++ jne int1c_1 ++ xorw %ax, %ax ++ cmpw %ax, 2(%edi) ++ jne int1c_1 ++ ++ /* restore the original */ ++ movw ABS(int1c_offset), %ax ++ movw %ax, (%edi) ++ movw ABS(int1c_segment), %ax ++ movw %ax, 2(%edi) ++ ++int1c_1: ++ popl %edi ++ ret ++ ++ ++/* ++ * blinks graphics cursor ++ */ ++ .code16 ++write_data: ++ movw $0, %ax ++ movw %ax, %ds ++ ++ mov $0xA000, %ax /* video in es:di */ ++ mov %ax, %es ++ mov $80, %ax ++ movw $ABS(cursorY), %si ++ mov %ds:(%si), %bx ++ mul %bx ++ movw $ABS(cursorX), %si ++ mov %ds:(%si), %bx ++ shr $3, %bx /* %bx /= 8 */ ++ add %bx, %ax ++ mov %ax, %di ++ ++ movw $ABS(cursorBuf), %si /* fontBuf in ds:si */ ++ ++ /* prepare for data moving */ ++ mov $16, %dx /* altura da fonte */ ++ mov $80, %bx /* bytes por linha */ ++ ++write_loop: ++ movb %ds:(%si), %al ++ xorb $0xff, %al ++ movb %al, %ds:(%si) /* invert cursorBuf */ ++ movb %al, %es:(%di) /* write to video */ ++ add %bx, %di ++ inc %si ++ dec %dx ++ jg write_loop ++ ret ++ ++int1c_handler: ++ pusha ++ mov $0, %ax ++ mov %ax, %ds ++ mov $ABS(cursorCount), %si ++ mov %ds:(%si), %ax ++ inc %ax ++ mov %ax, %ds:(%si) ++ cmp $9, %ax ++ jne int1c_done ++ ++ mov $0, %ax ++ mov %ax, %ds:(%si) ++ call write_data ++ ++int1c_done: ++ popa ++ iret ++ /* call previous int1c handler */ ++ /* ljmp */ ++ .byte 0xea ++int1c_offset: .word 0 ++int1c_segment: .word 0 ++ .code32 ++ ++ ++/* ++ * unsigned char set_videomode(unsigned char mode) ++ * BIOS call "INT 10H Function 0h" to set video mode ++ * Call with %ah = 0x0 ++ * %al = video mode ++ * Returns old videomode. ++ */ ++ENTRY(set_videomode) ++ pushl %ebp ++ movl %esp,%ebp ++ pushl %ebx ++ pushl %ecx ++ ++ movb 8(%ebp), %cl ++ ++ call EXT_C(prot_to_real) ++ .code16 ++ ++ xorb %al, %al ++ movb $0xf, %ah ++ int $0x10 /* Get Current Video mode */ ++ movb %al, %ch ++ xorb %ah, %ah ++ movb %cl, %al ++ int $0x10 /* Set Video mode */ ++ ++ DATA32 call EXT_C(real_to_prot) ++ .code32 ++ ++ xorl %eax, %eax ++ movb %ch, %al ++ ++ popl %ecx ++ popl %ebx ++ popl %ebp ++ ret ++ ++ ++/* ++ * int get_videomode() ++ * BIOS call "INT 10H Function 0Fh" to get current video mode ++ * Call with %al = 0x0 ++ * %ah = 0xF ++ * Returns current videomode. ++ */ ++ENTRY(get_videomode) ++ pushl %ebp ++ movl %esp,%ebp ++ pushl %ebx ++ pushl %ecx ++ ++ call EXT_C(prot_to_real) ++ .code16 ++ ++ xorb %al, %al ++ movb $0xF, %ah ++ int $0x10 /* Get Current Video mode */ ++ movb %al, %cl /* For now we only want display mode */ ++ ++ DATA32 call EXT_C(real_to_prot) ++ .code32 ++ ++ xorl %eax, %eax ++ movb %cl, %al ++ ++ popl %ecx ++ popl %ebx ++ popl %ebp ++ ret ++ ++ ++/* ++ * unsigned char * graphics_get_font() ++ * BIOS call "INT 10H Function 11h" to set font ++ * Call with %ah = 0x11 ++ */ ++ENTRY(graphics_get_font) ++ push %ebp ++ push %ebx ++ push %ecx ++ push %edx ++ ++ call EXT_C(prot_to_real) ++ .code16 ++ ++ movw $0x1130, %ax ++ movb $6, %bh /* font 8x16 */ ++ int $0x10 ++ movw %bp, %dx ++ movw %es, %cx ++ ++ DATA32 call EXT_C(real_to_prot) ++ .code32 ++ ++ xorl %eax, %eax ++ movw %cx, %ax ++ shll $4, %eax ++ movw %dx, %ax ++ ++ pop %edx ++ pop %ecx ++ pop %ebx ++ pop %ebp ++ ret ++ ++ ++/* ++ * graphics_set_palette(index, red, green, blue) ++ * BIOS call "INT 10H Function 10h" to set individual dac register ++ * Call with %ah = 0x10 ++ * %bx = register number ++ * %ch = new value for green (0-63) ++ * %cl = new value for blue (0-63) ++ * %dh = new value for red (0-63) ++ */ ++ ++ENTRY(graphics_set_palette) ++ push %ebp ++ push %eax ++ push %ebx ++ push %ecx ++ push %edx ++ ++ movw $0x3c8, %bx /* address write mode register */ ++ ++ /* wait vertical retrace */ ++ movw $0x3da, %dx ++l1b: ++ inb %dx, %al /* wait vertical active display */ ++ test $8, %al ++ jnz l1b ++ ++l2b: ++ inb %dx, %al /* wait vertical retrace */ ++ test $8, %al ++ jnz l2b ++ ++ mov %bx, %dx ++ movb 0x18(%esp), %al /* index */ ++ outb %al, %dx ++ inc %dx ++ ++ movb 0x1c(%esp), %al /* red */ ++ outb %al, %dx ++ ++ movb 0x20(%esp), %al /* green */ ++ outb %al, %dx ++ ++ movb 0x24(%esp), %al /* blue */ ++ outb %al, %dx ++ ++ movw 0x18(%esp), %bx ++ ++ call EXT_C(prot_to_real) ++ .code16 ++ ++ movb %bl, %bh ++ movw $0x1000, %ax ++ int $0x10 ++ ++ DATA32 call EXT_C(real_to_prot) ++ .code32 ++ ++ pop %edx ++ pop %ecx ++ pop %ebx ++ pop %eax ++ pop %ebp ++ ret ++#endif /* SUPPORT_GRAPHICS */ ++ ++ + /* + * getrtsecs() + * if a seconds value can be read, read it and return it (BCD), +diff -Naur grub-0.97.orig/stage2/builtins.c grub-0.97/stage2/builtins.c +--- grub-0.97.orig/stage2/builtins.c 2005-02-15 19:58:23.000000000 -0200 ++++ grub-0.97/stage2/builtins.c 2005-06-13 18:44:03.000000000 -0300 +@@ -28,6 +28,10 @@ + #include + #include + ++#ifdef SUPPORT_GRAPHICS ++# include ++#endif ++ + #ifdef SUPPORT_NETBOOT + # define GRUB 1 + # include +@@ -237,12 +241,22 @@ + static int + boot_func (char *arg, int flags) + { ++ struct term_entry *prev_term = current_term; + /* Clear the int15 handler if we can boot the kernel successfully. + This assumes that the boot code never fails only if KERNEL_TYPE is + not KERNEL_TYPE_NONE. Is this assumption is bad? */ + if (kernel_type != KERNEL_TYPE_NONE) + unset_int15_handler (); + ++ /* if our terminal needed initialization, we should shut it down ++ * before booting the kernel, but we want to save what it was so ++ * we can come back if needed */ ++ if (current_term->shutdown) ++ { ++ current_term->shutdown(); ++ current_term = term_table; /* assumption: console is first */ ++ } ++ + #ifdef SUPPORT_NETBOOT + /* Shut down the networking. */ + cleanup_net (); +@@ -306,6 +320,13 @@ + return 1; + } + ++ /* if we get back here, we should go back to what our term was before */ ++ current_term = prev_term; ++ if (current_term->startup) ++ /* if our terminal fails to initialize, fall back to console since ++ * it should always work */ ++ if (current_term->startup() == 0) ++ current_term = term_table; /* we know that console is first */ + return 0; + } + +@@ -852,6 +873,251 @@ + }; + #endif /* SUPPORT_NETBOOT */ + ++#ifdef SUPPORT_GRAPHICS ++ ++static int splashimage_func(char *arg, int flags) { ++ int i; ++ ++ /* filename can only be 256 characters due to our buffer size */ ++ if (grub_strlen(arg) > 256) { ++ grub_printf("Splash image filename too large\n"); ++ grub_printf("Press any key to continue..."); ++ getkey(); ++ return 1; ++ } ++ ++ /* get rid of TERM_NEED_INIT from the graphics terminal. */ ++ for (i = 0; term_table[i].name; i++) { ++ if (grub_strcmp (term_table[i].name, "graphics") == 0) { ++ term_table[i].flags &= ~TERM_NEED_INIT; ++ break; ++ } ++ } ++ ++ graphics_set_splash(arg); ++ ++ if (flags == BUILTIN_CMDLINE && graphics_inited) { ++ graphics_end(); ++ if (graphics_init() == 0) { ++ /* Fallback to default term */ ++ current_term = term_table; ++ max_lines = current_term->max_lines; ++ if (current_term->cls) ++ current_term->cls(); ++ grub_printf("Failed to set splash image and/or graphics mode\n"); ++ return 1; ++ } ++ graphics_cls(); ++ } ++ ++ if (flags == BUILTIN_MENU) ++ current_term = term_table + i; ++ ++ return 0; ++} ++ ++static struct builtin builtin_splashimage = ++{ ++ "splashimage", ++ splashimage_func, ++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, ++ "splashimage FILE", ++ "Load FILE as the background image when in graphics mode." ++}; ++ ++ ++/* shade */ ++static int ++shade_func(char *arg, int flags) ++{ ++ int new_shade; ++ ++ if (!arg || safe_parse_maxint(&arg, &new_shade) == 0) ++ return (1); ++ ++ if (shade != new_shade) { ++ shade = new_shade; ++ if (flags == BUILTIN_CMDLINE && graphics_inited) { ++ graphics_end(); ++ graphics_init(); ++ graphics_cls(); ++ } ++ } ++ ++ return 0; ++} ++ ++static struct builtin builtin_shade = ++{ ++ "shade", ++ shade_func, ++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, ++ "shade INTEGER", ++ "If set to 0, disables the use of shaded text, else enables it." ++}; ++ ++ ++/* foreground */ ++static int ++foreground_func(char *arg, int flags) ++{ ++ if (grub_strlen(arg) == 6) { ++ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2; ++ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2; ++ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2; ++ ++ foreground = (r << 16) | (g << 8) | b; ++ if (graphics_inited) ++ graphics_set_palette(15, r, g, b); ++ ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static struct builtin builtin_foreground = ++{ ++ "foreground", ++ foreground_func, ++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, ++ "foreground RRGGBB", ++ "Sets the foreground color when in graphics mode." ++ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal." ++}; ++ ++ ++/* background */ ++static int ++background_func(char *arg, int flags) ++{ ++ if (grub_strlen(arg) == 6) { ++ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2; ++ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2; ++ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2; ++ ++ background = (r << 16) | (g << 8) | b; ++ if (graphics_inited) ++ graphics_set_palette(0, r, g, b); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static struct builtin builtin_background = ++{ ++ "background", ++ background_func, ++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, ++ "background RRGGBB", ++ "Sets the background color when in graphics mode." ++ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal." ++}; ++ ++ ++/* border */ ++static int ++border_func(char *arg, int flags) ++{ ++ if (grub_strlen(arg) == 6) { ++ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2; ++ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2; ++ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2; ++ ++ window_border = (r << 16) | (g << 8) | b; ++ if (graphics_inited) ++ graphics_set_palette(0x11, r, g, b); ++ ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static struct builtin builtin_border = ++{ ++ "border", ++ border_func, ++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, ++ "border RRGGBB", ++ "Sets the border video color when in graphics mode." ++ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal." ++}; ++ ++ ++/* viewport */ ++static int ++viewport_func (char *arg, int flags) ++{ ++ int i; ++ int x0 = 0, y0 = 0, x1 = 80, y1 = 30; ++ int *pos[4] = { &x0, &y0, &x1, &y1 }; ++ ++ if (!arg) ++ return (1); ++ for (i = 0; i < 4; i++) { ++ if (!*arg) ++ return (1); ++ while (*arg && (*arg == ' ' || *arg == '\t')) ++ ++arg; ++ if (!safe_parse_maxint(&arg, pos[i])) ++ return (1); ++ while (*arg && (*arg != ' ' && *arg != '\t')) ++ ++arg; ++ } ++ ++ /* minimum size is 65 colums and 16 rows */ ++ if (x0 > x1 - 66 || y0 > y1 - 16 || x0 < 0 || y0 < 0 || x1 > 80 || y1 > 30) ++ return 1; ++ ++ view_x0 = x0; ++ view_y0 = y0; ++ view_x1 = x1; ++ view_y1 = y1; ++ ++ if (flags == BUILTIN_CMDLINE && graphics_inited) { ++ graphics_end(); ++ graphics_init(); ++ graphics_cls(); ++ } ++ ++ return 0; ++} ++ ++static struct builtin builtin_viewport = ++{ ++ "viewport", ++ viewport_func, ++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, ++ "viewport x0 y0 x1 y1", ++ "Changes grub internals to output text in the window defined by" ++ " four parameters. The x and y parameters are 0 based. This option" ++ " only works with the graphics interface." ++}; ++ ++#endif /* SUPPORT_GRAPHICS */ ++ ++ ++/* clear */ ++static int ++clear_func() ++{ ++ if (current_term->cls) ++ current_term->cls(); ++ ++ return 0; ++} ++ ++static struct builtin builtin_clear = ++{ ++ "clear", ++ clear_func, ++ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, ++ "clear", ++ "Clear the screen" ++}; ++ + + /* displayapm */ + static int +@@ -1454,14 +1720,20 @@ + + + /* help */ +-#define MAX_SHORT_DOC_LEN 39 +-#define MAX_LONG_DOC_LEN 66 +- + static int + help_func (char *arg, int flags) + { +- int all = 0; +- ++ int all = 0, max_short_doc_len, max_long_doc_len; ++ max_short_doc_len = 39; ++ max_long_doc_len = 66; ++#ifdef SUPPORT_GRAPHICS ++ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0) ++ { ++ max_short_doc_len = (view_x1 - view_x0 + 1) / 2 - 1; ++ max_long_doc_len = (view_x1 - view_x0) - 14; ++ } ++#endif ++ + if (grub_memcmp (arg, "--all", sizeof ("--all") - 1) == 0) + { + all = 1; +@@ -1491,13 +1763,13 @@ + + len = grub_strlen ((*builtin)->short_doc); + /* If the length of SHORT_DOC is too long, truncate it. */ +- if (len > MAX_SHORT_DOC_LEN - 1) +- len = MAX_SHORT_DOC_LEN - 1; ++ if (len > max_short_doc_len - 1) ++ len = max_short_doc_len - 1; + + for (i = 0; i < len; i++) + grub_putchar ((*builtin)->short_doc[i]); + +- for (; i < MAX_SHORT_DOC_LEN; i++) ++ for (; i < max_short_doc_len; i++) + grub_putchar (' '); + + if (! left) +@@ -1546,10 +1818,10 @@ + int i; + + /* If LEN is too long, fold DOC. */ +- if (len > MAX_LONG_DOC_LEN) ++ if (len > max_long_doc_len) + { + /* Fold this line at the position of a space. */ +- for (len = MAX_LONG_DOC_LEN; len > 0; len--) ++ for (len = max_long_doc_len; len > 0; len--) + if (doc[len - 1] == ' ') + break; + } +@@ -4085,7 +4357,7 @@ + }; + + +-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) ++#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS) + /* terminal */ + static int + terminal_func (char *arg, int flags) +@@ -4244,17 +4516,29 @@ + end: + current_term = term_table + default_term; + current_term->flags = term_flags; +- ++ + if (lines) + max_lines = lines; + else +- /* 24 would be a good default value. */ +- max_lines = 24; +- ++ max_lines = current_term->max_lines; ++ + /* If the interface is currently the command-line, + restart it to repaint the screen. */ +- if (current_term != prev_term && (flags & BUILTIN_CMDLINE)) ++ if ((current_term != prev_term) && (flags & BUILTIN_CMDLINE)){ ++ if (prev_term->shutdown) ++ prev_term->shutdown(); ++ if (current_term->startup) { ++ /* If startup fails, return to previous term */ ++ if (current_term->startup() == 0) { ++ current_term = prev_term; ++ max_lines = current_term->max_lines; ++ if (current_term->cls) { ++ current_term->cls(); ++ } ++ } ++ } + grub_longjmp (restart_cmdline_env, 0); ++ } + + return 0; + } +@@ -4264,7 +4548,7 @@ + "terminal", + terminal_func, + BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, +- "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules]", ++ "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules] [graphics]", + "Select a terminal. When multiple terminals are specified, wait until" + " you push any key to continue. If both console and serial are specified," + " the terminal to which you input a key first will be selected. If no" +@@ -4276,7 +4560,7 @@ + " seconds. The option --lines specifies the maximum number of lines." + " The option --silent is used to suppress messages." + }; +-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */ ++#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */ + + + #ifdef SUPPORT_SERIAL +@@ -4795,13 +5079,20 @@ + /* The table of builtin commands. Sorted in dictionary order. */ + struct builtin *builtin_table[] = + { ++#ifdef SUPPORT_GRAPHICS ++ &builtin_background, ++#endif + &builtin_blocklist, + &builtin_boot, + #ifdef SUPPORT_NETBOOT + &builtin_bootp, + #endif /* SUPPORT_NETBOOT */ ++#ifdef SUPPORT_GRAPHICS ++ &builtin_border, ++#endif + &builtin_cat, + &builtin_chainloader, ++ &builtin_clear, + &builtin_cmp, + &builtin_color, + &builtin_configfile, +@@ -4821,6 +5112,9 @@ + &builtin_embed, + &builtin_fallback, + &builtin_find, ++#ifdef SUPPORT_GRAPHICS ++ &builtin_foreground, ++#endif + &builtin_fstest, + &builtin_geometry, + &builtin_halt, +@@ -4864,9 +5158,13 @@ + #endif /* SUPPORT_SERIAL */ + &builtin_setkey, + &builtin_setup, +-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) ++#ifdef SUPPORT_GRAPHICS ++ &builtin_shade, ++ &builtin_splashimage, ++#endif /* SUPPORT_GRAPHICS */ ++#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS) + &builtin_terminal, +-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */ ++#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */ + #ifdef SUPPORT_SERIAL + &builtin_terminfo, + #endif /* SUPPORT_SERIAL */ +@@ -4880,5 +5178,8 @@ + &builtin_unhide, + &builtin_uppermem, + &builtin_vbeprobe, ++#ifdef SUPPORT_GRAPHICS ++ &builtin_viewport, ++#endif + 0 + }; +diff -Naur grub-0.97.orig/stage2/char_io.c grub-0.97/stage2/char_io.c +--- grub-0.97.orig/stage2/char_io.c 2005-02-01 18:51:23.000000000 -0200 ++++ grub-0.97/stage2/char_io.c 2005-06-12 20:56:49.000000000 -0300 +@@ -29,12 +29,17 @@ + # include + #endif + ++#ifdef SUPPORT_GRAPHICS ++# include ++#endif ++ + #ifndef STAGE1_5 + struct term_entry term_table[] = + { + { + "console", + 0, ++ 24, + console_putchar, + console_checkkey, + console_getkey, +@@ -43,13 +48,16 @@ + console_cls, + console_setcolorstate, + console_setcolor, +- console_setcursor ++ console_setcursor, ++ 0, ++ 0 + }, + #ifdef SUPPORT_SERIAL + { + "serial", + /* A serial device must be initialized. */ + TERM_NEED_INIT, ++ 24, + serial_putchar, + serial_checkkey, + serial_getkey, +@@ -58,6 +66,8 @@ + serial_cls, + serial_setcolorstate, + 0, ++ 0, ++ 0, + 0 + }, + #endif /* SUPPORT_SERIAL */ +@@ -65,6 +75,7 @@ + { + "hercules", + 0, ++ 24, + hercules_putchar, + console_checkkey, + console_getkey, +@@ -73,11 +84,30 @@ + hercules_cls, + hercules_setcolorstate, + hercules_setcolor, +- hercules_setcursor ++ hercules_setcursor, ++ 0, ++ 0 + }, + #endif /* SUPPORT_HERCULES */ ++#ifdef SUPPORT_GRAPHICS ++ { "graphics", ++ TERM_NEED_INIT, /* flags */ ++ 30, /* number of lines */ ++ graphics_putchar, /* putchar */ ++ console_checkkey, /* checkkey */ ++ console_getkey, /* getkey */ ++ graphics_getxy, /* getxy */ ++ graphics_gotoxy, /* gotoxy */ ++ graphics_cls, /* cls */ ++ graphics_setcolorstate, /* setcolorstate */ ++ graphics_setcolor, /* setcolor */ ++ graphics_setcursor, /* nocursor */ ++ graphics_init, /* initialize */ ++ graphics_end /* shutdown */ ++ }, ++#endif /* SUPPORT_GRAPHICS */ + /* This must be the last entry. */ +- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }; + + /* This must be console. */ +@@ -305,9 +335,10 @@ + + /* XXX: These should be defined in shared.h, but I leave these here, + until this code is freezed. */ +-#define CMDLINE_WIDTH 78 + #define CMDLINE_MARGIN 10 +- ++ ++ /* command-line limits */ ++ int cmdline_width = 78, col_start = 0; + int xpos, lpos, c, section; + /* The length of PROMPT. */ + int plen; +@@ -338,7 +369,7 @@ + + /* If the cursor is in the first section, display the first section + instead of the second. */ +- if (section == 1 && plen + lpos < CMDLINE_WIDTH) ++ if (section == 1 && plen + lpos < cmdline_width) + cl_refresh (1, 0); + else if (xpos - count < 1) + cl_refresh (1, 0); +@@ -354,7 +385,7 @@ + grub_putchar ('\b'); + } + else +- gotoxy (xpos, getxy () & 0xFF); ++ gotoxy (xpos + col_start, getxy () & 0xFF); + } + } + +@@ -364,7 +395,7 @@ + lpos += count; + + /* If the cursor goes outside, scroll the screen to the right. */ +- if (xpos + count >= CMDLINE_WIDTH) ++ if (xpos + count >= cmdline_width) + cl_refresh (1, 0); + else + { +@@ -383,7 +414,7 @@ + } + } + else +- gotoxy (xpos, getxy () & 0xFF); ++ gotoxy (xpos + col_start, getxy () & 0xFF); + } + } + +@@ -398,14 +429,14 @@ + if (full) + { + /* Recompute the section number. */ +- if (lpos + plen < CMDLINE_WIDTH) ++ if (lpos + plen < cmdline_width) + section = 0; + else +- section = ((lpos + plen - CMDLINE_WIDTH) +- / (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) + 1); ++ section = ((lpos + plen - cmdline_width) ++ / (cmdline_width - 1 - CMDLINE_MARGIN) + 1); + + /* From the start to the end. */ +- len = CMDLINE_WIDTH; ++ len = cmdline_width; + pos = 0; + grub_putchar ('\r'); + +@@ -445,8 +476,8 @@ + if (! full) + offset = xpos - 1; + +- start = ((section - 1) * (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) +- + CMDLINE_WIDTH - plen - CMDLINE_MARGIN); ++ start = ((section - 1) * (cmdline_width - 1 - CMDLINE_MARGIN) ++ + cmdline_width - plen - CMDLINE_MARGIN); + xpos = lpos + 1 - start; + start += offset; + } +@@ -471,7 +502,7 @@ + + /* If the cursor is at the last position, put `>' or a space, + depending on if there are more characters in BUF. */ +- if (pos == CMDLINE_WIDTH) ++ if (pos == cmdline_width) + { + if (start + len < llen) + grub_putchar ('>'); +@@ -488,7 +519,7 @@ + grub_putchar ('\b'); + } + else +- gotoxy (xpos, getxy () & 0xFF); ++ gotoxy (xpos + col_start, getxy () & 0xFF); + } + + /* Initialize the command-line. */ +@@ -518,10 +549,10 @@ + + llen += l; + lpos += l; +- if (xpos + l >= CMDLINE_WIDTH) ++ if (xpos + l >= cmdline_width) + cl_refresh (1, 0); +- else if (xpos + l + llen - lpos > CMDLINE_WIDTH) +- cl_refresh (0, CMDLINE_WIDTH - xpos); ++ else if (xpos + l + llen - lpos > cmdline_width) ++ cl_refresh (0, cmdline_width - xpos); + else + cl_refresh (0, l + llen - lpos); + } +@@ -533,12 +564,22 @@ + grub_memmove (buf + lpos, buf + lpos + count, llen - count + 1); + llen -= count; + +- if (xpos + llen + count - lpos > CMDLINE_WIDTH) +- cl_refresh (0, CMDLINE_WIDTH - xpos); ++ if (xpos + llen + count - lpos > cmdline_width) ++ cl_refresh (0, cmdline_width - xpos); + else + cl_refresh (0, llen + count - lpos); + } + ++ max_lines = current_term->max_lines; ++#ifdef SUPPORT_GRAPHICS ++ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0) ++ { ++ cmdline_width = (view_x1 - view_x0) - 2; ++ col_start = view_x0; ++ max_lines = view_y1 - view_y0; ++ } ++#endif ++ + plen = grub_strlen (prompt); + llen = grub_strlen (cmdline); + +@@ -1006,6 +1047,48 @@ + } + #endif /* ! STAGE1_5 */ + ++#ifndef STAGE1_5 ++/* Internal pager. */ ++int ++do_more (void) ++{ ++ if (count_lines >= 0) ++ { ++ count_lines++; ++ if (count_lines >= max_lines - 2) ++ { ++ int tmp; ++ ++ /* It's important to disable the feature temporarily, because ++ the following grub_printf call will print newlines. */ ++ count_lines = -1; ++ ++ grub_printf("\n"); ++ if (current_term->setcolorstate) ++ current_term->setcolorstate (COLOR_STATE_HIGHLIGHT); ++ ++ grub_printf ("[Hit return to continue]"); ++ ++ if (current_term->setcolorstate) ++ current_term->setcolorstate (COLOR_STATE_NORMAL); ++ ++ ++ do ++ { ++ tmp = ASCII_CHAR (getkey ()); ++ } ++ while (tmp != '\n' && tmp != '\r'); ++ grub_printf ("\r \r"); ++ ++ /* Restart to count lines. */ ++ count_lines = 0; ++ return 1; ++ } ++ } ++ return 0; ++} ++#endif ++ + /* Display an ASCII character. */ + void + grub_putchar (int c) +@@ -1034,38 +1117,11 @@ + + if (c == '\n') + { ++ int flag; + /* Internal `more'-like feature. */ +- if (count_lines >= 0) +- { +- count_lines++; +- if (count_lines >= max_lines - 2) +- { +- int tmp; +- +- /* It's important to disable the feature temporarily, because +- the following grub_printf call will print newlines. */ +- count_lines = -1; +- +- if (current_term->setcolorstate) +- current_term->setcolorstate (COLOR_STATE_HIGHLIGHT); +- +- grub_printf ("\n[Hit return to continue]"); +- +- if (current_term->setcolorstate) +- current_term->setcolorstate (COLOR_STATE_NORMAL); +- +- do +- { +- tmp = ASCII_CHAR (getkey ()); +- } +- while (tmp != '\n' && tmp != '\r'); +- grub_printf ("\r \r"); +- +- /* Restart to count lines. */ +- count_lines = 0; +- return; +- } +- } ++ flag = do_more (); ++ if (flag) ++ return; + } + + current_term->putchar (c); +@@ -1090,7 +1146,7 @@ + cls (void) + { + /* If the terminal is dumb, there is no way to clean the terminal. */ +- if (current_term->flags & TERM_DUMB) ++ if (current_term->flags & TERM_DUMB) + grub_putchar ('\n'); + else + current_term->cls (); +@@ -1217,6 +1273,16 @@ + return ! errnum; + } + ++void ++grub_memcpy(void *dest, const void *src, int len) ++{ ++ int i; ++ register char *d = (char*)dest, *s = (char*)src; ++ ++ for (i = 0; i < len; i++) ++ d[i] = s[i]; ++} ++ + void * + grub_memmove (void *to, const void *from, int len) + { +diff -Naur grub-0.97.orig/stage2/cmdline.c grub-0.97/stage2/cmdline.c +--- grub-0.97.orig/stage2/cmdline.c 2004-08-16 20:23:01.000000000 -0300 ++++ grub-0.97/stage2/cmdline.c 2005-06-12 20:56:49.000000000 -0300 +@@ -50,10 +50,11 @@ + void + print_cmdline_message (int forever) + { +- printf (" [ Minimal BASH-like line editing is supported. For the first word, TAB\n" +- " lists possible command completions. Anywhere else TAB lists the possible\n" +- " completions of a device/filename.%s ]\n", +- (forever ? "" : " ESC at any time exits.")); ++ grub_printf(" [ Minimal BASH-like line editing is supported. For\n" ++ " the first word, TAB lists possible command\n" ++ " completions. Anywhere else TAB lists the possible\n" ++ " completions of a device/filename.%s ]\n", ++ (forever ? "" : " ESC at any time\n exits.")); + } + + /* Find the builtin whose command name is COMMAND and return the +diff -Naur grub-0.97.orig/stage2/graphics.c grub-0.97/stage2/graphics.c +--- grub-0.97.orig/stage2/graphics.c 1969-12-31 21:00:00.000000000 -0300 ++++ grub-0.97/stage2/graphics.c 2005-06-13 19:13:31.000000000 -0300 +@@ -0,0 +1,585 @@ ++/* ++ * graphics.c - graphics mode support for GRUB ++ * Implemented as a terminal type by Jeremy Katz based ++ * on a patch by Paulo César Pereira de Andrade ++ * Options and enhancements made by Herton Ronaldo Krzesinski ++ * ++ * ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2001,2002 Red Hat, Inc. ++ * Portions copyright (C) 2000 Conectiva, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#ifdef SUPPORT_GRAPHICS ++ ++#include ++#include ++#include ++ ++int saved_videomode; ++unsigned char *font8x16; ++ ++int graphics_inited = 0; ++static char splashimage[256]; ++ ++int shade = 1, no_cursor = 0; ++ ++#define VSHADOW VSHADOW1 ++unsigned char VSHADOW1[38400]; ++unsigned char VSHADOW2[38400]; ++unsigned char VSHADOW4[38400]; ++unsigned char VSHADOW8[38400]; ++ ++/* define the default viewable area */ ++int view_x0 = 0; ++int view_y0 = 0; ++int view_x1 = 80; ++int view_y1 = 30; ++ ++/* text buffer has to be kept around so that we can write things as we ++ * scroll and the like */ ++unsigned short text[80 * 30]; ++ ++/* graphics options */ ++int foreground = (63 << 16) | (63 << 8) | (63), background = 0, window_border = 0; ++ ++/* current position */ ++static int fontx = 0; ++static int fonty = 0; ++ ++/* global state so that we don't try to recursively scroll or cursor */ ++static int no_scroll = 0; ++ ++/* color state */ ++static int graphics_standard_color = A_NORMAL; ++static int graphics_normal_color = A_NORMAL; ++static int graphics_highlight_color = A_REVERSE; ++static int graphics_current_color = A_NORMAL; ++static color_state graphics_color_state = COLOR_STATE_STANDARD; ++ ++static inline void outb(unsigned short port, unsigned char val) ++{ ++ __asm __volatile ("outb %0,%1"::"a" (val), "d" (port)); ++} ++ ++static void MapMask(int value) { ++ outb(0x3c4, 2); ++ outb(0x3c5, value); ++} ++ ++/* bit mask register */ ++static void BitMask(int value) { ++ outb(0x3ce, 8); ++ outb(0x3cf, value); ++} ++ ++/* move the graphics cursor location to col, row */ ++static void graphics_setxy(int col, int row) { ++ if (col >= view_x0 && col < view_x1) { ++ fontx = col; ++ cursorX = col << 3; ++ } ++ if (row >= view_y0 && row < view_y1) { ++ fonty = row; ++ cursorY = row << 4; ++ } ++} ++ ++/* scroll the screen */ ++static void graphics_scroll() { ++ int i, j, k; ++ ++ /* we don't want to scroll recursively... that would be bad */ ++ if (no_scroll) ++ return; ++ no_scroll = 1; ++ ++ /* disable pager temporarily */ ++ k = count_lines; ++ count_lines = -1; ++ ++ /* move everything up a line */ ++ for (j = view_y0 + 1; j < view_y1; j++) { ++ graphics_gotoxy(view_x0, j - 1); ++ for (i = view_x0; i < view_x1; i++) { ++ graphics_putchar(text[j * 80 + i]); ++ } ++ } ++ ++ /* last line should be blank */ ++ graphics_gotoxy(view_x0, view_y1 - 1); ++ for (i = view_x0; i < view_x1; i++) ++ graphics_putchar(' '); ++ graphics_setxy(view_x0, view_y1 - 1); ++ ++ count_lines = k; ++ ++ no_scroll = 0; ++} ++ ++/* Set the splash image */ ++void graphics_set_splash(char *splashfile) { ++ grub_strcpy(splashimage, splashfile); ++} ++ ++/* Get the current splash image */ ++char *graphics_get_splash(void) { ++ return splashimage; ++} ++ ++/* ++ * Initialize a vga16 graphics display with the palette based off of ++ * the image in splashimage. If the image doesn't exist, leave graphics ++ * mode. The mode initiated is 12h. From "Ralf Brown's Interrupt List": ++ * text/ text pixel pixel colors disply scrn system ++ * grph resol box resolution pages addr ++ * 12h G 80x30 8x16 640x480 16/256K . A000 VGA,ATI VIP ++ * G 80x30 8x16 640x480 16/64 . A000 ATI EGA Wonder ++ * G . . 640x480 16 . . UltraVision+256K EGA ++ */ ++int graphics_init() ++{ ++ if (!graphics_inited) { ++ saved_videomode = set_videomode(0x12); ++ if (get_videomode() != 0x12) { ++ set_videomode(saved_videomode); ++ return 0; ++ } ++ graphics_inited = 1; ++ } ++ else ++ return 1; ++ ++ font8x16 = (unsigned char*)graphics_get_font(); ++ ++ /* make sure that the highlight color is set correctly */ ++ graphics_highlight_color = ((graphics_normal_color >> 4) | ++ ((graphics_normal_color & 0xf) << 4)); ++ ++ graphics_cls(); ++ ++ if (!read_image(splashimage)) { ++ grub_printf("Failed to read splash image (%s)\n", splashimage); ++ grub_printf("Press any key to continue..."); ++ getkey(); ++ set_videomode(saved_videomode); ++ graphics_inited = 0; ++ return 0; ++ } ++ ++ set_int1c_handler(); ++ ++ return 1; ++} ++ ++/* Leave graphics mode */ ++void graphics_end(void) ++{ ++ if (graphics_inited) { ++ unset_int1c_handler(); ++ set_videomode(saved_videomode); ++ graphics_inited = 0; ++ no_cursor = 0; ++ } ++} ++ ++/* Print ch on the screen. Handle any needed scrolling or the like */ ++void graphics_putchar(int ch) { ++ ch &= 0xff; ++ ++ graphics_cursor(0); ++ ++ if (ch == '\n') { ++ if (fonty + 1 < view_y1) ++ graphics_setxy(fontx, fonty + 1); ++ else ++ graphics_scroll(); ++ graphics_cursor(1); ++ return; ++ } else if (ch == '\r') { ++ graphics_setxy(view_x0, fonty); ++ graphics_cursor(1); ++ return; ++ } ++ ++ graphics_cursor(0); ++ ++ text[fonty * 80 + fontx] = ch; ++ text[fonty * 80 + fontx] &= 0x00ff; ++ if (graphics_current_color & 0xf0) ++ text[fonty * 80 + fontx] |= 0x100; ++ ++ graphics_cursor(0); ++ ++ if ((fontx + 1) >= view_x1) { ++ graphics_setxy(view_x0, fonty); ++ if (fonty + 1 < view_y1) ++ graphics_setxy(view_x0, fonty + 1); ++ else ++ graphics_scroll(); ++ graphics_cursor(1); ++ do_more (); ++ graphics_cursor(0); ++ } else { ++ graphics_setxy(fontx + 1, fonty); ++ } ++ ++ graphics_cursor(1); ++} ++ ++/* get the current location of the cursor */ ++int graphics_getxy(void) { ++ return (fontx << 8) | fonty; ++} ++ ++void graphics_gotoxy(int x, int y) { ++ graphics_cursor(0); ++ ++ graphics_setxy(x, y); ++ ++ graphics_cursor(1); ++} ++ ++void graphics_cls(void) { ++ int i; ++ unsigned char *mem, *s1, *s2, *s4, *s8; ++ ++ graphics_cursor(0); ++ graphics_gotoxy(view_x0, view_y0); ++ ++ mem = (unsigned char*)VIDEOMEM; ++ s1 = (unsigned char*)VSHADOW1; ++ s2 = (unsigned char*)VSHADOW2; ++ s4 = (unsigned char*)VSHADOW4; ++ s8 = (unsigned char*)VSHADOW8; ++ ++ for (i = 0; i < 80 * 30; i++) ++ text[i] = ' '; ++ graphics_cursor(1); ++ ++ BitMask(0xff); ++ ++ /* plane 1 */ ++ MapMask(1); ++ grub_memcpy(mem, s1, 38400); ++ ++ /* plane 2 */ ++ MapMask(2); ++ grub_memcpy(mem, s2, 38400); ++ ++ /* plane 3 */ ++ MapMask(4); ++ grub_memcpy(mem, s4, 38400); ++ ++ /* plane 4 */ ++ MapMask(8); ++ grub_memcpy(mem, s8, 38400); ++ ++ MapMask(15); ++ ++ if (no_cursor) { ++ no_cursor = 0; ++ set_int1c_handler(); ++ } ++} ++ ++void graphics_setcolorstate (color_state state) { ++ switch (state) { ++ case COLOR_STATE_STANDARD: ++ graphics_current_color = graphics_standard_color; ++ break; ++ case COLOR_STATE_NORMAL: ++ graphics_current_color = graphics_normal_color; ++ break; ++ case COLOR_STATE_HIGHLIGHT: ++ graphics_current_color = graphics_highlight_color; ++ break; ++ default: ++ graphics_current_color = graphics_standard_color; ++ break; ++ } ++ ++ graphics_color_state = state; ++} ++ ++void graphics_setcolor (int normal_color, int highlight_color) { ++ graphics_normal_color = normal_color; ++ graphics_highlight_color = highlight_color; ++ ++ graphics_setcolorstate (graphics_color_state); ++} ++ ++int graphics_setcursor (int on) { ++ if (!no_cursor && !on) { ++ no_cursor = 1; ++ unset_int1c_handler(); ++ graphics_cursor(0); ++ } ++ else if(no_cursor && on) { ++ no_cursor = 0; ++ set_int1c_handler(); ++ graphics_cursor(1); ++ } ++ return 0; ++} ++ ++/* Read in the splashscreen image and set the palette up appropriately. ++ * Format of splashscreen is an xpm (can be gzipped) with 16 colors and ++ * 640x480. */ ++int read_image(char *s) ++{ ++ char buf[32], pal[16], c; ++ unsigned char base, mask, *s1, *s2, *s4, *s8; ++ unsigned i, len, idx, colors, x, y, width, height; ++ ++ if (!grub_open(s)) ++ return 0; ++ ++ /* read header */ ++ if (!grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) { ++ grub_close(); ++ return 0; ++ } ++ ++ /* parse info */ ++ while (grub_read(&c, 1)) { ++ if (c == '"') ++ break; ++ } ++ ++ while (grub_read(&c, 1) && (c == ' ' || c == '\t')) ++ ; ++ ++ i = 0; ++ width = c - '0'; ++ while (grub_read(&c, 1)) { ++ if (c >= '0' && c <= '9') ++ width = width * 10 + c - '0'; ++ else ++ break; ++ } ++ while (grub_read(&c, 1) && (c == ' ' || c == '\t')) ++ ; ++ ++ height = c - '0'; ++ while (grub_read(&c, 1)) { ++ if (c >= '0' && c <= '9') ++ height = height * 10 + c - '0'; ++ else ++ break; ++ } ++ while (grub_read(&c, 1) && (c == ' ' || c == '\t')) ++ ; ++ ++ colors = c - '0'; ++ while (grub_read(&c, 1)) { ++ if (c >= '0' && c <= '9') ++ colors = colors * 10 + c - '0'; ++ else ++ break; ++ } ++ ++ base = 0; ++ while (grub_read(&c, 1) && c != '"') ++ ; ++ ++ /* palette */ ++ for (i = 0, idx = 1; i < colors; i++) { ++ len = 0; ++ ++ while (grub_read(&c, 1) && c != '"') ++ ; ++ grub_read(&c, 1); /* char */ ++ base = c; ++ grub_read(buf, 4); /* \t c # */ ++ ++ while (grub_read(&c, 1) && c != '"') { ++ if (len < sizeof(buf)) ++ buf[len++] = c; ++ } ++ ++ if (len == 6 && idx < 15) { ++ int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2; ++ int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2; ++ int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2; ++ ++ pal[idx] = base; ++ graphics_set_palette(idx, r, g, b); ++ ++idx; ++ } ++ } ++ ++ x = y = len = 0; ++ ++ s1 = (unsigned char*)VSHADOW1; ++ s2 = (unsigned char*)VSHADOW2; ++ s4 = (unsigned char*)VSHADOW4; ++ s8 = (unsigned char*)VSHADOW8; ++ ++ for (i = 0; i < 38400; i++) ++ s1[i] = s2[i] = s4[i] = s8[i] = 0; ++ ++ /* parse xpm data */ ++ while (y < height) { ++ while (1) { ++ if (!grub_read(&c, 1)) { ++ grub_close(); ++ return 0; ++ } ++ if (c == '"') ++ break; ++ } ++ ++ while (grub_read(&c, 1) && c != '"') { ++ for (i = 1; i < 15; i++) ++ if (pal[i] == c) { ++ c = i; ++ break; ++ } ++ ++ mask = 0x80 >> (x & 7); ++ if (c & 1) ++ s1[len + (x >> 3)] |= mask; ++ if (c & 2) ++ s2[len + (x >> 3)] |= mask; ++ if (c & 4) ++ s4[len + (x >> 3)] |= mask; ++ if (c & 8) ++ s8[len + (x >> 3)] |= mask; ++ ++ if (++x >= 640) { ++ x = 0; ++ ++ if (y < 480) ++ len += 80; ++ ++y; ++ } ++ } ++ } ++ ++ grub_close(); ++ ++ graphics_set_palette(0, (background >> 16), (background >> 8) & 63, ++ background & 63); ++ graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63, ++ foreground & 63); ++ graphics_set_palette(0x11, (window_border >> 16), (window_border >> 8) & 63, ++ window_border & 63); ++ ++ return 1; ++} ++ ++/* Convert a character which is a hex digit to the appropriate integer */ ++int hex(int v) ++{ ++ if (v >= 'A' && v <= 'F') ++ return (v - 'A' + 10); ++ if (v >= 'a' && v <= 'f') ++ return (v - 'a' + 10); ++ return (v - '0'); ++} ++ ++void graphics_cursor(int set) { ++ unsigned char *pat, *mem, *ptr, chr[16 << 2]; ++ int i, ch, invert, offset; ++ ++ if (set && (no_cursor || no_scroll)) ++ return; ++ ++ offset = cursorY * 80 + fontx; ++ ch = text[fonty * 80 + fontx] & 0xff; ++ invert = (text[fonty * 80 + fontx] & 0xff00) != 0; ++ pat = font8x16 + (ch << 4); ++ ++ mem = (unsigned char*)VIDEOMEM + offset; ++ ++ if (!set) { ++ for (i = 0; i < 16; i++) { ++ unsigned char mask = pat[i]; ++ ++ if (!invert) { ++ chr[i ] = ((unsigned char*)VSHADOW1)[offset]; ++ chr[16 + i] = ((unsigned char*)VSHADOW2)[offset]; ++ chr[32 + i] = ((unsigned char*)VSHADOW4)[offset]; ++ chr[48 + i] = ((unsigned char*)VSHADOW8)[offset]; ++ ++ if (shade) { ++ if (ch == DISP_VERT || ch == DISP_LL || ++ ch == DISP_UR || ch == DISP_LR) { ++ unsigned char pmask = ~(pat[i] >> 1); ++ ++ chr[i ] &= pmask; ++ chr[16 + i] &= pmask; ++ chr[32 + i] &= pmask; ++ chr[48 + i] &= pmask; ++ } ++ if (i > 0 && ch != DISP_VERT) { ++ unsigned char pmask = ~(pat[i - 1] >> 1); ++ ++ chr[i ] &= pmask; ++ chr[16 + i] &= pmask; ++ chr[32 + i] &= pmask; ++ chr[48 + i] &= pmask; ++ if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) { ++ pmask = ~pat[i - 1]; ++ ++ chr[i ] &= pmask; ++ chr[16 + i] &= pmask; ++ chr[32 + i] &= pmask; ++ chr[48 + i] &= pmask; ++ } ++ } ++ } ++ chr[i ] |= mask; ++ chr[16 + i] |= mask; ++ chr[32 + i] |= mask; ++ chr[48 + i] |= mask; ++ ++ offset += 80; ++ } ++ else { ++ chr[i ] = mask; ++ chr[16 + i] = mask; ++ chr[32 + i] = mask; ++ chr[48 + i] = mask; ++ } ++ } ++ } ++ else { ++ MapMask(15); ++ ptr = mem; ++ for (i = 0; i < 16; i++, ptr += 80) { ++ cursorBuf[i] = pat[i]; ++ *ptr = ~pat[i]; ++ } ++ return; ++ } ++ ++ offset = 0; ++ for (i = 1; i < 16; i <<= 1, offset += 16) { ++ int j; ++ ++ MapMask(i); ++ ptr = mem; ++ for (j = 0; j < 16; j++, ptr += 80) ++ *ptr = chr[j + offset]; ++ } ++ ++ MapMask(15); ++} ++ ++#endif /* SUPPORT_GRAPHICS */ +diff -Naur grub-0.97.orig/stage2/graphics.h grub-0.97/stage2/graphics.h +--- grub-0.97.orig/stage2/graphics.h 1969-12-31 21:00:00.000000000 -0300 ++++ grub-0.97/stage2/graphics.h 2005-06-12 20:56:49.000000000 -0300 +@@ -0,0 +1,44 @@ ++/* graphics.h - graphics console interface */ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2002 Free Software Foundation, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#ifndef GRAPHICS_H ++#define GRAPHICS_H ++ ++/* magic constant */ ++#define VIDEOMEM 0xA0000 ++ ++/* function prototypes */ ++char *graphics_get_splash(void); ++ ++int read_image(char *s); ++void graphics_cursor(int set); ++ ++/* function prototypes for asm functions */ ++void * graphics_get_font(); ++void graphics_set_palette(int idx, int red, int green, int blue); ++void set_int1c_handler(); ++void unset_int1c_handler(); ++ ++extern short cursorX, cursorY; ++extern char cursorBuf[16]; ++extern int shade; ++extern int view_x0, view_y0, view_x1, view_y1; ++ ++#endif /* GRAPHICS_H */ +diff -Naur grub-0.97.orig/stage2/Makefile.am grub-0.97/stage2/Makefile.am +--- grub-0.97.orig/stage2/Makefile.am 2005-02-02 18:37:35.000000000 -0200 ++++ grub-0.97/stage2/Makefile.am 2005-06-12 20:56:49.000000000 -0300 +@@ -7,7 +7,7 @@ + fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \ + imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \ + nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \ +- terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h ++ terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h graphics.h + EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS) + + # For . +@@ -19,7 +19,7 @@ + disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \ + fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \ + fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \ +- terminfo.c tparm.c ++ terminfo.c tparm.c graphics.c + libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \ + -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \ + -DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \ +@@ -79,8 +79,14 @@ + HERCULES_FLAGS = + endif + ++if GRAPHICS_SUPPORT ++GRAPHICS_FLAGS = -DSUPPORT_GRAPHICS=1 ++else ++GRAPHICS_FLAGS = ++endif ++ + STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \ +- $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) ++ $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) $(GRAPHICS_FLAGS) + + STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000 + STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1 +@@ -90,7 +96,8 @@ + cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \ + fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \ + fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \ +- hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c ++ hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c \ ++ graphics.c + pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) + pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) + pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK) +diff -Naur grub-0.97.orig/stage2/shared.h grub-0.97/stage2/shared.h +--- grub-0.97.orig/stage2/shared.h 2004-06-19 13:40:09.000000000 -0300 ++++ grub-0.97/stage2/shared.h 2005-06-12 20:56:49.000000000 -0300 +@@ -792,6 +792,11 @@ + /* Set the cursor position. */ + void gotoxy (int x, int y); + ++/* Internal pager ++ Returns 1 = if pager was used ++ 0 = if pager wasn't used */ ++int do_more (void); ++ + /* Displays an ASCII character. IBM displays will translate some + characters to special graphical ones (see the DISP_* constants). */ + void grub_putchar (int c); +@@ -871,6 +876,7 @@ + int grub_tolower (int c); + int grub_isspace (int c); + int grub_strncat (char *s1, const char *s2, int n); ++void grub_memcpy(void *dest, const void *src, int len); + void *grub_memmove (void *to, const void *from, int len); + void *grub_memset (void *start, int c, int len); + int grub_strncat (char *s1, const char *s2, int n); +diff -Naur grub-0.97.orig/stage2/stage2.c grub-0.97/stage2/stage2.c +--- grub-0.97.orig/stage2/stage2.c 2005-03-19 14:51:57.000000000 -0300 ++++ grub-0.97/stage2/stage2.c 2005-06-13 22:38:08.000000000 -0300 +@@ -20,6 +20,12 @@ + #include + #include + ++#ifdef SUPPORT_GRAPHICS ++# include ++#endif ++ ++int col_start, col_end, row_start, box_size; ++ + grub_jmp_buf restart_env; + + #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS) +@@ -105,13 +111,13 @@ + if (highlight && current_term->setcolorstate) + current_term->setcolorstate (COLOR_STATE_HIGHLIGHT); + +- gotoxy (2, y); ++ gotoxy (2 + col_start, y); + grub_putchar (' '); +- for (x = 3; x < 75; x++) ++ for (x = 3 + col_start; x < (col_end - 5); x++) + { +- if (*entry && x <= 72) ++ if (*entry && x <= (col_end - 8)) + { +- if (x == 72) ++ if (x == (col_end - 8)) + grub_putchar (DISP_RIGHT); + else + grub_putchar (*entry++); +@@ -119,7 +125,7 @@ + else + grub_putchar (' '); + } +- gotoxy (74, y); ++ gotoxy ((col_end - 6), y); + + if (current_term->setcolorstate) + current_term->setcolorstate (COLOR_STATE_STANDARD); +@@ -131,7 +137,7 @@ + { + int i; + +- gotoxy (77, y + 1); ++ gotoxy ((col_end - 3), y + 1); + + if (first) + grub_putchar (DISP_UP); +@@ -151,14 +157,14 @@ + menu_entries++; + } + +- gotoxy (77, y + size); ++ gotoxy ((col_end - 3), y + size); + + if (*menu_entries) + grub_putchar (DISP_DOWN); + else + grub_putchar (' '); + +- gotoxy (74, y + entryno + 1); ++ gotoxy ((col_end - 6), y + entryno + 1); + } + + static void +@@ -196,30 +202,30 @@ + if (current_term->setcolorstate) + current_term->setcolorstate (COLOR_STATE_NORMAL); + +- gotoxy (1, y); ++ gotoxy (1 + col_start, y); + + grub_putchar (DISP_UL); +- for (i = 0; i < 73; i++) ++ for (i = col_start; i < (col_end - 7); i++) + grub_putchar (DISP_HORIZ); + grub_putchar (DISP_UR); + + i = 1; + while (1) + { +- gotoxy (1, y + i); ++ gotoxy (1 + col_start, y + i); + + if (i > size) + break; + + grub_putchar (DISP_VERT); +- gotoxy (75, y + i); ++ gotoxy ((col_end - 5), y + i); + grub_putchar (DISP_VERT); + + i++; + } + + grub_putchar (DISP_LL); +- for (i = 0; i < 73; i++) ++ for (i = col_start; i < (col_end - 7); i++) + grub_putchar (DISP_HORIZ); + grub_putchar (DISP_LR); + +@@ -233,6 +239,7 @@ + { + int c, time1, time2 = -1, first_entry = 0; + char *cur_entry = 0; ++ struct term_entry *prev_term = NULL; + + /* + * Main loop for menu UI. +@@ -250,6 +257,22 @@ + } + } + ++ col_start = 0; ++ col_end = 80; ++ row_start = 0; ++ box_size = 12; ++ /* if we're using viewport we need to make sure to setup ++ coordinates correctly. */ ++#ifdef SUPPORT_GRAPHICS ++ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0) ++ { ++ col_start = view_x0; ++ col_end = view_x1; ++ row_start = view_y0; ++ box_size = (view_y1 - view_y0) - 13; ++ } ++#endif ++ + /* If the timeout was expired or wasn't set, force to show the menu + interface. */ + if (grub_timeout < 0) +@@ -302,36 +325,36 @@ + if (current_term->flags & TERM_DUMB) + print_entries_raw (num_entries, first_entry, menu_entries); + else +- print_border (3, 12); ++ print_border (3 + row_start, box_size); + + grub_printf ("\n\ +- Use the %c and %c keys to select which entry is highlighted.\n", ++ Use the %c and %c keys to select which entry is highlighted.\n", + DISP_UP, DISP_DOWN); + + if (! auth && password) + { + printf ("\ +- Press enter to boot the selected OS or \'p\' to enter a\n\ +- password to unlock the next set of features."); ++ Press enter to boot the selected OS or \'p\' to enter a\n\ ++ password to unlock the next set of features."); + } + else + { + if (config_entries) + printf ("\ +- Press enter to boot the selected OS, \'e\' to edit the\n\ +- commands before booting, or \'c\' for a command-line."); ++ Press enter to boot the selected OS, \'e\' to edit the\n\ ++ commands before booting, or \'c\' for a command-line."); + else + printf ("\ +- Press \'b\' to boot, \'e\' to edit the selected command in the\n\ +- boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\ +- after (\'O\' for before) the selected line, \'d\' to remove the\n\ +- selected line, or escape to go back to the main menu."); ++ Press \'b\' to boot, \'e\' to edit the selected command in the\n\ ++ boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\ ++ after (\'O\' for before) the selected line, \'d\' to remove the\n\ ++ selected line, or escape to go back to the main menu."); + } + + if (current_term->flags & TERM_DUMB) + grub_printf ("\n\nThe selected entry is %d ", entryno); + else +- print_entries (3, 12, first_entry, entryno, menu_entries); ++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); + } + + /* XX using RT clock now, need to initialize value */ +@@ -358,10 +381,10 @@ + entryno, grub_timeout); + else + { +- gotoxy (3, 22); +- grub_printf ("The highlighted entry will be booted automatically in %d seconds. ", ++ gotoxy (3 + col_start, 10 + box_size + row_start); ++ grub_printf (" The highlighted entry will be booted automatically in %d seconds. ", + grub_timeout); +- gotoxy (74, 4 + entryno); ++ gotoxy ((col_end - 6), 4 + entryno + row_start); + } + + grub_timeout--; +@@ -387,12 +410,12 @@ + if (current_term->flags & TERM_DUMB) + grub_putchar ('\r'); + else +- gotoxy (3, 22); ++ gotoxy (3 + col_start, 10 + box_size + row_start); + printf (" "); + grub_timeout = -1; + fallback_entryno = -1; + if (! (current_term->flags & TERM_DUMB)) +- gotoxy (74, 4 + entryno); ++ gotoxy ((col_end - 6), 4 + entryno + row_start); + } + + /* We told them above (at least in SUPPORT_SERIAL) to use +@@ -408,12 +431,12 @@ + { + if (entryno > 0) + { +- print_entry (4 + entryno, 0, ++ print_entry (4 + entryno + row_start, 0, + get_entry (menu_entries, + first_entry + entryno, + 0)); + entryno--; +- print_entry (4 + entryno, 1, ++ print_entry (4 + entryno + row_start, 1, + get_entry (menu_entries, + first_entry + entryno, + 0)); +@@ -421,7 +444,7 @@ + else if (first_entry > 0) + { + first_entry--; +- print_entries (3, 12, first_entry, entryno, ++ print_entries (3 + row_start, box_size, first_entry, entryno, + menu_entries); + } + } +@@ -433,29 +456,29 @@ + entryno++; + else + { +- if (entryno < 11) ++ if (entryno < (box_size - 1)) + { +- print_entry (4 + entryno, 0, ++ print_entry (4 + entryno + row_start, 0, + get_entry (menu_entries, + first_entry + entryno, + 0)); + entryno++; +- print_entry (4 + entryno, 1, ++ print_entry (4 + entryno + row_start, 1, + get_entry (menu_entries, + first_entry + entryno, + 0)); + } +- else if (num_entries > 12 + first_entry) ++ else if (num_entries > box_size + first_entry) + { + first_entry++; +- print_entries (3, 12, first_entry, entryno, menu_entries); ++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); + } + } + } + else if (c == 7) + { + /* Page Up */ +- first_entry -= 12; ++ first_entry -= box_size; + if (first_entry < 0) + { + entryno += first_entry; +@@ -463,20 +486,20 @@ + if (entryno < 0) + entryno = 0; + } +- print_entries (3, 12, first_entry, entryno, menu_entries); ++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); + } + else if (c == 3) + { + /* Page Down */ +- first_entry += 12; ++ first_entry += box_size; + if (first_entry + entryno + 1 >= num_entries) + { +- first_entry = num_entries - 12; ++ first_entry = num_entries - box_size; + if (first_entry < 0) + first_entry = 0; + entryno = num_entries - first_entry - 1; + } +- print_entries (3, 12, first_entry, entryno, menu_entries); ++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); + } + + if (config_entries) +@@ -489,7 +512,7 @@ + if ((c == 'd') || (c == 'o') || (c == 'O')) + { + if (! (current_term->flags & TERM_DUMB)) +- print_entry (4 + entryno, 0, ++ print_entry (4 + entryno + row_start, 0, + get_entry (menu_entries, + first_entry + entryno, + 0)); +@@ -537,7 +560,7 @@ + + if (entryno >= num_entries) + entryno--; +- if (first_entry && num_entries < 12 + first_entry) ++ if (first_entry && num_entries < box_size + first_entry) + first_entry--; + } + +@@ -549,7 +572,7 @@ + grub_printf ("\n"); + } + else +- print_entries (3, 12, first_entry, entryno, menu_entries); ++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); + } + + cur_entry = menu_entries; +@@ -570,7 +593,7 @@ + if (current_term->flags & TERM_DUMB) + grub_printf ("\r "); + else +- gotoxy (1, 21); ++ gotoxy (1 + col_start, 9 + box_size + row_start); + + /* Wipe out the previously entered password */ + grub_memset (entered, 0, sizeof (entered)); +@@ -714,6 +737,15 @@ + + cls (); + setcursor (1); ++ /* if our terminal needed initialization, we should shut it down ++ * before booting the kernel, but we want to save what it was so ++ * we can come back if needed */ ++ prev_term = current_term; ++ if (current_term->shutdown) ++ { ++ current_term->shutdown(); ++ current_term = term_table; /* assumption: console is first */ ++ } + + while (1) + { +@@ -748,6 +780,13 @@ + break; + } + ++ /* if we get back here, we should go back to what our term was before */ ++ current_term = prev_term; ++ if (current_term->startup) ++ /* if our terminal fails to initialize, fall back to console since ++ * it should always work */ ++ if (current_term->startup() == 0) ++ current_term = term_table; /* we know that console is first */ + show_menu = 1; + goto restart; + } +@@ -1050,6 +1089,16 @@ + while (is_preset); + } + ++ /* go ahead and make sure the terminal is setup */ ++ if (current_term->startup) ++ { ++ /* If initialization fails, go back to default terminal */ ++ if (current_term->startup() == 0) ++ { ++ current_term = term_table; ++ } ++ } ++ + if (! num_entries) + { + /* If no acceptable config file, goto command-line, starting +diff -Naur grub-0.97.orig/stage2/term.h grub-0.97/stage2/term.h +--- grub-0.97.orig/stage2/term.h 2003-07-09 08:45:53.000000000 -0300 ++++ grub-0.97/stage2/term.h 2005-06-13 14:07:40.000000000 -0300 +@@ -60,6 +60,8 @@ + const char *name; + /* The feature flags defined above. */ + unsigned long flags; ++ /* Default for maximum number of lines if not specified */ ++ unsigned short max_lines; + /* Put a character. */ + void (*putchar) (int c); + /* Check if any input character is available. */ +@@ -79,6 +81,10 @@ + void (*setcolor) (int normal_color, int highlight_color); + /* Turn on/off the cursor. */ + int (*setcursor) (int on); ++ /* function to start a terminal */ ++ int (*startup) (void); ++ /* function to use to shutdown a terminal */ ++ void (*shutdown) (void); + }; + + /* This lists up available terminals. */ +@@ -124,4 +130,24 @@ + int hercules_setcursor (int on); + #endif + ++#ifdef SUPPORT_GRAPHICS ++extern int foreground, background, window_border, graphics_inited, saved_videomode; ++ ++void graphics_set_splash(char *splashfile); ++int set_videomode(int mode); ++int get_videomode(void); ++void graphics_putchar (int c); ++int graphics_getxy(void); ++void graphics_gotoxy(int x, int y); ++void graphics_cls(void); ++void graphics_setcolorstate (color_state state); ++void graphics_setcolor (int normal_color, int highlight_color); ++int graphics_setcursor (int on); ++int graphics_init(void); ++void graphics_end(void); ++ ++int hex(int v); ++void graphics_set_palette(int idx, int red, int green, int blue); ++#endif /* SUPPORT_GRAPHICS */ ++ + #endif /* ! GRUB_TERM_HEADER */ diff --git a/stubdom/grub.patches/20print_func.diff b/stubdom/grub.patches/20print_func.diff new file mode 100644 index 0000000000..ec9da0ea4e --- /dev/null +++ b/stubdom/grub.patches/20print_func.diff @@ -0,0 +1,80 @@ +2006-01-05 Otavio Salvador + + * Rediff. + +2005-16-10 Samuel Thibault + + * docs/grub.texi: Added print command description. + * stage2/builtins.c(print_func): New function. + (builtin_print): New variable. + (builtin_table): Added builtin_print in table. + +Debian Status Following: + Added by: Otavio Salvador + Date: 2006-01-05 + +diff -Nur grub-0.97-bkp/docs/grub.texi grub-0.97/docs/grub.texi +--- grub-0.97-bkp/docs/grub.texi 2006-01-05 10:59:05.564347912 -0200 ++++ grub-0.97/docs/grub.texi 2006-01-05 11:18:59.033912960 -0200 +@@ -2685,6 +2685,7 @@ + * module:: Load a module + * modulenounzip:: Load a module without decompression + * pause:: Wait for a key press ++* print:: Print a message + * quit:: Exit from the grub shell + * reboot:: Reboot your computer + * read:: Read data from memory +@@ -3091,6 +3092,16 @@ + @end deffn + + ++@node print ++@subsection print ++ ++@deffn Command print message @dots{} ++Print the @var{message}. Note that placing @key{^G} (ASCII code 7) in the ++message will cause the speaker to emit the standard beep sound, which is ++useful for visually impaired people. ++@end deffn ++ ++ + @node quit + @subsection quit + +diff -Nur grub-0.97-bkp/stage2/builtins.c grub-0.97/stage2/builtins.c +--- grub-0.97-bkp/stage2/builtins.c 2006-01-05 10:59:05.550350040 -0200 ++++ grub-0.97/stage2/builtins.c 2006-01-05 11:19:28.422445224 -0200 +@@ -2323,6 +2323,25 @@ + "Probe I/O ports used for the drive DRIVE." + }; + ++/* print */ ++static int ++print_func (char *arg, int flags) ++{ ++ printf("%s\n", arg); ++ ++ return 0; ++} ++ ++static struct builtin builtin_print = ++{ ++ "print", ++ print_func, ++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_NO_ECHO, ++ "print [MESSAGE ...]", ++ "Print MESSAGE." ++}; ++ ++ + + /* kernel */ + static int +@@ -4848,6 +4867,7 @@ + &builtin_parttype, + &builtin_password, + &builtin_pause, ++ &builtin_print, + #ifdef GRUB_UTIL + &builtin_quit, + #endif /* GRUB_UTIL */ diff --git a/stubdom/grub.patches/30savedefault.diff b/stubdom/grub.patches/30savedefault.diff new file mode 100644 index 0000000000..2902b876ec --- /dev/null +++ b/stubdom/grub.patches/30savedefault.diff @@ -0,0 +1,186 @@ +Index: grub/stage2/builtins.c +=================================================================== +--- grub.orig/stage2/builtins.c 2008-06-02 18:06:08.942580000 +0100 ++++ grub/stage2/builtins.c 2008-06-06 18:35:07.548390000 +0100 +@@ -86,6 +86,10 @@ + inside other functions. */ + static int configfile_func (char *arg, int flags); + ++static int savedefault_helper (char *arg, int flags); ++ ++static int savedefault_shell (char *arg, int flags); ++ + /* Initialize the data for builtins. */ + void + init_builtins (void) +@@ -3512,7 +3516,109 @@ + static int + savedefault_func (char *arg, int flags) + { +-#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL) ++#if !defined(SUPPORT_DISKLESS) ++ #if !defined(GRUB_UTIL) ++ return savedefault_helper(arg, flags); ++ #else ++ return savedefault_shell(arg, flags); ++ #endif ++#else /* !SUPPORT_DISKLESS */ ++ errnum = ERR_UNRECOGNIZED; ++ return 1; ++#endif /* !SUPPORT_DISKLESS */ ++} ++ ++#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL) ++/* savedefault_shell */ ++static int ++savedefault_shell(char *arg, int flags) ++ { ++ int once_only = 0; ++ int new_default; ++ int curr_default = -1; ++ int curr_prev_default = -1; ++ int new_prev_default = -1; ++ FILE *fp; ++ size_t bytes = 10; ++ char line[bytes]; ++ char *default_file = (char *) DEFAULT_FILE_BUF; ++ char buf[bytes]; ++ int i; ++ ++ while (1) ++ { ++ if (grub_memcmp ("--default=", arg, sizeof ("--default=") - 1) == 0) ++ { ++ char *p = arg + sizeof ("--default=") - 1; ++ if (! safe_parse_maxint (&p, &new_default)) ++ return 1; ++ arg = skip_to (0, arg); ++ } ++ else if (grub_memcmp ("--once", arg, sizeof ("--once") - 1) == 0) ++ { ++ once_only = 1; ++ arg = skip_to (0, arg); ++ } ++ else ++ break; ++ } ++ ++ *default_file = 0; ++ grub_strncat (default_file, config_file, DEFAULT_FILE_BUFLEN); ++ for (i = grub_strlen(default_file); i >= 0; i--) ++ if (default_file[i] == '/') ++ { ++ i++; ++ break; ++ } ++ default_file[i] = 0; ++ grub_strncat (default_file + i, "default", DEFAULT_FILE_BUFLEN - i); ++ ++ if(!(fp = fopen(default_file,"r"))) ++ { ++ errnum = ERR_READ; ++ goto fail; ++ } ++ ++ fgets(line, bytes, fp); ++ fclose(fp); ++ ++ sscanf(line, "%d:%d", &curr_prev_default, &curr_default); ++ ++ if(curr_default != -1) ++ new_prev_default = curr_default; ++ else ++ { ++ if(curr_prev_default != -1) ++ new_prev_default = curr_prev_default; ++ else ++ new_prev_default = 0; ++ } ++ ++ if(once_only) ++ sprintf(buf, "%d:%d", new_prev_default, new_default); ++ else ++ sprintf(buf, "%d", new_default); ++ ++ if(!(fp = fopen(default_file,"w"))) ++ { ++ errnum = ERR_READ; ++ goto fail; ++ } ++ ++ fprintf(fp, buf); ++ ++fail: ++ fclose(fp); ++ return errnum; ++} ++#endif ++ ++/* savedefault_helper */ ++static int ++savedefault_helper (char *arg, int flags) ++{ ++#if !defined(SUPPORT_DISKLESS) + unsigned long tmp_drive = saved_drive; + unsigned long tmp_partition = saved_partition; + char *default_file = (char *) DEFAULT_FILE_BUF; +@@ -3588,22 +3694,26 @@ + + disk_read_hook = disk_read_savesect_func; + len = grub_read (buf, sizeof (buf)); ++ buf[9]='\0';/* Make sure grub_strstr() below terminates */ + disk_read_hook = 0; + grub_close (); + +- if (len != sizeof (buf)) +- { +- /* This is too small. Do not modify the file manually, please! */ +- errnum = ERR_READ; +- goto fail; +- } +- + if (sector_count > 2) + { + /* Is this possible?! Too fragmented! */ + errnum = ERR_FSYS_CORRUPT; + goto fail; + } ++ ++ char *tmp; ++ if((tmp = grub_strstr(buf, ":")) != NULL) ++ { ++ int f_len = grub_strlen(buf) - grub_strlen(tmp); ++ char *def; ++ buf[f_len] = '\0'; ++ def = buf; ++ safe_parse_maxint (&def, &entryno); ++ } + + /* Set up a string to be written. */ + grub_memset (buf, '\n', sizeof (buf)); +Index: grub/stage2/stage2.c +=================================================================== +--- grub.orig/stage2/stage2.c 2008-06-02 18:06:08.858579000 +0100 ++++ grub/stage2/stage2.c 2008-06-06 18:04:03.585354000 +0100 +@@ -49,7 +49,8 @@ + return 0; + #endif /* GRUB_UTIL */ + +- preset_menu_offset = 0; ++ if (preset_menu_offset) ++ return 0; + return preset_menu != 0; + } + +@@ -934,7 +935,11 @@ + len = grub_read (buf, sizeof (buf)); + if (len > 0) + { ++ char *tmp; + buf[sizeof (buf) - 1] = 0; ++ if((tmp = grub_strstr(p, ":")) != NULL) ++ p = tmp + 1; ++ + safe_parse_maxint (&p, &saved_entryno); + } + diff --git a/stubdom/grub.patches/40ext3_256byte_inode.diff b/stubdom/grub.patches/40ext3_256byte_inode.diff new file mode 100644 index 0000000000..0c40854f94 --- /dev/null +++ b/stubdom/grub.patches/40ext3_256byte_inode.diff @@ -0,0 +1,114 @@ + +Patch from Red Hat. See #463236, #463123. + +Index: grub/stage2/fsys_ext2fs.c +=================================================================== +--- grub.orig/stage2/fsys_ext2fs.c 2008-05-27 18:47:19.045183000 +0100 ++++ grub/stage2/fsys_ext2fs.c 2008-05-27 19:09:21.293187000 +0100 +@@ -79,7 +79,52 @@ + __u32 s_rev_level; /* Revision level */ + __u16 s_def_resuid; /* Default uid for reserved blocks */ + __u16 s_def_resgid; /* Default gid for reserved blocks */ +- __u32 s_reserved[235]; /* Padding to the end of the block */ ++ /* ++ * These fields are for EXT2_DYNAMIC_REV superblocks only. ++ * ++ * Note: the difference between the compatible feature set and ++ * the incompatible feature set is that if there is a bit set ++ * in the incompatible feature set that the kernel doesn't ++ * know about, it should refuse to mount the filesystem. ++ * ++ * e2fsck's requirements are more strict; if it doesn't know ++ * about a feature in either the compatible or incompatible ++ * feature set, it must abort and not try to meddle with ++ * things it doesn't understand... ++ */ ++ __u32 s_first_ino; /* First non-reserved inode */ ++ __u16 s_inode_size; /* size of inode structure */ ++ __u16 s_block_group_nr; /* block group # of this superblock */ ++ __u32 s_feature_compat; /* compatible feature set */ ++ __u32 s_feature_incompat; /* incompatible feature set */ ++ __u32 s_feature_ro_compat; /* readonly-compatible feature set */ ++ __u8 s_uuid[16]; /* 128-bit uuid for volume */ ++ char s_volume_name[16]; /* volume name */ ++ char s_last_mounted[64]; /* directory where last mounted */ ++ __u32 s_algorithm_usage_bitmap; /* For compression */ ++ /* ++ * Performance hints. Directory preallocation should only ++ * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on. ++ */ ++ __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ ++ __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ ++ __u16 s_reserved_gdt_blocks;/* Per group table for online growth */ ++ /* ++ * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set. ++ */ ++ __u8 s_journal_uuid[16]; /* uuid of journal superblock */ ++ __u32 s_journal_inum; /* inode number of journal file */ ++ __u32 s_journal_dev; /* device number of journal file */ ++ __u32 s_last_orphan; /* start of list of inodes to delete */ ++ __u32 s_hash_seed[4]; /* HTREE hash seed */ ++ __u8 s_def_hash_version; /* Default hash version to use */ ++ __u8 s_jnl_backup_type; /* Default type of journal backup */ ++ __u16 s_reserved_word_pad; ++ __u32 s_default_mount_opts; ++ __u32 s_first_meta_bg; /* First metablock group */ ++ __u32 s_mkfs_time; /* When the filesystem was created */ ++ __u32 s_jnl_blocks[17]; /* Backup of the journal inode */ ++ __u32 s_reserved[172]; /* Padding to the end of the block */ + }; + + struct ext2_group_desc +@@ -218,6 +263,9 @@ + #define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32)) + #define EXT2_ADDR_PER_BLOCK_BITS(s) (log2(EXT2_ADDR_PER_BLOCK(s))) + ++#define EXT2_INODE_SIZE(s) (SUPERBLOCK->s_inode_size) ++#define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s)) ++ + /* linux/ext2_fs.h */ + #define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) + /* kind of from ext2/super.c */ +@@ -242,7 +290,14 @@ + static __inline__ unsigned long + ffz (unsigned long word) + { +- __asm__ ("bsfl %1,%0" ++ __asm__ ("bsf" ++#ifdef __i386__ ++ "l" ++#endif ++#ifdef __x86_64__ ++ "q" ++#endif ++ " %1,%0" + : "=r" (word) + : "r" (~word)); + return word; +@@ -553,7 +608,7 @@ + gdp = GROUP_DESC; + ino_blk = gdp[desc].bg_inode_table + + (((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group)) +- >> log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode))); ++ >> log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK))); + #ifdef E2DEBUG + printf ("inode table fsblock=%d\n", ino_blk); + #endif /* E2DEBUG */ +@@ -565,13 +620,12 @@ + /* reset indirect blocks! */ + mapblock2 = mapblock1 = -1; + +- raw_inode = INODE + +- ((current_ino - 1) +- & (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode) - 1)); ++ raw_inode = (struct ext2_inode *)((char *)INODE + ++ ((current_ino - 1) & (EXT2_INODES_PER_BLOCK (SUPERBLOCK) - 1)) * ++ EXT2_INODE_SIZE (SUPERBLOCK)); + #ifdef E2DEBUG + printf ("ipb=%d, sizeof(inode)=%d\n", +- (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)), +- sizeof (struct ext2_inode)); ++ EXT2_INODES_PER_BLOCK (SUPERBLOCK), EXT2_INODE_SIZE (SUPERBLOCK)); + printf ("inode=%x, raw_inode=%x\n", INODE, raw_inode); + printf ("offset into inode table block=%d\n", (int) raw_inode - (int) INODE); + for (i = (unsigned char *) INODE; i <= (unsigned char *) raw_inode; diff --git a/stubdom/grub.patches/99minios b/stubdom/grub.patches/99minios new file mode 100644 index 0000000000..3efc57177c --- /dev/null +++ b/stubdom/grub.patches/99minios @@ -0,0 +1,1456 @@ +Index: grub/stage2/builtins.c +=================================================================== +--- grub.orig/stage2/builtins.c 2008-06-16 15:18:14.649009000 +0100 ++++ grub/stage2/builtins.c 2008-06-16 15:18:14.719009000 +0100 +@@ -45,8 +45,10 @@ + #ifdef GRUB_UTIL + # include + #else /* ! GRUB_UTIL */ ++#ifndef __MINIOS + # include + # include ++#endif + #endif /* ! GRUB_UTIL */ + + #ifdef USE_MD5_PASSWORDS +@@ -246,11 +248,13 @@ + boot_func (char *arg, int flags) + { + struct term_entry *prev_term = current_term; ++#ifndef __MINIOS__ + /* Clear the int15 handler if we can boot the kernel successfully. + This assumes that the boot code never fails only if KERNEL_TYPE is + not KERNEL_TYPE_NONE. Is this assumption is bad? */ + if (kernel_type != KERNEL_TYPE_NONE) + unset_int15_handler (); ++#endif + + /* if our terminal needed initialization, we should shut it down + * before booting the kernel, but we want to save what it was so +@@ -261,13 +265,21 @@ + current_term = term_table; /* assumption: console is first */ + } + ++#ifndef __MINIOS__ + #ifdef SUPPORT_NETBOOT + /* Shut down the networking. */ + cleanup_net (); + #endif ++#endif + + switch (kernel_type) + { ++#ifdef __MINIOS__ ++ case KERNEL_TYPE_PV: ++ /* Paravirtualized */ ++ pv_boot(); ++ break; ++#else + case KERNEL_TYPE_FREEBSD: + case KERNEL_TYPE_NETBSD: + /* *BSD */ +@@ -319,6 +331,7 @@ + multi_boot ((int) entry_addr, (int) &mbi); + break; + ++#endif + default: + errnum = ERR_BOOT_COMMAND; + return 1; +@@ -1123,6 +1136,7 @@ + }; + + ++#ifndef __MINIOS__ + /* displayapm */ + static int + displayapm_func (char *arg, int flags) +@@ -1163,8 +1177,10 @@ + "displayapm", + "Display APM BIOS information." + }; ++#endif + + ++#ifndef __MINIOS__ + /* displaymem */ + static int + displaymem_func (char *arg, int flags) +@@ -1218,6 +1234,7 @@ + "Display what GRUB thinks the system address space map of the" + " machine is, including all regions of physical RAM installed." + }; ++#endif + + + /* dump FROM TO */ +@@ -1280,6 +1297,7 @@ + #endif /* GRUB_UTIL */ + + ++#ifndef __MINIOS__ + static char embed_info[32]; + /* embed */ + /* Embed a Stage 1.5 in the first cylinder after MBR or in the +@@ -1413,6 +1431,7 @@ + " is a drive, or in the \"bootloader\" area if DEVICE is a FFS partition." + " Print the number of sectors which STAGE1_5 occupies if successful." + }; ++#endif + + + /* fallback */ +@@ -1956,6 +1975,7 @@ + #endif /* SUPPORT_NETBOOT */ + + ++#ifndef __MINIOS__ + /* impsprobe */ + static int + impsprobe_func (char *arg, int flags) +@@ -1982,6 +2002,7 @@ + " configuration table and boot the various CPUs which are found into" + " a tight loop." + }; ++#endif + + + /* initrd */ +@@ -1992,6 +2013,7 @@ + { + case KERNEL_TYPE_LINUX: + case KERNEL_TYPE_BIG_LINUX: ++ case KERNEL_TYPE_PV: + if (! load_initrd (arg)) + return 1; + break; +@@ -2015,6 +2037,7 @@ + }; + + ++#ifndef __MINIOS__ + /* install */ + static int + install_func (char *arg, int flags) +@@ -2555,8 +2578,10 @@ + " for LBA mode. If the option `--stage2' is specified, rewrite the Stage" + " 2 via your OS's filesystem instead of the raw device." + }; ++#endif + + ++#ifndef __MINIOS__ + /* ioprobe */ + static int + ioprobe_func (char *arg, int flags) +@@ -2598,6 +2623,7 @@ + "ioprobe DRIVE", + "Probe I/O ports used for the drive DRIVE." + }; ++#endif + + /* print */ + static int +@@ -3776,6 +3802,7 @@ + }; + + ++#ifndef __MINIOS__ + #ifdef SUPPORT_SERIAL + /* serial */ + static int +@@ -3927,8 +3954,10 @@ + " default values are COM1, 9600, 8N1." + }; + #endif /* SUPPORT_SERIAL */ ++#endif + + ++#ifndef __MINIOS__ + /* setkey */ + struct keysym + { +@@ -4174,8 +4203,10 @@ + " is a digit), and delete. If no argument is specified, reset key" + " mappings." + }; ++#endif + + ++#ifndef __MINIOS__ + /* setup */ + static int + setup_func (char *arg, int flags) +@@ -4484,6 +4515,7 @@ + " partition where GRUB images reside, specify the option `--stage2'" + " to tell GRUB the file name under your OS." + }; ++#endif + + + #if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS) +@@ -4788,6 +4820,7 @@ + #endif /* SUPPORT_SERIAL */ + + ++#ifndef __MINIOS__ + /* testload */ + static int + testload_func (char *arg, int flags) +@@ -4874,8 +4907,10 @@ + " consistent offset error. If this test succeeds, then a good next" + " step is to try loading a kernel." + }; ++#endif + + ++#ifndef __MINIOS__ + /* testvbe MODE */ + static int + testvbe_func (char *arg, int flags) +@@ -4979,6 +5014,7 @@ + "testvbe MODE", + "Test the VBE mode MODE. Hit any key to return." + }; ++#endif + + + #ifdef SUPPORT_NETBOOT +@@ -5075,6 +5111,7 @@ + }; + + ++#ifndef __MINIOS__ + /* uppermem */ + static int + uppermem_func (char *arg, int flags) +@@ -5095,8 +5132,10 @@ + "Force GRUB to assume that only KBYTES kilobytes of upper memory are" + " installed. Any system address range maps are discarded." + }; ++#endif + + ++#ifndef __MINIOS__ + /* vbeprobe */ + static int + vbeprobe_func (char *arg, int flags) +@@ -5203,6 +5242,7 @@ + "Probe VBE information. If the mode number MODE is specified, show only" + " the information about only the mode." + }; ++#endif + + + /* The table of builtin commands. Sorted in dictionary order. */ +@@ -5233,12 +5273,16 @@ + #ifdef SUPPORT_NETBOOT + &builtin_dhcp, + #endif /* SUPPORT_NETBOOT */ ++#ifndef __MINIOS__ + &builtin_displayapm, + &builtin_displaymem, ++#endif + #ifdef GRUB_UTIL + &builtin_dump, + #endif /* GRUB_UTIL */ ++#ifndef __MINIOS__ + &builtin_embed, ++#endif + &builtin_fallback, + &builtin_find, + #ifdef SUPPORT_GRAPHICS +@@ -5253,10 +5297,14 @@ + #ifdef SUPPORT_NETBOOT + &builtin_ifconfig, + #endif /* SUPPORT_NETBOOT */ ++#ifndef __MINIOS__ + &builtin_impsprobe, ++#endif + &builtin_initrd, ++#ifndef __MINIOS__ + &builtin_install, + &builtin_ioprobe, ++#endif + &builtin_kernel, + &builtin_lock, + &builtin_makeactive, +@@ -5283,11 +5331,13 @@ + &builtin_root, + &builtin_rootnoverify, + &builtin_savedefault, ++#ifndef __MINIOS__ + #ifdef SUPPORT_SERIAL + &builtin_serial, + #endif /* SUPPORT_SERIAL */ + &builtin_setkey, + &builtin_setup, ++#endif + #ifdef SUPPORT_GRAPHICS + &builtin_shade, + &builtin_splashimage, +@@ -5298,16 +5348,20 @@ + #ifdef SUPPORT_SERIAL + &builtin_terminfo, + #endif /* SUPPORT_SERIAL */ ++#ifndef __MINIOS__ + &builtin_testload, + &builtin_testvbe, ++#endif + #ifdef SUPPORT_NETBOOT + &builtin_tftpserver, + #endif /* SUPPORT_NETBOOT */ + &builtin_timeout, + &builtin_title, + &builtin_unhide, ++#ifndef __MINIOS__ + &builtin_uppermem, + &builtin_vbeprobe, ++#endif + #ifdef SUPPORT_GRAPHICS + &builtin_viewport, + #endif +Index: grub/stage2/char_io.c +=================================================================== +--- grub.orig/stage2/char_io.c 2008-06-16 15:18:14.516009000 +0100 ++++ grub/stage2/char_io.c 2008-06-16 15:18:14.726009000 +0100 +@@ -20,6 +20,7 @@ + + #include + #include ++#include + + #ifdef SUPPORT_HERCULES + # include +@@ -36,6 +37,7 @@ + #ifndef STAGE1_5 + struct term_entry term_table[] = + { ++#ifdef SUPPORT_CONSOLE + { + "console", + 0, +@@ -52,6 +54,7 @@ + 0, + 0 + }, ++#endif + #ifdef SUPPORT_SERIAL + { + "serial", +@@ -131,9 +134,9 @@ + } + + char * +-convert_to_ascii (char *buf, int c,...) ++convert_to_ascii (char *buf, int c, int _num) + { +- unsigned long num = *((&c) + 1), mult = 10; ++ unsigned long num = _num, mult = 10; + char *ptr = buf; + + #ifndef STAGE1_5 +@@ -182,11 +185,11 @@ + void + grub_printf (const char *format,...) + { +- int *dataptr = (int *) &format; ++ va_list ap; + char c, str[16]; +- +- dataptr++; + ++ va_start(ap, format); ++ + while ((c = *(format++)) != 0) + { + if (c != '%') +@@ -200,21 +203,32 @@ + case 'X': + #endif + case 'u': +- *convert_to_ascii (str, c, *((unsigned long *) dataptr++)) = 0; ++ { ++ unsigned i = va_arg(ap, unsigned); ++ *convert_to_ascii (str, c, i) = 0; + grub_putstr (str); + break; ++ } + + #ifndef STAGE1_5 + case 'c': +- grub_putchar ((*(dataptr++)) & 0xff); ++ { ++ int c = va_arg(ap, int); ++ grub_putchar (c & 0xff); + break; ++ } + + case 's': +- grub_putstr ((char *) *(dataptr++)); ++ { ++ char *s = va_arg(ap, char*); ++ grub_putstr (s); + break; ++ } + #endif + } + } ++ ++ va_end(ap); + } + + #ifndef STAGE1_5 +@@ -223,11 +237,11 @@ + { + /* XXX hohmuth + ugly hack -- should unify with printf() */ +- int *dataptr = (int *) &format; ++ va_list ap; + char c, *ptr, str[16]; + char *bp = buffer; + +- dataptr++; ++ va_start(ap, format); + + while ((c = *format++) != 0) + { +@@ -237,20 +251,27 @@ + switch (c = *(format++)) + { + case 'd': case 'u': case 'x': +- *convert_to_ascii (str, c, *((unsigned long *) dataptr++)) = 0; ++ { ++ unsigned i = va_arg(ap, unsigned); ++ *convert_to_ascii (str, c, i) = 0; + + ptr = str; + + while (*ptr) + *bp++ = *(ptr++); /* putchar(*(ptr++)); */ + break; ++ } + +- case 'c': *bp++ = (*(dataptr++))&0xff; ++ case 'c': ++ { ++ int c = va_arg(ap, int); ++ *bp++ = c&0xff; + /* putchar((*(dataptr++))&0xff); */ + break; ++ } + + case 's': +- ptr = (char *) (*(dataptr++)); ++ ptr = va_arg(ap, char *); + + while ((c = *ptr++) != 0) + *bp++ = c; /* putchar(c); */ +@@ -258,6 +279,8 @@ + } + } + ++ va_end(ap); ++ + *bp = 0; + return bp - buffer; + } +@@ -1263,12 +1286,14 @@ + return ! errnum; + #endif /* GRUB_UTIL */ + ++#ifndef __MINIOS__ + if ((addr < RAW_ADDR (0x1000)) + || (addr < RAW_ADDR (0x100000) + && RAW_ADDR (mbi.mem_lower * 1024) < (addr + len)) + || (addr >= RAW_ADDR (0x100000) + && RAW_ADDR (mbi.mem_upper * 1024) < ((addr - 0x100000) + len))) + errnum = ERR_WONT_FIT; ++#endif + + return ! errnum; + } +@@ -1342,7 +1367,7 @@ + } + #endif /* ! STAGE1_5 */ + +-#ifndef GRUB_UTIL ++#if !defined(GRUB_UTIL) && !defined(__MINIOS__) + # undef memcpy + /* GCC emits references to memcpy() for struct copies etc. */ + void *memcpy (void *dest, const void *src, int n) __attribute__ ((alias ("grub_memmove"))); +Index: grub/stage2/disk_io.c +=================================================================== +--- grub.orig/stage2/disk_io.c 2008-06-16 15:18:03.327932000 +0100 ++++ grub/stage2/disk_io.c 2008-06-16 15:18:14.733009000 +0100 +@@ -130,7 +130,14 @@ + static inline unsigned long + log2 (unsigned long word) + { +- asm volatile ("bsfl %1,%0" ++ asm volatile ("bsf" ++#ifdef __i386__ ++ "l" ++#endif ++#ifdef __x86_64__ ++ "q" ++#endif ++ " %1,%0" + : "=r" (word) + : "r" (word)); + return word; +Index: grub/stage2/fsys_fat.c +=================================================================== +--- grub.orig/stage2/fsys_fat.c 2008-06-16 15:18:03.337934000 +0100 ++++ grub/stage2/fsys_fat.c 2008-06-16 15:18:14.737009000 +0100 +@@ -57,7 +57,14 @@ + static __inline__ unsigned long + log2 (unsigned long word) + { +- __asm__ ("bsfl %1,%0" ++ __asm__ ("bsf" ++#ifdef __i386__ ++ "l" ++#endif ++#ifdef __x86_64__ ++ "q" ++#endif ++ " %1,%0" + : "=r" (word) + : "r" (word)); + return word; +Index: grub/stage2/pc_slice.h +=================================================================== +--- grub.orig/stage2/pc_slice.h 2008-06-16 15:18:03.347932000 +0100 ++++ grub/stage2/pc_slice.h 2008-06-16 15:18:14.746009000 +0100 +@@ -38,50 +38,50 @@ + */ + + #define PC_MBR_CHECK_SIG(mbr_ptr) \ +- ( *( (unsigned short *) (((int) mbr_ptr) + PC_MBR_SIG_OFFSET) ) \ ++ ( *( (unsigned short *) (((long) mbr_ptr) + PC_MBR_SIG_OFFSET) ) \ + == PC_MBR_SIGNATURE ) + + #define PC_MBR_SIG(mbr_ptr) \ +- ( *( (unsigned short *) (((int) mbr_ptr) + PC_MBR_SIG_OFFSET) ) ) ++ ( *( (unsigned short *) (((long) mbr_ptr) + PC_MBR_SIG_OFFSET) ) ) + + #define PC_SLICE_FLAG(mbr_ptr, part) \ +- ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET \ ++ ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET \ + + (part << 4)) ) ) + + #define PC_SLICE_HEAD(mbr_ptr, part) \ +- ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 1 \ ++ ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 1 \ + + (part << 4)) ) ) + + #define PC_SLICE_SEC(mbr_ptr, part) \ +- ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 2 \ ++ ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 2 \ + + (part << 4)) ) ) + + #define PC_SLICE_CYL(mbr_ptr, part) \ +- ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 3 \ ++ ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 3 \ + + (part << 4)) ) ) + + #define PC_SLICE_TYPE(mbr_ptr, part) \ +- ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 4 \ ++ ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 4 \ + + (part << 4)) ) ) + + #define PC_SLICE_EHEAD(mbr_ptr, part) \ +- ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 5 \ ++ ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 5 \ + + (part << 4)) ) ) + + #define PC_SLICE_ESEC(mbr_ptr, part) \ +- ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 6 \ ++ ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 6 \ + + (part << 4)) ) ) + + #define PC_SLICE_ECYL(mbr_ptr, part) \ +- ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 7 \ ++ ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 7 \ + + (part << 4)) ) ) + + #define PC_SLICE_START(mbr_ptr, part) \ +- ( *( (unsigned long *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 8 \ ++ ( *( (unsigned long *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 8 \ + + (part << 4)) ) ) + + #define PC_SLICE_LENGTH(mbr_ptr, part) \ +- ( *( (unsigned long *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 12 \ ++ ( *( (unsigned long *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 12 \ + + (part << 4)) ) ) + + +Index: grub/stage2/shared.h +=================================================================== +--- grub.orig/stage2/shared.h 2008-06-16 15:18:14.537009000 +0100 ++++ grub/stage2/shared.h 2008-06-17 14:25:08.443906000 +0100 +@@ -39,6 +39,10 @@ + extern char *grub_scratch_mem; + # define RAW_ADDR(x) ((x) + (int) grub_scratch_mem) + # define RAW_SEG(x) (RAW_ADDR ((x) << 4) >> 4) ++#elif defined(__MINIOS__) ++extern char grub_scratch_mem[]; ++# define RAW_ADDR(x) ((x) + (int) grub_scratch_mem) ++# define RAW_SEG(x) (RAW_ADDR ((x) << 4) >> 4) + #else + # define RAW_ADDR(x) (x) + # define RAW_SEG(x) (x) +@@ -707,7 +711,9 @@ + + /* Halt the system, using APM if possible. If NO_APM is true, don't use + APM even if it is available. */ ++#ifndef __MINIOS__ + void grub_halt (int no_apm) __attribute__ ((noreturn)); ++#endif + + /* Copy MAP to the drive map and set up int13_handler. */ + void set_int13_handler (unsigned short *map); +@@ -857,7 +863,8 @@ + KERNEL_TYPE_BIG_LINUX, /* Big Linux. */ + KERNEL_TYPE_FREEBSD, /* FreeBSD. */ + KERNEL_TYPE_NETBSD, /* NetBSD. */ +- KERNEL_TYPE_CHAINLOADER /* Chainloader. */ ++ KERNEL_TYPE_CHAINLOADER, /* Chainloader. */ ++ KERNEL_TYPE_PV /* Paravirtualized. */ + } + kernel_t; + +@@ -890,7 +897,7 @@ + int grub_strlen (const char *str); + char *grub_strcpy (char *dest, const char *src); + +-#ifndef GRUB_UTIL ++#if !defined(GRUB_UTIL) && !defined(__MINIOS__) + typedef unsigned long grub_jmp_buf[6]; + #else + /* In the grub shell, use the libc jmp_buf instead. */ +@@ -898,7 +905,7 @@ + # define grub_jmp_buf jmp_buf + #endif + +-#ifdef GRUB_UTIL ++#if defined(GRUB_UTIL) || defined(__MINIOS__) + # define grub_setjmp setjmp + # define grub_longjmp longjmp + #else /* ! GRUB_UTIL */ +@@ -914,7 +921,7 @@ + /* misc */ + void init_page (void); + void print_error (void); +-char *convert_to_ascii (char *buf, int c, ...); ++char *convert_to_ascii (char *buf, int c, int num); + int get_cmdline (char *prompt, char *cmdline, int maxlen, + int echo_char, int history); + int substring (const char *s1, const char *s2); +Index: grub/netboot/etherboot.h +=================================================================== +--- grub.orig/netboot/etherboot.h 2008-06-16 15:18:03.446934000 +0100 ++++ grub/netboot/etherboot.h 2008-06-16 15:18:14.760009000 +0100 +@@ -246,7 +246,7 @@ + + typedef struct + { +- unsigned long s_addr; ++ unsigned int s_addr; + } + in_addr; + +@@ -302,7 +302,7 @@ + char bp_htype; + char bp_hlen; + char bp_hops; +- unsigned long bp_xid; ++ unsigned int bp_xid; + unsigned short bp_secs; + unsigned short unused; + in_addr bp_ciaddr; +@@ -411,25 +411,25 @@ + + struct + { +- long id; +- long type; +- long rpcvers; +- long prog; +- long vers; +- long proc; +- long data[1]; ++ int id; ++ int type; ++ int rpcvers; ++ int prog; ++ int vers; ++ int proc; ++ int data[1]; + } + call; + + struct + { +- long id; +- long type; +- long rstatus; +- long verifier; +- long v2; +- long astatus; +- long data[1]; ++ int id; ++ int type; ++ int rstatus; ++ int verifier; ++ int v2; ++ int astatus; ++ int data[1]; + } + reply; + } +@@ -517,7 +517,9 @@ + + /* misc.c */ + extern void twiddle (void); ++#ifndef __MINIOS__ + extern void sleep (int secs); ++#endif + extern int getdec (char **s); + extern void etherboot_printf (const char *, ...); + extern int etherboot_sprintf (char *, const char *, ...); +Index: grub/stage2/common.c +=================================================================== +--- grub.orig/stage2/common.c 2008-06-16 15:18:03.366934000 +0100 ++++ grub/stage2/common.c 2008-06-16 15:18:14.764009000 +0100 +@@ -137,6 +137,7 @@ + } + #endif /* ! STAGE1_5 */ + ++#ifndef __MINIOS__ + /* This queries for BIOS information. */ + void + init_bios_info (void) +@@ -335,3 +336,4 @@ + /* Start main routine here. */ + cmain (); + } ++#endif +Index: grub/stage2/serial.c +=================================================================== +--- grub.orig/stage2/serial.c 2008-06-16 15:18:03.376934000 +0100 ++++ grub/stage2/serial.c 2008-06-16 15:18:14.769009000 +0100 +@@ -37,7 +37,7 @@ + + /* Hardware-dependent definitions. */ + +-#ifndef GRUB_UTIL ++#if !defined(GRUB_UTIL) && !defined(__MINIOS__) + /* The structure for speed vs. divisor. */ + struct divisor + { +@@ -222,6 +222,8 @@ + {('3' | ('~' << 8)), 4}, + {('5' | ('~' << 8)), 7}, + {('6' | ('~' << 8)), 3}, ++ {('7' | ('~' << 8)), 1}, ++ {('8' | ('~' << 8)), 5}, + }; + + /* The buffer must start with ``ESC [''. */ +Index: grub/stage2/tparm.c +=================================================================== +--- grub.orig/stage2/tparm.c 2008-06-16 15:18:03.390933000 +0100 ++++ grub/stage2/tparm.c 2008-06-16 15:18:14.774010000 +0100 +@@ -48,6 +48,7 @@ + #include "shared.h" + + #include "tparm.h" ++#include + + /* + * Common/troublesome character definitions +@@ -320,7 +321,7 @@ + #define isLOWER(c) ((c) >= 'a' && (c) <= 'z') + + static inline char * +-tparam_internal(const char *string, int *dataptr) ++tparam_internal(const char *string, va_list ap) + { + #define NUM_VARS 26 + char *p_is_s[9]; +@@ -461,9 +462,9 @@ + * a char* and an int may not be the same size on the stack. + */ + if (p_is_s[i] != 0) { +- p_is_s[i] = (char *)(*(dataptr++)); ++ p_is_s[i] = va_arg(ap, char *); + } else { +- param[i] = (int)(*(dataptr++)); ++ param[i] = va_arg(ap, int); + } + } + +@@ -716,11 +717,13 @@ + grub_tparm(const char *string,...) + { + char *result; +- int *dataptr = (int *) &string; ++ va_list ap; + +- dataptr++; ++ va_start(ap, string); + +- result = tparam_internal(string, dataptr); ++ result = tparam_internal(string, ap); ++ ++ va_end(ap); + + return result; + } +Index: grub/stage2/fsys_iso9660.c +=================================================================== +--- grub.orig/stage2/fsys_iso9660.c 2008-06-16 15:18:03.400933000 +0100 ++++ grub/stage2/fsys_iso9660.c 2008-06-16 15:18:14.779009000 +0100 +@@ -59,7 +59,14 @@ + static inline unsigned long + log2 (unsigned long word) + { +- asm volatile ("bsfl %1,%0" ++ asm volatile ("bsf" ++#ifdef __i386__ ++ "l" ++#endif ++#ifdef __x86_64__ ++ "q" ++#endif ++ " %1,%0" + : "=r" (word) + : "r" (word)); + return word; +Index: grub/stage2/fsys_reiserfs.c +=================================================================== +--- grub.orig/stage2/fsys_reiserfs.c 2008-06-16 15:18:03.410933000 +0100 ++++ grub/stage2/fsys_reiserfs.c 2008-06-16 15:18:14.786009000 +0100 +@@ -369,7 +369,14 @@ + static __inline__ unsigned long + log2 (unsigned long word) + { +- __asm__ ("bsfl %1,%0" ++ __asm__ ("bsf" ++#ifdef __i386__ ++ "l" ++#endif ++#ifdef __x86_64__ ++ "q" ++#endif ++ " %1,%0" + : "=r" (word) + : "r" (word)); + return word; +Index: grub/netboot/misc.c +=================================================================== +--- grub.orig/netboot/misc.c 2008-06-16 15:18:03.456934000 +0100 ++++ grub/netboot/misc.c 2008-06-16 15:18:14.790009000 +0100 +@@ -21,7 +21,9 @@ + + #define GRUB 1 + #include ++#include + ++#ifndef __MINIOS__ + void + sleep (int secs) + { +@@ -30,6 +32,7 @@ + while (currticks () < tmo) + ; + } ++#endif + + void + twiddle (void) +@@ -71,7 +74,7 @@ + Note: width specification not supported + **************************************************************************/ + static int +-etherboot_vsprintf (char *buf, const char *fmt, const int *dp) ++etherboot_vsprintf (char *buf, const char *fmt, va_list ap) + { + char *p, *s; + +@@ -86,7 +89,7 @@ + + if (*++fmt == 's') + { +- for (p = (char *) *dp++; *p != '\0'; p++) ++ for (p = va_arg(ap, char *); *p != '\0'; p++) + buf ? *s++ = *p : grub_putchar (*p); + } + else +@@ -121,11 +124,9 @@ + if ((*fmt | 0x20) == 'x') + { + /* With x86 gcc, sizeof(long) == sizeof(int) */ +- const long *lp = (const long *) dp; +- long h = *lp++; ++ long h = va_arg(ap, int); + int ncase = (*fmt & 0x20); + +- dp = (const int *) lp; + if (alt) + { + *q++ = '0'; +@@ -136,7 +137,7 @@ + } + else if (*fmt == 'd') + { +- int i = *dp++; ++ int i = va_arg(ap, int); + char *r; + + if (i < 0) +@@ -171,10 +172,8 @@ + unsigned char c[4]; + } + u; +- const long *lp = (const long *) dp; + +- u.l = *lp++; +- dp = (const int *) lp; ++ u.l = va_arg(ap, int); + + for (r = &u.c[0]; r < &u.c[4]; ++r) + q += etherboot_sprintf (q, "%d.", *r); +@@ -184,7 +183,7 @@ + else if (*fmt == '!') + { + char *r; +- p = (char *) *dp++; ++ p = va_arg(ap, char *); + + for (r = p + ETH_ALEN; p < r; ++p) + q += etherboot_sprintf (q, "%hhX:", *p); +@@ -192,7 +191,7 @@ + --q; + } + else if (*fmt == 'c') +- *q++ = *dp++; ++ *q++ = va_arg(ap, int); + else + *q++ = *fmt; + +@@ -211,13 +210,21 @@ + int + etherboot_sprintf (char *buf, const char *fmt, ...) + { +- return etherboot_vsprintf (buf, fmt, ((const int *) &fmt) + 1); ++ va_list ap; ++ int ret; ++ va_start(ap, fmt); ++ ret = etherboot_vsprintf (buf, fmt, ap); ++ va_end(ap); ++ return ret; + } + + void + etherboot_printf (const char *fmt, ...) + { +- (void) etherboot_vsprintf (0, fmt, ((const int *) &fmt) + 1); ++ va_list ap; ++ va_start(ap, fmt); ++ etherboot_vsprintf (0, fmt, ap); ++ va_end(ap); + } + + int +Index: grub/netboot/main.c +=================================================================== +--- grub.orig/netboot/main.c 2008-06-16 15:18:03.470932000 +0100 ++++ grub/netboot/main.c 2008-06-16 15:18:14.797009000 +0100 +@@ -55,7 +55,7 @@ + static int vendorext_isvalid; + static unsigned long netmask; + static struct bootpd_t bootp_data; +-static unsigned long xid; ++static unsigned int xid; + + #define BOOTP_DATA_ADDR (&bootp_data) + +@@ -778,7 +778,7 @@ + + arpreply = (struct arprequest *) &nic.packet[ETH_HLEN]; + +- if (arpreply->opcode == htons (ARP_REPLY) ++ if (arpreply->opcode == htons (ARP_REPLY) && ptr + && ! grub_memcmp (arpreply->sipaddr, ptr, sizeof (in_addr)) + && type == AWAIT_ARP) + { +@@ -827,7 +827,7 @@ + { + arpreply = (struct arprequest *) &nic.packet[ETH_HLEN]; + +- if (arpreply->opcode == htons (RARP_REPLY) ++ if (arpreply->opcode == htons (RARP_REPLY) && ptr + && ! grub_memcmp (arpreply->thwaddr, ptr, ETH_ALEN)) + { + grub_memmove ((char *) arptable[ARP_SERVER].node, +@@ -1135,7 +1135,7 @@ + long + rfc2131_sleep_interval (int base, int exp) + { +- static long seed = 0; ++ static unsigned seed = 0; + long q; + unsigned long tmo; + +Index: grub/stage2/graphics.c +=================================================================== +--- grub.orig/stage2/graphics.c 2008-06-16 15:18:14.524009000 +0100 ++++ grub/stage2/graphics.c 2008-06-17 14:29:05.204328000 +0100 +@@ -30,7 +30,29 @@ + #include + #include + ++#ifdef __MINIOS__ ++#include ++typedef uint8_t Bit8u; ++#include ++#include ++#include ++#define set_int1c_handler() (void)0 ++#define unset_int1c_handler() (void)0 ++static uint32_t *VIDEOMEM; ++static struct fbfront_dev *fb_dev; ++static uint32_t palette[17]; ++short cursorX, cursorY; ++/* TODO: blink */ ++uint32_t cursorBuf32[16*8]; ++#define WIDTH 640 ++#define HEIGHT 480 ++#define DEPTH 32 ++#define RAMSIZE (WIDTH * HEIGHT * (DEPTH / 8)) ++#else ++#define fbfront_update(dev, x, y, w, h) (void)0 + int saved_videomode; ++#endif ++ + unsigned char *font8x16; + + int graphics_inited = 0; +@@ -38,11 +60,15 @@ + + int shade = 1, no_cursor = 0; + ++#ifdef __MINIOS__ ++uint32_t VSHADOW[RAMSIZE]; ++#else + #define VSHADOW VSHADOW1 + unsigned char VSHADOW1[38400]; + unsigned char VSHADOW2[38400]; + unsigned char VSHADOW4[38400]; + unsigned char VSHADOW8[38400]; ++#endif + + /* define the default viewable area */ + int view_x0 = 0; +@@ -129,6 +155,8 @@ + count_lines = k; + + no_scroll = 0; ++ ++ fbfront_update(fb_dev, view_x0 * 8, view_y0 * 16, (view_x1 - view_x0) * 8, (view_y1 - view_y0) * 16); + } + + /* Set the splash image */ +@@ -154,17 +182,29 @@ + int graphics_init() + { + if (!graphics_inited) { ++#ifdef __MINIOS__ ++ VIDEOMEM = memalign(PAGE_SIZE, RAMSIZE); ++ if (!(fb_dev = fb_open(VIDEOMEM, WIDTH, HEIGHT, DEPTH))) { ++ free(VIDEOMEM); ++ return 0; ++ } ++#else + saved_videomode = set_videomode(0x12); + if (get_videomode() != 0x12) { + set_videomode(saved_videomode); + return 0; + } ++#endif + graphics_inited = 1; + } + else + return 1; + ++#ifdef __MINIOS__ ++ font8x16 = vgafont16; ++#else + font8x16 = (unsigned char*)graphics_get_font(); ++#endif + + /* make sure that the highlight color is set correctly */ + graphics_highlight_color = ((graphics_normal_color >> 4) | +@@ -176,7 +216,11 @@ + grub_printf("Failed to read splash image (%s)\n", splashimage); + grub_printf("Press any key to continue..."); + getkey(); ++#ifdef __MINIOS__ ++ fb_close(); ++#else + set_videomode(saved_videomode); ++#endif + graphics_inited = 0; + return 0; + } +@@ -190,8 +234,13 @@ + void graphics_end(void) + { + if (graphics_inited) { ++#ifdef __MINIOS__ ++ fb_close(); ++ free(VIDEOMEM); ++#else + unset_int1c_handler(); + set_videomode(saved_videomode); ++#endif + graphics_inited = 0; + no_cursor = 0; + } +@@ -204,15 +253,19 @@ + graphics_cursor(0); + + if (ch == '\n') { ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + if (fonty + 1 < view_y1) + graphics_setxy(fontx, fonty + 1); + else + graphics_scroll(); + graphics_cursor(1); ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + return; + } else if (ch == '\r') { ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + graphics_setxy(view_x0, fonty); + graphics_cursor(1); ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + return; + } + +@@ -224,6 +277,7 @@ + text[fonty * 80 + fontx] |= 0x100; + + graphics_cursor(0); ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + + if ((fontx + 1) >= view_x1) { + graphics_setxy(view_x0, fonty); +@@ -232,13 +286,16 @@ + else + graphics_scroll(); + graphics_cursor(1); ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + do_more (); + graphics_cursor(0); ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + } else { + graphics_setxy(fontx + 1, fonty); + } + + graphics_cursor(1); ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + } + + /* get the current location of the cursor */ +@@ -248,10 +305,12 @@ + + void graphics_gotoxy(int x, int y) { + graphics_cursor(0); ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + + graphics_setxy(x, y); + + graphics_cursor(1); ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + } + + void graphics_cls(void) { +@@ -262,15 +321,21 @@ + graphics_gotoxy(view_x0, view_y0); + + mem = (unsigned char*)VIDEOMEM; ++#ifndef __MINIOS__ + s1 = (unsigned char*)VSHADOW1; + s2 = (unsigned char*)VSHADOW2; + s4 = (unsigned char*)VSHADOW4; + s8 = (unsigned char*)VSHADOW8; ++#endif + + for (i = 0; i < 80 * 30; i++) + text[i] = ' '; + graphics_cursor(1); + ++#ifdef __MINIOS__ ++ memcpy(mem, VSHADOW, RAMSIZE); ++ fbfront_update(fb_dev, 0, 0, 640, 480); ++#else + BitMask(0xff); + + /* plane 1 */ +@@ -290,6 +355,7 @@ + grub_memcpy(mem, s8, 38400); + + MapMask(15); ++#endif + + if (no_cursor) { + no_cursor = 0; +@@ -337,6 +403,11 @@ + return 0; + } + ++void graphics_set_palette(int idx, int red, int green, int blue) ++{ ++ palette[idx] = (red << (16 + 2)) | (green << (8 + 2)) | (blue << 2); ++} ++ + /* Read in the splashscreen image and set the palette up appropriately. + * Format of splashscreen is an xpm (can be gzipped) with 16 colors and + * 640x480. */ +@@ -413,18 +484,19 @@ + } + + if (len == 6 && idx < 15) { +- int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2; +- int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2; +- int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2; ++ int r = ((hex(buf[0]) << 4) | hex(buf[1])); ++ int g = ((hex(buf[2]) << 4) | hex(buf[3])); ++ int b = ((hex(buf[4]) << 4) | hex(buf[5])); + + pal[idx] = base; +- graphics_set_palette(idx, r, g, b); ++ graphics_set_palette(idx, r / 4, g / 4, b / 4); + ++idx; + } + } + + x = y = len = 0; + ++#ifndef __MINIOS__ + s1 = (unsigned char*)VSHADOW1; + s2 = (unsigned char*)VSHADOW2; + s4 = (unsigned char*)VSHADOW4; +@@ -432,6 +504,7 @@ + + for (i = 0; i < 38400; i++) + s1[i] = s2[i] = s4[i] = s8[i] = 0; ++#endif + + /* parse xpm data */ + while (y < height) { +@@ -451,6 +524,9 @@ + break; + } + ++#ifdef __MINIOS__ ++ VSHADOW[x + y * 640] = palette[i]; ++#else + mask = 0x80 >> (x & 7); + if (c & 1) + s1[len + (x >> 3)] |= mask; +@@ -460,6 +536,7 @@ + s4[len + (x >> 3)] |= mask; + if (c & 8) + s8[len + (x >> 3)] |= mask; ++#endif + + if (++x >= 640) { + x = 0; +@@ -494,7 +571,13 @@ + } + + void graphics_cursor(int set) { +- unsigned char *pat, *mem, *ptr, chr[16 << 2]; ++ unsigned char *pat; ++#ifdef __MINIOS__ ++ uint32_t *mem, *ptr, chr[16 * 8]; ++ int j; ++#else ++ unsigned char *mem, *ptr, chr[16 << 2]; ++#endif + int i, ch, invert, offset; + + if (set && (no_cursor || no_scroll)) +@@ -505,71 +588,127 @@ + invert = (text[fonty * 80 + fontx] & 0xff00) != 0; + pat = font8x16 + (ch << 4); + +- mem = (unsigned char*)VIDEOMEM + offset; ++ mem = (unsigned char*)VIDEOMEM + offset ++#ifdef __MINIOS__ ++ * 8 * 4 ++#endif ++ ; + + if (!set) { + for (i = 0; i < 16; i++) { + unsigned char mask = pat[i]; + + if (!invert) { ++#ifdef __MINIOS__ ++ memcpy(chr + i * 8, VSHADOW + offset * 8, 8 * 4); ++#else + chr[i ] = ((unsigned char*)VSHADOW1)[offset]; + chr[16 + i] = ((unsigned char*)VSHADOW2)[offset]; + chr[32 + i] = ((unsigned char*)VSHADOW4)[offset]; + chr[48 + i] = ((unsigned char*)VSHADOW8)[offset]; ++#endif + + if (shade) { + if (ch == DISP_VERT || ch == DISP_LL || + ch == DISP_UR || ch == DISP_LR) { + unsigned char pmask = ~(pat[i] >> 1); + ++#ifdef __MINIOS__ ++ for (j = 0; j < 8; j++) ++ if (!(pmask & (1U << j))) ++ chr[i * 8 + (7 - j)] = palette[0]; ++#else + chr[i ] &= pmask; + chr[16 + i] &= pmask; + chr[32 + i] &= pmask; + chr[48 + i] &= pmask; ++#endif + } + if (i > 0 && ch != DISP_VERT) { + unsigned char pmask = ~(pat[i - 1] >> 1); + ++#ifdef __MINIOS__ ++ for (j = 0; j < 8; j++) ++ if (!(pmask & (1U << j))) ++ chr[i * 8 + (7 - j)] = palette[0]; ++#else + chr[i ] &= pmask; + chr[16 + i] &= pmask; + chr[32 + i] &= pmask; + chr[48 + i] &= pmask; ++#endif + if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) { + pmask = ~pat[i - 1]; + ++#ifdef __MINIOS__ ++ for (j = 0; j < 8; j++) ++ if (!(pmask & (1U << j))) ++ chr[i * 8 + (7 - j)] = palette[0]; ++#else + chr[i ] &= pmask; + chr[16 + i] &= pmask; + chr[32 + i] &= pmask; + chr[48 + i] &= pmask; ++#endif + } + } + } ++#ifdef __MINIOS__ ++ for (j = 0; j < 8; j++) ++ if (mask & (1U << j)) ++ chr[i * 8 + (7 - j)] = palette[15]; ++#else + chr[i ] |= mask; + chr[16 + i] |= mask; + chr[32 + i] |= mask; + chr[48 + i] |= mask; ++#endif + + offset += 80; + } + else { ++#ifdef __MINIOS__ ++ for (j = 0; j < 8; j++) ++ if (mask & (1U << j)) ++ chr[i * 8 + (7 - j)] = palette[15]; ++ else ++ chr[i * 8 + (7 - j)] = palette[0]; ++#else + chr[i ] = mask; + chr[16 + i] = mask; + chr[32 + i] = mask; + chr[48 + i] = mask; ++#endif + } + } + } + else { ++#ifdef __MINIOS__ ++ ptr = mem; ++ for (i = 0; i < 16; i++, ptr += 80 * 8) ++ for (j = 0; j < 8; j++) { ++ if (pat[i] & (1U << (7 - j))) ++ cursorBuf32[i * 8 + j] = ptr[j] = palette[0]; ++ else ++ cursorBuf32[i * 8 + j] = ptr[j] = palette[15]; ++ } ++#else + MapMask(15); + ptr = mem; + for (i = 0; i < 16; i++, ptr += 80) { + cursorBuf[i] = pat[i]; + *ptr = ~pat[i]; + } ++#endif + return; + } + + offset = 0; ++#ifdef __MINIOS__ ++ ptr = mem; ++ for (j = 0; j < 16; j++, ptr += 80 * 8) ++ memcpy(ptr, chr + j * 8 + offset * 8, 8 * 4); ++#else + for (i = 1; i < 16; i <<= 1, offset += 16) { + int j; + +@@ -580,6 +719,7 @@ + } + + MapMask(15); ++#endif + } + + #endif /* SUPPORT_GRAPHICS */ +Index: grub/stage2/graphics.h +=================================================================== +--- grub.orig/stage2/graphics.h 2008-06-16 15:18:14.527010000 +0100 ++++ grub/stage2/graphics.h 2008-06-16 15:18:14.805010000 +0100 +@@ -21,8 +21,10 @@ + #ifndef GRAPHICS_H + #define GRAPHICS_H + ++#ifndef __MINIOS__ + /* magic constant */ + #define VIDEOMEM 0xA0000 ++#endif + + /* function prototypes */ + char *graphics_get_splash(void); +Index: grub/stage2/stage2.c +=================================================================== +--- grub.orig/stage2/stage2.c 2008-06-17 11:06:47.873523000 +0100 ++++ grub/stage2/stage2.c 2008-06-17 11:07:05.225628000 +0100 +@@ -31,10 +31,10 @@ + #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS) + + # if defined(PRESET_MENU_STRING) +-static const char *preset_menu = PRESET_MENU_STRING; ++const char *preset_menu = PRESET_MENU_STRING; + # elif defined(SUPPORT_DISKLESS) + /* Execute the command "bootp" automatically. */ +-static const char *preset_menu = "bootp\n"; ++const char *preset_menu = "bootp\n"; + # endif /* SUPPORT_DISKLESS */ + + static int preset_menu_offset; -- cgit v1.2.3