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 | + |
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 | + |
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 | + |
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 | + |
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 | + |
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 | + |
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 | + |
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 | |
2288 | /* displayapm */ |
2289 | static int |
2290 | @@ -1454,14 +1724,20 @@ static struct builtin builtin_halt = |
2291 | |
2292 | |
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 | |
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 | |
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 | |
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 |
4467 | |