Merge mips branch

This commit is contained in:
Robert Millan 2010-01-20 01:55:41 +00:00
commit d4a4ee5765
84 changed files with 3245 additions and 247 deletions

189
ChangeLog
View file

@ -1,3 +1,192 @@
2009-12-20 Robert Millan <rmh.grub@aybabtu.com>
* loader/mips/linux.c (grub_cmd_initrd)
(GRUB_MOD_INIT(linux)): Adjust and gettextize a few strings.
2009-12-20 Robert Millan <rmh.grub@aybabtu.com>
* kern/mips/yeeloong/init.c (grub_video_sm712_init)
(grub_video_video_init, grub_video_bitmap_init)
(grub_font_manager_init, grub_term_gfxterm_init)
(grub_at_keyboard_init): New extern declarations.
(grub_machine_init): Initialize gfxterm and at_keyboard.
* kern/main.c (grub_main): Revert grub_printf delay kludge.
* util/grub-install.in: Revert embed of `at_keyboard.mod' and
`gfxterm.mod' into core image.
* conf/mips.rmk (pkglib_IMAGES, kernel_img_SOURCES)
(kernel_img_CFLAGS, kernel_img_ASFLAGS, kernel_img_LDFLAGS)
(kernel_img_FORMAT): Copy to ...
* conf/mips-qemu-mips.rmk (pkglib_IMAGES, kernel_img_SOURCES)
(kernel_img_CFLAGS, kernel_img_ASFLAGS, kernel_img_LDFLAGS)
(kernel_img_FORMAT): ... here, and ...
* conf/mips-yeeloong.rmk (pkglib_IMAGES, kernel_img_SOURCES)
(kernel_img_CFLAGS, kernel_img_ASFLAGS, kernel_img_LDFLAGS)
(kernel_img_FORMAT): ... here.
(kernel_img_SOURCES): Add files necessary for output (gfxterm)
and input (at_keyboard) terminals in kernel.
(kernel_img_CFLAGS): Add `-DUSE_ASCII_FAILBACK'.
(pkglib_MODULES): Remove `pci.mod'.
(pci_mod_SOURCES, pci_mod_CFLAGS, pci_mod_LDFLAGS)
(sm712_mod_SOURCES, sm712_mod_CFLAGS, sm712_mod_LDFLAGS)
(at_keyboard_mod_SOURCES, at_keyboard_mod_CFLAGS)
(at_keyboard_mod_LDFLAGS): Remove variables.
2010-01-11 Felix Zielcke <fzielcke@z-51.de>
* po/POTFILES: Replace `term/i386/pc/serial.c' with `term/serial.c'.
2009-12-10 Robert Millan <rmh.grub@aybabtu.com>
* include/grub/mips/libgcc.h: Only export symbols for functions
that libgcc provides.
2009-12-02 Vladimir Serbinenko <phcoder@gmail.com>
MIPS support.
* bus/bonito.c: New file.
* bus/pci.c (grub_pci_iterate): Use GRUB_PCI_NUM_BUS and
GRUB_PCI_NUM_DEVICES.
* term/i386/pc/serial.c: Move to ...
* term/serial.c: ... here. All users updated.
* util/i386/pc/grub-mkimage.c: Move to ...
* util/grub-mkrawimage.c: ... here. All users updated.
* term/i386/pc/at_keyboard.c: Move to ...
* term/at_keyboard.c: ... here. All users updated.
* conf/mips-qemu-mips.rmk: New file.
* conf/mips-yeeloong.rmk: Likewise.
* conf/mips.rmk: Likewise.
* configure.ac: New platforms mipsel-yeeloong, mips-qemu-mips and
mipsel-qemu-mips.
* disk/ata.c (grub_ata_device_initialize): Add GRUB_MACHINE_PCI_IO_BASE
to port addresses.
(grub_ata_pciinit): Support CS5536.
* font/font.c (grub_font_load): Use grub_file_t instead of filename.
* font/font_cmd.c (loadfont_command): Open file before passing it to
grub_font_load.
(pseudo_file_read): New function.
(pseudo_file_close): Likewise.
(pseudo_fs): New structure.
(load_font_module): New function.
(GRUB_MOD_INIT(font_manager)): Load embedded font.
* fs/cpio.c (grub_cpio_open): Handle partial matches correctly.
* genmk.rb: Strip .rel.dyn, .reginfo, .note and .comment.
* genmoddep.awk: Ignore __gnu_local_gp. It's defined by linker.
* include/grub/i386/at_keyboard.h: Split into ...
* include/grub/at_keyboard.h: ... this ...
* include/grub/i386/at_keyboard.h: ... and this.
* include/grub/dl.h (grub_arch_dl_init_linker) [_mips && !GRUB_UTIL]:
New prototype.
* include/grub/elfload.h (grub_elf32_size): New parameter. All users
updated.
(grub_elf64_size): Likewise.
* include/grub/font.h (grub_font_load): Use grub_file_t instead of
filename.
* include/grub/i386/io.h (grub_port_t): New type. All users updated.
* include/grub/i386/coreboot/serial.h: Rewritten.
* include/grub/i386/ieee1275/serial.h: Include
grub/i386/coreboot/serial.h instead of grub/i386/pc/serial.h.
* include/grub/i386/pc/serial.h: Moved from here ...
* include/grub/serial.h: ... to here. All users updated.
* include/grub/i386/pci.h (GRUB_MACHINE_PCI_IO_BASE): New definition.
(GRUB_PCI_NUM_BUS): Likewise.
(GRUB_PCI_NUM_DEVICES): Likewise.
(grub_pci_device_map_range): Add missing volatile keyword.
* include/grub/kernel.h (OBJ_TYPE_FONT): New enum value.
* include/grub/mips/at_keyboard.h: New file.
* include/grub/mips/cache.h: Likewise.
* include/grub/mips/io.h: Likewise.
* include/grub/mips/kernel.h: Likewise.
* include/grub/mips/libgcc.h: Likewise.
* include/grub/mips/pci.h: Likewise.
* include/grub/mips/qemu-mips/boot.h: Likewise.
* include/grub/mips/qemu-mips/kernel.h: Likewise.
* include/grub/mips/qemu-mips/loader.h: Likewise.
* include/grub/mips/qemu-mips/memory.h: Likewise.
* include/grub/mips/qemu-mips/serial.h: Likewise.
* include/grub/mips/qemu-mips/time.h: Likewise.
* include/grub/mips/relocator.h: Likewise.
* include/grub/mips/time.h: Likewise.
* include/grub/mips/types.h: Likewise.
* include/grub/mips/yeeloong/at_keyboard.h: Likewise.
* include/grub/mips/yeeloong/boot.h: Likewise.
* include/grub/mips/yeeloong/kernel.h: Likewise.
* include/grub/mips/yeeloong/loader.h: Likewise.
* include/grub/mips/yeeloong/memory.h: Likewise.
* include/grub/mips/yeeloong/pci.h: Likewise.
* include/grub/mips/yeeloong/serial.h: Likewise.
* include/grub/mips/yeeloong/time.h: Likewise.
* kern/dl.c (grub_dl_resolve_symbols): Handle STT_OBJECT correctly.
* kern/elf.c (grub_elf32_size): New parameter. All users
updated.
(grub_elf64_size): Likewise.
* kern/main.c (grub_main): Call grub_arch_dl_init_linker if necessary.
Load modules before saying "Welcome to GRUB!".
Call grub_refresh after saying "Welcome to GRUB!".
* kern/mips/cache.S: New file.
* kern/mips/cache_flush.S: Likewise.
* kern/mips/dl.c: Likewise.
* kern/mips/init.c: Likewise.
* kern/mips/qemu-mips/init.c: Likewise.
* kern/mips/startup.S: Likewise.
* kern/mips/yeeloong/init.c: Likewise.
* kern/term.c (grub_putcode): Handle NULL terminal.
(grub_getcharwidth): Likewise.
(grub_getkey): Likewise.
(grub_checkkey): Likewise.
(grub_getkeystatus): Likewise.
(grub_getxy): Likewise.
(grub_getwh): Likewise.
(grub_gotoxy): Likewise.
(grub_cls): Likewise.
(grub_setcolorstate): Likewise.
(grub_setcolor): Likewise.
(grub_getcolor): Likewise.
(grub_refresh): Likewise.
* lib/mips/relocator.c (JUMP_SIZEOF): Fix incorrect value.
(write_jump): Add hatch nop.
* lib/mips/relocator_asm.S: Use kern/mips/cache_flush.S.
* lib/mips/setjmp.S: New file.
* loader/mips/linux.c: Likewise.
* term/i386/pc/at_keyboard.c: Move from here ...
* term/at_keyboard.c: ... to here.
* term/i386/pc/serial.c: Moved from here ...
* term/serial.c: ... to here. All users updated.
(TEXT_HEIGHT): Set to 24 to fit linux terminal.
(serial_hw_io_addr): Use GRUB_MACHINE_SERIAL_PORTS.
(serial_translate_key_sequence): Avoid deadlock.
(grub_serial_getkey): Handle backspace.
(grub_serial_putchar): Fix newline handling.
* util/i386/pc/grub-mkimage.c: Move from here ...
* util/grub-mkrawimage.c: ... to here. All users updated.
(generate_image): New parameters 'font_path' and 'format'.
Support embedding font.
Use grub_host_to_target* instead of grub_cpu_to_le*.
(generate_image) [GRUB_MACHINE_MIPS]: Support ELF encapsulation.
(options) [GRUB_PLATFORM_IMAGE_DEFAULT]: New option "--format".
(options): New option "--font".
(usage): Likewise.
(main) [GRUB_PLATFORM_IMAGE_DEFAULT]: Handle "--format".
(main): Handle "--font".
* term/gfxterm.c (grub_virtual_screen): New member bg_color_display.
(grub_virtual_screen_setup): Set bg_color_display.
(redraw_screen_rect): Use bg_color_display instead of incorrect
bg_color.
(grub_gfxterm_cls): Likewise.
* util/elf/grub-mkimage.c (load_modules): New parameter 'config_path'.
Support embedding config file.
(add_segments): Likewise.
(options): New option "--config".
(main): Handle "--config".
* video/sm712.c: New file.
2010-01-18 Robert Millan <rmh.grub@aybabtu.com> 2010-01-18 Robert Millan <rmh.grub@aybabtu.com>
Fix parallel builds. Fix parallel builds.

90
bus/bonito.c Normal file
View file

@ -0,0 +1,90 @@
/* bonito.c - PCI bonito interface. */
/*
* 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/pci.h>
#include <grub/misc.h>
static grub_uint32_t base_win[GRUB_MACHINE_PCI_NUM_WIN];
static const grub_size_t sizes_win[GRUB_MACHINE_PCI_NUM_WIN] =
{GRUB_MACHINE_PCI_WIN1_SIZE, GRUB_MACHINE_PCI_WIN_SIZE,
GRUB_MACHINE_PCI_WIN_SIZE};
/* Usage counters. */
static int usage_win[GRUB_MACHINE_PCI_NUM_WIN];
static grub_addr_t addr_win[GRUB_MACHINE_PCI_NUM_WIN] =
{GRUB_MACHINE_PCI_WIN1_ADDR, GRUB_MACHINE_PCI_WIN2_ADDR,
GRUB_MACHINE_PCI_WIN3_ADDR};
static inline void
write_bases (void)
{
int i;
grub_uint32_t reg = 0;
for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++)
reg |= (((base_win[i] >> GRUB_MACHINE_PCI_WIN_SHIFT)
& GRUB_MACHINE_PCI_WIN_MASK)
>> (i * GRUB_MACHINE_PCI_WIN_MASK_SIZE));
GRUB_MACHINE_PCI_IO_CTRL_REG = reg;
}
volatile void *
grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)),
grub_addr_t base, grub_size_t size)
{
int i;
grub_addr_t newbase;
/* First try already used registers. */
for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++)
if (usage_win[i] && base_win[i] <= base
&& base_win[i] + sizes_win[i] > base + size)
{
usage_win[i]++;
return (void *)
(addr_win[i] | (base & GRUB_MACHINE_PCI_WIN_OFFSET_MASK));
}
/* Map new register. */
newbase = base & ~GRUB_MACHINE_PCI_WIN_OFFSET_MASK;
for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++)
if (!usage_win[i] && newbase <= base
&& newbase + sizes_win[i] > base + size)
{
usage_win[i]++;
base_win[i] = newbase;
write_bases ();
return (void *)
(addr_win[i] | (base & GRUB_MACHINE_PCI_WIN_OFFSET_MASK));
}
grub_fatal ("Out of PCI windows.");
}
void
grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)),
volatile void *mem __attribute__ ((unused)),
grub_size_t size __attribute__ ((unused)))
{
int i;
for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++)
if (usage_win[i] && addr_win[i]
== (((grub_addr_t) mem) & ~GRUB_MACHINE_PCI_WIN_OFFSET_MASK))
{
usage_win[i]--;
return;
}
grub_fatal ("Tried to unmap not mapped region");
}

View file

