Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 103272 | Differences between
and this patch

Collapse All | Expand All

(-)file_not_specified_in_diff (-10 / +898 lines)
Line  Link Here
0
-- docs/grub.texi
0
++ docs/grub.texi
Lines 2118-2123 Link Here
2118
* default::                     Set the default entry
2118
* default::                     Set the default entry
2119
* fallback::                    Set the fallback entry
2119
* fallback::                    Set the fallback entry
2120
* hiddenmenu::                  Hide the menu interface
2120
* hiddenmenu::                  Hide the menu interface
2121
* gfxmenu::                     Use graphical menu interface
2121
* timeout::                     Set the timeout
2122
* timeout::                     Set the timeout
2122
* title::                       Start a menu entry
2123
* title::                       Start a menu entry
2123
@end menu
2124
@end menu
Lines 2150-2155 Link Here
2150
@end deffn
2151
@end deffn
2151
2152
2152
2153
2154
@node gfxmenu
2155
@subsection gfxmenu
2156
2157
@deffn Command gfxmenu file
2158
Use the graphical menu interface. The graphics data are taken from
2159
@var{file} and must be created using 'mkbootmsg' from the gfxboot package.
2160
@end deffn
2161
2162
2153
@node hiddenmenu
2163
@node hiddenmenu
2154
@subsection hiddenmenu
2164
@subsection hiddenmenu
2155
2165
2156
-- grub/asmstub.c
2166
++ grub/asmstub.c
Lines 498-503 Link Here
498
  return 0;
498
  return 0;
499
}
499
}
500
500
501
/* graphical menu functions .  */
502
int
503
gfx_init (gfx_data_t *gfx_data)
504
{
505
  return 0;
506
}
507
508
int
509
gfx_done (gfx_data_t *gfx_data)
510
{
511
  return 0;
512
}
513
514
int
515
gfx_input (gfx_data_t *gfx_data, int *menu_entry)
516
{
517
  return 0;
518
}
519
520
int
521
gfx_setup_menu (gfx_data_t *gfx_data)
522
{
523
  return 0;
524
}
525
526
501
/* low-level timing info */
527
/* low-level timing info */
502
int
528
int
503
getrtsecs (void)
529
getrtsecs (void)
504
-- stage2/asm.S
530
++ stage2/asm.S
Lines 1614-1619 Link Here
1614
	popl	%ebp
1614
	popl	%ebp
1615
	ret
1615
	ret
1616
1616
1617
1618
/*
1619
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1620
 *
1621
 * graphical menu functions
1622
 *
1623
 */
1624
1625
/*
1626
 * int gfx_init (gfx_data_t *gfx_data)
1627
 *
1628
 * init gfx things
1629
 *
1630
 * return vales:
1631
 *   0: ok
1632
 *   1: failed
1633
 *   sets gfx_data->ok
1634
 */
1635
1636
ENTRY(gfx_init)
1637
	pushl	%ebp
1638
	movl	%esp, %ebp
1639
	
1640
	pushl	%edi
1641
	pushl	%esi
1642
	pushl	%ebx
1643
1644
	movl	8(%ebp),%edx
1645
	movl	%edx,%edi
1646
	leal	gfx_ofs_sys_cfg(%edx),%esi
1647
	andl	$0xf,%edi
1648
	shrl	$4,%edx
1649
1650
	pushl	%ebp
1651
1652
	call	EXT_C(prot_to_real)
1653
	.code16
1654
1655
	pushw	%ds
1656
	movw	%dx,%ds
1657
1658
	lcall	*gfx_ofs_jmp_table + 4 * 0 (%di)
1659
1660
	sbbl	%ebx,%ebx
1661
	negl	%ebx
1662
1663
	popw	%ds
1664
1665
	DATA32	call	EXT_C(real_to_prot)
1666
	.code32
1667
1668
	popl	%ebp
1669
1670
	movl	%ebx,%eax
1671
	xorl	$1,%ebx
1672
	movl	8(%ebp),%edx
1673
	movl	%ebx,gfx_ofs_ok(%edx)
1674
1675
	popl	%ebx
1676
	popl	%esi
1677
	popl	%edi
1678
1679
	popl	%ebp
1680
	ret
1681
1682
1683
/*
1684
 * int gfx_done (gfx_data_t *gfx_data)
1685
 *
1686
 * shut down gfx things
1687
 *
1688
 * return vales:
1689
 *   always 0
1690
 *   sets gfx_data->ok
1691
 */
1692
1693
ENTRY(gfx_done)
1694
	pushl	%ebp
1695
	movl	%esp, %ebp
1696
	
1697
	pushl	%edi
1698
	pushl	%esi
