merge mainline into asprintf

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-01-20 07:36:17 +01:00
commit 2d49abe9e7
342 changed files with 14569 additions and 4699 deletions

View file

@ -1,7 +1,7 @@
/* device.c - device manager */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2002,2005,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -139,7 +139,7 @@ grub_device_iterate (int (*hook) (const char *name))
if (! partition_name)
return 1;
p = grub_malloc (sizeof (p->next));
p = grub_malloc (sizeof (*p));
if (!p)
{
grub_free (partition_name);

View file

@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2003,2004,2006,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2002,2003,2004,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -386,8 +386,6 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
char *tmp_buf;
unsigned real_offset;
grub_dprintf ("disk", "Reading `%s'...\n", disk->name);
/* First of all, check if the region is within the disk. */
if (grub_disk_adjust_range (disk, &sector, &offset, size) != GRUB_ERR_NONE)
{
@ -432,8 +430,9 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
else
{
/* Otherwise read data from the disk actually. */
if ((disk->dev->read) (disk, start_sector,
GRUB_DISK_CACHE_SIZE, tmp_buf)
if (start_sector + GRUB_DISK_CACHE_SIZE > disk->total_sectors
|| (disk->dev->read) (disk, start_sector,
GRUB_DISK_CACHE_SIZE, tmp_buf)
!= GRUB_ERR_NONE)
{
/* Uggh... Failed. Instead, just read necessary data. */

View file

@ -341,6 +341,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
switch (type)
{
case STT_NOTYPE:
case STT_OBJECT:
/* Resolve a global symbol. */
if (sym->st_name != 0 && sym->st_shndx == 0)
{
@ -350,15 +351,13 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
"the symbol `%s' not found", name);
}
else
sym->st_value = 0;
break;
case STT_OBJECT:
sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
sym->st_shndx);
if (bind != STB_LOCAL)
if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
return grub_errno;
{
sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
sym->st_shndx);
if (bind != STB_LOCAL)
if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
return grub_errno;
}
break;
case STT_FUNC:

View file

@ -1,7 +1,7 @@
/* efi.c - generic EFI support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View file

@ -81,6 +81,5 @@ void
grub_efi_fini (void)
{
grub_efidisk_fini ();
grub_efi_mm_fini ();
grub_console_fini ();
}

View file

@ -1,7 +1,7 @@
/* mm.c - generic EFI memory management */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
/* elf.c - load ELF files */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -172,7 +172,7 @@ grub_elf32_phdr_iterate (grub_elf_t elf,
/* Calculate the amount of memory spanned by the segments. */
grub_size_t
grub_elf32_size (grub_elf_t elf)
grub_elf32_size (grub_elf_t elf, Elf32_Addr *base)
{
Elf32_Addr segments_start = (Elf32_Addr) -1;
Elf32_Addr segments_end = 0;
@ -198,6 +198,9 @@ grub_elf32_size (grub_elf_t elf)
grub_elf32_phdr_iterate (elf, calcsize, 0);
if (base)
*base = 0;
if (nr_phdrs == 0)
{
grub_error (GRUB_ERR_BAD_OS, "no program headers present");
@ -211,10 +214,12 @@ grub_elf32_size (grub_elf_t elf)
return 0;
}
if (base)
*base = segments_start;
return segments_end - segments_start;
}
/* Load every loadable segment into memory specified by `_load_hook'. */
grub_err_t
grub_elf32_load (grub_elf_t _elf, grub_elf32_load_hook_t _load_hook,
@ -353,7 +358,7 @@ grub_elf64_phdr_iterate (grub_elf_t elf,
/* Calculate the amount of memory spanned by the segments. */
grub_size_t
grub_elf64_size (grub_elf_t elf)
grub_elf64_size (grub_elf_t elf, Elf64_Addr *base)
{
Elf64_Addr segments_start = (Elf64_Addr) -1;
Elf64_Addr segments_end = 0;
@ -379,6 +384,9 @@ grub_elf64_size (grub_elf_t elf)
grub_elf64_phdr_iterate (elf, calcsize, 0);
if (base)
*base = 0;
if (nr_phdrs == 0)
{
grub_error (GRUB_ERR_BAD_OS, "no program headers present");
@ -392,6 +400,9 @@ grub_elf64_size (grub_elf_t elf)
return 0;
}
if (base)
*base = segments_start;
return segments_end - segments_start;
}

View file

@ -264,10 +264,11 @@ grub_env_unset (const char *name)
if (! var)
return;
/* XXX: It is not possible to unset variables with a read or write
hook. */
if (var->read_hook || var->write_hook)
return;
{
grub_env_set (name, "");
return;
}
grub_env_remove (var);

View file

@ -20,6 +20,7 @@
#include <grub/err.h>
#include <grub/misc.h>
#include <stdarg.h>
#include <grub/i18n.h>
#define GRUB_MAX_ERRMSG 256
#define GRUB_ERROR_STACK_SIZE 10
@ -44,7 +45,7 @@ grub_error (grub_err_t n, const char *fmt, ...)
grub_errno = n;
va_start (ap, fmt);
grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), fmt, ap);
grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), _(fmt), ap);
va_end (ap);
return n;
@ -56,7 +57,7 @@ grub_fatal (const char *fmt, ...)
va_list ap;
va_start (ap, fmt);
grub_vprintf (fmt, ap);
grub_vprintf (_(fmt), ap);
va_end (ap);
grub_abort ();
@ -121,7 +122,7 @@ grub_print_error (void)
do
{
if (grub_errno != GRUB_ERR_NONE)
grub_err_printf ("error: %s\n", grub_errmsg);
grub_err_printf (_("error: %s.\n"), grub_errmsg);
}
while (grub_error_pop ());

View file

@ -1,7 +1,7 @@
/* file.c - file I/O functions */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2006,2007 Free Software Foundation, Inc.
* Copyright (C) 2002,2006,2007,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
/* dl-386.c - arch-dependent part of loadable module support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2005,2007 Free Software Foundation, Inc.
* Copyright (C) 2002,2005,2007,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View file

@ -59,7 +59,7 @@ VARIABLE(grub_linux_real_addr)
VARIABLE(grub_linux_is_bzimage)
.long 0
FUNCTION(grub_linux16_boot)
FUNCTION(grub_linux16_real_boot)
/* Must be done before zImage copy. */
call EXT_C(grub_dl_unload_all)

View file

@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View file

@ -22,7 +22,7 @@
#include <grub/types.h>
#include <grub/err.h>
#include <grub/misc.h>
#include <grub/i386/cmos.h>
#include <grub/cmos.h>
#define QEMU_CMOS_MEMSIZE_HIGH 0x35
#define QEMU_CMOS_MEMSIZE_LOW 0x34

View file

@ -1,7 +1,7 @@
/* of.c - Access the Open Firmware client interface. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
/* init.c -- Initialize GRUB on the newworld mac (PPC). */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
/* main.c - the kernel main routine */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2003,2005,2006,2008 Free Software Foundation, Inc.
* Copyright (C) 2002,2003,2005,2006,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -159,6 +159,9 @@ grub_main (void)
/* Load pre-loaded modules and free the space. */
grub_register_exported_symbols ();
#ifdef GRUB_LINKER_HAVE_INIT
grub_arch_dl_init_linker ();
#endif
grub_load_modules ();
/* It is better to set the root device as soon as possible,
@ -169,9 +172,8 @@ grub_main (void)
grub_register_core_commands ();
grub_register_rescue_parser ();
grub_register_rescue_reader ();
grub_load_config ();
grub_load_normal_mode ();
grub_reader_loop (0);
grub_rescue_run ();
}

7
kern/mips/cache.S Normal file
View file

@ -0,0 +1,7 @@
#include <grub/symbol.h>
FUNCTION (grub_cpu_flush_cache)
FUNCTION (grub_arch_sync_caches)
#include "cache_flush.S"
j $ra

23
kern/mips/cache_flush.S Normal file
View file

@ -0,0 +1,23 @@
move $t2, $a0
addu $t3, $a0, $a1
srl $t2, $t2, 5
sll $t2, $t2, 5
addu $t3, $t3, 0x1f
srl $t3, $t3, 5
sll $t3, $t3, 5
move $t0, $t2
subu $t1, $t3, $t2
1:
cache 1, 0($t0)
addiu $t0, $t0, 0x1
addiu $t1, $t1, 0xffff
bne $t1, $zero, 1b
sync
move $t0, $t2
subu $t1, $t3, $t2
2:
cache 0, 0($t0)
addiu $t0, $t0, 0x1
addiu $t1, $t1, 0xffff
bne $t1, $zero, 2b
sync

237
kern/mips/dl.c Normal file
View file

@ -0,0 +1,237 @@
/* dl-386.c - arch-dependent part of loadable module support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2005,2007,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/dl.h>
#include <grub/elf.h>
#include <grub/misc.h>
#include <grub/err.h>
#include <grub/cpu/types.h>
#include <grub/mm.h>
/* Dummy __gnu_local_gp. Resolved by linker. */
static char __gnu_local_gp_dummy;
/* Check if EHDR is a valid ELF header. */
grub_err_t
grub_arch_dl_check_header (void *ehdr)
{
Elf_Ehdr *e = ehdr;
/* Check the magic numbers. */
#ifdef WORDS_BIGENDIAN
if (e->e_ident[EI_CLASS] != ELFCLASS32
|| e->e_ident[EI_DATA] != ELFDATA2MSB
|| e->e_machine != EM_MIPS)
#else
if (e->e_ident[EI_CLASS] != ELFCLASS32
|| e->e_ident[EI_DATA] != ELFDATA2LSB
|| e->e_machine != EM_MIPS)
#endif
return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
return GRUB_ERR_NONE;
}
/* Relocate symbols. */
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
{
Elf_Ehdr *e = ehdr;
Elf_Shdr *s;
Elf_Word entsize;
unsigned i;
grub_size_t gp_size = 0;
/* FIXME: suboptimal. */
grub_uint32_t *gp, *gpptr;
grub_uint32_t gp0;
/* Find a symbol table. */
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_SYMTAB)
break;
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
entsize = s->sh_entsize;
/* Find reginfo. */
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_MIPS_REGINFO)
break;
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no reginfo found");
gp0 = ((grub_uint32_t *)((char *) e + s->sh_offset))[5];
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_REL)
{
grub_dl_segment_t seg;
/* Find the target segment. */
for (seg = mod->segment; seg; seg = seg->next)
if (seg->section == s->sh_info)
break;
if (seg)
{
Elf_Rel *rel, *max;
for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
rel++)
switch (ELF_R_TYPE (rel->r_info))
{
case R_MIPS_GOT16:
case R_MIPS_CALL16:
case R_MIPS_GPREL32:
gp_size += 4;
break;
}
}
}
if (gp_size > 0x08000)
return grub_error (GRUB_ERR_OUT_OF_RANGE, "__gnu_local_gp is too big\n");
gpptr = gp = grub_malloc (gp_size);
if (!gp)
return grub_errno;
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_REL)
{
grub_dl_segment_t seg;
/* Find the target segment. */
for (seg = mod->segment; seg; seg = seg->next)
if (seg->section == s->sh_info)
break;
if (seg)
{
Elf_Rel *rel, *max;
for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
rel++)
{
Elf_Word *addr;
Elf_Sym *sym;
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
sym = (Elf_Sym *) ((char *) mod->symtab
+ entsize * ELF_R_SYM (rel->r_info));
if (sym->st_value == (grub_addr_t) &__gnu_local_gp_dummy)
sym->st_value = (grub_addr_t) gp;
switch (ELF_R_TYPE (rel->r_info))
{
case R_MIPS_HI16:
{
grub_uint32_t value;
Elf_Rel *rel2;
/* Handle partner lo16 relocation. Lower part is
treated as signed. Hence add 0x8000 to compensate.
*/
value = (*(grub_uint16_t *) addr << 16)
+ sym->st_value + 0x8000;
for (rel2 = rel + 1; rel2 < max; rel2++)
if (ELF_R_SYM (rel2->r_info)
== ELF_R_SYM (rel->r_info)
&& ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16)
{
value += *(grub_int16_t *)
((char *) seg->addr + rel2->r_offset);
break;
}
*(grub_uint16_t *) addr = (value >> 16) & 0xffff;
}
break;
case R_MIPS_LO16:
*(grub_uint16_t *) addr += (sym->st_value) & 0xffff;
break;
case R_MIPS_32:
*(grub_uint32_t *) addr += sym->st_value;
break;
case R_MIPS_GPREL32:
*(grub_uint32_t *) addr = sym->st_value
+ *(grub_uint32_t *) addr + gp0 - (grub_uint32_t)gp;
break;
case R_MIPS_26:
{
grub_uint32_t value;
grub_uint32_t raw;
raw = (*(grub_uint32_t *) addr) & 0x3ffffff;
value = raw << 2;
value += sym->st_value;
raw = (value >> 2) & 0x3ffffff;
*(grub_uint32_t *) addr =
raw | ((*(grub_uint32_t *) addr) & 0xfc000000);
}
break;
case R_MIPS_GOT16:
case R_MIPS_CALL16:
/* FIXME: reuse*/
*gpptr = sym->st_value + *(grub_uint16_t *) addr;
*(grub_uint16_t *) addr
= sizeof (grub_uint32_t) * (gpptr - gp);
gpptr++;
break;
default:
{
grub_free (gp);
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"Unknown relocation type %d\n",
ELF_R_TYPE (rel->r_info));
}
break;
}
}
}
}
return GRUB_ERR_NONE;
}
void
grub_arch_dl_init_linker (void)
{
grub_dl_register_symbol ("__gnu_local_gp", &__gnu_local_gp_dummy, 0);
}