@ -35,9 +35,9 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook)
grub_pci_id_t id; grub_pci_id_t id;
grub_uint32_t hdr; grub_uint32_t hdr;
for (dev.bus = 0; dev.bus < 256; dev.bus++) for (dev.bus = 0; dev.bus < GRUB_PCI_NUM_BUS; dev.bus++)
{ {
for (dev.device = 0; dev.device < 32; dev.device++) for (dev.device = 0; dev.device < GRUB_PCI_NUM_DEVICES; dev.device++)
{ {
for (dev.function = 0; dev.function < 8; dev.function++) for (dev.function = 0; dev.function < 8; dev.function++)
{ {

View file

@ -53,9 +53,11 @@ boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LI
boot_img_FORMAT = binary boot_img_FORMAT = binary
bin_UTILITIES += grub-mkimage bin_UTILITIES += grub-mkimage
grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \ grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \
util/resolve.c gnulib/progname.c util/resolve.c gnulib/progname.c
grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
util/grub-mkrawimage.c_DEPENDENCIES = Makefile
pkglib_IMAGES += kernel.img pkglib_IMAGES += kernel.img
kernel_img_SOURCES = kern/i386/qemu/startup.S \ kernel_img_SOURCES = kern/i386/qemu/startup.S \
@ -136,7 +138,7 @@ halt_mod_CFLAGS = $(COMMON_CFLAGS)
halt_mod_LDFLAGS = $(COMMON_LDFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For serial.mod. # For serial.mod.
serial_mod_SOURCES = term/i386/pc/serial.c serial_mod_SOURCES = term/serial.c
serial_mod_CFLAGS = $(COMMON_CFLAGS) serial_mod_CFLAGS = $(COMMON_CFLAGS)
serial_mod_LDFLAGS = $(COMMON_LDFLAGS) serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
@ -173,7 +175,7 @@ lspci_mod_CFLAGS = $(COMMON_CFLAGS)
lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For datetime.mod # For datetime.mod
datetime_mod_SOURCES = lib/i386/datetime.c datetime_mod_SOURCES = lib/cmos_datetime.c
datetime_mod_CFLAGS = $(COMMON_CFLAGS) datetime_mod_CFLAGS = $(COMMON_CFLAGS)
datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -92,7 +92,7 @@ halt_mod_CFLAGS = $(COMMON_CFLAGS)
halt_mod_LDFLAGS = $(COMMON_LDFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For serial.mod. # For serial.mod.
serial_mod_SOURCES = term/i386/pc/serial.c serial_mod_SOURCES = term/serial.c
serial_mod_CFLAGS = $(COMMON_CFLAGS) serial_mod_CFLAGS = $(COMMON_CFLAGS)
serial_mod_LDFLAGS = $(COMMON_LDFLAGS) serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
@ -122,7 +122,7 @@ lspci_mod_CFLAGS = $(COMMON_CFLAGS)
lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For datetime.mod # For datetime.mod
datetime_mod_SOURCES = lib/i386/datetime.c datetime_mod_SOURCES = lib/cmos_datetime.c
datetime_mod_CFLAGS = $(COMMON_CFLAGS) datetime_mod_CFLAGS = $(COMMON_CFLAGS)
datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -84,10 +84,10 @@ bin_UTILITIES = grub-mkimage
sbin_UTILITIES = grub-setup sbin_UTILITIES = grub-setup
# For grub-mkimage. # For grub-mkimage.
grub_mkimage_SOURCES = gnulib/progname.c util/i386/pc/grub-mkimage.c util/misc.c \ grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \
util/resolve.c lib/LzmaEnc.c lib/LzFind.c util/resolve.c lib/LzmaEnc.c lib/LzFind.c
grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
util/i386/pc/grub-mkimage.c_DEPENDENCIES = Makefile util/grub-mkrawimage.c_DEPENDENCIES = Makefile
# For grub-setup. # For grub-setup.
util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h
@ -197,7 +197,7 @@ halt_mod_CFLAGS = $(COMMON_CFLAGS)
halt_mod_LDFLAGS = $(COMMON_LDFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For serial.mod. # For serial.mod.
serial_mod_SOURCES = term/i386/pc/serial.c serial_mod_SOURCES = term/serial.c
serial_mod_CFLAGS = $(COMMON_CFLAGS) serial_mod_CFLAGS = $(COMMON_CFLAGS)
serial_mod_LDFLAGS = $(COMMON_LDFLAGS) serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
@ -293,7 +293,7 @@ pxecmd_mod_CFLAGS = $(COMMON_CFLAGS)
pxecmd_mod_LDFLAGS = $(COMMON_LDFLAGS) pxecmd_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For datetime.mod # For datetime.mod
datetime_mod_SOURCES = lib/i386/datetime.c datetime_mod_SOURCES = lib/cmos_datetime.c
datetime_mod_CFLAGS = $(COMMON_CFLAGS) datetime_mod_CFLAGS = $(COMMON_CFLAGS)
datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -6,7 +6,7 @@ cpuid_mod_CFLAGS = $(COMMON_CFLAGS)
cpuid_mod_LDFLAGS = $(COMMON_LDFLAGS) cpuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += at_keyboard.mod pkglib_MODULES += at_keyboard.mod
at_keyboard_mod_SOURCES = term/i386/pc/at_keyboard.c at_keyboard_mod_SOURCES = term/at_keyboard.c
at_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) at_keyboard_mod_CFLAGS = $(COMMON_CFLAGS)
at_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) at_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS)

23
conf/mips-qemu-mips.rmk Normal file
View file

@ -0,0 +1,23 @@
# -*- makefile -*-
LINK_BASE = 0x80010000
target_machine=qemu-mips
COMMON_CFLAGS += -march=mips3
COMMON_ASFLAGS += -march=mips3
include $(srcdir)/conf/mips.mk
pkglib_IMAGES = kernel.img
kernel_img_SOURCES = kern/$(target_cpu)/startup.S \
kern/main.c kern/device.c kern/$(target_cpu)/init.c \
kern/$(target_cpu)/$(target_machine)/init.c \
kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \
kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c \
symlist.c kern/$(target_cpu)/cache.S
kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \
-Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic
kernel_img_FORMAT = binary

79
conf/mips-yeeloong.rmk Normal file
View file

@ -0,0 +1,79 @@
# -*- makefile -*-
LINK_BASE = 0x80200000
target_machine=yeeloong
COMMON_CFLAGS += -march=mips3
COMMON_ASFLAGS += -march=mips3
include $(srcdir)/conf/mips.mk
pkglib_IMAGES = kernel.img
kernel_img_SOURCES = kern/$(target_cpu)/startup.S \
kern/main.c kern/device.c kern/$(target_cpu)/init.c \
kern/$(target_cpu)/$(target_machine)/init.c \
kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \
kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c \
kern/$(target_cpu)/cache.S \
\
term/at_keyboard.c \
font/font_cmd.c font/font.c io/bufio.c \
video/video.c video/fb/video_fb.c video/fb/fbblit.c \
video/fb/fbfill.c video/fb/fbutil.c video/bitmap.c \
video/sm712.c bus/pci.c bus/bonito.c \
term/gfxterm.c commands/extcmd.c lib/arg.c \
symlist.c
kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \
-Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic
kernel_img_FORMAT = binary
# For ata.mod.
pkglib_MODULES += ata.mod
ata_mod_SOURCES = disk/ata.c
ata_mod_CFLAGS = $(COMMON_CFLAGS)
ata_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For lspci.mod
pkglib_MODULES += lspci.mod
lspci_mod_SOURCES = commands/lspci.c
lspci_mod_CFLAGS = $(COMMON_CFLAGS)
lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For ata_pthru.mod.
pkglib_MODULES += ata_pthru.mod
ata_pthru_mod_SOURCES = disk/ata_pthru.c
ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS)
ata_pthru_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For mmap.mod.
pkglib_MODULES += mmap.mod
mmap_mod_SOURCES = mmap/mmap.c mmap/mips/yeeloong/uppermem.c
mmap_mod_CFLAGS = $(COMMON_CFLAGS)
mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
# For datetime.mod
pkglib_MODULES += datetime.mod
datetime_mod_SOURCES = lib/cmos_datetime.c
datetime_mod_CFLAGS = $(COMMON_CFLAGS)
datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For date.mod
pkglib_MODULES += date.mod
date_mod_SOURCES = commands/date.c
date_mod_CFLAGS = $(COMMON_CFLAGS)
date_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For datehook.mod
pkglib_MODULES += datehook.mod
datehook_mod_SOURCES = hook/datehook.c
datehook_mod_CFLAGS = $(COMMON_CFLAGS)
datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
sbin_SCRIPTS += grub-install
grub_install_SOURCES = util/grub-install.in

78
conf/mips.rmk Normal file
View file

@ -0,0 +1,78 @@
# -*- makefile -*-
COMMON_ASFLAGS += -nostdinc
COMMON_CFLAGS += -ffreestanding -mexplicit-relocs -mflush-func=grub_cpu_flush_cache
COMMON_LDFLAGS += -nostdlib
# Used by various components. These rules need to precede them.
script/lexer.c_DEPENDENCIES = grub_script.tab.h
# Images.
MOSTLYCLEANFILES += symlist.c kernel_syms.lst
DEFSYMFILES += kernel_syms.lst
kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \
symbol.h term.h time.h types.h loader.h partition.h \
msdos_partition.h machine/kernel.h handler.h list.h \
command.h machine/memory.h cpu/libgcc.h cpu/cache.h i18n.h
symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh
/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh
/bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
# Scripts.
sbin_SCRIPTS =
bin_SCRIPTS =
# For grub-mkimage.
bin_UTILITIES += grub-mkimage
grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \
util/resolve.c lib/LzmaEnc.c lib/LzFind.c
grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE)
util/grub-mkrawimage.c_DEPENDENCIES = Makefile
# Modules.
pkglib_MODULES = memdisk.mod \
lsmmap.mod
# For boot.mod.
pkglib_MODULES += boot.mod
boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c
boot_mod_CFLAGS = $(COMMON_CFLAGS)
boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For memdisk.mod.
memdisk_mod_SOURCES = disk/memdisk.c
memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For lsmmap.mod
lsmmap_mod_SOURCES = commands/lsmmap.c
lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For serial.mod.
pkglib_MODULES += serial.mod
serial_mod_SOURCES = term/serial.c
serial_mod_CFLAGS = $(COMMON_CFLAGS)
serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For relocator.mod.
pkglib_MODULES += relocator.mod
relocator_mod_SOURCES = lib/$(target_cpu)/relocator.c lib/$(target_cpu)/relocator_asm.S
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

View file

@ -52,6 +52,16 @@ fi
case "$target_cpu" in case "$target_cpu" in
i[[3456]]86) target_cpu=i386 ;; i[[3456]]86) target_cpu=i386 ;;
sparc) target_cpu=sparc64 ;; sparc) target_cpu=sparc64 ;;
mipsel|mips64el)
target_cpu=mips;
TARGET_CFLAGS="$TARGET_CFLAGS -DGRUB_CPU_MIPSEL=1";
CFLAGS="$CFLAGS -DGRUB_CPU_MIPSEL=1";
;;
mips|mips64)
target_cpu=mips;
TARGET_CFLAGS="$TARGET_CFLAGS -DGRUB_CPU_MIPS=1";
CFLAGS="$CFLAGS -DGRUB_CPU_MIPS=1";
;;
esac esac
# Specify the platform (such as firmware). # Specify the platform (such as firmware).
@ -69,6 +79,7 @@ if test "x$with_platform" = x; then
powerpc-*) platform=ieee1275 ;; powerpc-*) platform=ieee1275 ;;
powerpc64-*) platform=ieee1275 ;; powerpc64-*) platform=ieee1275 ;;
sparc64-*) platform=ieee1275 ;; sparc64-*) platform=ieee1275 ;;
mips-*) platform=yeeloong ;;
*) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;; *) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;;
esac esac
else else
@ -95,6 +106,8 @@ case "$target_cpu"-"$platform" in
i386-qemu) ;; i386-qemu) ;;
powerpc-ieee1275) ;; powerpc-ieee1275) ;;
sparc64-ieee1275) ;; sparc64-ieee1275) ;;
mips-qemu-mips) ;;
mips-yeeloong) ;;
*-emu) ;; *-emu) ;;
*) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
esac esac
@ -125,6 +138,8 @@ case "$platform" in
qemu) machine_CFLAGS="-DGRUB_MACHINE_QEMU=1" ;; qemu) machine_CFLAGS="-DGRUB_MACHINE_QEMU=1" ;;
pc) machine_CFLAGS="-DGRUB_MACHINE_PCBIOS=1" ;; pc) machine_CFLAGS="-DGRUB_MACHINE_PCBIOS=1" ;;
emu) machine_CFLAGS="-DGRUB_MACHINE_EMU=1" ;; emu) machine_CFLAGS="-DGRUB_MACHINE_EMU=1" ;;
yeeloong) machine_CFLAGS="-DGRUB_MACHINE_MIPS_YEELOONG=1 -DGRUB_MACHINE_MIPS=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;;
qemu-mips) machine_CFLAGS="-DGRUB_MACHINE_MIPS_QEMU_MIPS=1 -DGRUB_MACHINE_MIPS=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;;
esac esac
CFLAGS="$CFLAGS $machine_CFLAGS" CFLAGS="$CFLAGS $machine_CFLAGS"
TARGET_ASFLAGS="$TARGET_ASFLAGS $machine_CFLAGS" TARGET_ASFLAGS="$TARGET_ASFLAGS $machine_CFLAGS"

View file

