Lines 59-65
Link Here
|
59 |
/* The default entry. */ |
59 |
/* The default entry. */ |
60 |
int default_entry = 0; |
60 |
int default_entry = 0; |
61 |
/* The fallback entry. */ |
61 |
/* The fallback entry. */ |
62 |
int fallback_entry = -1; |
62 |
int fallback_entryno; |
|
|
63 |
int fallback_entries[MAX_FALLBACK_ENTRIES]; |
63 |
/* The number of current entry. */ |
64 |
/* The number of current entry. */ |
64 |
int current_entryno; |
65 |
int current_entryno; |
65 |
/* The address for Multiboot command-line buffer. */ |
66 |
/* The address for Multiboot command-line buffer. */ |
Lines 97-103
Link Here
|
97 |
{ |
98 |
{ |
98 |
default_entry = 0; |
99 |
default_entry = 0; |
99 |
password = 0; |
100 |
password = 0; |
100 |
fallback_entry = -1; |
101 |
fallback_entryno = -1; |
|
|
102 |
fallback_entries[0] = -1; |
101 |
grub_timeout = -1; |
103 |
grub_timeout = -1; |
102 |
} |
104 |
} |
103 |
|
105 |
|
Lines 129-189
Link Here
|
129 |
} |
131 |
} |
130 |
|
132 |
|
131 |
|
133 |
|
|
|
134 |
/* blocklist_read_helper nee disk_read_blocklist_func was a nested |
135 |
* function, to which pointers were taken and exposed globally. Even |
136 |
* in the GNU-C nested functions extension, they have local linkage, |
137 |
* and aren't guaranteed to be accessable *at all* outside of their |
138 |
* containing scope. |
139 |
* |
140 |
* Above and beyond all of that, the variables within blocklist_func_context |
141 |
* are originally local variables, with local (not even static) linkage, |
142 |
* from within blocklist_func. These were each referenced by |
143 |
* disk_read_blocklist_func, which is only called from other functions |
144 |
* through a globally scoped pointer. |
145 |
* |
146 |
* The documentation in GCC actually uses the words "all hell will break |
147 |
* loose" to describe this scenario. |
148 |
* |
149 |
* Also, "start_sector" was also used uninitialized, but gcc doesn't warn |
150 |
* about it (possibly because of the scoping madness?) |
151 |
*/ |
152 |
|
153 |
static struct { |
154 |
int start_sector; |
155 |
int num_sectors; |
156 |
int num_entries; |
157 |
int last_length; |
158 |
} blocklist_func_context = { |
159 |
.start_sector = 0, |
160 |
.num_sectors = 0, |
161 |
.num_entries = 0, |
162 |
.last_length = 0 |
163 |
}; |
164 |
|
165 |
/* Collect contiguous blocks into one entry as many as possible, |
166 |
and print the blocklist notation on the screen. */ |
167 |
static void |
168 |
blocklist_read_helper (int sector, int offset, int length) |
169 |
{ |
170 |
int *start_sector = &blocklist_func_context.start_sector; |
171 |
int *num_sectors = &blocklist_func_context.num_sectors; |
172 |
int *num_entries = &blocklist_func_context.num_entries; |
173 |
int *last_length = &blocklist_func_context.last_length; |
174 |
|
175 |
if (*num_sectors > 0) |
176 |
{ |
177 |
if (*start_sector + *num_sectors == sector |
178 |
&& offset == 0 && *last_length == SECTOR_SIZE) |
179 |
{ |
180 |
*num_sectors++; |
181 |
*last_length = length; |
182 |
return; |
183 |
} |
184 |
else |
185 |
{ |
186 |
if (*last_length == SECTOR_SIZE) |
187 |
grub_printf ("%s%d+%d", *num_entries ? "," : "", |
188 |
*start_sector - part_start, *num_sectors); |
189 |
else if (*num_sectors > 1) |
190 |
grub_printf ("%s%d+%d,%d[0-%d]", *num_entries ? "," : "", |
191 |
*start_sector - part_start, *num_sectors-1, |
192 |
*start_sector + *num_sectors-1 - part_start, |
193 |
*last_length); |
194 |
else |
195 |
grub_printf ("%s%d[0-%d]", *num_entries ? "," : "", |
196 |
*start_sector - part_start, *last_length); |
197 |
*num_entries++; |
198 |
*num_sectors = 0; |
199 |
} |
200 |
} |
201 |
|
202 |
if (offset > 0) |
203 |
{ |
204 |
grub_printf("%s%d[%d-%d]", *num_entries ? "," : "", |
205 |
sector-part_start, offset, offset+length); |
206 |
*num_entries++; |
207 |
} |
208 |
else |
209 |
{ |
210 |
*start_sector = sector; |
211 |
*num_sectors = 1; |
212 |
*last_length = length; |
213 |
} |
214 |
} |
215 |
|
132 |
/* blocklist */ |
216 |
/* blocklist */ |
133 |
static int |
217 |
static int |
134 |
blocklist_func (char *arg, int flags) |
218 |
blocklist_func (char *arg, int flags) |
135 |
{ |
219 |
{ |
136 |
char *dummy = (char *) RAW_ADDR (0x100000); |
220 |
char *dummy = (char *) RAW_ADDR (0x100000); |
137 |
int start_sector; |
|
|
138 |
int num_sectors = 0; |
139 |
int num_entries = 0; |
140 |
int last_length = 0; |
141 |
|
142 |
/* Collect contiguous blocks into one entry as many as possible, |
143 |
and print the blocklist notation on the screen. */ |
144 |
static void disk_read_blocklist_func (int sector, int offset, int length) |
145 |
{ |
146 |
if (num_sectors > 0) |
147 |
{ |
148 |
if (start_sector + num_sectors == sector |
149 |
&& offset == 0 && last_length == SECTOR_SIZE) |
150 |
{ |
151 |
num_sectors++; |
152 |
last_length = length; |
153 |
return; |
154 |
} |
155 |
else |
156 |
{ |
157 |
if (last_length == SECTOR_SIZE) |
158 |
grub_printf ("%s%d+%d", num_entries ? "," : "", |
159 |
start_sector - part_start, num_sectors); |
160 |
else if (num_sectors > 1) |
161 |
grub_printf ("%s%d+%d,%d[0-%d]", num_entries ? "," : "", |
162 |
start_sector - part_start, num_sectors-1, |
163 |
start_sector + num_sectors-1 - part_start, |
164 |
last_length); |
165 |
else |
166 |
grub_printf ("%s%d[0-%d]", num_entries ? "," : "", |
167 |
start_sector - part_start, last_length); |
168 |
num_entries++; |
169 |
num_sectors = 0; |
170 |
} |
171 |
} |
172 |
|
173 |
if (offset > 0) |
174 |
{ |
175 |
grub_printf("%s%d[%d-%d]", num_entries ? "," : "", |
176 |
sector-part_start, offset, offset+length); |
177 |
num_entries++; |
178 |
} |
179 |
else |
180 |
{ |
181 |
start_sector = sector; |
182 |
num_sectors = 1; |
183 |
last_length = length; |
184 |
} |
185 |
} |
186 |
|
221 |
|
|
|
222 |
int *start_sector = &blocklist_func_context.start_sector; |
223 |
int *num_sectors = &blocklist_func_context.num_sectors; |
224 |
int *num_entries = &blocklist_func_context.num_entries; |
225 |
|
187 |
/* Open the file. */ |
226 |
/* Open the file. */ |
188 |
if (! grub_open (arg)) |
227 |
if (! grub_open (arg)) |
189 |
return 1; |
228 |
return 1; |
Lines 202-216
Link Here
|
202 |
grub_printf (")"); |
241 |
grub_printf (")"); |
203 |
|
242 |
|
204 |
/* Read in the whole file to DUMMY. */ |
243 |
/* Read in the whole file to DUMMY. */ |
205 |
disk_read_hook = disk_read_blocklist_func; |
244 |
disk_read_hook = blocklist_read_helper; |
206 |
if (! grub_read (dummy, -1)) |
245 |
if (! grub_read (dummy, -1)) |
207 |
goto fail; |
246 |
goto fail; |
208 |
|
247 |
|
209 |
/* The last entry may not be printed yet. Don't check if it is a |
248 |
/* The last entry may not be printed yet. Don't check if it is a |
210 |
* full sector, since it doesn't matter if we read too much. */ |
249 |
* full sector, since it doesn't matter if we read too much. */ |
211 |
if (num_sectors > 0) |
250 |
if (*num_sectors > 0) |
212 |
grub_printf ("%s%d+%d", num_entries ? "," : "", |
251 |
grub_printf ("%s%d+%d", *num_entries ? "," : "", |
213 |
start_sector - part_start, num_sectors); |
252 |
*start_sector - part_start, *num_sectors); |
214 |
|
253 |
|
215 |
grub_printf ("\n"); |
254 |
grub_printf ("\n"); |
216 |
|
255 |
|
Lines 587-594
Link Here
|
587 |
"white" |
626 |
"white" |
588 |
}; |
627 |
}; |
589 |
|
628 |
|
|
|
629 |
auto int color_number (char *str); |
630 |
|
590 |
/* Convert the color name STR into the magical number. */ |
631 |
/* Convert the color name STR into the magical number. */ |
591 |
static int color_number (char *str) |
632 |
auto int color_number (char *str) |
592 |
{ |
633 |
{ |
593 |
char *ptr; |
634 |
char *ptr; |
594 |
int i; |
635 |
int i; |
Lines 846-851
Link Here
|
846 |
}; |
887 |
}; |
847 |
#endif /* SUPPORT_NETBOOT */ |
888 |
#endif /* SUPPORT_NETBOOT */ |
848 |
|
889 |
|
|
|
890 |
static int terminal_func (char *arg, int flags); |
891 |
|
892 |
#ifdef SUPPORT_GRAPHICS |
893 |
|
894 |
static int splashimage_func(char *arg, int flags) { |
895 |
char splashimage[64]; |
896 |
int i; |
897 |
|
898 |
/* filename can only be 64 characters due to our buffer size */ |
899 |
if (strlen(arg) > 63) |
900 |
return 1; |
901 |
if (flags == BUILTIN_CMDLINE) { |
902 |
if (!grub_open(arg)) |
903 |
return 1; |
904 |
grub_close(); |
905 |
} |
906 |
|
907 |
strcpy(splashimage, arg); |
908 |
|
909 |
/* get rid of TERM_NEED_INIT from the graphics terminal. */ |
910 |
for (i = 0; term_table[i].name; i++) { |
911 |
if (grub_strcmp (term_table[i].name, "graphics") == 0) { |
912 |
term_table[i].flags &= ~TERM_NEED_INIT; |
913 |
break; |
914 |
} |
915 |
} |
916 |
|
917 |
graphics_set_splash(splashimage); |
918 |
|
919 |
if (flags == BUILTIN_CMDLINE && graphics_inited) { |
920 |
graphics_end(); |
921 |
graphics_init(); |
922 |
graphics_cls(); |
923 |
} |
924 |
|
925 |
/* FIXME: should we be explicitly switching the terminal as a |
926 |
* side effect here? */ |
927 |
terminal_func("graphics", flags); |
928 |
|
929 |
return 0; |
930 |
} |
931 |
|
932 |
static struct builtin builtin_splashimage = |
933 |
{ |
934 |
"splashimage", |
935 |
splashimage_func, |
936 |
BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, |
937 |
"splashimage FILE", |
938 |
"Load FILE as the background image when in graphics mode." |
939 |
}; |
940 |
|
941 |
|
942 |
/* foreground */ |
943 |
static int |
944 |
foreground_func(char *arg, int flags) |
945 |
{ |
946 |
if (grub_strlen(arg) == 6) { |
947 |
int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2; |
948 |
int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2; |
949 |
int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2; |
950 |
|
951 |
foreground = (r << 16) | (g << 8) | b; |
952 |
if (graphics_inited) |
953 |
graphics_set_palette(15, r, g, b); |
954 |
|
955 |
return (0); |
956 |
} |
957 |
|
958 |
return (1); |
959 |
} |
960 |
|
961 |
static struct builtin builtin_foreground = |
962 |
{ |
963 |
"foreground", |
964 |
foreground_func, |
965 |
BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, |
966 |
"foreground RRGGBB", |
967 |
"Sets the foreground color when in graphics mode." |
968 |
"RR is red, GG is green, and BB blue. Numbers must be in hexadecimal." |
969 |
}; |
970 |
|
971 |
|
972 |
/* background */ |
973 |
static int |
974 |
background_func(char *arg, int flags) |
975 |
{ |
976 |
if (grub_strlen(arg) == 6) { |
977 |
int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2; |
978 |
int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2; |
979 |
int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2; |
980 |
|
981 |
background = (r << 16) | (g << 8) | b; |
982 |
if (graphics_inited) |
983 |
graphics_set_palette(0, r, g, b); |
984 |
return (0); |
985 |
} |
986 |
|
987 |
return (1); |
988 |
} |
989 |
|
990 |
static struct builtin builtin_background = |
991 |
{ |
992 |
"background", |
993 |
background_func, |
994 |
BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, |
995 |
"background RRGGBB", |
996 |
"Sets the background color when in graphics mode." |
997 |
"RR is red, GG is green, and BB blue. Numbers must be in hexadecimal." |
998 |
}; |
999 |
|
1000 |
#endif /* SUPPORT_GRAPHICS */ |
1001 |
|
1002 |
|
1003 |
/* clear */ |
1004 |
static int |
1005 |
clear_func() |
1006 |
{ |
1007 |
if (current_term->cls) |
1008 |
current_term->cls(); |
1009 |
|
1010 |
return 0; |
1011 |
} |
1012 |
|
1013 |
static struct builtin builtin_clear = |
1014 |
{ |
1015 |
"clear", |
1016 |
clear_func, |
1017 |
BUILTIN_CMDLINE | BUILTIN_HELP_LIST, |
1018 |
"clear", |
1019 |
"Clear the screen" |
1020 |
}; |
1021 |
|
849 |
|
1022 |
|
850 |
/* displayapm */ |
1023 |
/* displayapm */ |
851 |
static int |
1024 |
static int |
Lines 1143-1151
Link Here
|
1143 |
static int |
1316 |
static int |
1144 |
fallback_func (char *arg, int flags) |
1317 |
fallback_func (char *arg, int flags) |
1145 |
{ |
1318 |
{ |
1146 |
if (! safe_parse_maxint (&arg, &fallback_entry)) |
1319 |
int i = 0; |
1147 |
return 1; |
1320 |
|
|
|
1321 |
while (*arg) |
1322 |
{ |
1323 |
int entry; |
1324 |
int j; |
1325 |
|
1326 |
if (! safe_parse_maxint (&arg, &entry)) |
1327 |
return 1; |
1328 |
|
1329 |
/* Remove duplications to prevent infinite looping. */ |
1330 |
for (j = 0; j < i; j++) |
1331 |
if (entry == fallback_entries[j]) |
1332 |
break; |
1333 |
if (j != i) |
1334 |
continue; |
1335 |
|
1336 |
fallback_entries[i++] = entry; |
1337 |
if (i == MAX_FALLBACK_ENTRIES) |
1338 |
break; |
1339 |
|
1340 |
arg = skip_to (0, arg); |
1341 |
} |
1148 |
|
1342 |
|
|
|
1343 |
if (i < MAX_FALLBACK_ENTRIES) |
1344 |
fallback_entries[i] = -1; |
1345 |
|
1346 |
fallback_entryno = (i == 0) ? -1 : 0; |
1347 |
|
1149 |
return 0; |
1348 |
return 0; |
1150 |
} |
1349 |
} |
1151 |
|
1350 |
|
Lines 1155-1161
Link Here
|
1155 |
fallback_func, |
1354 |
fallback_func, |
1156 |
BUILTIN_MENU, |
1355 |
BUILTIN_MENU, |
1157 |
#if 0 |
1356 |
#if 0 |
1158 |
"fallback NUM", |
1357 |
"fallback NUM...", |
1159 |
"Go into unattended boot mode: if the default boot entry has any" |
1358 |
"Go into unattended boot mode: if the default boot entry has any" |
1160 |
" errors, instead of waiting for the user to do anything, it" |
1359 |
" errors, instead of waiting for the user to do anything, it" |
1161 |
" immediately starts over using the NUM entry (same numbering as the" |
1360 |
" immediately starts over using the NUM entry (same numbering as the" |
Lines 1708-1713
Link Here
|
1708 |
|
1907 |
|
1709 |
|
1908 |
|
1710 |
/* install */ |
1909 |
/* install */ |
|
|
1910 |
static struct { |
1911 |
int saved_sector; |
1912 |
int installaddr; |
1913 |
int installlist; |
1914 |
char *stage2_first_buffer; |
1915 |
} install_func_context = { |
1916 |
.saved_sector = 0, |
1917 |
.installaddr = 0, |
1918 |
.installlist = 0, |
1919 |
.stage2_first_buffer = NULL, |
1920 |
}; |
1921 |
|
1922 |
/* Save the first sector of Stage2 in STAGE2_SECT. */ |
1923 |
/* Formerly disk_read_savesect_func with local scope inside install_func */ |
1924 |
static void |
1925 |
install_savesect_helper(int sector, int offset, int length) |
1926 |
{ |
1927 |
if (debug) |
1928 |
printf ("[%d]", sector); |
1929 |
|
1930 |
/* ReiserFS has files which sometimes contain data not aligned |
1931 |
on sector boundaries. Returning an error is better than |
1932 |
silently failing. */ |
1933 |
if (offset != 0 || length != SECTOR_SIZE) |
1934 |
errnum = ERR_UNALIGNED; |
1935 |
|
1936 |
install_func_context.saved_sector = sector; |
1937 |
} |
1938 |
|
1939 |
/* Write SECTOR to INSTALLLIST, and update INSTALLADDR and INSTALLSECT. */ |
1940 |
/* Formerly disk_read_blocklist_func with local scope inside install_func */ |
1941 |
static void |
1942 |
install_blocklist_helper (int sector, int offset, int length) |
1943 |
{ |
1944 |
int *installaddr = &install_func_context.installaddr; |
1945 |
int *installlist = &install_func_context.installlist; |
1946 |
char **stage2_first_buffer = &install_func_context.stage2_first_buffer; |
1947 |
/* Was the last sector full? */ |
1948 |
static int last_length = SECTOR_SIZE; |
1949 |
|
1950 |
if (debug) |
1951 |
printf("[%d]", sector); |
1952 |
|
1953 |
if (offset != 0 || last_length != SECTOR_SIZE) |
1954 |
{ |
1955 |
/* We found a non-sector-aligned data block. */ |
1956 |
errnum = ERR_UNALIGNED; |
1957 |
return; |
1958 |
} |
1959 |
|
1960 |
last_length = length; |
1961 |
|
1962 |
if (*((unsigned long *) (*installlist - 4)) |
1963 |
+ *((unsigned short *) *installlist) != sector |
1964 |
|| *installlist == (int) *stage2_first_buffer + SECTOR_SIZE + 4) |
1965 |
{ |
1966 |
*installlist -= 8; |
1967 |
|
1968 |
if (*((unsigned long *) (*installlist - 8))) |
1969 |
errnum = ERR_WONT_FIT; |
1970 |
else |
1971 |
{ |
1972 |
*((unsigned short *) (*installlist + 2)) = (*installaddr >> 4); |
1973 |
*((unsigned long *) (*installlist - 4)) = sector; |
1974 |
} |
1975 |
} |
1976 |
|
1977 |
*((unsigned short *) *installlist) += 1; |
1978 |
*installaddr += 512; |
1979 |
} |
1980 |
|
1711 |
static int |
1981 |
static int |
1712 |
install_func (char *arg, int flags) |
1982 |
install_func (char *arg, int flags) |
1713 |
{ |
1983 |
{ |
Lines 1715-1734
Link Here
|
1715 |
char *stage1_buffer = (char *) RAW_ADDR (0x100000); |
1985 |
char *stage1_buffer = (char *) RAW_ADDR (0x100000); |
1716 |
char *stage2_buffer = stage1_buffer + SECTOR_SIZE; |
1986 |
char *stage2_buffer = stage1_buffer + SECTOR_SIZE; |
1717 |
char *old_sect = stage2_buffer + SECTOR_SIZE; |
1987 |
char *old_sect = stage2_buffer + SECTOR_SIZE; |
1718 |
char *stage2_first_buffer = old_sect + SECTOR_SIZE; |
1988 |
/* stage2_first_buffer used to be defined as: |
1719 |
char *stage2_second_buffer = stage2_first_buffer + SECTOR_SIZE; |
1989 |
* char *stage2_first_buffer = old_sect + SECTOR_SIZE; */ |
|
|
1990 |
char **stage2_first_buffer = &install_func_context.stage2_first_buffer; |
1991 |
/* and stage2_second_buffer was: |
1992 |
* char *stage2_second_buffer = stage2_first_buffer + SECTOR_SIZE; */ |
1993 |
char *stage2_second_buffer = old_sect + SECTOR_SIZE + SECTOR_SIZE; |
1720 |
/* XXX: Probably SECTOR_SIZE is reasonable. */ |
1994 |
/* XXX: Probably SECTOR_SIZE is reasonable. */ |
1721 |
char *config_filename = stage2_second_buffer + SECTOR_SIZE; |
1995 |
char *config_filename = stage2_second_buffer + SECTOR_SIZE; |
1722 |
char *dummy = config_filename + SECTOR_SIZE; |
1996 |
char *dummy = config_filename + SECTOR_SIZE; |
1723 |
int new_drive = 0xFF; |
1997 |
int new_drive = GRUB_INVALID_DRIVE; |
1724 |
int dest_drive, dest_partition, dest_sector; |
1998 |
int dest_drive, dest_partition, dest_sector; |
1725 |
int src_drive, src_partition, src_part_start; |
1999 |
int src_drive, src_partition, src_part_start; |
1726 |
int i; |
2000 |
int i; |
1727 |
struct geometry dest_geom, src_geom; |
2001 |
struct geometry dest_geom, src_geom; |
1728 |
int saved_sector; |
2002 |
int *saved_sector = &install_func_context.saved_sector; |
1729 |
int stage2_first_sector, stage2_second_sector; |
2003 |
int stage2_first_sector, stage2_second_sector; |
1730 |
char *ptr; |
2004 |
char *ptr; |
1731 |
int installaddr, installlist; |
2005 |
int *installaddr = &install_func_context.installaddr; |
|
|
2006 |
int *installlist = &install_func_context.installlist; |
1732 |
/* Point to the location of the name of a configuration file in Stage 2. */ |
2007 |
/* Point to the location of the name of a configuration file in Stage 2. */ |
1733 |
char *config_file_location; |
2008 |
char *config_file_location; |
1734 |
/* If FILE is a Stage 1.5? */ |
2009 |
/* If FILE is a Stage 1.5? */ |
Lines 1737-1800
Link Here
|
1737 |
int is_open = 0; |
2012 |
int is_open = 0; |
1738 |
/* If LBA is forced? */ |
2013 |
/* If LBA is forced? */ |
1739 |
int is_force_lba = 0; |
2014 |
int is_force_lba = 0; |
1740 |
/* Was the last sector full? */ |
|
|
1741 |
int last_length = SECTOR_SIZE; |
1742 |
|
1743 |
#ifdef GRUB_UTIL |
2015 |
#ifdef GRUB_UTIL |
1744 |
/* If the Stage 2 is in a partition mounted by an OS, this will store |
2016 |
/* If the Stage 2 is in a partition mounted by an OS, this will store |
1745 |
the filename under the OS. */ |
2017 |
the filename under the OS. */ |
1746 |
char *stage2_os_file = 0; |
2018 |
char *stage2_os_file = 0; |
1747 |
#endif /* GRUB_UTIL */ |
2019 |
#endif /* GRUB_UTIL */ |
1748 |
|
|
|
1749 |
/* Save the first sector of Stage2 in STAGE2_SECT. */ |
1750 |
static void disk_read_savesect_func (int sector, int offset, int length) |
1751 |
{ |
1752 |
if (debug) |
1753 |
printf ("[%d]", sector); |
1754 |
|
1755 |
/* ReiserFS has files which sometimes contain data not aligned |
1756 |
on sector boundaries. Returning an error is better than |
1757 |
silently failing. */ |
1758 |
if (offset != 0 || length != SECTOR_SIZE) |
1759 |
errnum = ERR_UNALIGNED; |
1760 |
|
2020 |
|
1761 |
saved_sector = sector; |
2021 |
*stage2_first_buffer = old_sect + SECTOR_SIZE; |
1762 |
} |
|
|
1763 |
|
1764 |
/* Write SECTOR to INSTALLLIST, and update INSTALLADDR and |
1765 |
INSTALLSECT. */ |
1766 |
static void disk_read_blocklist_func (int sector, int offset, int length) |
1767 |
{ |
1768 |
if (debug) |
1769 |
printf("[%d]", sector); |
1770 |
|
1771 |
if (offset != 0 || last_length != SECTOR_SIZE) |
1772 |
{ |
1773 |
/* We found a non-sector-aligned data block. */ |
1774 |
errnum = ERR_UNALIGNED; |
1775 |
return; |
1776 |
} |
1777 |
|
1778 |
last_length = length; |
1779 |
|
1780 |
if (*((unsigned long *) (installlist - 4)) |
1781 |
+ *((unsigned short *) installlist) != sector |
1782 |
|| installlist == (int) stage2_first_buffer + SECTOR_SIZE + 4) |
1783 |
{ |
1784 |
installlist -= 8; |
1785 |
|
1786 |
if (*((unsigned long *) (installlist - 8))) |
1787 |
errnum = ERR_WONT_FIT; |
1788 |
else |
1789 |
{ |
1790 |
*((unsigned short *) (installlist + 2)) = (installaddr >> 4); |
1791 |
*((unsigned long *) (installlist - 4)) = sector; |
1792 |
} |
1793 |
} |
1794 |
|
1795 |
*((unsigned short *) installlist) += 1; |
1796 |
installaddr += 512; |
1797 |
} |
1798 |
|
2022 |
|
1799 |
/* First, check the GNU-style long option. */ |
2023 |
/* First, check the GNU-style long option. */ |
1800 |
while (1) |
2024 |
while (1) |
Lines 1827-1836
Link Here
|
1827 |
addr = skip_to (0, file); |
2051 |
addr = skip_to (0, file); |
1828 |
|
2052 |
|
1829 |
/* Get the installation address. */ |
2053 |
/* Get the installation address. */ |
1830 |
if (! safe_parse_maxint (&addr, &installaddr)) |
2054 |
if (! safe_parse_maxint (&addr, installaddr)) |
1831 |
{ |
2055 |
{ |
1832 |
/* ADDR is not specified. */ |
2056 |
/* ADDR is not specified. */ |
1833 |
installaddr = 0; |
2057 |
*installaddr = 0; |
1834 |
ptr = addr; |
2058 |
ptr = addr; |
1835 |
errnum = 0; |
2059 |
errnum = 0; |
1836 |
} |
2060 |
} |
Lines 1924-1940
Link Here
|
1924 |
= (dest_drive & BIOS_FLAG_FIXED_DISK); |
2148 |
= (dest_drive & BIOS_FLAG_FIXED_DISK); |
1925 |
|
2149 |
|
1926 |
/* Read the first sector of Stage 2. */ |
2150 |
/* Read the first sector of Stage 2. */ |
1927 |
disk_read_hook = disk_read_savesect_func; |
2151 |
disk_read_hook = install_savesect_helper; |
1928 |
if (grub_read (stage2_first_buffer, SECTOR_SIZE) != SECTOR_SIZE) |
2152 |
if (grub_read (*stage2_first_buffer, SECTOR_SIZE) != SECTOR_SIZE) |
1929 |
goto fail; |
2153 |
goto fail; |
1930 |
|
2154 |
|
1931 |
stage2_first_sector = saved_sector; |
2155 |
stage2_first_sector = *saved_sector; |
1932 |
|
2156 |
|
1933 |
/* Read the second sector of Stage 2. */ |
2157 |
/* Read the second sector of Stage 2. */ |
1934 |
if (grub_read (stage2_second_buffer, SECTOR_SIZE) != SECTOR_SIZE) |
2158 |
if (grub_read (stage2_second_buffer, SECTOR_SIZE) != SECTOR_SIZE) |
1935 |
goto fail; |
2159 |
goto fail; |
1936 |
|
2160 |
|
1937 |
stage2_second_sector = saved_sector; |
2161 |
stage2_second_sector = *saved_sector; |
1938 |
|
2162 |
|
1939 |
/* Check for the version of Stage 2. */ |
2163 |
/* Check for the version of Stage 2. */ |
1940 |
if (*((short *) (stage2_second_buffer + STAGE2_VER_MAJ_OFFS)) |
2164 |
if (*((short *) (stage2_second_buffer + STAGE2_VER_MAJ_OFFS)) |
Lines 1950-1976
Link Here
|
1950 |
|
2174 |
|
1951 |
/* If INSTALLADDR is not specified explicitly in the command-line, |
2175 |
/* If INSTALLADDR is not specified explicitly in the command-line, |
1952 |
determine it by the Stage 2 id. */ |
2176 |
determine it by the Stage 2 id. */ |
1953 |
if (! installaddr) |
2177 |
if (! *installaddr) |
1954 |
{ |
2178 |
{ |
1955 |
if (! is_stage1_5) |
2179 |
if (! is_stage1_5) |
1956 |
/* Stage 2. */ |
2180 |
/* Stage 2. */ |
1957 |
installaddr = 0x8000; |
2181 |
*installaddr = 0x8000; |
1958 |
else |
2182 |
else |
1959 |
/* Stage 1.5. */ |
2183 |
/* Stage 1.5. */ |
1960 |
installaddr = 0x2000; |
2184 |
*installaddr = 0x2000; |
1961 |
} |
2185 |
} |
1962 |
|
2186 |
|
1963 |
*((unsigned long *) (stage1_buffer + STAGE1_STAGE2_SECTOR)) |
2187 |
*((unsigned long *) (stage1_buffer + STAGE1_STAGE2_SECTOR)) |
1964 |
= stage2_first_sector; |
2188 |
= stage2_first_sector; |
1965 |
*((unsigned short *) (stage1_buffer + STAGE1_STAGE2_ADDRESS)) |
2189 |
*((unsigned short *) (stage1_buffer + STAGE1_STAGE2_ADDRESS)) |
1966 |
= installaddr; |
2190 |
= *installaddr; |
1967 |
*((unsigned short *) (stage1_buffer + STAGE1_STAGE2_SEGMENT)) |
2191 |
*((unsigned short *) (stage1_buffer + STAGE1_STAGE2_SEGMENT)) |
1968 |
= installaddr >> 4; |
2192 |
= *installaddr >> 4; |
1969 |
|
2193 |
|
1970 |
i = (int) stage2_first_buffer + SECTOR_SIZE - 4; |
2194 |
i = (int) *stage2_first_buffer + SECTOR_SIZE - 4; |
1971 |
while (*((unsigned long *) i)) |
2195 |
while (*((unsigned long *) i)) |
1972 |
{ |
2196 |
{ |
1973 |
if (i < (int) stage2_first_buffer |
2197 |
if (i < (int) *stage2_first_buffer |
1974 |
|| (*((int *) (i - 4)) & 0x80000000) |
2198 |
|| (*((int *) (i - 4)) & 0x80000000) |
1975 |
|| *((unsigned short *) i) >= 0xA00 |
2199 |
|| *((unsigned short *) i) >= 0xA00 |
1976 |
|| *((short *) (i + 2)) == 0) |
2200 |
|| *((short *) (i + 2)) == 0) |
Lines 1984-1996
Link Here
|
1984 |
i -= 8; |
2208 |
i -= 8; |
1985 |
} |
2209 |
} |
1986 |
|
2210 |
|
1987 |
installlist = (int) stage2_first_buffer + SECTOR_SIZE + 4; |
2211 |
*installlist = (int) *stage2_first_buffer + SECTOR_SIZE + 4; |
1988 |
installaddr += SECTOR_SIZE; |
2212 |
*installaddr += SECTOR_SIZE; |
1989 |
|
2213 |
|
1990 |
/* Read the whole of Stage2 except for the first sector. */ |
2214 |
/* Read the whole of Stage2 except for the first sector. */ |
1991 |
grub_seek (SECTOR_SIZE); |
2215 |
grub_seek (SECTOR_SIZE); |
1992 |
|
2216 |
|
1993 |
disk_read_hook = disk_read_blocklist_func; |
2217 |
disk_read_hook = install_blocklist_helper; |
1994 |
if (! grub_read (dummy, -1)) |
2218 |
if (! grub_read (dummy, -1)) |
1995 |
goto fail; |
2219 |
goto fail; |
1996 |
|
2220 |
|
Lines 2051-2057
Link Here
|
2051 |
/* If the drive where the Stage 2 resides is the same as |
2275 |
/* If the drive where the Stage 2 resides is the same as |
2052 |
the one where the Stage 1.5 resides, do not embed the |
2276 |
the one where the Stage 1.5 resides, do not embed the |
2053 |
drive number. */ |
2277 |
drive number. */ |
2054 |
current_drive = 0xFF; |
2278 |
current_drive = GRUB_INVALID_DRIVE; |
2055 |
} |
2279 |
} |
2056 |
|
2280 |
|
2057 |
device = (current_drive << 24) | current_partition; |
2281 |
device = (current_drive << 24) | current_partition; |
Lines 2073-2079
Link Here
|
2073 |
/* Skip the first sector. */ |
2297 |
/* Skip the first sector. */ |
2074 |
grub_seek (SECTOR_SIZE); |
2298 |
grub_seek (SECTOR_SIZE); |
2075 |
|
2299 |
|
2076 |
disk_read_hook = disk_read_savesect_func; |
2300 |
disk_read_hook = install_savesect_helper; |
2077 |
if (grub_read (stage2_buffer, SECTOR_SIZE) != SECTOR_SIZE) |
2301 |
if (grub_read (stage2_buffer, SECTOR_SIZE) != SECTOR_SIZE) |
2078 |
goto fail; |
2302 |
goto fail; |
2079 |
|
2303 |
|
Lines 2143-2149
Link Here
|
2143 |
else |
2367 |
else |
2144 |
#endif /* GRUB_UTIL */ |
2368 |
#endif /* GRUB_UTIL */ |
2145 |
{ |
2369 |
{ |
2146 |
if (! devwrite (saved_sector - part_start, 1, stage2_buffer)) |
2370 |
if (! devwrite (*saved_sector - part_start, 1, stage2_buffer)) |
2147 |
goto fail; |
2371 |
goto fail; |
2148 |
} |
2372 |
} |
2149 |
} |
2373 |
} |
Lines 2165-2171
Link Here
|
2165 |
goto fail; |
2389 |
goto fail; |
2166 |
} |
2390 |
} |
2167 |
|
2391 |
|
2168 |
if (fwrite (stage2_first_buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE) |
2392 |
if (fwrite (*stage2_first_buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE) |
2169 |
{ |
2393 |
{ |
2170 |
fclose (fp); |
2394 |
fclose (fp); |
2171 |
errnum = ERR_WRITE; |
2395 |
errnum = ERR_WRITE; |
Lines 2192-2198
Link Here
|
2192 |
goto fail; |
2416 |
goto fail; |
2193 |
|
2417 |
|
2194 |
if (! devwrite (stage2_first_sector - src_part_start, 1, |
2418 |
if (! devwrite (stage2_first_sector - src_part_start, 1, |
2195 |
stage2_first_buffer)) |
2419 |
*stage2_first_buffer)) |
2196 |
goto fail; |
2420 |
goto fail; |
2197 |
|
2421 |
|
2198 |
if (! devwrite (stage2_second_sector - src_part_start, 1, |
2422 |
if (! devwrite (stage2_second_sector - src_part_start, 1, |
Lines 3185-3192
Link Here
|
3185 |
savedefault_func (char *arg, int flags) |
3409 |
savedefault_func (char *arg, int flags) |
3186 |
{ |
3410 |
{ |
3187 |
#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL) |
3411 |
#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL) |
3188 |
char buffer[512]; |
3412 |
unsigned long tmp_drive = saved_drive; |
3189 |
int *entryno_ptr; |
3413 |
unsigned long tmp_partition = saved_partition; |
|
|
3414 |
char *default_file = (char *) DEFAULT_FILE_BUF; |
3415 |
char buf[10]; |
3416 |
char sect[SECTOR_SIZE]; |
3417 |
int entryno; |
3418 |
int sector_count = 0; |
3419 |
int saved_sectors[2]; |
3420 |
int saved_offsets[2]; |
3421 |
int saved_lengths[2]; |
3422 |
|
3423 |
/* Save sector information about at most two sectors. */ |
3424 |
auto void disk_read_savesect_func (int sector, int offset, int length); |
3425 |
void disk_read_savesect_func (int sector, int offset, int length) |
3426 |
{ |
3427 |
if (sector_count < 2) |
3428 |
{ |
3429 |
saved_sectors[sector_count] = sector; |
3430 |
saved_offsets[sector_count] = offset; |
3431 |
saved_lengths[sector_count] = length; |
3432 |
} |
3433 |
sector_count++; |
3434 |
} |
3190 |
|
3435 |
|
3191 |
/* This command is only useful when you boot an entry from the menu |
3436 |
/* This command is only useful when you boot an entry from the menu |
3192 |
interface. */ |
3437 |
interface. */ |
Lines 3195-3240
Link Here
|
3195 |
errnum = ERR_UNRECOGNIZED; |
3440 |
errnum = ERR_UNRECOGNIZED; |
3196 |
return 1; |
3441 |
return 1; |
3197 |
} |
3442 |
} |
3198 |
|
|
|
3199 |
/* Get the geometry of the boot drive (i.e. the disk which contains |
3200 |
this stage2). */ |
3201 |
if (get_diskinfo (boot_drive, &buf_geom)) |
3202 |
{ |
3203 |
errnum = ERR_NO_DISK; |
3204 |
return 1; |
3205 |
} |
3206 |
|
3443 |
|
3207 |
/* Load the second sector of this stage2. */ |
3444 |
/* Determine a saved entry number. */ |
3208 |
if (! rawread (boot_drive, install_second_sector, 0, SECTOR_SIZE, buffer)) |
3445 |
if (*arg) |
3209 |
{ |
3446 |
{ |
3210 |
return 1; |
3447 |
if (grub_memcmp (arg, "fallback", sizeof ("fallback") - 1) == 0) |
3211 |
} |
3448 |
{ |
|
|
3449 |
int i; |
3450 |
int index = 0; |
3451 |
|
3452 |
for (i = 0; i < MAX_FALLBACK_ENTRIES; i++) |
3453 |
{ |
3454 |
if (fallback_entries[i] < 0) |
3455 |
break; |
3456 |
if (fallback_entries[i] == current_entryno) |
3457 |
{ |
3458 |
index = i + 1; |
3459 |
break; |
3460 |
} |
3461 |
} |
3462 |
|
3463 |
if (index >= MAX_FALLBACK_ENTRIES || fallback_entries[index] < 0) |
3464 |
{ |
3465 |
/* This is the last. */ |
3466 |
errnum = ERR_BAD_ARGUMENT; |
3467 |
return 1; |
3468 |
} |
3212 |
|
3469 |
|
3213 |
/* Sanity check. */ |
3470 |
entryno = fallback_entries[index]; |
3214 |
if (buffer[STAGE2_STAGE2_ID] != STAGE2_ID_STAGE2 |
3471 |
} |
3215 |
|| *((short *) (buffer + STAGE2_VER_MAJ_OFFS)) != COMPAT_VERSION) |
3472 |
else if (! safe_parse_maxint (&arg, &entryno)) |
3216 |
{ |
3473 |
return 1; |
3217 |
errnum = ERR_BAD_VERSION; |
|
|
3218 |
return 1; |
3219 |
} |
3474 |
} |
3220 |
|
3475 |
else |
3221 |
entryno_ptr = (int *) (buffer + STAGE2_SAVED_ENTRYNO); |
3476 |
entryno = current_entryno; |
3222 |
|
3477 |
|
3223 |
/* Check if the saved entry number differs from current entry number. */ |
3478 |
/* Open the default file. */ |
3224 |
if (*entryno_ptr != current_entryno) |
3479 |
saved_drive = boot_drive; |
3225 |
{ |
3480 |
saved_partition = install_partition; |
3226 |
/* Overwrite the saved entry number. */ |
3481 |
if (grub_open (default_file)) |
3227 |
*entryno_ptr = current_entryno; |
3482 |
{ |
|
|
3483 |
int len; |
3484 |
|
3485 |
disk_read_hook = disk_read_savesect_func; |
3486 |
len = grub_read (buf, sizeof (buf)); |
3487 |
disk_read_hook = 0; |
3488 |
grub_close (); |
3228 |
|
3489 |
|
3229 |
/* Save the image in the disk. */ |
3490 |
if (len != sizeof (buf)) |
3230 |
if (! rawwrite (boot_drive, install_second_sector, buffer)) |
3491 |
{ |
3231 |
return 1; |
3492 |
/* This is too small. Do not modify the file manually, please! */ |
|
|
3493 |
errnum = ERR_READ; |
3494 |
goto fail; |
3495 |
} |
3496 |
|
3497 |
if (sector_count > 2) |
3498 |
{ |
3499 |
/* Is this possible?! Too fragmented! */ |
3500 |
errnum = ERR_FSYS_CORRUPT; |
3501 |
goto fail; |
3502 |
} |
3232 |
|
3503 |
|
|
|
3504 |
/* Set up a string to be written. */ |
3505 |
grub_memset (buf, '\n', sizeof (buf)); |
3506 |
grub_sprintf (buf, "%d", entryno); |
3507 |
|
3508 |
if (saved_lengths[0] < sizeof (buf)) |
3509 |
{ |
3510 |
/* The file is anchored to another file and the first few bytes |
3511 |
are spanned in two sectors. Uggh... */ |
3512 |
if (! rawread (current_drive, saved_sectors[0], 0, SECTOR_SIZE, |
3513 |
sect)) |
3514 |
goto fail; |
3515 |
grub_memmove (sect + saved_offsets[0], buf, saved_lengths[0]); |
3516 |
if (! rawwrite (current_drive, saved_sectors[0], sect)) |
3517 |
goto fail; |
3518 |
|
3519 |
if (! rawread (current_drive, saved_sectors[1], 0, SECTOR_SIZE, |
3520 |
sect)) |
3521 |
goto fail; |
3522 |
grub_memmove (sect + saved_offsets[1], |
3523 |
buf + saved_lengths[0], |
3524 |
sizeof (buf) - saved_lengths[0]); |
3525 |
if (! rawwrite (current_drive, saved_sectors[1], sect)) |
3526 |
goto fail; |
3527 |
} |
3528 |
else |
3529 |
{ |
3530 |
/* This is a simple case. It fits into a single sector. */ |
3531 |
if (! rawread (current_drive, saved_sectors[0], 0, SECTOR_SIZE, |
3532 |
sect)) |
3533 |
goto fail; |
3534 |
grub_memmove (sect + saved_offsets[0], buf, sizeof (buf)); |
3535 |
if (! rawwrite (current_drive, saved_sectors[0], sect)) |
3536 |
goto fail; |
3537 |
} |
3538 |
|
3233 |
/* Clear the cache. */ |
3539 |
/* Clear the cache. */ |
3234 |
buf_track = -1; |
3540 |
buf_track = -1; |
3235 |
} |
3541 |
} |
3236 |
|
3542 |
|
3237 |
return 0; |
3543 |
fail: |
|
|
3544 |
saved_drive = tmp_drive; |
3545 |
saved_partition = tmp_partition; |
3546 |
return errnum; |
3238 |
#else /* ! SUPPORT_DISKLESS && ! GRUB_UTIL */ |
3547 |
#else /* ! SUPPORT_DISKLESS && ! GRUB_UTIL */ |
3239 |
errnum = ERR_UNRECOGNIZED; |
3548 |
errnum = ERR_UNRECOGNIZED; |
3240 |
return 1; |
3549 |
return 1; |
Lines 3246-3253
Link Here
|
3246 |
"savedefault", |
3555 |
"savedefault", |
3247 |
savedefault_func, |
3556 |
savedefault_func, |
3248 |
BUILTIN_CMDLINE, |
3557 |
BUILTIN_CMDLINE, |
3249 |
"savedefault", |
3558 |
"savedefault [NUM | `fallback']", |
3250 |
"Save the current entry as the default boot entry." |
3559 |
"Save the current entry as the default boot entry if no argument is" |
|
|
3560 |
" specified. If a number is specified, this number is saved. If" |
3561 |
" `fallback' is used, next fallback entry is saved." |
3251 |
}; |
3562 |
}; |
3252 |
|
3563 |
|
3253 |
|
3564 |
|
Lines 3495-3501
Link Here
|
3495 |
int to_code, from_code; |
3806 |
int to_code, from_code; |
3496 |
int map_in_interrupt = 0; |
3807 |
int map_in_interrupt = 0; |
3497 |
|
3808 |
|
3498 |
static int find_key_code (char *key) |
3809 |
auto int find_key_code (char *key); |
|
|
3810 |
auto int find_ascii_code (char *key); |
3811 |
|
3812 |
auto int find_key_code (char *key) |
3499 |
{ |
3813 |
{ |
3500 |
int i; |
3814 |
int i; |
3501 |
|
3815 |
|
Lines 3512-3518
Link Here
|
3512 |
return 0; |
3826 |
return 0; |
3513 |
} |
3827 |
} |
3514 |
|
3828 |
|
3515 |
static int find_ascii_code (char *key) |
3829 |
auto int find_ascii_code (char *key) |
3516 |
{ |
3830 |
{ |
3517 |
int i; |
3831 |
int i; |
3518 |
|
3832 |
|
Lines 3747-3753
Link Here
|
3747 |
{ |
4061 |
{ |
3748 |
{"ext2fs", "/e2fs_stage1_5"}, |
4062 |
{"ext2fs", "/e2fs_stage1_5"}, |
3749 |
{"fat", "/fat_stage1_5"}, |
4063 |
{"fat", "/fat_stage1_5"}, |
|
|
4064 |
{"ufs2", "/ufs2_stage1_5"}, |
3750 |
{"ffs", "/ffs_stage1_5"}, |
4065 |
{"ffs", "/ffs_stage1_5"}, |
|
|
4066 |
{"iso9660", "/iso9660_stage1_5"}, |
3751 |
{"jfs", "/jfs_stage1_5"}, |
4067 |
{"jfs", "/jfs_stage1_5"}, |
3752 |
{"minix", "/minix_stage1_5"}, |
4068 |
{"minix", "/minix_stage1_5"}, |
3753 |
{"reiserfs", "/reiserfs_stage1_5"}, |
4069 |
{"reiserfs", "/reiserfs_stage1_5"}, |
Lines 3956-3962
Link Here
|
3956 |
}; |
4272 |
}; |
3957 |
|
4273 |
|
3958 |
|
4274 |
|
3959 |
#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) |
4275 |
#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS) |
3960 |
/* terminal */ |
4276 |
/* terminal */ |
3961 |
static int |
4277 |
static int |
3962 |
terminal_func (char *arg, int flags) |
4278 |
terminal_func (char *arg, int flags) |
Lines 4115-4131
Link Here
|
4115 |
end: |
4431 |
end: |
4116 |
current_term = term_table + default_term; |
4432 |
current_term = term_table + default_term; |
4117 |
current_term->flags = term_flags; |
4433 |
current_term->flags = term_flags; |
4118 |
|
4434 |
|
4119 |
if (lines) |
4435 |
if (lines) |
4120 |
max_lines = lines; |
4436 |
max_lines = lines; |
4121 |
else |
4437 |
else |
4122 |
/* 24 would be a good default value. */ |
4438 |
max_lines = current_term->max_lines; |
4123 |
max_lines = 24; |
4439 |
|
4124 |
|
|
|
4125 |
/* If the interface is currently the command-line, |
4440 |
/* If the interface is currently the command-line, |
4126 |
restart it to repaint the screen. */ |
4441 |
restart it to repaint the screen. */ |
4127 |
if (current_term != prev_term && (flags & BUILTIN_CMDLINE)) |
4442 |
if ((current_term != prev_term) && (flags & BUILTIN_CMDLINE)){ |
|
|
4443 |
if (prev_term->shutdown) |
4444 |
prev_term->shutdown(); |
4445 |
if (current_term->startup) |
4446 |
current_term->startup(); |
4128 |
grub_longjmp (restart_cmdline_env, 0); |
4447 |
grub_longjmp (restart_cmdline_env, 0); |
|
|
4448 |
} |
4129 |
|
4449 |
|
4130 |
return 0; |
4450 |
return 0; |
4131 |
} |
4451 |
} |
Lines 4135-4141
Link Here
|
4135 |
"terminal", |
4455 |
"terminal", |
4136 |
terminal_func, |
4456 |
terminal_func, |
4137 |
BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, |
4457 |
BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, |
4138 |
"terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules]", |
4458 |
"terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules] [graphics]", |
4139 |
"Select a terminal. When multiple terminals are specified, wait until" |
4459 |
"Select a terminal. When multiple terminals are specified, wait until" |
4140 |
" you push any key to continue. If both console and serial are specified," |
4460 |
" you push any key to continue. If both console and serial are specified," |
4141 |
" the terminal to which you input a key first will be selected. If no" |
4461 |
" the terminal to which you input a key first will be selected. If no" |
Lines 4147-4153
Link Here
|
4147 |
" seconds. The option --lines specifies the maximum number of lines." |
4467 |
" seconds. The option --lines specifies the maximum number of lines." |
4148 |
" The option --silent is used to suppress messages." |
4468 |
" The option --silent is used to suppress messages." |
4149 |
}; |
4469 |
}; |
4150 |
#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */ |
4470 |
#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */ |
4151 |
|
4471 |
|
4152 |
|
4472 |
|
4153 |
#ifdef SUPPORT_SERIAL |
4473 |
#ifdef SUPPORT_SERIAL |
Lines 4666-4671
Link Here
|
4666 |
/* The table of builtin commands. Sorted in dictionary order. */ |
4986 |
/* The table of builtin commands. Sorted in dictionary order. */ |
4667 |
struct builtin *builtin_table[] = |
4987 |
struct builtin *builtin_table[] = |
4668 |
{ |
4988 |
{ |
|
|
4989 |
#ifdef SUPPORT_GRAPHICS |
4990 |
&builtin_background, |
4991 |
#endif |
4669 |
&builtin_blocklist, |
4992 |
&builtin_blocklist, |
4670 |
&builtin_boot, |
4993 |
&builtin_boot, |
4671 |
#ifdef SUPPORT_NETBOOT |
4994 |
#ifdef SUPPORT_NETBOOT |
Lines 4673-4678
Link Here
|
4673 |
#endif /* SUPPORT_NETBOOT */ |
4996 |
#endif /* SUPPORT_NETBOOT */ |
4674 |
&builtin_cat, |
4997 |
&builtin_cat, |
4675 |
&builtin_chainloader, |
4998 |
&builtin_chainloader, |
|
|
4999 |
&builtin_clear, |
4676 |
&builtin_cmp, |
5000 |
&builtin_cmp, |
4677 |
&builtin_color, |
5001 |
&builtin_color, |
4678 |
&builtin_configfile, |
5002 |
&builtin_configfile, |
Lines 4692-4697
Link Here
|
4692 |
&builtin_embed, |
5016 |
&builtin_embed, |
4693 |
&builtin_fallback, |
5017 |
&builtin_fallback, |
4694 |
&builtin_find, |
5018 |
&builtin_find, |
|
|
5019 |
#ifdef SUPPORT_GRAPHICS |
5020 |
&builtin_foreground, |
5021 |
#endif |
4695 |
&builtin_fstest, |
5022 |
&builtin_fstest, |
4696 |
&builtin_geometry, |
5023 |
&builtin_geometry, |
4697 |
&builtin_halt, |
5024 |
&builtin_halt, |
Lines 4735-4743
Link Here
|
4735 |
#endif /* SUPPORT_SERIAL */ |
5062 |
#endif /* SUPPORT_SERIAL */ |
4736 |
&builtin_setkey, |
5063 |
&builtin_setkey, |
4737 |
&builtin_setup, |
5064 |
&builtin_setup, |
4738 |
#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) |
5065 |
#ifdef SUPPORT_GRAPHICS |
|
|
5066 |
&builtin_splashimage, |
5067 |
#endif /* SUPPORT_GRAPHICS */ |
5068 |
#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS) |
4739 |
&builtin_terminal, |
5069 |
&builtin_terminal, |
4740 |
#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */ |
5070 |
#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */ |
4741 |
#ifdef SUPPORT_SERIAL |
5071 |
#ifdef SUPPORT_SERIAL |
4742 |
&builtin_terminfo, |
5072 |
&builtin_terminfo, |
4743 |
#endif /* SUPPORT_SERIAL */ |
5073 |
#endif /* SUPPORT_SERIAL */ |