91a9e21903d0f1605cdc9f6cc16c68a29cbd011f
[openwrt/openwrt.git] / package / grub / patches / 010-fixes-1.patch
1 Submitted By: Jim Gifford (jim at linuxfromscratch dot org)
2 Date: 2006-07-04
3 Initial Package Version: 0.97
4 Origin: Debian
5 Upstream Status: Unknown
6 Description: Contains various fixes and enhancements
7 Graphics mode support
8 Fixes for Raid Support
9 XFS Filesystem Boot Freeze Fixes
10 Removed 2GB Memory Limitation
11 Freebsd support
12 Fixes for initrd support
13 Grub installation Fixes
14 Linux 2.6 geometry Fixes
15 Intel Mac Support
16 Autoconf and aclocal updates
17
18 http://trac.cross-lfs.org/browser/trunk/patches/grub-0.97-fixes-1.patch
19
20 --- a/aclocal.m4
21 +++ b/aclocal.m4
22 @@ -1,7 +1,7 @@
23 -# generated automatically by aclocal 1.9.4 -*- Autoconf -*-
24 +# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
25
26 -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
27 -# Free Software Foundation, Inc.
28 +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
29 +# 2005 Free Software Foundation, Inc.
30 # This file is free software; the Free Software Foundation
31 # gives unlimited permission to copy and/or distribute it,
32 # with or without modifications, as long as this notice is preserved.
33 @@ -11,23 +11,11 @@
34 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
35 # PARTICULAR PURPOSE.
36
37 -# -*- Autoconf -*-
38 -# Copyright (C) 2002, 2003 Free Software Foundation, Inc.
39 -# Generated from amversion.in; do not edit by hand.
40 -
41 -# This program is free software; you can redistribute it and/or modify
42 -# it under the terms of the GNU General Public License as published by
43 -# the Free Software Foundation; either version 2, or (at your option)
44 -# any later version.
45 -
46 -# This program is distributed in the hope that it will be useful,
47 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
48 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49 -# GNU General Public License for more details.
50 -
51 -# You should have received a copy of the GNU General Public License
52 -# along with this program; if not, write to the Free Software
53 -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
54 +# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
55 +#
56 +# This file is free software; the Free Software Foundation
57 +# gives unlimited permission to copy and/or distribute it,
58 +# with or without modifications, as long as this notice is preserved.
59
60 # AM_AUTOMAKE_VERSION(VERSION)
61 # ----------------------------
62 @@ -40,26 +28,15 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api
63 # Call AM_AUTOMAKE_VERSION so it can be traced.
64 # This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
65 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
66 - [AM_AUTOMAKE_VERSION([1.9.4])])
67 -
68 -# AM_AUX_DIR_EXPAND
69 -
70 -# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
71 + [AM_AUTOMAKE_VERSION([1.9.6])])
72
73 -# This program is free software; you can redistribute it and/or modify
74 -# it under the terms of the GNU General Public License as published by
75 -# the Free Software Foundation; either version 2, or (at your option)
76 -# any later version.
77 +# AM_AUX_DIR_EXPAND -*- Autoconf -*-
78
79 -# This program is distributed in the hope that it will be useful,
80 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
81 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
82 -# GNU General Public License for more details.
83 -
84 -# You should have received a copy of the GNU General Public License
85 -# along with this program; if not, write to the Free Software
86 -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
87 -# 02111-1307, USA.
88 +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
89 +#
90 +# This file is free software; the Free Software Foundation
91 +# gives unlimited permission to copy and/or distribute it,
92 +# with or without modifications, as long as this notice is preserved.
93
94 # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
95 # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
96 @@ -106,26 +83,16 @@ AC_PREREQ([2.50])dnl
97 am_aux_dir=`cd $ac_aux_dir && pwd`
98 ])
99
100 -# AM_CONDITIONAL -*- Autoconf -*-
101 +# AM_CONDITIONAL -*- Autoconf -*-
102
103 -# Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
104 -
105 -# This program is free software; you can redistribute it and/or modify
106 -# it under the terms of the GNU General Public License as published by
107 -# the Free Software Foundation; either version 2, or (at your option)
108 -# any later version.
109 -
110 -# This program is distributed in the hope that it will be useful,
111 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
112 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
113 -# GNU General Public License for more details.
114 -
115 -# You should have received a copy of the GNU General Public License
116 -# along with this program; if not, write to the Free Software
117 -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
118 -# 02111-1307, USA.
119 +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
120 +# Free Software Foundation, Inc.
121 +#
122 +# This file is free software; the Free Software Foundation
123 +# gives unlimited permission to copy and/or distribute it,
124 +# with or without modifications, as long as this notice is preserved.
125
126 -# serial 6
127 +# serial 7
128
129 # AM_CONDITIONAL(NAME, SHELL-CONDITION)
130 # -------------------------------------
131 @@ -149,26 +116,15 @@ AC_CONFIG_COMMANDS_PRE(
132 Usually this means the macro was only invoked conditionally.]])
133 fi])])
134
135 -# serial 7 -*- Autoconf -*-
136
137 -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
138 +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
139 # Free Software Foundation, Inc.
140 +#
141 +# This file is free software; the Free Software Foundation
142 +# gives unlimited permission to copy and/or distribute it,
143 +# with or without modifications, as long as this notice is preserved.
144
145 -# This program is free software; you can redistribute it and/or modify
146 -# it under the terms of the GNU General Public License as published by
147 -# the Free Software Foundation; either version 2, or (at your option)
148 -# any later version.
149 -
150 -# This program is distributed in the hope that it will be useful,
151 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
152 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
153 -# GNU General Public License for more details.
154 -
155 -# You should have received a copy of the GNU General Public License
156 -# along with this program; if not, write to the Free Software
157 -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
158 -# 02111-1307, USA.
159 -
160 +# serial 8
161
162 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
163 # written in clear, in which case automake, when reading aclocal.m4,
164 @@ -177,7 +133,6 @@ fi])])
165 # CC etc. in the Makefile, will ask for an AC_PROG_CC use...
166
167
168 -
169 # _AM_DEPENDENCIES(NAME)
170 # ----------------------
171 # See how the compiler implements dependency checking.
172 @@ -317,27 +272,16 @@ AM_CONDITIONAL([AMDEP], [test "x$enable_
173 AC_SUBST([AMDEPBACKSLASH])
174 ])
175
176 -# Generate code to set up dependency tracking. -*- Autoconf -*-
177 -
178 -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
179 -# Free Software Foundation, Inc.
180 -
181 -# This program is free software; you can redistribute it and/or modify
182 -# it under the terms of the GNU General Public License as published by
183 -# the Free Software Foundation; either version 2, or (at your option)
184 -# any later version.
185 +# Generate code to set up dependency tracking. -*- Autoconf -*-
186
187 -# This program is distributed in the hope that it will be useful,
188 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
189 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
190 -# GNU General Public License for more details.
191 -
192 -# You should have received a copy of the GNU General Public License
193 -# along with this program; if not, write to the Free Software
194 -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
195 -# 02111-1307, USA.
196 +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
197 +# Free Software Foundation, Inc.
198 +#
199 +# This file is free software; the Free Software Foundation
200 +# gives unlimited permission to copy and/or distribute it,
201 +# with or without modifications, as long as this notice is preserved.
202
203 -#serial 2
204 +#serial 3
205
206 # _AM_OUTPUT_DEPENDENCY_COMMANDS
207 # ------------------------------
208 @@ -396,30 +340,19 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS]
209 [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
210 ])
211
212 -# Do all the work for Automake. -*- Autoconf -*-
213 +# Do all the work for Automake. -*- Autoconf -*-
214
215 -# This macro actually does too much some checks are only needed if
216 -# your package does certain things. But this isn't really a big deal.
217 -
218 -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
219 +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
220 # Free Software Foundation, Inc.
221 +#
222 +# This file is free software; the Free Software Foundation
223 +# gives unlimited permission to copy and/or distribute it,
224 +# with or without modifications, as long as this notice is preserved.
225
226 -# This program is free software; you can redistribute it and/or modify
227 -# it under the terms of the GNU General Public License as published by
228 -# the Free Software Foundation; either version 2, or (at your option)
229 -# any later version.
230 -
231 -# This program is distributed in the hope that it will be useful,
232 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
233 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
234 -# GNU General Public License for more details.
235 -
236 -# You should have received a copy of the GNU General Public License
237 -# along with this program; if not, write to the Free Software
238 -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
239 -# 02111-1307, USA.
240 +# serial 12
241
242 -# serial 11
243 +# This macro actually does too much. Some checks are only needed if
244 +# your package does certain things. But this isn't really a big deal.
245
246 # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
247 # AM_INIT_AUTOMAKE([OPTIONS])
248 @@ -521,51 +454,27 @@ for _am_header in $config_headers :; do
249 done
250 echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
251
252 +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
253 +#
254 +# This file is free software; the Free Software Foundation
255 +# gives unlimited permission to copy and/or distribute it,
256 +# with or without modifications, as long as this notice is preserved.
257 +
258 # AM_PROG_INSTALL_SH
259 # ------------------
260 # Define $install_sh.
261 -
262 -# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
263 -
264 -# This program is free software; you can redistribute it and/or modify
265 -# it under the terms of the GNU General Public License as published by
266 -# the Free Software Foundation; either version 2, or (at your option)
267 -# any later version.
268 -
269 -# This program is distributed in the hope that it will be useful,
270 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
271 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
272 -# GNU General Public License for more details.
273 -
274 -# You should have received a copy of the GNU General Public License
275 -# along with this program; if not, write to the Free Software
276 -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
277 -# 02111-1307, USA.
278 -
279 AC_DEFUN([AM_PROG_INSTALL_SH],
280 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
281 install_sh=${install_sh-"$am_aux_dir/install-sh"}
282 AC_SUBST(install_sh)])
283
284 -# -*- Autoconf -*-
285 -# Copyright (C) 2003 Free Software Foundation, Inc.
286 -
287 -# This program is free software; you can redistribute it and/or modify
288 -# it under the terms of the GNU General Public License as published by
289 -# the Free Software Foundation; either version 2, or (at your option)
290 -# any later version.
291 -
292 -# This program is distributed in the hope that it will be useful,
293 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
294 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
295 -# GNU General Public License for more details.
296 -
297 -# You should have received a copy of the GNU General Public License
298 -# along with this program; if not, write to the Free Software
299 -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
300 -# 02111-1307, USA.
301 +# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
302 +#
303 +# This file is free software; the Free Software Foundation
304 +# gives unlimited permission to copy and/or distribute it,
305 +# with or without modifications, as long as this notice is preserved.
306
307 -# serial 1
308 +# serial 2
309
310 # Check whether the underlying file-system supports filenames
311 # with a leading dot. For instance MS-DOS doesn't.
312 @@ -580,28 +489,17 @@ fi
313 rmdir .tst 2>/dev/null
314 AC_SUBST([am__leading_dot])])
315
316 -# Add --enable-maintainer-mode option to configure.
317 +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
318 # From Jim Meyering
319
320 -# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004
321 +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005
322 # Free Software Foundation, Inc.
323 +#
324 +# This file is free software; the Free Software Foundation
325 +# gives unlimited permission to copy and/or distribute it,
326 +# with or without modifications, as long as this notice is preserved.
327
328 -# This program is free software; you can redistribute it and/or modify
329 -# it under the terms of the GNU General Public License as published by
330 -# the Free Software Foundation; either version 2, or (at your option)
331 -# any later version.
332 -
333 -# This program is distributed in the hope that it will be useful,
334 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
335 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
336 -# GNU General Public License for more details.
337 -
338 -# You should have received a copy of the GNU General Public License
339 -# along with this program; if not, write to the Free Software
340 -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
341 -# 02111-1307, USA.
342 -
343 -# serial 3
344 +# serial 4
345
346 AC_DEFUN([AM_MAINTAINER_MODE],
347 [AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
348 @@ -620,26 +518,15 @@ AC_DEFUN([AM_MAINTAINER_MODE],
349
350 AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
351
352 -# Check to see how 'make' treats includes. -*- Autoconf -*-
353 -
354 -# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
355 +# Check to see how 'make' treats includes. -*- Autoconf -*-
356
357 -# This program is free software; you can redistribute it and/or modify
358 -# it under the terms of the GNU General Public License as published by
359 -# the Free Software Foundation; either version 2, or (at your option)
360 -# any later version.
361 -
362 -# This program is distributed in the hope that it will be useful,
363 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
364 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
365 -# GNU General Public License for more details.
366 -
367 -# You should have received a copy of the GNU General Public License
368 -# along with this program; if not, write to the Free Software
369 -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
370 -# 02111-1307, USA.
371 +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
372 +#
373 +# This file is free software; the Free Software Foundation
374 +# gives unlimited permission to copy and/or distribute it,
375 +# with or without modifications, as long as this notice is preserved.
376
377 -# serial 2
378 +# serial 3
379
380 # AM_MAKE_INCLUDE()
381 # -----------------
382 @@ -683,27 +570,16 @@ AC_MSG_RESULT([$_am_result])
383 rm -f confinc confmf
384 ])
385
386 -# -*- Autoconf -*-
387 -
388 -
389 -# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
390 -
391 -# This program is free software; you can redistribute it and/or modify
392 -# it under the terms of the GNU General Public License as published by
393 -# the Free Software Foundation; either version 2, or (at your option)
394 -# any later version.
395 +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
396
397 -# This program is distributed in the hope that it will be useful,
398 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
399 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
400 -# GNU General Public License for more details.
401 -
402 -# You should have received a copy of the GNU General Public License
403 -# along with this program; if not, write to the Free Software
404 -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
405 -# 02111-1307, USA.
406 +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
407 +# Free Software Foundation, Inc.
408 +#
409 +# This file is free software; the Free Software Foundation
410 +# gives unlimited permission to copy and/or distribute it,
411 +# with or without modifications, as long as this notice is preserved.
412
413 -# serial 3
414 +# serial 4
415
416 # AM_MISSING_PROG(NAME, PROGRAM)
417 # ------------------------------
418 @@ -729,27 +605,16 @@ else
419 fi
420 ])
421
422 +# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
423 +#
424 +# This file is free software; the Free Software Foundation
425 +# gives unlimited permission to copy and/or distribute it,
426 +# with or without modifications, as long as this notice is preserved.
427 +
428 # AM_PROG_MKDIR_P
429 # ---------------
430 # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
431 -
432 -# Copyright (C) 2003, 2004 Free Software Foundation, Inc.
433 -
434 -# This program is free software; you can redistribute it and/or modify
435 -# it under the terms of the GNU General Public License as published by
436 -# the Free Software Foundation; either version 2, or (at your option)
437 -# any later version.
438 -
439 -# This program is distributed in the hope that it will be useful,
440 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
441 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
442 -# GNU General Public License for more details.
443 -
444 -# You should have received a copy of the GNU General Public License
445 -# along with this program; if not, write to the Free Software
446 -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
447 -# 02111-1307, USA.
448 -
449 +#
450 # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
451 # created by `make install' are always world readable, even if the
452 # installer happens to have an overly restrictive umask (e.g. 077).
453 @@ -803,26 +668,15 @@ else
454 fi
455 AC_SUBST([mkdir_p])])
456
457 -# Helper functions for option handling. -*- Autoconf -*-
458 +# Helper functions for option handling. -*- Autoconf -*-
459
460 -# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
461 -
462 -# This program is free software; you can redistribute it and/or modify
463 -# it under the terms of the GNU General Public License as published by
464 -# the Free Software Foundation; either version 2, or (at your option)
465 -# any later version.
466 -
467 -# This program is distributed in the hope that it will be useful,
468 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
469 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
470 -# GNU General Public License for more details.
471 -
472 -# You should have received a copy of the GNU General Public License
473 -# along with this program; if not, write to the Free Software
474 -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
475 -# 02111-1307, USA.
476 +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
477 +#
478 +# This file is free software; the Free Software Foundation
479 +# gives unlimited permission to copy and/or distribute it,
480 +# with or without modifications, as long as this notice is preserved.
481
482 -# serial 2
483 +# serial 3
484
485 # _AM_MANGLE_OPTION(NAME)
486 # -----------------------
487 @@ -847,28 +701,16 @@ AC_DEFUN([_AM_SET_OPTIONS],
488 AC_DEFUN([_AM_IF_OPTION],
489 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
490
491 -#
492 -# Check to make sure that the build environment is sane.
493 -#
494 -
495 -# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
496 -
497 -# This program is free software; you can redistribute it and/or modify
498 -# it under the terms of the GNU General Public License as published by
499 -# the Free Software Foundation; either version 2, or (at your option)
500 -# any later version.
501 +# Check to make sure that the build environment is sane. -*- Autoconf -*-
502
503 -# This program is distributed in the hope that it will be useful,
504 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
505 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
506 -# GNU General Public License for more details.
507 -
508 -# You should have received a copy of the GNU General Public License
509 -# along with this program; if not, write to the Free Software
510 -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
511 -# 02111-1307, USA.
512 +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
513 +# Free Software Foundation, Inc.
514 +#
515 +# This file is free software; the Free Software Foundation
516 +# gives unlimited permission to copy and/or distribute it,
517 +# with or without modifications, as long as this notice is preserved.
518
519 -# serial 3
520 +# serial 4
521
522 # AM_SANITY_CHECK
523 # ---------------
524 @@ -911,25 +753,14 @@ Check your system clock])
525 fi
526 AC_MSG_RESULT(yes)])
527
528 -# AM_PROG_INSTALL_STRIP
529 -
530 -# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
531 -
532 -# This program is free software; you can redistribute it and/or modify
533 -# it under the terms of the GNU General Public License as published by
534 -# the Free Software Foundation; either version 2, or (at your option)
535 -# any later version.
536 -
537 -# This program is distributed in the hope that it will be useful,
538 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
539 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
540 -# GNU General Public License for more details.
541 -
542 -# You should have received a copy of the GNU General Public License
543 -# along with this program; if not, write to the Free Software
544 -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
545 -# 02111-1307, USA.
546 +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
547 +#
548 +# This file is free software; the Free Software Foundation
549 +# gives unlimited permission to copy and/or distribute it,
550 +# with or without modifications, as long as this notice is preserved.
551
552 +# AM_PROG_INSTALL_STRIP
553 +# ---------------------
554 # One issue with vendor `install' (even GNU) is that you can't
555 # specify the program used to strip binaries. This is especially
556 # annoying in cross-compiling environments, where the build's strip
557 @@ -952,25 +783,13 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])])
558
559 # Check how to create a tarball. -*- Autoconf -*-
560
561 -# Copyright (C) 2004 Free Software Foundation, Inc.
562 -
563 -# This program is free software; you can redistribute it and/or modify
564 -# it under the terms of the GNU General Public License as published by
565 -# the Free Software Foundation; either version 2, or (at your option)
566 -# any later version.
567 -
568 -# This program is distributed in the hope that it will be useful,
569 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
570 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
571 -# GNU General Public License for more details.
572 -
573 -# You should have received a copy of the GNU General Public License
574 -# along with this program; if not, write to the Free Software
575 -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
576 -# 02111-1307, USA.
577 -
578 -# serial 1
579 +# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
580 +#
581 +# This file is free software; the Free Software Foundation
582 +# gives unlimited permission to copy and/or distribute it,
583 +# with or without modifications, as long as this notice is preserved.
584
585 +# serial 2
586
587 # _AM_PROG_TAR(FORMAT)
588 # --------------------
589 --- a/ChangeLog
590 +++ b/ChangeLog
591 @@ -1,3 +1,51 @@
592 +2006-05-02 Pavel Roskin <proski@gnu.org>
593 +
594 + * stage2/stage2.c (run_menu): Fix "savedefault" to save only top
595 + level menu positions. Remember current position when calling a
596 + submenu. Don't recalculate it when booting from a submenu.
597 +
598 + * grub/main.c (main): Make sure the boot drive number doesn't
599 + exceed 255.
600 +
601 +2006-05-02 Vesa Jaaskelainen <chaac@nic.fi>
602 +
603 + * stage2/shared.h (vbe_mode): Back ported aligment fix from GRUB 2
604 + to GRUB Legacy. Problem reported by Gerardo Richarte.
605 +
606 +2006-04-23 Robert Millan <robertmh@gnu.org>
607 +
608 + * grub/asmstub.c (get_diskinfo): Optimize sysctl routine.
609 +
610 +2006-04-20 Robert Millan <robertmh@gnu.org>
611 +
612 + Fixes for kernel of FreeBSD:
613 + * grub/asmstub.c (get_diskinfo): Toggle "kern.geom.debugflags" sysctl
614 + before opening a device for writing.
615 + * util/grub-install.in: Devices don't have this "r" prefix anymore.
616 +
617 +2006-04-16 Yoshinori K. Okuji <okuji@enbug.org>
618 +
619 + * docs/multiboot.texi: Correct the offset of address
620 + fields. Reported by Jeroen Dekkers.
621 +
622 +2006-03-21 Yoshinori K. Okuji <okuji@enbug.org>
623 +
624 + * stage2/builtins.c (setup_func): Specify the size of DEVICE to
625 + grub_strncat instead of a strange number 256. Reported by Vitaly
626 + Fertman <vitaly@namesys.com>.
627 +
628 +2005-09-29 Yoshinori K. Okuji <okuji@enbug.org>
629 +
630 + * docs/multiboot.texi: Fix a bug in the byte order of
631 + boot_device. I hope this won't affect any OS image.
632 + Increased the version number to 0.6.94.
633 +
634 +2005-09-28 Yoshinori K. Okuji <okuji@enbug.org>
635 +
636 + * stage2/boot.c (load_image): Even if an OS image is an ELF
637 + object, use the a.out kludge if MULTIBOOT_AOUT_KLUDGE is
638 + specified.
639 +
640 2005-05-08 Yoshinori K. Okuji <okuji@enbug.org>
641
642 * configure.ac (AC_INIT): Upgraded to 0.97.
643 --- a/configure
644 +++ b/configure
645 @@ -311,7 +311,7 @@ ac_includes_default="\
646 # include <unistd.h>
647 #endif"
648
649 -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar build build_cpu build_vendor build_os host host_cpu host_vendor host_os MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT PERL CC ac_ct_CC CFLAGS LDFLAGS CPPFLAGS EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CCAS RANLIB ac_ct_RANLIB STAGE1_CFLAGS STAGE2_CFLAGS GRUB_CFLAGS OBJCOPY ac_ct_OBJCOPY GRUB_LIBS CPP EGREP NETBOOT_SUPPORT_TRUE NETBOOT_SUPPORT_FALSE DISKLESS_SUPPORT_TRUE DISKLESS_SUPPORT_FALSE HERCULES_SUPPORT_TRUE HERCULES_SUPPORT_FALSE SERIAL_SUPPORT_TRUE SERIAL_SUPPORT_FALSE SERIAL_SPEED_SIMULATION_TRUE SERIAL_SPEED_SIMULATION_FALSE BUILD_EXAMPLE_KERNEL_TRUE BUILD_EXAMPLE_KERNEL_FALSE FSYS_CFLAGS NET_CFLAGS NET_EXTRAFLAGS NETBOOT_DRIVERS CCASFLAGS LIBOBJS LTLIBOBJS'
650 +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar build build_cpu build_vendor build_os host host_cpu host_vendor host_os MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT PERL CC ac_ct_CC CFLAGS LDFLAGS CPPFLAGS EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CCAS RANLIB ac_ct_RANLIB STAGE1_CFLAGS STAGE2_CFLAGS GRUB_CFLAGS OBJCOPY ac_ct_OBJCOPY GRUB_LIBS CPP EGREP NETBOOT_SUPPORT_TRUE NETBOOT_SUPPORT_FALSE DISKLESS_SUPPORT_TRUE DISKLESS_SUPPORT_FALSE GRAPHICS_SUPPORT_TRUE GRAPHICS_SUPPORT_FALSE HERCULES_SUPPORT_TRUE HERCULES_SUPPORT_FALSE SERIAL_SUPPORT_TRUE SERIAL_SUPPORT_FALSE SERIAL_SPEED_SIMULATION_TRUE SERIAL_SPEED_SIMULATION_FALSE BUILD_EXAMPLE_KERNEL_TRUE BUILD_EXAMPLE_KERNEL_FALSE FSYS_CFLAGS NET_CFLAGS NET_EXTRAFLAGS NETBOOT_DRIVERS CCASFLAGS LIBOBJS LTLIBOBJS'
651 ac_subst_files=''
652
653 # Initialize some variables set by options.
654 @@ -914,6 +914,7 @@ Optional Features:
655 set the default memory location for WD/SMC
656 --enable-cs-scan=LIST probe for CS89x0 base address using LIST
657 --enable-diskless enable diskless support
658 + --disable-graphics disable graphics terminal support
659 --disable-hercules disable hercules terminal support
660 --disable-serial disable serial terminal support
661 --enable-serial-speed-simulation
662 @@ -5966,6 +5967,22 @@ else
663 fi
664
665
666 +# Check whether --enable-graphics or --disable-graphics was given.
667 +if test "${enable_graphics+set}" = set; then
668 + enableval="$enable_graphics"
669 +
670 +fi;
671 +
672 +
673 +if test "x$enable_graphics" != xno; then
674 + GRAPHICS_SUPPORT_TRUE=
675 + GRAPHICS_SUPPORT_FALSE='#'
676 +else
677 + GRAPHICS_SUPPORT_TRUE='#'
678 + GRAPHICS_SUPPORT_FALSE=
679 +fi
680 +
681 +
682 # Check whether --enable-hercules or --disable-hercules was given.
683 if test "${enable_hercules+set}" = set; then
684 enableval="$enable_hercules"
685 @@ -6270,6 +6287,13 @@ echo "$as_me: error: conditional \"DISKL
686 Usually this means the macro was only invoked conditionally." >&2;}
687 { (exit 1); exit 1; }; }
688 fi
689 +if test -z "${GRAPHICS_SUPPORT_TRUE}" && test -z "${GRAPHICS_SUPPORT_FALSE}"; then
690 + { { echo "$as_me:$LINENO: error: conditional \"GRAPHICS_SUPPORT\" was never defined.
691 +Usually this means the macro was only invoked conditionally." >&5
692 +echo "$as_me: error: conditional \"GRAPHICS_SUPPORT\" was never defined.
693 +Usually this means the macro was only invoked conditionally." >&2;}
694 + { (exit 1); exit 1; }; }
695 +fi
696 if test -z "${HERCULES_SUPPORT_TRUE}" && test -z "${HERCULES_SUPPORT_FALSE}"; then
697 { { echo "$as_me:$LINENO: error: conditional \"HERCULES_SUPPORT\" was never defined.
698 Usually this means the macro was only invoked conditionally." >&5
699 @@ -6907,6 +6931,8 @@ s,@NETBOOT_SUPPORT_TRUE@,$NETBOOT_SUPPOR
700 s,@NETBOOT_SUPPORT_FALSE@,$NETBOOT_SUPPORT_FALSE,;t t
701 s,@DISKLESS_SUPPORT_TRUE@,$DISKLESS_SUPPORT_TRUE,;t t
702 s,@DISKLESS_SUPPORT_FALSE@,$DISKLESS_SUPPORT_FALSE,;t t
703 +s,@GRAPHICS_SUPPORT_TRUE@,$GRAPHICS_SUPPORT_TRUE,;t t
704 +s,@GRAPHICS_SUPPORT_FALSE@,$GRAPHICS_SUPPORT_FALSE,;t t
705 s,@HERCULES_SUPPORT_TRUE@,$HERCULES_SUPPORT_TRUE,;t t
706 s,@HERCULES_SUPPORT_FALSE@,$HERCULES_SUPPORT_FALSE,;t t
707 s,@SERIAL_SUPPORT_TRUE@,$SERIAL_SUPPORT_TRUE,;t t
708 --- a/configure.ac
709 +++ b/configure.ac
710 @@ -595,6 +595,11 @@ AC_ARG_ENABLE(diskless,
711 [ --enable-diskless enable diskless support])
712 AM_CONDITIONAL(DISKLESS_SUPPORT, test "x$enable_diskless" = xyes)
713
714 +dnl Graphical splashscreen support
715 +AC_ARG_ENABLE(graphics,
716 + [ --disable-graphics disable graphics terminal support])
717 +AM_CONDITIONAL(GRAPHICS_SUPPORT, test "x$enable_graphics" != xno)
718 +
719 dnl Hercules terminal
720 AC_ARG_ENABLE(hercules,
721 [ --disable-hercules disable hercules terminal support])
722 --- a/docs/grub.8
723 +++ b/docs/grub.8
724 @@ -1,5 +1,5 @@
725 .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.23.
726 -.TH GRUB "8" "May 2005" "grub (GNU GRUB 0.97)" FSF
727 +.TH GRUB "8" "September 2005" "grub (GNU GRUB 0.97)" FSF
728 .SH NAME
729 grub \- the grub shell
730 .SH SYNOPSIS
731 --- a/docs/grub.texi
732 +++ b/docs/grub.texi
733 @@ -2199,6 +2199,7 @@ Commands usable anywhere in the menu and
734 * rarp:: Initialize a network device via RARP
735 * serial:: Set up a serial device
736 * setkey:: Configure the key map
737 +* splashimage:: Use a splash image
738 * terminal:: Choose a terminal
739 * terminfo:: Define escape sequences for a terminal
740 * tftpserver:: Specify a TFTP server
741 @@ -2578,6 +2579,16 @@ character each of the symbols correspond
742 @end deffn
743
744
745 +@node splashimage
746 +@subsection splashimage
747 +
748 +@deffn Command splashimage file
749 +Select an image to use as the background image. This should be
750 +specified using normal GRUB device naming syntax. The format of the
751 +file is a gzipped xpm which is 640x480 with a 14 color palette.
752 +@end deffn
753 +
754 +
755 @node terminal
756 @subsection terminal
757
758 @@ -2685,6 +2696,7 @@ you forget a command, you can run the co
759 * module:: Load a module
760 * modulenounzip:: Load a module without decompression
761 * pause:: Wait for a key press
762 +* print:: Print a message
763 * quit:: Exit from the grub shell
764 * reboot:: Reboot your computer
765 * read:: Read data from memory
766 @@ -3091,6 +3103,16 @@ change floppies.
767 @end deffn
768
769
770 +@node print
771 +@subsection print
772 +
773 +@deffn Command print message @dots{}
774 +Print the @var{message}. Note that placing @key{^G} (ASCII code 7) in the
775 +message will cause the speaker to emit the standard beep sound, which is
776 +useful for visually impaired people.
777 +@end deffn
778 +
779 +
780 @node quit
781 @subsection quit
782
783 --- a/docs/multiboot.texi
784 +++ b/docs/multiboot.texi
785 @@ -25,7 +25,7 @@
786 @ifinfo
787 Copyright @copyright{} 1995, 96 Bryan Ford <baford@@cs.utah.edu>
788 Copyright @copyright{} 1995, 96 Erich Stefan Boleyn <erich@@uruk.org>
789 -Copyright @copyright{} 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
790 +Copyright @copyright{} 1999, 2000, 2001, 2002, 2005, 2006 Free Software Foundation, Inc.
791
792 Permission is granted to make and distribute verbatim copies of
793 this manual provided the copyright notice and this permission notice
794 @@ -57,7 +57,7 @@ into another language, under the above c
795 @vskip 0pt plus 1filll
796 Copyright @copyright{} 1995, 96 Bryan Ford <baford@@cs.utah.edu>
797 Copyright @copyright{} 1995, 96 Erich Stefan Boleyn <erich@@uruk.org>
798 -Copyright @copyright{} 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
799 +Copyright @copyright{} 1999, 2000, 2001, 2002, 2005, 2006 Free Software Foundation, Inc.
800
801 Permission is granted to make and distribute verbatim copies of
802 this manual provided the copyright notice and this permission notice
803 @@ -80,7 +80,7 @@ into another language, under the above c
804 @top Multiboot Specification
805
806 This file documents Multiboot Specification, the proposal for the boot
807 -sequence standard. This edition documents version 0.6.93.
808 +sequence standard. This edition documents version 0.6.94.
809 @end ifnottex
810
811 @menu
812 @@ -426,7 +426,7 @@ mode table (@pxref{Boot information form
813 kernel.
814
815 If bit 16 in the @samp{flags} word is set, then the fields at offsets
816 -8-24 in the Multiboot header are valid, and the boot loader should use
817 +12-28 in the Multiboot header are valid, and the boot loader should use
818 them instead of the fields in the actual executable header to calculate
819 where to load the OS image. This information does not need to be
820 provided if the kernel image is in @sc{elf} format, but it @emph{must}
821 @@ -677,7 +677,7 @@ follows:
822 @example
823 @group
824 +-------+-------+-------+-------+
825 -| drive | part1 | part2 | part3 |
826 +| part3 | part2 | part1 | drive |
827 +-------+-------+-------+-------+
828 @end group
829 @end example
830 @@ -1199,6 +1199,13 @@ The maintainer changes to the GNU GRUB m
831 @email{bug-grub@@gnu.org}, from Bryan Ford and Erich Stefan Boleyn.
832 @end itemize
833
834 +@item
835 +The byte order of the @samp{boot_device} in Multiboot information is
836 +reversed. This was a mistake.
837 +
838 +@item
839 +The offset of the address fields were wrong.
840 +
841 @item 0.6
842 @itemize @bullet
843 @item
844 --- a/grub/asmstub.c
845 +++ b/grub/asmstub.c
846 @@ -42,6 +42,12 @@ int grub_stage2 (void);
847 #include <sys/time.h>
848 #include <termios.h>
849 #include <signal.h>
850 +#include <sys/mman.h>
851 +
852 +#include <limits.h>
853 +#ifndef PAGESIZE
854 +#define PAGESIZE 4096
855 +#endif
856
857 #ifdef __linux__
858 # include <sys/ioctl.h> /* ioctl */
859 @@ -55,6 +61,10 @@ int grub_stage2 (void);
860 # endif /* ! BLKFLSBUF */
861 #endif /* __linux__ */
862
863 +#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
864 +# include <sys/sysctl.h>
865 +#endif
866 +
867 /* We want to prevent any circularararity in our stubs, as well as
868 libc name clashes. */
869 #define WITHOUT_LIBC_STUBS 1
870 @@ -144,6 +154,22 @@ grub_stage2 (void)
871 assert (grub_scratch_mem == 0);
872 scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15);
873 assert (scratch);
874 +
875 + {
876 + char *p;
877 + int ret;
878 +
879 + /* Align to a multiple of PAGESIZE, assumed to be a power of two. */
880 + p = (char *) (((long) scratch) & ~(PAGESIZE - 1));
881 +
882 + /* The simulated stack needs to be executable, since GCC uses stack
883 + * trampolines to implement nested functions.
884 + */
885 + ret = mprotect (p, 0x100000 + EXTENDED_MEMSIZE + 15,
886 + PROT_READ | PROT_WRITE | PROT_EXEC);
887 + assert (ret == 0);
888 + }
889 +
890 grub_scratch_mem = (char *) ((((int) scratch) >> 4) << 4);
891
892 /* FIXME: simulate the memory holes using mprot, if available. */
893 @@ -777,7 +803,39 @@ get_diskinfo (int drive, struct geometry
894
895 /* Open read/write, or read-only if that failed. */
896 if (! read_only)
897 - disks[drive].flags = open (devname, O_RDWR);
898 + {
899 +/* By default, kernel of FreeBSD does not allow overwriting MBR */
900 +#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
901 +#define GEOM_SYSCTL "kern.geom.debugflags"
902 + int old_flags, flags;
903 + size_t sizeof_int = sizeof (int);
904 +
905 + if (sysctlbyname (GEOM_SYSCTL, &old_flags, &sizeof_int, NULL, 0) != 0)
906 + grub_printf ("failed to get " GEOM_SYSCTL "sysctl: %s\n", strerror (errno));
907 +
908 + if ((old_flags & 0x10) == 0)
909 + {
910 + /* "allow foot shooting", see geom(4) */
911 + flags = old_flags | 0x10;
912 +
913 + if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &flags, sizeof (int)) != 0)
914 + {
915 + flags = old_flags;
916 + grub_printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", strerror (errno));
917 + }
918 + }
919 + else
920 + flags = old_flags;
921 +#endif
922 + disks[drive].flags = open (devname, O_RDWR);
923 +#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
924 + if (flags != old_flags)
925 + {
926 + if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &old_flags, sizeof (int)) != 0)
927 + grub_printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", strerror (errno));
928 + }
929 +#endif
930 + }
931
932 if (disks[drive].flags == -1)
933 {
934 --- a/grub/main.c
935 +++ b/grub/main.c
936 @@ -32,6 +32,7 @@ int grub_stage2 (void);
937 #define WITHOUT_LIBC_STUBS 1
938 #include <shared.h>
939 #include <term.h>
940 +#include <device.h>
941
942 char *program_name = 0;
943 int use_config_file = 1;
944 @@ -192,6 +193,12 @@ main (int argc, char **argv)
945 perror ("strtoul");
946 exit (1);
947 }
948 + if (boot_drive >= NUM_DISKS)
949 + {
950 + fprintf (stderr, "boot_drive should be from 0 to %d\n",
951 + NUM_DISKS - 1);
952 + exit (1);
953 + }
954 break;
955
956 case OPT_NO_CONFIG_FILE:
957 --- a/lib/device.c
958 +++ b/lib/device.c
959 @@ -131,6 +131,152 @@ get_kfreebsd_version ()
960 #include <shared.h>
961 #include <device.h>
962
963 +#if defined(__linux__)
964 +/* The 2.6 kernel has removed all of the geometry handling for IDE drives
965 + * that did fixups for LBA, etc. This means that the geometry we get
966 + * with the ioctl has a good chance of being wrong. So, we get to
967 + * also know about partition tables and try to read what the geometry
968 + * is there. *grumble* Very closely based on code from cfdisk
969 + */
970 +static void get_kernel_geometry(int fd, long long *cyl, int *heads, int *sectors) {
971 + struct hd_geometry hdg;
972 +
973 + if (ioctl (fd, HDIO_GETGEO, &hdg))
974 + return;
975 +
976 + *cyl = hdg.cylinders;
977 + *heads = hdg.heads;
978 + *sectors = hdg.sectors;
979 +}
980 +
981 +struct partition {
982 + unsigned char boot_ind; /* 0x80 - active */
983 + unsigned char head; /* starting head */
984 + unsigned char sector; /* starting sector */
985 + unsigned char cyl; /* starting cylinder */
986 + unsigned char sys_ind; /* What partition type */
987 + unsigned char end_head; /* end head */
988 + unsigned char end_sector; /* end sector */
989 + unsigned char end_cyl; /* end cylinder */
990 + unsigned char start4[4]; /* starting sector counting from 0 */
991 + unsigned char size4[4]; /* nr of sectors in partition */
992 +};
993 +
994 +#define ALIGNMENT 2
995 +typedef union {
996 + struct {
997 + unsigned char align[ALIGNMENT];
998 + unsigned char b[SECTOR_SIZE];
999 + } c;
1000 + struct {
1001 + unsigned char align[ALIGNMENT];
1002 + unsigned char buffer[0x1BE];
1003 + struct partition part[4];
1004 + unsigned char magicflag[2];
1005 + } p;
1006 +} partition_table;
1007 +
1008 +#define PART_TABLE_FLAG0 0x55
1009 +#define PART_TABLE_FLAG1 0xAA
1010 +
1011 +static void
1012 +get_partition_table_geometry(partition_table *bufp, long long *cyl, int *heads,
1013 + int *sectors) {
1014 + struct partition *p;
1015 + int i,h,s,hh,ss;
1016 + int first = 1;
1017 + int bad = 0;
1018 +
1019 + if (bufp->p.magicflag[0] != PART_TABLE_FLAG0 ||
1020 + bufp->p.magicflag[1] != PART_TABLE_FLAG1) {
1021 + /* Matthew Wilcox: slightly friendlier version of
1022 + fatal(_("Bad signature on partition table"), 3);
1023 + */
1024 + fprintf(stderr, "Unknown partition table signature\n");
1025 + return;
1026 + }
1027 +
1028 + hh = ss = 0;
1029 + for (i=0; i<4; i++) {
1030 + p = &(bufp->p.part[i]);
1031 + if (p->sys_ind != 0) {
1032 + h = p->end_head + 1;
1033 + s = (p->end_sector & 077);
1034 + if (first) {
1035 + hh = h;
1036 + ss = s;
1037 + first = 0;
1038 + } else if (hh != h || ss != s)
1039 + bad = 1;
1040 + }
1041 + }
1042 +
1043 + if (!first && !bad) {
1044 + *heads = hh;
1045 + *sectors = ss;
1046 + }
1047 +}
1048 +
1049 +static long long my_lseek (unsigned int fd, long long offset,
1050 + unsigned int origin)
1051 +{
1052 +#if defined(__linux__) && (!defined(__GLIBC__) || \
1053 + ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
1054 + /* Maybe libc doesn't have large file support. */
1055 + loff_t offset, result;
1056 + static int _llseek (uint filedes, ulong hi, ulong lo,
1057 + loff_t *res, uint wh);
1058 + _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
1059 + loff_t *, res, uint, wh);
1060 +
1061 + if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET) < 0)
1062 + return (long long) -1;
1063 + return result;
1064 +#else
1065 + return lseek(fd, offset, SEEK_SET);
1066 +#endif
1067 +}
1068 +
1069 +static void get_linux_geometry (int fd, struct geometry *geom) {
1070 + long long kern_cyl = 0; int kern_head = 0, kern_sectors = 0;
1071 + long long pt_cyl = 0; int pt_head = 0, pt_sectors = 0;
1072 + partition_table bufp;
1073 + char *buff, *buf_unaligned;
1074 +
1075 + buf_unaligned = malloc(sizeof(partition_table) + 4095);
1076 + buff = (char *) (((unsigned long)buf_unaligned + 4096 - 1) &
1077 + (~(4096-1)));
1078 +
1079 + get_kernel_geometry(fd, &kern_cyl, &kern_head, &kern_sectors);
1080 +
1081 + if (my_lseek (fd, 0*SECTOR_SIZE, SEEK_SET) < 0) {
1082 + fprintf(stderr, "Unable to seek");
1083 + }
1084 +
1085 + if (read(fd, buff, SECTOR_SIZE) == SECTOR_SIZE) {
1086 + memcpy(bufp.c.b, buff, SECTOR_SIZE);
1087 + get_partition_table_geometry(&bufp, &pt_cyl, &pt_head, &pt_sectors);
1088 + } else {
1089 + fprintf(stderr, "Unable to read partition table: %s\n", strerror(errno));
1090 + }
1091 +
1092 + if (pt_head && pt_sectors) {
1093 + int cyl_size;
1094 +
1095 + geom->heads = pt_head;
1096 + geom->sectors = pt_sectors;
1097 + cyl_size = pt_head * pt_sectors;
1098 + geom->cylinders = geom->total_sectors/cyl_size;
1099 + } else {
1100 + geom->heads = kern_head;
1101 + geom->sectors = kern_sectors;
1102 + geom->cylinders = kern_cyl;
1103 + }
1104 +
1105 + return;
1106 +}
1107 +#endif
1108 +
1109 /* Get the geometry of a drive DRIVE. */
1110 void
1111 get_drive_geometry (struct geometry *geom, char **map, int drive)
1112 @@ -151,21 +297,16 @@ get_drive_geometry (struct geometry *geo
1113 #if defined(__linux__)
1114 /* Linux */
1115 {
1116 - struct hd_geometry hdg;
1117 unsigned long nr;
1118 -
1119 - if (ioctl (fd, HDIO_GETGEO, &hdg))
1120 - goto fail;
1121
1122 if (ioctl (fd, BLKGETSIZE, &nr))
1123 goto fail;
1124
1125 /* Got the geometry, so save it. */
1126 - geom->cylinders = hdg.cylinders;
1127 - geom->heads = hdg.heads;
1128 - geom->sectors = hdg.sectors;
1129 geom->total_sectors = nr;
1130 -
1131 + get_linux_geometry(fd, geom);
1132 + if (!geom->heads && !geom->cylinders && !geom->sectors)
1133 + goto fail;
1134 goto success;
1135 }
1136
1137 @@ -403,6 +544,18 @@ get_dac960_disk_name (char *name, int co
1138 }
1139
1140 static void
1141 +get_cciss_disk_name (char *name, int controller, int drive)
1142 +{
1143 + sprintf (name, "/dev/cciss/c%dd%d", controller, drive);
1144 +}
1145 +
1146 +static void
1147 +get_ida_disk_name (char *name, int controller, int drive)
1148 +{
1149 + sprintf (name, "/dev/ida/c%dd%d", controller, drive);
1150 +}
1151 +
1152 +static void
1153 get_ataraid_disk_name (char *name, int unit)
1154 {
1155 sprintf (name, "/dev/ataraid/d%c", unit + '0');
1156 @@ -801,6 +954,74 @@ init_device_map (char ***map, const char
1157 }
1158 }
1159 }
1160 +
1161 + /* This is for CCISS, its like the DAC960 - we have
1162 + /dev/cciss/<controller>d<logical drive>p<partition>
1163 +
1164 + It currently supports up to 3 controllers, 10 logical volumes
1165 + and 10 partitions
1166 +
1167 + Code gratuitously copied from DAC960 above.
1168 + Horms <horms@verge.net.au> 23rd July 2004
1169 + */
1170 + {
1171 + int controller, drive;
1172 +
1173 + for (controller = 0; controller < 2; controller++)
1174 + {
1175 + for (drive = 0; drive < 9; drive++)
1176 + {
1177 + char name[24];
1178 +
1179 + get_cciss_disk_name (name, controller, drive);
1180 + if (check_device (name))
1181 + {
1182 + (*map)[num_hd + 0x80] = strdup (name);
1183 + assert ((*map)[num_hd + 0x80]);
1184 +
1185 + /* If the device map file is opened, write the map. */
1186 + if (fp)
1187 + fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
1188 +
1189 + num_hd++;
1190 + }
1191 + }
1192 + }
1193 + }
1194 +
1195 + /* This is for Compaq Smart Array, its like the DAC960 - we have
1196 + /dev/ida/<controller>d<logical drive>p<partition>
1197 +
1198 + It currently supports up to 3 controllers, 10 logical volumes
1199 + and 15 partitions
1200 +
1201 + Code gratuitously copied from DAC960 above.
1202 + Piotr Roszatycki <dexter@debian.org>
1203 + */
1204 + {
1205 + int controller, drive;
1206 +
1207 + for (controller = 0; controller < 2; controller++)
1208 + {
1209 + for (drive = 0; drive < 9; drive++)
1210 + {
1211 + char name[24];
1212 +
1213 + get_ida_disk_name (name, controller, drive);
1214 + if (check_device (name))
1215 + {
1216 + (*map)[num_hd + 0x80] = strdup (name);
1217 + assert ((*map)[num_hd + 0x80]);
1218 +
1219 + /* If the device map file is opened, write the map. */
1220 + if (fp)
1221 + fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
1222 +
1223 + num_hd++;
1224 + }
1225 + }
1226 + }
1227 + }
1228 #endif /* __linux__ */
1229
1230 /* OK, close the device map file if opened. */
1231 @@ -844,6 +1065,7 @@ write_to_partition (char **map, int driv
1232 {
1233 char dev[PATH_MAX]; /* XXX */
1234 int fd;
1235 + off_t offset = (off_t) sector * (off_t) SECTOR_SIZE;
1236
1237 if ((partition & 0x00FF00) != 0x00FF00)
1238 {
1239 @@ -861,8 +1083,14 @@ write_to_partition (char **map, int driv
1240 if (strcmp (dev + strlen(dev) - 5, "/disc") == 0)
1241 strcpy (dev + strlen(dev) - 5, "/part");
1242 }
1243 - sprintf (dev + strlen(dev), "%d", ((partition >> 16) & 0xFF) + 1);
1244 -
1245 + sprintf (dev + strlen(dev), "%s%d",
1246 + /* Compaq smart and others */
1247 + (strncmp(dev, "/dev/ida/", 9) == 0 ||
1248 + strncmp(dev, "/dev/ataraid/", 13) == 0 ||
1249 + strncmp(dev, "/dev/cciss/", 11) == 0 ||
1250 + strncmp(dev, "/dev/rd/", 8) == 0) ? "p" : "",
1251 + ((partition >> 16) & 0xFF) + 1);
1252 +
1253 /* Open the partition. */
1254 fd = open (dev, O_RDWR);
1255 if (fd < 0)
1256 @@ -870,35 +1098,13 @@ write_to_partition (char **map, int driv
1257 errnum = ERR_NO_PART;
1258 return 0;
1259 }
1260 -
1261 -#if defined(__linux__) && (!defined(__GLIBC__) || \
1262 - ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
1263 - /* Maybe libc doesn't have large file support. */
1264 - {
1265 - loff_t offset, result;
1266 - static int _llseek (uint filedes, ulong hi, ulong lo,
1267 - loff_t *res, uint wh);
1268 - _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
1269 - loff_t *, res, uint, wh);
1270
1271 - offset = (loff_t) sector * (loff_t) SECTOR_SIZE;
1272 - if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET))
1273 - {
1274 - errnum = ERR_DEV_VALUES;
1275 - return 0;
1276 - }
1277 - }
1278 -#else
1279 - {
1280 - off_t offset = (off_t) sector * (off_t) SECTOR_SIZE;
1281
1282 - if (lseek (fd, offset, SEEK_SET) != offset)
1283 - {
1284 - errnum = ERR_DEV_VALUES;
1285 - return 0;
1286 - }
1287 - }
1288 -#endif
1289 + if (my_lseek(fd, offset, SEEK_SET) != offset)
1290 + {
1291 + errnum = ERR_DEV_VALUES;
1292 + return 0;
1293 + }
1294
1295 if (write (fd, buf, size * SECTOR_SIZE) != (size * SECTOR_SIZE))
1296 {
1297 --- a/stage2/asm.S
1298 +++ b/stage2/asm.S
1299 @@ -1651,7 +1651,29 @@ ENTRY(gateA20)
1300 jnz 3f
1301 ret
1302
1303 -3: /* use keyboard controller */
1304 +3: /*
1305 + * try to switch gateA20 using PORT92, the "Fast A20 and Init"
1306 + * register
1307 + */
1308 + mov $0x92, %dx
1309 + inb %dx, %al
1310 + /* skip the port92 code if it's unimplemented (read returns 0xff) */
1311 + cmpb $0xff, %al
1312 + jz 6f
1313 +
1314 + /* set or clear bit1, the ALT_A20_GATE bit */
1315 + movb 4(%esp), %ah
1316 + testb %ah, %ah
1317 + jz 4f
1318 + orb $2, %al
1319 + jmp 5f
1320 +4: and $0xfd, %al
1321 +
1322 + /* clear the INIT_NOW bit don't accidently reset the machine */
1323 +5: and $0xfe, %al
1324 + outb %al, %dx
1325 +
1326 +6: /* use keyboard controller */
1327 pushl %eax
1328
1329 call gloop1
1330 @@ -1661,9 +1683,12 @@ ENTRY(gateA20)
1331
1332 gloopint1:
1333 inb $K_STATUS
1334 + cmpb $0xff, %al
1335 + jz gloopint1_done
1336 andb $K_IBUF_FUL, %al
1337 jnz gloopint1
1338
1339 +gloopint1_done:
1340 movb $KB_OUTPUT_MASK, %al
1341 cmpb $0, 0x8(%esp)
1342 jz gdoit
1343 @@ -1684,6 +1709,8 @@ gdoit:
1344
1345 gloop1:
1346 inb $K_STATUS
1347 + cmpb $0xff, %al
1348 + jz gloop2ret
1349 andb $K_IBUF_FUL, %al
1350 jnz gloop1
1351
1352 @@ -1991,6 +2018,11 @@ ENTRY(ascii_key_map)
1353 ENTRY(console_getkey)
1354 push %ebp
1355
1356 +wait_for_key:
1357 + call EXT_C(console_checkkey)
1358 + incl %eax
1359 + jz wait_for_key
1360 +
1361 call EXT_C(prot_to_real)
1362 .code16
1363
1364 @@ -2216,7 +2248,304 @@ ENTRY(console_setcursor)
1365 pop %ebx
1366 pop %ebp
1367 ret
1368 -
1369 +
1370 +
1371 +/* graphics mode functions */
1372 +#ifdef SUPPORT_GRAPHICS
1373 +VARIABLE(cursorX)
1374 +.word 0
1375 +VARIABLE(cursorY)
1376 +.word 0
1377 +VARIABLE(cursorCount)
1378 +.word 0
1379 +VARIABLE(cursorBuf)
1380 +.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1381 +
1382 +
1383 +/*
1384 + * set_int1c_handler(void)
1385 + */
1386 +ENTRY(set_int1c_handler)
1387 + pushl %edi
1388 +
1389 + /* save the original int1c handler */
1390 + movl $0x70, %edi
1391 + movw (%edi), %ax
1392 + movw %ax, ABS(int1c_offset)
1393 + movw 2(%edi), %ax
1394 + movw %ax, ABS(int1c_segment)
1395 +
1396 + /* save the new int1c handler */
1397 + movw $ABS(int1c_handler), %ax
1398 + movw %ax, (%edi)
1399 + xorw %ax, %ax
1400 + movw %ax, 2(%edi)
1401 +
1402 + popl %edi
1403 + ret
1404 +
1405 +
1406 +/*
1407 + * unset_int1c_handler(void)
1408 + */
1409 +ENTRY(unset_int1c_handler)
1410 + pushl %edi
1411 +
1412 + /* check if int1c_handler is set */
1413 + movl $0x70, %edi
1414 + movw $ABS(int1c_handler), %ax
1415 + cmpw %ax, (%edi)
1416 + jne int1c_1
1417 + xorw %ax, %ax
1418 + cmpw %ax, 2(%edi)
1419 + jne int1c_1
1420 +
1421 + /* restore the original */
1422 + movw ABS(int1c_offset), %ax
1423 + movw %ax, (%edi)
1424 + movw ABS(int1c_segment), %ax
1425 + movw %ax, 2(%edi)
1426 +
1427 +int1c_1:
1428 + popl %edi
1429 + ret
1430 +
1431 +
1432 +/*
1433 + * blinks graphics cursor
1434 + */
1435 + .code16
1436 +write_data:
1437 + movw $0, %ax
1438 + movw %ax, %ds
1439 +
1440 + mov $0xA000, %ax /* video in es:di */
1441 + mov %ax, %es
1442 + mov $80, %ax
1443 + movw $ABS(cursorY), %si
1444 + mov %ds:(%si), %bx
1445 + mul %bx
1446 + movw $ABS(cursorX), %si
1447 + mov %ds:(%si), %bx
1448 + shr $3, %bx /* %bx /= 8 */
1449 + add %bx, %ax
1450 + mov %ax, %di
1451 +
1452 + movw $ABS(cursorBuf), %si /* fontBuf in ds:si */
1453 +
1454 + /* prepare for data moving */
1455 + mov $16, %dx /* altura da fonte */
1456 + mov $80, %bx /* bytes por linha */
1457 +
1458 +write_loop:
1459 + movb %ds:(%si), %al
1460 + xorb $0xff, %al
1461 + movb %al, %ds:(%si) /* invert cursorBuf */
1462 + movb %al, %es:(%di) /* write to video */
1463 + add %bx, %di
1464 + inc %si
1465 + dec %dx
1466 + jg write_loop
1467 + ret
1468 +
1469 +int1c_handler:
1470 + pusha
1471 + mov $0, %ax
1472 + mov %ax, %ds
1473 + mov $ABS(cursorCount), %si
1474 + mov %ds:(%si), %ax
1475 + inc %ax
1476 + mov %ax, %ds:(%si)
1477 + cmp $9, %ax
1478 + jne int1c_done
1479 +
1480 + mov $0, %ax
1481 + mov %ax, %ds:(%si)
1482 + call write_data
1483 +
1484 +int1c_done:
1485 + popa
1486 + iret
1487 + /* call previous int1c handler */
1488 + /* ljmp */
1489 + .byte 0xea
1490 +int1c_offset: .word 0
1491 +int1c_segment: .word 0
1492 + .code32
1493 +
1494 +
1495 +/*
1496 + * unsigned char set_videomode(unsigned char mode)
1497 + * BIOS call "INT 10H Function 0h" to set video mode
1498 + * Call with %ah = 0x0
1499 + * %al = video mode
1500 + * Returns old videomode.
1501 + */
1502 +ENTRY(set_videomode)
1503 + pushl %ebp
1504 + movl %esp,%ebp
1505 + pushl %ebx
1506 + pushl %ecx
1507 +
1508 + movb 8(%ebp), %cl
1509 +
1510 + call EXT_C(prot_to_real)
1511 + .code16
1512 +
1513 + xorb %al, %al
1514 + movb $0xf, %ah
1515 + int $0x10 /* Get Current Video mode */
1516 + movb %al, %ch
1517 + xorb %ah, %ah
1518 + movb %cl, %al
1519 + int $0x10 /* Set Video mode */
1520 +
1521 + DATA32 call EXT_C(real_to_prot)
1522 + .code32
1523 +
1524 + xorl %eax, %eax
1525 + movb %ch, %al
1526 +
1527 + popl %ecx
1528 + popl %ebx
1529 + popl %ebp
1530 + ret
1531 +
1532 +
1533 +/*
1534 + * int get_videomode()
1535 + * BIOS call "INT 10H Function 0Fh" to get current video mode
1536 + * Call with %al = 0x0
1537 + * %ah = 0xF
1538 + * Returns current videomode.
1539 + */
1540 +ENTRY(get_videomode)
1541 + pushl %ebp
1542 + movl %esp,%ebp
1543 + pushl %ebx
1544 + pushl %ecx
1545 +
1546 + call EXT_C(prot_to_real)
1547 + .code16
1548 +
1549 + xorb %al, %al
1550 + movb $0xF, %ah
1551 + int $0x10 /* Get Current Video mode */
1552 + movb %al, %cl /* For now we only want display mode */
1553 +
1554 + DATA32 call EXT_C(real_to_prot)
1555 + .code32
1556 +
1557 + xorl %eax, %eax
1558 + movb %cl, %al
1559 +
1560 + popl %ecx
1561 + popl %ebx
1562 + popl %ebp
1563 + ret
1564 +
1565 +
1566 +/*
1567 + * unsigned char * graphics_get_font()
1568 + * BIOS call "INT 10H Function 11h" to set font
1569 + * Call with %ah = 0x11
1570 + */
1571 +ENTRY(graphics_get_font)
1572 + push %ebp
1573 + push %ebx
1574 + push %ecx
1575 + push %edx
1576 +
1577 + call EXT_C(prot_to_real)
1578 + .code16
1579 +
1580 + movw $0x1130, %ax
1581 + movb $6, %bh /* font 8x16 */
1582 + int $0x10
1583 + movw %bp, %dx
1584 + movw %es, %cx
1585 +
1586 + DATA32 call EXT_C(real_to_prot)
1587 + .code32
1588 +
1589 + xorl %eax, %eax
1590 + movw %cx, %ax
1591 + shll $4, %eax
1592 + movw %dx, %ax
1593 +
1594 + pop %edx
1595 + pop %ecx
1596 + pop %ebx
1597 + pop %ebp
1598 + ret
1599 +
1600 +
1601 +/*
1602 + * graphics_set_palette(index, red, green, blue)
1603 + * BIOS call "INT 10H Function 10h" to set individual dac register
1604 + * Call with %ah = 0x10
1605 + * %bx = register number
1606 + * %ch = new value for green (0-63)
1607 + * %cl = new value for blue (0-63)
1608 + * %dh = new value for red (0-63)
1609 + */
1610 +
1611 +ENTRY(graphics_set_palette)
1612 + push %ebp
1613 + push %eax
1614 + push %ebx
1615 + push %ecx
1616 + push %edx
1617 +
1618 + movw $0x3c8, %bx /* address write mode register */
1619 +
1620 + /* wait vertical retrace */
1621 + movw $0x3da, %dx
1622 +l1b:
1623 + inb %dx, %al /* wait vertical active display */
1624 + test $8, %al
1625 + jnz l1b
1626 +
1627 +l2b:
1628 + inb %dx, %al /* wait vertical retrace */
1629 + test $8, %al
1630 + jnz l2b
1631 +
1632 + mov %bx, %dx
1633 + movb 0x18(%esp), %al /* index */
1634 + outb %al, %dx
1635 + inc %dx
1636 +
1637 + movb 0x1c(%esp), %al /* red */
1638 + outb %al, %dx
1639 +
1640 + movb 0x20(%esp), %al /* green */
1641 + outb %al, %dx
1642 +
1643 + movb 0x24(%esp), %al /* blue */
1644 + outb %al, %dx
1645 +
1646 + movw 0x18(%esp), %bx
1647 +
1648 + call EXT_C(prot_to_real)
1649 + .code16
1650 +
1651 + movb %bl, %bh
1652 + movw $0x1000, %ax
1653 + int $0x10
1654 +
1655 + DATA32 call EXT_C(real_to_prot)
1656 + .code32
1657 +
1658 + pop %edx
1659 + pop %ecx
1660 + pop %ebx
1661 + pop %eax
1662 + pop %ebp
1663 + ret
1664 +#endif /* SUPPORT_GRAPHICS */
1665 +
1666 +
1667 /*
1668 * getrtsecs()
1669 * if a seconds value can be read, read it and return it (BCD),
1670 --- a/stage2/boot.c
1671 +++ b/stage2/boot.c
1672 @@ -1,7 +1,7 @@
1673 /* boot.c - load and bootstrap a kernel */
1674 /*
1675 * GRUB -- GRand Unified Bootloader
1676 - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
1677 + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005 Free Software Foundation, Inc.
1678 *
1679 * This program is free software; you can redistribute it and/or modify
1680 * it under the terms of the GNU General Public License as published by
1681 @@ -29,6 +29,8 @@ static int cur_addr;
1682 entry_func entry_addr;
1683 static struct mod_list mll[99];
1684 static int linux_mem_size;
1685 +static int elf_kernel_addr;
1686 +static int elf_kernel_size;
1687
1688 /*
1689 * The next two functions, 'load_image' and 'load_module', are the building
1690 @@ -96,7 +98,7 @@ load_image (char *kernel, char *arg, ker
1691 lh = (struct linux_kernel_header *) buffer;
1692
1693 /* ELF loading supported if multiboot, FreeBSD and NetBSD. */
1694 - if ((type == KERNEL_TYPE_MULTIBOOT
1695 + if (((type == KERNEL_TYPE_MULTIBOOT && ! (flags & MULTIBOOT_AOUT_KLUDGE))
1696 || pu.elf->e_ident[EI_OSABI] == ELFOSABI_FREEBSD
1697 || grub_strcmp (pu.elf->e_ident + EI_BRAND, "FreeBSD") == 0
1698 || suggested_type == KERNEL_TYPE_NETBSD)
1699 @@ -594,6 +596,7 @@ load_image (char *kernel, char *arg, ker
1700
1701 /* reset this to zero for now */
1702 cur_addr = 0;
1703 + elf_kernel_addr = ~0;
1704
1705 /* scan for program segments */
1706 for (i = 0; i < pu.elf->e_phnum; i++)
1707 @@ -630,6 +633,8 @@ load_image (char *kernel, char *arg, ker
1708 /* mark memory as used */
1709 if (cur_addr < memaddr + memsiz)
1710 cur_addr = memaddr + memsiz;
1711 + if (elf_kernel_addr > cur_addr)
1712 + elf_kernel_addr = cur_addr;
1713 printf (", <0x%x:0x%x:0x%x>", memaddr, filesiz,
1714 memsiz - filesiz);
1715 /* increment number of segments */
1716 @@ -647,6 +652,8 @@ load_image (char *kernel, char *arg, ker
1717 }
1718 }
1719
1720 + elf_kernel_size = cur_addr - elf_kernel_addr;
1721 +
1722 if (! errnum)
1723 {
1724 if (! loaded)
1725 @@ -824,8 +831,11 @@ load_initrd (char *initrd)
1726 moveto = (mbi.mem_upper + 0x400) << 10;
1727
1728 moveto = (moveto - len) & 0xfffff000;
1729 - max_addr = (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0203
1730 - ? lh->initrd_addr_max : LINUX_INITRD_MAX_ADDRESS);
1731 + max_addr = LINUX_INITRD_MAX_ADDRESS;
1732 + if (lh->header == LINUX_MAGIC_SIGNATURE &&
1733 + lh->version >= 0x0203 &&
1734 + lh->initrd_addr_max < max_addr)
1735 + max_addr = lh->initrd_addr_max;
1736 if (moveto + len >= max_addr)
1737 moveto = (max_addr - len) & 0xfffff000;
1738
1739 @@ -864,6 +874,129 @@ bsd_boot_entry (int flags, int bootdev,
1740 }
1741 #endif
1742
1743 +#define mem_align4k(p) ((p) + 0xFFF) & 0xFFFFF000
1744 +
1745 +static void
1746 +kfreebsd_setenv (char *env, const char *var, const char *value)
1747 +{
1748 + while (1)
1749 + {
1750 + if (env[0] == '\0' && env[1] == '\0')
1751 + {
1752 + env++;
1753 + break;
1754 + }
1755 + else
1756 + env++;
1757 + }
1758 +
1759 + grub_sprintf (env, "%s=%s", var, value);
1760 + env[grub_strlen (env) + 1] = '\0';
1761 +}
1762 +
1763 +static char *
1764 +kfreebsd_read_hints (char *buf)
1765 +{
1766 + char *buf_end = buf;
1767 +
1768 + if (grub_open ("/boot/device.hints"))
1769 + {
1770 + char *line_start;
1771 + int line_len = 0;
1772 + char *envp;
1773 + int env_len;
1774 +
1775 + env_len = grub_read (buf, -1);
1776 + if (env_len)
1777 + {
1778 + buf_end += env_len;
1779 + *(buf_end++) = '\0';
1780 + }
1781 + else
1782 + return buf_end;
1783 +
1784 + grub_close ();
1785 +
1786 + envp = line_start = buf;
1787 + while (*envp)
1788 + {
1789 + char *envp_current = envp;
1790 +
1791 + switch (*envp)
1792 + {
1793 + case ' ':
1794 + while (*envp == ' ')
1795 + {
1796 + envp++;
1797 + env_len--;
1798 + }
1799 + grub_memmove (envp_current, envp, env_len + 1);
1800 + envp = envp_current;
1801 + break;
1802 + case '#':
1803 + while (*envp != '\n')
1804 + {
1805 + envp++;
1806 + env_len--;
1807 + }
1808 + if (!line_len)
1809 + envp++;
1810 + grub_memmove (envp_current, envp, env_len + 1);
1811 + envp = envp_current;
1812 + break;
1813 + case '\n':
1814 + if (!line_len)
1815 + {
1816 + env_len--;
1817 + grub_memmove (line_start, envp, env_len + 1);
1818 + }
1819 + *(envp++) = '\0';
1820 + line_len = 0;
1821 + line_start = envp;
1822 + default:
1823 + envp++;
1824 + line_len++;
1825 + break;
1826 + }
1827 + }
1828 +
1829 + buf_end = buf + env_len;
1830 + *(buf_end++) = '\0';
1831 + }
1832 +
1833 + return buf_end;
1834 +}
1835 +
1836 +static u32_t *
1837 +kfreebsd_set_module_string (u32_t type, u32_t *dst, char *src)
1838 +{
1839 + int size;
1840 +
1841 + *(dst++) = type;
1842 + *(dst++) = size = grub_strlen (src) + 1;
1843 + grub_strcpy ((void *) dst, src);
1844 +
1845 + return dst + (size + sizeof(u32_t) - 1) / sizeof(u32_t);
1846 +}
1847 +
1848 +static u32_t *
1849 +kfreebsd_set_module_var (u32_t type, u32_t *dst, u32_t src)
1850 +{
1851 + *(dst++) = type;
1852 + *(dst++) = sizeof(u32_t);
1853 + *(dst++) = src;
1854 +
1855 + return dst;
1856 +}
1857 +
1858 +static u32_t *
1859 +kfreebsd_set_modules (u32_t *modulep)
1860 +{
1861 + /* XXX: Need to copy the whole module structure. */
1862 + /* XXX: How to pass the module name ? */
1863 +
1864 + return modulep;
1865 +}
1866
1867 /*
1868 * All "*_boot" commands depend on the images being loaded into memory
1869 @@ -877,7 +1010,10 @@ void
1870 bsd_boot (kernel_t type, int bootdev, char *arg)
1871 {
1872 char *str;
1873 - int clval = 0, i;
1874 + char *kernelname;
1875 + char *bsd_root;
1876 + int clval = 0;
1877 + int i;
1878 struct bootinfo bi;
1879
1880 #ifdef GRUB_UTIL
1881 @@ -886,8 +1022,21 @@ bsd_boot (kernel_t type, int bootdev, ch
1882 stop_floppy ();
1883 #endif
1884
1885 + while (*arg != '/')
1886 + arg++;
1887 + kernelname = arg;
1888 +
1889 while (*(++arg) && *arg != ' ');
1890 + *(arg++) = 0;
1891 str = arg;
1892 +
1893 + bsd_root = grub_strstr (str, "root=");
1894 + if (bsd_root)
1895 + {
1896 + bsd_root += 5;
1897 + /* XXX: should copy the str or terminate it. */
1898 + }
1899 +
1900 while (*str)
1901 {
1902 if (*str == '-')
1903 @@ -910,6 +1059,8 @@ bsd_boot (kernel_t type, int bootdev, ch
1904 clval |= RB_GDB;
1905 if (*str == 'h')
1906 clval |= RB_SERIAL;
1907 + if (*str == 'p')
1908 + clval |= RB_PAUSE;
1909 if (*str == 'm')
1910 clval |= RB_MUTE;
1911 if (*str == 'r')
1912 @@ -927,14 +1078,17 @@ bsd_boot (kernel_t type, int bootdev, ch
1913
1914 if (type == KERNEL_TYPE_FREEBSD)
1915 {
1916 + char *envp;
1917 + u32_t *modp;
1918 +
1919 clval |= RB_BOOTINFO;
1920
1921 bi.bi_version = BOOTINFO_VERSION;
1922
1923 - *arg = 0;
1924 - while ((--arg) > (char *) MB_CMDLINE_BUF && *arg != '/');
1925 - if (*arg == '/')
1926 - bi.bi_kernelname = arg + 1;
1927 + bi.bi_pad[0] = bi.bi_pad[1] = 0;
1928 +
1929 + if (*kernelname == '/')
1930 + bi.bi_kernelname = kernelname;
1931 else
1932 bi.bi_kernelname = 0;
1933
1934 @@ -961,6 +1115,30 @@ bsd_boot (kernel_t type, int bootdev, ch
1935 bi.bi_basemem = mbi.mem_lower;
1936 bi.bi_extmem = extended_memory;
1937
1938 + /* Setup the environment. */
1939 + bi.bi_envp = cur_addr = mem_align4k (cur_addr);
1940 + grub_memset ((void *) cur_addr, 0, 2);
1941 + cur_addr = (int) kfreebsd_read_hints ((void *) cur_addr);
1942 +
1943 + envp = (char *) bi.bi_envp;
1944 + kfreebsd_setenv (envp, "kernelname", kernelname);
1945 + kfreebsd_setenv (envp, "vfs.root.mountfrom", bsd_root);
1946 +
1947 + /* Setup the modules list. */
1948 + bi.bi_modulep = cur_addr = mem_align4k (cur_addr);
1949 + modp = (u32_t *) bi.bi_modulep;
1950 + /* The first module is the kernel. */
1951 + modp = kfreebsd_set_module_string (MODINFO_NAME, modp, kernelname);
1952 + modp = kfreebsd_set_module_string (MODINFO_TYPE, modp, "elf kernel");
1953 + modp = kfreebsd_set_module_string (MODINFO_ARGS, modp, arg);
1954 + modp = kfreebsd_set_module_var (MODINFO_ADDR, modp, elf_kernel_addr);
1955 + modp = kfreebsd_set_module_var (MODINFO_SIZE, modp, elf_kernel_size);
1956 + /* Now the real modules. */
1957 + modp = kfreebsd_set_modules(modp);
1958 +
1959 + /* Set the kernel end. */
1960 + bi.bi_kernend = cur_addr = mem_align4k (((int) modp) + 1);
1961 +
1962 if (mbi.flags & MB_INFO_AOUT_SYMS)
1963 {
1964 bi.bi_symtab = mbi.syms.a.addr;
1965 @@ -970,8 +1148,9 @@ bsd_boot (kernel_t type, int bootdev, ch
1966 #if 0
1967 else if (mbi.flags & MB_INFO_ELF_SHDR)
1968 {
1969 - /* FIXME: Should check if a symbol table exists and, if exists,
1970 - pass the table to BI. */
1971 + bi.bi_symtab = mbi.syms.e.addr;
1972 + bi.bi_esymtab = mbi.syms.e.addr
1973 + + mbi.syms.e.size * mbi.syms.e.num * mbi.syms.e.shndx;
1974 }
1975 #endif
1976 else
1977 --- a/stage2/builtins.c
1978 +++ b/stage2/builtins.c
1979 @@ -28,6 +28,10 @@
1980 #include <filesys.h>
1981 #include <term.h>
1982
1983 +#ifdef SUPPORT_GRAPHICS
1984 +# include <graphics.h>
1985 +#endif
1986 +
1987 #ifdef SUPPORT_NETBOOT
1988 # define GRUB 1
1989 # include <etherboot.h>
1990 @@ -82,6 +86,10 @@ static unsigned short bios_drive_map[DRI
1991 inside other functions. */
1992 static int configfile_func (char *arg, int flags);
1993
1994 +static int savedefault_helper (char *arg, int flags);
1995 +
1996 +static int savedefault_shell (char *arg, int flags);
1997 +
1998 /* Initialize the data for builtins. */
1999 void
2000 init_builtins (void)
2001 @@ -237,12 +245,22 @@ static struct builtin builtin_blocklist
2002 static int
2003 boot_func (char *arg, int flags)
2004 {
2005 + struct term_entry *prev_term = current_term;
2006 /* Clear the int15 handler if we can boot the kernel successfully.
2007 This assumes that the boot code never fails only if KERNEL_TYPE is
2008 not KERNEL_TYPE_NONE. Is this assumption is bad? */
2009 if (kernel_type != KERNEL_TYPE_NONE)
2010 unset_int15_handler ();
2011
2012 + /* if our terminal needed initialization, we should shut it down
2013 + * before booting the kernel, but we want to save what it was so
2014 + * we can come back if needed */
2015 + if (current_term->shutdown)
2016 + {
2017 + current_term->shutdown();
2018 + current_term = term_table; /* assumption: console is first */
2019 + }
2020 +
2021 #ifdef SUPPORT_NETBOOT
2022 /* Shut down the networking. */
2023 cleanup_net ();
2024 @@ -306,6 +324,13 @@ boot_func (char *arg, int flags)
2025 return 1;
2026 }
2027
2028 + /* if we get back here, we should go back to what our term was before */
2029 + current_term = prev_term;
2030 + if (current_term->startup)
2031 + /* if our terminal fails to initialize, fall back to console since
2032 + * it should always work */
2033 + if (current_term->startup() == 0)
2034 + current_term = term_table; /* we know that console is first */
2035 return 0;
2036 }
2037
2038 @@ -852,6 +877,251 @@ static struct builtin builtin_dhcp =
2039 };
2040 #endif /* SUPPORT_NETBOOT */
2041
2042 +#ifdef SUPPORT_GRAPHICS
2043 +\f
2044 +static int splashimage_func(char *arg, int flags) {
2045 + int i;
2046 +
2047 + /* filename can only be 256 characters due to our buffer size */
2048 + if (grub_strlen(arg) > 256) {
2049 + grub_printf("Splash image filename too large\n");
2050 + grub_printf("Press any key to continue...");
2051 + getkey();
2052 + return 1;
2053 + }
2054 +
2055 + /* get rid of TERM_NEED_INIT from the graphics terminal. */
2056 + for (i = 0; term_table[i].name; i++) {
2057 + if (grub_strcmp (term_table[i].name, "graphics") == 0) {
2058 + term_table[i].flags &= ~TERM_NEED_INIT;
2059 + break;
2060 + }
2061 + }
2062 +
2063 + graphics_set_splash(arg);
2064 +
2065 + if (flags == BUILTIN_CMDLINE && graphics_inited) {
2066 + graphics_end();
2067 + if (graphics_init() == 0) {
2068 + /* Fallback to default term */
2069 + current_term = term_table;
2070 + max_lines = current_term->max_lines;
2071 + if (current_term->cls)
2072 + current_term->cls();
2073 + grub_printf("Failed to set splash image and/or graphics mode\n");
2074 + return 1;
2075 + }
2076 + graphics_cls();
2077 + }
2078 +
2079 + if (flags == BUILTIN_MENU)
2080 + current_term = term_table + i;
2081 +
2082 + return 0;
2083 +}
2084 +
2085 +static struct builtin builtin_splashimage =
2086 +{
2087 + "splashimage",
2088 + splashimage_func,
2089 + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
2090 + "splashimage FILE",
2091 + "Load FILE as the background image when in graphics mode."
2092 +};
2093 +
2094 +\f
2095 +/* shade */
2096 +static int
2097 +shade_func(char *arg, int flags)
2098 +{
2099 + int new_shade;
2100 +
2101 + if (!arg || safe_parse_maxint(&arg, &new_shade) == 0)
2102 + return (1);
2103 +
2104 + if (shade != new_shade) {
2105 + shade = new_shade;
2106 + if (flags == BUILTIN_CMDLINE && graphics_inited) {
2107 + graphics_end();
2108 + graphics_init();
2109 + graphics_cls();
2110 + }
2111 + }
2112 +
2113 + return 0;
2114 +}
2115 +
2116 +static struct builtin builtin_shade =
2117 +{
2118 + "shade",
2119 + shade_func,
2120 + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
2121 + "shade INTEGER",
2122 + "If set to 0, disables the use of shaded text, else enables it."
2123 +};
2124 +
2125 +\f
2126 +/* foreground */
2127 +static int
2128 +foreground_func(char *arg, int flags)
2129 +{
2130 + if (grub_strlen(arg) == 6) {
2131 + int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
2132 + int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
2133 + int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
2134 +
2135 + foreground = (r << 16) | (g << 8) | b;
2136 + if (graphics_inited)
2137 + graphics_set_palette(15, r, g, b);
2138 +
2139 + return 0;
2140 + }
2141 +
2142 + return 1;
2143 +}
2144 +
2145 +static struct builtin builtin_foreground =
2146 +{
2147 + "foreground",
2148 + foreground_func,
2149 + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
2150 + "foreground RRGGBB",
2151 + "Sets the foreground color when in graphics mode."
2152 + "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
2153 +};
2154 +
2155 +\f
2156 +/* background */
2157 +static int
2158 +background_func(char *arg, int flags)
2159 +{
2160 + if (grub_strlen(arg) == 6) {
2161 + int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
2162 + int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
2163 + int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
2164 +
2165 + background = (r << 16) | (g << 8) | b;
2166 + if (graphics_inited)
2167 + graphics_set_palette(0, r, g, b);
2168 + return 0;
2169 + }
2170 +
2171 + return 1;
2172 +}
2173 +
2174 +static struct builtin builtin_background =
2175 +{
2176 + "background",
2177 + background_func,
2178 + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
2179 + "background RRGGBB",
2180 + "Sets the background color when in graphics mode."
2181 + "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
2182 +};
2183 +
2184 +\f
2185 +/* border */
2186 +static int
2187 +border_func(char *arg, int flags)
2188 +{
2189 + if (grub_strlen(arg) == 6) {
2190 + int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
2191 + int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
2192 + int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
2193 +
2194 + window_border = (r << 16) | (g << 8) | b;
2195 + if (graphics_inited)
2196 + graphics_set_palette(0x11, r, g, b);
2197 +
2198 + return 0;
2199 + }
2200 +
2201 + return 1;
2202 +}
2203 +
2204 +static struct builtin builtin_border =
2205 +{
2206 + "border",
2207 + border_func,
2208 + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
2209 + "border RRGGBB",
2210 + "Sets the border video color when in graphics mode."
2211 + "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
2212 +};
2213 +
2214 +\f
2215 +/* viewport */
2216 +static int
2217 +viewport_func (char *arg, int flags)
2218 +{
2219 + int i;
2220 + int x0 = 0, y0 = 0, x1 = 80, y1 = 30;
2221 + int *pos[4] = { &x0, &y0, &x1, &y1 };
2222 +
2223 + if (!arg)
2224 + return (1);
2225 + for (i = 0; i < 4; i++) {
2226 + if (!*arg)
2227 + return (1);
2228 + while (*arg && (*arg == ' ' || *arg == '\t'))
2229 + ++arg;
2230 + if (!safe_parse_maxint(&arg, pos[i]))
2231 + return (1);
2232 + while (*arg && (*arg != ' ' && *arg != '\t'))
2233 + ++arg;
2234 + }
2235 +
2236 + /* minimum size is 65 colums and 16 rows */
2237 + if (x0 > x1 - 66 || y0 > y1 - 16 || x0 < 0 || y0 < 0 || x1 > 80 || y1 > 30)
2238 + return 1;
2239 +
2240 + view_x0 = x0;
2241 + view_y0 = y0;
2242 + view_x1 = x1;
2243 + view_y1 = y1;
2244 +
2245 + if (flags == BUILTIN_CMDLINE && graphics_inited) {
2246 + graphics_end();
2247 + graphics_init();
2248 + graphics_cls();
2249 + }
2250 +
2251 + return 0;
2252 +}
2253 +
2254 +static struct builtin builtin_viewport =
2255 +{
2256 + "viewport",
2257 + viewport_func,
2258 + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
2259 + "viewport x0 y0 x1 y1",
2260 + "Changes grub internals to output text in the window defined by"
2261 + " four parameters. The x and y parameters are 0 based. This option"
2262 + " only works with the graphics interface."
2263 +};
2264 +
2265 +#endif /* SUPPORT_GRAPHICS */
2266 +
2267 +\f
2268 +/* clear */
2269 +static int
2270 +clear_func()
2271 +{
2272 + if (current_term->cls)
2273 + current_term->cls();
2274 +
2275 + return 0;
2276 +}
2277 +
2278 +static struct builtin builtin_clear =
2279 +{
2280 + "clear",
2281 + clear_func,
2282 + BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
2283 + "clear",
2284 + "Clear the screen"
2285 +};
2286 +
2287 \f
2288 /* displayapm */
2289 static int
2290 @@ -1454,14 +1724,20 @@ static struct builtin builtin_halt =
2291
2292 \f
2293 /* help */
2294 -#define MAX_SHORT_DOC_LEN 39
2295 -#define MAX_LONG_DOC_LEN 66
2296 -
2297 static int
2298 help_func (char *arg, int flags)
2299 {
2300 - int all = 0;
2301 -
2302 + int all = 0, max_short_doc_len, max_long_doc_len;
2303 + max_short_doc_len = 39;
2304 + max_long_doc_len = 66;
2305 +#ifdef SUPPORT_GRAPHICS
2306 + if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
2307 + {
2308 + max_short_doc_len = (view_x1 - view_x0 + 1) / 2 - 1;
2309 + max_long_doc_len = (view_x1 - view_x0) - 14;
2310 + }
2311 +#endif
2312 +
2313 if (grub_memcmp (arg, "--all", sizeof ("--all") - 1) == 0)
2314 {
2315 all = 1;
2316 @@ -1491,13 +1767,13 @@ help_func (char *arg, int flags)
2317
2318 len = grub_strlen ((*builtin)->short_doc);
2319 /* If the length of SHORT_DOC is too long, truncate it. */
2320 - if (len > MAX_SHORT_DOC_LEN - 1)
2321 - len = MAX_SHORT_DOC_LEN - 1;
2322 + if (len > max_short_doc_len - 1)
2323 + len = max_short_doc_len - 1;
2324
2325 for (i = 0; i < len; i++)
2326 grub_putchar ((*builtin)->short_doc[i]);
2327
2328 - for (; i < MAX_SHORT_DOC_LEN; i++)
2329 + for (; i < max_short_doc_len; i++)
2330 grub_putchar (' ');
2331
2332 if (! left)
2333 @@ -1546,10 +1822,10 @@ help_func (char *arg, int flags)
2334 int i;
2335
2336 /* If LEN is too long, fold DOC. */
2337 - if (len > MAX_LONG_DOC_LEN)
2338 + if (len > max_long_doc_len)
2339 {
2340 /* Fold this line at the position of a space. */
2341 - for (len = MAX_LONG_DOC_LEN; len > 0; len--)
2342 + for (len = max_long_doc_len; len > 0; len--)
2343 if (doc[len - 1] == ' ')
2344 break;
2345 }
2346 @@ -2323,6 +2599,25 @@ static struct builtin builtin_ioprobe =
2347 "Probe I/O ports used for the drive DRIVE."
2348 };
2349
2350 +/* print */
2351 +static int
2352 +print_func (char *arg, int flags)
2353 +{
2354 + printf("%s\n", arg);
2355 +
2356 + return 0;
2357 +}
2358 +
2359 +static struct builtin builtin_print =
2360 +{
2361 + "print",
2362 + print_func,
2363 + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_NO_ECHO,
2364 + "print [MESSAGE ...]",
2365 + "Print MESSAGE."
2366 +};
2367 +
2368 +
2369 \f
2370 /* kernel */
2371 static int
2372 @@ -3221,7 +3516,102 @@ static struct builtin builtin_rootnoveri
2373 static int
2374 savedefault_func (char *arg, int flags)
2375 {
2376 -#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
2377 +#if !defined(SUPPORT_DISKLESS)
2378 + #if !defined(GRUB_UTIL)
2379 + savedefault_helper(arg, flags);
2380 + #else
2381 + savedefault_shell(arg, flags);
2382 + #endif
2383 +#else /* !SUPPORT_DISKLESS */
2384 + errnum = ERR_UNRECOGNIZED;
2385 + return 1;
2386 +#endif /* !SUPPORT_DISKLESS */
2387 +}
2388 +
2389 +#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL)
2390 +/* savedefault_shell */
2391 +static int
2392 +savedefault_shell(char *arg, int flags)
2393 + {
2394 + int once_only = 0;
2395 + int new_default;
2396 + int curr_default = -1;
2397 + int curr_prev_default = -1;
2398 + int new_prev_default = -1;
2399 + FILE *fp;
2400 + size_t bytes = 10;
2401 + char line[bytes];
2402 + char *default_file = (char *) DEFAULT_FILE_BUF;
2403 + char buf[bytes];
2404 + int i;
2405 +
2406 + while (1)
2407 + {
2408 + if (grub_memcmp ("--default=", arg, sizeof ("--default=") - 1) == 0)
2409 + {
2410 + char *p = arg + sizeof ("--default=") - 1;
2411 + if (! safe_parse_maxint (&p, &new_default))
2412 + return 1;
2413 + arg = skip_to (0, arg);
2414 + }
2415 + else if (grub_memcmp ("--once", arg, sizeof ("--once") - 1) == 0)
2416 + {
2417 + once_only = 1;
2418 + arg = skip_to (0, arg);
2419 + }
2420 + else
2421 + break;
2422 + }
2423 +
2424 + *default_file = 0;
2425 + grub_strncat (default_file, config_file, DEFAULT_FILE_BUFLEN);
2426 + for (i = grub_strlen(default_file); i >= 0; i--)
2427 + if (default_file[i] == '/')
2428 + {
2429 + i++;
2430 + break;
2431 + }
2432 + default_file[i] = 0;
2433 + grub_strncat (default_file + i, "default", DEFAULT_FILE_BUFLEN - i);
2434 +
2435 + if(!(fp = fopen(default_file,"w")))
2436 + {
2437 + errnum = ERR_READ;
2438 + goto fail;
2439 + }
2440 +
2441 + read(&line, -1);
2442 +
2443 + sscanf(line, "%d:%d", &curr_prev_default, &curr_default);
2444 +
2445 + if(curr_default != -1)
2446 + new_prev_default = curr_default;
2447 + else
2448 + {
2449 + if(curr_prev_default != -1)
2450 + new_prev_default = curr_prev_default;
2451 + else
2452 + new_prev_default = 0;
2453 + }
2454 +
2455 + if(once_only)
2456 + sprintf(buf, "%d:%d\n", new_prev_default, new_default);
2457 + else
2458 + sprintf(buf, "%d\n", new_default);
2459 +
2460 + fprintf(fp, buf);
2461 +
2462 +fail:
2463 + fclose(fp);
2464 + return errnum;
2465 +}
2466 +#endif
2467 +
2468 +/* savedefault_helper */
2469 +static int
2470 +savedefault_helper (char *arg, int flags)
2471 +{
2472 +#if !defined(SUPPORT_DISKLESS)
2473 unsigned long tmp_drive = saved_drive;
2474 unsigned long tmp_partition = saved_partition;
2475 char *default_file = (char *) DEFAULT_FILE_BUF;
2476 @@ -3300,19 +3690,23 @@ savedefault_func (char *arg, int flags)
2477 disk_read_hook = 0;
2478 grub_close ();
2479
2480 - if (len != sizeof (buf))
2481 - {
2482 - /* This is too small. Do not modify the file manually, please! */
2483 - errnum = ERR_READ;
2484 - goto fail;
2485 - }
2486 -
2487 if (sector_count > 2)
2488 {
2489 /* Is this possible?! Too fragmented! */
2490 errnum = ERR_FSYS_CORRUPT;
2491 goto fail;
2492 }
2493 +
2494 + char *tmp;
2495 + if((tmp = grub_strstr(buf, ":")) != NULL)
2496 + {
2497 + int f_len = grub_strlen(buf) - grub_strlen(tmp);
2498 + char *def;
2499 + int a;
2500 + for(a = 0; a < f_len; a++)
2501 + grub_memcpy(&def[a], &buf[a], sizeof(char));
2502 + safe_parse_maxint (&def, &entryno);
2503 + }
2504
2505 /* Set up a string to be written. */
2506 grub_memset (buf, '\n', sizeof (buf));
2507 @@ -3830,15 +4224,15 @@ setup_func (char *arg, int flags)
2508 {
2509 char tmp[16];
2510 grub_sprintf (tmp, ",%d", (partition >> 16) & 0xFF);
2511 - grub_strncat (device, tmp, 256);
2512 + grub_strncat (device, tmp, sizeof (device));
2513 }
2514 if ((partition & 0x00FF00) != 0x00FF00)
2515 {
2516 char tmp[16];
2517 grub_sprintf (tmp, ",%c", 'a' + ((partition >> 8) & 0xFF));
2518 - grub_strncat (device, tmp, 256);
2519 + grub_strncat (device, tmp, sizeof (device));
2520 }
2521 - grub_strncat (device, ")", 256);
2522 + grub_strncat (device, ")", sizeof (device));
2523 }
2524
2525 int embed_stage1_5 (char *stage1_5, int drive, int partition)
2526 @@ -4085,7 +4479,7 @@ static struct builtin builtin_setup =
2527 };
2528
2529 \f
2530 -#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
2531 +#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
2532 /* terminal */
2533 static int
2534 terminal_func (char *arg, int flags)
2535 @@ -4244,17 +4638,29 @@ terminal_func (char *arg, int flags)
2536 end:
2537 current_term = term_table + default_term;
2538 current_term->flags = term_flags;
2539 -
2540 +
2541 if (lines)
2542 max_lines = lines;
2543 else
2544 - /* 24 would be a good default value. */
2545 - max_lines = 24;
2546 -
2547 + max_lines = current_term->max_lines;
2548 +
2549 /* If the interface is currently the command-line,
2550 restart it to repaint the screen. */
2551 - if (current_term != prev_term && (flags & BUILTIN_CMDLINE))
2552 + if ((current_term != prev_term) && (flags & BUILTIN_CMDLINE)){
2553 + if (prev_term->shutdown)
2554 + prev_term->shutdown();
2555 + if (current_term->startup) {
2556 + /* If startup fails, return to previous term */
2557 + if (current_term->startup() == 0) {
2558 + current_term = prev_term;
2559 + max_lines = current_term->max_lines;
2560 + if (current_term->cls) {
2561 + current_term->cls();
2562 + }
2563 + }
2564 + }
2565 grub_longjmp (restart_cmdline_env, 0);
2566 + }
2567
2568 return 0;
2569 }
2570 @@ -4264,7 +4670,7 @@ static struct builtin builtin_terminal =
2571 "terminal",
2572 terminal_func,
2573 BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
2574 - "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules]",
2575 + "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules] [graphics]",
2576 "Select a terminal. When multiple terminals are specified, wait until"
2577 " you push any key to continue. If both console and serial are specified,"
2578 " the terminal to which you input a key first will be selected. If no"
2579 @@ -4276,7 +4682,7 @@ static struct builtin builtin_terminal =
2580 " seconds. The option --lines specifies the maximum number of lines."
2581 " The option --silent is used to suppress messages."
2582 };
2583 -#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
2584 +#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
2585
2586 \f
2587 #ifdef SUPPORT_SERIAL
2588 @@ -4795,13 +5201,20 @@ static struct builtin builtin_vbeprobe =
2589 /* The table of builtin commands. Sorted in dictionary order. */
2590 struct builtin *builtin_table[] =
2591 {
2592 +#ifdef SUPPORT_GRAPHICS
2593 + &builtin_background,
2594 +#endif
2595 &builtin_blocklist,
2596 &builtin_boot,
2597 #ifdef SUPPORT_NETBOOT
2598 &builtin_bootp,
2599 #endif /* SUPPORT_NETBOOT */
2600 +#ifdef SUPPORT_GRAPHICS
2601 + &builtin_border,
2602 +#endif
2603 &builtin_cat,
2604 &builtin_chainloader,
2605 + &builtin_clear,
2606 &builtin_cmp,
2607 &builtin_color,
2608 &builtin_configfile,
2609 @@ -4821,6 +5234,9 @@ struct builtin *builtin_table[] =
2610 &builtin_embed,
2611 &builtin_fallback,
2612 &builtin_find,
2613 +#ifdef SUPPORT_GRAPHICS
2614 + &builtin_foreground,
2615 +#endif
2616 &builtin_fstest,
2617 &builtin_geometry,
2618 &builtin_halt,
2619 @@ -4848,6 +5264,7 @@ struct builtin *builtin_table[] =
2620 &builtin_parttype,
2621 &builtin_password,
2622 &builtin_pause,
2623 + &builtin_print,
2624 #ifdef GRUB_UTIL
2625 &builtin_quit,
2626 #endif /* GRUB_UTIL */
2627 @@ -4864,9 +5281,13 @@ struct builtin *builtin_table[] =
2628 #endif /* SUPPORT_SERIAL */
2629 &builtin_setkey,
2630 &builtin_setup,
2631 -#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
2632 +#ifdef SUPPORT_GRAPHICS
2633 + &builtin_shade,
2634 + &builtin_splashimage,
2635 +#endif /* SUPPORT_GRAPHICS */
2636 +#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
2637 &builtin_terminal,
2638 -#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
2639 +#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
2640 #ifdef SUPPORT_SERIAL
2641 &builtin_terminfo,
2642 #endif /* SUPPORT_SERIAL */
2643 @@ -4880,5 +5301,8 @@ struct builtin *builtin_table[] =
2644 &builtin_unhide,
2645 &builtin_uppermem,
2646 &builtin_vbeprobe,
2647 +#ifdef SUPPORT_GRAPHICS
2648 + &builtin_viewport,
2649 +#endif
2650 0
2651 };
2652 --- a/stage2/char_io.c
2653 +++ b/stage2/char_io.c
2654 @@ -29,12 +29,17 @@
2655 # include <serial.h>
2656 #endif
2657
2658 +#ifdef SUPPORT_GRAPHICS
2659 +# include <graphics.h>
2660 +#endif
2661 +
2662 #ifndef STAGE1_5
2663 struct term_entry term_table[] =
2664 {
2665 {
2666 "console",
2667 0,
2668 + 24,
2669 console_putchar,
2670 console_checkkey,
2671 console_getkey,
2672 @@ -43,13 +48,16 @@ struct term_entry term_table[] =
2673 console_cls,
2674 console_setcolorstate,
2675 console_setcolor,
2676 - console_setcursor
2677 + console_setcursor,
2678 + 0,
2679 + 0
2680 },
2681 #ifdef SUPPORT_SERIAL
2682 {
2683 "serial",
2684 /* A serial device must be initialized. */
2685 TERM_NEED_INIT,
2686 + 24,
2687 serial_putchar,
2688 serial_checkkey,
2689 serial_getkey,
2690 @@ -58,6 +66,8 @@ struct term_entry term_table[] =
2691 serial_cls,
2692 serial_setcolorstate,
2693 0,
2694 + 0,
2695 + 0,
2696 0
2697 },
2698 #endif /* SUPPORT_SERIAL */
2699 @@ -65,6 +75,7 @@ struct term_entry term_table[] =
2700 {
2701 "hercules",
2702 0,
2703 + 24,
2704 hercules_putchar,
2705 console_checkkey,
2706 console_getkey,
2707 @@ -73,11 +84,30 @@ struct term_entry term_table[] =
2708 hercules_cls,
2709 hercules_setcolorstate,
2710 hercules_setcolor,
2711 - hercules_setcursor
2712 + hercules_setcursor,
2713 + 0,
2714 + 0
2715 },
2716 #endif /* SUPPORT_HERCULES */
2717 +#ifdef SUPPORT_GRAPHICS
2718 + { "graphics",
2719 + TERM_NEED_INIT, /* flags */
2720 + 30, /* number of lines */
2721 + graphics_putchar, /* putchar */
2722 + console_checkkey, /* checkkey */
2723 + console_getkey, /* getkey */
2724 + graphics_getxy, /* getxy */
2725 + graphics_gotoxy, /* gotoxy */
2726 + graphics_cls, /* cls */
2727 + graphics_setcolorstate, /* setcolorstate */
2728 + graphics_setcolor, /* setcolor */
2729 + graphics_setcursor, /* nocursor */
2730 + graphics_init, /* initialize */
2731 + graphics_end /* shutdown */
2732 + },
2733 +#endif /* SUPPORT_GRAPHICS */
2734 /* This must be the last entry. */
2735 - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
2736 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
2737 };
2738
2739 /* This must be console. */
2740 @@ -305,9 +335,10 @@ real_get_cmdline (char *prompt, char *cm
2741
2742 /* XXX: These should be defined in shared.h, but I leave these here,
2743 until this code is freezed. */
2744 -#define CMDLINE_WIDTH 78
2745 #define CMDLINE_MARGIN 10
2746 -
2747 +
2748 + /* command-line limits */
2749 + int cmdline_width = 78, col_start = 0;
2750 int xpos, lpos, c, section;
2751 /* The length of PROMPT. */
2752 int plen;
2753 @@ -338,7 +369,7 @@ real_get_cmdline (char *prompt, char *cm
2754
2755 /* If the cursor is in the first section, display the first section
2756 instead of the second. */
2757 - if (section == 1 && plen + lpos < CMDLINE_WIDTH)
2758 + if (section == 1 && plen + lpos < cmdline_width)
2759 cl_refresh (1, 0);
2760 else if (xpos - count < 1)
2761 cl_refresh (1, 0);
2762 @@ -354,7 +385,7 @@ real_get_cmdline (char *prompt, char *cm
2763 grub_putchar ('\b');
2764 }
2765 else
2766 - gotoxy (xpos, getxy () & 0xFF);
2767 + gotoxy (xpos + col_start, getxy () & 0xFF);
2768 }
2769 }
2770
2771 @@ -364,7 +395,7 @@ real_get_cmdline (char *prompt, char *cm
2772 lpos += count;
2773
2774 /* If the cursor goes outside, scroll the screen to the right. */
2775 - if (xpos + count >= CMDLINE_WIDTH)
2776 + if (xpos + count >= cmdline_width)
2777 cl_refresh (1, 0);
2778 else
2779 {
2780 @@ -383,7 +414,7 @@ real_get_cmdline (char *prompt, char *cm
2781 }
2782 }
2783 else
2784 - gotoxy (xpos, getxy () & 0xFF);
2785 + gotoxy (xpos + col_start, getxy () & 0xFF);
2786 }
2787 }
2788
2789 @@ -398,14 +429,14 @@ real_get_cmdline (char *prompt, char *cm
2790 if (full)
2791 {
2792 /* Recompute the section number. */
2793 - if (lpos + plen < CMDLINE_WIDTH)
2794 + if (lpos + plen < cmdline_width)
2795 section = 0;
2796 else
2797 - section = ((lpos + plen - CMDLINE_WIDTH)
2798 - / (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) + 1);
2799 + section = ((lpos + plen - cmdline_width)
2800 + / (cmdline_width - 1 - CMDLINE_MARGIN) + 1);
2801
2802 /* From the start to the end. */
2803 - len = CMDLINE_WIDTH;
2804 + len = cmdline_width;
2805 pos = 0;
2806 grub_putchar ('\r');
2807
2808 @@ -445,8 +476,8 @@ real_get_cmdline (char *prompt, char *cm
2809 if (! full)
2810 offset = xpos - 1;
2811
2812 - start = ((section - 1) * (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN)
2813 - + CMDLINE_WIDTH - plen - CMDLINE_MARGIN);
2814 + start = ((section - 1) * (cmdline_width - 1 - CMDLINE_MARGIN)
2815 + + cmdline_width - plen - CMDLINE_MARGIN);
2816 xpos = lpos + 1 - start;
2817 start += offset;
2818 }
2819 @@ -471,7 +502,7 @@ real_get_cmdline (char *prompt, char *cm
2820
2821 /* If the cursor is at the last position, put `>' or a space,
2822 depending on if there are more characters in BUF. */
2823 - if (pos == CMDLINE_WIDTH)
2824 + if (pos == cmdline_width)
2825 {
2826 if (start + len < llen)
2827 grub_putchar ('>');
2828 @@ -488,7 +519,7 @@ real_get_cmdline (char *prompt, char *cm
2829 grub_putchar ('\b');
2830 }
2831 else
2832 - gotoxy (xpos, getxy () & 0xFF);
2833 + gotoxy (xpos + col_start, getxy () & 0xFF);
2834 }
2835
2836 /* Initialize the command-line. */
2837 @@ -518,10 +549,10 @@ real_get_cmdline (char *prompt, char *cm
2838
2839 llen += l;
2840 lpos += l;
2841 - if (xpos + l >= CMDLINE_WIDTH)
2842 + if (xpos + l >= cmdline_width)
2843 cl_refresh (1, 0);
2844 - else if (xpos + l + llen - lpos > CMDLINE_WIDTH)
2845 - cl_refresh (0, CMDLINE_WIDTH - xpos);
2846 + else if (xpos + l + llen - lpos > cmdline_width)
2847 + cl_refresh (0, cmdline_width - xpos);
2848 else
2849 cl_refresh (0, l + llen - lpos);
2850 }
2851 @@ -533,12 +564,22 @@ real_get_cmdline (char *prompt, char *cm
2852 grub_memmove (buf + lpos, buf + lpos + count, llen - count + 1);
2853 llen -= count;
2854
2855 - if (xpos + llen + count - lpos > CMDLINE_WIDTH)
2856 - cl_refresh (0, CMDLINE_WIDTH - xpos);
2857 + if (xpos + llen + count - lpos > cmdline_width)
2858 + cl_refresh (0, cmdline_width - xpos);
2859 else
2860 cl_refresh (0, llen + count - lpos);
2861 }
2862
2863 + max_lines = current_term->max_lines;
2864 +#ifdef SUPPORT_GRAPHICS
2865 + if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
2866 + {
2867 + cmdline_width = (view_x1 - view_x0) - 2;
2868 + col_start = view_x0;
2869 + max_lines = view_y1 - view_y0;
2870 + }
2871 +#endif
2872 +
2873 plen = grub_strlen (prompt);
2874 llen = grub_strlen (cmdline);
2875
2876 @@ -1006,6 +1047,48 @@ checkkey (void)
2877 }
2878 #endif /* ! STAGE1_5 */
2879
2880 +#ifndef STAGE1_5
2881 +/* Internal pager. */
2882 +int
2883 +do_more (void)
2884 +{
2885 + if (count_lines >= 0)
2886 + {
2887 + count_lines++;
2888 + if (count_lines >= max_lines - 2)
2889 + {
2890 + int tmp;
2891 +
2892 + /* It's important to disable the feature temporarily, because
2893 + the following grub_printf call will print newlines. */
2894 + count_lines = -1;
2895 +
2896 + grub_printf("\n");
2897 + if (current_term->setcolorstate)
2898 + current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
2899 +
2900 + grub_printf ("[Hit return to continue]");
2901 +
2902 + if (current_term->setcolorstate)
2903 + current_term->setcolorstate (COLOR_STATE_NORMAL);
2904 +
2905 +
2906 + do
2907 + {
2908 + tmp = ASCII_CHAR (getkey ());
2909 + }
2910 + while (tmp != '\n' && tmp != '\r');
2911 + grub_printf ("\r \r");
2912 +
2913 + /* Restart to count lines. */
2914 + count_lines = 0;
2915 + return 1;
2916 + }
2917 + }
2918 + return 0;
2919 +}
2920 +#endif
2921 +
2922 /* Display an ASCII character. */
2923 void
2924 grub_putchar (int c)
2925 @@ -1034,38 +1117,11 @@ grub_putchar (int c)
2926
2927 if (c == '\n')
2928 {
2929 + int flag;
2930 /* Internal `more'-like feature. */
2931 - if (count_lines >= 0)
2932 - {
2933 - count_lines++;
2934 - if (count_lines >= max_lines - 2)
2935 - {
2936 - int tmp;
2937 -
2938 - /* It's important to disable the feature temporarily, because
2939 - the following grub_printf call will print newlines. */
2940 - count_lines = -1;
2941 -
2942 - if (current_term->setcolorstate)
2943 - current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
2944 -
2945 - grub_printf ("\n[Hit return to continue]");
2946 -
2947 - if (current_term->setcolorstate)
2948 - current_term->setcolorstate (COLOR_STATE_NORMAL);
2949 -
2950 - do
2951 - {
2952 - tmp = ASCII_CHAR (getkey ());
2953 - }
2954 - while (tmp != '\n' && tmp != '\r');
2955 - grub_printf ("\r \r");
2956 -
2957 - /* Restart to count lines. */
2958 - count_lines = 0;
2959 - return;
2960 - }
2961 - }
2962 + flag = do_more ();
2963 + if (flag)
2964 + return;
2965 }
2966
2967 current_term->putchar (c);
2968 @@ -1090,7 +1146,7 @@ void
2969 cls (void)
2970 {
2971 /* If the terminal is dumb, there is no way to clean the terminal. */
2972 - if (current_term->flags & TERM_DUMB)
2973 + if (current_term->flags & TERM_DUMB)
2974 grub_putchar ('\n');
2975 else
2976 current_term->cls ();
2977 @@ -1175,13 +1231,13 @@ grub_strlen (const char *str)
2978 #endif /* ! STAGE1_5 */
2979
2980 int
2981 -memcheck (int addr, int len)
2982 +memcheck (unsigned long int addr, unsigned long int len)
2983 {
2984 #ifdef GRUB_UTIL
2985 - auto int start_addr (void);
2986 - auto int end_addr (void);
2987 + auto unsigned long int start_addr (void);
2988 + auto int unsigned long end_addr (void);
2989
2990 - auto int start_addr (void)
2991 + auto unsigned long int start_addr (void)
2992 {
2993 int ret;
2994 # if defined(HAVE_START_SYMBOL)
2995 @@ -1192,7 +1248,7 @@ memcheck (int addr, int len)
2996 return ret;
2997 }
2998
2999 - auto int end_addr (void)
3000 + auto unsigned long int end_addr (void)
3001 {
3002 int ret;
3003 # if defined(HAVE_END_SYMBOL)
3004 @@ -1217,6 +1273,16 @@ memcheck (int addr, int len)
3005 return ! errnum;
3006 }
3007
3008 +void
3009 +grub_memcpy(void *dest, const void *src, int len)
3010 +{
3011 + int i;
3012 + register char *d = (char*)dest, *s = (char*)src;
3013 +
3014 + for (i = 0; i < len; i++)
3015 + d[i] = s[i];
3016 +}
3017 +
3018 void *
3019 grub_memmove (void *to, const void *from, int len)
3020 {
3021 --- a/stage2/cmdline.c
3022 +++ b/stage2/cmdline.c
3023 @@ -50,10 +50,11 @@ skip_to (int after_equal, char *cmdline)
3024 void
3025 print_cmdline_message (int forever)
3026 {
3027 - printf (" [ Minimal BASH-like line editing is supported. For the first word, TAB\n"
3028 - " lists possible command completions. Anywhere else TAB lists the possible\n"
3029 - " completions of a device/filename.%s ]\n",
3030 - (forever ? "" : " ESC at any time exits."));
3031 + grub_printf(" [ Minimal BASH-like line editing is supported. For\n"
3032 + " the first word, TAB lists possible command\n"
3033 + " completions. Anywhere else TAB lists the possible\n"
3034 + " completions of a device/filename.%s ]\n",
3035 + (forever ? "" : " ESC at any time\n exits."));
3036 }
3037
3038 /* Find the builtin whose command name is COMMAND and return the
3039 --- a/stage2/freebsd.h
3040 +++ b/stage2/freebsd.h
3041 @@ -1,7 +1,7 @@
3042
3043 /*
3044 * GRUB -- GRand Unified Bootloader
3045 - * Copyright (C) 2001 Free Software Foundation, Inc.
3046 + * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
3047 *
3048 * This program is free software; you can redistribute it and/or modify
3049 * it under the terms of the GNU General Public License as published by
3050 @@ -35,6 +35,10 @@
3051 #define RB_CDROM 0x2000 /* use cdrom as root */
3052 #define RB_GDB 0x8000 /* use GDB remote debugger instead of DDB */
3053 #define RB_MUTE 0x10000 /* Come up with the console muted */
3054 +#define RB_SELFTEST 0x20000 /* don't complete the boot; do selftest */
3055 +#define RB_RESERVED1 0x40000 /* reserved for internal use of boot blocks */
3056 +#define RB_RESERVED2 0x80000 /* reserved for internal use of boot blocks */
3057 +#define RB_PAUSE 0x100000 /* pause after each output line during probe */
3058 #define RB_MULTIPLE 0x20000000 /* Use multiple consoles */
3059
3060 #define RB_BOOTINFO 0x80000000 /* have `struct bootinfo *' arg */
3061 @@ -70,6 +74,9 @@
3062
3063 #define N_BIOS_GEOM 8
3064
3065 +typedef unsigned char u8_t;
3066 +typedef unsigned int u32_t;
3067 +
3068 /*
3069 * A zero bootinfo field often means that there is no info available.
3070 * Flags are used to indicate the validity of fields where zero is a
3071 @@ -77,19 +84,33 @@
3072 */
3073 struct bootinfo
3074 {
3075 - unsigned int bi_version;
3076 - unsigned char *bi_kernelname;
3077 - struct nfs_diskless *bi_nfs_diskless;
3078 + u32_t bi_version;
3079 + u8_t *bi_kernelname;
3080 + u32_t bi_nfs_diskless;
3081 /* End of fields that are always present. */
3082 #define bi_endcommon bi_n_bios_used
3083 - unsigned int bi_n_bios_used;
3084 - unsigned long bi_bios_geom[N_BIOS_GEOM];
3085 - unsigned int bi_size;
3086 - unsigned char bi_memsizes_valid;
3087 - unsigned char bi_bios_dev;
3088 - unsigned char bi_pad[2];
3089 - unsigned long bi_basemem;
3090 - unsigned long bi_extmem;
3091 - unsigned long bi_symtab;
3092 - unsigned long bi_esymtab;
3093 + u32_t bi_n_bios_used;
3094 + u32_t bi_bios_geom[N_BIOS_GEOM];
3095 + u32_t bi_size;
3096 + u8_t bi_memsizes_valid;
3097 + u8_t bi_bios_dev;
3098 + u8_t bi_pad[2];
3099 + u32_t bi_basemem;
3100 + u32_t bi_extmem;
3101 + u32_t bi_symtab;
3102 + u32_t bi_esymtab;
3103 + /* Items below only from advanced bootloader */
3104 + u32_t bi_kernend;
3105 + u32_t bi_envp;
3106 + u32_t bi_modulep;
3107 };
3108 +
3109 +#define MODINFO_END 0x0000 /* End of list */
3110 +#define MODINFO_NAME 0x0001 /* Name of module (string) */
3111 +#define MODINFO_TYPE 0x0002 /* Type of module (string) */
3112 +#define MODINFO_ADDR 0x0003 /* Loaded address */
3113 +#define MODINFO_SIZE 0x0004 /* Size of module */
3114 +#define MODINFO_EMPTY 0x0005 /* Has been deleted */
3115 +#define MODINFO_ARGS 0x0006 /* Parameters string */
3116 +#define MODINFO_METADATA 0x8000 /* Module-specfic */
3117 +
3118 --- /dev/null
3119 +++ b/stage2/graphics.c
3120 @@ -0,0 +1,585 @@
3121 +/*
3122 + * graphics.c - graphics mode support for GRUB
3123 + * Implemented as a terminal type by Jeremy Katz <katzj@redhat.com> based
3124 + * on a patch by Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
3125 + * Options and enhancements made by Herton Ronaldo Krzesinski
3126 + * <herton@mandriva.com>
3127 + *
3128 + * GRUB -- GRand Unified Bootloader
3129 + * Copyright (C) 2001,2002 Red Hat, Inc.
3130 + * Portions copyright (C) 2000 Conectiva, Inc.
3131 + *
3132 + * This program is free software; you can redistribute it and/or modify
3133 + * it under the terms of the GNU General Public License as published by
3134 + * the Free Software Foundation; either version 2 of the License, or
3135 + * (at your option) any later version.
3136 + *
3137 + * This program is distributed in the hope that it will be useful,
3138 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3139 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3140 + * GNU General Public License for more details.
3141 + *
3142 + * You should have received a copy of the GNU General Public License
3143 + * along with this program; if not, write to the Free Software
3144 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
3145 + */
3146 +
3147 +#ifdef SUPPORT_GRAPHICS
3148 +
3149 +#include <term.h>
3150 +#include <shared.h>
3151 +#include <graphics.h>
3152 +
3153 +int saved_videomode;
3154 +unsigned char *font8x16;
3155 +
3156 +int graphics_inited = 0;
3157 +static char splashimage[256];
3158 +
3159 +int shade = 1, no_cursor = 0;
3160 +
3161 +#define VSHADOW VSHADOW1
3162 +unsigned char VSHADOW1[38400];
3163 +unsigned char VSHADOW2[38400];
3164 +unsigned char VSHADOW4[38400];
3165 +unsigned char VSHADOW8[38400];
3166 +
3167 +/* define the default viewable area */
3168 +int view_x0 = 0;
3169 +int view_y0 = 0;
3170 +int view_x1 = 80;
3171 +int view_y1 = 30;
3172 +
3173 +/* text buffer has to be kept around so that we can write things as we
3174 + * scroll and the like */
3175 +unsigned short text[80 * 30];
3176 +
3177 +/* graphics options */
3178 +int foreground = (63 << 16) | (63 << 8) | (63), background = 0, window_border = 0;
3179 +
3180 +/* current position */
3181 +static int fontx = 0;
3182 +static int fonty = 0;
3183 +
3184 +/* global state so that we don't try to recursively scroll or cursor */
3185 +static int no_scroll = 0;
3186 +
3187 +/* color state */
3188 +static int graphics_standard_color = A_NORMAL;
3189 +static int graphics_normal_color = A_NORMAL;
3190 +static int graphics_highlight_color = A_REVERSE;
3191 +static int graphics_current_color = A_NORMAL;
3192 +static color_state graphics_color_state = COLOR_STATE_STANDARD;
3193 +
3194 +static inline void outb(unsigned short port, unsigned char val)
3195 +{
3196 + __asm __volatile ("outb %0,%1"::"a" (val), "d" (port));
3197 +}
3198 +
3199 +static void MapMask(int value) {
3200 + outb(0x3c4, 2);
3201 + outb(0x3c5, value);
3202 +}
3203 +
3204 +/* bit mask register */
3205 +static void BitMask(int value) {
3206 + outb(0x3ce, 8);
3207 + outb(0x3cf, value);
3208 +}
3209 +
3210 +/* move the graphics cursor location to col, row */
3211 +static void graphics_setxy(int col, int row) {
3212 + if (col >= view_x0 && col < view_x1) {
3213 + fontx = col;
3214 + cursorX = col << 3;
3215 + }
3216 + if (row >= view_y0 && row < view_y1) {
3217 + fonty = row;
3218 + cursorY = row << 4;
3219 + }
3220 +}
3221 +
3222 +/* scroll the screen */
3223 +static void graphics_scroll() {
3224 + int i, j, k;
3225 +
3226 + /* we don't want to scroll recursively... that would be bad */
3227 + if (no_scroll)
3228 + return;
3229 + no_scroll = 1;
3230 +
3231 + /* disable pager temporarily */
3232 + k = count_lines;
3233 + count_lines = -1;
3234 +
3235 + /* move everything up a line */
3236 + for (j = view_y0 + 1; j < view_y1; j++) {
3237 + graphics_gotoxy(view_x0, j - 1);
3238 + for (i = view_x0; i < view_x1; i++) {
3239 + graphics_putchar(text[j * 80 + i]);
3240 + }
3241 + }
3242 +
3243 + /* last line should be blank */
3244 + graphics_gotoxy(view_x0, view_y1 - 1);
3245 + for (i = view_x0; i < view_x1; i++)
3246 + graphics_putchar(' ');
3247 + graphics_setxy(view_x0, view_y1 - 1);
3248 +
3249 + count_lines = k;
3250 +
3251 + no_scroll = 0;
3252 +}
3253 +
3254 +/* Set the splash image */
3255 +void graphics_set_splash(char *splashfile) {
3256 + grub_strcpy(splashimage, splashfile);
3257 +}
3258 +
3259 +/* Get the current splash image */
3260 +char *graphics_get_splash(void) {
3261 + return splashimage;
3262 +}
3263 +
3264 +/*
3265 + * Initialize a vga16 graphics display with the palette based off of
3266 + * the image in splashimage. If the image doesn't exist, leave graphics
3267 + * mode. The mode initiated is 12h. From "Ralf Brown's Interrupt List":
3268 + * text/ text pixel pixel colors disply scrn system
3269 + * grph resol box resolution pages addr
3270 + * 12h G 80x30 8x16 640x480 16/256K . A000 VGA,ATI VIP
3271 + * G 80x30 8x16 640x480 16/64 . A000 ATI EGA Wonder
3272 + * G . . 640x480 16 . . UltraVision+256K EGA
3273 + */
3274 +int graphics_init()
3275 +{
3276 + if (!graphics_inited) {
3277 + saved_videomode = set_videomode(0x12);
3278 + if (get_videomode() != 0x12) {
3279 + set_videomode(saved_videomode);
3280 + return 0;
3281 + }
3282 + graphics_inited = 1;
3283 + }
3284 + else
3285 + return 1;
3286 +
3287 + font8x16 = (unsigned char*)graphics_get_font();
3288 +
3289 + /* make sure that the highlight color is set correctly */
3290 + graphics_highlight_color = ((graphics_normal_color >> 4) |
3291 + ((graphics_normal_color & 0xf) << 4));
3292 +
3293 + graphics_cls();
3294 +
3295 + if (!read_image(splashimage)) {
3296 + grub_printf("Failed to read splash image (%s)\n", splashimage);
3297 + grub_printf("Press any key to continue...");
3298 + getkey();
3299 + set_videomode(saved_videomode);
3300 + graphics_inited = 0;
3301 + return 0;
3302 + }
3303 +
3304 + set_int1c_handler();
3305 +
3306 + return 1;
3307 +}
3308 +
3309 +/* Leave graphics mode */
3310 +void graphics_end(void)
3311 +{
3312 + if (graphics_inited) {
3313 + unset_int1c_handler();
3314 + set_videomode(saved_videomode);
3315 + graphics_inited = 0;
3316 + no_cursor = 0;
3317 + }
3318 +}
3319 +
3320 +/* Print ch on the screen. Handle any needed scrolling or the like */
3321 +void graphics_putchar(int ch) {
3322 + ch &= 0xff;
3323 +
3324 + graphics_cursor(0);
3325 +
3326 + if (ch == '\n') {
3327 + if (fonty + 1 < view_y1)
3328 + graphics_setxy(fontx, fonty + 1);
3329 + else
3330 + graphics_scroll();
3331 + graphics_cursor(1);
3332 + return;
3333 + } else if (ch == '\r') {
3334 + graphics_setxy(view_x0, fonty);
3335 + graphics_cursor(1);
3336 + return;
3337 + }
3338 +
3339 + graphics_cursor(0);
3340 +
3341 + text[fonty * 80 + fontx] = ch;
3342 + text[fonty * 80 + fontx] &= 0x00ff;
3343 + if (graphics_current_color & 0xf0)
3344 + text[fonty * 80 + fontx] |= 0x100;
3345 +
3346 + graphics_cursor(0);
3347 +
3348 + if ((fontx + 1) >= view_x1) {
3349 + graphics_setxy(view_x0, fonty);
3350 + if (fonty + 1 < view_y1)
3351 + graphics_setxy(view_x0, fonty + 1);
3352 + else
3353 + graphics_scroll();
3354 + graphics_cursor(1);
3355 + do_more ();
3356 + graphics_cursor(0);
3357 + } else {
3358 + graphics_setxy(fontx + 1, fonty);
3359 + }
3360 +
3361 + graphics_cursor(1);
3362 +}
3363 +
3364 +/* get the current location of the cursor */
3365 +int graphics_getxy(void) {
3366 + return (fontx << 8) | fonty;
3367 +}
3368 +
3369 +void graphics_gotoxy(int x, int y) {
3370 + graphics_cursor(0);
3371 +
3372 + graphics_setxy(x, y);
3373 +
3374 + graphics_cursor(1);
3375 +}
3376 +
3377 +void graphics_cls(void) {
3378 + int i;
3379 + unsigned char *mem, *s1, *s2, *s4, *s8;
3380 +
3381 + graphics_cursor(0);
3382 + graphics_gotoxy(view_x0, view_y0);
3383 +
3384 + mem = (unsigned char*)VIDEOMEM;
3385 + s1 = (unsigned char*)VSHADOW1;
3386 + s2 = (unsigned char*)VSHADOW2;
3387 + s4 = (unsigned char*)VSHADOW4;
3388 + s8 = (unsigned char*)VSHADOW8;
3389 +
3390 + for (i = 0; i < 80 * 30; i++)
3391 + text[i] = ' ';
3392 + graphics_cursor(1);
3393 +
3394 + BitMask(0xff);
3395 +
3396 + /* plane 1 */
3397 + MapMask(1);
3398 + grub_memcpy(mem, s1, 38400);
3399 +
3400 + /* plane 2 */
3401 + MapMask(2);
3402 + grub_memcpy(mem, s2, 38400);
3403 +
3404 + /* plane 3 */
3405 + MapMask(4);
3406 + grub_memcpy(mem, s4, 38400);
3407 +
3408 + /* plane 4 */
3409 + MapMask(8);
3410 + grub_memcpy(mem, s8, 38400);
3411 +
3412 + MapMask(15);
3413 +
3414 + if (no_cursor) {
3415 + no_cursor = 0;
3416 + set_int1c_handler();
3417 + }
3418 +}
3419 +
3420 +void graphics_setcolorstate (color_state state) {
3421 + switch (state) {
3422 + case COLOR_STATE_STANDARD:
3423 + graphics_current_color = graphics_standard_color;
3424 + break;
3425 + case COLOR_STATE_NORMAL:
3426 + graphics_current_color = graphics_normal_color;
3427 + break;
3428 + case COLOR_STATE_HIGHLIGHT:
3429 + graphics_current_color = graphics_highlight_color;
3430 + break;
3431 + default:
3432 + graphics_current_color = graphics_standard_color;
3433 + break;
3434 + }
3435 +
3436 + graphics_color_state = state;
3437 +}
3438 +
3439 +void graphics_setcolor (int normal_color, int highlight_color) {
3440 + graphics_normal_color = normal_color;
3441 + graphics_highlight_color = highlight_color;
3442 +
3443 + graphics_setcolorstate (graphics_color_state);
3444 +}
3445 +
3446 +int graphics_setcursor (int on) {
3447 + if (!no_cursor && !on) {
3448 + no_cursor = 1;
3449 + unset_int1c_handler();
3450 + graphics_cursor(0);
3451 + }
3452 + else if(no_cursor && on) {
3453 + no_cursor = 0;
3454 + set_int1c_handler();
3455 + graphics_cursor(1);
3456 + }
3457 + return 0;
3458 +}
3459 +
3460 +/* Read in the splashscreen image and set the palette up appropriately.
3461 + * Format of splashscreen is an xpm (can be gzipped) with 16 colors and
3462 + * 640x480. */
3463 +int read_image(char *s)
3464 +{
3465 + char buf[32], pal[16], c;
3466 + unsigned char base, mask, *s1, *s2, *s4, *s8;
3467 + unsigned i, len, idx, colors, x, y, width, height;
3468 +
3469 + if (!grub_open(s))
3470 + return 0;
3471 +
3472 + /* read header */
3473 + if (!grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) {
3474 + grub_close();
3475 + return 0;
3476 + }
3477 +
3478 + /* parse info */
3479 + while (grub_read(&c, 1)) {
3480 + if (c == '"')
3481 + break;
3482 + }
3483 +
3484 + while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
3485 + ;
3486 +
3487 + i = 0;
3488 + width = c - '0';
3489 + while (grub_read(&c, 1)) {
3490 + if (c >= '0' && c <= '9')
3491 + width = width * 10 + c - '0';
3492 + else
3493 + break;
3494 + }
3495 + while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
3496 + ;
3497 +
3498 + height = c - '0';
3499 + while (grub_read(&c, 1)) {
3500 + if (c >= '0' && c <= '9')
3501 + height = height * 10 + c - '0';
3502 + else
3503 + break;
3504 + }
3505 + while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
3506 + ;
3507 +
3508 + colors = c - '0';
3509 + while (grub_read(&c, 1)) {
3510 + if (c >= '0' && c <= '9')
3511 + colors = colors * 10 + c - '0';
3512 + else
3513 + break;
3514 + }
3515 +
3516 + base = 0;
3517 + while (grub_read(&c, 1) && c != '"')
3518 + ;
3519 +
3520 + /* palette */
3521 + for (i = 0, idx = 1; i < colors; i++) {
3522 + len = 0;
3523 +
3524 + while (grub_read(&c, 1) && c != '"')
3525 + ;
3526 + grub_read(&c, 1); /* char */
3527 + base = c;
3528 + grub_read(buf, 4); /* \t c # */
3529 +
3530 + while (grub_read(&c, 1) && c != '"') {
3531 + if (len < sizeof(buf))
3532 + buf[len++] = c;
3533 + }
3534 +
3535 + if (len == 6 && idx < 15) {
3536 + int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2;
3537 + int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2;
3538 + int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2;
3539 +
3540 + pal[idx] = base;
3541 + graphics_set_palette(idx, r, g, b);
3542 + ++idx;
3543 + }
3544 + }
3545 +
3546 + x = y = len = 0;
3547 +
3548 + s1 = (unsigned char*)VSHADOW1;
3549 + s2 = (unsigned char*)VSHADOW2;
3550 + s4 = (unsigned char*)VSHADOW4;
3551 + s8 = (unsigned char*)VSHADOW8;
3552 +
3553 + for (i = 0; i < 38400; i++)
3554 + s1[i] = s2[i] = s4[i] = s8[i] = 0;
3555 +
3556 + /* parse xpm data */
3557 + while (y < height) {
3558 + while (1) {
3559 + if (!grub_read(&c, 1)) {
3560 + grub_close();
3561 + return 0;
3562 + }
3563 + if (c == '"')
3564 + break;
3565 + }
3566 +
3567 + while (grub_read(&c, 1) && c != '"') {
3568 + for (i = 1; i < 15; i++)
3569 + if (pal[i] == c) {
3570 + c = i;
3571 + break;
3572 + }
3573 +
3574 + mask = 0x80 >> (x & 7);
3575 + if (c & 1)
3576 + s1[len + (x >> 3)] |= mask;
3577 + if (c & 2)
3578 + s2[len + (x >> 3)] |= mask;
3579 + if (c & 4)
3580 + s4[len + (x >> 3)] |= mask;
3581 + if (c & 8)
3582 + s8[len + (x >> 3)] |= mask;
3583 +
3584 + if (++x >= 640) {
3585 + x = 0;
3586 +
3587 + if (y < 480)
3588 + len += 80;
3589 + ++y;
3590 + }
3591 + }
3592 + }
3593 +
3594 + grub_close();
3595 +
3596 + graphics_set_palette(0, (background >> 16), (background >> 8) & 63,
3597 + background & 63);
3598 + graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63,
3599 + foreground & 63);
3600 + graphics_set_palette(0x11, (window_border >> 16), (window_border >> 8) & 63,
3601 + window_border & 63);
3602 +
3603 + return 1;
3604 +}
3605 +
3606 +/* Convert a character which is a hex digit to the appropriate integer */
3607 +int hex(int v)
3608 +{
3609 + if (v >= 'A' && v <= 'F')
3610 + return (v - 'A' + 10);
3611 + if (v >= 'a' && v <= 'f')
3612 + return (v - 'a' + 10);
3613 + return (v - '0');
3614 +}
3615 +
3616 +void graphics_cursor(int set) {
3617 + unsigned char *pat, *mem, *ptr, chr[16 << 2];
3618 + int i, ch, invert, offset;
3619 +
3620 + if (set && (no_cursor || no_scroll))
3621 + return;
3622 +
3623 + offset = cursorY * 80 + fontx;
3624 + ch = text[fonty * 80 + fontx] & 0xff;
3625 + invert = (text[fonty * 80 + fontx] & 0xff00) != 0;
3626 + pat = font8x16 + (ch << 4);
3627 +
3628 + mem = (unsigned char*)VIDEOMEM + offset;
3629 +
3630 + if (!set) {
3631 + for (i = 0; i < 16; i++) {
3632 + unsigned char mask = pat[i];
3633 +
3634 + if (!invert) {
3635 + chr[i ] = ((unsigned char*)VSHADOW1)[offset];
3636 + chr[16 + i] = ((unsigned char*)VSHADOW2)[offset];
3637 + chr[32 + i] = ((unsigned char*)VSHADOW4)[offset];
3638 + chr[48 + i] = ((unsigned char*)VSHADOW8)[offset];
3639 +
3640 + if (shade) {
3641 + if (ch == DISP_VERT || ch == DISP_LL ||
3642 + ch == DISP_UR || ch == DISP_LR) {
3643 + unsigned char pmask = ~(pat[i] >> 1);
3644 +
3645 + chr[i ] &= pmask;
3646 + chr[16 + i] &= pmask;
3647 + chr[32 + i] &= pmask;
3648 + chr[48 + i] &= pmask;
3649 + }
3650 + if (i > 0 && ch != DISP_VERT) {
3651 + unsigned char pmask = ~(pat[i - 1] >> 1);
3652 +
3653 + chr[i ] &= pmask;
3654 + chr[16 + i] &= pmask;
3655 + chr[32 + i] &= pmask;
3656 + chr[48 + i] &= pmask;
3657 + if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) {
3658 + pmask = ~pat[i - 1];
3659 +
3660 + chr[i ] &= pmask;
3661 + chr[16 + i] &= pmask;
3662 + chr[32 + i] &= pmask;
3663 + chr[48 + i] &= pmask;
3664 + }
3665 + }
3666 + }
3667 + chr[i ] |= mask;
3668 + chr[16 + i] |= mask;
3669 + chr[32 + i] |= mask;
3670 + chr[48 + i] |= mask;
3671 +
3672 + offset += 80;
3673 + }
3674 + else {
3675 + chr[i ] = mask;
3676 + chr[16 + i] = mask;
3677 + chr[32 + i] = mask;
3678 + chr[48 + i] = mask;
3679 + }
3680 + }
3681 + }
3682 + else {
3683 + MapMask(15);
3684 + ptr = mem;
3685 + for (i = 0; i < 16; i++, ptr += 80) {
3686 + cursorBuf[i] = pat[i];
3687 + *ptr = ~pat[i];
3688 + }
3689 + return;
3690 + }
3691 +
3692 + offset = 0;
3693 + for (i = 1; i < 16; i <<= 1, offset += 16) {
3694 + int j;
3695 +
3696 + MapMask(i);
3697 + ptr = mem;
3698 + for (j = 0; j < 16; j++, ptr += 80)
3699 + *ptr = chr[j + offset];
3700 + }
3701 +
3702 + MapMask(15);
3703 +}
3704 +
3705 +#endif /* SUPPORT_GRAPHICS */
3706 --- /dev/null
3707 +++ b/stage2/graphics.h
3708 @@ -0,0 +1,44 @@
3709 +/* graphics.h - graphics console interface */
3710 +/*
3711 + * GRUB -- GRand Unified Bootloader
3712 + * Copyright (C) 2002 Free Software Foundation, Inc.
3713 + *
3714 + * This program is free software; you can redistribute it and/or modify
3715 + * it under the terms of the GNU General Public License as published by
3716 + * the Free Software Foundation; either version 2 of the License, or
3717 + * (at your option) any later version.
3718 + *
3719 + * This program is distributed in the hope that it will be useful,
3720 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3721 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3722 + * GNU General Public License for more details.
3723 + *
3724 + * You should have received a copy of the GNU General Public License
3725 + * along with this program; if not, write to the Free Software
3726 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
3727 + */
3728 +
3729 +#ifndef GRAPHICS_H
3730 +#define GRAPHICS_H
3731 +
3732 +/* magic constant */
3733 +#define VIDEOMEM 0xA0000
3734 +
3735 +/* function prototypes */
3736 +char *graphics_get_splash(void);
3737 +
3738 +int read_image(char *s);
3739 +void graphics_cursor(int set);
3740 +
3741 +/* function prototypes for asm functions */
3742 +void * graphics_get_font();
3743 +void graphics_set_palette(int idx, int red, int green, int blue);
3744 +void set_int1c_handler();
3745 +void unset_int1c_handler();
3746 +
3747 +extern short cursorX, cursorY;
3748 +extern char cursorBuf[16];
3749 +extern int shade;
3750 +extern int view_x0, view_y0, view_x1, view_y1;
3751 +
3752 +#endif /* GRAPHICS_H */
3753 --- a/stage2/Makefile.am
3754 +++ b/stage2/Makefile.am
3755 @@ -7,7 +7,7 @@ noinst_HEADERS = apic.h defs.h dir.h dis
3756 fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \
3757 imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \
3758 nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \
3759 - terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h
3760 + terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h graphics.h
3761 EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS)
3762
3763 # For <stage1.h>.
3764 @@ -19,7 +19,7 @@ libgrub_a_SOURCES = boot.c builtins.c ch
3765 disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \
3766 fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \
3767 fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \
3768 - terminfo.c tparm.c
3769 + terminfo.c tparm.c graphics.c
3770 libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
3771 -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
3772 -DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
3773 @@ -79,8 +79,14 @@ else
3774 HERCULES_FLAGS =
3775 endif
3776
3777 +if GRAPHICS_SUPPORT
3778 +GRAPHICS_FLAGS = -DSUPPORT_GRAPHICS=1
3779 +else
3780 +GRAPHICS_FLAGS =
3781 +endif
3782 +
3783 STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3784 - $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS)
3785 + $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) $(GRAPHICS_FLAGS)
3786
3787 STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
3788 STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1
3789 @@ -90,7 +96,8 @@ pre_stage2_exec_SOURCES = asm.S bios.c b
3790 cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
3791 fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
3792 fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \
3793 - hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c
3794 + hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c \
3795 + graphics.c
3796 pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
3797 pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
3798 pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
3799 --- a/stage2/shared.h
3800 +++ b/stage2/shared.h
3801 @@ -499,7 +499,11 @@ struct vbe_mode
3802 unsigned char linear_reserved_field_position;
3803 unsigned long max_pixel_clock;
3804
3805 - unsigned char reserved3[189];
3806 + /* Reserved field to make structure to be 256 bytes long, VESA BIOS
3807 + Extension 3.0 Specification says to reserve 189 bytes here but
3808 + that doesn't make structure to be 256 bytes. So additional one is
3809 + added here. */
3810 + unsigned char reserved3[189 + 1];
3811 } __attribute__ ((packed));
3812
3813
3814 @@ -792,6 +796,11 @@ int getxy (void);
3815 /* Set the cursor position. */
3816 void gotoxy (int x, int y);
3817
3818 +/* Internal pager
3819 + Returns 1 = if pager was used
3820 + 0 = if pager wasn't used */
3821 +int do_more (void);
3822 +
3823 /* Displays an ASCII character. IBM displays will translate some
3824 characters to special graphical ones (see the DISP_* constants). */
3825 void grub_putchar (int c);
3826 @@ -871,6 +880,7 @@ int grub_sprintf (char *buffer, const ch
3827 int grub_tolower (int c);
3828 int grub_isspace (int c);
3829 int grub_strncat (char *s1, const char *s2, int n);
3830 +void grub_memcpy(void *dest, const void *src, int len);
3831 void *grub_memmove (void *to, const void *from, int len);
3832 void *grub_memset (void *start, int c, int len);
3833 int grub_strncat (char *s1, const char *s2, int n);
3834 @@ -911,7 +921,7 @@ int substring (const char *s1, const cha
3835 int nul_terminate (char *str);
3836 int get_based_digit (int c, int base);
3837 int safe_parse_maxint (char **str_ptr, int *myint_ptr);
3838 -int memcheck (int start, int len);
3839 +int memcheck (unsigned long int start, unsigned long int len);
3840 void grub_putstr (const char *str);
3841
3842 #ifndef NO_DECOMPRESSION
3843 --- a/stage2/stage2.c
3844 +++ b/stage2/stage2.c
3845 @@ -20,6 +20,12 @@
3846 #include <shared.h>
3847 #include <term.h>
3848
3849 +#ifdef SUPPORT_GRAPHICS
3850 +# include <graphics.h>
3851 +#endif
3852 +
3853 +int col_start, col_end, row_start, box_size;
3854 +
3855 grub_jmp_buf restart_env;
3856
3857 #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS)
3858 @@ -105,13 +111,13 @@ print_entry (int y, int highlight, char
3859 if (highlight && current_term->setcolorstate)
3860 current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
3861
3862 - gotoxy (2, y);
3863 + gotoxy (2 + col_start, y);
3864 grub_putchar (' ');
3865 - for (x = 3; x < 75; x++)
3866 + for (x = 3 + col_start; x < (col_end - 5); x++)
3867 {
3868 - if (*entry && x <= 72)
3869 + if (*entry && x <= (col_end - 8))
3870 {
3871 - if (x == 72)
3872 + if (x == (col_end - 8))
3873 grub_putchar (DISP_RIGHT);
3874 else
3875 grub_putchar (*entry++);
3876 @@ -119,7 +125,7 @@ print_entry (int y, int highlight, char
3877 else
3878 grub_putchar (' ');
3879 }
3880 - gotoxy (74, y);
3881 + gotoxy ((col_end - 6), y);
3882
3883 if (current_term->setcolorstate)
3884 current_term->setcolorstate (COLOR_STATE_STANDARD);
3885 @@ -131,7 +137,7 @@ print_entries (int y, int size, int firs
3886 {
3887 int i;
3888
3889 - gotoxy (77, y + 1);
3890 + gotoxy ((col_end - 3), y + 1);
3891
3892 if (first)
3893 grub_putchar (DISP_UP);
3894 @@ -151,14 +157,14 @@ print_entries (int y, int size, int firs
3895 menu_entries++;
3896 }
3897
3898 - gotoxy (77, y + size);
3899 + gotoxy ((col_end - 3), y + size);
3900
3901 if (*menu_entries)
3902 grub_putchar (DISP_DOWN);
3903 else
3904 grub_putchar (' ');
3905
3906 - gotoxy (74, y + entryno + 1);
3907 + gotoxy ((col_end - 6), y + entryno + 1);
3908 }
3909
3910 static void
3911 @@ -196,30 +202,30 @@ print_border (int y, int size)
3912 if (current_term->setcolorstate)
3913 current_term->setcolorstate (COLOR_STATE_NORMAL);
3914
3915 - gotoxy (1, y);
3916 + gotoxy (1 + col_start, y);
3917
3918 grub_putchar (DISP_UL);
3919 - for (i = 0; i < 73; i++)
3920 + for (i = col_start; i < (col_end - 7); i++)
3921 grub_putchar (DISP_HORIZ);
3922 grub_putchar (DISP_UR);
3923
3924 i = 1;
3925 while (1)
3926 {
3927 - gotoxy (1, y + i);
3928 + gotoxy (1 + col_start, y + i);
3929
3930 if (i > size)
3931 break;
3932
3933 grub_putchar (DISP_VERT);
3934 - gotoxy (75, y + i);
3935 + gotoxy ((col_end - 5), y + i);
3936 grub_putchar (DISP_VERT);
3937
3938 i++;
3939 }
3940
3941 grub_putchar (DISP_LL);
3942 - for (i = 0; i < 73; i++)
3943 + for (i = col_start; i < (col_end - 7); i++)
3944 grub_putchar (DISP_HORIZ);
3945 grub_putchar (DISP_LR);
3946
3947 @@ -233,6 +239,7 @@ run_menu (char *menu_entries, char *conf
3948 {
3949 int c, time1, time2 = -1, first_entry = 0;
3950 char *cur_entry = 0;
3951 + struct term_entry *prev_term = NULL;
3952
3953 /*
3954 * Main loop for menu UI.
3955 @@ -250,6 +257,22 @@ restart:
3956 }
3957 }
3958
3959 + col_start = 0;
3960 + col_end = 80;
3961 + row_start = 0;
3962 + box_size = 12;
3963 + /* if we're using viewport we need to make sure to setup
3964 + coordinates correctly. */
3965 +#ifdef SUPPORT_GRAPHICS
3966 + if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
3967 + {
3968 + col_start = view_x0;
3969 + col_end = view_x1;
3970 + row_start = view_y0;
3971 + box_size = (view_y1 - view_y0) - 13;
3972 + }
3973 +#endif
3974 +
3975 /* If the timeout was expired or wasn't set, force to show the menu
3976 interface. */
3977 if (grub_timeout < 0)
3978 @@ -302,36 +325,36 @@ restart:
3979 if (current_term->flags & TERM_DUMB)
3980 print_entries_raw (num_entries, first_entry, menu_entries);
3981 else
3982 - print_border (3, 12);
3983 + print_border (3 + row_start, box_size);
3984
3985 grub_printf ("\n\
3986 - Use the %c and %c keys to select which entry is highlighted.\n",
3987 + Use the %c and %c keys to select which entry is highlighted.\n",
3988 DISP_UP, DISP_DOWN);
3989
3990 if (! auth && password)
3991 {
3992 printf ("\
3993 - Press enter to boot the selected OS or \'p\' to enter a\n\
3994 - password to unlock the next set of features.");
3995 + Press enter to boot the selected OS or \'p\' to enter a\n\
3996 + password to unlock the next set of features.");
3997 }
3998 else
3999 {
4000 if (config_entries)
4001 printf ("\
4002 - Press enter to boot the selected OS, \'e\' to edit the\n\
4003 - commands before booting, or \'c\' for a command-line.");
4004 + Press enter to boot the selected OS, \'e\' to edit the\n\
4005 + commands before booting, or \'c\' for a command-line.");
4006 else
4007 printf ("\
4008 - Press \'b\' to boot, \'e\' to edit the selected command in the\n\
4009 - boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\
4010 - after (\'O\' for before) the selected line, \'d\' to remove the\n\
4011 - selected line, or escape to go back to the main menu.");
4012 + Press \'b\' to boot, \'e\' to edit the selected command in the\n\
4013 + boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\
4014 + after (\'O\' for before) the selected line, \'d\' to remove the\n\
4015 + selected line, or escape to go back to the main menu.");
4016 }
4017
4018 if (current_term->flags & TERM_DUMB)
4019 grub_printf ("\n\nThe selected entry is %d ", entryno);
4020 else
4021 - print_entries (3, 12, first_entry, entryno, menu_entries);
4022 + print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
4023 }
4024
4025 /* XX using RT clock now, need to initialize value */
4026 @@ -358,10 +381,10 @@ restart:
4027 entryno, grub_timeout);
4028 else
4029 {
4030 - gotoxy (3, 22);
4031 - grub_printf ("The highlighted entry will be booted automatically in %d seconds. ",
4032 + gotoxy (3 + col_start, 10 + box_size + row_start);
4033 + grub_printf (" The highlighted entry will be booted automatically in %d seconds. ",
4034 grub_timeout);
4035 - gotoxy (74, 4 + entryno);
4036 + gotoxy ((col_end - 6), 4 + entryno + row_start);
4037 }
4038
4039 grub_timeout--;
4040 @@ -387,12 +410,12 @@ restart:
4041 if (current_term->flags & TERM_DUMB)
4042 grub_putchar ('\r');
4043 else
4044 - gotoxy (3, 22);
4045 + gotoxy (3 + col_start, 10 + box_size + row_start);
4046 printf (" ");
4047 grub_timeout = -1;
4048 fallback_entryno = -1;
4049 if (! (current_term->flags & TERM_DUMB))
4050 - gotoxy (74, 4 + entryno);
4051 + gotoxy ((col_end - 6), 4 + entryno + row_start);
4052 }
4053
4054 /* We told them above (at least in SUPPORT_SERIAL) to use
4055 @@ -408,12 +431,12 @@ restart:
4056 {
4057 if (entryno > 0)
4058 {
4059 - print_entry (4 + entryno, 0,
4060 + print_entry (4 + entryno + row_start, 0,
4061 get_entry (menu_entries,
4062 first_entry + entryno,
4063 0));
4064 entryno--;
4065 - print_entry (4 + entryno, 1,
4066 + print_entry (4 + entryno + row_start, 1,
4067 get_entry (menu_entries,
4068 first_entry + entryno,
4069 0));
4070 @@ -421,7 +444,7 @@ restart:
4071 else if (first_entry > 0)
4072 {
4073 first_entry--;
4074 - print_entries (3, 12, first_entry, entryno,
4075 + print_entries (3 + row_start, box_size, first_entry, entryno,
4076 menu_entries);
4077 }
4078 }
4079 @@ -433,29 +456,29 @@ restart:
4080 entryno++;
4081 else
4082 {
4083 - if (entryno < 11)
4084 + if (entryno < (box_size - 1))
4085 {
4086 - print_entry (4 + entryno, 0,
4087 + print_entry (4 + entryno + row_start, 0,
4088 get_entry (menu_entries,
4089 first_entry + entryno,
4090 0));
4091 entryno++;
4092 - print_entry (4 + entryno, 1,
4093 + print_entry (4 + entryno + row_start, 1,
4094 get_entry (menu_entries,
4095 first_entry + entryno,
4096 0));
4097 }
4098 - else if (num_entries > 12 + first_entry)
4099 + else if (num_entries > box_size + first_entry)
4100 {
4101 first_entry++;
4102 - print_entries (3, 12, first_entry, entryno, menu_entries);
4103 + print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
4104 }
4105 }
4106 }
4107 else if (c == 7)
4108 {
4109 /* Page Up */
4110 - first_entry -= 12;
4111 + first_entry -= box_size;
4112 if (first_entry < 0)
4113 {
4114 entryno += first_entry;
4115 @@ -463,20 +486,20 @@ restart:
4116 if (entryno < 0)
4117 entryno = 0;
4118 }
4119 - print_entries (3, 12, first_entry, entryno, menu_entries);
4120 + print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
4121 }
4122 else if (c == 3)
4123 {
4124 /* Page Down */
4125 - first_entry += 12;
4126 + first_entry += box_size;
4127 if (first_entry + entryno + 1 >= num_entries)
4128 {
4129 - first_entry = num_entries - 12;
4130 + first_entry = num_entries - box_size;
4131 if (first_entry < 0)
4132 first_entry = 0;
4133 entryno = num_entries - first_entry - 1;
4134 }
4135 - print_entries (3, 12, first_entry, entryno, menu_entries);
4136 + print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
4137 }
4138
4139 if (config_entries)
4140 @@ -489,7 +512,7 @@ restart:
4141 if ((c == 'd') || (c == 'o') || (c == 'O'))
4142 {
4143 if (! (current_term->flags & TERM_DUMB))
4144 - print_entry (4 + entryno, 0,
4145 + print_entry (4 + entryno + row_start, 0,
4146 get_entry (menu_entries,
4147 first_entry + entryno,
4148 0));
4149 @@ -537,7 +560,7 @@ restart:
4150
4151 if (entryno >= num_entries)
4152 entryno--;
4153 - if (first_entry && num_entries < 12 + first_entry)
4154 + if (first_entry && num_entries < box_size + first_entry)
4155 first_entry--;
4156 }
4157
4158 @@ -549,7 +572,7 @@ restart:
4159 grub_printf ("\n");
4160 }
4161 else
4162 - print_entries (3, 12, first_entry, entryno, menu_entries);
4163 + print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
4164 }
4165
4166 cur_entry = menu_entries;
4167 @@ -570,7 +593,7 @@ restart:
4168 if (current_term->flags & TERM_DUMB)
4169 grub_printf ("\r ");
4170 else
4171 - gotoxy (1, 21);
4172 + gotoxy (1 + col_start, 9 + box_size + row_start);
4173
4174 /* Wipe out the previously entered password */
4175 grub_memset (entered, 0, sizeof (entered));
4176 @@ -651,7 +674,10 @@ restart:
4177 *(new_heap++) = 0;
4178
4179 if (config_entries)
4180 - run_menu (heap, NULL, new_num_entries, new_heap, 0);
4181 + {
4182 + current_entryno = first_entry + entryno;
4183 + run_menu (heap, NULL, new_num_entries, new_heap, 0);
4184 + }
4185 else
4186 {
4187 cls ();
4188 @@ -714,6 +740,15 @@ restart:
4189
4190 cls ();
4191 setcursor (1);
4192 + /* if our terminal needed initialization, we should shut it down
4193 + * before booting the kernel, but we want to save what it was so
4194 + * we can come back if needed */
4195 + prev_term = current_term;
4196 + if (current_term->shutdown)
4197 + {
4198 + current_term->shutdown();
4199 + current_term = term_table; /* assumption: console is first */
4200 + }
4201
4202 while (1)
4203 {
4204 @@ -727,7 +762,8 @@ restart:
4205 cur_entry = get_entry (config_entries, first_entry + entryno, 1);
4206
4207 /* Set CURRENT_ENTRYNO for the command "savedefault". */
4208 - current_entryno = first_entry + entryno;
4209 + if (config_entries)
4210 + current_entryno = first_entry + entryno;
4211
4212 if (run_script (cur_entry, heap))
4213 {
4214 @@ -748,6 +784,13 @@ restart:
4215 break;
4216 }
4217
4218 + /* if we get back here, we should go back to what our term was before */
4219 + current_term = prev_term;
4220 + if (current_term->startup)
4221 + /* if our terminal fails to initialize, fall back to console since
4222 + * it should always work */
4223 + if (current_term->startup() == 0)
4224 + current_term = term_table; /* we know that console is first */
4225 show_menu = 1;
4226 goto restart;
4227 }
4228 @@ -891,8 +934,18 @@ cmain (void)
4229 len = grub_read (buf, sizeof (buf));
4230 if (len > 0)
4231 {
4232 + char *tmp;
4233 + char *def;
4234 buf[sizeof (buf) - 1] = 0;
4235 - safe_parse_maxint (&p, &saved_entryno);
4236 +
4237 + if((tmp = grub_strstr(p, ":")) != NULL)
4238 + {
4239 + *tmp++;
4240 + grub_memcpy(&def, &tmp, sizeof(p));
4241 + }else
4242 + grub_memcpy(&def, &p, sizeof(p));
4243 +
4244 + safe_parse_maxint (&def, &saved_entryno);
4245 }
4246
4247 grub_close ();
4248 @@ -1050,6 +1103,16 @@ cmain (void)
4249 while (is_preset);
4250 }
4251
4252 + /* go ahead and make sure the terminal is setup */
4253 + if (current_term->startup)
4254 + {
4255 + /* If initialization fails, go back to default terminal */
4256 + if (current_term->startup() == 0)
4257 + {
4258 + current_term = term_table;
4259 + }
4260 + }
4261 +
4262 if (! num_entries)
4263 {
4264 /* If no acceptable config file, goto command-line, starting
4265 --- a/stage2/term.h
4266 +++ b/stage2/term.h
4267 @@ -60,6 +60,8 @@ struct term_entry
4268 const char *name;
4269 /* The feature flags defined above. */
4270 unsigned long flags;
4271 + /* Default for maximum number of lines if not specified */
4272 + unsigned short max_lines;
4273 /* Put a character. */
4274 void (*putchar) (int c);
4275 /* Check if any input character is available. */
4276 @@ -79,6 +81,10 @@ struct term_entry
4277 void (*setcolor) (int normal_color, int highlight_color);
4278 /* Turn on/off the cursor. */
4279 int (*setcursor) (int on);
4280 + /* function to start a terminal */
4281 + int (*startup) (void);
4282 + /* function to use to shutdown a terminal */
4283 + void (*shutdown) (void);
4284 };
4285
4286 /* This lists up available terminals. */
4287 @@ -124,4 +130,24 @@ void hercules_setcolor (int normal_color
4288 int hercules_setcursor (int on);
4289 #endif
4290
4291 +#ifdef SUPPORT_GRAPHICS
4292 +extern int foreground, background, window_border, graphics_inited, saved_videomode;
4293 +
4294 +void graphics_set_splash(char *splashfile);
4295 +int set_videomode(int mode);
4296 +int get_videomode(void);
4297 +void graphics_putchar (int c);
4298 +int graphics_getxy(void);
4299 +void graphics_gotoxy(int x, int y);
4300 +void graphics_cls(void);
4301 +void graphics_setcolorstate (color_state state);
4302 +void graphics_setcolor (int normal_color, int highlight_color);
4303 +int graphics_setcursor (int on);
4304 +int graphics_init(void);
4305 +void graphics_end(void);
4306 +
4307 +int hex(int v);
4308 +void graphics_set_palette(int idx, int red, int green, int blue);
4309 +#endif /* SUPPORT_GRAPHICS */
4310 +
4311 #endif /* ! GRUB_TERM_HEADER */
4312 --- a/THANKS
4313 +++ b/THANKS
4314 @@ -121,3 +121,4 @@ Vesa Jaaskelainen <jaaskela@tietomyrsky.
4315 Yedidyah Bar-David <didi@post.tau.ac.il>
4316 Yury V. Umanets <umka@namesys.com>
4317 Yuri Zaporogets <yuriz@ukr.net>
4318 +Vitaly Fertman <vitaly@namesys.com>
4319 --- a/util/grub-install.in
4320 +++ b/util/grub-install.in
4321 @@ -81,6 +81,50 @@ Report bugs to <bug-grub@gnu.org>.
4322 EOF
4323 }
4324
4325 +# Usage: getraid_mdadm mddevice
4326 +# Routine to find a physical device from an md device
4327 +# If found, the first grub BIOS device (from device.map) is returned
4328 +# If no BIOS drives match the RAID devices, the first device returned
4329 +# from mdadm -D is returned
4330 +getraid_mdadm() {
4331 + device=$1
4332 + mdadm=$(mdadm -D "$device") || {
4333 + echo "$PROG: mdadm -D $device failed" >&2
4334 + exit 1
4335 + }
4336 + eval "$(
4337 + echo "$mdadm" | awk '
4338 + $1 == "Number" && $2 == "Major" { start = 1; next }
4339 + $1 == "UUID" { print "uuid=" $3; start = 0; next }
4340 + !start { next }
4341 + $2 == 0 && $3 == 0 { next }
4342 + { devices = devices "\n" $NF }
4343 + END { print "devices='\''" devices "'\''" }
4344 + '
4345 + )"
4346 +
4347 + # Convert RAID devices list into a list of disks
4348 + tmp_disks=`echo "$devices" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' \
4349 + -e 's%\(d[0-9]*\)p[0-9]*$%\1%' \
4350 + -e 's%\(fd[0-9]*\)$%\1%' \
4351 + -e 's%/part[0-9]*$%/disc%' \
4352 + -e 's%\(c[0-7]d[0-9]*\).*$%\1%' \
4353 + -e '/^$/d' |
4354 + sed -n '1h;2,$H;${g;s/\n/|/g;p}'`
4355 +
4356 + # Find first BIOS disk that's a member of the RAID array
4357 + # Default to first RAID member if no tmp_disks are BIOS devices
4358 + set -- `egrep $tmp_disks $device_map | \
4359 + sort | \
4360 + sed -n 1p `
4361 + device=${2:-${tmp_disks%%|*}}
4362 +
4363 + # Return first partition on BIOS disk that's part of the RAID
4364 + echo "$devices" | \
4365 + sed -n "\:${device}:p" | \
4366 + sed -n 1p
4367 +}
4368 +
4369 # Usage: convert os_device
4370 # Convert an OS device to the corresponding GRUB drive.
4371 # This part is OS-specific.
4372 @@ -96,6 +140,10 @@ convert () {
4373 # Break the device name into the disk part and the partition part.
4374 case "$host_os" in
4375 linux*)
4376 + # Find an actual physical device if we're passed a RAID device
4377 + case $1 in
4378 + /dev/md*) set -- `getraid_mdadm $1`
4379 + esac
4380 tmp_disk=`echo "$1" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' \
4381 -e 's%\(d[0-9]*\)p[0-9]*$%\1%' \
4382 -e 's%\(fd[0-9]*\)$%\1%' \
4383 @@ -112,8 +160,8 @@ convert () {
4384 tmp_disk=`echo "$1" | sed 's%\([sh]d[0-9]*\).*%\1%'`
4385 tmp_part=`echo "$1" | sed "s%$tmp_disk%%"` ;;
4386 freebsd* | kfreebsd*-gnu)
4387 - tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%r\1%' \
4388 - | sed 's%r\{0,1\}\(da[0-9]*\).*$%r\1%'`
4389 + tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%\1%' \
4390 + | sed 's%r\{0,1\}\(da[0-9]*\).*$%\1%'`
4391 tmp_part=`echo "$1" \
4392 | sed "s%.*/r\{0,1\}[saw]d[0-9]\(s[0-9]*[a-h]\)%\1%" \
4393 | sed "s%.*/r\{0,1\}da[0-9]\(s[0-9]*[a-h]\)%\1%"`
4394 @@ -131,7 +179,7 @@ convert () {
4395
4396 # Get the drive name.
4397 tmp_drive=`grep -v '^#' $device_map | grep "$tmp_disk *$" \
4398 - | sed 's%.*\(([hf]d[0-9][a-g0-9,]*)\).*%\1%'`
4399 + | sed 's%.*\(([hf]d[0-9][a-z0-9,]*)\).*%\1%'`
4400
4401 # If not found, print an error message and exit.
4402 if test "x$tmp_drive" = x; then
4403 @@ -148,13 +196,13 @@ convert () {
4404 gnu*)
4405 if echo $tmp_part | grep "^s" >/dev/null; then
4406 tmp_pc_slice=`echo $tmp_part \
4407 - | sed "s%s\([0-9]*\)[a-g]*$%\1%"`
4408 + | sed "s%s\([0-9]*\)[a-z]*$%\1%"`
4409 tmp_drive=`echo "$tmp_drive" \
4410 | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
4411 fi
4412 - if echo $tmp_part | grep "[a-g]$" >/dev/null; then
4413 + if echo $tmp_part | grep "[a-z]$" >/dev/null; then
4414 tmp_bsd_partition=`echo "$tmp_part" \
4415 - | sed "s%[^a-g]*\([a-g]\)$%\1%"`
4416 + | sed "s%[^a-z]*\([a-z]\)$%\1%"`
4417 tmp_drive=`echo "$tmp_drive" \
4418 | sed "s%)%,$tmp_bsd_partition)%"`
4419 fi
4420 @@ -336,6 +384,10 @@ else
4421 # Create a safe temporary file.
4422 test -n "$mklog" && log_file=`$mklog`
4423
4424 + # Before all invocations of the grub shell, call sync to make sure
4425 + # the raw device is in sync with any bufferring in filesystems.
4426 + sync
4427 +
4428 $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
4429 quit
4430 EOF
4431 @@ -450,6 +502,24 @@ rm -f $log_file
4432 # Create a safe temporary file.
4433 test -n "$mklog" && log_file=`$mklog`
4434
4435 +# Sync to prevent GRUB from not finding stage files (notably, on XFS)
4436 +sync
4437 +
4438 +# XFS needs special magic
4439 +xfs_frozen=false
4440 +if which xfs_freeze > /dev/null ; then
4441 + cat << EOF
4442 +Due to a bug in xfs_freeze, the following command might produce a segmentation
4443 +fault when ${grubdir} is not in an XFS filesystem. This error is harmless and
4444 +can be ignored.
4445 +EOF
4446 + if xfs_freeze -f ${grubdir} ; then xfs_frozen=true ; fi
4447 +fi
4448 +
4449 +# Before all invocations of the grub shell, call sync to make sure
4450 +# the raw device is in sync with any bufferring in filesystems.
4451 +sync
4452 +
4453 # Now perform the installation.
4454 $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
4455 root $root_drive
4456 @@ -457,6 +527,10 @@ setup $force_lba --stage2=$grubdir/stage
4457 quit
4458 EOF
4459
4460 +if ${xfs_frozen} ; then
4461 + xfs_freeze -u ${grubdir}
4462 +fi
4463 +
4464 if grep "Error [0-9]*: " $log_file >/dev/null || test $debug = yes; then
4465 cat $log_file 1>&2
4466 exit 1