@ -26,8 +26,8 @@
#include <grub/scsi.h> #include <grub/scsi.h>
/* At the moment, only two IDE ports are supported. */ /* At the moment, only two IDE ports are supported. */
static const int grub_ata_ioaddress[] = { 0x1f0, 0x170 }; static const grub_port_t grub_ata_ioaddress[] = { 0x1f0, 0x170 };
static const int grub_ata_ioaddress2[] = { 0x3f6, 0x376 }; static const grub_port_t grub_ata_ioaddress2[] = { 0x3f6, 0x376 };
static struct grub_ata_device *grub_ata_devices; static struct grub_ata_device *grub_ata_devices;
@ -347,8 +347,8 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2)
/* Setup the device information. */ /* Setup the device information. */
dev->port = port; dev->port = port;
dev->device = device; dev->device = device;
dev->ioaddress = addr; dev->ioaddress = addr + GRUB_MACHINE_PCI_IO_BASE;
dev->ioaddress2 = addr2; dev->ioaddress2 = addr2 + GRUB_MACHINE_PCI_IO_BASE;
dev->next = NULL; dev->next = NULL;
grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4); grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
@ -389,7 +389,7 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2)
static int NESTED_FUNC_ATTR static int NESTED_FUNC_ATTR
grub_ata_pciinit (grub_pci_device_t dev, grub_ata_pciinit (grub_pci_device_t dev,
grub_pci_id_t pciid __attribute__((unused))) grub_pci_id_t pciid)
{ {
static int compat_use[2] = { 0 }; static int compat_use[2] = { 0 };
grub_pci_address_t addr; grub_pci_address_t addr;
@ -400,19 +400,34 @@ grub_ata_pciinit (grub_pci_device_t dev,
int regb; int regb;
int i; int i;
static int controller = 0; static int controller = 0;
int cs5536 = 0;
int nports = 2;
/* Read class. */ /* Read class. */
addr = grub_pci_make_address (dev, 2); addr = grub_pci_make_address (dev, 2);
class = grub_pci_read (addr); class = grub_pci_read (addr);
/* AMD CS5536 Southbridge. */
if (pciid == 0x208f1022)
{
cs5536 = 1;
nports = 1;
}
/* Check if this class ID matches that of a PCI IDE Controller. */ /* Check if this class ID matches that of a PCI IDE Controller. */
if (class >> 16 != 0x0101) if (!cs5536 && (class >> 16 != 0x0101))
return 0; return 0;
for (i = 0; i < 2; i++) for (i = 0; i < nports; i++)
{ {
/* Set to 0 when the channel operated in compatibility mode. */ /* Set to 0 when the channel operated in compatibility mode. */
int compat = (class >> (8 + 2 * i)) & 1; int compat;
/* We don't support non-compatibility mode for CS5536. */
if (cs5536)
compat = 0;
else
compat = (class >> (8 + 2 * i)) & 1;
rega = 0; rega = 0;
regb = 0; regb = 0;
@ -485,7 +500,6 @@ grub_ata_initialize (void)
return 0; return 0;
} }
static void static void
grub_ata_setlba (struct grub_ata_device *dev, grub_disk_addr_t sector, grub_ata_setlba (struct grub_ata_device *dev, grub_disk_addr_t sector,
grub_size_t size) grub_size_t size)

View file

@ -280,8 +280,10 @@ grub_cpio_open (grub_file_t file, const char *name)
/* Compare NAME and FN by hand in order to cope with duplicate /* Compare NAME and FN by hand in order to cope with duplicate
slashes. */ slashes. */
i = 1; i = 0;
j = 0; j = 0;
while (name[i] == '/')
i++;
while (1) while (1)
{ {
if (name[i] != fn[j]) if (name[i] != fn[j])
@ -290,13 +292,16 @@ grub_cpio_open (grub_file_t file, const char *name)
if (name[i] == '\0') if (name[i] == '\0')
break; break;
if (name[i] == '/' && name[i+1] == '/') while (name[i] == '/' && name[i+1] == '/')
i++; i++;
i++; i++;
j++; j++;
} }
if (name[i] != fn[j])
goto no_match;
file->data = data; file->data = data;
file->size = data->size; file->size = data->size;
grub_free (fn); grub_free (fn);

View file

@ -68,7 +68,7 @@ MOSTLYCLEAN_IMAGE_TARGETS += mostlyclean-image-#{@name}.#{@rule_count}
ifneq ($(TARGET_APPLE_CC),1) ifneq ($(TARGET_APPLE_CC),1)
#{@name}: #{exe} #{@name}: #{exe}
$(OBJCOPY) -O $(#{prefix}_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@ $(OBJCOPY) -O $(#{prefix}_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn $< $@
else else
ifneq (#{exe},kernel.exec) ifneq (#{exe},kernel.exec)
#{@name}: #{exe} ./grub-macho2img #{@name}: #{exe} ./grub-macho2img
@ -333,6 +333,7 @@ MOSTLYCLEANFILES += #{deps_str}
#{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str} #{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str}
$(TARGET_CC) -o $@ #{objs_str} $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS) $(TARGET_CC) -o $@ #{objs_str} $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS)
$(STRIP) -R .rel.dyn -R .reginfo -R .note -R .comment $@
" + objs.collect_with_index do |obj, i| " + objs.collect_with_index do |obj, i|
src = sources[i] src = sources[i]
@ -344,6 +345,7 @@ MOSTLYCLEANFILES += #{deps_str}
"#{obj}: #{src} $(#{src}_DEPENDENCIES) "#{obj}: #{src} $(#{src}_DEPENDENCIES)
$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -MD -c -o $@ $< $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -MD -c -o $@ $<
-include #{dep} -include #{dep}
" "

View file

@ -29,7 +29,7 @@ FNR == 1 {
if ($1 in symtab) { if ($1 in symtab) {
modtab[module] = modtab[module] " " symtab[$1]; modtab[module] = modtab[module] " " symtab[$1];
} }
else { else if ($1 != "__gnu_local_gp") {
printf "%s in %s is not defined\n", $1, module >"/dev/stderr"; printf "%s in %s is not defined\n", $1, module >"/dev/stderr";
error++; error++;
exit; exit;

View file

@ -0,0 +1,54 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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
* 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/>.
*/
#ifndef GRUB_AT_KEYBOARD_HEADER
#define GRUB_AT_KEYBOARD_HEADER 1
#define SHIFT_L 0x2a
#define SHIFT_R 0x36
#define CTRL 0x1d
#define ALT 0x38
#define CAPS_LOCK 0x3a
#define NUM_LOCK 0x45
#define SCROLL_LOCK 0x46
/* Used for sending commands to the controller. */
#define KEYBOARD_COMMAND_ISREADY(x) !((x) & 0x02)
#define KEYBOARD_COMMAND_READ 0x20
#define KEYBOARD_COMMAND_WRITE 0x60
#define KEYBOARD_COMMAND_REBOOT 0xfe
#define KEYBOARD_SCANCODE_SET1 0x40
#define KEYBOARD_ISMAKE(x) !((x) & 0x80)
#define KEYBOARD_ISREADY(x) ((x) & 0x01)
#define KEYBOARD_SCANCODE(x) ((x) & 0x7f)
#ifdef GRUB_MACHINE_IEEE1275
#define OLPC_UP GRUB_TERM_UP
#define OLPC_DOWN GRUB_TERM_DOWN
#define OLPC_LEFT GRUB_TERM_LEFT
#define OLPC_RIGHT GRUB_TERM_RIGHT
#else
#define OLPC_UP '\0'
#define OLPC_DOWN '\0'
#define OLPC_LEFT '\0'
#define OLPC_RIGHT '\0'
#endif
#endif

View file

@ -98,8 +98,8 @@ struct grub_ata_device
/* IO addresses on which the registers for this device can be /* IO addresses on which the registers for this device can be
found. */ found. */
int ioaddress; grub_port_t ioaddress;
int ioaddress2; grub_port_t ioaddress2;
/* Two devices can be connected to a single cable. Use this field /* Two devices can be connected to a single cable. Use this field
to select device 0 (commonly known as "master") or device 1 to select device 0 (commonly known as "master") or device 1

72
include/grub/cmos.h Normal file
View file

@ -0,0 +1,72 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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
* 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/>.
*/
#ifndef GRUB_CMOS_H
#define GRUB_CMOS_H 1
#include <grub/types.h>
#include <grub/cpu/io.h>
#include <grub/cpu/cmos.h>
#define GRUB_CMOS_INDEX_SECOND 0
#define GRUB_CMOS_INDEX_SECOND_ALARM 1
#define GRUB_CMOS_INDEX_MINUTE 2
#define GRUB_CMOS_INDEX_MINUTE_ALARM 3
#define GRUB_CMOS_INDEX_HOUR 4
#define GRUB_CMOS_INDEX_HOUR_ALARM 5
#define GRUB_CMOS_INDEX_DAY_OF_WEEK 6
#define GRUB_CMOS_INDEX_DAY_OF_MONTH 7
#define GRUB_CMOS_INDEX_MONTH 8
#define GRUB_CMOS_INDEX_YEAR 9
#define GRUB_CMOS_INDEX_STATUS_A 0xA
#define GRUB_CMOS_INDEX_STATUS_B 0xB
#define GRUB_CMOS_INDEX_STATUS_C 0xC
#define GRUB_CMOS_INDEX_STATUS_D 0xD
#define GRUB_CMOS_STATUS_B_DAYLIGHT 1
#define GRUB_CMOS_STATUS_B_24HOUR 2
#define GRUB_CMOS_STATUS_B_BINARY 4
static inline grub_uint8_t
grub_bcd_to_num (grub_uint8_t a)
{
return ((a >> 4) * 10 + (a & 0xF));
}
static inline grub_uint8_t
grub_num_to_bcd (grub_uint8_t a)
{
return (((a / 10) << 4) + (a % 10));
}
static inline grub_uint8_t
grub_cmos_read (grub_uint8_t index)
{
grub_outb (index, GRUB_CMOS_ADDR_REG);
return grub_inb (GRUB_CMOS_DATA_REG);
}
static inline void
grub_cmos_write (grub_uint8_t index, grub_uint8_t value)
{
grub_outb (index, GRUB_CMOS_ADDR_REG);
grub_outb (value, GRUB_CMOS_DATA_REG);
}
#endif /* GRUB_CMOS_H */

View file

@ -116,4 +116,9 @@ grub_err_t EXPORT_FUNC(grub_dl_register_symbol) (const char *name, void *addr,
grub_err_t grub_arch_dl_check_header (void *ehdr); grub_err_t grub_arch_dl_check_header (void *ehdr);
grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr); grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr);
#if defined (_mips) && ! defined (GRUB_UTIL)
#define GRUB_LINKER_HAVE_INIT 1
void grub_arch_dl_init_linker (void);
#endif
#endif /* ! GRUB_DL_H */ #endif /* ! GRUB_DL_H */

View file

@ -46,12 +46,12 @@ grub_elf_t grub_elf_file (grub_file_t);
grub_err_t grub_elf_close (grub_elf_t); grub_err_t grub_elf_close (grub_elf_t);
int grub_elf_is_elf32 (grub_elf_t); int grub_elf_is_elf32 (grub_elf_t);
grub_size_t grub_elf32_size (grub_elf_t); grub_size_t grub_elf32_size (grub_elf_t, Elf32_Addr *);
grub_err_t grub_elf32_load (grub_elf_t, grub_elf32_load_hook_t, grub_addr_t *, grub_err_t grub_elf32_load (grub_elf_t, grub_elf32_load_hook_t, grub_addr_t *,
grub_size_t *); grub_size_t *);
int grub_elf_is_elf64 (grub_elf_t); int grub_elf_is_elf64 (grub_elf_t);
grub_size_t grub_elf64_size (grub_elf_t); grub_size_t grub_elf64_size (grub_elf_t, Elf64_Addr *);
grub_err_t grub_elf64_load (grub_elf_t, grub_elf64_load_hook_t, grub_addr_t *, grub_err_t grub_elf64_load (grub_elf_t, grub_elf64_load_hook_t, grub_addr_t *,
grub_size_t *); grub_size_t *);

View file

@ -21,6 +21,7 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/video.h> #include <grub/video.h>
#include <grub/file.h>
/* Forward declaration of opaque structure grub_font. /* Forward declaration of opaque structure grub_font.
Users only pass struct grub_font pointers to the font module functions, Users only pass struct grub_font pointers to the font module functions,
@ -74,7 +75,7 @@ void grub_font_loader_init (void);
/* Load a font and add it to the beginning of the global font list. /* Load a font and add it to the beginning of the global font list.
Returns: 0 upon success; nonzero upon failure. */ Returns: 0 upon success; nonzero upon failure. */
int grub_font_load (const char *filename); int grub_font_load (grub_file_t file);
/* Get the font that has the specified name. Font names are in the form /* Get the font that has the specified name. Font names are in the form
"Family Name Bold Italic 14", where Bold and Italic are optional. "Family Name Bold Italic 14", where Bold and Italic are optional.

View file

@ -19,40 +19,7 @@
#ifndef GRUB_CPU_AT_KEYBOARD_HEADER #ifndef GRUB_CPU_AT_KEYBOARD_HEADER
#define GRUB_CPU_AT_KEYBOARD_HEADER 1 #define GRUB_CPU_AT_KEYBOARD_HEADER 1
#define SHIFT_L 0x2a
#define SHIFT_R 0x36
#define CTRL 0x1d
#define ALT 0x38
#define CAPS_LOCK 0x3a
#define NUM_LOCK 0x45
#define SCROLL_LOCK 0x46
#define KEYBOARD_REG_DATA 0x60 #define KEYBOARD_REG_DATA 0x60
#define KEYBOARD_REG_STATUS 0x64 #define KEYBOARD_REG_STATUS 0x64
/* Used for sending commands to the controller. */
#define KEYBOARD_COMMAND_ISREADY(x) !((x) & 0x02)
#define KEYBOARD_COMMAND_READ 0x20
#define KEYBOARD_COMMAND_WRITE 0x60
#define KEYBOARD_COMMAND_REBOOT 0xfe
#define KEYBOARD_SCANCODE_SET1 0x40
#define KEYBOARD_ISMAKE(x) !((x) & 0x80)
#define KEYBOARD_ISREADY(x) ((x) & 0x01)
#define KEYBOARD_SCANCODE(x) ((x) & 0x7f)
#ifdef GRUB_MACHINE_IEEE1275
#define OLPC_UP GRUB_TERM_UP
#define OLPC_DOWN GRUB_TERM_DOWN
#define OLPC_LEFT GRUB_TERM_LEFT
#define OLPC_RIGHT GRUB_TERM_RIGHT
#else
#define OLPC_UP '\0'
#define OLPC_DOWN '\0'
#define OLPC_LEFT '\0'
#define OLPC_RIGHT '\0'
#endif
#endif #endif

View file

@ -20,55 +20,9 @@
#define GRUB_CPU_CMOS_H 1 #define GRUB_CPU_CMOS_H 1
#include <grub/types.h> #include <grub/types.h>
#include <grub/i386/io.h> #include <grub/cpu/io.h>
#define GRUB_CMOS_ADDR_REG 0x70 #define GRUB_CMOS_ADDR_REG 0x70
#define GRUB_CMOS_DATA_REG 0x71 #define GRUB_CMOS_DATA_REG 0x71
#define GRUB_CMOS_INDEX_SECOND 0
#define GRUB_CMOS_INDEX_SECOND_ALARM 1
#define GRUB_CMOS_INDEX_MINUTE 2
#define GRUB_CMOS_INDEX_MINUTE_ALARM 3
#define GRUB_CMOS_INDEX_HOUR 4
#define GRUB_CMOS_INDEX_HOUR_ALARM 5
#define GRUB_CMOS_INDEX_DAY_OF_WEEK 6
#define GRUB_CMOS_INDEX_DAY_OF_MONTH 7
#define GRUB_CMOS_INDEX_MONTH 8
#define GRUB_CMOS_INDEX_YEAR 9
#define GRUB_CMOS_INDEX_STATUS_A 0xA
#define GRUB_CMOS_INDEX_STATUS_B 0xB
#define GRUB_CMOS_INDEX_STATUS_C 0xC
#define GRUB_CMOS_INDEX_STATUS_D 0xD
#define GRUB_CMOS_STATUS_B_DAYLIGHT 1
#define GRUB_CMOS_STATUS_B_24HOUR 2
#define GRUB_CMOS_STATUS_B_BINARY 4
static inline grub_uint8_t
grub_bcd_to_num (grub_uint8_t a)
{
return ((a >> 4) * 10 + (a & 0xF));
}
static inline grub_uint8_t
grub_num_to_bcd (grub_uint8_t a)
{
return (((a / 10) << 4) + (a % 10));
}
static inline grub_uint8_t
grub_cmos_read (grub_uint8_t index)
{
grub_outb (index, GRUB_CMOS_ADDR_REG);
return grub_inb (GRUB_CMOS_DATA_REG);
}
static inline void
grub_cmos_write (grub_uint8_t index, grub_uint8_t value)
{
grub_outb (index, GRUB_CMOS_ADDR_REG);
grub_outb (value, GRUB_CMOS_DATA_REG);
}
#endif /* GRUB_CPU_CMOS_H */ #endif /* GRUB_CPU_CMOS_H */

View file

@ -1 +1,24 @@
#include <grub/i386/pc/serial.h> /*
* 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/>.
*/
#ifndef GRUB_MACHINE_SERIAL_HEADER
#define GRUB_MACHINE_SERIAL_HEADER 1
#define GRUB_MACHINE_SERIAL_PORTS { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }
#endif

View file

@ -1 +1 @@
#include <grub/i386/pc/serial.h> #include <grub/i386/coreboot/serial.h>

View file

@ -21,6 +21,8 @@
#ifndef GRUB_IO_H #ifndef GRUB_IO_H
#define GRUB_IO_H 1 #define GRUB_IO_H 1
typedef unsigned short int grub_port_t;
static __inline unsigned char static __inline unsigned char
grub_inb (unsigned short int port) grub_inb (unsigned short int port)
{ {

View file

@ -22,8 +22,11 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/i386/io.h> #include <grub/i386/io.h>
#define GRUB_MACHINE_PCI_IO_BASE 0
#define GRUB_PCI_ADDR_REG 0xcf8 #define GRUB_PCI_ADDR_REG 0xcf8
#define GRUB_PCI_DATA_REG 0xcfc #define GRUB_PCI_DATA_REG 0xcfc
#define GRUB_PCI_NUM_BUS 256
#define GRUB_PCI_NUM_DEVICES 32
static inline grub_uint32_t static inline grub_uint32_t
grub_pci_read (grub_pci_address_t addr) grub_pci_read (grub_pci_address_t addr)
@ -67,12 +70,12 @@ grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data)
grub_outb (data, GRUB_PCI_DATA_REG + (addr & 3)); grub_outb (data, GRUB_PCI_DATA_REG + (addr & 3));
} }
static inline void * static inline volatile void *
grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)),
grub_addr_t base, grub_addr_t base,
grub_size_t size __attribute__ ((unused))) grub_size_t size __attribute__ ((unused)))
{ {
return (void *) base; return (volatile void *) base;
} }
static inline void static inline void

View file

@ -26,7 +26,8 @@ enum
{ {
OBJ_TYPE_ELF, OBJ_TYPE_ELF,
OBJ_TYPE_MEMDISK, OBJ_TYPE_MEMDISK,
OBJ_TYPE_CONFIG OBJ_TYPE_CONFIG,
OBJ_TYPE_FONT
}; };
/* The module header. */ /* The module header. */

View file

@ -0,0 +1 @@
#include <grub/machine/at_keyboard.h>

27
include/grub/mips/cache.h Normal file
View file

@ -0,0 +1,27 @@
/* cache.h - Flush the processor's cache. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2004,2007 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/>.
*/
#ifndef GRUB_CPU_CACHE_H
#define GRUB_CPU_CACHE_H 1
#include <grub/symbol.h>
#include <grub/types.h>
void EXPORT_FUNC(grub_cpu_flush_cache) (void *start, grub_size_t size, int type);
#endif

1
include/grub/mips/cmos.h Normal file
View file

@ -0,0 +1 @@
#include <grub/machine/cmos.h>

62
include/grub/mips/io.h Normal file
View file

@ -0,0 +1,62 @@
/*
* 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/>.
*/
#ifndef GRUB_IO_H
#define GRUB_IO_H 1
#include <grub/types.h>
typedef grub_addr_t grub_port_t;
static __inline unsigned char
grub_inb (grub_port_t port)
{
return *(volatile grub_uint8_t *) port;
}
static __inline unsigned short int
grub_inw (grub_port_t port)
{
return *(volatile grub_uint16_t *) port;
}
static __inline unsigned int
grub_inl (grub_port_t port)
{
return *(volatile grub_uint32_t *) port;
}
static __inline void
grub_outb (unsigned char value, grub_port_t port)
{
*(volatile grub_uint8_t *) port = value;
}
static __inline void
grub_outw (unsigned short int value, grub_port_t port)
{
*(volatile grub_uint16_t *) port = value;
}
static __inline void
grub_outl (unsigned int value, grub_port_t port)
{
*(volatile grub_uint32_t *) port = value;
}
#endif /* _SYS_IO_H */

View file

@ -0,0 +1,65 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2005,2006,2007,2008 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/>.
*/
#ifndef GRUB_KERNEL_CPU_HEADER
#define GRUB_KERNEL_CPU_HEADER 1
#define GRUB_MOD_ALIGN 0x1
/* Non-zero value is only needed for PowerMacs. */
#define GRUB_MOD_GAP 0x0
#define GRUB_KERNEL_MACHINE_LINK_ALIGN 32
#define GRUB_KERNEL_CPU_RAW_SIZE 0x200
#define GRUB_KERNEL_CPU_COMPRESSED_SIZE 0x8
#define GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE 0xc
#define GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE 0x10
#define GRUB_KERNEL_CPU_PREFIX GRUB_KERNEL_CPU_RAW_SIZE
#define GRUB_KERNEL_CPU_DATA_END GRUB_KERNEL_CPU_RAW_SIZE + 0x48
#define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_KERNEL_CPU_RAW_SIZE
#define GRUB_KERNEL_MACHINE_PREFIX GRUB_KERNEL_CPU_PREFIX
#define GRUB_KERNEL_MACHINE_DATA_END GRUB_KERNEL_CPU_DATA_END
#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE
#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE
#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_KERNEL_CPU_COMPRESSED_SIZE
#define GRUB_PLATFORM_IMAGE_FORMATS "raw, elf"
#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw"
#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW
#ifndef ASM_FILE
typedef enum {
GRUB_PLATFORM_IMAGE_RAW,
GRUB_PLATFORM_IMAGE_ELF
}
grub_platform_image_format_t;
#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW
#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF
/* The prefix which points to the directory where GRUB modules and its
configuration file are located. */
extern char grub_prefix[];
#endif
#endif

View file

@ -0,0 +1,38 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2004,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 <config.h>
#ifdef HAVE___ASHLDI3
void EXPORT_FUNC (__ashldi3) (void);
#endif
#ifdef HAVE___ASHRDI3
void EXPORT_FUNC (__ashrdi3) (void);
#endif
#ifdef HAVE___LSHRDI3
void EXPORT_FUNC (__lshrdi3) (void);
#endif
#ifdef HAVE___UCMPDI2
void EXPORT_FUNC (__ucmpdi2) (void);
#endif
#ifdef HAVE___BSWAPSI2
void EXPORT_FUNC (__bswapsi2) (void);
#endif
#ifdef HAVE___BSWAPDI2
void EXPORT_FUNC (__bswapdi2) (void);
#endif

1
include/grub/mips/pci.h Normal file
View file

@ -0,0 +1 @@
#include <grub/machine/pci.h>

View file

View file

@ -0,0 +1,36 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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
* 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/>.
*/
#ifndef GRUB_KERNEL_MACHINE_HEADER
#define GRUB_KERNEL_MACHINE_HEADER 1
#include <grub/symbol.h>
#include <grub/cpu/kernel.h>
#ifndef ASM_FILE
void EXPORT_FUNC (grub_reboot) (void);
void EXPORT_FUNC (grub_halt) (void);
/* The prefix which points to the directory where GRUB modules and its
configuration file are located. */
extern char grub_prefix[];
#endif
#endif /* ! GRUB_KERNEL_MACHINE_HEADER */

View file

View file

@ -0,0 +1,54 @@
/*
* 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/>.
*/
#ifndef GRUB_MEMORY_MACHINE_HEADER
#define GRUB_MEMORY_MACHINE_HEADER 1
#ifndef ASM_FILE
#include <grub/symbol.h>
#include <grub/err.h>
#include <grub/types.h>
#endif
#define GRUB_MACHINE_MEMORY_STACK_HIGH 0x80f00000
#define GRUB_MACHINE_MEMORY_USABLE 0x81000000
#define GRUB_MACHINE_MEMORY_AVAILABLE 1
#ifndef ASM_FILE
grub_err_t EXPORT_FUNC (grub_machine_mmap_iterate)
(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
static inline grub_err_t
grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
grub_uint64_t size __attribute__ ((unused)),
int type __attribute__ ((unused)),
int handle __attribute__ ((unused)))
{
return GRUB_ERR_NONE;
}
static inline grub_err_t
grub_machine_mmap_unregister (int handle __attribute__ ((unused)))
{
return GRUB_ERR_NONE;
}
#endif
#endif

View file

@ -0,0 +1,24 @@
/*
* 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/>.
*/
#ifndef GRUB_MACHINE_SERIAL_HEADER
#define GRUB_MACHINE_SERIAL_HEADER 1
#define GRUB_MACHINE_SERIAL_PORTS { 0x140003f8 }
#endif

View file

@ -0,0 +1,34 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2004,2005,2007 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/>.
*/
#ifndef KERNEL_MACHINE_TIME_HEADER
#define KERNEL_MACHINE_TIME_HEADER 1
#include <grub/symbol.h>
#define GRUB_TICKS_PER_SECOND 1000
/* Return the real time in ticks. */
grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
static inline void
grub_cpu_idle(void)
{
}
#endif /* ! KERNEL_MACHINE_TIME_HEADER */

View file

@ -0,0 +1,39 @@
/*
* 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/>.
*/
#ifndef GRUB_RELOCATOR_CPU_HEADER
#define GRUB_RELOCATOR_CPU_HEADER 1
#include <grub/types.h>
#include <grub/err.h>
struct grub_relocator32_state
{
/* gpr[0] is ignored since it's hardwired to 0. */
grub_uint32_t gpr[32];
/* Register holding target $pc. */
int jumpreg;
};
void *grub_relocator32_alloc (grub_size_t size);
grub_err_t grub_relocator32_boot (void *relocator, grub_uint32_t dest,
struct grub_relocator32_state state);
void *grub_relocator32_realloc (void *relocator, grub_size_t size);
void grub_relocator32_free (void *relocator);
#endif /* ! GRUB_RELOCATOR_CPU_HEADER */

View file

@ -0,0 +1,27 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2004,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
* 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/>.
*/
#ifndef GRUB_SETJMP_CPU_HEADER
#define GRUB_SETJMP_CPU_HEADER 1
typedef unsigned long grub_jmp_buf[11];
int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice));
void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
#endif /* ! GRUB_SETJMP_CPU_HEADER */

