x86: add grub2 iso support
[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