~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

Viewing changes to term/efi/console.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Evan Broder, Mario Limonciello
  • Date: 2010-11-24 13:59:55 UTC
  • mfrom: (1.17.6 upstream) (17.6.15 experimental)
  • Revision ID: james.westby@ubuntu.com-20101124135955-r6ii5sepayr7jt53
Tags: 1.99~20101124-1ubuntu1
[ Colin Watson ]
* Resynchronise with Debian experimental.  Remaining changes:
  - Adjust for default Ubuntu boot options ("quiet splash").
  - Default to hiding the menu; holding down Shift at boot will show it.
  - Set a monochromatic theme for Ubuntu.
  - Apply Ubuntu GRUB Legacy changes to legacy update-grub script: title,
    recovery mode, quiet option, tweak how memtest86+ is displayed, and
    use UUIDs where appropriate.
  - Fix backslash-escaping in merge_debconf_into_conf.
  - Remove "GNU/Linux" from default distributor string.
  - Add crashkernel= options if kdump and makedumpfile are available.
  - If other operating systems are installed, then automatically unhide
    the menu.  Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus
    if available to check whether Shift is pressed.  If it is, show the
    menu, otherwise boot immediately.  If keystatus is not available, then
    fall back to a short delay interruptible with Escape.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Don't display introductory message about line editing unless we're
    actually offering a shell prompt.  Don't clear the screen just before
    booting if we never drew the menu in the first place.
  - Remove some verbose messages printed before reading the configuration
    file.
  - Suppress progress messages as the kernel and initrd load for
    non-recovery kernel menu entries.
  - Change prepare_grub_to_access_device to handle filesystems
    loop-mounted on file images.
  - Ignore devices loop-mounted from files in 10_linux.
  - Show the boot menu if the previous boot failed, that is if it failed
    to get to the end of one of the normal runlevels.
  - Don't generate /boot/grub/device.map during grub-install or
    grub-mkconfig by default.
  - Adjust upgrade version checks for Ubuntu.
  - Don't display "GRUB loading" unless Shift is held down.
  - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate
    our backport of the grub-doc split.
  - Fix LVM/RAID probing in the absence of /boot/grub/device.map.
  - Look for .mo files in /usr/share/locale-langpack as well, in
    preference.
  - Make sure GRUB_TIMEOUT isn't quoted unnecessarily.
  - Probe all devices in 'grub-probe --target=drive' if
    /boot/grub/device.map is missing.
  - Build-depend on qemu-kvm rather than qemu-system for grub-pc tests.
  - Use qemu rather than qemu-system-i386.
  - Program vesafb on BIOS systems rather than efifb.
  - Add a grub-rescue-efi-amd64 package containing a rescue CD-ROM image
    for EFI-AMD64.
  - On Wubi, don't ask for an install device, but just update wubildr
    using the diverted grub-install.
  - When embedding the core image in a post-MBR gap, check for and avoid
    sectors matching any of a list of known signatures.
  - Disable video_bochs and video_cirrus on PC BIOS systems, as probing
    PCI space seems to break on some systems.
* Downgrade "ACPI shutdown failed" error to a debug message, since it can
  cause spurious test failures.

[ Evan Broder ]
* Enable lua from grub-extras.
* Incorporate the bitop library into lua.
* Add enum_pci function to grub module in lua.
* Switch back to gfxpayload=keep by default, unless the video hardware
  is known to not support it.

[ Mario Limonciello ]
* Built part_msdos and vfat into bootx64.efi (LP: #677758)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  GRUB  --  GRand Unified Bootloader
3
 
 *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
4
 
 *
5
 
 *  GRUB is free software: you can redistribute it and/or modify
6
 
 *  it under the terms of the GNU General Public License as published by
7
 
 *  the Free Software Foundation, either version 3 of the License, or
8
 
 *  (at your option) any later version.
9
 
 *
10
 
 *  GRUB is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
17
 
 */
18
 
 
19
 
#include <grub/term.h>
20
 
#include <grub/misc.h>
21
 
#include <grub/types.h>
22
 
#include <grub/err.h>
23
 
#include <grub/efi/efi.h>
24
 
#include <grub/efi/api.h>
25
 
#include <grub/efi/console.h>
26
 
 
27
 
static const grub_uint8_t
28
 
grub_console_standard_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_YELLOW,
29
 
                                                  GRUB_EFI_BACKGROUND_BLACK);
30
 
 
31
 
