make linux loader work on qemu-mips
This commit is contained in:
parent
a228ec103a
commit
dc16af0369
1 changed files with 67 additions and 1 deletions
|
@ -27,6 +27,7 @@
|
||||||
#include <grub/mips/relocator.h>
|
#include <grub/mips/relocator.h>
|
||||||
#include <grub/memory.h>
|
#include <grub/memory.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/lib/cmdline.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -53,12 +54,16 @@ static grub_size_t linux_size;
|
||||||
static struct grub_relocator *relocator;
|
static struct grub_relocator *relocator;
|
||||||
static grub_uint8_t *playground;
|
static grub_uint8_t *playground;
|
||||||
static grub_addr_t target_addr, entry_addr;
|
static grub_addr_t target_addr, entry_addr;
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
|
static char *params;
|
||||||
|
#else
|
||||||
static int linux_argc;
|
static int linux_argc;
|
||||||
static grub_off_t argv_off;
|
static grub_off_t argv_off;
|
||||||
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
static grub_off_t envp_off;
|
static grub_off_t envp_off;
|
||||||
#endif
|
#endif
|
||||||
static grub_off_t rd_addr_arg_off, rd_size_arg_off;
|
static grub_off_t rd_addr_arg_off, rd_size_arg_off;
|
||||||
|
#endif
|
||||||
static int initrd_loaded = 0;
|
static int initrd_loaded = 0;
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
@ -66,8 +71,26 @@ grub_linux_boot (void)
|
||||||
{
|
{
|
||||||
struct grub_relocator32_state state;
|
struct grub_relocator32_state state;
|
||||||
|
|
||||||
|
grub_memset (&state, 0, sizeof (state));
|
||||||
|
|
||||||
/* Boot the kernel. */
|
/* Boot the kernel. */
|
||||||
state.gpr[1] = entry_addr;
|
state.gpr[1] = entry_addr;
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
grub_relocator_chunk_t ch;
|
||||||
|
|
||||||
|
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||||
|
((16 << 20) - 256),
|
||||||
|
grub_strlen (params) + 1);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
grub_strcpy (get_virtual_current_address (ch), params);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
state.gpr[4] = linux_argc;
|
state.gpr[4] = linux_argc;
|
||||||
state.gpr[5] = target_addr + argv_off;
|
state.gpr[5] = target_addr + argv_off;
|
||||||
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
|
@ -76,6 +99,7 @@ grub_linux_boot (void)
|
||||||
state.gpr[6] = 0;
|
state.gpr[6] = 0;
|
||||||
#endif
|
#endif
|
||||||
state.gpr[7] = 0;
|
state.gpr[7] = 0;
|
||||||
|
#endif
|
||||||
state.jumpreg = 1;
|
state.jumpreg = 1;
|
||||||
grub_relocator32_boot (relocator, state);
|
grub_relocator32_boot (relocator, state);
|
||||||
|
|
||||||
|
@ -88,6 +112,11 @@ grub_linux_unload (void)
|
||||||
grub_relocator_unload (relocator);
|
grub_relocator_unload (relocator);
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
|
grub_free (params);
|
||||||
|
params = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
loaded = 0;
|
loaded = 0;
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
@ -207,11 +236,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
{
|
{
|
||||||
grub_elf_t elf = 0;
|
grub_elf_t elf = 0;
|
||||||
int i;
|
|
||||||
int size;
|
int size;
|
||||||
void *extra = NULL;
|
void *extra = NULL;
|
||||||
|
#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
|
int i;
|
||||||
grub_uint32_t *linux_argv;
|
grub_uint32_t *linux_argv;
|
||||||
char *linux_args;
|
char *linux_args;
|
||||||
|
#endif
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
char *linux_envs;
|
char *linux_envs;
|
||||||
|
@ -236,6 +267,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_loader_unset ();
|
grub_loader_unset ();
|
||||||
loaded = 0;
|
loaded = 0;
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
|
size = 0;
|
||||||
|
#else
|
||||||
/* For arguments. */
|
/* For arguments. */
|
||||||
linux_argc = argc;
|
linux_argc = argc;
|
||||||
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
#ifdef GRUB_MACHINE_MIPS_LOONGSON
|
||||||
|
@ -268,6 +302,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
+ ALIGN_UP (sizeof ("highmemsize=XXXXXXXXXXXXXXXXXXXX"), 4)
|
+ ALIGN_UP (sizeof ("highmemsize=XXXXXXXXXXXXXXXXXXXX"), 4)
|
||||||
+ ALIGN_UP (sizeof ("busclock=XXXXXXXXXX"), 4)
|
+ ALIGN_UP (sizeof ("busclock=XXXXXXXXXX"), 4)
|
||||||
+ ALIGN_UP (sizeof ("cpuclock=XXXXXXXXXX"), 4);
|
+ ALIGN_UP (sizeof ("cpuclock=XXXXXXXXXX"), 4);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (grub_elf_is_elf32 (elf))
|
if (grub_elf_is_elf32 (elf))
|
||||||
err = grub_linux_load32 (elf, &extra, size);
|
err = grub_linux_load32 (elf, &extra, size);
|
||||||
|
@ -282,6 +317,20 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
|
/* Create kernel command line. */
|
||||||
|
size = grub_loader_cmdline_size(argc, argv);
|
||||||
|
params = grub_malloc (size + sizeof (LINUX_IMAGE));
|
||||||
|
if (! params)
|
||||||
|
{
|
||||||
|
grub_linux_unload ();
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_memcpy (params, LINUX_IMAGE, sizeof (LINUX_IMAGE));
|
||||||
|
grub_create_loader_cmdline (argc, argv, params + sizeof (LINUX_IMAGE) - 1,
|
||||||
|
size);
|
||||||
|
#else
|
||||||
linux_argv = extra;
|
linux_argv = extra;
|
||||||
argv_off = (grub_uint8_t *) linux_argv - (grub_uint8_t *) playground;
|
argv_off = (grub_uint8_t *) linux_argv - (grub_uint8_t *) playground;
|
||||||
extra = linux_argv + (linux_argc + 1 + 2);
|
extra = linux_argv + (linux_argc + 1 + 2);
|
||||||
|
@ -362,6 +411,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
|
linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
|
||||||
|
|
||||||
linux_envp[4] = 0;
|
linux_envp[4] = 0;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
|
grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
|
||||||
|
@ -425,6 +475,21 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
tmp = grub_xasprintf ("%s rd_start=0x%" PRIxGRUB_ADDR
|
||||||
|
" rd_size=0x%" PRIxGRUB_ADDR, params,
|
||||||
|
initrd_dest, size);
|
||||||
|
if (!tmp)
|
||||||
|
{
|
||||||
|
grub_file_close (file);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
grub_free (params);
|
||||||
|
params = tmp;
|
||||||
|
}
|
||||||
|
#else
|
||||||
grub_snprintf ((char *) playground + rd_addr_arg_off,
|
grub_snprintf ((char *) playground + rd_addr_arg_off,
|
||||||
sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), "rd_start=0x%llx",
|
sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), "rd_start=0x%llx",
|
||||||
(unsigned long long) initrd_dest);
|
(unsigned long long) initrd_dest);
|
||||||
|
@ -438,6 +503,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
((grub_uint32_t *) (playground + argv_off))[linux_argc]
|
((grub_uint32_t *) (playground + argv_off))[linux_argc]
|
||||||
= target_addr + rd_size_arg_off;
|
= target_addr + rd_size_arg_off;
|
||||||
linux_argc++;
|
linux_argc++;
|
||||||
|
#endif
|
||||||
|
|
||||||
initrd_loaded = 1;
|
initrd_loaded = 1;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue