]> git.proxmox.com Git - grub2.git/commitdiff
merge with mainline
authorBVK Chaitanya <bvk@dbook>
Mon, 23 Aug 2010 16:20:38 +0000 (21:50 +0530)
committerBVK Chaitanya <bvk@dbook>
Mon, 23 Aug 2010 16:20:38 +0000 (21:50 +0530)
1  2 
grub-core/kern/mips/startup.S
grub-core/kern/powerpc/ieee1275/startup.S
grub-core/term/at_keyboard.c

index c67bb9742d6d3023717c915855d0ace2a8fb5d64,0000000000000000000000000000000000000000..134853a9de05f7177d02152c6e12d925ff1851c8
mode 100644,000000..100644
--- /dev/null
@@@ -1,226 -1,0 +1,226 @@@
-       /* to be filled by grub-mkelfimage */
 +/* startup.S - Startup code for the MIPS.  */
 +/*
 + *  GRUB  --  GRand Unified Bootloader
 + *  Copyright (C) 2009  Free Software Foundation, Inc.
 + *
 + *  GRUB is free software: you can redistribute it and/or modify
 + *  it under the terms of the GNU General Public License as published by
 + *  the Free Software Foundation, either version 3 of the License, or
 + *  (at your option) any later version.
 + *
 + *  GRUB is distributed in the hope that it will be useful,
 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + *  GNU General Public License for more details.
 + *
 + *  You should have received a copy of the GNU General Public License
 + *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 + */
 +
 +#include <grub/symbol.h>
 +#include <grub/offsets.h>
 +#include <grub/machine/memory.h>
 +#include <grub/offsets.h>
 +
 +#define BASE_ADDR 8
 +      
 +.extern __bss_start
 +.extern _end
 +      
 +      .globl __start, _start, start
 +__start:
 +_start:
 +start:        
 +      bal codestart
 +base: 
 +      . = _start + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE
 +compressed_size:
 +      .long 0
 +      . = _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
 +total_module_size:
 +      .long 0
 +      . = _start + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE
 +kernel_image_size:    
 +      .long   0
 +codestart:
 +      /* Save our base.  */
 +      move $s0, $ra
 +
 +      /* Parse arguments. Has to be done before relocation.
 +      So need to do it in asm.  */
 +#ifdef GRUB_MACHINE_MIPS_YEELOONG
 +      move $s2, $zero
 +      move $s3, $zero
 +      move $s4, $zero
 +      move $s5, $zero
 +
 +      /* $a2 has the environment.  */
 +      addiu $t0, $a2, 1
 +      beq $t0, $zero, argdone
 +      move $t0, $a2   
 +argcont:      
 +      lw $t1, 0($t0)
 +      beq $t1, $zero, argdone
 +#define DO_PARSE(str, reg) \
 +      addiu $t2, $s0, (str-base);\
 +      bal parsestr;\
 +      beq $v0, $zero, 1f;\
 +      move reg, $v0;\
 +      b 2f;\
 +1:    
 +      DO_PARSE (busclockstr, $s2)
 +      DO_PARSE (cpuclockstr, $s3)
 +      DO_PARSE (memsizestr, $s4)
 +      DO_PARSE (highmemsizestr, $s5)
 +2:    
 +      addiu $t0, $t0, 4
 +      b argcont
 +parsestr:
 +      move $v0, $zero
 +      move $t3, $t1
 +3:    
 +      lb $t4, 0($t2)
 +      lb $t5, 0($t3)
 +      addiu $t2, $t2, 1
 +      addiu $t3, $t3, 1
 +      beq $t5, $zero, 1f
 +      beq $t5, $t4, 3b
 +      bne $t4, $zero, 1f
 +
 +      addiu $t3, $t3, 0xffff
 +digcont:      
 +      lb $t5, 0($t3)
 +      /* Substract '0' from digit.  */
 +      addiu $t5, $t5, 0xffd0
 +      bltz $t5, 1f
 +      addiu $t4, $t5, 0xfff7
 +      bgtz $t4, 1f
 +      /* Multiply $v0 by 10 with bitshifts. */
 +      sll $v0, $v0, 1
 +      sll $t4, $v0, 2
 +      addu $v0, $v0, $t4
 +      addu $v0, $v0, $t5
 +      addiu $t3, $t3, 1
 +      b digcont
 +1:
 +      jr $ra
 +busclockstr:  .asciiz "busclock="
 +cpuclockstr:  .asciiz "cpuclock="
 +memsizestr:   .asciiz "memsize="
 +highmemsizestr:       .asciiz "highmemsize="
 +      .p2align 2
 +argdone:
 +#endif
 +
 +      /* Decompress the payload. */
 +      addiu $a0, $s0, GRUB_KERNEL_MACHINE_RAW_SIZE - BASE_ADDR
 +      lui $a1, %hi(compressed)
 +      addiu $a1, %lo(compressed)
 +      lw $a2, (GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0)
 +      move $s1, $a1
 +
 +      /* $a0 contains source compressed address, $a1 is destination,
 +         $a2 is compressed size. FIXME: put LZMA here. Don't clober $s0,
 +         $s1, $s2, $s3, $s4 and $s5.
 +         On return $v0 contains uncompressed size.
 +      */
 +      move $v0, $a2
 +reloccont:
 +      lb $t4, 0($a0)
 +      sb $t4, 0($a1)
 +      addiu $a1,$a1,1
 +      addiu $a0,$a0,1
 +      addiu $a2, 0xffff
 +      bne $a2, $0, reloccont
 +
 +      move $a0, $s1
 +      move $a1, $v0
 +
 +#include "cache_flush.S"
 +
 +      lui $t1, %hi(cont)
 +      addiu $t1, %lo(cont)
 +
 +      jr $t1
 +      . = _start + GRUB_KERNEL_MACHINE_RAW_SIZE
 +compressed:   
 +      . = _start + GRUB_KERNEL_MACHINE_PREFIX
 +
 +VARIABLE(grub_prefix)
 +