0
include/grub/mips/time.h Normal file
View file

38
include/grub/mips/types.h Normal file
View file

@ -0,0 +1,38 @@
/*
* GRUB -- GRand Unified Bootloader
* 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
* 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/>.
*/
#ifndef GRUB_TYPES_CPU_HEADER
#define GRUB_TYPES_CPU_HEADER 1
/* The size of void *. */
#define GRUB_TARGET_SIZEOF_VOID_P 4
/* The size of long. */
#define GRUB_TARGET_SIZEOF_LONG 4
#ifdef GRUB_CPU_MIPSEL
/* mipsEL is little-endian. */
#undef GRUB_TARGET_WORDS_BIGENDIAN
#elif defined (GRUB_CPU_MIPS)
/* mips is big-endian. */
#define GRUB_TARGET_WORDS_BIGENDIAN
#elif !defined (GRUB_SYMBOL_GENERATOR)
#error Neither GRUB_CPU_MIPS nor GRUB_CPU_MIPSEL is defined
#endif
#endif /* ! GRUB_TYPES_CPU_HEADER */

View file

@ -0,0 +1,25 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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
* 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/>.
*/
#ifndef GRUB_MACHINE_AT_KEYBOARD_HEADER
#define GRUB_MACHINE_AT_KEYBOARD_HEADER 1
#define KEYBOARD_REG_DATA 0xbfd00060
#define KEYBOARD_REG_STATUS 0xbfd00064
#endif

View file

View file

@ -0,0 +1,28 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2008 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/>.
*/
#ifndef GRUB_CPU_CMOS_H
#define GRUB_CPU_CMOS_H 1
#include <grub/types.h>
#include <grub/cpu/io.h>
#define GRUB_CMOS_ADDR_REG 0xbfd00070
#define GRUB_CMOS_DATA_REG 0xbfd00071
#endif /* GRUB_CPU_CMOS_H */

View file

@ -0,0 +1,32 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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
* 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/>.
*/
#ifndef GRUB_KERNEL_MACHINE_HEADER
#define GRUB_KERNEL_MACHINE_HEADER 1
#include <grub/symbol.h>
#include <grub/cpu/kernel.h>
#ifndef ASM_FILE
void EXPORT_FUNC (grub_reboot) (void);
void EXPORT_FUNC (grub_halt) (void);
#endif
#endif /* ! GRUB_KERNEL_MACHINE_HEADER */

View file

View file

@ -0,0 +1,68 @@
/*
* 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/>.
*/
#ifndef GRUB_MEMORY_MACHINE_HEADER
#define GRUB_MEMORY_MACHINE_HEADER 1
#ifndef ASM_FILE
#include <grub/symbol.h>
#include <grub/err.h>
#include <grub/types.h>
#endif
#define GRUB_MACHINE_MEMORY_STACK_HIGH 0x801ffff0
#define GRUB_ARCH_LOWMEMVSTART 0x80000000
#define GRUB_ARCH_LOWMEMPSTART 0x00000000
#define GRUB_ARCH_LOWMEMMAXSIZE 0x10000000
#define GRUB_ARCH_HIGHMEMPSTART 0x10000000
#define GRUB_MACHINE_MEMORY_AVAILABLE 1
#define GRUB_MACHINE_MEMORY_MAX_TYPE 1
/* This one is special: it's used internally but is never reported
by firmware. */
#define GRUB_MACHINE_MEMORY_HOLE 2
#define GRUB_MACHINE_MEMORY_RESERVED GRUB_MACHINE_MEMORY_HOLE
#ifndef ASM_FILE
grub_err_t EXPORT_FUNC (grub_machine_mmap_iterate)
(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
static inline grub_err_t
grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
grub_uint64_t size __attribute__ ((unused)),
int type __attribute__ ((unused)),
int handle __attribute__ ((unused)))
{
return GRUB_ERR_NONE;
}
static inline grub_err_t
grub_machine_mmap_unregister (int handle __attribute__ ((unused)))
{
return GRUB_ERR_NONE;
}
grub_uint64_t grub_mmap_get_lower (void);
grub_uint64_t grub_mmap_get_upper (void);
extern grub_uint32_t EXPORT_VAR (grub_arch_memsize);
extern grub_uint32_t EXPORT_VAR (grub_arch_highmemsize);
#endif
#endif

View file

@ -0,0 +1,105 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2008 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/>.
*/
#ifndef GRUB_MACHINE_PCI_H
#define GRUB_MACHINE_PCI_H 1
#include <grub/types.h>
#include <grub/cpu/io.h>
#define GRUB_PCI_NUM_BUS 1
#define GRUB_PCI_NUM_DEVICES 16
#define GRUB_MACHINE_PCI_IO_BASE 0xbfd00000
#define GRUB_MACHINE_PCI_CONFSPACE 0xbfe80000
#define GRUB_MACHINE_PCI_CONF_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00118)
#define GRUB_MACHINE_PCI_IO_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00110)
#define GRUB_MACHINE_PCI_WIN_MASK_SIZE 6
#define GRUB_MACHINE_PCI_WIN_MASK ((1 << GRUB_MACHINE_PCI_WIN_MASK_SIZE) - 1)
/* We have 3 PCI windows. */
#define GRUB_MACHINE_PCI_NUM_WIN 3
/* Each window is 64MiB. */
#define GRUB_MACHINE_PCI_WIN_SHIFT 26
#define GRUB_MACHINE_PCI_WIN_OFFSET_MASK ((1 << GRUB_MACHINE_PCI_WIN_SHIFT) - 1)
#define GRUB_MACHINE_PCI_WIN_SIZE 0x04000000
/* Graphical acceleration takes 1 MiB away. */
#define GRUB_MACHINE_PCI_WIN1_SIZE 0x03f00000
#define GRUB_MACHINE_PCI_WIN1_ADDR 0xb0000000
#define GRUB_MACHINE_PCI_WIN2_ADDR 0xb4000000
#define GRUB_MACHINE_PCI_WIN3_ADDR 0xb8000000
static inline grub_uint32_t
grub_pci_read (grub_pci_address_t addr)
{
GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
return *(volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONFSPACE
| (addr & 0x03ff));
}
static inline grub_uint16_t
grub_pci_read_word (grub_pci_address_t addr)
{
GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
return *(volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONFSPACE
| (addr & 0x03ff));
}
static inline grub_uint8_t
grub_pci_read_byte (grub_pci_address_t addr)
{
GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
return *(volatile grub_uint8_t *) (GRUB_MACHINE_PCI_CONFSPACE
| (addr & 0x03ff));
}
static inline void
grub_pci_write (grub_pci_address_t addr, grub_uint32_t data)
{
GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
*(volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONFSPACE
| (addr & 0x03ff)) = data;
}
static inline void
grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data)
{
GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
*(volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONFSPACE
| (addr & 0x03ff)) = data;
}
static inline void
grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data)
{
GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
*(volatile grub_uint8_t *) (GRUB_MACHINE_PCI_CONFSPACE
| (addr & 0x03ff)) = data;
}
volatile void *
grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)),
grub_addr_t base, grub_size_t size);
void
grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)),
volatile void *mem,
grub_size_t size __attribute__ ((unused)));
#endif /* GRUB_MACHINE_PCI_H */

View file

@ -0,0 +1,24 @@
/*
* 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/>.
*/
#ifndef GRUB_MACHINE_SERIAL_HEADER
#define GRUB_MACHINE_SERIAL_HEADER 1
#define GRUB_MACHINE_SERIAL_PORTS { 0xbff003f8 }
#endif

View file

@ -0,0 +1,37 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2004,2005,2007 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/>.
*/
#ifndef KERNEL_MACHINE_TIME_HEADER
#define KERNEL_MACHINE_TIME_HEADER 1
#include <grub/symbol.h>
#define GRUB_TICKS_PER_SECOND (grub_arch_cpuclock / 2)
/* Return the real time in ticks. */
grub_uint64_t EXPORT_FUNC (grub_get_rtc) (void);
extern grub_uint32_t EXPORT_VAR (grub_arch_busclock);
extern grub_uint32_t EXPORT_VAR (grub_arch_cpuclock);
static inline void
grub_cpu_idle(void)
{
}
#endif /* ! KERNEL_MACHINE_TIME_HEADER */

View file

@ -17,8 +17,8 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GRUB_SERIAL_MACHINE_HEADER #ifndef GRUB_SERIAL_HEADER
#define GRUB_SERIAL_MACHINE_HEADER 1 #define GRUB_SERIAL_HEADER 1
/* Macros. */ /* Macros. */

View file