static int read_key = -1;
32
 
 
33
 
static grub_uint32_t
34
 
map_char (grub_uint32_t c)
35
 
{
36
 
  /* Map some unicode characters to the EFI character.  */
37
 
  switch (c)
38
 
    {
39
 
    case GRUB_UNICODE_LEFTARROW:
40
 
      c = GRUB_UNICODE_BLACK_LEFT_TRIANGLE;
41
 
      break;
42
 
    case GRUB_UNICODE_UPARROW:
43
 
      c = GRUB_UNICODE_BLACK_UP_TRIANGLE;
44
 
      break;
45
 
    case GRUB_UNICODE_RIGHTARROW:
46
 
      c = GRUB_UNICODE_BLACK_RIGHT_TRIANGLE;
47
 
      break;
48
 
    case GRUB_UNICODE_DOWNARROW:
49
 
      c = GRUB_UNICODE_BLACK_DOWN_TRIANGLE;
50
 
      break;
51
 
    case GRUB_UNICODE_HLINE:
52
 
      c = GRUB_UNICODE_LIGHT_HLINE;
53
 
      break;
54
 
    case GRUB_UNICODE_VLINE:
55
 
      c = GRUB_UNICODE_LIGHT_VLINE;
56
 
      break;
57
 
    case GRUB_UNICODE_CORNER_UL:
58
 
      c = GRUB_UNICODE_LIGHT_CORNER_UL;
59
 
      break;
60
 
    case GRUB_UNICODE_CORNER_UR:
61
 
      c = GRUB_UNICODE_LIGHT_CORNER_UR;
62
 
      break;
63
 
    case GRUB_UNICODE_CORNER_LL:
64
 
      c = GRUB_UNICODE_LIGHT_CORNER_LL;
65
 
      break;
66
 
    case GRUB_UNICODE_CORNER_LR:
67
 
      c = GRUB_UNICODE_LIGHT_CORNER_LR;
68
 
      break;
69
 
    }
70
 
 
71
 
  return c;
72
 
}
73
 
 
74
 
static void
75
 
grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)),
76
 
                      const struct grub_unicode_glyph *c)
77
 
{
78
 
  grub_efi_char16_t str[2 + c->ncomb];
79
 
  grub_efi_simple_text_output_interface_t *o;
80
 
  unsigned i, j;
81
 
 
82
 
  o = grub_efi_system_table->con_out;
83
 
 
84
 
  /* For now, do not try to use a surrogate pair.  */
85
 
  if (c->base > 0xffff)
86
 
    str[0] = '?';
87
 
  else
88
 
    str[0] = (grub_efi_char16_t)  map_char (c->base & 0xffff);
89
 
  j = 1;
90
 
  for (i = 0; i < c->ncomb; i++)
91
 
    if (c->base < 0xffff)
92
 
      str[j++] = c->combining[i].code;
93
 
  str[j] = 0;
94
 
 
95
 
  /* Should this test be cached?  */
96
 
  if ((c->base > 0x7f || c->ncomb)
97
 
      && efi_call_2 (o->test_string, o, str) != GRUB_EFI_SUCCESS)
98
 
    return;
99
 
 
100
 
  efi_call_2 (o->output_string, o, str);
101
 
}
102
 
 
103
 
static int
104
 
grub_console_checkkey (struct grub_term_input *term __attribute__ ((unused)))
105
 
