~ubuntu-branches/ubuntu/trusty/grub2/trusty-updates

« back to all changes in this revision

Viewing changes to grub-core/loader/i386/coreboot/chainloader.c

  • Committer: Package Import Robot
  • Author(s): Colin Watson
  • Date: 2012-09-13 18:02:04 UTC
  • mfrom: (1.17.15 upstream)
  • mto: (17.6.27 experimental)
  • mto: This revision was merged to the branch mainline in revision 145.
  • Revision ID: package-import@ubuntu.com-20120913180204-mojnmocbimlom4im
Tags: upstream-2.00
ImportĀ upstreamĀ versionĀ 2.00

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  GRUB  --  GRand Unified Bootloader
 
3
 *  Copyright (C) 2011  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/loader.h>
 
20
#include <grub/memory.h>
 
21
#include <grub/i386/memory.h>
 
22
#include <grub/file.h>
 
23
#include <grub/err.h>
 
24
#include <grub/dl.h>
 
25
#include <grub/mm.h>
 
26
#include <grub/elfload.h>
 
27
#include <grub/video.h>
 
28
#include <grub/relocator.h>
 
29
#include <grub/i386/relocator.h>
 
30
#include <grub/command.h>
 
31
#include <grub/i18n.h>
 
32
 
 
33
GRUB_MOD_LICENSE ("GPLv3+");
 
34
 
 
35
static grub_addr_t entry;
 
36
static struct grub_relocator *relocator = NULL;
 
37
 
 
38
static grub_err_t
 
39
grub_chain_boot (void)
 
40
{
 
41
  struct grub_relocator32_state state;
 
42
 
 
43
  grub_video_set_mode ("text", 0, 0);
 
44
 
 
45
  state.eip = entry;
 
46
  return grub_relocator32_boot (relocator, state, 0);
 
47
}
 
48
 
 
49
static grub_err_t
 
50
grub_chain_unload (void)
 
51
{
 
52
  grub_relocator_unload (relocator);
 
53
  relocator = NULL;
 
54
 
 
55
  return GRUB_ERR_NONE;
 
56
}
 
57
 
 
58
static grub_err_t
 
59
grub_chain_elf32_hook (Elf32_Phdr * phdr, grub_addr_t * addr, int *do_load)
 
60
{
 
61
  grub_err_t err;
 
62
  grub_relocator_chunk_t ch;
 
63
 
 
64
  if (phdr->p_type != PT_LOAD)
 
65
    {
 
66
      *do_load = 0;
 
67
      return 0;
 
68
    }
 
69
 
 
70
  *do_load = 1;
 
71
  err = grub_relocator_alloc_chunk_addr (relocator, &ch,
 
72
                                         phdr->p_paddr, phdr->p_memsz);
 
73
  if (err)
 
74
    return err;
 
75
 
 
76
  *addr = (grub_addr_t) get_virtual_current_address (ch);
 
77
 
 
78
  return GRUB_ERR_NONE;
 
79
}
 
80
 
 
81
 
 
82
static grub_err_t
 
83
grub_cmd_chain (grub_command_t cmd __attribute__ ((unused)),
 
84
                int argc, char *argv[])
 
85
{
 
86
  grub_err_t err;
 
87
  grub_file_t file;
 
88
  grub_elf_t elf;
 
89
 
 
90
  if (argc != 1)
 
91
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
 
92
 
 
93
  grub_loader_unset ();
 
94
 
 
95
  file = grub_file_open (argv[0]);
 
96
  if (!file)
 
97
    return grub_errno;
 
98
 
 
99
  relocator = grub_relocator_new ();
 
100
  if (!relocator)
 
101
    {
 
102
      grub_file_close (file);
 
103
      return grub_errno;
 
104
    }
 
105
 
 
106
  elf = grub_elf_file (file, argv[0]);
 
107
  if (!elf)
 
108
    {
 
109
      grub_relocator_unload (relocator);
 
110
      relocator = 0;
 
111
      grub_file_close (file);
 
112
    }
 
113
 
 
114
  if (!grub_elf_is_elf32 (elf))
 
115
    {
 
116
      grub_relocator_unload (relocator);
 
117
      relocator = 0;
 
118
      grub_elf_close (elf);
 
119
    }
 
120
 
 
121
  entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFF;
 
122
  
 
123
  err = grub_elf32_load (elf, argv[0], grub_chain_elf32_hook, 0, 0);
 
124
 
 
125
  grub_elf_close (elf);
 
126
  if (err)
 
127
    return err;
 
128
 
 
129
  grub_loader_set (grub_chain_boot, grub_chain_unload, 0);
 
130
  return GRUB_ERR_NONE;
 
131
}
 
132
 
 
133
static grub_command_t cmd_chain;
 
134
 
 
135
GRUB_MOD_INIT (chain)
 
136
{
 
137
  cmd_chain = grub_register_command ("chainloader", grub_cmd_chain,
 
138
                                     N_("FILE"),
 
139
                                     /* TRANSLATORS: "payload" is a term used
 
140
                                        by coreboot and must be translated in
 
141
                                        sync with coreboot. If unsure,
 
142
                                        let it untranslated.  */
 
143
                                     N_("Load another coreboot payload"));
 
144
}
 
145
 
 
146
GRUB_MOD_FINI (chain)
 
147
{
 
148
  grub_unregister_command (cmd_chain);
 
149
  grub_chain_unload ();
 
150
}