@ -23,7 +23,7 @@
#include <grub/symbol.h> #include <grub/symbol.h>
#include <grub/cpu/time.h> #include <grub/cpu/time.h>
#ifdef GRUB_MACHINE_EMU #if defined (GRUB_MACHINE_EMU) || defined (GRUB_UTIL)
#define GRUB_TICKS_PER_SECOND 100000 #define GRUB_TICKS_PER_SECOND 100000
#else #else
#include <grub/machine/time.h> #include <grub/machine/time.h>

View file

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

View file

@ -172,7 +172,7 @@ grub_elf32_phdr_iterate (grub_elf_t elf,
/* Calculate the amount of memory spanned by the segments. */ /* Calculate the amount of memory spanned by the segments. */
grub_size_t 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_start = (Elf32_Addr) -1;
Elf32_Addr segments_end = 0; Elf32_Addr segments_end = 0;
@ -198,6 +198,9 @@ grub_elf32_size (grub_elf_t elf)
grub_elf32_phdr_iterate (elf, calcsize, 0); grub_elf32_phdr_iterate (elf, calcsize, 0);
if (base)
*base = 0;
if (nr_phdrs == 0) if (nr_phdrs == 0)
{ {
grub_error (GRUB_ERR_BAD_OS, "no program headers present"); grub_error (GRUB_ERR_BAD_OS, "no program headers present");
@ -211,10 +214,12 @@ grub_elf32_size (grub_elf_t elf)
return 0; return 0;
} }
if (base)
*base = segments_start;
return segments_end - segments_start; return segments_end - segments_start;
} }
/* Load every loadable segment into memory specified by `_load_hook'. */ /* Load every loadable segment into memory specified by `_load_hook'. */
grub_err_t grub_err_t
grub_elf32_load (grub_elf_t _elf, grub_elf32_load_hook_t _load_hook, 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. */ /* Calculate the amount of memory spanned by the segments. */
grub_size_t 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_start = (Elf64_Addr) -1;
Elf64_Addr segments_end = 0; Elf64_Addr segments_end = 0;
@ -379,6 +384,9 @@ grub_elf64_size (grub_elf_t elf)
grub_elf64_phdr_iterate (elf, calcsize, 0); grub_elf64_phdr_iterate (elf, calcsize, 0);
if (base)
*base = 0;
if (nr_phdrs == 0) if (nr_phdrs == 0)
{ {
grub_error (GRUB_ERR_BAD_OS, "no program headers present"); grub_error (GRUB_ERR_BAD_OS, "no program headers present");
@ -392,6 +400,9 @@ grub_elf64_size (grub_elf_t elf)
return 0; return 0;
} }
if (base)
*base = segments_start;
return segments_end - segments_start; return segments_end - segments_start;
} }

View file

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

View file

@ -159,6 +159,9 @@ grub_main (void)
/* Load pre-loaded modules and free the space. */ /* Load pre-loaded modules and free the space. */
grub_register_exported_symbols (); grub_register_exported_symbols ();
#ifdef GRUB_LINKER_HAVE_INIT
grub_arch_dl_init_linker ();
#endif
grub_load_modules (); grub_load_modules ();
/* It is better to set the root device as soon as possible, /* It is better to set the root device as soon as possible,

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);
}

35
kern/mips/init.c Normal file
View file

@ -0,0 +1,35 @@
/*
* 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/kernel.h>
#include <grub/env.h>
#include <grub/mips/kernel.h>
void
grub_machine_set_prefix (void)
{
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 @@
/* kern/i386/datetime.c - x86 CMOS datetime function. /* kern/cmos_datetime.c - CMOS datetime function.
* *
* GRUB -- GRand Unified Bootloader * GRUB -- GRand Unified Bootloader
* Copyright (C) 2008 Free Software Foundation, Inc. * Copyright (C) 2008,2009 Free Software Foundation, Inc.
* *
* GRUB is free software: you can redistribute it and/or modify * GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -18,7 +18,7 @@
*/ */
#include <grub/datetime.h> #include <grub/datetime.h>
#include <grub/i386/cmos.h> #include <grub/cmos.h>
grub_err_t grub_err_t
grub_get_datetime (struct grub_datetime *datetime) grub_get_datetime (struct grub_datetime *datetime)

View file

@ -36,7 +36,7 @@ extern grub_uint8_t grub_relocator32_backward_start;
extern grub_uint8_t grub_relocator32_backward_end; extern grub_uint8_t grub_relocator32_backward_end;
#define REGW_SIZEOF (2 * sizeof (grub_uint32_t)) #define REGW_SIZEOF (2 * sizeof (grub_uint32_t))
#define JUMP_SIZEOF (sizeof (grub_uint32_t)) #define JUMP_SIZEOF (2 * sizeof (grub_uint32_t))
#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator32_##x##_end \ #define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator32_##x##_end \
- &grub_relocator32_##x##_start) - &grub_relocator32_##x##_start)
@ -64,6 +64,9 @@ write_jump (int regn, void **target)
/* j $r. */ /* j $r. */
*(grub_uint32_t *) *target = (regn<<21) | 0x8; *(grub_uint32_t *) *target = (regn<<21) | 0x8;
*target = ((grub_uint32_t *) *target) + 1; *target = ((grub_uint32_t *) *target) + 1;
/* nop. */
*(grub_uint32_t *) *target = 0;
*target = ((grub_uint32_t *) *target) + 1;
} }
static void static void

View file

@ -21,8 +21,8 @@
.p2align 4 /* force 16-byte alignment */ .p2align 4 /* force 16-byte alignment */
VARIABLE (grub_relocator32_forward_start) VARIABLE (grub_relocator32_forward_start)
move $12, $9 move $a0, $9
move $13, $10 move $a1, $10
copycont1: copycont1:
lb $11,0($8) lb $11,0($8)
@ -32,31 +32,13 @@ copycont1:
addiu $10, $10, 0xffff addiu $10, $10, 0xffff
bne $10, $0, copycont1 bne $10, $0, copycont1
move $9, $12 #include "../../kern/mips/cache_flush.S"
move $10, $13
cachecont1a:
cache 1,0($12)
addiu $12, $12, 0x1
addiu $13, $13, 0xffff
bne $13, $0, cachecont1a
sync
move $12, $9
move $13, $10
cachecont1b:
cache 0,0($12)
addiu $12, $12, 0x1
addiu $13, $13, 0xffff
bne $13, $0, cachecont1b
sync
VARIABLE (grub_relocator32_forward_end) VARIABLE (grub_relocator32_forward_end)
VARIABLE (grub_relocator32_backward_start) VARIABLE (grub_relocator32_backward_start)
move $12, $9 move $a0, $9
move $13, $10 move $a1, $10
addu $9, $9, $10 addu $9, $9, $10
addu $8, $8, $10 addu $8, $8, $10
@ -71,23 +53,6 @@ copycont2:
addiu $10, 0xffff addiu $10, 0xffff
bne $10, $0, copycont2 bne $10, $0, copycont2
move $9, $12 #include "../../kern/mips/cache_flush.S"
move $10, $13
cachecont2a:
cache 1,0($12)
addiu $12, $12, 0x1
addiu $13, $13, 0xffff
bne $13, $0, cachecont2a
sync
move $12, $9
move $13, $10
cachecont2b:
cache 0,0($12)
addiu $12, $12, 0x1
addiu $13, $13, 0xffff
bne $13, $0, cachecont2b
sync
VARIABLE (grub_relocator32_backward_end) VARIABLE (grub_relocator32_backward_end)

65
lib/mips/setjmp.S Normal file
View file

@ -0,0 +1,65 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,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/symbol.h>
.file "setjmp.S"
.text
/*
* int grub_setjmp (grub_jmp_buf env)
*/
FUNCTION(grub_setjmp)
sw $s0, 0($a0)
sw $s1, 4($a0)
sw $s2, 8($a0)
sw $s3, 12($a0)
sw $s4, 16($a0)
sw $s5, 20($a0)
sw $s6, 24($a0)
sw $s7, 28($a0)
sw $s8, 32($a0)
sw $gp, 36($a0)
sw $sp, 40($a0)
sw $ra, 44($a0)
move $v0, $zero
move $v1, $zero
jr $ra
/*
* int grub_longjmp (grub_jmp_buf env, int val)
*/
FUNCTION(grub_longjmp)
lw $s0, 0($a0)
lw $s1, 4($a0)
lw $s2, 8($a0)
lw $s3, 12($a0)
lw $s4, 16($a0)
lw $s5, 20($a0)
lw $s6, 24($a0)
lw $s7, 28($a0)
lw $s8, 32($a0)
lw $gp, 36($a0)
lw $sp, 40($a0)
lw $ra, 44($a0)
move $v0, $a1
bne $v0, $zero, 1f
addiu $v0, $v0, 1
1:
move $v1, $zero
jr $ra

389
loader/mips/linux.c Normal file
View file

@ -0,0 +1,389 @@
/* linux.c - boot Linux */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2004,2005,2007,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/elf.h>
#include <grub/elfload.h>
#include <grub/loader.h>
#include <grub/dl.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/machine/loader.h>
#include <grub/command.h>
#include <grub/mips/relocator.h>
#include <grub/machine/memory.h>
/* For frequencies. */
#include <grub/pci.h>
#include <grub/machine/time.h>
#define ELF32_LOADMASK (0x00000000UL)
#define ELF64_LOADMASK (0x0000000000000000ULL)
static grub_dl_t my_mod;
static int loaded;
static grub_size_t linux_size;
static grub_uint8_t *playground;
static grub_addr_t target_addr, entry_addr;
static int linux_argc;
static grub_off_t argv_off, envp_off;
static grub_off_t rd_addr_arg_off, rd_size_arg_off;
static int initrd_loaded = 0;
static grub_err_t
grub_linux_boot (void)
{
struct grub_relocator32_state state;
/* Boot the kernel. */
state.gpr[1] = entry_addr;
state.gpr[4] = linux_argc;
state.gpr[5] = target_addr + argv_off;
state.gpr[6] = target_addr + envp_off;
state.jumpreg = 1;
grub_relocator32_boot (playground, target_addr, state);
return GRUB_ERR_NONE;
}
static grub_err_t
grub_linux_release_mem (void)
{
grub_relocator32_free (playground);
return GRUB_ERR_NONE;
}
static grub_err_t
grub_linux_unload (void)
{
grub_err_t err;
err = grub_linux_release_mem ();
grub_dl_unref (my_mod);
loaded = 0;
return err;
}
static grub_err_t
grub_linux_load32 (grub_elf_t elf, void **extra_mem, grub_size_t extra_size)
{
Elf32_Addr base;
int extraoff;
/* Linux's entry point incorrectly contains a virtual address. */
entry_addr = elf->ehdr.ehdr32.e_entry & ~ELF32_LOADMASK;
linux_size = grub_elf32_size (elf, &base);
if (linux_size == 0)
return grub_errno;
target_addr = base;
/* Pad it; the kernel scribbles over memory beyond its load address. */
linux_size += 0x100000;
linux_size = ALIGN_UP (base + linux_size, 4) - base;
extraoff = linux_size;
linux_size += extra_size;
playground = grub_relocator32_alloc (linux_size);
if (!playground)
return grub_errno;
*extra_mem = playground + extraoff;
/* Now load the segments into the area we claimed. */
auto grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load);
grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load)
{
if (phdr->p_type != PT_LOAD)
{
*do_load = 0;
return 0;
}
*do_load = 1;
/* Linux's program headers incorrectly contain virtual addresses.
* Translate those to physical, and offset to the area we claimed. */
*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, void **extra_mem, grub_size_t extra_size)
{
Elf64_Addr base;
int extraoff;
/* Linux's entry point incorrectly contains a virtual address. */
entry_addr = elf->ehdr.ehdr64.e_entry & ~ELF64_LOADMASK;
linux_size = grub_elf64_size (elf, &base);
if (linux_size == 0)
return grub_errno;
target_addr = base;
/* Pad it; the kernel scribbles over memory beyond its load address. */
linux_size += 0x100000;
linux_size = ALIGN_UP (base + linux_size, 4) - base;
extraoff = linux_size;
linux_size += extra_size;
playground = grub_relocator32_alloc (linux_size);
if (!playground)
return grub_errno;
*extra_mem = playground + extraoff;
/* Now load the segments into the area we claimed. */
auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load);
grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load)
{
if (phdr->p_type != PT_LOAD)
{
*do_load = 0;
return 0;
}
*do_load = 1;
/* Linux's program headers incorrectly contain virtual addresses.
* Translate those to physical, and offset to the area we claimed. */
*addr = (grub_addr_t) (phdr->p_paddr - base + playground);
return 0;
}
return grub_elf64_load (elf, offset_phdr, 0, 0);
}
static grub_err_t
grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
{
grub_elf_t elf = 0;
int i;
int size;
void *extra = NULL;
grub_uint32_t *linux_argv, *linux_envp;
char *linux_args, *linux_envs;
grub_err_t err;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
elf = grub_elf_open (argv[0]);
if (! elf)
return grub_errno;
if (elf->ehdr.ehdr32.e_type != ET_EXEC)
{
grub_elf_close (elf);
return grub_error (GRUB_ERR_UNKNOWN_OS,
"This ELF file is not of the right type\n");
}
/* Release the previously used memory. */
grub_loader_unset ();
loaded = 0;
/* For arguments. */
linux_argc = argc;
/* Main arguments. */
size = (linux_argc) * sizeof (grub_uint32_t);
/* Initrd address and size. */
size += 2 * sizeof (grub_uint32_t);
/* NULL terminator. */
size += sizeof (grub_uint32_t);
/* First argument is always "a0". */
size += ALIGN_UP (sizeof ("a0"), 4);
/* Normal arguments. */
for (i = 1; i < argc; i++)
size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4);
/* rd arguments. */
size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4);
size += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4);
/* For the environment. */
size += sizeof (grub_uint32_t);
size += 4 * sizeof (grub_uint32_t);
size += ALIGN_UP (sizeof ("memsize=XXXXXXXXXXXXXXXXXXXX"), 4)
+ ALIGN_UP (sizeof ("highmemsize=XXXXXXXXXXXXXXXXXXXX"), 4)
+ ALIGN_UP (sizeof ("busclock=XXXXXXXXXX"), 4)
+ ALIGN_UP (sizeof ("cpuclock=XXXXXXXXXX"), 4);
if (grub_elf_is_elf32 (elf))
err = grub_linux_load32 (elf, &extra, size);
else
if (grub_elf_is_elf64 (elf))
err = grub_linux_load64 (elf, &extra, size);
else
err = grub_error (GRUB_ERR_BAD_FILE_TYPE, "Unknown ELF class");
grub_elf_close (elf);
if (err)
return err;
linux_argv = extra;
argv_off = (grub_uint8_t *) linux_argv - (grub_uint8_t *) playground;
extra = linux_argv + (linux_argc + 1 + 2);
linux_args = extra;
grub_memcpy (linux_args, "a0", sizeof ("a0"));
*linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground
+ target_addr;
linux_argv++;
linux_args += ALIGN_UP (sizeof ("a0"), 4);
for (i = 1; i < argc; i++)
{
grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1);
*linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground
+ target_addr;
linux_argv++;
linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4);
}
/* Reserve space for rd arguments. */
rd_addr_arg_off = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground;
linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4);
*linux_argv = 0;
linux_argv++;
rd_size_arg_off = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground;
linux_args += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4);
*linux_argv = 0;
linux_argv++;
*linux_argv = 0;
extra = linux_args;
linux_envp = extra;
envp_off = (grub_uint8_t *) linux_envp - (grub_uint8_t *) playground;
linux_envs = (char *) (linux_envp + 5);
grub_sprintf (linux_envs, "memsize=%lld", (unsigned long long) grub_mmap_get_lower () >> 20);
linux_envp[0] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground
+ target_addr;
linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
grub_sprintf (linux_envs, "highmemsize=%lld", (unsigned long long) grub_mmap_get_upper () >> 20);
linux_envp[1] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground
+ target_addr;
linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
grub_sprintf (linux_envs, "busclock=%d", grub_arch_busclock);
linux_envp[2] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground
+ target_addr;
linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
grub_sprintf (linux_envs, "cpuclock=%d", grub_arch_cpuclock);
linux_envp[3] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground
+ target_addr;
linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
linux_envp[4] = 0;
grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
initrd_loaded = 0;
loaded = 1;
grub_dl_ref (my_mod);
return GRUB_ERR_NONE;
}
static grub_err_t
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
{
grub_file_t file = 0;
grub_ssize_t size;
grub_size_t overhead;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "No initrd specified");
if (!loaded)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load Linux first.");
if (initrd_loaded)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Only one initrd can be loaded.");
file = grub_file_open (argv[0]);
if (! file)
return grub_errno;
size = grub_file_size (file);
overhead = ALIGN_UP (target_addr + linux_size + 0x10000, 0x10000)
- (target_addr + linux_size);
playground = grub_relocator32_realloc (playground,
linux_size + overhead + size);
if (!playground)
{
grub_file_close (file);
return grub_errno;
}
if (grub_file_read (file, playground + linux_size + overhead, size) != size)
{
grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
grub_file_close (file);
return grub_errno;
}
grub_sprintf ((char *) playground + rd_addr_arg_off, "rd_start=0x%llx",
(unsigned long long) target_addr + linux_size + overhead);
((grub_uint32_t *) (playground + argv_off))[linux_argc]
= target_addr + rd_addr_arg_off;
linux_argc++;
grub_sprintf ((char *) playground + rd_size_arg_off, "rd_size=0x%llx",
(unsigned long long) size);
((grub_uint32_t *) (playground + argv_off))[linux_argc]
= target_addr + rd_size_arg_off;
linux_argc++;
initrd_loaded = 1;
grub_file_close (file);
return GRUB_ERR_NONE;
}
static grub_command_t cmd_linux, cmd_initrd;
GRUB_MOD_INIT(linux)
{
cmd_linux = grub_register_command ("linux", grub_cmd_linux,
0, N_("Load Linux."));
cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
0, N_("Load initrd."));
my_mod = mod;
}
GRUB_MOD_FINI(linux)
{
grub_unregister_command (cmd_linux);
grub_unregister_command (cmd_initrd);
}

