diff options
Diffstat (limited to 'sys-boot/grub/files/grub-0.97-gfxmenu-v8.patch')
-rw-r--r-- | sys-boot/grub/files/grub-0.97-gfxmenu-v8.patch | 1003 |
1 files changed, 0 insertions, 1003 deletions
diff --git a/sys-boot/grub/files/grub-0.97-gfxmenu-v8.patch b/sys-boot/grub/files/grub-0.97-gfxmenu-v8.patch deleted file mode 100644 index 7921fc82..00000000 --- a/sys-boot/grub/files/grub-0.97-gfxmenu-v8.patch +++ /dev/null @@ -1,1003 +0,0 @@ -diff -Nurp grub-0.97.orig/docs/grub.texi grub-0.97/docs/grub.texi ---- grub-0.97.orig/docs/grub.texi 2009-08-03 16:25:36.636294219 +0200 -+++ grub-0.97/docs/grub.texi 2009-08-03 16:25:52.207398764 +0200 -@@ -2118,6 +2118,7 @@ These commands can only be used in the m - * default:: Set the default entry - * fallback:: Set the fallback entry - * hiddenmenu:: Hide the menu interface -+* gfxmenu:: Use graphical menu interface - * timeout:: Set the timeout - * title:: Start a menu entry - @end menu -@@ -2150,6 +2151,15 @@ fallback entry numbers. - @end deffn - - -+@node gfxmenu -+@subsection gfxmenu -+ -+@deffn Command gfxmenu file -+Use the graphical menu interface. The graphics data are taken from -+@var{file} and must be created using 'mkbootmsg' from the gfxboot package. -+@end deffn -+ -+ - @node hiddenmenu - @subsection hiddenmenu - -diff -Nurp grub-0.97.orig/grub/asmstub.c grub-0.97/grub/asmstub.c ---- grub-0.97.orig/grub/asmstub.c 2009-08-03 16:25:36.483169221 +0200 -+++ grub-0.97/grub/asmstub.c 2009-08-03 16:25:52.217342924 +0200 -@@ -480,6 +480,32 @@ set_vbe_mode (int mode_number) - return 0; - } - -+/* graphical menu functions . */ -+int -+gfx_init (gfx_data_t *gfx_data) -+{ -+ return 0; -+} -+ -+int -+gfx_done (gfx_data_t *gfx_data) -+{ -+ return 0; -+} -+ -+int -+gfx_input (gfx_data_t *gfx_data, int *menu_entry) -+{ -+ return 0; -+} -+ -+int -+gfx_setup_menu (gfx_data_t *gfx_data) -+{ -+ return 0; -+} -+ -+ - /* low-level timing info */ - int - getrtsecs (void) -diff -Nurp grub-0.97.orig/stage2/asm.S grub-0.97/stage2/asm.S ---- grub-0.97.orig/stage2/asm.S 2004-06-19 18:55:22.000000000 +0200 -+++ grub-0.97/stage2/asm.S 2009-08-03 16:25:52.218406926 +0200 -@@ -1610,6 +1610,286 @@ ENTRY(set_vbe_mode) - popl %ebp - ret - -+ -+/* -+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ * -+ * graphical menu functions -+ * -+ */ -+ -+/* -+ * int gfx_init (gfx_data_t *gfx_data) -+ * -+ * init gfx things -+ * -+ * return vales: -+ * 0: ok -+ * 1: failed -+ * sets gfx_data->ok -+ */ -+ -+ENTRY(gfx_init) -+ pushl %ebp -+ movl %esp, %ebp -+ -+ pushl %edi -+ pushl %esi -+ pushl %ebx -+ -+ movl 8(%ebp),%edx -+ movl %edx,%edi -+ leal gfx_ofs_sys_cfg(%edx),%esi -+ andl $0xf,%edi -+ shrl $4,%edx -+ -+ pushl %ebp -+ -+ call EXT_C(prot_to_real) -+ .code16 -+ -+ pushw %ds -+ movw %dx,%ds -+ -+ lcall *gfx_ofs_jmp_table + 4 * 0 (%di) -+ -+ sbbl %ebx,%ebx -+ negl %ebx -+ -+ popw %ds -+ -+ DATA32 call EXT_C(real_to_prot) -+ .code32 -+ -+ popl %ebp -+ -+ movl %ebx,%eax -+ xorl $1,%ebx -+ movl 8(%ebp),%edx -+ movl %ebx,gfx_ofs_ok(%edx) -+ -+ popl %ebx -+ popl %esi -+ popl %edi -+ -+ popl %ebp -+ ret -+ -+ -+/* -+ * int gfx_done (gfx_data_t *gfx_data) -+ * -+ * shut down gfx things -+ * -+ * return vales: -+ * always 0 -+ * sets gfx_data->ok -+ */ -+ -+ENTRY(gfx_done) -+ pushl %ebp -+ movl %esp, %ebp -+ -+ pushl %edi -+ pushl %esi -+ pushl %ebx -+ -+ movl 8(%ebp),%edx -+ movl %edx,%ebx -+ andl $0xf,%ebx -+ shrl $4,%edx -+ -+ pushl %ebp -+ -+ call EXT_C(prot_to_real) -+ .code16 -+ -+ pushw %ds -+ -+ movw %dx,%ds -+ -+ lcall *gfx_ofs_jmp_table + 4 * 1 (%bx) -+ -+ popw %ds -+ -+ DATA32 call EXT_C(real_to_prot) -+ .code32 -+ -+ popl %ebp -+ -+ xorl %eax,%eax -+ movl 8(%ebp),%edx -+ movl %eax,gfx_ofs_ok(%edx) -+ -+ popl %ebx -+ popl %esi -+ popl %edi -+ -+ popl %ebp -+ ret -+ -+ -+/* -+ * int gfx_input (gfx_data_t *gfx_data, int *menu_entry) -+ * -+ * let user enter a command line -+ * -+ * uses gfx_data->cmdline as buffer -+ * -+ * return values: -+ * 1: abort -+ * 2: boot -+ * menu_entry: selected entry -+ */ -+ -+ENTRY(gfx_input) -+ pushl %ebp -+ movl %esp, %ebp -+ -+ pushl %edi -+ pushl %esi -+ pushl %ebx -+ -+ movl 8(%ebp),%edx -+ movl %edx,%ebx -+ leal gfx_ofs_sys_cfg(%edx),%esi -+ andl $0xf,%ebx -+ shrl $4,%edx -+ -+ pushl %ebp -+ -+ call EXT_C(prot_to_real) -+ .code16 -+ -+ pushw %ds -+ -+ movw %dx,%ds -+ -+ movl gfx_ofs_cmdline(%bx),%edi -+ movl gfx_ofs_cmdline_len(%bx),%ecx -+ movl gfx_ofs_timeout(%bx),%eax -+ imull $18,%eax -+ -+ lcall *gfx_ofs_jmp_table + 4 * 2 (%bx) -+ -+ movl %eax,%ecx -+ -+ popw %ds -+ -+ DATA32 call EXT_C(real_to_prot) -+ .code32 -+ -+ popl %ebp -+ -+ movl 12(%ebp),%edx -+ movl %ebx,(%edx) -+ -+ movl %ecx,%eax -+ -+ popl %ebx -+ popl %esi -+ popl %edi -+ -+ popl %ebp -+ ret -+ -+ -+/* -+ * int gfx_setup_menu (gfx_data_t *gfx_data) -+ * -+ * draw boot menu -+ * -+ * return values: -+ * always 0 -+ */ -+ -+/* menu entry descriptor */ -+#define menu_entries 0 -+#define menu_default 2 /* seg:ofs */ -+#define menu_ent_list 6 /* seg:ofs */ -+#define menu_ent_size 10 -+#define menu_arg_list 12 /* seg:ofs */ -+#define menu_arg_size 16 -+#define sizeof_menu_desc 18 -+ -+ENTRY(gfx_setup_menu) -+ pushl %ebp -+ movl %esp, %ebp -+ -+ pushl %edi -+ pushl %esi -+ pushl %ebx -+ -+ movl 8(%ebp),%edx -+ movl %edx,%ebx -+ andl $0xf,%ebx -+ shrl $4,%edx -+ -+ call EXT_C(prot_to_real) -+ .code16 -+ -+ pushw %ds -+ -+ movw %dx,%ds -+ shll $4,%edx -+ -+ subw $sizeof_menu_desc,%sp -+ movw %esp,%ebp -+ -+ movl gfx_ofs_menu_entries(%bx),%eax -+ movw %ax,menu_entries(%bp) -+ -+ movl gfx_ofs_menu_default_entry(%bx),%eax -+ subl %edx,%eax -+ movw %ax,menu_default(%bp) -+ movw %ds,menu_default+2(%bp) -+ -+ movl gfx_ofs_menu_list(%bx),%eax -+ subl %edx,%eax -+ movw %ax,menu_ent_list(%bp) -+ movw %ds,menu_ent_list+2(%bp) -+ -+ movl gfx_ofs_menu_entry_len(%bx),%eax -+ movw %ax,menu_ent_size(%bp) -+ -+ movl gfx_ofs_args_list(%bx),%eax -+ subl %edx,%eax -+ movw %ax,menu_arg_list(%bp) -+ movw %ds,menu_arg_list+2(%bp) -+ -+ movl gfx_ofs_args_entry_len(%bx),%eax -+ movw %ax,menu_arg_size(%bp) -+ -+ movl %ss,%esi -+ shll $4,%esi -+ addl %ebp,%esi -+ -+ lcall %ds: *gfx_ofs_jmp_table + 4 * 3 (%bx) -+ -+ addw $sizeof_menu_desc,%sp -+ -+ popw %ds -+ -+ DATA32 call EXT_C(real_to_prot) -+ .code32 -+ -+ xorl %eax,%eax -+ -+ popl %ebx -+ popl %esi -+ popl %edi -+ -+ popl %ebp -+ ret -+ -+ -+/* -+ * -+ * end graphics stuff -+ * -+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ */ -+ - - /* - * gateA20(int linear) -diff -Nurp grub-0.97.orig/stage2/builtins.c grub-0.97/stage2/builtins.c ---- grub-0.97.orig/stage2/builtins.c 2009-08-03 16:25:36.601273171 +0200 -+++ grub-0.97/stage2/builtins.c 2009-08-03 16:25:52.219523396 +0200 -@@ -67,6 +67,8 @@ int fallback_entryno; - int fallback_entries[MAX_FALLBACK_ENTRIES]; - /* The number of current entry. */ - int current_entryno; -+/* graphics file */ -+char graphics_file[64]; - /* The address for Multiboot command-line buffer. */ - static char *mb_cmdline; - /* The password. */ -@@ -1335,6 +1337,26 @@ static struct builtin builtin_fstest = - }; - - -+/* graphics */ -+static int -+gfxmenu_func (char *arg, int flags) -+{ -+ memmove(graphics_file, arg, sizeof graphics_file - 1); -+ graphics_file[sizeof graphics_file - 1] = 0; -+ -+ return 0; -+} -+ -+static struct builtin builtin_gfxmenu = -+{ -+ "gfxmenu", -+ gfxmenu_func, -+ BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "gfxmenu FILE", -+ "Use the graphical menu from FILE." -+}; -+ -+ - /* geometry */ - static int - geometry_func (char *arg, int flags) -@@ -4989,6 +5011,7 @@ struct builtin *builtin_table[] = - &builtin_find, - &builtin_fstest, - &builtin_geometry, -+ &builtin_gfxmenu, - &builtin_halt, - &builtin_help, - &builtin_hiddenmenu, -diff -Nurp grub-0.97.orig/stage2/shared.h grub-0.97/stage2/shared.h ---- grub-0.97.orig/stage2/shared.h 2004-06-19 18:40:09.000000000 +0200 -+++ grub-0.97/stage2/shared.h 2009-08-03 16:25:52.219523396 +0200 -@@ -374,6 +374,22 @@ extern char *grub_scratch_mem; - #endif /* WITHOUT_LIBC_STUBS */ - - -+/* see typedef gfx_data_t below */ -+#define gfx_ofs_ok 0x00 -+#define gfx_ofs_code_seg 0x04 -+#define gfx_ofs_jmp_table 0x08 -+#define gfx_ofs_sys_cfg 0x38 -+#define gfx_ofs_cmdline 0x6c -+#define gfx_ofs_cmdline_len 0x70 -+#define gfx_ofs_menu_list 0x74 -+#define gfx_ofs_menu_default_entry 0x78 -+#define gfx_ofs_menu_entries 0x7c -+#define gfx_ofs_menu_entry_len 0x80 -+#define gfx_ofs_args_list 0x84 -+#define gfx_ofs_args_entry_len 0x88 -+#define gfx_ofs_timeout 0x8c -+ -+ - #ifndef ASM_FILE - /* - * Below this should be ONLY defines and other constructs for C code. -@@ -595,6 +611,38 @@ extern int fallback_entryno; - extern int default_entry; - extern int current_entryno; - -+ -+/* -+ * graphics menu stuff -+ * -+ * Note: gfx_data and all data referred to in it must lie within a 64k area. -+ */ -+typedef struct { -+ unsigned ok; /* set while we're in graphics mode */ -+ unsigned code_seg; /* code segment of binary graphics code */ -+ unsigned jmp_table[12]; /* link to graphics functions */ -+ unsigned char sys_cfg[52]; /* sys_cfg[0]: identifies boot loader (grub == 2) */ -+ char *cmdline; /* command line returned by gfx_input() */ -+ unsigned cmdline_len; /* length of the above */ -+ char *menu_list; /* list of menu entries, each of fixed length (menu_entry_len) */ -+ char *menu_default_entry; /* the default entry */ -+ unsigned menu_entries; /* number of entries in menu_list */ -+ unsigned menu_entry_len; /* one entry */ -+ char *args_list; /* same structure as menu_list, menu_entries entries */ -+ unsigned args_entry_len; /* one entry */ -+ unsigned timeout; /* in seconds (0: no timeout) */ -+} __attribute__ ((packed)) gfx_data_t; -+ -+extern gfx_data_t *graphics_data; -+ -+/* pointer to graphics image data */ -+extern char graphics_file[64]; -+ -+int gfx_init(gfx_data_t *gfx_data); -+int gfx_done(gfx_data_t *gfx_data); -+int gfx_input(gfx_data_t *gfx_data, int *menu_entry); -+int gfx_setup_menu(gfx_data_t *gfx_data); -+ - /* The constants for password types. */ - typedef enum - { -diff -Nurp grub-0.97.orig/stage2/stage2.c grub-0.97/stage2/stage2.c ---- grub-0.97.orig/stage2/stage2.c 2005-03-19 18:51:57.000000000 +0100 -+++ grub-0.97/stage2/stage2.c 2009-08-03 16:25:52.220523160 +0200 -@@ -22,6 +22,8 @@ - - grub_jmp_buf restart_env; - -+gfx_data_t *graphics_data; -+ - #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS) - - # if defined(PRESET_MENU_STRING) -@@ -310,6 +312,12 @@ restart: - - if (! auth && password) - { -+ if (*graphics_file) -+ { -+ printf ("\ -+ WARNING: graphical menu doesn\'t work\ -+ in conjunction with the password feature\n" ); -+ } - printf ("\ - Press enter to boot the selected OS or \'p\' to enter a\n\ - password to unlock the next set of features."); -@@ -753,6 +761,496 @@ restart: - } - - -+ -+#if 0 -+/* for debugging */ -+static void hexdump(unsigned char *buf, unsigned len) -+{ -+ int i, j = 0; -+ char s[17]; -+ unsigned addr = (unsigned) buf; -+ -+ s[16] = 0; -+ while(len--) { -+ i = buf[j]; -+ i = i & 0xff; -+ s[j & 15] = (i >= 0x20 && i <= 0x7e) ? i : '.'; -+ if(!(j & 15)) { -+ printf("%x ", j + addr); -+ } -+ if(!(j & 7) && (j & 15)) printf(" "); -+ /* stupid grub_printf */ -+ printf("%x", (i >> 4) & 0x0f); -+ printf("%x ", i & 0x0f); -+ if(!(++j & 15)) { -+ printf(" %s\n", s); -+ } -+ } -+ -+ if(j & 15) { -+ s[j & 15] = 0; -+ if(!(j & 8)) printf(" "); -+ i = 1 + 3 * (16 - (j & 15)); -+ while(i--) printf(" "); -+ printf("%s\n", s); -+ } -+} -+#endif -+ -+ -+/* kernel + (grub-)module options */ -+#define GFX_CMD_BUF_SIZE 512 -+ -+/* command line separator char */ -+#define GFX_CMD_SEP 1 -+ -+/* -+ * Go through config entry and find kernel args, if any. -+ * Put things into buf and return it. -+ */ -+static char *get_kernel_args(char *cfg, char *buf) -+{ -+ int i, j; -+ char *s, *t = "", *p, *t2; -+ -+ *(p = buf) = 0; -+ -+ for(j = 0; ; j++) { -+ s = get_entry(cfg, j, 0); -+ if(!*s) break; -+ if( -+ (!memcmp(s, "kernel", 6) || !memcmp(s, "module", 6)) && -+ (s[6] == ' ' || s[6] == '\t') -+ ) { -+ t = skip_to(0, s); -+ t2 = s[0] == 'm' ? strstr(t, "initrd") : NULL; -+ if(*t) t = skip_to(0, t); -+ if(t2 && t2 < t) break; /* module is likely a normal initrd -> skip */ -+ i = strlen(t); -+ if(p - buf + i > GFX_CMD_BUF_SIZE - 2) break; -+ *p++ = GFX_CMD_SEP; -+ strcpy(p, t); -+ p += i; -+ -+ continue; -+ } -+ } -+ -+ if(*buf) buf++; /* skip initial separator char */ -+ -+ return buf; -+} -+ -+ -+/* -+ * Check header and return code start offset. -+ */ -+static unsigned magic_ok(unsigned char *buf) -+{ -+ if( -+ *(unsigned *) buf == 0x0b2d97f00 && /* magic id */ -+ (buf[4] == 8) /* version 8 */ -+ ) { -+ return *(unsigned *) (buf + 8); -+ } -+ -+ return 0; -+} -+ -+ -+/* -+ * Search cpio archive for gfx file. -+ */ -+static unsigned find_file(unsigned char *buf, unsigned len, unsigned *gfx_file_start, unsigned *file_len) -+{ -+ unsigned i, fname_len, code_start = 0; -+ -+ *gfx_file_start = 0; -+ -+ for(i = 0; i < len;) { -+ if((len - i) >= 0x1a && (buf[i] + (buf[i + 1] << 8)) == 0x71c7) { -+ fname_len = *(unsigned short *) (buf + i + 20); -+ *file_len = *(unsigned short *) (buf + i + 24) + (*(unsigned short *) (buf + i + 22) << 16); -+ i += 26 + fname_len; -+ i = ((i + 1) & ~1); -+ if((code_start = magic_ok(buf + i))) { -+ *gfx_file_start = i; -+ return code_start; -+ } -+ i += *file_len; -+ i = ((i + 1) & ~1); -+ } -+ else { -+ break; -+ } -+ } -+ -+ return code_start; -+} -+ -+static inline unsigned char * stack_ptr(void) -+{ -+ unsigned char * u; -+ -+ asm("movl %%esp, %0" : "=r" (u)); -+ -+ return u; -+} -+ -+static void sleep(int delay) -+{ -+ int tick, last_tick = currticks(); -+ -+ delay *= 18; -+ -+ while(delay--) { -+ while((tick = currticks()) == last_tick) { } -+ last_tick = tick; -+ } -+} -+ -+static void wait_for_key() -+{ -+ printf("Press a key to continue..."); -+ getkey(); -+ printf("\r \r"); -+} -+ -+ -+/* -+ * Leave that much space on the heap. Everything else goes to the graphics -+ * functions. -+ * -+ * 0x2000 is _not_ enough -+ */ -+#define MIN_HEAP_SIZE 0x4000 -+#define MIN_GFX_FREE 0x1000 -+ -+#define SC_BOOTLOADER 0 -+#define SC_FAILSAFE 3 -+#define SC_SYSCONFIG_SIZE 4 -+#define SC_BOOTLOADER_SEG 8 -+#define SC_XMEM_0 24 -+#define SC_XMEM_1 26 -+#define SC_XMEM_2 28 -+#define SC_XMEM_3 30 -+#define SC_FILE 32 -+#define SC_ARCHIVE_START 36 -+#define SC_ARCHIVE_END 40 -+#define SC_MEM0_START 44 -+#define SC_MEM0_END 48 -+ -+/* -+ * Does normally not return. -+ */ -+static void -+run_graphics_menu (char *menu_entries, char *config_entries, int num_entries, -+ char *heap, int entryno) -+{ -+ unsigned char *buf, *buf_ext; -+ unsigned buf_size, buf_ext_size, code_start, file_start; -+ char *s, *t, *t2, *cfg, *new_config, *p; -+ char *saved_heap; -+ int i, j, max_len, gfx_file_size, verbose; -+ int selected_entry; -+ gfx_data_t *gfx_data; -+ char *cmd_buf; -+ unsigned mem0_start, mem0_end, file_len; -+ -+ /* -+ * check gfx_data_t struct offsets for consistency; gcc will optimize away -+ * the whole block -+ */ -+ -+ /* dummy function to make ld fail */ -+ { -+ extern void wrong_struct_size(void); -+ #define gfx_ofs_check(a) if(gfx_ofs_##a != (char *) &gfx_data->a - (char *) gfx_data) wrong_struct_size(); -+ gfx_ofs_check(ok); -+ gfx_ofs_check(code_seg); -+ gfx_ofs_check(jmp_table); -+ gfx_ofs_check(sys_cfg); -+ gfx_ofs_check(cmdline); -+ gfx_ofs_check(cmdline_len); -+ gfx_ofs_check(menu_list); -+ gfx_ofs_check(menu_default_entry); -+ gfx_ofs_check(menu_entries); -+ gfx_ofs_check(menu_entry_len); -+ gfx_ofs_check(args_list); -+ gfx_ofs_check(args_entry_len); -+ gfx_ofs_check(timeout); -+ #undef gfx_ofs_check -+ } -+ -+ if(!num_entries) return; -+ -+ graphics_data = gfx_data = (gfx_data_t *) heap; -+ heap += sizeof *gfx_data; -+ memset(gfx_data, 0, sizeof *gfx_data); -+ -+ gfx_data->sys_cfg[SC_BOOTLOADER] = 2; /* bootloader: grub */ -+ gfx_data->sys_cfg[SC_SYSCONFIG_SIZE] = 52; /* config data size */ -+ *(unsigned short *) (gfx_data->sys_cfg + SC_BOOTLOADER_SEG) = (unsigned) gfx_data >> 4; /* segment */ -+ gfx_data->sys_cfg[SC_XMEM_0] = 0x28; /* 8MB @ 2MB, see buf_ext below */ -+ // gfx_data->sys_cfg[SC_XMEM_1] = 0xYZ; /* Z MB @ Y MB */ -+ verbose = (*(unsigned char *) 0x417) & 3 ? 1 : 0; /* SHIFT pressed */ -+ gfx_data->sys_cfg[SC_FAILSAFE] = verbose; -+ -+ gfx_data->timeout = grub_timeout >= 0 ? grub_timeout : 0; -+ -+ -+ /* setup command line edit buffer */ -+ -+ gfx_data->cmdline_len = 256; -+ -+ gfx_data->cmdline = heap; -+ heap += gfx_data->cmdline_len; -+ memset(gfx_data->cmdline, 0, gfx_data->cmdline_len); -+ -+ cmd_buf = heap; -+ heap += GFX_CMD_BUF_SIZE; -+ -+ /* setup menu entries */ -+ -+ for(i = max_len = 0; i < num_entries; i++) { -+ j = strlen(get_entry(menu_entries, i, 0)); -+ if(j > max_len) max_len = j; -+ } -+ -+ if(!max_len) return; -+ -+ gfx_data->menu_entry_len = max_len + 1; -+ gfx_data->menu_entries = num_entries; -+ -+ gfx_data->menu_list = heap; -+ heap += gfx_data->menu_entry_len * gfx_data->menu_entries; -+ -+ memset(gfx_data->menu_list, 0, gfx_data->menu_entry_len * gfx_data->menu_entries); -+ -+ for(i = 0; i < (int) gfx_data->menu_entries; i++) { -+ strcpy(gfx_data->menu_list + i * gfx_data->menu_entry_len, get_entry(menu_entries, i, 0)); -+ } -+ -+ gfx_data->menu_default_entry = gfx_data->menu_list + entryno * gfx_data->menu_entry_len; -+ -+ -+ /* setup list of kernel args */ -+ -+ for(i = max_len = 0; i < num_entries; i++) { -+ s = get_kernel_args(get_entry(config_entries, i, 1), cmd_buf); -+ j = strlen(s); -+ if(j > max_len) max_len = j; -+ } -+ -+ gfx_data->args_entry_len = max_len + 1; -+ -+ gfx_data->args_list = heap; -+ heap += gfx_data->args_entry_len * gfx_data->menu_entries; -+ -+ memset(gfx_data->args_list, 0, gfx_data->args_entry_len * gfx_data->menu_entries); -+ -+ for(i = 0; i < (int) gfx_data->menu_entries; i++) { -+ strcpy(gfx_data->args_list + i* gfx_data->args_entry_len, get_kernel_args(get_entry(config_entries, i, 1), cmd_buf)); -+ } -+ -+ -+ /* go back here when we no longer need the graphics data */ -+ saved_heap = heap; -+ -+ -+ /* get memory area to be used by graphics functions */ -+ -+ /* use 8MB starting at 2MB as file buffer; see SC_XMEM_0 above (A20 is enabled anyway) */ -+ buf_ext = (unsigned char *) (2 << 20); -+ buf_ext_size = 8 << 20; -+ -+ /* must be 16-byte aligned */ -+ buf = (unsigned char *) (((unsigned) heap + 0xf) & ~0xf); -+ -+ buf_size = stack_ptr() - buf - MIN_HEAP_SIZE; -+ buf_size &= ~0xf; -+ -+ mem0_start = (unsigned) buf; -+ mem0_end = mem0_start + buf_size; -+ -+ if(verbose) { -+ printf("low memory 0x%x - 0x%x (%d bytes)\n", mem0_start, mem0_end, buf_size); -+ wait_for_key(); -+ } -+ -+ heap += buf_size; -+ -+ /* read the file */ -+ -+ if(!grub_open(graphics_file)) { -+ printf("%s: file not found\n", graphics_file); -+ sleep(5); -+ heap = saved_heap; -+ return; -+ } -+ -+ gfx_file_size = grub_read(buf_ext, buf_ext_size); -+ -+ grub_close(); -+ -+ if(gfx_file_size <= 0) { -+ printf("%s: read error\n", graphics_file); -+ sleep(5); -+ heap = saved_heap; -+ return; -+ } -+ -+ if(verbose) { -+ printf("%s: %d bytes (%d bytes left)\n", graphics_file, gfx_file_size, buf_ext_size - gfx_file_size); -+ wait_for_key(); -+ } -+ -+ /* locate file inside cpio archive */ -+ if(!(code_start = find_file(buf_ext, gfx_file_size, &file_start, &file_len))) { -+ printf("%s: invalid file format\n", graphics_file); -+ sleep(5); -+ heap = saved_heap; -+ return; -+ } -+ -+ if(verbose) { -+ printf("init: start 0x%x, len %d; code offset 0x%x\n", file_start, file_len, code_start); -+ wait_for_key(); -+ } -+ -+ if(file_len - code_start + MIN_GFX_FREE > buf_size) { -+ printf("not enough free memory: %d extra bytes need\n", file_len - code_start + MIN_GFX_FREE - buf_size); -+ sleep(5); -+ heap = saved_heap; -+ return; -+ } -+ -+ memcpy((void *) buf, (void *) (buf_ext + file_start + code_start), file_len - code_start); -+ -+ mem0_start += file_len - code_start; -+ mem0_start = (mem0_start + 3) & ~3; /* align */ -+ -+ /* init interface to graphics functions */ -+ -+ *(unsigned *) (gfx_data->sys_cfg + SC_FILE) = (unsigned) buf_ext + file_start; -+ *(unsigned *) (gfx_data->sys_cfg + SC_ARCHIVE_START) = (unsigned) buf_ext; -+ *(unsigned *) (gfx_data->sys_cfg + SC_ARCHIVE_END) = (unsigned) buf_ext + gfx_file_size; -+ *(unsigned *) (gfx_data->sys_cfg + SC_MEM0_START) = mem0_start; -+ *(unsigned *) (gfx_data->sys_cfg + SC_MEM0_END) = mem0_end; -+ -+ gfx_data->code_seg = (unsigned) buf >> 4; -+ -+ if(verbose) { -+ printf("init 0x%x, archive 0x%x - 0x%x, low mem 0x%x - 0x%x\ncode seg 0x%x\n", -+ (unsigned) buf_ext + file_start, -+ (unsigned) buf_ext, (unsigned) buf_ext + gfx_file_size, -+ mem0_start, mem0_end, gfx_data->code_seg -+ ); -+ wait_for_key(); -+ } -+ -+ for(i = 0; (unsigned) i < sizeof gfx_data->jmp_table / sizeof *gfx_data->jmp_table; i++) { -+ gfx_data->jmp_table[i] = (gfx_data->code_seg << 16) + ((unsigned short *) buf)[i]; -+ } -+ -+ if(verbose) { -+ for(i = 0; i < 12; i++) { -+ printf("%d: 0x%x\n", i, gfx_data->jmp_table[i]); -+ } -+ -+ for(i = 0; i < gfx_data->menu_entries; i++) { -+ printf("\"%s\" -- \"%s\"\n", -+ gfx_data->menu_list + i * gfx_data->menu_entry_len, -+ gfx_data->args_list + i * gfx_data->args_entry_len -+ ); -+ } -+ -+ printf("default: \"%s\"\n", gfx_data->menu_default_entry); -+ wait_for_key(); -+ } -+ -+ /* switch to graphics mode */ -+ -+ if(gfx_init(gfx_data)) { -+ printf("graphics initialization failed\n"); -+ sleep(5); -+ heap = saved_heap; -+ return; -+ } -+ -+ gfx_setup_menu(gfx_data); -+ -+ i = gfx_input(gfx_data, &selected_entry); -+ -+ /* ESC -> show text menu */ -+ if(i == 1) { -+ gfx_done(gfx_data); -+ grub_timeout = -1; -+ -+ heap = saved_heap; -+ return; -+ } -+ -+ gfx_done(gfx_data); -+ -+ heap = saved_heap; /* free most of the graphics data */ -+ -+ // printf("cmdline: >%s<, entry = %d\n", gfx_data->cmdline, selected_entry); -+ -+ if(selected_entry < 0 || selected_entry > num_entries) return; -+ -+ /* for 'savedefault' */ -+ current_entryno = selected_entry; -+ -+ -+ /* create new config with modified kernel option */ -+ -+ cfg = get_entry(config_entries, selected_entry, 1); -+ -+ new_config = heap; -+ -+ for(p = gfx_data->cmdline, i = 0; ; i++) { -+ s = get_entry(cfg, i, 0); -+ if(!*s) { -+ if(!i) *heap++ = 0; -+ *heap++ = 0; -+ break; -+ } -+ /* note: must match get_kernel_args() */ -+ if( -+ (!memcmp(s, "kernel", 6) || !memcmp(s, "module", 6)) && -+ (s[6] == ' ' || s[6] == '\t') -+ ) { -+ t = skip_to(0, s); -+ t2 = s[0] == 'm' ? strstr(t, "initrd") : NULL; -+ if(*t) t = skip_to(0, t); -+ if(t2 && t2 < t) { /* module is likely a normal initrd -> skip */ -+ strcpy(heap, s); -+ heap += strlen(s) + 1; -+ continue; -+ } -+ memmove(heap, s, t - s); -+ heap += t - s; -+ *heap++ = ' '; -+ while(*p && *p != GFX_CMD_SEP) *heap++ = *p++; -+ *heap++ = 0; -+ if(*p == GFX_CMD_SEP) p++; -+ } -+ else { -+ strcpy(heap, s); -+ heap += strlen(s) + 1; -+ } -+ } -+ -+ *heap++ = 0; -+ -+ // hexdump(new_config, heap - new_config); -+ // getkey(); -+ -+ run_script(new_config, heap); -+} -+ -+ - static int - get_line_from_config (char *cmdline, int maxlen, int read_from_file) - { -@@ -1059,9 +1557,12 @@ cmain (void) - } - else - { -- /* Run menu interface. */ -- run_menu (menu_entries, config_entries, num_entries, -- menu_entries + menu_len, default_entry); -+ if (*graphics_file && !password && show_menu && grub_timeout) -+ { -+ run_graphics_menu(menu_entries, config_entries, num_entries,menu_entries + menu_len, default_entry); -+ } -+ /* Run menu interface. */ -+ run_menu (menu_entries, config_entries, num_entries, menu_entries + menu_len, default_entry); - } - } - } |