++      /* to be filled by grub-mkimage */
 +
 +      /*
 +       *  Leave some breathing room for the prefix.
 +       */
 +
 +      . = _start + GRUB_KERNEL_MACHINE_DATA_END
 +#ifdef GRUB_MACHINE_MIPS_YEELOONG
 +VARIABLE (grub_arch_busclock)
 +      .long 0
 +VARIABLE (grub_arch_cpuclock)
 +      .long 0
 +VARIABLE (grub_arch_memsize)
 +      .long 0
 +VARIABLE (grub_arch_highmemsize)
 +      .long 0
 +#endif
 +cont:
 +
 +#ifdef GRUB_MACHINE_MIPS_YEELOONG
 +      lui $t1, %hi(grub_arch_busclock)
 +      addiu $t1, %lo(grub_arch_busclock)
 +      sw $s2, 0($t1)
 +      sw $s3, 4($t1)
 +      sw $s4, 8($t1)
 +      sw $s5, 12($t1)
 +#endif
 +
 +      /* Move the modules out of BSS.  */
 +      lui $t1, %hi(_start)
 +      addiu $t1, %lo(_start)
 +      lw $t2, (GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0)
 +      addu $t2, $t1, $t2
 +      
 +      lui $t1, %hi(_end)
 +      addiu $t1, %lo(_end)
 +      addiu $t1, (GRUB_KERNEL_MACHINE_MOD_ALIGN-1)
 +      li $t3, (GRUB_KERNEL_MACHINE_MOD_ALIGN-1)
 +      nor $t3, $t3, $0
 +      and $t1, $t1, $t3
 +      
 +      lw $t3, (GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE - BASE_ADDR)($s0)
 +
 +      /* Backward copy.  */
 +      add $t1, $t1, $t3
 +      add $t2, $t2, $t3
 +      addiu $t1, $t1, 0xffff
 +      addiu $t2, $t2, 0xffff
 +
 +      /* $t2 is source. $t1 is destination. $t3 is size.  */
 +modulesmovcont:
 +      lb $t4, 0($t2)
 +      sb $t4, 0($t1)
 +      addiu $t1,$t1,0xffff
 +      addiu $t2,$t2,0xffff
 +      addiu $t3, 0xffff
 +      bne $t3, $0, modulesmovcont
 +
 +      /* Clean BSS.  */
 +      
 +      lui $t1, %hi(__bss_start)
 +      addiu $t1, %lo(__bss_start)
 +      lui $t2, %hi(_end)
 +      addiu $t2, %lo(_end)
 +bsscont:
 +      sb $0,0($t1)
 +      addiu $t1,$t1,1
 +      sltu $t3,$t1,$t2
 +      bne $t3, $0, bsscont
 +
 +      li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH
 +      lui $t1, %hi(grub_main)
 +      addiu $t1, %lo(grub_main)
 +
 +      jr $t1
 +