View file

@ -111,7 +111,7 @@ grub_linux_load32 (grub_elf_t elf)
if (entry == 0) if (entry == 0)
entry = 0x01400000; entry = 0x01400000;
linux_size = grub_elf32_size (elf); linux_size = grub_elf32_size (elf, 0);
if (linux_size == 0) if (linux_size == 0)
return grub_errno; return grub_errno;
/* Pad it; the kernel scribbles over memory beyond its load address. */ /* Pad it; the kernel scribbles over memory beyond its load address. */
@ -161,7 +161,7 @@ grub_linux_load64 (grub_elf_t elf)
if (entry == 0) if (entry == 0)
entry = 0x01400000; entry = 0x01400000;
linux_size = grub_elf64_size (elf); linux_size = grub_elf64_size (elf, 0);
if (linux_size == 0) if (linux_size == 0)
return grub_errno; return grub_errno;
/* Pad it; the kernel scribbles over memory beyond its load address. */ /* Pad it; the kernel scribbles over memory beyond its load address. */

View file

@ -247,7 +247,7 @@ grub_linux_load64 (grub_elf_t elf)
linux_entry = elf->ehdr.ehdr64.e_entry; linux_entry = elf->ehdr.ehdr64.e_entry;
linux_addr = 0x40004000; linux_addr = 0x40004000;
off = 0x4000; off = 0x4000;
linux_size = grub_elf64_size (elf); linux_size = grub_elf64_size (elf, 0);
if (linux_size == 0) if (linux_size == 0)
return grub_errno; return grub_errno;

View file