{
106
 
  grub_efi_simple_input_interface_t *i;
107
 
  grub_efi_input_key_t key;
108
 
  grub_efi_status_t status;
109
 
 
110
 
  if (read_key >= 0)
111
 
    return 1;
112
 
 
113
 
  i = grub_efi_system_table->con_in;
114
 
  status = efi_call_2 (i->read_key_stroke, i, &key);
115
 
#if 0
116
 
  switch (status)
117
 
    {
118
 
    case GRUB_EFI_SUCCESS:
119
 
      {
120
 
        grub_uint16_t xy;
121
 
 
122
 
        xy = grub_getxy ();
123
 
        grub_gotoxy (0, 0);
124
 
        grub_printf ("scan_code=%x,unicode_char=%x  ",
125
 
                     (unsigned) key.scan_code,
126
 
                     (unsigned) key.unicode_char);
127
 
        grub_gotoxy (xy >> 8, xy & 0xff);
128
 
      }
129
 
      break;
130
 
 
131
 
    case GRUB_EFI_NOT_READY:
132
 
      //grub_printf ("not ready   ");
133
 
      break;
134
 
 
135
 
    default:
136
 
      //grub_printf ("device error   ");
137
 
      break;
138
 
    }
139
 
#endif
140
 
 
141
 
  if (status == GRUB_EFI_SUCCESS)
142
 
    {
143
 
      switch (key.scan_code)
144
 
        {
145
 
        case 0x00:
146
 
          read_key = key.unicode_char;
147
 
          break;
148
 
        case 0x01:
149
 
          read_key = GRUB_TERM_UP;
150
 
          break;
151
 
        case 0x02:
152
 
          read_key = GRUB_TERM_DOWN;
153
 
          break;
154
 
        case 0x03:
155
 
          read_key = GRUB_TERM_RIGHT;
156
 
          break;
157
 
        case 0x04:
158
 
          read_key = GRUB_TERM_LEFT;
159
 
          break;
160
 
        case 0x05:
161
 
          read_key = GRUB_TERM_HOME;
162
 
          break;
163
 
        case 0x06:
164
 
          read_key = GRUB_TERM_END;
165
 
          break;
166
 
        case 0x07:
167
 
          break;
168
 
        case 0x08:
169
 
          read_key = GRUB_TERM_DC;
170
 
          break;
171
 
        case 0x09:
172
 
          break;
173
 
        case 0x0a:
174
 
          break;
175
 
        case 0x0b:
176
 
          read_key = 24;
177
 
          break;
178
 
        case 0x0c:
179
 
          read_key = 1;
180
 
          break;
181
 
        case 0x0d:
182
 
          read_key = 5;
183
 
          break;
184
 
        case 0x0e:
185
 
          read_key = 3;
186
 
          break;
187
 
        case 0x17:
188
 
          read_key = '\e';
189
 
          break;
190
 
        default:
191
 
          break;
192
 
        }
193
 
    }
194
 
 
195
 
  return read_key;
196
 
}
197
 
 
198
 
static int
199
 
grub_console_getkey (struct grub_term_input *term)
200
 
{
201
 
  grub_efi_simple_input_interface_t *i;
202
 
  grub_efi_boot_services_t *b;
203
 
  grub_efi_uintn_t index;
204
 
  grub_efi_status_t status;
205
 
  int key;
206
 
 
207
 
  if (read_key >= 0)
208
 
    {
209
 
      key = read_key;
210
 
      read_key = -1;
211
 
      return key;
212
 
    }
213
 
 
214
 
  i = grub_efi_system_table->con_in;
215
 
  b = grub_efi_system_table->boot_services;
216
 
 
217
 
  do
218
 
    {
219
 
      status = efi_call_3 (b->wait_for_event, 1, &(i->wait_for_key), &index);
220
 
      if (status != GRUB_EFI_SUCCESS)
221
 
        return -1;
222
 
 
223
 
      grub_console_checkkey (term);
224
 
    }
225
 
  while (read_key < 0);
226
 
 
227
 
  key = read_key;
228
 
  read_key = -1;
229
 
  return key;
230
 
}
231
 
 
232
 
static grub_uint16_t
233
 
grub_console_getwh (struct grub_term_output *term __attribute__ ((unused)))
234
 
{
235
 
  grub_efi_simple_text_output_interface_t *o;
236
 
  grub_efi_uintn_t columns, rows;
237
 
 
238
 
  o = grub_efi_system_table->con_out;
239
 
  if (efi_call_4 (o->query_mode, o, o->mode->mode, &columns, &rows) != GRUB_EFI_SUCCESS)
240
 
    {
241
 
      /* Why does this fail?  */
242
 
      columns = 80;
243
 
      rows = 25;
244
 
    }
245
 
 
246
 
  return ((columns << 8) | rows);
247
 
}
248
 
 
249
 
static grub_uint16_t
250
 
grub_console_getxy (struct grub_term_output *term __attribute__ ((unused)))
251
 
{
252
 
  grub_efi_simple_text_output_interface_t *o;
253
 
 
254
 
  o = grub_efi_system_table->con_out;
255
 
  return ((o->mode->cursor_column << 8) | o->mode->cursor_row);
256
 
}
257
 
 
258
 
static void
259
 
grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
260
 
                     grub_uint8_t x, grub_uint8_t y)
261
 