index 96d153778341bc6ff41d77b41df86d66b646d987,0000000000000000000000000000000000000000..526df1d915da5e357662868f5080d962208bcc25
mode 100644,000000..100644
--- /dev/null
@@@ -1,64 -1,0 +1,64 @@@
-       /* to be filled by grub-mkelfimage */
 +/* startup.S - Startup code for the PowerPC.  */
 +/*
 + *  GRUB  --  GRand Unified Bootloader
 + *  Copyright (C) 2003,2004,2005,2007,2008  Free Software Foundation, Inc.
 + *
 + *  GRUB is free software: you can redistribute it and/or modify
 + *  it under the terms of the GNU General Public License as published by
 + *  the Free Software Foundation, either version 3 of the License, or
 + *  (at your option) any later version.
 + *
 + *  GRUB is distributed in the hope that it will be useful,
 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + *  GNU General Public License for more details.
 + *
 + *  You should have received a copy of the GNU General Public License
 + *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 + */
 +
 +#include <grub/symbol.h>
 +#include <grub/offsets.h>
 +
 +.extern __bss_start
 +.extern _end
 +
 +      .text
 +      .align  2
 +      .globl  start, _start
 +start:
 +_start:
 +      b       codestart
 +
 +      . = _start + GRUB_KERNEL_MACHINE_PREFIX
 +
 +VARIABLE(grub_prefix)
++      /* to be filled by grub-mkimage */
 +
 +      /*
 +       *  Leave some breathing room for the prefix.
 +       */
 +
 +      . = _start + GRUB_KERNEL_MACHINE_DATA_END
 +
 +codestart:
 +      li      2, 0
 +      li      13, 0
 +
 +      /* Stage1 won't zero BSS for us. In other cases, why not do it again?  */
 +      lis     6, (__bss_start - 4)@h
 +      ori     6, 6, (__bss_start - 4)@l
 +      lis     7, (_end - 4)@h
 +      ori     7, 7, (_end - 4)@l
 +      subf    7, 6, 7
 +      srwi    7, 7, 2 /* We store 4 bytes at a time.  */
 +      mtctr   7
 +2:    stwu    2, 4(6) /* We know r2 is already 0 from above.  */
 +      bdnz    2b
 +
 +      /* Store r5 in grub_ieee1275_entry_fn.  */
 +      lis     9, grub_ieee1275_entry_fn@ha
 +      stw     5, grub_ieee1275_entry_fn@l(9)
 +
 +      bl      grub_main
 +1:    b       1b
