arm64: Export useful functions from linux.c
Signed-off-by: Fu Wei <fu.wei@linaro.org>
This commit is contained in:
parent
cc699535e5
commit
f8451af825
5 changed files with 49 additions and 37 deletions
|
@ -759,7 +759,7 @@ def image(defn, platform):
|
||||||
if test x$(TARGET_APPLE_LINKER) = x1; then \
|
if test x$(TARGET_APPLE_LINKER) = x1; then \
|
||||||
$(MACHO2IMG) $< $@; \
|
$(MACHO2IMG) $< $@; \
|
||||||
else \
|
else \
|
||||||
$(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version $< $@; \
|
$(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version -R .hash -R .dynsym -R .dynstr -R .rel.text $< $@; \
|
||||||
fi
|
fi
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
|
|
@ -33,12 +33,6 @@
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
#define GRUB_EFI_PAGE_SHIFT 12
|
|
||||||
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> GRUB_EFI_PAGE_SHIFT)
|
|
||||||
#define GRUB_EFI_PE_MAGIC 0x5A4D
|
|
||||||
|
|
||||||
static grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
|
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
static grub_dl_t my_mod;
|
||||||
static int loaded;
|
static int loaded;
|
||||||
|
|
||||||
|
@ -58,6 +52,7 @@ static void *
|
||||||
get_firmware_fdt (void)
|
get_firmware_fdt (void)
|
||||||
{
|
{
|
||||||
grub_efi_configuration_table_t *tables;
|
grub_efi_configuration_table_t *tables;
|
||||||
|
grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
|
||||||
void *firmware_fdt = NULL;
|
void *firmware_fdt = NULL;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
@ -75,8 +70,8 @@ get_firmware_fdt (void)
|
||||||
return firmware_fdt;
|
return firmware_fdt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void *
|
||||||
get_fdt (void)
|
grub_linux_get_fdt (void)
|
||||||
{
|
{
|
||||||
void *raw_fdt;
|
void *raw_fdt;
|
||||||
grub_size_t size;
|
grub_size_t size;
|
||||||
|
@ -99,7 +94,7 @@ get_fdt (void)
|
||||||
grub_dprintf ("linux", "allocating %ld bytes for fdt\n", size);
|
grub_dprintf ("linux", "allocating %ld bytes for fdt\n", size);
|
||||||
fdt = grub_efi_allocate_pages (0, BYTES_TO_PAGES (size));
|
fdt = grub_efi_allocate_pages (0, BYTES_TO_PAGES (size));
|
||||||
if (!fdt)
|
if (!fdt)
|
||||||
return;
|
return NULL;
|
||||||
|
|
||||||
if (raw_fdt)
|
if (raw_fdt)
|
||||||
{
|
{
|
||||||
|
@ -110,10 +105,11 @@ get_fdt (void)
|
||||||
{
|
{
|
||||||
grub_fdt_create_empty_tree (fdt, size);
|
grub_fdt_create_empty_tree (fdt, size);
|
||||||
}
|
}
|
||||||
|
return fdt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
grub_err_t
|
||||||
check_kernel (struct grub_arm64_linux_kernel_header *lh)
|
grub_arm64_uefi_check_image (struct grub_arm64_linux_kernel_header * lh)
|
||||||
{
|
{
|
||||||
if (lh->magic != GRUB_ARM64_LINUX_MAGIC)
|
if (lh->magic != GRUB_ARM64_LINUX_MAGIC)
|
||||||
return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
|
return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
|
||||||
|
@ -131,14 +127,14 @@ check_kernel (struct grub_arm64_linux_kernel_header *lh)
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
finalize_params (void)
|
finalize_params_linux (void)
|
||||||
{
|
{
|
||||||
grub_efi_boot_services_t *b;
|
grub_efi_boot_services_t *b;
|
||||||
|
grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
|
||||||
grub_efi_status_t status;
|
grub_efi_status_t status;
|
||||||
int node, retval;
|
int node, retval;
|
||||||
|
|
||||||
get_fdt ();
|
if (!grub_linux_get_fdt ())
|
||||||
if (!fdt)
|
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
node = grub_fdt_find_subnode (fdt, 0, "chosen");
|
node = grub_fdt_find_subnode (fdt, 0, "chosen");
|
||||||
|
@ -240,21 +236,16 @@ out:
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
grub_err_t
|
||||||
grub_linux_boot (void)
|
grub_arm64_uefi_boot_image (grub_addr_t addr, grub_size_t size, char *args)
|
||||||
{
|
{
|
||||||
grub_efi_memory_mapped_device_path_t *mempath;
|
grub_efi_memory_mapped_device_path_t *mempath;
|
||||||
grub_efi_handle_t image_handle;
|
grub_efi_handle_t image_handle;
|
||||||
grub_efi_boot_services_t *b;
|
grub_efi_boot_services_t *b;
|
||||||
grub_efi_status_t status;
|
grub_efi_status_t status;
|
||||||
grub_err_t retval;
|
|
||||||
grub_efi_loaded_image_t *loaded_image;
|
grub_efi_loaded_image_t *loaded_image;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
retval = finalize_params();
|
|
||||||
if (retval != GRUB_ERR_NONE)
|
|
||||||
return retval;
|
|
||||||
|
|
||||||
mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t));
|
mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t));
|
||||||
if (!mempath)
|
if (!mempath)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
@ -263,8 +254,8 @@ grub_linux_boot (void)
|
||||||
mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE;
|
mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE;
|
||||||
mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath));
|
mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath));
|
||||||
mempath[0].memory_type = GRUB_EFI_LOADER_DATA;
|
mempath[0].memory_type = GRUB_EFI_LOADER_DATA;
|
||||||
mempath[0].start_address = (grub_addr_t) kernel_addr;
|
mempath[0].start_address = addr;
|
||||||
mempath[0].end_address = (grub_addr_t) kernel_addr + kernel_size;
|
mempath[0].end_address = addr + size;
|
||||||
|
|
||||||
mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
||||||
mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||||
|
@ -273,16 +264,16 @@ grub_linux_boot (void)
|
||||||
b = grub_efi_system_table->boot_services;
|
b = grub_efi_system_table->boot_services;
|
||||||
status = b->load_image (0, grub_efi_image_handle,
|
status = b->load_image (0, grub_efi_image_handle,
|
||||||
(grub_efi_device_path_t *) mempath,
|
(grub_efi_device_path_t *) mempath,
|
||||||
kernel_addr, kernel_size, &image_handle);
|
(void *) addr, size, &image_handle);
|
||||||
if (status != GRUB_EFI_SUCCESS)
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
return grub_error (GRUB_ERR_BAD_OS, "cannot load image");
|
return grub_error (GRUB_ERR_BAD_OS, "cannot load image");
|
||||||
|
|
||||||
grub_dprintf ("linux", "linux command line: '%s'\n", linux_args);
|
grub_dprintf ("linux", "linux command line: '%s'\n", args);
|
||||||
|
|
||||||
/* Convert command line to UCS-2 */
|
/* Convert command line to UCS-2 */
|
||||||
loaded_image = grub_efi_get_loaded_image (image_handle);
|
loaded_image = grub_efi_get_loaded_image (image_handle);
|
||||||
loaded_image->load_options_size = len =
|
loaded_image->load_options_size = len =
|
||||||
(grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t);
|
(grub_strlen (args) + 1) * sizeof (grub_efi_char16_t);
|
||||||
loaded_image->load_options =
|
loaded_image->load_options =
|
||||||
grub_efi_allocate_pages (0,
|
grub_efi_allocate_pages (0,
|
||||||
BYTES_TO_PAGES (loaded_image->load_options_size));
|
BYTES_TO_PAGES (loaded_image->load_options_size));
|
||||||
|
@ -291,9 +282,9 @@ grub_linux_boot (void)
|
||||||
|
|
||||||
loaded_image->load_options_size =
|
loaded_image->load_options_size =
|
||||||
2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
|
2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
|
||||||
(grub_uint8_t *) linux_args, len, NULL);
|
(grub_uint8_t *) args, len, NULL);
|
||||||
|
|
||||||
grub_dprintf("linux", "starting image %p\n", image_handle);
|
grub_dprintf ("linux", "starting image %p\n", image_handle);
|
||||||
status = b->start_image (image_handle, 0, NULL);
|
status = b->start_image (image_handle, 0, NULL);
|
||||||
|
|
||||||
/* When successful, not reached */
|
/* When successful, not reached */
|
||||||
|
@ -304,6 +295,16 @@ grub_linux_boot (void)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_linux_boot (void)
|
||||||
|
{
|
||||||
|
if (finalize_params_linux () != GRUB_ERR_NONE)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
return (grub_arm64_uefi_boot_image((grub_addr_t)kernel_addr,
|
||||||
|
kernel_size, linux_args));
|
||||||
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_linux_unload (void)
|
grub_linux_unload (void)
|
||||||
{
|
{
|
||||||
|
@ -400,7 +401,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
|
if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
if (check_kernel (&lh) != GRUB_ERR_NONE)
|
if (grub_arm64_uefi_check_image (&lh) != GRUB_ERR_NONE)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
grub_loader_unset();
|
grub_loader_unset();
|
||||||
|
|
|
@ -69,7 +69,6 @@ static grub_addr_t prot_mode_target;
|
||||||
static void *initrd_mem;
|
static void *initrd_mem;
|
||||||
static grub_addr_t initrd_mem_target;
|
static grub_addr_t initrd_mem_target;
|
||||||
static grub_size_t prot_init_space;
|
static grub_size_t prot_init_space;
|
||||||
static grub_uint32_t initrd_pages;
|
|
||||||
static struct grub_relocator *relocator = NULL;
|
static struct grub_relocator *relocator = NULL;
|
||||||
static void *efi_mmap_buf;
|
static void *efi_mmap_buf;
|
||||||
static grub_size_t maximal_cmdline_size;
|
static grub_size_t maximal_cmdline_size;
|
||||||
|
@ -1046,7 +1045,7 @@ static grub_err_t
|
||||||
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
{
|
{
|
||||||
grub_size_t size = 0;
|
grub_size_t size = 0, aligned_size = 0;
|
||||||
grub_addr_t addr_min, addr_max;
|
grub_addr_t addr_min, addr_max;
|
||||||
grub_addr_t addr;
|
grub_addr_t addr;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
@ -1068,8 +1067,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
size = grub_get_initrd_size (&initrd_ctx);
|
size = grub_get_initrd_size (&initrd_ctx);
|
||||||
|
aligned_size = ALIGN_UP (size, 4096);
|
||||||
initrd_pages = (page_align (size) >> 12);
|
|
||||||
|
|
||||||
/* Get the highest address available for the initrd. */
|
/* Get the highest address available for the initrd. */
|
||||||
if (grub_le_to_cpu16 (linux_params.version) >= 0x0203)
|
if (grub_le_to_cpu16 (linux_params.version) >= 0x0203)
|
||||||
|
@ -1097,7 +1095,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
addr_min = (grub_addr_t) prot_mode_target + prot_init_space;
|
addr_min = (grub_addr_t) prot_mode_target + prot_init_space;
|
||||||
|
|
||||||
/* Put the initrd as high as possible, 4KiB aligned. */
|
/* Put the initrd as high as possible, 4KiB aligned. */
|
||||||
addr = (addr_max - size) & ~0xFFF;
|
addr = (addr_max - aligned_size) & ~0xFFF;
|
||||||
|
|
||||||
if (addr < addr_min)
|
if (addr < addr_min)
|
||||||
{
|
{
|
||||||
|
@ -1108,7 +1106,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
{
|
{
|
||||||
grub_relocator_chunk_t ch;
|
grub_relocator_chunk_t ch;
|
||||||
err = grub_relocator_alloc_chunk_align (relocator, &ch,
|
err = grub_relocator_alloc_chunk_align (relocator, &ch,
|
||||||
addr_min, addr, size, 0x1000,
|
addr_min, addr, aligned_size,
|
||||||
|
0x1000,
|
||||||
GRUB_RELOCATOR_PREFERENCE_HIGH,
|
GRUB_RELOCATOR_PREFERENCE_HIGH,
|
||||||
1);
|
1);
|
||||||
if (err)
|
if (err)
|
||||||
|
|
|
@ -205,7 +205,8 @@ grub_initrd_init (int argc, char *argv[],
|
||||||
initrd_ctx->nfiles++;
|
initrd_ctx->nfiles++;
|
||||||
initrd_ctx->components[i].size
|
initrd_ctx->components[i].size
|
||||||
= grub_file_size (initrd_ctx->components[i].file);
|
= grub_file_size (initrd_ctx->components[i].file);
|
||||||
initrd_ctx->size += ALIGN_UP (initrd_ctx->components[i].size, 4);
|
if (argc != 1)
|
||||||
|
initrd_ctx->size += ALIGN_UP (initrd_ctx->components[i].size, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newc)
|
if (newc)
|
||||||
|
|
|
@ -23,6 +23,10 @@
|
||||||
|
|
||||||
#define GRUB_ARM64_LINUX_MAGIC 0x644d5241 /* 'ARM\x64' */
|
#define GRUB_ARM64_LINUX_MAGIC 0x644d5241 /* 'ARM\x64' */
|
||||||
|
|
||||||
|
#define GRUB_EFI_PAGE_SHIFT 12
|
||||||
|
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> GRUB_EFI_PAGE_SHIFT)
|
||||||
|
#define GRUB_EFI_PE_MAGIC 0x5A4D
|
||||||
|
|
||||||
/* From linux/Documentation/arm64/booting.txt */
|
/* From linux/Documentation/arm64/booting.txt */
|
||||||
struct grub_arm64_linux_kernel_header
|
struct grub_arm64_linux_kernel_header
|
||||||
{
|
{
|
||||||
|
@ -38,4 +42,11 @@ struct grub_arm64_linux_kernel_header
|
||||||
grub_uint32_t hdr_offset; /* Offset of PE/COFF header */
|
grub_uint32_t hdr_offset; /* Offset of PE/COFF header */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Declare the functions for getting dtb and checking/booting image */
|
||||||
|
void *grub_linux_get_fdt (void);
|
||||||
|
grub_err_t grub_arm64_uefi_check_image (struct grub_arm64_linux_kernel_header
|
||||||
|
*lh);
|
||||||
|
grub_err_t grub_arm64_uefi_boot_image (grub_addr_t addr, grub_size_t size,
|
||||||
|
char *args);
|
||||||
|
|
||||||
#endif /* ! GRUB_LINUX_CPU_HEADER */
|
#endif /* ! GRUB_LINUX_CPU_HEADER */
|
||||||
|
|
Loading…
Add table
Reference in a new issue