View file

@ -1,4 +1,3 @@
/* reader.c - reader support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
@ -17,33 +16,20 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/types.h>
#include <grub/mm.h>
#include <grub/reader.h>
#include <grub/parser.h>
#include <grub/kernel.h>
#include <grub/env.h>
#include <grub/mips/kernel.h>
struct grub_handler_class grub_reader_class =
{
.name = "reader"
};
grub_err_t
grub_reader_loop (grub_reader_getline_t getline)
void
grub_machine_set_prefix (void)
{
while (1)
{
char *line;
grub_reader_getline_t func;
/* Print an error, if any. */
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
func = (getline) ? : grub_reader_get_current ()->read_line;
if ((func (&line, 0)) || (! line))
return grub_errno;
grub_parser_get_current ()->parse_line (line, func);
grub_free (line);
}
grub_env_set ("prefix", grub_prefix);
}
extern char _end[];
grub_addr_t
grub_arch_modules_addr (void)
{
return (grub_addr_t) _end;
}

View file

@ -0,0 +1,61 @@
#include <grub/kernel.h>
#include <grub/misc.h>
#include <grub/env.h>
#include <grub/time.h>
#include <grub/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/time.h>
#include <grub/machine/kernel.h>
#include <grub/machine/memory.h>
#include <grub/cpu/kernel.h>
#define RAMSIZE (*(grub_uint32_t *) ((16 << 20) - 264))
grub_uint32_t
grub_get_rtc (void)
{
static int calln = 0;
return calln++;
}
void
grub_machine_init (void)
{
grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_USABLE,
RAMSIZE - (GRUB_MACHINE_MEMORY_USABLE & 0x7fffffff));
grub_install_get_time_ms (grub_rtc_get_time_ms);
}
void
grub_machine_fini (void)
{
}
void
grub_exit (void)
{
while (1);
}
void
grub_halt (void)
{
while (1);
}
void
grub_reboot (void)
{
while (1);
}
grub_err_t
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
grub_uint64_t,
grub_uint32_t))
{
hook (0, RAMSIZE,
GRUB_MACHINE_MEMORY_AVAILABLE);
return GRUB_ERR_NONE;
}

218
kern/mips/startup.S Normal file
View file

@ -0,0 +1,218 @@
/* startup.S - Startup code for the MIPS. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/symbol.h>
#include <grub/cpu/kernel.h>
#include <grub/machine/memory.h>
#define BASE_ADDR 8
.extern __bss_start
.extern _end
.globl __start, _start, start
__start:
_start:
start:
bal codestart
base:
. = _start + GRUB_KERNEL_CPU_COMPRESSED_SIZE
compressed_size:
.long 0
. = _start + GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE
total_module_size:
.long 0
. = _start + GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE
kernel_image_size:
.long 0
codestart:
/* Save our base. */
move $s0, $ra
/* Parse arguments. Has to be done before relocation.
So need to do it in asm. */
#ifdef GRUB_MACHINE_MIPS_YEELOONG
/* $a2 has the environment. */
move $t0, $a2
argcont:
lw $t1, 0($t0)
beq $t1, $zero, argdone
#define DO_PARSE(str, reg) \
addiu $t2, $s0, (str-base);\
bal parsestr;\
beq $v0, $zero, 1f;\
move reg, $v0;\
b 2f;\
1:
DO_PARSE (busclockstr, $s2)
DO_PARSE (cpuclockstr, $s3)
DO_PARSE (memsizestr, $s4)
DO_PARSE (highmemsizestr, $s5)
2:
addiu $t0, $t0, 4
b argcont
parsestr:
move $v0, $zero
move $t3, $t1
3:
lb $t4, 0($t2)
lb $t5, 0($t3)
addiu $t2, $t2, 1
addiu $t3, $t3, 1
beq $t5, $zero, 1f
beq $t5, $t4, 3b
bne $t4, $zero, 1f
addiu $t3, $t3, 0xffff
digcont:
lb $t5, 0($t3)
/* Substract '0' from digit. */
addiu $t5, $t5, 0xffd0
bltz $t5, 1f
addiu $t4, $t5, 0xfff7
bgtz $t4, 1f
/* Multiply $v0 by 10 with bitshifts. */
sll $v0, $v0, 1
sll $t4, $v0, 2
addu $v0, $v0, $t4
addu $v0, $v0, $t5
addiu $t3, $t3, 1
b digcont
1:
jr $ra
busclockstr: .asciiz "busclock="
cpuclockstr: .asciiz "cpuclock="
memsizestr: .asciiz "memsize="
highmemsizestr: .asciiz "highmemsize="
.p2align 2
argdone:
#endif
/* Decompress the payload. */
addiu $a0, $s0, GRUB_KERNEL_CPU_RAW_SIZE - BASE_ADDR
lui $a1, %hi(compressed)
addiu $a1, %lo(compressed)
lw $a2, (GRUB_KERNEL_CPU_COMPRESSED_SIZE - BASE_ADDR)($s0)
move $s1, $a1
/* $a0 contains source compressed address, $a1 is destination,
$a2 is compressed size. FIXME: put LZMA here. Don't clober $s0,
$s1, $s2, $s3, $s4 and $s5.
On return $v0 contains uncompressed size.
*/
move $v0, $a2
reloccont:
lb $t4, 0($a0)
sb $t4, 0($a1)
addiu $a1,$a1,1
addiu $a0,$a0,1
addiu $a2, 0xffff
bne $a2, $0, reloccont
move $a0, $s1
move $a1, $v0
#include "cache_flush.S"
lui $t1, %hi(cont)
addiu $t1, %lo(cont)
jr $t1
. = _start + GRUB_KERNEL_CPU_RAW_SIZE
compressed:
. = _start + GRUB_KERNEL_CPU_PREFIX
VARIABLE(grub_prefix)
/* to be filled by grub-mkelfimage */
/*
* Leave some breathing room for the prefix.
*/
. = _start + GRUB_KERNEL_CPU_DATA_END
#ifdef GRUB_MACHINE_MIPS_YEELOONG
VARIABLE (grub_arch_busclock)
.long 0
VARIABLE (grub_arch_cpuclock)
.long 0
VARIABLE (grub_arch_memsize)
.long 0
VARIABLE (grub_arch_highmemsize)
.long 0
#endif
cont:
#ifdef GRUB_MACHINE_MIPS_YEELOONG
lui $t1, %hi(grub_arch_busclock)
addiu $t1, %lo(grub_arch_busclock)
sw $s2, 0($t1)
sw $s3, 4($t1)
sw $s4, 8($t1)
sw $s5, 12($t1)
#endif
/* Move the modules out of BSS. */
lui $t1, %hi(_start)
addiu $t1, %lo(_start)
lw $t2, (GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0)
addu $t2, $t1, $t2
lui $t1, %hi(_end)
addiu $t1, %lo(_end)
addiu $t1, (GRUB_MOD_ALIGN-1)
li $t3, (GRUB_MOD_ALIGN-1)
nor $t3, $t3, $0
and $t1, $t1, $t3
lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($s0)
/* Backward copy. */
add $t1, $t1, $t3
add $t2, $t2, $t3
addiu $t1, $t1, 0xffff
addiu $t2, $t2, 0xffff
/* $t2 is source. $t1 is destination. $t3 is size. */
modulesmovcont:
lb $t4, 0($t2)
sb $t4, 0($t1)
addiu $t1,$t1,0xffff
addiu $t2,$t2,0xffff
addiu $t3, 0xffff
bne $t3, $0, modulesmovcont
/* Clean BSS. */
lui $t1, %hi(__bss_start)
addiu $t1, %lo(__bss_start)
lui $t2, %hi(_end)
addiu $t2, %lo(_end)
bsscont:
sb $0,0($t1)
addiu $t1,$t1,1
sltu $t3,$t1,$t2
bne $t3, $0, bsscont
li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH
lui $t1, %hi(grub_main)
addiu $t1, %lo(grub_main)
jr $t1