@ -0,0 +1,66 @@
/* Compute amount of lower and upper memory till the first hole. */
/*
* 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/memory.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/machine/memory.h>
grub_uint64_t
grub_mmap_get_lower (void)
{
grub_uint64_t lower = 0;
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
grub_uint32_t type)
{
if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
return 0;
if (addr == 0)
lower = size;
return 0;
}
grub_mmap_iterate (hook);
if (lower > GRUB_ARCH_LOWMEMMAXSIZE)
lower = GRUB_ARCH_LOWMEMMAXSIZE;
return lower;
}
grub_uint64_t
grub_mmap_get_upper (void)
{
grub_uint64_t upper = 0;
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
grub_uint32_t type)
{
if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
return 0;
if (addr <= GRUB_ARCH_HIGHMEMPSTART && addr + size
> GRUB_ARCH_HIGHMEMPSTART)
upper = addr + size - GRUB_ARCH_HIGHMEMPSTART;
return 0;
}
grub_mmap_iterate (hook);
return upper;
}

View file

@ -52,7 +52,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
#ifdef GRUB_MACHINE_MEMORY_AVAILABLE #ifdef GRUB_MACHINE_MEMORY_AVAILABLE
[GRUB_MACHINE_MEMORY_AVAILABLE] = 1, [GRUB_MACHINE_MEMORY_AVAILABLE] = 1,
#endif #endif
#ifdef GRUB_MACHINE_MEMORY_RESERVED #if defined (GRUB_MACHINE_MEMORY_RESERVED) && GRUB_MACHINE_MEMORY_RESERVED != GRUB_MACHINE_MEMORY_HOLE
[GRUB_MACHINE_MEMORY_RESERVED] = 3, [GRUB_MACHINE_MEMORY_RESERVED] = 3,
#endif #endif
#ifdef GRUB_MACHINE_MEMORY_ACPI #ifdef GRUB_MACHINE_MEMORY_ACPI

View file

@ -75,9 +75,9 @@ normal/menu_entry.c
normal/menu_text.c normal/menu_text.c
normal/misc.c normal/misc.c
term/i386/pc/serial.c term/serial.c
util/i386/pc/grub-mkimage.c util/grub-mkrawimage.c
util/i386/pc/grub-setup.c util/i386/pc/grub-setup.c
util/mkisofs/eltorito.c util/mkisofs/eltorito.c

View file

@ -17,13 +17,14 @@
*/ */
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/i386/pc/console.h> #include <grub/at_keyboard.h>
#include <grub/i386/at_keyboard.h> #include <grub/cpu/at_keyboard.h>
#include <grub/i386/io.h> #include <grub/cpu/io.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/term.h> #include <grub/term.h>
static short at_keyboard_status = 0; static short at_keyboard_status = 0;
static int pending_key = -1;
#define KEYBOARD_STATUS_SHIFT_L (1 << 0) #define KEYBOARD_STATUS_SHIFT_L (1 << 0)
#define KEYBOARD_STATUS_SHIFT_R (1 << 1) #define KEYBOARD_STATUS_SHIFT_R (1 << 1)
@ -237,14 +238,27 @@ grub_at_keyboard_getkey_noblock (void)
static int static int
grub_at_keyboard_checkkey (void) grub_at_keyboard_checkkey (void)
{ {
/* FIXME: this will be triggered by BREAK events. */ if (pending_key != -1)
return KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS)) ? 1 : -1; return 1;
pending_key = grub_at_keyboard_getkey_noblock ();
if (pending_key != -1)
return 1;
return -1;
} }
static int static int
grub_at_keyboard_getkey (void) grub_at_keyboard_getkey (void)
{ {
int key; int key;
if (pending_key != -1)
{
key = pending_key;
pending_key = -1;
return key;
}
do do
{ {
key = grub_at_keyboard_getkey_noblock (); key = grub_at_keyboard_getkey_noblock ();
@ -255,6 +269,8 @@ grub_at_keyboard_getkey (void)
static grub_err_t static grub_err_t
grub_keyboard_controller_init (void) grub_keyboard_controller_init (void)
{ {
pending_key = -1;
at_keyboard_status = 0;
grub_keyboard_controller_orig = grub_keyboard_controller_read (); grub_keyboard_controller_orig = grub_keyboard_controller_read ();
grub_keyboard_controller_write (grub_keyboard_controller_orig | KEYBOARD_SCANCODE_SET1); grub_keyboard_controller_write (grub_keyboard_controller_orig | KEYBOARD_SCANCODE_SET1);
return GRUB_ERR_NONE; return GRUB_ERR_NONE;

View file

@ -95,6 +95,7 @@ struct grub_virtual_screen
/* Color settings. */ /* Color settings. */
grub_video_color_t fg_color; grub_video_color_t fg_color;
grub_video_color_t bg_color; grub_video_color_t bg_color;
grub_video_color_t bg_color_display;
/* Text buffer for virtual screen. Contains (columns * rows) number /* Text buffer for virtual screen. Contains (columns * rows) number
of entries. */ of entries. */
@ -237,6 +238,8 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y,
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
virtual_screen.bg_color_display = grub_video_map_rgba(0, 0, 0, 0);
/* Clear out text buffer. */ /* Clear out text buffer. */
for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++) for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++)
clear_char (&(virtual_screen.text_buffer[i])); clear_char (&(virtual_screen.text_buffer[i]));
@ -341,7 +344,7 @@ redraw_screen_rect (unsigned int x, unsigned int y,
/* If bitmap is smaller than requested blit area, use background /* If bitmap is smaller than requested blit area, use background
color. */ color. */
color = virtual_screen.bg_color; color = virtual_screen.bg_color_display;
/* Fill right side of the bitmap if needed. */ /* Fill right side of the bitmap if needed. */
if ((x + width >= bitmap_width) && (y < bitmap_height)) if ((x + width >= bitmap_width) && (y < bitmap_height))
@ -388,7 +391,7 @@ redraw_screen_rect (unsigned int x, unsigned int y,
else else
{ {
/* Render background layer. */ /* Render background layer. */
color = virtual_screen.bg_color; color = virtual_screen.bg_color_display;
grub_video_fill_rect (color, x, y, width, height); grub_video_fill_rect (color, x, y, width, height);
/* Render text layer as replaced (to get texts background color). */ /* Render text layer as replaced (to get texts background color). */
@ -810,7 +813,8 @@ grub_gfxterm_cls (void)
/* Clear text layer. */ /* Clear text layer. */
grub_video_set_active_render_target (text_layer); grub_video_set_active_render_target (text_layer);
color = virtual_screen.bg_color; color = virtual_screen.bg_color;
grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height); grub_video_fill_rect (color, 0, 0, virtual_screen.width,
virtual_screen.height);
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
/* Mark virtual screen to be redrawn. */ /* Mark virtual screen to be redrawn. */

View file

@ -17,8 +17,7 @@
*/ */
#include <grub/machine/memory.h> #include <grub/machine/memory.h>
#include <grub/machine/serial.h> #include <grub/serial.h>
#include <grub/machine/console.h>
#include <grub/term.h> #include <grub/term.h>
#include <grub/types.h> #include <grub/types.h>
#include <grub/dl.h> #include <grub/dl.h>
@ -29,9 +28,8 @@
#include <grub/i18n.h> #include <grub/i18n.h>
#define TEXT_WIDTH 80 #define TEXT_WIDTH 80
#define TEXT_HEIGHT 25 #define TEXT_HEIGHT 24
static struct grub_term_output grub_serial_term_output;
static unsigned int xpos, ypos; static unsigned int xpos, ypos;
static unsigned int keep_track = 1; static unsigned int keep_track = 1;
static unsigned int registered = 0; static unsigned int registered = 0;
@ -40,6 +38,8 @@ static unsigned int registered = 0;
static char input_buf[8]; static char input_buf[8];
static unsigned int npending = 0; static unsigned int npending = 0;
static struct grub_term_output grub_serial_term_output;
/* Argument options. */ /* Argument options. */
static const struct grub_arg_option options[] = static const struct grub_arg_option options[] =
{ {
@ -55,7 +55,7 @@ static const struct grub_arg_option options[] =
/* Serial port settings. */ /* Serial port settings. */
struct serial_port struct serial_port
{ {
unsigned short port; grub_port_t port;
unsigned short divisor; unsigned short divisor;
unsigned short word_len; unsigned short word_len;
unsigned int parity; unsigned int parity;
@ -69,12 +69,13 @@ static struct serial_port serial_settings;
static const unsigned short *serial_hw_io_addr = (const unsigned short *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR; static const unsigned short *serial_hw_io_addr = (const unsigned short *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR;
#define GRUB_SERIAL_PORT_NUM 4 #define GRUB_SERIAL_PORT_NUM 4
#else #else
static const unsigned short serial_hw_io_addr[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; #include <grub/machine/serial.h>
static const grub_port_t serial_hw_io_addr[] = GRUB_MACHINE_SERIAL_PORTS;
#define GRUB_SERIAL_PORT_NUM (ARRAY_SIZE(serial_hw_io_addr)) #define GRUB_SERIAL_PORT_NUM (ARRAY_SIZE(serial_hw_io_addr))
#endif #endif
/* Return the port number for the UNITth serial device. */ /* Return the port number for the UNITth serial device. */
static inline unsigned short static inline grub_port_t
serial_hw_get_port (const unsigned int unit) serial_hw_get_port (const unsigned int unit)
{ {
if (unit < GRUB_SERIAL_PORT_NUM) if (unit < GRUB_SERIAL_PORT_NUM)
@ -150,7 +151,7 @@ serial_translate_key_sequence (void)
if (input_buf[0] != '\e' || input_buf[1] != '[') if (input_buf[0] != '\e' || input_buf[1] != '[')
return; return;
for (i = 0; ARRAY_SIZE (three_code_table); i++) for (i = 0; i < ARRAY_SIZE (three_code_table); i++)
if (three_code_table[i].key == input_buf[2]) if (three_code_table[i].key == input_buf[2])
{ {
input_buf[0] = three_code_table[i].ascii; input_buf[0] = three_code_table[i].ascii;
@ -255,6 +256,9 @@ grub_serial_getkey (void)
; ;
c = input_buf[0]; c = input_buf[0];
if (c == 0x7f)
c = GRUB_TERM_BACKSPACE;
grub_memmove (input_buf, input_buf + 1, --npending); grub_memmove (input_buf, input_buf + 1, --npending);
return c; return c;
@ -365,7 +369,7 @@ grub_serial_putchar (grub_uint32_t c)
break; break;
case '\n': case '\n':
if (ypos < TEXT_HEIGHT) if (ypos < TEXT_HEIGHT - 1)
ypos++; ypos++;
break; break;
@ -504,7 +508,7 @@ grub_cmd_serial (grub_extcmd_t cmd,
} }
if (state[1].set) if (state[1].set)
serial_settings.port = (unsigned short) grub_strtoul (state[1].arg, 0, 0); serial_settings.port = (grub_port_t) grub_strtoul (state[1].arg, 0, 0);
if (state[2].set) if (state[2].set)
{ {
@ -604,8 +608,8 @@ GRUB_MOD_INIT(serial)
{ {
cmd = grub_register_extcmd ("serial", grub_cmd_serial, cmd = grub_register_extcmd ("serial", grub_cmd_serial,
GRUB_COMMAND_FLAG_BOTH, GRUB_COMMAND_FLAG_BOTH,
N_("[OPTIONS...]"), "serial [OPTIONS...]",
N_("Configure serial port."), options); "Configure serial port.", options);
/* Set default settings. */ /* Set default settings. */
serial_settings.port = serial_hw_get_port (0); serial_settings.port = serial_hw_get_port (0);

View file

@ -100,7 +100,7 @@ load_note (Elf32_Phdr *phdr, FILE *out)
void void
load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir, load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir,
char *mods[], FILE *out, char *memdisk_path) char *mods[], FILE *out, char *memdisk_path, char *config_path)
{ {
char *module_img; char *module_img;
struct grub_util_path_list *path_list; struct grub_util_path_list *path_list;
@ -109,6 +109,7 @@ load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir,
size_t offset; size_t offset;
size_t total_module_size; size_t total_module_size;
size_t memdisk_size = 0; size_t memdisk_size = 0;
size_t config_size = 0;
path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
@ -122,6 +123,13 @@ load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir,
total_module_size += memdisk_size + sizeof (struct grub_module_header); total_module_size += memdisk_size + sizeof (struct grub_module_header);
} }
if (config_path)
{
config_size = ALIGN_UP(grub_util_get_image_size (config_path), 512);
grub_util_info ("the size of memory disk is 0x%x", config_size);
total_module_size += config_size + sizeof (struct grub_module_header);
}
for (p = path_list; p; p = p->next) for (p = path_list; p; p = p->next)
{ {
total_module_size += (grub_util_get_image_size (p->name) total_module_size += (grub_util_get_image_size (p->name)
@ -168,6 +176,19 @@ load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir,
offset += memdisk_size; offset += memdisk_size;
} }
if (config_path)
{
struct grub_module_header *header;
header = (struct grub_module_header *) (module_img + offset);
header->type = OBJ_TYPE_CONFIG;
header->size = grub_host_to_target32 (config_size + sizeof (*header));
offset += sizeof (*header);
grub_util_load_image (config_path, module_img + offset);
offset += config_size;
}
/* Write the module data to the new segment. */ /* Write the module data to the new segment. */
grub_util_write_image_at (module_img, total_module_size, grub_util_write_image_at (module_img, total_module_size,
@ -184,7 +205,7 @@ load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir,
} }
void void
add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[], char *memdisk_path) add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[], char *memdisk_path, char *config_path)
{ {
Elf32_Ehdr ehdr; Elf32_Ehdr ehdr;
Elf32_Phdr *phdrs = NULL; Elf32_Phdr *phdrs = NULL;
@ -273,7 +294,7 @@ add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[], char *
phdr->p_offset = grub_host_to_target32 (ALIGN_UP (grub_util_get_fp_size (out), phdr->p_offset = grub_host_to_target32 (ALIGN_UP (grub_util_get_fp_size (out),
GRUB_TARGET_SIZEOF_LONG)); GRUB_TARGET_SIZEOF_LONG));
load_modules (modbase, phdr, dir, mods, out, memdisk_path); load_modules (modbase, phdr, dir, mods, out, memdisk_path, config_path);
} }
if (chrp) if (chrp)
@ -316,6 +337,7 @@ static struct option options[] =
{"directory", required_argument, 0, 'd'}, {"directory", required_argument, 0, 'd'},
{"prefix", required_argument, 0, 'p'}, {"prefix", required_argument, 0, 'p'},
{"memdisk", required_argument, 0, 'm'}, {"memdisk", required_argument, 0, 'm'},
{"config", required_argument, 0, 'c'},
{"output", required_argument, 0, 'o'}, {"output", required_argument, 0, 'o'},
{"help", no_argument, 0, 'h'}, {"help", no_argument, 0, 'h'},
{"note", no_argument, 0, 'n'}, {"note", no_argument, 0, 'n'},
@ -338,6 +360,7 @@ Make a bootable image of GRUB.\n\
-d, --directory=DIR use images and modules under DIR [default=%s]\n\ -d, --directory=DIR use images and modules under DIR [default=%s]\n\
-p, --prefix=DIR set grub_prefix directory\n\ -p, --prefix=DIR set grub_prefix directory\n\
-m, --memdisk=FILE embed FILE as a memdisk image\n\ -m, --memdisk=FILE embed FILE as a memdisk image\n\
-c, --config=FILE embed FILE as boot config\n\
-o, --output=FILE output a generated image to FILE\n\ -o, --output=FILE output a generated image to FILE\n\
-h, --help display this message and exit\n\ -h, --help display this message and exit\n\
-n, --note add NOTE segment for CHRP Open Firmware\n\ -n, --note add NOTE segment for CHRP Open Firmware\n\
@ -358,6 +381,7 @@ main (int argc, char *argv[])
char *dir = NULL; char *dir = NULL;
char *prefix = NULL; char *prefix = NULL;
char *memdisk = NULL; char *memdisk = NULL;
char *config = NULL;
int chrp = 0; int chrp = 0;
set_program_name (argv[0]); set_program_name (argv[0]);
@ -366,7 +390,7 @@ main (int argc, char *argv[])
while (1) while (1)
{ {
int c = getopt_long (argc, argv, "d:p:m:o:hVvn", options, 0); int c = getopt_long (argc, argv, "d:p:m:c:o:hVvn", options, 0);
if (c == -1) if (c == -1)
break; break;
@ -392,6 +416,13 @@ main (int argc, char *argv[])
prefix = xstrdup ("(memdisk)/boot/grub"); prefix = xstrdup ("(memdisk)/boot/grub");
break; break;
case 'c':
if (config)
free (config);
config = xstrdup (optarg);
break;
case 'h': case 'h':
usage (0); usage (0);
break; break;
@ -422,7 +453,8 @@ main (int argc, char *argv[])
if (! fp) if (! fp)
grub_util_error ("cannot open %s", output); grub_util_error ("cannot open %s", output);
add_segments (dir ? : GRUB_LIBDIR, prefix, fp, chrp, argv + optind, memdisk); add_segments (dir ? : GRUB_LIBDIR, prefix, fp, chrp, argv + optind, memdisk,
config);
fclose (fp); fclose (fp);

View file

@ -30,10 +30,11 @@ PACKAGE_VERSION=@PACKAGE_VERSION@
target_cpu=@target_cpu@ target_cpu=@target_cpu@
platform=@platform@ platform=@platform@
host_os=@host_os@ host_os=@host_os@
font=@datadir@/@PACKAGE_TARNAME@/ascii.pf2
pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
grub_setup=${sbindir}/`echo grub-setup | sed ${transform}` grub_setup=${sbindir}/`echo grub-setup | sed ${transform}`
if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] || [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then
grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
else else
grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}` grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}`
@ -83,6 +84,11 @@ if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then
cat <<EOF cat <<EOF
--disk-module=MODULE disk module to use --disk-module=MODULE disk module to use
EOF EOF
fi
if [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then
cat <<EOF
--font=FILE font file to use
EOF
fi fi
cat <<EOF cat <<EOF
@ -109,6 +115,8 @@ for option in "$@"; do
exit 0 ;; exit 0 ;;
--modules=*) --modules=*)
modules=`echo "$option" | sed 's/--modules=//'` ;; modules=`echo "$option" | sed 's/--modules=//'` ;;
--font=*)
font=`echo "$option" | sed 's/--font=//'` ;;
--root-directory=*) --root-directory=*)
rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
--grub-setup=*) --grub-setup=*)
@ -150,7 +158,7 @@ done
# for make_system_path_relative_to_its_root() # for make_system_path_relative_to_its_root()
. ${libdir}/grub/grub-mkconfig_lib . ${libdir}/grub/grub-mkconfig_lib
if test "x$install_device" = x; then if test "x$install_device" = x && test "${target_cpu}-${platform}" != "mips-yeeloong"; then
echo "install_device not specified." 1>&2 echo "install_device not specified." 1>&2
usage usage
exit 1 exit 1
@ -297,15 +305,17 @@ prefix_drive=
config_opt= config_opt=
if [ "x${devabstraction_module}" = "x" ] ; then if [ "x${devabstraction_module}" = "x" ] ; then
if [ x"${install_device}" != x ]; then
if echo "${install_device}" | grep -qx "(.*)" ; then if echo "${install_device}" | grep -qx "(.*)" ; then
install_drive="${install_device}" install_drive="${install_device}"
else else
install_drive="`$grub_probe --target=drive --device ${install_device}`" install_drive="`$grub_probe --target=drive --device ${install_device}`"
fi fi
install_drive="`echo ${install_drive} | sed -e s/,[0-9]*[a-z]*//g`"
fi
grub_drive="`$grub_probe --target=drive --device ${grub_device}`" grub_drive="`$grub_probe --target=drive --device ${grub_device}`"
# Strip partition number # Strip partition number
install_drive="`echo ${install_drive} | sed -e s/,[0-9]*[a-z]*//g`"
grub_drive="`echo ${grub_drive} | sed -e s/,[0-9]*[a-z]*//g`" grub_drive="`echo ${grub_drive} | sed -e s/,[0-9]*[a-z]*//g`"
if [ "$disk_module" = ata ] ; then if [ "$disk_module" = ata ] ; then
# generic method (used on coreboot and ata mod) # generic method (used on coreboot and ata mod)
@ -339,6 +349,8 @@ if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}"
# Now perform the installation. # Now perform the installation.
$grub_setup ${setup_verbose} ${setup_force} --directory=${grubdir} --device-map=${device_map} \ $grub_setup ${setup_verbose} ${setup_force} --directory=${grubdir} --device-map=${device_map} \
${install_device} || exit 1 ${install_device} || exit 1
elif [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then
$grub_mkimage ${config_opt} -f ${font} -d ${pkglibdir} -O elf --output=/boot/grub.elf --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1
else else
$grub_mkimage ${config_opt} -d ${pkglibdir} --output=/boot/multiboot.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 $grub_mkimage ${config_opt} -d ${pkglibdir} --output=/boot/multiboot.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1
fi fi

View file

@ -22,6 +22,7 @@
#include <grub/machine/boot.h> #include <grub/machine/boot.h>
#include <grub/machine/kernel.h> #include <grub/machine/kernel.h>
#include <grub/machine/memory.h> #include <grub/machine/memory.h>
#include <grub/elf.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/kernel.h> #include <grub/kernel.h>
#include <grub/disk.h> #include <grub/disk.h>
@ -95,12 +96,19 @@ compress_kernel (char *kernel_img, size_t kernel_size,
static void static void
generate_image (const char *dir, char *prefix, FILE *out, char *mods[], generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
char *memdisk_path, char *config_path) char *memdisk_path, char *font_path, char *config_path,
#ifdef GRUB_PLATFORM_IMAGE_DEFAULT
grub_platform_image_format_t format
#else
int dummy __attribute__ ((unused))
#endif
)
{ {
char *kernel_img, *boot_img, *core_img; char *kernel_img, *core_img;
size_t kernel_size, boot_size, total_module_size, core_size; size_t kernel_size, total_module_size, core_size;
size_t memdisk_size = 0, config_size = 0; size_t memdisk_size = 0, font_size = 0, config_size = 0, config_size_pure = 0;
char *kernel_path, *boot_path; char *kernel_path;
size_t offset; size_t offset;
struct grub_util_path_list *path_list, *p, *next; struct grub_util_path_list *path_list, *p, *next;
struct grub_module_info *modinfo; struct grub_module_info *modinfo;
@ -119,9 +127,16 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
total_module_size += memdisk_size + sizeof (struct grub_module_header); total_module_size += memdisk_size + sizeof (struct grub_module_header);
} }
if (font_path)
{
font_size = ALIGN_UP(grub_util_get_image_size (font_path), 4);
total_module_size += font_size + sizeof (struct grub_module_header);
}
if (config_path) if (config_path)
{ {
config_size = grub_util_get_image_size (config_path) + 1; config_size_pure = grub_util_get_image_size (config_path) + 1;
config_size = ALIGN_UP(config_size_pure, 4);
grub_util_info ("the size of config file is 0x%x", config_size); grub_util_info ("the size of config file is 0x%x", config_size);
total_module_size += config_size + sizeof (struct grub_module_header); total_module_size += config_size + sizeof (struct grub_module_header);
} }
@ -150,15 +165,17 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
for (p = path_list; p; p = p->next) for (p = path_list; p; p = p->next)
{ {
struct grub_module_header *header; struct grub_module_header *header;
size_t mod_size; size_t mod_size, orig_size;
mod_size = grub_util_get_image_size (p->name); orig_size = grub_util_get_image_size (p->name);
mod_size = ALIGN_UP(orig_size, 4);
header = (struct grub_module_header *) (kernel_img + offset); header = (struct grub_module_header *) (kernel_img + offset);
memset (header, 0, sizeof (struct grub_module_header)); memset (header, 0, sizeof (struct grub_module_header));
header->type = OBJ_TYPE_ELF; header->type = OBJ_TYPE_ELF;
header->size = grub_host_to_target32 (mod_size + sizeof (*header)); header->size = grub_host_to_target32 (mod_size + sizeof (*header));
offset += sizeof (*header); offset += sizeof (*header);
memset (kernel_img + offset + orig_size, 0, mod_size - orig_size);
grub_util_load_image (p->name, kernel_img + offset); grub_util_load_image (p->name, kernel_img + offset);
offset += mod_size; offset += mod_size;
@ -178,6 +195,20 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
offset += memdisk_size; offset += memdisk_size;
} }
if (font_path)
{
struct grub_module_header *header;
header = (struct grub_module_header *) (kernel_img + offset);
memset (header, 0, sizeof (struct grub_module_header));
header->type = OBJ_TYPE_FONT;
header->size = grub_host_to_target32 (font_size + sizeof (*header));
offset += sizeof (*header);
grub_util_load_image (font_path, kernel_img + offset);
offset += font_size;
}
if (config_path) if (config_path)
{ {
struct grub_module_header *header; struct grub_module_header *header;
@ -189,8 +220,8 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
offset += sizeof (*header); offset += sizeof (*header);
grub_util_load_image (config_path, kernel_img + offset); grub_util_load_image (config_path, kernel_img + offset);
*(kernel_img + offset + config_size_pure - 1) = 0;
offset += config_size; offset += config_size;
*(kernel_img + offset - 1) = 0;
} }
grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size); grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size);
@ -202,6 +233,8 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
#if defined(GRUB_MACHINE_PCBIOS) #if defined(GRUB_MACHINE_PCBIOS)
{ {
unsigned num; unsigned num;
char *boot_path, *boot_img;
size_t boot_size;
num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS);
if (num > 0xffff) if (num > 0xffff)
grub_util_error (_("the core image is too big")); grub_util_error (_("the core image is too big"));
@ -209,7 +242,8 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
boot_path = grub_util_get_path (dir, "diskboot.img"); boot_path = grub_util_get_path (dir, "diskboot.img");
boot_size = grub_util_get_image_size (boot_path); boot_size = grub_util_get_image_size (boot_path);
if (boot_size != GRUB_DISK_SECTOR_SIZE) if (boot_size != GRUB_DISK_SECTOR_SIZE)
grub_util_error (_("diskboot.img size must be %u bytes"), GRUB_DISK_SECTOR_SIZE); grub_util_error (_("diskboot.img size must be %u bytes"),
GRUB_DISK_SECTOR_SIZE);
boot_img = grub_util_read_image (boot_path); boot_img = grub_util_read_image (boot_path);
@ -221,7 +255,8 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
block->len = grub_host_to_target16 (num); block->len = grub_host_to_target16 (num);
/* This is filled elsewhere. Verify it just in case. */ /* This is filled elsewhere. Verify it just in case. */
assert (block->segment == grub_host_to_target16 (GRUB_BOOT_MACHINE_KERNEL_SEG assert (block->segment
== grub_host_to_target16 (GRUB_BOOT_MACHINE_KERNEL_SEG
+ (GRUB_DISK_SECTOR_SIZE >> 4))); + (GRUB_DISK_SECTOR_SIZE >> 4)));
} }
@ -233,6 +268,8 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
{ {
char *rom_img; char *rom_img;
size_t rom_size; size_t rom_size;
char *boot_path, *boot_img;
size_t boot_size;
boot_path = grub_util_get_path (dir, "boot.img"); boot_path = grub_util_get_path (dir, "boot.img");
boot_size = grub_util_get_image_size (boot_path); boot_size = grub_util_get_image_size (boot_path);
@ -245,12 +282,12 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
memset (rom_img, 0, rom_size); memset (rom_img, 0, rom_size);
*((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR)) *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR))
= grub_cpu_to_le32 ((grub_uint32_t) -rom_size); = grub_host_to_target32 ((grub_uint32_t) -rom_size);
memcpy (rom_img, core_img, core_size); memcpy (rom_img, core_img, core_size);
*((grub_int32_t *) (boot_img + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR)) *((grub_int32_t *) (boot_img + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR))
= grub_cpu_to_le32 ((grub_uint32_t) -rom_size); = grub_host_to_target32 ((grub_uint32_t) -rom_size);
memcpy (rom_img + rom_size - boot_size, boot_img, boot_size); memcpy (rom_img + rom_size - boot_size, boot_img, boot_size);
@ -261,18 +298,17 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
free (boot_img); free (boot_img);
free (boot_path); free (boot_path);
} }
#endif #endif
#ifdef GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE #ifdef GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
*((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE))
= grub_cpu_to_le32 (total_module_size); = grub_host_to_target32 (total_module_size);
#endif #endif
*((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE))
= grub_cpu_to_le32 (kernel_size); = grub_host_to_target32 (kernel_size);
#ifdef GRUB_KERNEL_MACHINE_COMPRESSED_SIZE #ifdef GRUB_KERNEL_MACHINE_COMPRESSED_SIZE
*((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE)) *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE))
= grub_cpu_to_le32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE); = grub_host_to_target32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE);
#endif #endif
#if defined(GRUB_KERNEL_MACHINE_INSTALL_DOS_PART) && defined(GRUB_KERNEL_MACHINE_INSTALL_BSD_PART) #if defined(GRUB_KERNEL_MACHINE_INSTALL_DOS_PART) && defined(GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)
@ -281,16 +317,79 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
if (prefix[0] == '(') if (prefix[0] == '(')
{ {
*((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART)) *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART))
= grub_cpu_to_le32 (-2); = grub_host_to_target32 (-2);
*((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)) *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART))
= grub_cpu_to_le32 (-2); = grub_host_to_target32 (-2);
} }
#endif #endif
#ifdef GRUB_MACHINE_PCBIOS #ifdef GRUB_MACHINE_PCBIOS
if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_MACHINE_UPPER) if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_MACHINE_UPPER)
grub_util_error (_("core image is too big (%p > %p)"), grub_util_error (_("core image is too big (%p > %p)"),
GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, GRUB_MEMORY_MACHINE_UPPER); GRUB_KERNEL_MACHINE_LINK_ADDR + core_size,
GRUB_MEMORY_MACHINE_UPPER);
#endif
#if defined(GRUB_MACHINE_MIPS)
if (format == GRUB_PLATFORM_IMAGE_ELF)
{
char *elf_img;
size_t program_size;
Elf32_Ehdr *ehdr;
Elf32_Phdr *phdr;
grub_uint32_t target_addr;
program_size = ALIGN_UP (core_size, 4);
elf_img = xmalloc (program_size + sizeof (*ehdr) + sizeof (*phdr));
memset (elf_img, 0, program_size + sizeof (*ehdr) + sizeof (*phdr));
memcpy (elf_img + sizeof (*ehdr) + sizeof (*phdr), core_img, core_size);
ehdr = (void *) elf_img;
phdr = (void *) (elf_img + sizeof (*ehdr));
memcpy (ehdr->e_ident, ELFMAG, SELFMAG);
ehdr->e_ident[EI_CLASS] = ELFCLASS32;
#ifdef GRUB_CPU_MIPSEL
ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
#else
ehdr->e_ident[EI_DATA] = ELFDATA2MSB;
#endif
ehdr->e_ident[EI_VERSION] = EV_CURRENT;
ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE;
ehdr->e_type = grub_host_to_target16 (ET_EXEC);
ehdr->e_machine = grub_host_to_target16 (EM_MIPS);
ehdr->e_version = grub_host_to_target32 (EV_CURRENT);
ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr);
ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr));
ehdr->e_phnum = grub_host_to_target16 (1);
/* No section headers. */
ehdr->e_shoff = grub_host_to_target32 (0);
ehdr->e_shentsize = grub_host_to_target16 (0);
ehdr->e_shnum = grub_host_to_target16 (0);
ehdr->e_shstrndx = grub_host_to_target16 (0);
ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr));
phdr->p_type = grub_host_to_target32 (PT_LOAD);
phdr->p_offset = grub_host_to_target32 (sizeof (*ehdr) + sizeof (*phdr));
phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X);
target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR
+ kernel_size + total_module_size, 32);
ehdr->e_entry = grub_host_to_target32 (target_addr);
phdr->p_vaddr = grub_host_to_target32 (target_addr);
phdr->p_paddr = grub_host_to_target32 (target_addr);
phdr->p_align = grub_host_to_target32 (GRUB_KERNEL_MACHINE_LINK_ALIGN);
ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER
| EF_MIPS_PIC | EF_MIPS_CPIC);
phdr->p_filesz = grub_host_to_target32 (core_size);
phdr->p_memsz = grub_host_to_target32 (core_size);
free (core_img);
core_img = elf_img;
core_size = program_size + sizeof (*ehdr) + sizeof (*phdr);
}
#endif #endif
grub_util_write_image (core_img, core_size, out); grub_util_write_image (core_img, core_size, out);
@ -314,8 +413,12 @@ static struct option options[] =
{"directory", required_argument, 0, 'd'}, {"directory", required_argument, 0, 'd'},
{"prefix", required_argument, 0, 'p'}, {"prefix", required_argument, 0, 'p'},
{"memdisk", required_argument, 0, 'm'}, {"memdisk", required_argument, 0, 'm'},
{"font", required_argument, 0, 'f'},
{"config", required_argument, 0, 'c'}, {"config", required_argument, 0, 'c'},
{"output", required_argument, 0, 'o'}, {"output", required_argument, 0, 'o'},
#ifdef GRUB_PLATFORM_IMAGE_DEFAULT
{"format", required_argument, 0, 'O'},
#endif
{"help", no_argument, 0, 'h'}, {"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'}, {"version", no_argument, 0, 'V'},
{"verbose", no_argument, 0, 'v'}, {"verbose", no_argument, 0, 'v'},
@ -336,8 +439,17 @@ Make a bootable image of GRUB.\n\
-d, --directory=DIR use images and modules under DIR [default=%s]\n\ -d, --directory=DIR use images and modules under DIR [default=%s]\n\
-p, --prefix=DIR set grub_prefix directory [default=%s]\n\ -p, --prefix=DIR set grub_prefix directory [default=%s]\n\
-m, --memdisk=FILE embed FILE as a memdisk image\n\ -m, --memdisk=FILE embed FILE as a memdisk image\n\
-f, --font=FILE embed FILE as a boot font\n\
-c, --config=FILE embed FILE as boot config\n\ -c, --config=FILE embed FILE as boot config\n\
-o, --output=FILE output a generated image to FILE [default=stdout]\n\ -o, --output=FILE output a generated image to FILE [default=stdout]\n"
#ifdef GRUB_PLATFORM_IMAGE_DEFAULT
"\
-O, --format=FORMAT generate an image in format [default="
GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "]\n \
available formats: "
GRUB_PLATFORM_IMAGE_FORMATS "\n"
#endif
"\
-h, --help display this message and exit\n\ -h, --help display this message and exit\n\
-V, --version print version information and exit\n\ -V, --version print version information and exit\n\
-v, --verbose print verbose messages\n\ -v, --verbose print verbose messages\n\
@ -355,16 +467,18 @@ main (int argc, char *argv[])
char *dir = NULL; char *dir = NULL;
char *prefix = NULL; char *prefix = NULL;
char *memdisk = NULL; char *memdisk = NULL;
char *font = NULL;
char *config = NULL; char *config = NULL;
FILE *fp = stdout; FILE *fp = stdout;
#ifdef GRUB_PLATFORM_IMAGE_DEFAULT
set_program_name (argv[0]); grub_platform_image_format_t format = GRUB_PLATFORM_IMAGE_DEFAULT;
#endif
grub_util_init_nls (); grub_util_init_nls ();
while (1) while (1)
{ {
int c = getopt_long (argc, argv, "d:p:m:c:o:hVv", options, 0); int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:hVv", options, 0);
if (c == -1) if (c == -1)
break; break;
@ -378,6 +492,22 @@ main (int argc, char *argv[])
output = xstrdup (optarg); output = xstrdup (optarg);
break; break;
#ifdef GRUB_PLATFORM_IMAGE_DEFAULT
case 'O':
#ifdef GRUB_PLATFORM_IMAGE_RAW
if (strcmp (optarg, "raw") == 0)
format = GRUB_PLATFORM_IMAGE_RAW;
else
#endif
#ifdef GRUB_PLATFORM_IMAGE_ELF
if (strcmp (optarg, "elf") == 0)
format = GRUB_PLATFORM_IMAGE_ELF;
else
#endif
usage (1);
break;
#endif
case 'd': case 'd':
if (dir) if (dir)
free (dir); free (dir);
@ -397,6 +527,13 @@ main (int argc, char *argv[])
prefix = xstrdup ("(memdisk)/boot/grub"); prefix = xstrdup ("(memdisk)/boot/grub");
break; break;
case 'f':
if (font)
free (font);
font = xstrdup (optarg);
break;
case 'c': case 'c':
if (config) if (config)
free (config); free (config);
@ -438,7 +575,13 @@ main (int argc, char *argv[])
} }
generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp,
argv + optind, memdisk, config); argv + optind, memdisk, font, config,
#ifdef GRUB_PLATFORM_IMAGE_DEFAULT
format
#else
0
#endif
);
fclose (fp); fclose (fp);

