first linux boot
This commit is contained in:
parent
ea818634b5
commit
a45337b5d7
4 changed files with 20 additions and 18 deletions
|
@ -147,4 +147,10 @@ relocator_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||||
relocator_mod_ASFLAGS = $(COMMON_ASFLAGS)
|
relocator_mod_ASFLAGS = $(COMMON_ASFLAGS)
|
||||||
relocator_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
relocator_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
||||||
|
|
||||||
|
pkglib_MODULES += linux.mod
|
||||||
|
linux_mod_SOURCES = loader/$(target_cpu)/linux.c
|
||||||
|
linux_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||||
|
linux_mod_ASFLAGS = $(COMMON_ASFLAGS)
|
||||||
|
linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
||||||
|
|
||||||
include $(srcdir)/conf/common.mk
|
include $(srcdir)/conf/common.mk
|
||||||
|
|
|
@ -53,7 +53,7 @@ write_reg (int regn, grub_uint32_t val, void **target)
|
||||||
*target = ((grub_uint32_t *) *target) + 1;
|
*target = ((grub_uint32_t *) *target) + 1;
|
||||||
/* addiu $r, $r, val. */
|
/* addiu $r, $r, val. */
|
||||||
*(grub_uint32_t *) *target = (((0x2400 | regn << 5 | regn) << 16)
|
*(grub_uint32_t *) *target = (((0x2400 | regn << 5 | regn) << 16)
|
||||||
| ((val + 0x8000) >> 16));
|
| (val & 0xffff));
|
||||||
*target = ((grub_uint32_t *) *target) + 1;
|
*target = ((grub_uint32_t *) *target) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,10 +76,11 @@ write_call_relocator_bw (void *ptr0, void *src, grub_uint32_t dest,
|
||||||
write_reg (4, size, &ptr);
|
write_reg (4, size, &ptr);
|
||||||
grub_memcpy (ptr, &grub_relocator32_backward_start,
|
grub_memcpy (ptr, &grub_relocator32_backward_start,
|
||||||
RELOCATOR_SRC_SIZEOF (backward));
|
RELOCATOR_SRC_SIZEOF (backward));
|
||||||
|
ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (backward);
|
||||||
for (i = 1; i < 32; i++)
|
for (i = 1; i < 32; i++)
|
||||||
write_reg (i, state.gpr[i], &ptr);
|
write_reg (i, state.gpr[i], &ptr);
|
||||||
write_jump (state.jumpreg, &ptr);
|
write_jump (state.jumpreg, &ptr);
|
||||||
((void (*) ())ptr0) ();
|
((void (*) ()) ptr0) ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -93,10 +94,11 @@ write_call_relocator_fw (void *ptr0, void *src, grub_uint32_t dest,
|
||||||
write_reg (4, size, &ptr);
|
write_reg (4, size, &ptr);
|
||||||
grub_memcpy (ptr, &grub_relocator32_forward_start,
|
grub_memcpy (ptr, &grub_relocator32_forward_start,
|
||||||
RELOCATOR_SRC_SIZEOF (forward));
|
RELOCATOR_SRC_SIZEOF (forward));
|
||||||
|
ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (forward);
|
||||||
for (i = 1; i < 32; i++)
|
for (i = 1; i < 32; i++)
|
||||||
write_reg (i, state.gpr[i], &ptr);
|
write_reg (i, state.gpr[i], &ptr);
|
||||||
write_jump (state.jumpreg, &ptr);
|
write_jump (state.jumpreg, &ptr);
|
||||||
((void (*) ())ptr0) ();
|
((void (*) ()) ptr0) ();
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "../relocator.c"
|
#include "../relocator.c"
|
||||||
|
|
|
@ -30,6 +30,8 @@ VARIABLE (grub_relocator32_forward_start)
|
||||||
copycont1:
|
copycont1:
|
||||||
lb $5,0($2)
|
lb $5,0($2)
|
||||||
sb $5,0($3)
|
sb $5,0($3)
|
||||||
|
addiu $2, $2, 0x1
|
||||||
|
addiu $3, $3, 0x1
|
||||||
addiu $4, $4, 0xffff
|
addiu $4, $4, 0xffff
|
||||||
subu $5,$4,$0
|
subu $5,$4,$0
|
||||||
bne $5, $0, copycont1
|
bne $5, $0, copycont1
|
||||||
|
@ -44,6 +46,8 @@ VARIABLE (grub_relocator32_backward_start)
|
||||||
copycont2:
|
copycont2:
|
||||||
lb $5,0($2)
|
lb $5,0($2)
|
||||||
sb $5,0($3)
|
sb $5,0($3)
|
||||||
|
addiu $2, $2, 0xffff
|
||||||
|
addiu $3, $3, 0xffff
|
||||||
addiu $4, 0xffff
|
addiu $4, 0xffff
|
||||||
subu $5,$4,$0
|
subu $5,$4,$0
|
||||||
bne $5, $0, copycont2
|
bne $5, $0, copycont2
|
||||||
|
|
|
@ -45,7 +45,6 @@ static grub_addr_t target_addr, entry_addr, initrd_addr, args_addr;
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_linux_boot (void)
|
grub_linux_boot (void)
|
||||||
{
|
{
|
||||||
grub_ssize_t actual;
|
|
||||||
struct grub_relocator32_state state;
|
struct grub_relocator32_state state;
|
||||||
|
|
||||||
/* Boot the kernel. */
|
/* Boot the kernel. */
|
||||||
|
@ -81,7 +80,6 @@ static grub_err_t
|
||||||
grub_linux_load32 (grub_elf_t elf, char *args)
|
grub_linux_load32 (grub_elf_t elf, char *args)
|
||||||
{
|
{
|
||||||
Elf32_Addr base;
|
Elf32_Addr base;
|
||||||
int found_addr = 0;
|
|
||||||
int argsoff;
|
int argsoff;
|
||||||
|
|
||||||
/* Linux's entry point incorrectly contains a virtual address. */
|
/* Linux's entry point incorrectly contains a virtual address. */
|
||||||
|
@ -116,17 +114,16 @@ grub_linux_load32 (grub_elf_t elf, char *args)
|
||||||
|
|
||||||
/* Linux's program headers incorrectly contain virtual addresses.
|
/* Linux's program headers incorrectly contain virtual addresses.
|
||||||
* Translate those to physical, and offset to the area we claimed. */
|
* Translate those to physical, and offset to the area we claimed. */
|
||||||
*addr = phdr->p_paddr - base + playground;
|
*addr = (grub_addr_t) (phdr->p_paddr - base + playground);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return grub_elf32_load (elf, offset_phdr, 0, 0);
|
return grub_elf32_load (elf, offset_phdr, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_linux_load64 (grub_elf_t elf)
|
grub_linux_load64 (grub_elf_t elf, char *args)
|
||||||
{
|
{
|
||||||
Elf64_Addr base;
|
Elf64_Addr base;
|
||||||
int found_addr = 0;
|
|
||||||
int argsoff;
|
int argsoff;
|
||||||
|
|
||||||
/* Linux's entry point incorrectly contains a virtual address. */
|
/* Linux's entry point incorrectly contains a virtual address. */
|
||||||
|
@ -160,7 +157,7 @@ grub_linux_load64 (grub_elf_t elf)
|
||||||
*do_load = 1;
|
*do_load = 1;
|
||||||
/* Linux's program headers incorrectly contain virtual addresses.
|
/* Linux's program headers incorrectly contain virtual addresses.
|
||||||
* Translate those to physical, and offset to the area we claimed. */
|
* Translate those to physical, and offset to the area we claimed. */
|
||||||
*addr = phdr->p_paddr - base + playground;
|
*addr = (grub_addr_t) (phdr->p_paddr - base + playground);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return grub_elf64_load (elf, offset_phdr, 0, 0);
|
return grub_elf64_load (elf, offset_phdr, 0, 0);
|
||||||
|
@ -254,19 +251,12 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_file_t file = 0;
|
grub_file_t file = 0;
|
||||||
grub_ssize_t size;
|
grub_ssize_t size;
|
||||||
grub_addr_t addr;
|
grub_addr_t addr;
|
||||||
int found_addr = 0;
|
|
||||||
|
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
{
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified");
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!loaded)
|
if (!loaded)
|
||||||
{
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first.");
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first.");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
file = grub_file_open (argv[0]);
|
file = grub_file_open (argv[0]);
|
||||||
if (! file)
|
if (! file)
|
||||||
|
|
Loading…
Add table
Reference in a new issue