1699
	pushl	%ebx
1700
1701
	movl	8(%ebp),%edx
1702
	movl	%edx,%ebx
1703
	andl	$0xf,%ebx
1704
	shrl	$4,%edx
1705
1706
	pushl	%ebp
1707
1708
	call	EXT_C(prot_to_real)
1709
	.code16
1710
1711
	pushw	%ds
1712
1713
	movw	%dx,%ds
1714
1715
	lcall	*gfx_ofs_jmp_table + 4 * 1 (%bx)
1716
1717
	popw	%ds
1718
1719
	DATA32	call	EXT_C(real_to_prot)
1720
	.code32
1721
1722
	popl	%ebp
1723
1724
	xorl	%eax,%eax
1725
	movl	8(%ebp),%edx
1726
	movl	%eax,gfx_ofs_ok(%edx)
1727
1728
	popl	%ebx
1729
	popl	%esi
1730
	popl	%edi
1731
1732
	popl	%ebp
1733
	ret
1734
1735
1736
/*
1737
 * int gfx_input (gfx_data_t *gfx_data, int *menu_entry)
1738
 *
1739
 * let user enter a command line
1740
 *
1741
 * uses gfx_data->cmdline as buffer
1742
 *
1743
 * return values:
1744
 *   1: abort
1745
 *   2: boot
1746
 *   menu_entry: selected entry
1747
 */
1748
1749
ENTRY(gfx_input)
1750
	pushl	%ebp
1751
	movl	%esp, %ebp
1752
	
1753
	pushl	%edi
1754
	pushl	%esi
1755
	pushl	%ebx
1756
1757
	movl	8(%ebp),%edx
1758
	movl	%edx,%ebx
1759
	leal	gfx_ofs_sys_cfg(%edx),%esi
1760
	andl	$0xf,%ebx
1761
	shrl	$4,%edx
1762
1763
	pushl	%ebp
1764
1765
	call	EXT_C(prot_to_real)
1766
	.code16
1767
1768
	pushw	%ds
1769
1770
	movw	%dx,%ds
1771
1772
	movl	gfx_ofs_cmdline(%bx),%edi
1773
	movl	gfx_ofs_cmdline_len(%bx),%ecx
1774
	movl	gfx_ofs_timeout(%bx),%eax
1775
	imull	$18,%eax
1776
1777
	lcall	*gfx_ofs_jmp_table + 4 * 2 (%bx)
1778
1779
	movl	%eax,%ecx
1780
1781
	popw	%ds
1782
1783
	DATA32	call	EXT_C(real_to_prot)
1784
	.code32
1785
1786
	popl	%ebp
1787
1788
	movl	12(%ebp),%edx
1789
	movl	%ebx,(%edx)
1790
1791
	movl	%ecx,%eax
1792
1793
	popl	%ebx
1794
	popl	%esi
1795
	popl	%edi
1796
1797
	popl	%ebp
1798
	ret
1799
1800
1801
/*
1802
 * int gfx_setup_menu (gfx_data_t *gfx_data)
1803
 *
1804
 * draw boot menu
1805
 *
1806
 * return values:
1807
 *   always 0
1808
 */
1809
1810
/* menu entry descriptor */
1811
#define menu_entries		0
1812
#define menu_default		2	/* seg:ofs */
1813
#define menu_ent_list		6	/* seg:ofs */
1814
#define menu_ent_size		10
1815
#define menu_arg_list		12	/* seg:ofs */
1816
#define menu_arg_size		16
1817
#define sizeof_menu_desc	18
1818
1819
ENTRY(gfx_setup_menu)
1820
	pushl	%ebp
1821
	movl	%esp, %ebp
1822
	
1823
	pushl	%edi
1824
	pushl	%esi
1825
	pushl	%ebx
1826
1827
	movl	8(%ebp),%edx
1828
	movl	%edx,%ebx
1829
	andl	$0xf,%ebx
1830
	shrl	$4,%edx
1831
1832
	call	EXT_C(prot_to_real)
1833
	.code16
1834
1835
	pushw	%ds
1836
1837
	movw	%dx,%ds
1838
	shll	$4,%edx
1839
1840
	subw	$sizeof_menu_desc,%sp
1841
	movw	%esp,%ebp
1842
1843
	movl	gfx_ofs_menu_entries(%bx),%eax
1844
	movw	%ax,menu_entries(%bp)
1845
1846
	movl	gfx_ofs_menu_default_entry(%bx),%eax
1847
	subl	%edx,%eax
1848
	movw	%ax,menu_default(%bp)
1849
	movw	%ds,menu_default+2(%bp)
1850
1851
	movl	gfx_ofs_menu_list(%bx),%eax
