diff options
author | BlackNoxis <steven.darklight@gmail.com> | 2014-02-15 23:24:26 +0200 |
---|---|---|
committer | BlackNoxis <steven.darklight@gmail.com> | 2014-02-15 23:24:26 +0200 |
commit | 7224c1253228e5c29c78cb3f0f26ce34770f2356 (patch) | |
tree | 1684924656132935256e034f35f92abee6623265 /sys-boot/grub/files/grub-0.97-gfxmenu-v8.patch |
Added ebuilds for kogaion desktop
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, 1003 insertions, 0 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 new file mode 100644 index 00000000..7921fc82 --- /dev/null +++ b/sys-boot/grub/files/grub-0.97-gfxmenu-v8.patch @@ -0,0 +1,1003 @@ +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); + } + } + } |