229
video/sm712.c Normal file
View file

@ -0,0 +1,229 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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
* 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/>.
*/
#define grub_video_render_target grub_video_fbrender_target
#include <grub/err.h>
#include <grub/types.h>
#include <grub/dl.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/video.h>
#include <grub/video_fb.h>
#include <grub/pci.h>
static struct
{
struct grub_video_mode_info mode_info;
struct grub_video_render_target *render_target;
unsigned int bytes_per_scan_line;
unsigned int bytes_per_pixel;
grub_uint8_t *ptr;
int index_color_mode;
int mapped;
grub_uint32_t base;
grub_pci_device_t dev;
} framebuffer;
static grub_err_t
grub_video_sm712_video_init (void)
{
/* Reset frame buffer. */
grub_memset (&framebuffer, 0, sizeof(framebuffer));
return grub_video_fb_init ();
}
static grub_err_t
grub_video_sm712_video_fini (void)
{
if (framebuffer.mapped)
grub_pci_device_unmap_range (framebuffer.dev, framebuffer.ptr,
1024 * 600 * 2);
return grub_video_fb_fini ();
}
static grub_err_t
grub_video_sm712_setup (unsigned int width, unsigned int height,
unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused)))
{
int depth;
grub_err_t err;
int found = 0;
auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)));
int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)))
{
grub_pci_address_t addr;
grub_uint32_t class;
addr = grub_pci_make_address (dev, 2);
class = grub_pci_read (addr);
if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x0712126f)
return 0;
found = 1;
addr = grub_pci_make_address (dev, 4);
framebuffer.base = grub_pci_read (addr);
framebuffer.dev = dev;
return 1;
}
/* Decode depth from mode_type. If it is zero, then autodetect. */
depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
>> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
if ((width != 1024 && width != 0) || (height != 600 && height != 0)
|| (depth != 16 && depth != 0))
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"Only 1024x600x16 is supported");
grub_pci_iterate (find_card);
if (!found)
return grub_error (GRUB_ERR_IO, "Couldn't find graphics card");
if (found && framebuffer.base == 0)
{
/* FIXME: change framebuffer base */
}
/* Fill mode info details. */
framebuffer.mode_info.width = 1024;
framebuffer.mode_info.height = 600;
framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
framebuffer.mode_info.bpp = 16;
framebuffer.mode_info.bytes_per_pixel = 2;
framebuffer.mode_info.pitch = 1024 * 2;
framebuffer.mode_info.number_of_colors = 256;
framebuffer.mode_info.red_mask_size = 5;
framebuffer.mode_info.red_field_pos = 11;
framebuffer.mode_info.green_mask_size = 6;
framebuffer.mode_info.green_field_pos = 5;
framebuffer.mode_info.blue_mask_size = 5;
framebuffer.mode_info.blue_field_pos = 0;
framebuffer.mode_info.reserved_mask_size = 0;
framebuffer.mode_info.reserved_field_pos = 0;
framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info);
/* We can safely discard volatile attribute. */
framebuffer.ptr = (void *) grub_pci_device_map_range (framebuffer.dev,
framebuffer.base,
1024 * 600 * 2);
framebuffer.mapped = 1;
err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr);
if (err)
return err;
err = grub_video_fb_set_active_render_target (framebuffer.render_target);
if (err)
return err;
/* Copy default palette to initialize emulated palette. */
err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
grub_video_fbstd_colors);
return err;
}
static grub_err_t
grub_video_sm712_set_palette (unsigned int start, unsigned int count,
struct grub_video_palette_data *palette_data)
{
if (framebuffer.index_color_mode)
{
/* TODO: Implement setting indexed color mode palette to hardware. */
}
/* Then set color to emulated palette. */
return grub_video_fb_set_palette (start, count, palette_data);
}
static grub_err_t
grub_video_sm712_swap_buffers (void)
{
/* TODO: Implement buffer swapping. */
return GRUB_ERR_NONE;
}
static grub_err_t
grub_video_sm712_set_active_render_target (struct grub_video_render_target *target)
{
if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
target = framebuffer.render_target;
return grub_video_fb_set_active_render_target (target);
}
static grub_err_t
grub_video_sm712_get_info_and_fini (struct grub_video_mode_info *mode_info,
void **framebuf)
{
grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
*framebuf = (char *) framebuffer.ptr;
grub_video_fb_fini ();
return GRUB_ERR_NONE;
}
static struct grub_video_adapter grub_video_sm712_adapter =
{
.name = "SM712 Video Driver",
.init = grub_video_sm712_video_init,
.fini = grub_video_sm712_video_fini,
.setup = grub_video_sm712_setup,
.get_info = grub_video_fb_get_info,
.get_info_and_fini = grub_video_sm712_get_info_and_fini,
.set_palette = grub_video_sm712_set_palette,
.get_palette = grub_video_fb_get_palette,
.set_viewport = grub_video_fb_set_viewport,
.get_viewport = grub_video_fb_get_viewport,
.map_color = grub_video_fb_map_color,
.map_rgb = grub_video_fb_map_rgb,
.map_rgba = grub_video_fb_map_rgba,
.unmap_color = grub_video_fb_unmap_color,
.fill_rect = grub_video_fb_fill_rect,
.blit_bitmap = grub_video_fb_blit_bitmap,
.blit_render_target = grub_video_fb_blit_render_target,
.scroll = grub_video_fb_scroll,
.swap_buffers = grub_video_sm712_swap_buffers,
.create_render_target = grub_video_fb_create_render_target,
.delete_render_target = grub_video_fb_delete_render_target,
.set_active_render_target = grub_video_sm712_set_active_render_target,
.get_active_render_target = grub_video_fb_get_active_render_target,
.next = 0
};
GRUB_MOD_INIT(video_sm712)
{
grub_video_register (&grub_video_sm712_adapter);
}
GRUB_MOD_FINI(video_sm712)
{
grub_video_unregister (&grub_video_sm712_adapter);
}