1852
	subl	%edx,%eax
1853
	movw	%ax,menu_ent_list(%bp)
1854
	movw	%ds,menu_ent_list+2(%bp)
1855
1856
	movl	gfx_ofs_menu_entry_len(%bx),%eax
1857
	movw	%ax,menu_ent_size(%bp)
1858
1859
	movl	gfx_ofs_args_list(%bx),%eax
1860
	subl	%edx,%eax
1861
	movw	%ax,menu_arg_list(%bp)
1862
	movw	%ds,menu_arg_list+2(%bp)
1863
1864
	movl	gfx_ofs_args_entry_len(%bx),%eax
1865
	movw	%ax,menu_arg_size(%bp)
1866
1867
	movl	%ss,%esi
1868
	shll	$4,%esi
1869
	addl	%ebp,%esi
1870
	
1871
	lcall	%ds: *gfx_ofs_jmp_table + 4 * 3 (%bx)
1872
1873
	addw	$sizeof_menu_desc,%sp
1874
1875
	popw	%ds
1876
1877
	DATA32	call	EXT_C(real_to_prot)
1878
	.code32
1879
1880
	xorl	%eax,%eax
1881
1882
	popl	%ebx
1883
	popl	%esi
1884
	popl	%edi
1885
1886
	popl	%ebp
1887
	ret
1888
1889
1890
/*
1891
 *
1892
 * end graphics stuff
1893
 *
1894
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1895
 */
1896
1617
		
1897
		
1618
/*
1898
/*
1619
 * gateA20(int linear)
1899
 * gateA20(int linear)
1620
-- stage2/builtins.c
1900
++ stage2/builtins.c
Lines 63-68 Link Here
63
int fallback_entries[MAX_FALLBACK_ENTRIES];
63
int fallback_entries[MAX_FALLBACK_ENTRIES];
64
/* The number of current entry.  */
64
/* The number of current entry.  */
65
int current_entryno;
65
int current_entryno;
66
/* graphics file */
67
char graphics_file[64];
66
/* The address for Multiboot command-line buffer.  */
68
/* The address for Multiboot command-line buffer.  */
67
static char *mb_cmdline;
69
static char *mb_cmdline;
68
/* The password.  */
70
/* The password.  */
Lines 1351-1356 Link Here
1351
};
1353
};
1352
1354
1353
1355
1356
/* graphics */
1357
static int
1358
gfxmenu_func (char *arg, int flags)
1359
{
1360
  memmove(graphics_file, arg, sizeof graphics_file - 1);
1361
  graphics_file[sizeof graphics_file - 1] = 0;
1362
1363
  return 0;
1364
}
1365
1366
static struct builtin builtin_gfxmenu =
1367
{
1368
  "gfxmenu",
1369
  gfxmenu_func,
1370
  BUILTIN_MENU | BUILTIN_HELP_LIST,
1371
  "gfxmenu FILE",
1372
  "Use the graphical menu from FILE."
1373
};
1374
1375
1354
/* geometry */
1376
/* geometry */
1355
static int
1377
static int
1356
geometry_func (char *arg, int flags)
1378
geometry_func (char *arg, int flags)
Lines 4874-4879 Link Here
4874
  &builtin_find,
4896
  &builtin_find,
4875
  &builtin_fstest,
4897
  &builtin_fstest,
4876
  &builtin_geometry,
4898
  &builtin_geometry,
4899
  &builtin_gfxmenu,
4877
  &builtin_halt,
4900
  &builtin_halt,
4878
  &builtin_help,
4901
  &builtin_help,
4879
  &builtin_hiddenmenu,
4902
  &builtin_hiddenmenu,
4880
-- stage2/shared.h
4903
++ stage2/shared.h
Lines 374-379 Link Here
374
#endif /* WITHOUT_LIBC_STUBS */
374
#endif /* WITHOUT_LIBC_STUBS */
375
375
376
376
377
/* see typedef gfx_data_t below */
378
#define gfx_ofs_ok			0x00
379
#define gfx_ofs_code_seg		0x04
380
#define gfx_ofs_jmp_table		0x08
381
#define gfx_ofs_sys_cfg			0x38
382
#define gfx_ofs_cmdline			0x6c
383
#define gfx_ofs_cmdline_len		0x70
384
#define gfx_ofs_menu_list		0x74
385
#define gfx_ofs_menu_default_entry	0x78
386
#define gfx_ofs_menu_entries		0x7c
387
#define gfx_ofs_menu_entry_len		0x80
388
#define gfx_ofs_args_list		0x84
389
#define gfx_ofs_args_entry_len		0x88
390
#define gfx_ofs_timeout			0x8c
391
392
377
#ifndef ASM_FILE
393
#ifndef ASM_FILE
378
/*
394
/*
379
 *  Below this should be ONLY defines and other constructs for C code.
395
 *  Below this should be ONLY defines and other constructs for C code.
Lines 595-600 Link Here
595
extern int default_entry;
611
extern int default_entry;
596
extern int current_entryno;
612
extern int current_entryno;
597
613
614
615
/*
616
 * graphics menu stuff
617
 *
618
 * Note: gfx_data and all data referred to in it must lie within a 64k area.
619
 */
620
typedef struct {
621
  unsigned ok;			/* set while we're in graphics mode */
622
  unsigned code_seg;		/* code segment of binary graphics code */
623
  unsigned jmp_table[12];	/* link to graphics functions */
624
  unsigned char sys_cfg[52];	/* sys_cfg[0]: identifies boot loader (grub == 2) */
625
  char *cmdline;		/* command line returned by gfx_input() */
626
  unsigned cmdline_len;		/* length of the above */
627
  char *menu_list;		/* list of menu entries, each of fixed length (menu_entry_len) */
628
  char *menu_default_entry;	/* the default entry */
629
  unsigned menu_entries;	/* number of entries in menu_list */
630
  unsigned menu_entry_len;	/* one entry */
631
  char *args_list;		/* same structure as menu_list, menu_entries entries */
632
  unsigned args_entry_len;	/* one entry */
633
  unsigned timeout;		/* in seconds (0: no timeout) */
634
} __attribute__ ((packed)) gfx_data_t;
635
636
extern gfx_data_t *graphics_data;
637
638
/* pointer to graphics image data */
639
extern char graphics_file[64];
640
641
int gfx_init(gfx_data_t *gfx_data);
642
int gfx_done(gfx_data_t *gfx_data);
643
int gfx_input(gfx_data_t *gfx_data, int *menu_entry);
644
int gfx_setup_menu(gfx_data_t *gfx_data);
645
598
/* The constants for password types.  */
646
/* The constants for password types.  */
599
typedef enum
647
typedef enum
600
{
648
{
601
-- stage2/stage2.c
649
++ stage2/stage2.c
Lines 22-27 Link Here
22
22
23
grub_jmp_buf restart_env;
23
grub_jmp_buf restart_env;
24
24
25
gfx_data_t *graphics_data;
26
25
#if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS)
27
#if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS)
26
28
27
# if defined(PRESET_MENU_STRING)
29
# if defined(PRESET_MENU_STRING)
Lines 310-315 Link Here
310
      
312
      
311
      if (! auth && password)
313
      if (! auth && password)
312
	{
314
	{
315
	  if (*graphics_file)
316
	    {
317
	      printf ("\
318
	WARNING: graphical menu doesn\'t work\
319
	in conjunction with the password feature\n" );
320
	    }
313
	  printf ("\
321
	  printf ("\
314
      Press enter to boot the selected OS or \'p\' to enter a\n\
322
      Press enter to boot the selected OS or \'p\' to enter a\n\
315
      password to unlock the next set of features.");
323
      password to unlock the next set of features.");
Lines 753-758 Link Here
753
}
761
}
754
762
755
763
764
765
#if 0
766
/* for debugging */
767
static void hexdump(unsigned char *buf, unsigned len)
768
{
769
  int i, j = 0;
770
  char s[17];
771
  unsigned addr = (unsigned) buf;
772
773
  s[16] = 0;
774
  while(len--) {
775
    i = buf[j];
776
    i = i & 0xff;
777
    s[j & 15] = (i >= 0x20 && i <= 0x7e) ? i : '.';
778
    if(!(j & 15)) {
779
      printf("%x  ", j + addr);
780
    }
781
    if(!(j & 7) && (j & 15)) printf(" ");
782
    /* stupid grub_printf */
783
    printf("%x", (i >> 4) & 0x0f);
784
    printf("%x ", i & 0x0f);
785
    if(!(++j & 15)) {
786
      printf(" %s\n", s);
787
    }
788
  }
789
790
  if(j & 15) {
791
    s[j & 15] = 0;
792
    if(!(j & 8)) printf(" ");
793
    i = 1 + 3 * (16 - (j & 15));
794
    while(i--) printf(" ");
795
    printf("%s\n", s);
796
  }
797
}
798
#endif
799
800
801
/* kernel + (grub-)module options */
802
#define GFX_CMD_BUF_SIZE 512
803
804
/* command line separator char */
805
#define GFX_CMD_SEP 1
806
807
/*
808
 * Go through config entry and find kernel args, if any.
809
 * Put things into buf and return it.
810
 */
811
static char *get_kernel_args(char *cfg, char *buf)
812
{
813
  int i, j;
814
  char *s, *t = "", *p, *t2;
815
816
  *(p = buf) = 0;
817
818
  for(j = 0; ; j++) {
819
    s = get_entry(cfg, j, 0);
820
    if(!*s) break;
821
    if(
822
      (!memcmp(s, "kernel", 6) || !memcmp(s, "module", 6)) &&
823
      (s[6] == ' ' || s[6] == '\t')
824
    ) {
825
      t = skip_to(0, s);
826
      t2 = s[0] == 'm' ? strstr(t, "initrd") : NULL;
827
      if(*t) t = skip_to(0, t);
828
      if(t2 && t2 < t) break;	/* module is likely a normal initrd -> skip */
829
      i = strlen(t);
830
      if(p - buf + i > GFX_CMD_BUF_SIZE - 2) break;
831
      *p++ = GFX_CMD_SEP;
832
      strcpy(p, t);
833
      p += i;
834
835
      continue;
836
    }
837
  }
838
839
  if(*buf) buf++;	/* skip initial separator char */
840
841
  return buf;
842
}
843
844
845
/*
846
 * Check header and return code start offset.
847
 */
848
static unsigned magic_ok(unsigned char *buf)
849
{
850
  if(
851
    *(unsigned *) buf == 0x0b2d97f00 &&		/* magic id */
852
    (buf[4] == 8)				/* version 8 */
853
  ) {
854
    return *(unsigned *) (buf + 8);
855
  }
856
857
  return 0;
858
}
859
860
861
/*
862
 * Search cpio archive for gfx file.
863
 */
864
static unsigned find_file(unsigned char *buf, unsigned len, unsigned *gfx_file_start, unsigned *file_len)
865
{
866
  unsigned i, fname_len, code_start = 0;
867
868
  *gfx_file_start = 0;
869
870
  for(i = 0; i < len;) {
871
    if((len - i) >= 0x1a && (buf[i] + (buf[i + 1] << 8)) == 0x71c7) {
872
      fname_len = *(unsigned short *) (buf + i + 20);
873
      *file_len = *(unsigned short *) (buf + i + 24) + (*(unsigned short *) (buf + i + 22) << 16);
874
      i += 26 + fname_len;
875
      i = ((i + 1) & ~1);
876
      if((code_start = magic_ok(buf + i))) {
877
        *gfx_file_start = i;
878
        return code_start;
879
      }
880
      i += *file_len;
881
      i = ((i + 1) & ~1);
882
    }
883
    else {
884
      break;
885
    }
886
  }
887
888
  return code_start;
889
}
890
891
static inline unsigned char * stack_ptr(void)
892
{
893
  unsigned char * u;
894
895
  asm("movl %%esp, %0" : "=r" (u));
896
897
  return u;
898
}
899
900
static void sleep(int delay)
901
{
902
  int tick, last_tick = currticks();
903
904
  delay *= 18;
905
906
  while(delay--) {
907
    while((tick = currticks()) == last_tick) { }
908
    last_tick = tick;
909
  }
910
}  
911
912
static void wait_for_key()
913
{
914
  printf("Press a key to continue...");
915
  getkey();
916
  printf("\r                          \r");
917
}
918
919
920
/*
921
 * Leave that much space on the heap. Everything else goes to the graphics
922
 * functions.
923
 *
924
 * 0x2000 is _not_ enough
925
 */
926
#define MIN_HEAP_SIZE	0x4000
927
#define MIN_GFX_FREE	0x1000
928
929
#define SC_BOOTLOADER		0
930
#define SC_FAILSAFE		3
931
#define SC_SYSCONFIG_SIZE	4
932
#define SC_BOOTLOADER_SEG	8
933
#define SC_XMEM_0		24
934
#define SC_XMEM_1		26
935
#define SC_XMEM_2		28
936
#define SC_XMEM_3		30
937
#define SC_FILE			32
938
#define SC_ARCHIVE_START	36
939
#define SC_ARCHIVE_END		40
940
#define SC_MEM0_START		44
941
#define SC_MEM0_END		48
942
943
/*
944
 * Does normally not return.
945
 */
946
static void
947
run_graphics_menu (char *menu_entries, char *config_entries, int num_entries,
948
	  char *heap, int entryno)
949
{
950
  unsigned char *buf, *buf_ext;
951
  unsigned buf_size, buf_ext_size, code_start, file_start;
952
  char *s, *t, *t2, *cfg, *new_config, *p;
953
  char *saved_heap;
954
  int i, j, max_len, gfx_file_size, verbose;
955
  int selected_entry;
956
  gfx_data_t *gfx_data;
957
  char *cmd_buf;
958
  unsigned mem0_start, mem0_end, file_len;
959
960
  /*
961
   * check gfx_data_t struct offsets for consistency; gcc will optimize away
962
   * the whole block
963
   */
964
965
  /* dummy function to make ld fail */
966
  {
967
    extern void wrong_struct_size(void);
968
    #define gfx_ofs_check(a) if(gfx_ofs_##a != (char *) &gfx_data->a - (char *) gfx_data) wrong_struct_size();
969
    gfx_ofs_check(ok);
970
    gfx_ofs_check(code_seg);
971
    gfx_ofs_check(jmp_table);
972
    gfx_ofs_check(sys_cfg);
973
    gfx_ofs_check(cmdline);
974
    gfx_ofs_check(cmdline_len);
975
    gfx_ofs_check(menu_list);
976
    gfx_ofs_check(menu_default_entry);
977
    gfx_ofs_check(menu_entries);
978
    gfx_ofs_check(menu_entry_len);
979
    gfx_ofs_check(args_list);
980
    gfx_ofs_check(args_entry_len);
981
    gfx_ofs_check(timeout);
982
    #undef gfx_ofs_check
983
  }
984
985
  if(!num_entries) return;
986
987
  graphics_data = gfx_data = (gfx_data_t *) heap;
988
  heap += sizeof *gfx_data;
989
  memset(gfx_data, 0, sizeof *gfx_data);
990
991
  gfx_data->sys_cfg[SC_BOOTLOADER] = 2;			/* bootloader: grub */
992
  gfx_data->sys_cfg[SC_SYSCONFIG_SIZE] = 52;		/* config data size */
993
  *(unsigned short *) (gfx_data->sys_cfg + SC_BOOTLOADER_SEG) = (unsigned) gfx_data >> 4;	/* segment */
994
  gfx_data->sys_cfg[SC_XMEM_0] = 0x21;			/* 1MB @ 2MB */
995
  gfx_data->sys_cfg[SC_XMEM_1] = 0x41;			/* 1MB @ 4MB */
996
  verbose = (*(unsigned char *) 0x417) & 3 ? 1 : 0;	/* SHIFT pressed */
997
  gfx_data->sys_cfg[SC_FAILSAFE] = verbose;
998
999
  gfx_data->timeout = grub_timeout >= 0 ? grub_timeout : 0;
1000
1001
1002
  /* setup command line edit buffer */
1003
1004
  gfx_data->cmdline_len = 256;
1005
1006
  gfx_data->cmdline = heap;
1007
  heap += gfx_data->cmdline_len;
1008
  memset(gfx_data->cmdline, 0, gfx_data->cmdline_len);
1009
1010
  cmd_buf = heap;
1011
  heap += GFX_CMD_BUF_SIZE;
1012
1013
  /* setup menu entries */
1014
1015
  for(i = max_len = 0; i < num_entries; i++) {
1016
    j = strlen(get_entry(menu_entries, i, 0));
1017
    if(j > max_len) max_len = j;
1018
  }
1019
1020
  if(!max_len) return;
1021
1022
  gfx_data->menu_entry_len = max_len + 1;
1023
  gfx_data->menu_entries = num_entries;
1024
1025
  gfx_data->menu_list = heap;
1026
  heap += gfx_data->menu_entry_len * gfx_data->menu_entries;
1027
1028
  memset(gfx_data->menu_list, 0, gfx_data->menu_entry_len * gfx_data->menu_entries);
1029
1030
  for(i = 0; i < (int) gfx_data->menu_entries; i++) {
1031
    strcpy(gfx_data->menu_list + i * gfx_data->menu_entry_len, get_entry(menu_entries, i, 0));
1032
  }
1033
1034
  gfx_data->menu_default_entry = gfx_data->menu_list + entryno * gfx_data->menu_entry_len;
1035
1036
1037
  /* setup list of kernel args */
1038
1039
  for(i = max_len = 0; i < num_entries; i++) {
1040
    s = get_kernel_args(get_entry(config_entries, i, 1), cmd_buf);
1041
    j = strlen(s);
1042
    if(j > max_len) max_len = j;
1043
  }
1044
1045
  gfx_data->args_entry_len = max_len + 1;
1046
1047
  gfx_data->args_list = heap;
1048
  heap += gfx_data->args_entry_len * gfx_data->menu_entries;
1049
1050
  memset(gfx_data->args_list, 0, gfx_data->args_entry_len * gfx_data->menu_entries);
1051
1052
  for(i = 0; i < (int) gfx_data->menu_entries; i++) {
1053
    strcpy(gfx_data->args_list + i* gfx_data->args_entry_len, get_kernel_args(get_entry(config_entries, i, 1), cmd_buf));
1054
  }
1055
1056
1057
  /* go back here when we no longer need the graphics data */
1058
  saved_heap = heap;
1059
1060
1061
  /* get memory area to be used by graphics functions */
1062
1063
  /* use 1MB starting at 2MB as file buffer */
1064
  buf_ext = (unsigned char *) (2 << 20);
1065
  buf_ext_size = 1 << 20;
1066
1067
  /* must be 16-byte aligned */
1068
  buf = (unsigned char *) (((unsigned) heap + 0xf) & ~0xf);
1069
1070
  buf_size = stack_ptr() - buf - MIN_HEAP_SIZE;
1071
  buf_size &= ~0xf;
1072
1073
  mem0_start = (unsigned) buf;
1074
  mem0_end = mem0_start + buf_size;
1075
1076
  if(verbose) {
1077
    printf("low memory 0x%x - 0x%x (%d bytes)\n", mem0_start, mem0_end, buf_size);
1078
    wait_for_key();
1079
  }
1080
1081
  heap += buf_size;
1082
1083
  /* read the file */
1084
1085
  if(!grub_open(graphics_file)) {
1086
    printf("%s: file not found\n", graphics_file);
1087
    sleep(5);
1088
    heap = saved_heap;
1089
    return;
1090
  }
1091
1092
  gfx_file_size = grub_read(buf_ext, buf_ext_size);
1093
1094
  grub_close();
1095
1096
  if(gfx_file_size <= 0) {
1097
    printf("%s: read error\n", graphics_file);
1098
    sleep(5);
1099
    heap = saved_heap;
1100
    return;
1101
  }
1102
1103
  if(verbose) {
1104
    printf("%s: %d bytes (%d bytes left)\n", graphics_file, gfx_file_size, buf_ext_size - gfx_file_size);
1105
    wait_for_key();
1106
  }
1107
1108
  /* locate file inside cpio archive */
1109
  if(!(code_start = find_file(buf_ext, gfx_file_size, &file_start, &file_len))) {
1110
    printf("%s: invalid file format\n", graphics_file);
1111
    sleep(5);
1112
    heap = saved_heap;
1113
    return;
1114
  }
1115
1116
  if(verbose) {
1117
    printf("init: start 0x%x, len %d; code offset 0x%x\n", file_start, file_len, code_start);
1118
    wait_for_key();
1119
  }
1120
1121
  if(file_len - code_start + MIN_GFX_FREE > buf_size) {
1122
    printf("not enough free memory: %d extra bytes need\n", file_len - code_start + MIN_GFX_FREE - buf_size);
1123
    sleep(5);
1124
    heap = saved_heap;
1125
    return;
1126
  }
1127
1128
  memcpy((void *) buf, (void *) (buf_ext + file_start + code_start), file_len - code_start);
1129
1130
  mem0_start += file_len - code_start;
1131
  mem0_start = (mem0_start + 3) & ~3;		/* align */
1132
1133
  /* init interface to graphics functions */
1134
1135
  *(unsigned *) (gfx_data->sys_cfg + SC_FILE) = (unsigned) buf_ext + file_start;
1136
  *(unsigned *) (gfx_data->sys_cfg + SC_ARCHIVE_START) = (unsigned) buf_ext;
1137
  *(unsigned *) (gfx_data->sys_cfg + SC_ARCHIVE_END) = (unsigned) buf_ext + gfx_file_size;
1138
  *(unsigned *) (gfx_data->sys_cfg + SC_MEM0_START) = mem0_start;
1139
  *(unsigned *) (gfx_data->sys_cfg + SC_MEM0_END) = mem0_end;
1140
1141
  gfx_data->code_seg = (unsigned) buf >> 4;
1142
1143
  if(verbose) {
1144
    printf("init 0x%x, archive 0x%x - 0x%x, low mem 0x%x - 0x%x\ncode seg 0x%x\n",
1145
      (unsigned) buf_ext + file_start,
1146
      (unsigned) buf_ext, (unsigned) buf_ext + gfx_file_size,
1147
      mem0_start, mem0_end, gfx_data->code_seg
1148
    );
1149
    wait_for_key();
1150
  }
1151
1152
  for(i = 0; (unsigned) i < sizeof gfx_data->jmp_table / sizeof *gfx_data->jmp_table; i++) {
1153
    gfx_data->jmp_table[i] = (gfx_data->code_seg << 16) + ((unsigned short *) buf)[i];
1154
  }
1155
1156
  if(verbose) {
1157
    for(i = 0; i < 12; i++) {
1158
      printf("%d: 0x%x\n", i, gfx_data->jmp_table[i]);
1159
    }
1160
1161
    for(i = 0; i < gfx_data->menu_entries; i++) {
1162
      printf("\"%s\"  --  \"%s\"\n",
1163
        gfx_data->menu_list + i * gfx_data->menu_entry_len,
1164
        gfx_data->args_list + i * gfx_data->args_entry_len
1165
      );
1166
    }
1167
1168
    printf("default: \"%s\"\n", gfx_data->menu_default_entry);
1169
    wait_for_key();
1170
  }
1171
1172
  /* switch to graphics mode */
1173
1174
  if(gfx_init(gfx_data)) {
1175
    printf("graphics initialization failed\n");
1176
    sleep(5);
1177
    heap = saved_heap;
1178
    return;
1179
  }
1180
1181
  gfx_setup_menu(gfx_data);
1182
1183
  i = gfx_input(gfx_data, &selected_entry);
1184
1185
  /* ESC -> show text menu */
1186
  if(i == 1) {
1187
    gfx_done(gfx_data);
1188
    grub_timeout = -1;
1189
1190
    heap = saved_heap;
1191
    return;
1192
  }
1193
1194
  gfx_done(gfx_data);
1195
1196
  heap = saved_heap;	/* free most of the graphics data */
1197
1198
  // printf("cmdline: >%s<, entry = %d\n", gfx_data->cmdline, selected_entry);
1199
1200
  if(selected_entry < 0 || selected_entry > num_entries) return;
1201
1202
1203
  /* create new config with modified kernel option */
1204
1205
  cfg = get_entry(config_entries, selected_entry, 1);
1206
1207
  new_config = heap;
1208
1209
  for(p = gfx_data->cmdline, i = 0; ; i++) {
1210
    s = get_entry(cfg, i, 0);
1211
    if(!*s) {
1212
      if(!i) *heap++ = 0;
1213
      *heap++ = 0;
1214
      break;
1215
    }
1216
    /* note: must match get_kernel_args() */
1217
    if(
1218
      (!memcmp(s, "kernel", 6) || !memcmp(s, "module", 6)) &&
1219
      (s[6] == ' ' || s[6] == '\t')
1220
    ) {
1221
      t = skip_to(0, s);
1222
      t2 = s[0] == 'm' ? strstr(t, "initrd") : NULL;
1223
      if(*t) t = skip_to(0, t);
1224
      if(t2 && t2 < t) {	/* module is likely a normal initrd -> skip */
1225
        strcpy(heap, s);
1226
        heap += strlen(s) + 1;
1227
        continue;
1228
      }
1229
      memmove(heap, s, t - s);
1230
      heap += t - s;
1231
      *heap++ = ' ';
1232
      while(*p && *p != GFX_CMD_SEP) *heap++ = *p++;
1233
      *heap++ = 0;
1234
      if(*p == GFX_CMD_SEP) p++;
1235
    }
1236
    else {
1237
      strcpy(heap, s);
1238
      heap += strlen(s) + 1;
1239
    }
1240
  }
1241
1242
  *heap++ = 0;
1243
1244
  // hexdump(new_config, heap - new_config);
1245
  // getkey();
1246
1247
  run_script(new_config, heap);
1248
}
1249
1250
756
static int
1251
static int
757
get_line_from_config (char *cmdline, int maxlen, int read_from_file)
1252
get_line_from_config (char *cmdline, int maxlen, int read_from_file)
758
{
1253
{
Lines 1062-1070 Link Here
1062
	}
1557
	}
1063
      else
1558
      else
1064
	{
1559
	{
1065
	  /* Run menu interface.  */
1560
	  if (*graphics_file && !password && show_menu && grub_timeout)
1066
	  run_menu (menu_entries, config_entries, num_entries,
1561
	    {
1067
		    menu_entries + menu_len, default_entry);
1562
	      run_graphics_menu(menu_entries, config_entries, num_entries,menu_entries + menu_len, default_entry);
1563
	    }
1564
	    /* Run menu interface.  */
1565
            run_menu (menu_entries, config_entries, num_entries, menu_entries + menu_len, default_entry);
1068
	}
1566
	}
1069
    }
1567
    }
1070
}
1568
}
1071
-- stage2/stage2.c
1569
++ stage2/stage2.c
Lines 1199-1204 Link Here
1199
1199
1200
  if(selected_entry < 0 || selected_entry > num_entries) return;
1200
  if(selected_entry < 0 || selected_entry > num_entries) return;
1201
1201
1202
  /* for 'savedefault' */
1203
  current_entryno = selected_entry;
1204
1202
1205
1203
  /* create new config with modified kernel option */
1206
  /* create new config with modified kernel option */
1204
1207

Return to bug 103272