index c3e71ea2dfebf991d9db7ff772dbacc534d97ef9,0000000000000000000000000000000000000000..25f32a0a5bc8621d49ccea5efcb2d524f6af018b
mode 100644,000000..100644
--- /dev/null
@@@ -1,303 -1,0 +1,297 @@@
-       /* Caps lock sends scan code twice.  Get the second one and discard it.  */
-       while (grub_keyboard_getkey () == -1);
 +/*
 + *  GRUB  --  GRand Unified Bootloader
 + *  Copyright (C) 2007,2008,2009  Free Software Foundation, Inc.
 + *
 + *  GRUB is free software: you can redistribute it and/or modify
 + *  it under the terms of the GNU General Public License as published by
 + *  the Free Software Foundation, either version 3 of the License, or
 + *  (at your option) any later version.
 + *
 + *  GRUB is distributed in the hope that it will be useful,
 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + *  GNU General Public License for more details.
 + *
 + *  You should have received a copy of the GNU General Public License
 + *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 + */
 +
 +#include <grub/dl.h>
 +#include <grub/at_keyboard.h>
 +#include <grub/cpu/at_keyboard.h>
 +#include <grub/cpu/io.h>
 +#include <grub/misc.h>
 +#include <grub/term.h>
 +
 +static short at_keyboard_status = 0;
 +static int pending_key = -1;
 +
 +#define KEYBOARD_STATUS_SHIFT_L               (1 << 0)
 +#define KEYBOARD_STATUS_SHIFT_R               (1 << 1)
 +#define KEYBOARD_STATUS_ALT_L         (1 << 2)
 +#define KEYBOARD_STATUS_ALT_R         (1 << 3)
 +#define KEYBOARD_STATUS_CTRL_L                (1 << 4)
 +#define KEYBOARD_STATUS_CTRL_R                (1 << 5)
 +#define KEYBOARD_STATUS_CAPS_LOCK     (1 << 6)
 +#define KEYBOARD_STATUS_NUM_LOCK      (1 << 7)
 +
 +static grub_uint8_t led_status;
 +
 +#define KEYBOARD_LED_SCROLL           (1 << 0)
 +#define KEYBOARD_LED_NUM              (1 << 1)
 +#define KEYBOARD_LED_CAPS             (1 << 2)
 +
 +static char keyboard_map[128] =
 +{
 +  '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6',
 +  '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB,
 +  'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
 +  'o', 'p', '[', ']', '\n', '\0', 'a', 's',
 +  'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
 +  '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v',
 +  'b', 'n', 'm', ',', '.', '/', '\0', '*',
 +  '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0',
 +  '\0', '\0', '\0', '\0', '\0', '\0', '\0', GRUB_TERM_HOME,
 +  GRUB_TERM_UP, GRUB_TERM_NPAGE, '-', GRUB_TERM_LEFT, '\0', GRUB_TERM_RIGHT, '+', GRUB_TERM_END,
 +  GRUB_TERM_DOWN, GRUB_TERM_PPAGE, '\0', GRUB_TERM_DC, '\0', '\0', '\0', '\0',
 +  '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
 +  '\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT,
 +  OLPC_RIGHT
 +};
 +
 +static char keyboard_map_shift[128] =
 +{
 +  '\0', '\0', '!', '@', '#', '$', '%', '^',
 +  '&', '*', '(', ')', '_', '+', '\0', '\0',
 +  'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
 +  'O', 'P', '{', '}', '\n', '\0', 'A', 'S',
 +  'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
 +  '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V',
 +  'B', 'N', 'M', '<', '>', '?'
 +};
 +
 +static grub_uint8_t grub_keyboard_controller_orig;
 +
 +static void
 +keyboard_controller_wait_until_ready (void)
 +{
 +  while (! KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS)));
 +}
 +
 +static void
 +grub_keyboard_controller_write (grub_uint8_t c)
 +{
 +  keyboard_controller_wait_until_ready ();
 +  grub_outb (KEYBOARD_COMMAND_WRITE, KEYBOARD_REG_STATUS);
 +  grub_outb (c, KEYBOARD_REG_DATA);
 +}
 +
 +static grub_uint8_t
 +grub_keyboard_controller_read (void)
 +{
 +  keyboard_controller_wait_until_ready ();
 +  grub_outb (KEYBOARD_COMMAND_READ, KEYBOARD_REG_STATUS);
 +  return grub_inb (KEYBOARD_REG_DATA);
 +}
 +
 +static void
 +keyboard_controller_led (grub_uint8_t leds)
 +{
 +  keyboard_controller_wait_until_ready ();
 +  grub_outb (0xed, KEYBOARD_REG_DATA);
 +  keyboard_controller_wait_until_ready ();
 +  grub_outb (leds & 0x7, KEYBOARD_REG_DATA);
 +}
 +
 +/* FIXME: This should become an interrupt service routine.  For now
 +   it's just used to catch events from control keys.  */
 +static void
 +grub_keyboard_isr (char key)
 +{
 +  char is_make = KEYBOARD_ISMAKE (key);
 +  key = KEYBOARD_SCANCODE (key);
 +  if (is_make)
 +    switch (key)
 +      {
 +      case SHIFT_L:
 +        at_keyboard_status |= KEYBOARD_STATUS_SHIFT_L;
 +        break;
 +      case SHIFT_R:
 +        at_keyboard_status |= KEYBOARD_STATUS_SHIFT_R;
 +        break;
 +      case CTRL:
 +        at_keyboard_status |= KEYBOARD_STATUS_CTRL_L;
 +        break;
 +      case ALT:
 +        at_keyboard_status |= KEYBOARD_STATUS_ALT_L;
 +        break;
 +      default:
 +        /* Skip grub_dprintf.  */
 +        return;
 +      }
 +  else
 +    switch (key)
 +      {
 +      case SHIFT_L:
 +        at_keyboard_status &= ~KEYBOARD_STATUS_SHIFT_L;
 +        break;
 +      case SHIFT_R:
 +        at_keyboard_status &= ~KEYBOARD_STATUS_SHIFT_R;
 +        break;
 +      case CTRL:
 +        at_keyboard_status &= ~KEYBOARD_STATUS_CTRL_L;
 +        break;
 +      case ALT:
 +        at_keyboard_status &= ~KEYBOARD_STATUS_ALT_L;
 +        break;
 +      default:
 +        /* Skip grub_dprintf.  */
 +        return;
 +      }
 +#ifdef DEBUG_AT_KEYBOARD
 +  grub_dprintf ("atkeyb", "Control key 0x%0x was %s\n", key, is_make ? "pressed" : "unpressed");
 +#endif
 +}
 +
 +/* If there is a raw key pending, return it; otherwise return -1.  */
 +static int
 +grub_keyboard_getkey (void)
 +{
 +  grub_uint8_t key;
 +  if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS)))
 +    return -1;
 +  key = grub_inb (KEYBOARD_REG_DATA);
 +  /* FIXME */ grub_keyboard_isr (key);
 +  if (! KEYBOARD_ISMAKE (key))
 +    return -1;
 +  return (KEYBOARD_SCANCODE (key));
 +}
 +
 +/* If there is a character pending, return it; otherwise return -1.  */
 +static int
 +grub_at_keyboard_getkey_noblock (void)
 +{
 +  int code, key;
 +  code = grub_keyboard_getkey ();
 +  if (code == -1)
 +    return -1;
 +#ifdef DEBUG_AT_KEYBOARD
 +  grub_dprintf ("atkeyb", "Detected key 0x%x\n", key);
 +#endif
 +  switch (code)
 +    {
 +      case CAPS_LOCK:
-       /* Num lock sends scan code twice.  Get the second one and discard it.  */
-       while (grub_keyboard_getkey () == -1);
 +      at_keyboard_status ^= KEYBOARD_STATUS_CAPS_LOCK;
 +      led_status ^= KEYBOARD_LED_CAPS;
 +      keyboard_controller_led (led_status);
 +
 +#ifdef DEBUG_AT_KEYBOARD
 +      grub_dprintf ("atkeyb", "caps_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK));
 +#endif
 +      key = -1;
 +      break;
 +      case NUM_LOCK:
 +      at_keyboard_status ^= KEYBOARD_STATUS_NUM_LOCK;
 +      led_status ^= KEYBOARD_LED_NUM;
 +      keyboard_controller_led (led_status);
 +
 +#ifdef DEBUG_AT_KEYBOARD
 +      grub_dprintf ("atkeyb", "num_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_NUM_LOCK));
 +#endif
 +      key = -1;
 +      break;
 +      case SCROLL_LOCK:
 +      /* For scroll lock we don't keep track of status.  Only update its led.  */
 +      led_status ^= KEYBOARD_LED_SCROLL;
 +      keyboard_controller_led (led_status);
 +      key = -1;
 +      break;
 +      default:
 +      if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L | KEYBOARD_STATUS_CTRL_R))
 +        key = keyboard_map[code] - 'a' + 1;
 +      else if ((at_keyboard_status & (KEYBOARD_STATUS_SHIFT_L | KEYBOARD_STATUS_SHIFT_R))
 +          && keyboard_map_shift[code])
 +        key = keyboard_map_shift[code];
 +      else
 +        key = keyboard_map[code];
 +
 +      if (key == 0)
 +        grub_dprintf ("atkeyb", "Unknown key 0x%x detected\n", code);
 +
 +      if (at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK)
 +        {
 +          if ((key >= 'a') && (key <= 'z'))
 +            key += 'A' - 'a';
 +          else if ((key >= 'A') && (key <= 'Z'))
 +            key += 'a' - 'A';
 +        }
 +    }
 +  return key;
 +}
 +
 +static int
 +grub_at_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused)))
 +{
 +  if (pending_key != -1)
 +    return 1;
 +
 +  pending_key = grub_at_keyboard_getkey_noblock ();
 +
 +  if (pending_key != -1)
 +    return 1;
 +
 +  return -1;
 +}
 +
 +static int
 +grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused)))
 +{
 +  int key;
 +  if (pending_key != -1)
 +    {
 +      key = pending_key;
 +      pending_key = -1;
 +      return key;
 +    }
 +  do
 +    {
 +      key = grub_at_keyboard_getkey_noblock ();
 +    } while (key == -1);
 +  return key;
 +}
 +
 +static grub_err_t
 +grub_keyboard_controller_init (struct grub_term_input *term __attribute__ ((unused)))
 +{
 +  pending_key = -1;
 +  at_keyboard_status = 0;
 +  grub_keyboard_controller_orig = grub_keyboard_controller_read ();
 +  grub_keyboard_controller_write (grub_keyboard_controller_orig | KEYBOARD_SCANCODE_SET1);
 +  return GRUB_ERR_NONE;
 +}
 +
 +static grub_err_t
 +grub_keyboard_controller_fini (struct grub_term_input *term __attribute__ ((unused)))
 +{
 +  grub_keyboard_controller_write (grub_keyboard_controller_orig);
 +  return GRUB_ERR_NONE;
 +}
 +
 +static struct grub_term_input grub_at_keyboard_term =
 +  {
 +    .name = "at_keyboard",
 +    .init = grub_keyboard_controller_init,
 +    .fini = grub_keyboard_controller_fini,
 +    .checkkey = grub_at_keyboard_checkkey,
 +    .getkey = grub_at_keyboard_getkey,
 +  };
 +
 +GRUB_MOD_INIT(at_keyboard)
 +{
 +  grub_term_register_input ("at_keyboard", &grub_at_keyboard_term);
 +}
 +
 +GRUB_MOD_FINI(at_keyboard)
 +{
 +  grub_term_unregister_input (&grub_at_keyboard_term);
 +}