131
kern/mips/yeeloong/init.c Normal file
View file

@ -0,0 +1,131 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/kernel.h>
#include <grub/misc.h>
#include <grub/env.h>
#include <grub/time.h>
#include <grub/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/time.h>
#include <grub/machine/kernel.h>
#include <grub/machine/memory.h>
#include <grub/cpu/kernel.h>
extern void grub_video_sm712_init (void);
extern void grub_video_video_init (void);
extern void grub_video_bitmap_init (void);
extern void grub_font_manager_init (void);
extern void grub_term_gfxterm_init (void);
extern void grub_at_keyboard_init (void);
/* FIXME: use interrupt to count high. */
grub_uint64_t
grub_get_rtc (void)
{
static grub_uint32_t high = 0;
static grub_uint32_t last = 0;
grub_uint32_t low;
asm volatile ("mfc0 %0, $9": "=r" (low));
if (low < last)
high++;
last = low;
return (((grub_uint64_t) high) << 32) | low;
}
grub_err_t
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
grub_uint64_t,
grub_uint32_t))
{
hook (GRUB_ARCH_LOWMEMPSTART, grub_arch_memsize << 20,
GRUB_MACHINE_MEMORY_AVAILABLE);
hook (GRUB_ARCH_HIGHMEMPSTART, grub_arch_highmemsize << 20,
GRUB_MACHINE_MEMORY_AVAILABLE);
return GRUB_ERR_NONE;
}
static void *
get_modules_end (void)
{
struct grub_module_info *modinfo;
struct grub_module_header *header;
grub_addr_t modbase;
modbase = grub_arch_modules_addr ();
modinfo = (struct grub_module_info *) modbase;
/* Check if there are any modules. */
if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC)
return modinfo;
for (header = (struct grub_module_header *) (modbase + modinfo->offset);
header < (struct grub_module_header *) (modbase + modinfo->size);
header = (struct grub_module_header *) ((char *) header + header->size));
return header;
}
void
grub_machine_init (void)
{
void *modend;
modend = get_modules_end ();
grub_mm_init_region (modend, (grub_arch_memsize << 20)
- (((grub_addr_t) modend) - GRUB_ARCH_LOWMEMVSTART));
/* FIXME: use upper memory as well. */
grub_install_get_time_ms (grub_rtc_get_time_ms);
/* Initialize output terminal (can't be done earlier, as gfxterm
relies on a working heap. */
grub_video_sm712_init ();
grub_video_video_init ();
grub_video_bitmap_init ();
grub_font_manager_init ();
grub_term_gfxterm_init ();
grub_at_keyboard_init ();
}
void
grub_machine_fini (void)
{
}
void
grub_exit (void)
{
while (1);
}
void
grub_halt (void)
{
while (1);
}
void
grub_reboot (void)
{
while (1);
}