{
262
 
  grub_efi_simple_text_output_interface_t *o;
263
 
 
264
 
  o = grub_efi_system_table->con_out;
265
 
  efi_call_3 (o->set_cursor_position, o, x, y);
266
 
}
267
 
 
268
 
static void
269
 
grub_console_cls (struct grub_term_output *term __attribute__ ((unused)))
270
 
{
271
 
  grub_efi_simple_text_output_interface_t *o;
272
 
  grub_efi_int32_t orig_attr;
273
 
 
274
 
  o = grub_efi_system_table->con_out;
275
 
  orig_attr = o->mode->attribute;
276
 
  efi_call_2 (o->set_attributes, o, GRUB_EFI_BACKGROUND_BLACK);
277
 
  efi_call_1 (o->clear_screen, o);
278
 
  efi_call_2 (o->set_attributes, o, orig_attr);
279
 
}
280
 
 
281
 
static void
282
 
grub_console_setcolorstate (struct grub_term_output *term,
283
 
                            grub_term_color_state state)
284
 
{
285
 
  grub_efi_simple_text_output_interface_t *o;
286
 
 
287
 
  o = grub_efi_system_table->con_out;
288
 
 
289
 
  switch (state) {
290
 
    case GRUB_TERM_COLOR_STANDARD:
291
 
      efi_call_2 (o->set_attributes, o, grub_console_standard_color);
292
 
      break;
293
 
    case GRUB_TERM_COLOR_NORMAL:
294
 
      efi_call_2 (o->set_attributes, o, term->normal_color);
295
 
      break;
296
 
    case GRUB_TERM_COLOR_HIGHLIGHT:
297
 
      efi_call_2 (o->set_attributes, o, term->highlight_color);
298
 
      break;
299
 
    default:
300
 
      break;
301
 
  }
302
 
}
303
 
 
304
 
static void
305
 
grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)),
306
 
                        int on)
307
 
{
308
 
  grub_efi_simple_text_output_interface_t *o;
309
 
 
310
 
  o = grub_efi_system_table->con_out;
311
 
  efi_call_2 (o->enable_cursor, o, on);
312
 
}
313
 
 
314
 
static grub_err_t
315
 
grub_efi_console_init (struct grub_term_output *term)
316
 
{
317
 
  grub_console_setcursor (term, 1);
318
 
  return 0;
319
 
}
320
 
 
321
 
static grub_err_t
322
 
grub_efi_console_fini (struct grub_term_output *term)
323
 
{
324
 
  grub_console_setcursor (term, 0);
325
 
  return 0;
326
 
}
327
 
 
328
 
static struct grub_term_input grub_console_term_input =
329
 
  {
330
 
    .name = "console",
331
 
    .checkkey = grub_console_checkkey,
332
 
    .getkey = grub_console_getkey,
333
 
  };
334
 
 
335
 
static struct grub_term_output grub_console_term_output =
336
 
  {
337
 
    .name = "console",
338
 
    .init = grub_efi_console_init,
339
 
    .fini = grub_efi_console_fini,
340
 
    .putchar = grub_console_putchar,
341
 
    .getwh = grub_console_getwh,
342
 
    .getxy = grub_console_getxy,
343
 
    .gotoxy = grub_console_gotoxy,
344
 
    .cls = grub_console_cls,
345
 
    .setcolorstate = grub_console_setcolorstate,
346
 
    .setcursor = grub_console_setcursor,
347
 
    .normal_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_LIGHTGRAY,
348
 
                                        GRUB_EFI_BACKGROUND_BLACK),
349
 
    .highlight_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_BLACK,
350
 
                                           GRUB_EFI_BACKGROUND_LIGHTGRAY),
351
 
    .flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
352
 
  };
353
 
 
354
 
void
355
 
grub_console_init (void)
356
 
{
357
 
  /* FIXME: it is necessary to consider the case where no console control
358
 
     is present but the default is already in text mode.  */
359
 
  if (! grub_efi_set_text_mode (1))
360
 
    {
361
 
      grub_error (GRUB_ERR_BAD_DEVICE, "cannot set text mode");
362
 
      return;
363
 
    }
364
 
 
365
 
  grub_term_register_input ("console", &grub_console_term_input);
366
 
  grub_term_register_output ("console", &grub_console_term_output);
367
 
}
368
 
 
369
 
void
370
 
grub_console_fini (void)
371
 
{
372
 
  grub_term_unregister_input (&grub_console_term_input);
373
 
  grub_term_unregister_output (&grub_console_term_output);
374
 
}