From a45337b5d7bf769b9e1533b349ed597932b90126 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 17 Oct 2009 12:18:39 +0200 Subject: [PATCH] first linux boot --- conf/mips.rmk | 6 ++++++ lib/mips/relocator.c | 8 +++++--- lib/mips/relocator_asm.S | 4 ++++ loader/mips/linux.c | 20 +++++--------------- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/conf/mips.rmk b/conf/mips.rmk index 46b74d68f..9920f6878 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -147,4 +147,10 @@ relocator_mod_CFLAGS = $(COMMON_CFLAGS) relocator_mod_ASFLAGS = $(COMMON_ASFLAGS) 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 diff --git a/lib/mips/relocator.c b/lib/mips/relocator.c index 91e66893a..cc9d23f39 100644 --- a/lib/mips/relocator.c +++ b/lib/mips/relocator.c @@ -53,7 +53,7 @@ write_reg (int regn, grub_uint32_t val, void **target) *target = ((grub_uint32_t *) *target) + 1; /* addiu $r, $r, val. */ *(grub_uint32_t *) *target = (((0x2400 | regn << 5 | regn) << 16) - | ((val + 0x8000) >> 16)); + | (val & 0xffff)); *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); grub_memcpy (ptr, &grub_relocator32_backward_start, RELOCATOR_SRC_SIZEOF (backward)); + ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (backward); for (i = 1; i < 32; i++) write_reg (i, state.gpr[i], &ptr); write_jump (state.jumpreg, &ptr); - ((void (*) ())ptr0) (); + ((void (*) ()) ptr0) (); } static void @@ -93,10 +94,11 @@ write_call_relocator_fw (void *ptr0, void *src, grub_uint32_t dest, write_reg (4, size, &ptr); grub_memcpy (ptr, &grub_relocator32_forward_start, RELOCATOR_SRC_SIZEOF (forward)); + ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (forward); for (i = 1; i < 32; i++) write_reg (i, state.gpr[i], &ptr); write_jump (state.jumpreg, &ptr); - ((void (*) ())ptr0) (); + ((void (*) ()) ptr0) (); } #include "../relocator.c" diff --git a/lib/mips/relocator_asm.S b/lib/mips/relocator_asm.S index 24541e2d0..8dea8a4e3 100644 --- a/lib/mips/relocator_asm.S +++ b/lib/mips/relocator_asm.S @@ -30,6 +30,8 @@ VARIABLE (grub_relocator32_forward_start) copycont1: lb $5,0($2) sb $5,0($3) + addiu $2, $2, 0x1 + addiu $3, $3, 0x1 addiu $4, $4, 0xffff subu $5,$4,$0 bne $5, $0, copycont1 @@ -44,6 +46,8 @@ VARIABLE (grub_relocator32_backward_start) copycont2: lb $5,0($2) sb $5,0($3) + addiu $2, $2, 0xffff + addiu $3, $3, 0xffff addiu $4, 0xffff subu $5,$4,$0 bne $5, $0, copycont2 diff --git a/loader/mips/linux.c b/loader/mips/linux.c index 6b94304a5..03e489bf7 100644 --- a/loader/mips/linux.c +++ b/loader/mips/linux.c @@ -45,7 +45,6 @@ static grub_addr_t target_addr, entry_addr, initrd_addr, args_addr; static grub_err_t grub_linux_boot (void) { - grub_ssize_t actual; struct grub_relocator32_state state; /* Boot the kernel. */ @@ -81,7 +80,6 @@ static grub_err_t grub_linux_load32 (grub_elf_t elf, char *args) { Elf32_Addr base; - int found_addr = 0; int argsoff; /* 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. * 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 grub_elf32_load (elf, offset_phdr, 0, 0); } static grub_err_t -grub_linux_load64 (grub_elf_t elf) +grub_linux_load64 (grub_elf_t elf, char *args) { Elf64_Addr base; - int found_addr = 0; int argsoff; /* Linux's entry point incorrectly contains a virtual address. */ @@ -160,7 +157,7 @@ grub_linux_load64 (grub_elf_t elf) *do_load = 1; /* Linux's program headers incorrectly contain virtual addresses. * 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 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_ssize_t size; grub_addr_t addr; - int found_addr = 0; if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified"); - goto fail; - } + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified"); if (!loaded) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); - goto fail; - } + return grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); file = grub_file_open (argv[0]); if (! file)