View file

@ -1,7 +1,7 @@
/* misc.c - definitions of misc functions */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -230,6 +230,11 @@ grub_memcmp (const void *s1, const void *s2, grub_size_t n)
#ifndef APPLE_CC
int memcmp (const void *s1, const void *s2, grub_size_t n)
__attribute__ ((alias ("grub_memcmp")));
#else
int memcmp (const void *s1, const void *s2, grub_size_t n)
{
return grub_memcmp (s1, s2, n);
}
#endif
int
@ -515,6 +520,11 @@ grub_memset (void *s, int c, grub_size_t n)
#ifndef APPLE_CC
void *memset (void *s, int c, grub_size_t n)
__attribute__ ((alias ("grub_memset")));
#else
void *memset (void *s, int c, grub_size_t n)
{
return grub_memset (s, c, n);
}
#endif
grub_size_t
@ -939,10 +949,10 @@ grub_asprintf (const char *fmt, ...)
/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string.
Return the number of characters converted. DEST must be able to hold
at least DESTSIZE characters. If an invalid sequence is found, return -1.
at least DESTSIZE characters.
If SRCEND is not NULL, then *SRCEND is set to the next byte after the
last byte used in SRC. */
grub_ssize_t
grub_size_t
grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
const grub_uint8_t *src, grub_size_t srcsize,
const grub_uint8_t **srcend)
@ -964,7 +974,8 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
if ((c & 0xc0) != 0x80)
{
/* invalid */
return -1;
code = '?';
count = 0;
}
else
{
@ -1006,7 +1017,11 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
code = c & 0x01;
}
else
return -1;
{
/* invalid */
code = '?';
count = 0;
}
}
if (count == 0)
@ -1025,15 +1040,14 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
void
grub_abort (void)
{
if (grub_term_get_current_output ())
grub_printf ("\nAborted.");
#ifndef GRUB_UTIL
if (grub_term_inputs)
#endif
{
grub_printf ("\nAborted.");
if (grub_term_get_current_input ())
{
grub_printf (" Press any key to exit.");
grub_getkey ();
}
grub_printf (" Press any key to exit.");
grub_getkey ();
}
grub_exit ();

View file

@ -1,7 +1,7 @@
/* mm.c - functions for memory manager */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc.
* Copyright (C) 2002,2005,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
/* dl.c - arch-dependent part of loadable module support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2004,2005,2007 Free Software Foundation, Inc.
* Copyright (C) 2002,2004,2005,2007,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
/* rescue_reader.c - rescue mode reader */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
* Copyright (C) 2009,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,20 +19,15 @@
#include <grub/types.h>
#include <grub/reader.h>
#include <grub/parser.h>
#include <grub/misc.h>
#include <grub/term.h>
#include <grub/mm.h>
#define GRUB_RESCUE_BUF_SIZE 256
static char linebuf[GRUB_RESCUE_BUF_SIZE];
static grub_err_t
grub_rescue_init (void)
{
grub_printf ("Entering rescue mode...\n");
return 0;
}
/* Prompt to input a command and read the line. */
static grub_err_t
grub_rescue_read_line (char **line, int cont)
@ -74,15 +69,24 @@ grub_rescue_read_line (char **line, int cont)
return 0;
}
static struct grub_reader grub_rescue_reader =
{
.name = "rescue",
.init = grub_rescue_init,
.read_line = grub_rescue_read_line
};
void
grub_register_rescue_reader (void)
grub_rescue_run (void)
{
grub_reader_register ("rescue", &grub_rescue_reader);
grub_printf ("Entering rescue mode...\n");
while (1)
{
char *line;
/* Print an error, if any. */
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
grub_rescue_read_line (&line, 0);
if (! line || line[0] == '\0')
continue;
grub_parser_get_current ()->parse_line (line, grub_rescue_read_line);
grub_free (line);
}
}

