diff options
| author | Koen Kooi <koen@dominion.thruhere.net> | 2014-01-06 12:01:25 +0100 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2014-01-06 22:17:29 +0000 |
| commit | b1bf8f7f2bf7c6117c56e08b6ba667720862d3da (patch) | |
| tree | 4d59020cbf37745d0370aa32d6c5f8809248db2d | |
| parent | 2acd6174dea199917255cfe69f7504923069185e (diff) | |
| download | poky-b1bf8f7f2bf7c6117c56e08b6ba667720862d3da.tar.gz | |
grub: add git version
Recently grub git gained support for ARM builds (using u-boot or EFI as first stage loader) and with 2 extra patches we get support for 64-bit ARM as well.
Buildtested for genericarmv7a, genericarmv8 and qemux86. The genericarmv8 build fails in do_package/strip due to a binutils problem.
(From OE-Core rev: b4e28912af0618755ce75d0cc27d53fa9d745b30)
Signed-off-by: Koen Kooi <koen.kooi@linaro.org>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
| -rw-r--r-- | meta/recipes-bsp/grub/grub/0001-fdt-add-grub_fdt_create_empty_tree-function.patch | 73 | ||||
| -rw-r--r-- | meta/recipes-bsp/grub/grub/0002-arm64-add-EFI-Linux-loader.patch | 653 | ||||
| -rwxr-xr-x | meta/recipes-bsp/grub/grub/40_custom (renamed from meta/recipes-bsp/grub/grub-2.00/40_custom) | 0 | ||||
| -rw-r--r-- | meta/recipes-bsp/grub/grub_git.bb | 61 |
4 files changed, 787 insertions, 0 deletions
diff --git a/meta/recipes-bsp/grub/grub/0001-fdt-add-grub_fdt_create_empty_tree-function.patch b/meta/recipes-bsp/grub/grub/0001-fdt-add-grub_fdt_create_empty_tree-function.patch new file mode 100644 index 0000000000..341457488d --- /dev/null +++ b/meta/recipes-bsp/grub/grub/0001-fdt-add-grub_fdt_create_empty_tree-function.patch | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | From b3417ec69ff7d52379a8f2cb291dbecccdab684f Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Leif Lindholm <leif.lindholm@linaro.org> | ||
| 3 | Date: Wed, 4 Dec 2013 13:09:21 +0000 | ||
| 4 | Subject: [PATCH 1/2] fdt: add grub_fdt_create_empty_tree() function | ||
| 5 | |||
| 6 | Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org> | ||
| 7 | --- | ||
| 8 | grub-core/lib/fdt.c | 39 +++++++++++++++++++++++++++++++++++++++ | ||
| 9 | include/grub/fdt.h | 1 + | ||
| 10 | 2 files changed, 40 insertions(+) | ||
| 11 | |||
| 12 | diff --git a/grub-core/lib/fdt.c b/grub-core/lib/fdt.c | ||
| 13 | index 9f34dc7..581a118 100644 | ||
| 14 | --- a/grub-core/lib/fdt.c | ||
| 15 | +++ b/grub-core/lib/fdt.c | ||
| 16 | @@ -423,3 +423,42 @@ int grub_fdt_set_prop (void *fdt, unsigned int nodeoffset, const char *name, | ||
| 17 | grub_memcpy (prop + 3, val, len); | ||
| 18 | return 0; | ||
| 19 | } | ||
| 20 | + | ||
| 21 | +struct empty_tree { | ||
| 22 | + grub_fdt_header_t header; | ||
| 23 | + grub_uint64_t empty_rsvmap[2]; | ||
| 24 | + struct { | ||
| 25 | + grub_uint32_t prop_start; | ||
| 26 | + grub_uint8_t name[1]; | ||
| 27 | + grub_uint32_t prop_end; | ||
| 28 | + grub_uint32_t node_end; | ||
| 29 | + } empty_node; | ||
| 30 | +}; | ||
| 31 | + | ||
| 32 | +int | ||
| 33 | +grub_fdt_create_empty_tree (void *fdt, unsigned int size) | ||
| 34 | +{ | ||
| 35 | + struct empty_tree *et; | ||
| 36 | + | ||
| 37 | + if (size < sizeof (struct empty_tree)) | ||
| 38 | + return -1; | ||
| 39 | + | ||
| 40 | + grub_memset (fdt, 0, size); | ||
| 41 | + et = fdt; | ||
| 42 | + | ||
| 43 | + et->empty_node.node_end = grub_cpu_to_be32 (FDT_END); | ||
| 44 | + et->empty_node.prop_end = grub_cpu_to_be32 (FDT_END_NODE); | ||
| 45 | + et->empty_node.prop_start = grub_cpu_to_be32 (FDT_BEGIN_NODE); | ||
| 46 | + ((struct empty_tree *) fdt)->header.off_mem_rsvmap = | ||
| 47 | + grub_cpu_to_be32 (ALIGN_UP (sizeof (grub_fdt_header_t), 8)); | ||
| 48 | + | ||
| 49 | + grub_fdt_set_off_dt_strings (fdt, sizeof (struct empty_tree)); | ||
| 50 | + grub_fdt_set_off_dt_struct (fdt, sizeof (grub_fdt_header_t) + 16); | ||
| 51 | + grub_fdt_set_version (fdt, FDT_SUPPORTED_VERSION); | ||
| 52 | + grub_fdt_set_last_comp_version (fdt, FDT_SUPPORTED_VERSION); | ||
| 53 | + grub_fdt_set_size_dt_struct (fdt, sizeof (et->empty_node)); | ||
| 54 | + grub_fdt_set_totalsize (fdt, size); | ||
| 55 | + grub_fdt_set_magic (fdt, FDT_MAGIC); | ||
| 56 | + | ||
| 57 | + return 0; | ||
| 58 | +} | ||
| 59 | diff --git a/include/grub/fdt.h b/include/grub/fdt.h | ||
| 60 | index 2ad0536..06eec19 100644 | ||
| 61 | --- a/include/grub/fdt.h | ||
| 62 | +++ b/include/grub/fdt.h | ||
| 63 | @@ -82,6 +82,7 @@ typedef struct { | ||
| 64 | #define grub_fdt_set_size_dt_struct(fdt, value) \ | ||
| 65 | grub_fdt_set_header(fdt, size_dt_struct, value) | ||
| 66 | |||
| 67 | +int grub_fdt_create_empty_tree (void *fdt, unsigned int size); | ||
| 68 | int grub_fdt_check_header (void *fdt, unsigned int size); | ||
| 69 | int grub_fdt_find_subnode (const void *fdt, unsigned int parentoffset, | ||
| 70 | const char *name); | ||
| 71 | -- | ||
| 72 | 1.8.4.2 | ||
| 73 | |||
diff --git a/meta/recipes-bsp/grub/grub/0002-arm64-add-EFI-Linux-loader.patch b/meta/recipes-bsp/grub/grub/0002-arm64-add-EFI-Linux-loader.patch new file mode 100644 index 0000000000..4e9df62bdf --- /dev/null +++ b/meta/recipes-bsp/grub/grub/0002-arm64-add-EFI-Linux-loader.patch | |||
| @@ -0,0 +1,653 @@ | |||
| 1 | From 55cbddc471b6caf27355ce93d1534d894e6ed0bb Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Leif Lindholm <leif.lindholm@linaro.org> | ||
| 3 | Date: Wed, 4 Dec 2013 15:21:16 +0000 | ||
| 4 | Subject: [PATCH 2/2] arm64: add EFI Linux loader | ||
| 5 | |||
| 6 | Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org> | ||
| 7 | --- | ||
| 8 | grub-core/Makefile.core.def | 4 +- | ||
| 9 | grub-core/loader/arm64/linux.c | 252 ++++++++++++++++++++++++++++++++++ | ||
| 10 | grub-core/loader/arm64/linuxefi.c | 279 ++++++++++++++++++++++++++++++++++++++ | ||
| 11 | include/grub/arm64/linux.h | 54 ++++++++ | ||
| 12 | include/grub/efi/api.h | 4 + | ||
| 13 | 5 files changed, 592 insertions(+), 1 deletion(-) | ||
| 14 | create mode 100644 grub-core/loader/arm64/linux.c | ||
| 15 | create mode 100644 grub-core/loader/arm64/linuxefi.c | ||
| 16 | create mode 100644 include/grub/arm64/linux.h | ||
| 17 | |||
| 18 | diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def | ||
| 19 | index 060de44..7cf91a6 100644 | ||
| 20 | --- a/grub-core/Makefile.core.def | ||
| 21 | +++ b/grub-core/Makefile.core.def | ||
| 22 | @@ -1663,7 +1663,9 @@ module = { | ||
| 23 | sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c; | ||
| 24 | ia64_efi = loader/ia64/efi/linux.c; | ||
| 25 | arm = loader/arm/linux.c; | ||
| 26 | - arm = lib/fdt.c; | ||
| 27 | + arm64 = loader/arm64/linux.c; | ||
| 28 | + arm64 = loader/arm64/linuxefi.c; | ||
| 29 | + fdt = lib/fdt.c; | ||
| 30 | common = loader/linux.c; | ||
| 31 | common = lib/cmdline.c; | ||
| 32 | enable = noemu; | ||
| 33 | diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c | ||
| 34 | new file mode 100644 | ||
| 35 | index 0000000..38821c9 | ||
| 36 | --- /dev/null | ||
| 37 | +++ b/grub-core/loader/arm64/linux.c | ||
| 38 | @@ -0,0 +1,252 @@ | ||
| 39 | +/* Helper functions for the generic UEFI Linux loader */ | ||
| 40 | +/* | ||
| 41 | + * GRUB -- GRand Unified Bootloader | ||
| 42 | + * Copyright (C) 2013 Free Software Foundation, Inc. | ||
| 43 | + * | ||
| 44 | + * GRUB is free software: you can redistribute it and/or modify | ||
| 45 | + * it under the terms of the GNU General Public License as published by | ||
| 46 | + * the Free Software Foundation, either version 3 of the License, or | ||
| 47 | + * (at your option) any later version. | ||
| 48 | + * | ||
| 49 | + * GRUB is distributed in the hope that it will be useful, | ||
| 50 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 51 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 52 | + * GNU General Public License for more details. | ||
| 53 | + * | ||
| 54 | + * You should have received a copy of the GNU General Public License | ||
| 55 | + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. | ||
| 56 | + */ | ||
| 57 | + | ||
| 58 | +#include <grub/command.h> | ||
| 59 | +#include <grub/err.h> | ||
| 60 | +#include <grub/file.h> | ||
| 61 | +#include <grub/fdt.h> | ||
| 62 | +#include <grub/mm.h> | ||
| 63 | +#include <grub/cpu/linux.h> | ||
| 64 | +#include <grub/efi/efi.h> | ||
| 65 | + | ||
| 66 | +static grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID; | ||
| 67 | + | ||
| 68 | +static int chosen; | ||
| 69 | + | ||
| 70 | +static grub_addr_t initrd_start; | ||
| 71 | +static grub_addr_t initrd_end; | ||
| 72 | + | ||
| 73 | +static void * fw_fdt; | ||
| 74 | +static void * fdt; | ||
| 75 | + | ||
| 76 | +static char *linux_args; | ||
| 77 | + | ||
| 78 | +static void | ||
| 79 | +get_fdt (void) | ||
| 80 | +{ | ||
| 81 | + grub_efi_configuration_table_t * tables; | ||
| 82 | + unsigned int i; | ||
| 83 | + int size; | ||
| 84 | + | ||
| 85 | + /* If already loaded, just return address. */ | ||
| 86 | + if (fdt) | ||
| 87 | + return; | ||
| 88 | + | ||
| 89 | + tables = grub_efi_system_table->configuration_table; | ||
| 90 | + | ||
| 91 | + if (!fw_fdt) | ||
| 92 | + /* Look for FDT in UEFI config tables. */ | ||
| 93 | + for (i=0; i < grub_efi_system_table->num_table_entries; i++) | ||
| 94 | + if (grub_memcmp (&tables[i].vendor_guid, &fdt_guid, sizeof (fdt_guid)) | ||
| 95 | + == 0) | ||
| 96 | + { | ||
| 97 | + fw_fdt = tables[i].vendor_table; | ||
| 98 | + grub_dprintf("linux", "found registered FDT @ 0x%p\n", fw_fdt); | ||
| 99 | + break; | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + size = fw_fdt ? grub_fdt_get_totalsize (fw_fdt) : 0; | ||
| 103 | + size += grub_strlen (linux_args) + 0x400; | ||
| 104 | + | ||
| 105 | + grub_dprintf("linux", "allocating %d bytes for fdt\n", size); | ||
| 106 | + fdt = grub_malloc (size); | ||
| 107 | + if (!fdt) | ||
| 108 | + return; | ||
| 109 | + | ||
| 110 | + if (fw_fdt) | ||
| 111 | + { | ||
| 112 | + grub_memmove (fdt, fw_fdt, size); | ||
| 113 | + grub_fdt_set_totalsize (fdt, size); | ||
| 114 | + } | ||
| 115 | + else | ||
| 116 | + { | ||
| 117 | + grub_fdt_create_empty_tree (fdt, size); | ||
| 118 | + } | ||
| 119 | +} | ||
| 120 | + | ||
| 121 | +static int | ||
| 122 | +get_chosen (void) | ||
| 123 | +{ | ||
| 124 | + chosen = grub_fdt_find_subnode (fdt, 0, "chosen"); | ||
| 125 | + grub_printf("chosen: 0x%08x\n", chosen); | ||
| 126 | + if (chosen < 0) | ||
| 127 | + { | ||
| 128 | + grub_dprintf ("linux", "No 'chosen' node in FDT - creating.\n"); | ||
| 129 | + chosen = grub_fdt_add_subnode (fdt, 0, "chosen"); | ||
| 130 | + if (chosen < 0) | ||
| 131 | + return 0; | ||
| 132 | + grub_printf("chosen=0x%08x\n", chosen); | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + return chosen; | ||
| 136 | +} | ||
| 137 | + | ||
| 138 | + | ||
| 139 | +grub_err_t | ||
| 140 | +grub_linux_init_params (void) | ||
| 141 | +{ | ||
| 142 | + return GRUB_ERR_NONE; | ||
| 143 | +} | ||
| 144 | + | ||
| 145 | +grub_err_t | ||
| 146 | +grub_linux_check_kernel (struct linux_kernel_header *lh) | ||
| 147 | +{ | ||
| 148 | + if (lh->magic != GRUB_LINUX_MAGIC) | ||
| 149 | + return GRUB_ERR_BAD_OS; | ||
| 150 | + | ||
| 151 | + if ((lh->code0 & 0xffff) == 0x5A4D) | ||
| 152 | + grub_dprintf ("linux", "UEFI stub kernel\n"); | ||
| 153 | + else | ||
| 154 | + grub_dprintf ("linux", "Plain Image kernel\n"); | ||
| 155 | + | ||
| 156 | + return GRUB_ERR_NONE; | ||
| 157 | +} | ||
| 158 | + | ||
| 159 | +grub_err_t | ||
| 160 | +grub_linux_register_cmdline (void * addr) | ||
| 161 | +{ | ||
| 162 | + linux_args = addr; | ||
| 163 | + | ||
| 164 | + return GRUB_ERR_NONE; | ||
| 165 | +} | ||
| 166 | + | ||
| 167 | +grub_err_t | ||
| 168 | +grub_linux_register_initrd (void * addr, grub_size_t size) | ||
| 169 | +{ | ||
| 170 | + initrd_start = (grub_addr_t) addr; | ||
| 171 | + initrd_end = initrd_start + size; | ||
| 172 | + | ||
| 173 | + return GRUB_ERR_NONE; | ||
| 174 | +} | ||
| 175 | + | ||
| 176 | +grub_err_t | ||
| 177 | +grub_linux_finalize_params (void) | ||
| 178 | +{ | ||
| 179 | + grub_efi_boot_services_t *b; | ||
| 180 | + grub_efi_status_t status; | ||
| 181 | + int node, retval; | ||
| 182 | + | ||
| 183 | + get_fdt(); | ||
| 184 | + if (!fdt) | ||
| 185 | + goto failure; | ||
| 186 | + | ||
| 187 | + node = get_chosen(); | ||
| 188 | + if (node < 1) | ||
| 189 | + goto failure; | ||
| 190 | + | ||
| 191 | + /* Generate and set command line */ | ||
| 192 | + retval = grub_fdt_set_prop (fdt, node, "bootargs", linux_args, | ||
| 193 | + grub_strlen (linux_args) + 1); | ||
| 194 | + if (retval) | ||
| 195 | + { | ||
| 196 | + grub_dprintf("linux", "failed to set command line\n"); | ||
| 197 | + goto failure; | ||
| 198 | + } | ||
| 199 | + | ||
| 200 | + grub_dprintf ("linux", "linux command line: '%s'\n", linux_args); | ||
| 201 | + | ||
| 202 | + b = grub_efi_system_table->boot_services; | ||
| 203 | + status = b->install_configuration_table (&fdt_guid, fdt); | ||
| 204 | + if (status != GRUB_EFI_SUCCESS) | ||
| 205 | + return GRUB_ERR_BAD_OS; | ||
| 206 | + | ||
| 207 | + grub_dprintf ("linux", "Installed/updated FDT configuration table!\n"); | ||
| 208 | + grub_dprintf ("linux", " @ %p\n", fdt); | ||
| 209 | + | ||
| 210 | + return GRUB_ERR_NONE; | ||
| 211 | + | ||
| 212 | + failure: | ||
| 213 | + return GRUB_ERR_BAD_OS; | ||
| 214 | +} | ||
| 215 | + | ||
| 216 | +static void * | ||
| 217 | +load_dtb (const char * filename) | ||
| 218 | +{ | ||
| 219 | + grub_file_t dtb; | ||
| 220 | + void * tmp_fdt; | ||
| 221 | + int size; | ||
| 222 | + | ||
| 223 | + tmp_fdt = NULL; | ||
| 224 | + dtb = grub_file_open (filename); | ||
| 225 | + if (!dtb) | ||
| 226 | + { | ||
| 227 | + grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("failed to open file")); | ||
| 228 | + return NULL; | ||
| 229 | + } | ||
| 230 | + | ||
| 231 | + size = grub_file_size (dtb); | ||
| 232 | + if (size == 0) | ||
| 233 | + goto out; | ||
| 234 | + | ||
| 235 | + tmp_fdt = grub_malloc (size); | ||
| 236 | + if (!tmp_fdt) | ||
| 237 | + goto out; | ||
| 238 | + | ||
| 239 | + if (grub_file_read (dtb, tmp_fdt, size) != size) | ||
| 240 | + { | ||
| 241 | + grub_free (tmp_fdt); | ||
| 242 | + return NULL; | ||
| 243 | + } | ||
| 244 | + | ||
| 245 | + if (grub_fdt_check_header (tmp_fdt, size) != 0) | ||
| 246 | + { | ||
| 247 | + grub_free (tmp_fdt); | ||
| 248 | + return NULL; | ||
| 249 | + } | ||
| 250 | + | ||
| 251 | + out: | ||
| 252 | + grub_file_close (dtb); | ||
| 253 | + return tmp_fdt; | ||
| 254 | +} | ||
| 255 | + | ||
| 256 | +static grub_err_t | ||
| 257 | +grub_cmd_devicetree (grub_command_t cmd __attribute__ ((unused)), | ||
| 258 | + int argc, char *argv[]) | ||
| 259 | +{ | ||
| 260 | + void *blob; | ||
| 261 | + | ||
| 262 | + if (argc != 1) | ||
| 263 | + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); | ||
| 264 | + | ||
| 265 | + grub_free(fdt); | ||
| 266 | + | ||
| 267 | + blob = load_dtb (argv[0]); | ||
| 268 | + if (!blob) | ||
| 269 | + return GRUB_ERR_FILE_NOT_FOUND; | ||
| 270 | + | ||
| 271 | + fw_fdt = blob; | ||
| 272 | + | ||
| 273 | + return GRUB_ERR_NONE; | ||
| 274 | +} | ||
| 275 | + | ||
| 276 | +static grub_command_t cmd_devicetree; | ||
| 277 | + | ||
| 278 | +void | ||
| 279 | +grub_efi_linux_arch_register_commands (void) | ||
| 280 | +{ | ||
| 281 | + cmd_devicetree = | ||
| 282 | + grub_register_command ("devicetree", grub_cmd_devicetree, 0, | ||
| 283 | + N_("Load DTB file.")); | ||
| 284 | +} | ||
| 285 | + | ||
| 286 | +void | ||
| 287 | +grub_efi_linux_arch_unregister_commands (void) | ||
| 288 | +{ | ||
| 289 | + grub_unregister_command (cmd_devicetree); | ||
| 290 | +} | ||
| 291 | diff --git a/grub-core/loader/arm64/linuxefi.c b/grub-core/loader/arm64/linuxefi.c | ||
| 292 | new file mode 100644 | ||
| 293 | index 0000000..71d11f4 | ||
| 294 | --- /dev/null | ||
| 295 | +++ b/grub-core/loader/arm64/linuxefi.c | ||
| 296 | @@ -0,0 +1,279 @@ | ||
| 297 | +/* | ||
| 298 | + * GRUB -- GRand Unified Bootloader | ||
| 299 | + * Copyright (C) 2013 Free Software Foundation, Inc. | ||
| 300 | + * | ||
| 301 | + * GRUB is free software: you can redistribute it and/or modify | ||
| 302 | + * it under the terms of the GNU General Public License as published by | ||
| 303 | + * the Free Software Foundation, either version 3 of the License, or | ||
| 304 | + * (at your option) any later version. | ||
| 305 | + * | ||
| 306 | + * GRUB is distributed in the hope that it will be useful, | ||
| 307 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 308 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 309 | + * GNU General Public License for more details. | ||
| 310 | + * | ||
| 311 | + * You should have received a copy of the GNU General Public License | ||
| 312 | + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. | ||
| 313 | + */ | ||
| 314 | + | ||
| 315 | +#include <grub/loader.h> | ||
| 316 | +#include <grub/file.h> | ||
| 317 | +#include <grub/err.h> | ||
| 318 | +#include <grub/types.h> | ||
| 319 | +#include <grub/mm.h> | ||
| 320 | +#include <grub/cpu/linux.h> | ||
| 321 | +#include <grub/command.h> | ||
| 322 | +#include <grub/i18n.h> | ||
| 323 | +#include <grub/lib/cmdline.h> | ||
| 324 | +#include <grub/efi/efi.h> | ||
| 325 | +#include <grub/efi/pe32.h> | ||
| 326 | + | ||
| 327 | +GRUB_MOD_LICENSE ("GPLv3+"); | ||
| 328 | + | ||
| 329 | +static grub_dl_t my_mod; | ||
| 330 | +static int loaded; | ||
| 331 | +static void *kernel_mem; | ||
| 332 | +static grub_uint64_t kernel_size; | ||
| 333 | +static void *initrd_mem; | ||
| 334 | +static grub_uint32_t initrd_size; | ||
| 335 | +static char *linux_cmdline; | ||
| 336 | + | ||
| 337 | +static grub_uint32_t cmdline_size; | ||
| 338 | + | ||
| 339 | +#define GRUB_EFI_PAGE_SHIFT 12 | ||
| 340 | +#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> GRUB_EFI_PAGE_SHIFT) | ||
| 341 | + | ||
| 342 | +typedef void (* handover_func) (grub_efi_handle_t, grub_efi_system_table_t *, void *); | ||
| 343 | + | ||
| 344 | +static grub_err_t | ||
| 345 | +grub_linuxefi_boot (void) | ||
| 346 | +{ | ||
| 347 | + handover_func hf; | ||
| 348 | + struct linux_kernel_header *lh = kernel_mem; | ||
| 349 | + struct grub_pe32_optional_header *oh; | ||
| 350 | + grub_err_t retval; | ||
| 351 | + | ||
| 352 | + retval = grub_linux_finalize_params(); | ||
| 353 | + if (retval != GRUB_ERR_NONE) | ||
| 354 | + return retval; | ||
| 355 | + | ||
| 356 | + grub_printf ("PE/COFF header @ %08x\n", lh->hdr_offset); | ||
| 357 | + oh = (void *) ((grub_addr_t) kernel_mem + sizeof ("PE\0") + lh->hdr_offset | ||
| 358 | + + sizeof (struct grub_pe32_coff_header)); | ||
| 359 | + | ||
| 360 | + grub_printf ("Entry point: 0x%08x\n", oh->entry_addr); | ||
| 361 | + hf = (handover_func) ((char *) kernel_mem + oh->entry_addr); | ||
| 362 | + grub_printf ("hf: %p\n", (void *) hf); | ||
| 363 | + grub_printf("grub_efi_image_handle: %p\n", grub_efi_image_handle); | ||
| 364 | + grub_printf("grub_efi_system_table: %p\n", grub_efi_system_table); | ||
| 365 | + | ||
| 366 | + hf (grub_efi_image_handle, grub_efi_system_table, grub_linux_get_params()); | ||
| 367 | + | ||
| 368 | + grub_printf("holy shit!\n"); | ||
| 369 | + | ||
| 370 | + /* Not reached */ | ||
| 371 | + return GRUB_ERR_NONE; | ||
| 372 | +} | ||
| 373 | + | ||
| 374 | +static grub_err_t | ||
| 375 | +grub_linuxefi_unload (void) | ||
| 376 | +{ | ||
| 377 | + grub_dl_unref (my_mod); | ||
| 378 | + loaded = 0; | ||
| 379 | + if (initrd_mem) | ||
| 380 | + grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, | ||
| 381 | + BYTES_TO_PAGES(initrd_size)); | ||
| 382 | + if (kernel_mem) | ||
| 383 | + grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, | ||
| 384 | + BYTES_TO_PAGES(kernel_size)); | ||
| 385 | + return GRUB_ERR_NONE; | ||
| 386 | +} | ||
| 387 | + | ||
| 388 | +static grub_err_t | ||
| 389 | +grub_cmd_initrdefi (grub_command_t cmd __attribute__ ((unused)), | ||
| 390 | + int argc, char *argv[]) | ||
| 391 | +{ | ||
| 392 | + grub_file_t *files = 0; | ||
| 393 | + int i, nfiles = 0; | ||
| 394 | + grub_size_t size = 0; | ||
| 395 | + grub_uint8_t *ptr; | ||
| 396 | + | ||
| 397 | + if (argc == 0) | ||
| 398 | + { | ||
| 399 | + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); | ||
| 400 | + goto fail; | ||
| 401 | + } | ||
| 402 | + | ||
| 403 | + if (!loaded) | ||
| 404 | + { | ||
| 405 | + grub_error (GRUB_ERR_BAD_ARGUMENT, | ||
| 406 | + N_("you need to load the kernel first")); | ||
| 407 | + goto fail; | ||
| 408 | + } | ||
| 409 | + | ||
| 410 | + files = grub_zalloc (argc * sizeof (files[0])); | ||
| 411 | + if (!files) | ||
| 412 | + goto fail; | ||
| 413 | + | ||
| 414 | + for (i = 0; i < argc; i++) | ||
| 415 | + { | ||
| 416 | + grub_file_filter_disable_compression (); | ||
| 417 | + files[i] = grub_file_open (argv[i]); | ||
| 418 | + if (! files[i]) | ||
| 419 | + goto fail; | ||
| 420 | + nfiles++; | ||
| 421 | + size += ALIGN_UP (grub_file_size (files[i]), 4); | ||
| 422 | + } | ||
| 423 | + | ||
| 424 | + initrd_mem = grub_efi_allocate_pages (0, BYTES_TO_PAGES(size)); | ||
| 425 | + | ||
| 426 | + if (!initrd_mem) | ||
| 427 | + { | ||
| 428 | + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd")); | ||
| 429 | + goto fail; | ||
| 430 | + } | ||
| 431 | + | ||
| 432 | + grub_linux_register_initrd (initrd_mem, size); | ||
| 433 | + | ||
| 434 | + ptr = initrd_mem; | ||
| 435 | + | ||
| 436 | + for (i = 0; i < nfiles; i++) | ||
| 437 | + { | ||
| 438 | + grub_ssize_t cursize = grub_file_size (files[i]); | ||
| 439 | + if (grub_file_read (files[i], ptr, cursize) != cursize) | ||
| 440 | + { | ||
| 441 | + if (!grub_errno) | ||
| 442 | + grub_error (GRUB_ERR_FILE_READ_ERROR, | ||
| 443 | + N_("premature end of file %s"), argv[i]); | ||
| 444 | + goto fail; | ||
| 445 | + } | ||
| 446 | + ptr += cursize; | ||
| 447 | + grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); | ||
| 448 | + ptr += ALIGN_UP_OVERHEAD (cursize, 4); | ||
| 449 | + } | ||
| 450 | + | ||
| 451 | + fail: | ||
| 452 | + for (i = 0; i < nfiles; i++) | ||
| 453 | + grub_file_close (files[i]); | ||
| 454 | + grub_free (files); | ||
| 455 | + | ||
| 456 | + if (initrd_mem && grub_errno) | ||
| 457 | + grub_efi_free_pages((grub_efi_physical_address_t) initrd_mem, | ||
| 458 | + BYTES_TO_PAGES(size)); | ||
| 459 | + | ||
| 460 | + return grub_errno; | ||
| 461 | +} | ||
| 462 | + | ||
| 463 | +static grub_err_t | ||
| 464 | +grub_cmd_linuxefi (grub_command_t cmd __attribute__ ((unused)), | ||
| 465 | + int argc, char *argv[]) | ||
| 466 | +{ | ||
| 467 | + grub_file_t file = 0; | ||
| 468 | + struct linux_kernel_header *lh; | ||
| 469 | + grub_ssize_t filelen; | ||
| 470 | + | ||
| 471 | + grub_dl_ref (my_mod); | ||
| 472 | + | ||
| 473 | + if (argc == 0) | ||
| 474 | + { | ||
| 475 | + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); | ||
| 476 | + goto fail; | ||
| 477 | + } | ||
| 478 | + | ||
| 479 | + file = grub_file_open (argv[0]); | ||
| 480 | + if (! file) | ||
| 481 | + goto fail; | ||
| 482 | + | ||
| 483 | + filelen = grub_file_size (file); | ||
| 484 | + | ||
| 485 | + grub_printf ("kernel file size: %lld\n", (long long) filelen); | ||
| 486 | + kernel_mem = grub_efi_allocate_pages (0, BYTES_TO_PAGES(filelen)); | ||
| 487 | + grub_printf ("kernel numpages: %lld\n", (long long) BYTES_TO_PAGES(filelen)); | ||
| 488 | + if (!kernel_mem) | ||
| 489 | + { | ||
| 490 | + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); | ||
| 491 | + goto fail; | ||
| 492 | + } | ||
| 493 | + | ||
| 494 | + if (grub_file_read (file, kernel_mem, filelen) != filelen) | ||
| 495 | + { | ||
| 496 | + grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), | ||
| 497 | + argv[0]); | ||
| 498 | + goto fail; | ||
| 499 | + } | ||
| 500 | + | ||
| 501 | + lh = (void *) kernel_mem; | ||
| 502 | + grub_dprintf ("linux", "kernel_mem @ %p\n", kernel_mem); | ||
| 503 | + grub_dprintf ("linux", "code0: 0x%08x\n", lh->code0); | ||
| 504 | + grub_dprintf ("linux", "code1: 0x%08x\n", lh->code1); | ||
| 505 | + grub_dprintf ("linux", "text_offset: 0x%016llx\n", | ||
| 506 | + (long long unsigned) lh->text_offset); | ||
| 507 | + grub_dprintf ("linux", "magic: 0x%08x\n", lh->magic); | ||
| 508 | + grub_dprintf ("linux", "hdr_offset: 0x%08llx\n", | ||
| 509 | + (long long unsigned) lh->hdr_offset); | ||
| 510 | + | ||
| 511 | + if (grub_linux_init_params() != GRUB_ERR_NONE) | ||
| 512 | + { | ||
| 513 | + grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); | ||
| 514 | + goto fail; | ||
| 515 | + } | ||
| 516 | + | ||
| 517 | + cmdline_size = grub_loader_cmdline_size (argc, argv); | ||
| 518 | + | ||
| 519 | + linux_cmdline = grub_malloc(cmdline_size + sizeof (LINUX_IMAGE)); | ||
| 520 | + if (!linux_cmdline) | ||
| 521 | + grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate command line"); | ||
| 522 | + grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); | ||
| 523 | + grub_create_loader_cmdline (argc, argv, | ||
| 524 | + linux_cmdline + sizeof (LINUX_IMAGE) - 1, | ||
| 525 | + cmdline_size); | ||
| 526 | + | ||
| 527 | + grub_linux_register_cmdline (linux_cmdline); | ||
| 528 | + | ||
| 529 | + if (grub_errno == GRUB_ERR_NONE) | ||
| 530 | + { | ||
| 531 | + grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); | ||
| 532 | + loaded = 1; | ||
| 533 | + } | ||
| 534 | + | ||
| 535 | + fail: | ||
| 536 | + | ||
| 537 | + if (file) | ||
| 538 | + grub_file_close (file); | ||
| 539 | + | ||
| 540 | + if (grub_errno != GRUB_ERR_NONE) | ||
| 541 | + { | ||
| 542 | + grub_dl_unref (my_mod); | ||
| 543 | + loaded = 0; | ||
| 544 | + } | ||
| 545 | + | ||
| 546 | + if (linux_cmdline && !loaded) | ||
| 547 | + grub_efi_free_pages ((grub_efi_physical_address_t) linux_cmdline, | ||
| 548 | + BYTES_TO_PAGES(cmdline_size)); | ||
| 549 | + | ||
| 550 | + if (kernel_mem && !loaded) | ||
| 551 | + grub_efi_free_pages ((grub_efi_physical_address_t) kernel_mem, | ||
| 552 | + BYTES_TO_PAGES(kernel_size)); | ||
| 553 | + | ||
| 554 | + return grub_errno; | ||
| 555 | +} | ||
| 556 | + | ||
| 557 | +static grub_command_t cmd_linuxefi, cmd_initrdefi; | ||
| 558 | + | ||
| 559 | +GRUB_MOD_INIT(linuxefi) | ||
| 560 | +{ | ||
| 561 | + cmd_linuxefi = | ||
| 562 | + grub_register_command ("linuxefi", grub_cmd_linuxefi, 0, N_("Load Linux.")); | ||
| 563 | + cmd_initrdefi = | ||
| 564 | + grub_register_command ("initrdefi", grub_cmd_initrdefi, | ||
| 565 | + 0, N_("Load initrd.")); | ||
| 566 | + grub_efi_linux_arch_register_commands(); | ||
| 567 | + my_mod = mod; | ||
| 568 | +} | ||
| 569 | + | ||
| 570 | +GRUB_MOD_FINI(linuxefi) | ||
| 571 | +{ | ||
| 572 | + grub_unregister_command (cmd_linuxefi); | ||
| 573 | + grub_unregister_command (cmd_initrdefi); | ||
| 574 | + grub_efi_linux_arch_unregister_commands(); | ||
| 575 | +} | ||
| 576 | diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h | ||
| 577 | new file mode 100644 | ||
| 578 | index 0000000..9529bc3 | ||
| 579 | --- /dev/null | ||
| 580 | +++ b/include/grub/arm64/linux.h | ||
| 581 | @@ -0,0 +1,54 @@ | ||
| 582 | +/* | ||
| 583 | + * GRUB -- GRand Unified Bootloader | ||
| 584 | + * Copyright (C) 2013 Free Software Foundation, Inc. | ||
| 585 | + * | ||
| 586 | + * GRUB is free software: you can redistribute it and/or modify | ||
| 587 | + * it under the terms of the GNU General Public License as published by | ||
| 588 | + * the Free Software Foundation, either version 3 of the License, or | ||
| 589 | + * (at your option) any later version. | ||
| 590 | + * | ||
| 591 | + * GRUB is distributed in the hope that it will be useful, | ||
| 592 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 593 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 594 | + * GNU General Public License for more details. | ||
| 595 | + * | ||
| 596 | + * You should have received a copy of the GNU General Public License | ||
| 597 | + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. | ||
| 598 | + */ | ||
| 599 | + | ||
| 600 | +#ifndef GRUB_LINUX_CPU_HEADER | ||
| 601 | +#define GRUB_LINUX_CPU_HEADER 1 | ||
| 602 | + | ||
| 603 | +#include <grub/efi/efi.h> | ||
| 604 | + | ||
| 605 | +#define GRUB_EFI_KERNEL_STUB_ENTRY_OFFSET 0 | ||
| 606 | +#define GRUB_LINUX_MAX_LOAD_ADDR 0xffffffffffffULL | ||
| 607 | + | ||
| 608 | +#define GRUB_LINUX_MAGIC 0x644d5241 /* 'ARM\x64' */ | ||
| 609 | + | ||
| 610 | +/* From linux/Documentation/arm64/booting.txt */ | ||
| 611 | +struct linux_kernel_header | ||
| 612 | +{ | ||
| 613 | + grub_uint32_t code0; /* Executable code */ | ||
| 614 | + grub_uint32_t code1; /* Executable code */ | ||
| 615 | + grub_uint64_t text_offset; /* Image load offset */ | ||
| 616 | + grub_uint64_t res0; /* reserved */ | ||
| 617 | + grub_uint64_t res1; /* reserved */ | ||
| 618 | + grub_uint64_t res2; /* reserved */ | ||
| 619 | + grub_uint64_t res3; /* reserved */ | ||
| 620 | + grub_uint64_t res4; /* reserved */ | ||
| 621 | + grub_uint32_t magic; /* Magic number, little endian, "ARM\x64" */ | ||
| 622 | + grub_uint32_t hdr_offset; /* Offset of PE/COFF header */ | ||
| 623 | +}; | ||
| 624 | + | ||
| 625 | +#define grub_linux_get_params() NULL | ||
| 626 | +extern grub_err_t grub_linux_init_params (void); | ||
| 627 | +extern grub_err_t grub_linux_finalize_params (void); | ||
| 628 | +extern grub_err_t grub_linux_check_kernel (struct linux_kernel_header *lh); | ||
| 629 | +extern grub_err_t grub_linux_register_cmdline (void * addr); | ||
| 630 | +extern grub_err_t grub_linux_register_initrd (void * addr, grub_size_t size); | ||
| 631 | + | ||
| 632 | +extern void grub_efi_linux_arch_register_commands (void); | ||
| 633 | +extern void grub_efi_linux_arch_unregister_commands (void); | ||
| 634 | + | ||
| 635 | +#endif /* ! GRUB_LINUX_CPU_HEADER */ | ||
| 636 | diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h | ||
| 637 | index 3af0911..055b01d 100644 | ||
| 638 | --- a/include/grub/efi/api.h | ||
| 639 | +++ b/include/grub/efi/api.h | ||
| 640 | @@ -276,6 +276,10 @@ | ||
| 641 | { 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 } \ | ||
| 642 | } | ||
| 643 | |||
| 644 | +#define GRUB_EFI_DEVICE_TREE_GUID \ | ||
| 645 | + { 0xb1b621d5, 0xf19c, 0x41a5, \ | ||
| 646 | + { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } \ | ||
| 647 | + } | ||
| 648 | struct grub_efi_sal_system_table | ||
| 649 | { | ||
| 650 | grub_uint32_t signature; | ||
| 651 | -- | ||
| 652 | 1.8.4.2 | ||
| 653 | |||
diff --git a/meta/recipes-bsp/grub/grub-2.00/40_custom b/meta/recipes-bsp/grub/grub/40_custom index f891b02779..f891b02779 100755 --- a/meta/recipes-bsp/grub/grub-2.00/40_custom +++ b/meta/recipes-bsp/grub/grub/40_custom | |||
diff --git a/meta/recipes-bsp/grub/grub_git.bb b/meta/recipes-bsp/grub/grub_git.bb new file mode 100644 index 0000000000..ca636f32ce --- /dev/null +++ b/meta/recipes-bsp/grub/grub_git.bb | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | SUMMARY = "GRUB2 is the next-generation GRand Unified Bootloader" | ||
| 2 | |||
| 3 | DESCRIPTION = "GRUB2 is the next generaion of a GPLed bootloader \ | ||
| 4 | intended to unify bootloading across x86 operating systems. In \ | ||
| 5 | addition to loading the Linux kernel, it implements the Multiboot \ | ||
| 6 | standard, which allows for flexible loading of multiple boot images." | ||
| 7 | |||
| 8 | HOMEPAGE = "http://www.gnu.org/software/grub/" | ||
| 9 | SECTION = "bootloaders" | ||
| 10 | |||
| 11 | LICENSE = "GPLv3" | ||
| 12 | LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504" | ||
| 13 | |||
| 14 | DEPENDS = "autogen-native flex-native bison-native xz freetype" | ||
| 15 | |||
| 16 | DEFAULT_PREFERENCE = "-1" | ||
| 17 | DEFAULT_PREFERENCE_arm = "1" | ||
| 18 | |||
| 19 | PV = "2.00+${SRCPV}" | ||
| 20 | SRCREV = "3bc1b2daabb9b07a9c08bca386005d96f07147fe" | ||
| 21 | SRC_URI = "git://git.savannah.gnu.org/grub.git \ | ||
| 22 | file://0001-fdt-add-grub_fdt_create_empty_tree-function.patch \ | ||
| 23 | file://0002-arm64-add-EFI-Linux-loader.patch \ | ||
| 24 | file://40_custom \ | ||
| 25 | " | ||
| 26 | |||
| 27 | S = "${WORKDIR}/git" | ||
| 28 | |||
| 29 | COMPATIBLE_HOST = '(x86_64.*|i.86.*|arm.*|aarch64.*)-(linux.*|freebsd.*)' | ||
| 30 | |||
| 31 | inherit autotools | ||
| 32 | inherit gettext | ||
| 33 | |||
| 34 | PACKAGECONFIG ??= "" | ||
| 35 | PACKAGECONFIG[grub-mount] = "--enable-grub-mount,--disable-grub-mount,fuse" | ||
| 36 | |||
| 37 | # configure.ac has code to set this automagically from the target tuple | ||
| 38 | # but the OE freeform one (core2-foo-bar-linux) don't work with that. | ||
| 39 | |||
| 40 | GRUBPLATFORM_arm = "uboot" | ||
| 41 | GRUBPLATFORM_aarch64 = "efi" | ||
| 42 | GRUBPLATFORM ??= "pc" | ||
| 43 | |||
| 44 | EXTRA_OECONF = "--with-platform=${GRUBPLATFORM} --disable-grub-mkfont --program-prefix="" \ | ||
| 45 | --enable-liblzma=no --enable-device-mapper=no --enable-libzfs=no" | ||
| 46 | |||
| 47 | do_configure_prepend() { | ||
| 48 | ( cd ${S} | ||
| 49 | ${S}/autogen.sh ) | ||
| 50 | } | ||
| 51 | |||
| 52 | do_install_append () { | ||
| 53 | install -d ${D}${sysconfdir}/grub.d | ||
| 54 | install -m 0755 ${WORKDIR}/40_custom ${D}${sysconfdir}/grub.d/40_custom | ||
| 55 | } | ||
| 56 | |||
| 57 | RDEPENDS_${PN} = "diffutils freetype" | ||
| 58 | FILES_${PN}-dbg += "${libdir}/${BPN}/*/.debug" | ||
| 59 | |||
| 60 | INSANE_SKIP_${PN} = "arch" | ||
| 61 | INSANE_SKIP_${PN}-dbg = "arch" | ||