View file

@ -1,7 +1,7 @@
/* dl.c - arch-dependent part of loadable module support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2004,2005,2007 Free Software Foundation, Inc.
* Copyright (C) 2002,2004,2005,2007,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View file

@ -21,79 +21,33 @@
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/env.h>
#include <grub/time.h>
/* The amount of lines counted by the pager. */
static int grub_more_lines;
struct grub_term_output *grub_term_outputs_disabled;
struct grub_term_input *grub_term_inputs_disabled;
struct grub_term_output *grub_term_outputs;
struct grub_term_input *grub_term_inputs;
/* If the more pager is active. */
static int grub_more;
/* The current cursor state. */
static int cursor_state = 1;
struct grub_handler_class grub_term_input_class =
{
.name = "terminal_input"
};
struct grub_handler_class grub_term_output_class =
{
.name = "terminal_output"
};
#define grub_cur_term_input grub_term_get_current_input ()
#define grub_cur_term_output grub_term_get_current_output ()
void (*grub_newline_hook) (void) = NULL;
/* Put a Unicode character. */
void
grub_putcode (grub_uint32_t code)
grub_putcode (grub_uint32_t code, struct grub_term_output *term)
{
int height = grub_getwh () & 255;
if (code == '\t' && grub_cur_term_output->getxy)
if (code == '\t' && term->getxy)
{
int n;
n = 8 - ((grub_getxy () >> 8) & 7);
n = 8 - ((term->getxy () >> 8) & 7);
while (n--)
grub_putcode (' ');
grub_putcode (' ', term);
return;
}
(grub_cur_term_output->putchar) (code);
(term->putchar) (code);
if (code == '\n')
{
grub_putcode ('\r');
grub_more_lines++;
if (grub_more && grub_more_lines == height - 1)
{
char key;
int pos = grub_getxy ();
/* Show --MORE-- on the lower left side of the screen. */
grub_gotoxy (1, height - 1);
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf ("--MORE--");
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
key = grub_getkey ();
/* Remove the message. */
grub_gotoxy (1, height - 1);
grub_printf (" ");
grub_gotoxy (pos >> 8, pos & 0xFF);
/* Scroll one lines or an entire page, depending on the key. */
if (key == '\r' || key =='\n')
grub_more_lines--;
else
grub_more_lines = 0;
}
}
(term->putchar) ('\r');
}
/* Put a character. C is one byte of a UTF-8 stream.
@ -104,136 +58,101 @@ grub_putchar (int c)
static grub_size_t size = 0;
static grub_uint8_t buf[6];
grub_uint32_t code;
grub_ssize_t ret;
grub_size_t ret;
buf[size++] = c;
ret = grub_utf8_to_ucs4 (&code, 1, buf, size, 0);
if (ret > 0)
if (ret != 0)
{
struct grub_term_output *term;
size = 0;
grub_putcode (code);
FOR_ACTIVE_TERM_OUTPUTS(term)
grub_putcode (code, term);
if (code == '\n' && grub_newline_hook)
grub_newline_hook ();
}
else if (ret < 0)
{
size = 0;
grub_putcode ('?');
}
}
/* Return the number of columns occupied by the character code CODE. */
grub_ssize_t
grub_getcharwidth (grub_uint32_t code)
{
return (grub_cur_term_output->getcharwidth) (code);
}
int
grub_getkey (void)
{
return (grub_cur_term_input->getkey) ();
grub_term_input_t term;
while (1)
{
FOR_ACTIVE_TERM_INPUTS(term)
{
int key = term->checkkey ();
if (key != -1)
return term->getkey ();
}
grub_cpu_idle ();
}
}
int
grub_checkkey (void)
{
return (grub_cur_term_input->checkkey) ();
grub_term_input_t term;
FOR_ACTIVE_TERM_INPUTS(term)
{
int key = term->checkkey ();
if (key != -1)
return key;
}
return -1;
}
int
grub_getkeystatus (void)
{
if (grub_cur_term_input->getkeystatus)
return (grub_cur_term_input->getkeystatus) ();
else
return 0;
}
int status = 0;
grub_term_input_t term;
grub_uint16_t
grub_getxy (void)
{
return (grub_cur_term_output->getxy) ();
}
FOR_ACTIVE_TERM_INPUTS(term)
{
if (term->getkeystatus)
status |= term->getkeystatus ();
}
grub_uint16_t
grub_getwh (void)
{
return (grub_cur_term_output->getwh) ();
}
void
grub_gotoxy (grub_uint8_t x, grub_uint8_t y)
{
(grub_cur_term_output->gotoxy) (x, y);
return status;
}
void
grub_cls (void)
{
if ((grub_cur_term_output->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
{
grub_putchar ('\n');
grub_refresh ();
}
else
(grub_cur_term_output->cls) ();
struct grub_term_output *term;
FOR_ACTIVE_TERM_OUTPUTS(term)
{
if ((term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
{
grub_putcode ('\n', term);
grub_term_refresh (term);
}
else
(term->cls) ();
}
}
void
grub_setcolorstate (grub_term_color_state state)
{
if (grub_cur_term_output->setcolorstate)
(grub_cur_term_output->setcolorstate) (state);
}
void
grub_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
{
if (grub_cur_term_output->setcolor)
(grub_cur_term_output->setcolor) (normal_color, highlight_color);
}
void
grub_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
{
if (grub_cur_term_output->getcolor)
(grub_cur_term_output->getcolor) (normal_color, highlight_color);
}
int
grub_setcursor (int on)
{
int ret = cursor_state;
if (grub_cur_term_output->setcursor)
{
(grub_cur_term_output->setcursor) (on);
cursor_state = on;
}
return ret;
}
int
grub_getcursor (void)
{
return cursor_state;
struct grub_term_output *term;
FOR_ACTIVE_TERM_OUTPUTS(term)
grub_term_setcolorstate (term, state);
}
void
grub_refresh (void)
{
if (grub_cur_term_output->refresh)
(grub_cur_term_output->refresh) ();
}
struct grub_term_output *term;
void
grub_set_more (int onoff)
{
if (onoff == 1)
grub_more++;
else
grub_more--;
grub_more_lines = 0;
FOR_ACTIVE_TERM_OUTPUTS(term)
grub_term_refresh (term);
}

View file

@ -1,7 +1,7 @@
/* dl-x86_64.c - arch-dependent part of loadable module support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2005,2007 Free Software Foundation, Inc.
* Copyright (C) 2002,2005,2007,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by