merge with mainline

This commit is contained in:
BVK Chaitanya 2010-07-12 16:38:19 +05:30
commit 8d17eeeef2
170 changed files with 34663 additions and 3738 deletions

View file

@ -2,6 +2,7 @@
10_* 10_*
30_os-prober 30_os-prober
40_custom 40_custom
41_custom
aclocal.m4 aclocal.m4
ascii.bitmaps ascii.bitmaps
ascii.h ascii.h
@ -75,3 +76,4 @@ stamp-h.in
symlist.c symlist.c
trigtables.c trigtables.c
update-grub_lib update-grub_lib
unidata.c

1098
ChangeLog

File diff suppressed because it is too large Load diff

View file

@ -53,9 +53,13 @@ XGETTEXT = @XGETTEXT@
MSGMERGE = @MSGMERGE@ MSGMERGE = @MSGMERGE@
MSGFMT = @MSGFMT@ MSGFMT = @MSGFMT@
ifdef ENABLE_NLS
LINGUAS = $(shell for i in $(srcdir)/po/*.po ; do \ LINGUAS = $(shell for i in $(srcdir)/po/*.po ; do \
if test -e $$i ; then echo $$i ; fi ; \ if test -e $$i ; then echo $$i ; fi ; \
done | sed -e "s,.*/po/\(.*\)\.po$$,\1,") done | sed -e "s,.*/po/\(.*\)\.po$$,\1,")
else
LINGUAS =
endif
PACKAGE = @PACKAGE@ PACKAGE = @PACKAGE@
PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_NAME = @PACKAGE_NAME@
@ -164,7 +168,9 @@ DISTCLEANFILES = config.status config.cache config.log config.h \
MAINTAINER_CLEANFILES = $(srcdir)/configure $(srcdir)/aclocal.m4 \ MAINTAINER_CLEANFILES = $(srcdir)/configure $(srcdir)/aclocal.m4 \
$(MKFILES) $(srcdir)/config.guess \ $(MKFILES) $(srcdir)/config.guess \
$(srcdir)/config.sub $(srcdir)/install-sh $(srcdir)/missing \ $(srcdir)/config.sub $(srcdir)/install-sh $(srcdir)/missing \
$(srcdir)/DISTLIST $(srcdir)/config.h.in $(srcdir)/stamp-h.in $(INFOS) $(srcdir)/DISTLIST $(srcdir)/config.h.in $(srcdir)/stamp-h.in \
$(srcdir)/unidata.c \
$(INFOS)
# The default target. # The default target.
all: all-local all: all-local
@ -247,10 +253,9 @@ docs/stamp-vti: docs/grub.texi configure.ac
-@rm -f vti.tmp -@rm -f vti.tmp
@cp $(builddir)/docs/version.texi $@ @cp $(builddir)/docs/version.texi $@
# Use --force until such time as the documentation is cleaned up.
docs/grub.info: docs/grub.texi docs/version.texi docs/fdl.texi docs/grub.info: docs/grub.texi docs/version.texi docs/fdl.texi
$(MKDIR_P) docs $(MKDIR_P) docs
-$(MAKEINFO) -P $(builddir)/docs --no-split --force $< -o $@ $(MAKEINFO) -P $(builddir)/docs --no-split $< -o $@
ifeq (, $(FONT_SOURCE)) ifeq (, $(FONT_SOURCE))
else else
@ -276,7 +281,13 @@ ascii.bitmaps: $(FONT_SOURCE) grub-mkfont
ascii.h: ascii.bitmaps grub-bin2h ascii.h: ascii.bitmaps grub-bin2h
$(builddir)/grub-bin2h ascii_bitmaps < $< > $@ $(builddir)/grub-bin2h ascii_bitmaps < $< > $@
TARGET_CFLAGS += -DUSE_ASCII_FAILBACK=1 widthspec.bin: $(FONT_SOURCE) grub-mkfont
$(builddir)/grub-mkfont --width-spec -o $@ $(FONT_SOURCE)
widthspec.h: widthspec.bin grub-bin2h
$(builddir)/grub-bin2h widthspec < $< > $@
TARGET_CFLAGS += -DUSE_ASCII_FAILBACK=1 -DHAVE_UNIFONT_WIDTHSPEC=1
endif endif
endif endif
@ -323,26 +334,26 @@ install-local: all
if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
$(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \ $(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \
$(HELP2MAN) --section=1 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ PATH="$(builddir):$$PATH" $(HELP2MAN) --section=1 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $$file; \
done done
$(SHELL) $(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man8 $(SHELL) $(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man8
@list='$(sbin_UTILITIES)'; for file in $$list; do \ @list='$(sbin_UTILITIES)'; for file in $$list; do \
if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
$(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \ $(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \
$(HELP2MAN) --section=8 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ PATH="$(builddir):$$PATH" $(HELP2MAN) --section=8 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $$file; \
done done
@list='$(bin_SCRIPTS)'; for file in $$list; do \ @list='$(bin_SCRIPTS)'; for file in $$list; do \
if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
$(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \ $(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \
$(HELP2MAN) --section=1 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ PATH="$(builddir):$$PATH" $(HELP2MAN) --section=1 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $$file; \
done done
@list='$(sbin_SCRIPTS)'; for file in $$list; do \ @list='$(sbin_SCRIPTS)'; for file in $$list; do \
if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
$(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \ $(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \
$(HELP2MAN) --section=8 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ PATH="$(builddir):$$PATH" $(HELP2MAN) --section=8 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $$file; \
done done
$(SHELL) $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/grub.d $(SHELL) $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/grub.d
@list='$(grub-mkconfig_SCRIPTS)'; for file in $$list; do \ @list='$(grub-mkconfig_SCRIPTS)'; for file in $$list; do \

View file

@ -13,6 +13,8 @@ echo timestamp > stamp-h.in
python util/import_gcry.py lib/libgcrypt/ . python util/import_gcry.py lib/libgcrypt/ .
python util/import_unicode.py unicode/UnicodeData.txt unicode/BidiMirroring.txt unicode/ArabicShaping.txt unidata.c
for rmk in conf/*.rmk ${GRUB_CONTRIB}/*/conf/*.rmk; do for rmk in conf/*.rmk ${GRUB_CONTRIB}/*/conf/*.rmk; do
if test -e $rmk ; then if test -e $rmk ; then
ruby genmk.rb < $rmk > `echo $rmk | sed 's/\.rmk$/.mk/'` ruby genmk.rb < $rmk > `echo $rmk | sed 's/\.rmk$/.mk/'`

View file

@ -36,9 +36,6 @@ VARIABLE(grub_core_entry_addr)
.long 0 .long 0
1: 1:
/* Process VGA rom. */
call $0xc000, $0x3
/* Set up %ds, %ss, and %es. */ /* Set up %ds, %ss, and %es. */
xorw %ax, %ax xorw %ax, %ax
movw %ax, %ds movw %ax, %ds

View file

@ -0,0 +1,630 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2000,2001,2002,2003,2004,2005,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/>.
*/
#include <grub/mips/yeeloong/serial.h>
#include <grub/mips/yeeloong/pci.h>
#include <grub/mips/loongson.h>
#include <grub/pci.h>
#include <grub/serial.h>
#include <grub/cs5536.h>
#include <grub/smbus.h>
.set noreorder
.set noat
.set nomacro
.global start,_start,__start
start:
_start:
__start:
bal serial_hw_init
nop
/* Find CS5536 controller. */
/* $t4 chooses device in priority encoding. */
/* Resulting value is kept in GRUB_MACHINE_PCI_CONF_CTRL_REG.
This way we don't need to sacrifice a register for it. */
/* We have only one bus (0). Function is 0. */
lui $t0, %hi(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR)
lui $t1, %hi(GRUB_MACHINE_PCI_CONFSPACE)
lui $t3, %hi(GRUB_CS5536_PCIID)
addiu $t3, $t3, %lo(GRUB_CS5536_PCIID)
ori $t4, $zero, 1
lui $a0, %hi(no_cs5536)
1:
andi $t4, $t4, ((1 << GRUB_PCI_NUM_DEVICES) - 1)
beql $t4, $zero, fatal
addiu $a0, $a0, %lo(no_cs5536)
sw $t4, %lo(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) ($t0)
lw $t2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_PCI_REG_PCI_ID) ($t1)
bnel $t2, $t3, 1b
sll $t4, $t4, 1
bal message
addiu $a0, $a0, %lo(cs5536_found)
bal printhex
move $a0, $t4
/* Initialise SMBus controller. */
/* Set GPIO LBAR. */
lui $a0, %hi(GRUB_CS5536_MSR_GPIO_BAR)
addiu $a0, $a0, %lo(GRUB_CS5536_MSR_GPIO_BAR)
ori $a1, $zero, GRUB_CS5536_LBAR_GPIO
/* Set mask to 0xf and enabled bit to 1. */
bal wrmsr
ori $a2, $zero, ((GRUB_CS5536_LBAR_MASK_MASK \
| GRUB_CS5536_LBAR_ENABLE) >> 32)
/* Set SMBUS LBAR. */
lui $a0, %hi(GRUB_CS5536_MSR_SMB_BAR)
addiu $a0, $a0, %lo(GRUB_CS5536_MSR_SMB_BAR)
ori $a1, $zero, GRUB_CS5536_LBAR_SMBUS
/* Set mask to 0xf and enabled bit to 1. */
bal wrmsr
ori $a2, $zero, ((GRUB_CS5536_LBAR_MASK_MASK \
| GRUB_CS5536_LBAR_ENABLE) >> 32)
lui $a0, %hi(smbus_enabled)
bal message
addiu $a0, $a0, %lo(smbus_enabled)
/* Enable SMBus controller pins. */
lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO)
ori $t1, $zero, GRUB_GPIO_SMBUS_PINS
sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_OUT_EN) ($t0)
sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_OUT_AUX1) ($t0)
sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_IN_EN) ($t0)
sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_IN_AUX1) ($t0)
lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS)
/* Disable SMB. */
sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0)
/* Disable interrupts. */
sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1) ($t0)
/* Set as master. */
sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_ADDR) ($t0)
/* Launch SMBus controller at slowest speed possible. */
ori $t1, $zero, 0xff
sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL3) ($t0)
sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0)
/* Yeeloong has only one memory slot. */
/* Output first byte on serial for debugging. */
ori $a1, $zero, GRUB_SMB_RAM_START_ADDR
bal read_spd
move $a0, $zero
bal printhex
move $a0, $v0
bal read_spd
ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_TYPE_ADDR
ori $t0, $zero, GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2
lui $a0, %hi(unimplemented_memory_type)
bne $t0, $v0, fatal
addiu $a0, $a0, %hi(unimplemented_memory_type)
/* And here is our goal: DDR2 controller initialisation. */
lui $t0, %hi(GRUB_CPU_LOONGSON_CORECFG)
ld $t1, %lo(GRUB_CPU_LOONGSON_CORECFG) ($t0)
/* Use addiu for sign-extension. */
addiu $t2, $zero, ~(GRUB_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE|GRUB_CPU_LOONGSON_CORECFG_BUFFER_CPU)
and $t1, $t1, $t2
sd $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0)
b continue
. = start + GRUB_CPU_LOONGSON_FLASH_TLB_REFILL - GRUB_CPU_LOONGSON_FLASH_START
tlb_refill:
mfc0 $s1, GRUB_CPU_LOONGSON_COP0_EPC
mfc0 $s2, GRUB_CPU_LOONGSON_COP0_BADVADDR
move $s3, $ra
lui $a0, %hi(epc)
bal message
addiu $a0, $a0, %lo(epc)
bal printhex
move $a0, $s1
lui $a0, %hi(badvaddr)
bal message
addiu $a0, $a0, %lo(badvaddr)
bal printhex
move $a0, $s2
lui $a0, %hi(return_msg)
bal message
addiu $a0, $a0, %lo(return_msg)
bal printhex
move $a0, $s3
lui $a0, %hi(newline)
bal message
addiu $a0, $a0, %lo(newline)
lui $a0, %hi(unhandled_tlb_refill)
b fatal
addiu $a0, $a0, %lo(unhandled_tlb_refill)
. = start + GRUB_CPU_LOONGSON_FLASH_CACHE_ERROR - GRUB_CPU_LOONGSON_FLASH_START
cache_error:
lui $a0, %hi(unhandled_cache_error)
b fatal
addiu $a0, $a0, %lo(unhandled_cache_error)
. = start + GRUB_CPU_LOONGSON_FLASH_OTHER_EXCEPTION - GRUB_CPU_LOONGSON_FLASH_START
other_exception:
mfc0 $s0, GRUB_CPU_LOONGSON_COP0_CAUSE
mfc0 $s1, GRUB_CPU_LOONGSON_COP0_EPC
mfc0 $s2, GRUB_CPU_LOONGSON_COP0_BADVADDR
lui $a0, %hi(cause)
bal message
addiu $a0, $a0, %lo(cause)
bal printhex
move $a0, $s0
lui $a0, %hi(epc)
bal message
addiu $a0, $a0, %lo(epc)
bal printhex
move $a0, $s1
lui $a0, %hi(badvaddr)
bal message
addiu $a0, $a0, %lo(badvaddr)
bal printhex
move $a0, $s2
lui $a0, %hi(newline)
bal message
addiu $a0, $a0, %lo(newline)
lui $a0, %hi(unhandled_exception)
b fatal
addiu $a0, $a0, %lo(unhandled_exception)
/* Same as similarly named C function but in asm since
we need it early. */
/* In: none. Out: none. Clobbered: $t0, $t1, $a0. */
serial_hw_init:
lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT)
/* Turn off the interrupt. */
sb $zero, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_IER)($t0)
/* Set DLAB. */
ori $t1, $zero, UART_DLAB
sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LCR)($t0)
/* Set the baud rate 115200. */
ori $t1, $zero, GRUB_MACHINE_SERIAL_DIVISOR_115200
sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_DLL)($t0)
sb $zero, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_DLH)($t0)
/* Set the line status. */
ori $t1, $zero, (UART_NO_PARITY | UART_8BITS_WORD | UART_1_STOP_BIT)
sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LCR)($t0)
/* Enable the FIFO. */
ori $t1, $zero, UART_ENABLE_FIFO_TRIGGER1
sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_FCR)($t0)
/* Turn on DTR and RTS. */
ori $t1, $zero, UART_ENABLE_DTRRTS
sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_MCR)($t0)
/* Let message return to original caller. */
lui $a0, %hi(notification_string)
addiu $a0, $a0, %lo(notification_string)
/* Print message on serial console. */
/* In: $a0 = asciiz message. Out: none. Clobbered: $t0, $t1, $a0. */
message:
lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT)
1:
lb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LSR)($t0)
andi $t1, $t1, UART_EMPTY_TRANSMITTER
beq $t1, $zero, 1b
nop
lb $t1, 0($a0)
sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_TX)($t0)
bne $t1, $zero, 1b
addiu $a0, $a0, 1
jr $ra
nop
/* Print 32-bit hexadecimal on serial.
In: $a0. Out: None. Clobbered: $a0, $t0, $t1, $t2
*/
printhex:
lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT)
ori $t2, $zero, 8
1:
lb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LSR)($t0)
andi $t1, $t1, UART_EMPTY_TRANSMITTER
beq $t1, $zero, 1b
nop
srl $t1, $a0, 28
addiu $t1, $t1, -10
blt $t1, $zero, 2f
sll $a0, $a0, 4
addiu $t1, $t1, 'A'-10-'0'
2: addiu $t1, $t1, '0'+10
sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_TX)($t0)
addiu $t2, $t2, -1
bne $t2, $zero, 1b
nop
jr $ra
nop
fatal:
bal message
nop
self:
b self
nop
/* Write CS5536 MSR.
In: $a0 address, $a1 lower word, $a2 upper word.
Out: None
Clobbered: $t0
*/
wrmsr:
lui $t0, %hi(GRUB_MACHINE_PCI_CONFSPACE)
sw $a0, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_ADDR) ($t0)
sw $a1, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_DATA0) ($t0)
jr $ra
sw $a2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_DATA1) ($t0)
/* Wait for SMBus data or empty transmitter. */
/* In: $a0 = exception handler. Out: none. Clobbered: $t0, $t1 */
smbus_wait:
1:
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_STATUS + GRUB_MACHINE_PCI_IO_BASE)
lb $t0, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_STATUS + GRUB_MACHINE_PCI_IO_BASE) ($t0)
andi $t1, $t0, GRUB_CS5536_SMB_REG_STATUS_SDAST
bne $t1, $zero, return
nop
andi $t1, $t0, (GRUB_CS5536_SMB_REG_STATUS_BER | GRUB_CS5536_SMB_REG_STATUS_NACK)
beq $t1, $zero, 1b
nop
jr $a0
nop
return:
jr $ra
nop
/* Read SPD byte. In: $a0 byte, $a1 device. Out: $v0 read byte (0x100 on failure).
Clobbered: $t0, $t1, $t2, $t3, $a0. */
read_spd:
move $t2, $a0
move $t3, $ra
lui $a0, %hi(read_spd_fail)
addiu $a0, $a0, %hi(read_spd_fail)
/* Send START. */
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE)
lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_START
bal smbus_wait
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
/* Send device address. */
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE)
sll $t1, $a1, 1
bal smbus_wait
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0)
/* Send ACK. */
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE)
lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_ACK
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
/* Send byte address. */
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE)
bal smbus_wait
sb $t2, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0)
/* Send START. */
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE)
lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_START
bal smbus_wait
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
/* Send device address. */
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE)
sll $t1, $a1, 1
ori $t1, $t1, 1
bal smbus_wait
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0)
/* Send STOP. */
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE)
lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_STOP
bal smbus_wait
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE)
lb $v0, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0)
jr $t3
andi $v0, $v0, 0xff
read_spd_fail:
jr $t3
ori $v0, $v0, 0x100
notification_string: .asciz "GRUB "
no_cs5536: .asciz "No CS5536 found.\n\r"
cs5536_found: .asciz "CS5536 at "
sm_failed: .asciz "SM transaction failed.\n\r"
unhandled_tlb_refill: .asciz "Unhandled TLB refill.\n\r"
unhandled_cache_error: .asciz "Unhandled cache error.\n\r"
unhandled_exception: .asciz "Unhandled exception.\n\r"
smbus_enabled: .asciz "SMBus controller enabled.\n\r"
unimplemented_memory_type: .asciz "non-DDR2 memory isn't supported.\n\r"
no_cas_latency: .asciz "Couldn't determine CAS latency.\n\r"
cause: .asciz "Cause: "
epc: .asciz "\n\rEPC: "
badvaddr: .asciz "\n\rBadVaddr: "
newline: .asciz "\n\r"
return_msg: .asciz "\n\rReturn address: "
caches_enabled: .asciz "Caches enabled\n\r"
.p2align 3
regdump:
.quad 0x0100010000000101 /* 0 */
.quad 0x0100010100000000 /* 2 */
.quad 0x0101000001000000 /* 3 */
.quad 0x0100020200010101 /* 4 */
.quad 0x0a04030603050203 /* 6 */
.quad 0x0f0e040000010a0b /* 7 */
.quad 0x0000010200000102 /* 8 */
.quad 0x0000060c00000000 /* 9 */
.quad 0x2323233f3f1f0200 /* a */
.quad 0x5f7f232323232323 /* b */
.quad 0x002a3c0615000000 /* c */
.quad 0x002a002a002a002a /* d */
.quad 0x002a002a002a002a /* e */
.quad 0x00b40020006d0004 /* f */
.quad 0x070007ff00000087 /* 10 */
.quad 0x000000000016101f /* 11 */
.quad 0x001c000000000000 /* 12 */
.quad 0x28e1000200c8006b /* 13 */
.quad 0x0000204200c8002f /* 14 */
.quad 0x0000000000030d40 /* 15 */
.quad 0 /* 16 */
.quad 0 /* 17 */
.quad 0 /* 18 */
.quad 0 /* 19 */
.quad 0 /* 1a */
.quad 0 /* 1b */
.quad 0 /* 1c */
.p2align
write_dumpreg:
ld $t2, 0($t6)
sd $t2, 0($t4)
addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP
jr $ra
addiu $t6, $t6, GRUB_CPU_LOONGSON_DDR2_REG_SIZE
continue:
lui $t4, %hi(GRUB_CPU_LOONGSON_DDR2_BASE)
addiu $t4, $t4, %lo(GRUB_CPU_LOONGSON_DDR2_BASE)
lui $t6, %hi(regdump)
/* 0 */
bal write_dumpreg
addiu $t6, $t6, %lo(regdump)
/* 1 */
ori $a1, $a1, GRUB_SMB_RAM_START_ADDR
move $t8, $zero
lui $t5, 0x0001
bal read_spd
ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_BANKS_ADDR
ori $t7, $zero, 8
bne $v0, $t7, 1f
ori $t5, $t5, 0x0001
ori $t8, $t8, GRUB_CPU_LOONGSON_DDR2_REG1_HI_8BANKS
1:
dsll $t8, $t8, 32
or $t5, $t5, $t8
sd $t5, 0 ($t4)
addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP
/* 2 */
bal write_dumpreg
nop
/* 3 */
bal write_dumpreg
nop
/* 4 */
bal write_dumpreg
nop
/* 5 */
/* FIXME: figure termination resistance. */
ori $t5, $zero, 0x2
bal read_spd
ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_ROWS_ADDR
/* $v0 = 15 - $v0. */
xori $v0, $v0, 0xf
andi $v0, $v0, 0x7
sll $v0, $v0, 8
or $t5, $t5, $v0
/* Find the fastest supported CAS latency. */
bal read_spd
ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_ADDR
ori $t0, $zero, GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE
ori $t1, $zero, (1 << GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE)
2:
and $t2, $t1, $v0
bne $t2, $zero, 1f
ori $t3, $zero, 8
lui $a0, %hi(no_cas_latency)
beq $t0, $t3, fatal
addiu $a0, $a0, %lo(no_cas_latency)
addiu $t0, $t0, 1
b 2b
sll $t1, $t1, 1
1:
sll $t0, $t0, 16
or $t5, $t5, $t0
bal read_spd
ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_COLUMNS_ADDR
/* $v0 = 15 - ($v0 + 1) = 14 - $v0. */
addiu $v0, $v0, 1
xori $v0, $v0, 0xf
andi $v0, $v0, 0x7
sll $v0, 24
or $t5, $t5, $v0
sd $t5, 0 ($t4)
addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP
ori $t7, $zero, 0x16
1:
ld $t2, 0($t6)
sd $t2, 0($t4)
addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP
addiu $t7, $t7, -1
bne $t7, $zero, 1b
addiu $t6, $t6, GRUB_CPU_LOONGSON_DDR2_REG_SIZE
lui $t4, %hi(GRUB_CPU_LOONGSON_DDR2_BASE)
ld $t5, (%lo(GRUB_CPU_LOONGSON_DDR2_BASE) + 0x30) ($t4)
ori $t0, $zero, 1
dsll $t0, $t0, 40
or $t5, $t5, $t0
sd $t5, (%lo(GRUB_CPU_LOONGSON_DDR2_BASE) + 0x30) ($t4)
/* Desactivate DDR2 registers. */
lui $t0, %hi (GRUB_CPU_LOONGSON_CORECFG)
ld $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0)
ori $t1, $t1, GRUB_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE
sd $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0)
/* Enable cache. */
mfc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG
addiu $t1, $zero, ~GRUB_CPU_LOONGSON_CACHE_TYPE_MASK
and $t0, $t1, $t1
/* Set line size to 32 bytes and disabled cache. */
ori $t0, $t0, (GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_ILINESIZE \
| GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_DLINESIZE \
| GRUB_CPU_LOONGSON_CACHE_ACCELERATED)
mtc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG
/* Invalidate all I-cache entries. */
srl $t1, $t0, GRUB_CPU_LOONGSON_COP0_CACHE_ISIZE_SHIFT
andi $t1, $t1, GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK
ori $t2, $zero, (1 << (GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET \
- GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \
- GRUB_CPU_LOONGSON_I_CACHE_LOG_WAYS))
sll $t1, $t2, $t1
lui $t2, 0x8000
1:
cache GRUB_CPU_LOONGSON_COP0_I_INDEX_INVALIDATE, 0($t2)
addiu $t1, $t1, -1
bne $t1, $zero, 1b
addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_I_INDEX_BIT_OFFSET)
/* Invalidate all D-cache entries. */
srl $t1, $t0, GRUB_CPU_LOONGSON_COP0_CACHE_DSIZE_SHIFT
andi $t1, $t1, GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK
ori $t2, $zero, (1 << (GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET \
- GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \
- GRUB_CPU_LOONGSON_D_CACHE_LOG_WAYS))
sll $t1, $t2, $t1
lui $t2, 0x8000
mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO
mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI
1:
/* All four ways. */
cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 0($t2)
cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 1($t2)
cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 2($t2)
cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 3($t2)
addiu $t1, $t1, -1
bne $t1, $zero, 1b
addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET)
/* Invalidate all S-cache entries. */
ori $t1, $zero, (1 << (GRUB_CPU_LOONGSON_SECONDARY_CACHE_LOG_SIZE \
- GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \
- GRUB_CPU_LOONGSON_S_CACHE_LOG_WAYS))
lui $t2, 0x8000
mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO
mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI
1:
/* All four ways. */
cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 0($t2)
cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 1($t2)
cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 2($t2)
cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 3($t2)
addiu $t1, $t1, -1
bne $t1, $zero, 1b
addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET)
/* Finally enable cache. */
mfc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG
addiu $t1, $zero, ~GRUB_CPU_LOONGSON_CACHE_TYPE_MASK
and $t0, $t1, $t1
ori $t0, $t0, GRUB_CPU_LOONGSON_CACHE_CACHED
mtc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG
lui $a0, %hi(caches_enabled)
bal message
addiu $a0, $a0, %lo(caches_enabled)
/* Set ROM delay cycles to 1. */
lui $t0, %hi(GRUB_CPU_LOONGSON_LIOCFG)
lw $t1, %lo(GRUB_CPU_LOONGSON_LIOCFG) ($t0)
addiu $t2, $zero, ~(GRUB_CPU_LOONGSON_ROM_DELAY_MASK \
<< GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET)
and $t1, $t1, $t2
ori $t1, $t1, (1 << GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET)
sw $t1, %lo(GRUB_CPU_LOONGSON_LIOCFG) ($t0)
addiu $a0, $zero, -1
addiu $a1, $zero, -1
/* Take advantage of cache. */
lui $t0, %hi(cached_continue - 0x20000000)
addiu $t0, $t0, %lo(cached_continue - 0x20000000)
jr $t0
addiu $a2, $zero, -1
cached_continue:

View file

@ -213,3 +213,168 @@ grub_cs5536_read_spd (grub_port_t smbbase, grub_uint8_t dev,
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
/* Dump of GPIO connections. FIXME: Remove useless and macroify. */
static grub_uint32_t gpiodump[] = {
0xffff0000, 0x2ffdd002, 0xffff0000, 0xffff0000,
0x2fffd000, 0xffff0000, 0x1000efff, 0xefff1000,
0x3ffbc004, 0xffff0000, 0xffff0000, 0xffff0000,
0x3ffbc004, 0x3ffbc004, 0xffff0000, 0x00000000,
0xffff0000, 0xffff0000, 0x3ffbc004, 0x3f9bc064,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000,
0xffff0000, 0xffff0000, 0x0000ffff, 0xffff0000,
0xefff1000, 0xffff0000, 0xffff0000, 0xffff0000,
0xefff1000, 0xefff1000, 0xffff0000, 0x00000000,
0xffff0000, 0xffff0000, 0xefff1000, 0xffff0000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x50000000, 0x00000000, 0x00000000,
};
static inline void
set_io_space (grub_pci_device_t dev, int num, grub_uint16_t start,
grub_uint16_t len)
{
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_REGIONS_START + num,
((((grub_uint64_t) start + len - 4)
<< GRUB_CS5536_MSR_GL_REGION_IO_TOP_SHIFT)
& GRUB_CS5536_MSR_GL_REGION_TOP_MASK)
| (((grub_uint64_t) start
<< GRUB_CS5536_MSR_GL_REGION_IO_BASE_SHIFT)
& GRUB_CS5536_MSR_GL_REGION_BASE_MASK)
| GRUB_CS5536_MSR_GL_REGION_IO
| GRUB_CS5536_MSR_GL_REGION_ENABLE);
}
static inline void
set_iod (grub_pci_device_t dev, int num, int dest, int start, int mask)
{
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_IOD_START + num,
((grub_uint64_t) dest << GRUB_CS5536_IOD_DEST_SHIFT)
| (((grub_uint64_t) start & GRUB_CS5536_IOD_ADDR_MASK)
<< GRUB_CS5536_IOD_BASE_SHIFT)
| ((mask & GRUB_CS5536_IOD_ADDR_MASK)
<< GRUB_CS5536_IOD_MASK_SHIFT));
}
static inline void
set_p2d (grub_pci_device_t dev, int num, int dest, grub_uint32_t start)
{
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_P2D_START + num,
(((grub_uint64_t) dest) << GRUB_CS5536_P2D_DEST_SHIFT)
| ((grub_uint64_t) (start >> GRUB_CS5536_P2D_LOG_ALIGN)
<< GRUB_CS5536_P2D_BASE_SHIFT)
| (((1 << (32 - GRUB_CS5536_P2D_LOG_ALIGN)) - 1)
<< GRUB_CS5536_P2D_MASK_SHIFT));
}
void
grub_cs5536_init_geode (grub_pci_device_t dev)
{
int i;
/* Make sure GPIO is where we expect it to be. */
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GPIO_BAR,
GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_GPIO);
/* Setup GPIO. */
for (i = 0; i < (int) ARRAY_SIZE (gpiodump); i++)
((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_IO_BASE
+ GRUB_CS5536_LBAR_GPIO)) [i] = gpiodump[i];
/* Enable more BARs. */
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IRQ_MAP_BAR,
GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_IRQ_MAP);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_MFGPT_BAR,
GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_MFGPT);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_ACPI_BAR,
GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_ACPI);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_PM_BAR,
GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_PM);
/* Setup DIVIL. */
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LEG_IO,
GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86
| GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP
| GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0
| GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK,
(~GRUB_CS5536_DIVIL_LPC_INTERRUPTS) & 0xffff);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK,
GRUB_CS5536_DIVIL_LPC_INTERRUPTS);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL,
GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL_ENABLE);
/* Initialise USB controller. */
/* FIXME: assign adresses dynamically. */
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE,
GRUB_CS5536_MSR_USB_BASE_BUS_MASTER
| GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE
| 0x05024000);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE,
GRUB_CS5536_MSR_USB_BASE_BUS_MASTER
| GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE
| (0x20ULL << GRUB_CS5536_MSR_USB_EHCI_BASE_FLDJ_SHIFT)
| 0x05023000);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_CONTROLLER_BASE,
GRUB_CS5536_MSR_USB_BASE_BUS_MASTER
| GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE | 0x05020000);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OPTION_CONTROLLER_BASE,
GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE | 0x05022000);
set_p2d (dev, 0, GRUB_CS5536_DESTINATION_USB, 0x05020000);
set_p2d (dev, 1, GRUB_CS5536_DESTINATION_USB, 0x05022000);
set_p2d (dev, 5, GRUB_CS5536_DESTINATION_USB, 0x05024000);
set_p2d (dev, 6, GRUB_CS5536_DESTINATION_USB, 0x05023000);
{
volatile grub_uint32_t *oc;
oc = grub_pci_device_map_range (dev, 0x05022000,
GRUB_CS5536_USB_OPTION_REGS_SIZE);
oc[GRUB_CS5536_USB_OPTION_REG_UOCMUX] =
(oc[GRUB_CS5536_USB_OPTION_REG_UOCMUX]
& ~GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_MASK)
| GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_HC;
grub_pci_device_unmap_range (dev, oc, GRUB_CS5536_USB_OPTION_REGS_SIZE);
}
/* Setup IDE controller. */
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_IO_BAR,
GRUB_CS5536_LBAR_IDE
| GRUB_CS5536_MSR_IDE_IO_BAR_UNITS);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_CFG,
GRUB_CS5536_MSR_IDE_CFG_CHANNEL_ENABLE);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_TIMING,
(GRUB_CS5536_MSR_IDE_TIMING_PIO0
<< GRUB_CS5536_MSR_IDE_TIMING_DRIVE0_SHIFT)
| (GRUB_CS5536_MSR_IDE_TIMING_PIO0
<< GRUB_CS5536_MSR_IDE_TIMING_DRIVE1_SHIFT));
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_CAS_TIMING,
(GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_PIO0
<< GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_SHIFT)
| (GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0
<< GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE0_SHIFT)
| (GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0
<< GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE1_SHIFT));
/* Setup Geodelink PCI. */
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_PCI_CTRL,
(4ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_OUT_THR_SHIFT)
| (4ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_IN_THR_SHIFT)
| (8ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_LATENCY_SHIFT)
| GRUB_CS5536_MSR_GL_PCI_CTRL_IO_ENABLE
| GRUB_CS5536_MSR_GL_PCI_CTRL_MEMORY_ENABLE);
/* Setup windows. */
set_io_space (dev, 0, GRUB_CS5536_LBAR_SMBUS, GRUB_CS5536_SMBUS_REGS_SIZE);
set_io_space (dev, 1, GRUB_CS5536_LBAR_GPIO, GRUB_CS5536_GPIO_REGS_SIZE);
set_io_space (dev, 2, GRUB_CS5536_LBAR_MFGPT, GRUB_CS5536_MFGPT_REGS_SIZE);
set_io_space (dev, 3, GRUB_CS5536_LBAR_IRQ_MAP, GRUB_CS5536_IRQ_MAP_REGS_SIZE);
set_io_space (dev, 4, GRUB_CS5536_LBAR_PM, GRUB_CS5536_PM_REGS_SIZE);
set_io_space (dev, 5, GRUB_CS5536_LBAR_ACPI, GRUB_CS5536_ACPI_REGS_SIZE);
set_iod (dev, 0, GRUB_CS5536_DESTINATION_IDE, GRUB_ATA_CH0_PORT1, 0xffff8);
set_iod (dev, 1, GRUB_CS5536_DESTINATION_ACC, GRUB_CS5536_LBAR_ACC, 0xfff80);
set_iod (dev, 2, GRUB_CS5536_DESTINATION_IDE, GRUB_CS5536_LBAR_IDE, 0xffff0);
}

View file

@ -222,7 +222,6 @@ grub_ohci_pci_iter (grub_pci_device_t dev,
if ((revision & 0xFF) != 0x10) if ((revision & 0xFF) != 0x10)
goto fail; goto fail;
{ {
grub_uint32_t control; grub_uint32_t control;
/* Check SMM/BIOS ownership of OHCI (SMM = USB Legacy Support driver for BIOS) */ /* Check SMM/BIOS ownership of OHCI (SMM = USB Legacy Support driver for BIOS) */

View file

@ -21,6 +21,7 @@
#include <grub/mm.h> #include <grub/mm.h>
#include <grub/usb.h> #include <grub/usb.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/time.h>
/* USB Supports 127 devices, with device 0 as special case. */ /* USB Supports 127 devices, with device 0 as special case. */
static struct grub_usb_device *grub_usb_devs[128]; static struct grub_usb_device *grub_usb_devs[128];
@ -75,13 +76,46 @@ grub_usb_add_hub (grub_usb_device_t dev)
struct grub_usb_usb_hubdesc hubdesc; struct grub_usb_usb_hubdesc hubdesc;
grub_err_t err; grub_err_t err;
int i; int i;
grub_uint64_t timeout;
grub_usb_device_t next_dev;
grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
| GRUB_USB_REQTYPE_CLASS | GRUB_USB_REQTYPE_CLASS
| GRUB_USB_REQTYPE_TARGET_DEV), | GRUB_USB_REQTYPE_TARGET_DEV),
GRUB_USB_REQ_GET_DESCRIPTOR, GRUB_USB_REQ_GET_DESCRIPTOR,
(GRUB_USB_DESCRIPTOR_HUB << 8) | 0, (GRUB_USB_DESCRIPTOR_HUB << 8) | 0,
0, sizeof (hubdesc), (char *) &hubdesc); 0, sizeof (hubdesc), (char *) &hubdesc);
if (err)
return err;
grub_dprintf ("usb", "Hub descriptor:\n\t\t len:%d, typ:0x%02x, cnt:%d, char:0x%02x, pwg:%d, curr:%d\n",
hubdesc.length, hubdesc.type, hubdesc.portcnt,
hubdesc.characteristics, hubdesc.pwdgood,
hubdesc.current);
/* Activate the first configuration. Hubs should have only one conf. */
grub_dprintf ("usb", "Hub set configuration\n");
grub_usb_set_configuration (dev, 1);
/* Power on all Hub ports. */
for (i = 1; i <= hubdesc.portcnt; i++)
{
grub_dprintf ("usb", "Power on - port %d\n", i);
/* Power on the port and wait for possible device connect */
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
| GRUB_USB_REQTYPE_CLASS
| GRUB_USB_REQTYPE_TARGET_OTHER),
GRUB_USB_REQ_SET_FEATURE,
GRUB_USB_HUB_FEATURE_PORT_POWER,
i, 0, NULL);
/* Just ignore the device if some error happened */
if (err)
continue;
}
/* Wait for port power-on */
if (hubdesc.pwdgood >= 50)
grub_millisleep (hubdesc.pwdgood * 2);
else
grub_millisleep (100);
/* Iterate over the Hub ports. */ /* Iterate over the Hub ports. */
for (i = 1; i <= hubdesc.portcnt; i++) for (i = 1; i <= hubdesc.portcnt; i++)
@ -92,13 +126,13 @@ grub_usb_add_hub (grub_usb_device_t dev)
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
| GRUB_USB_REQTYPE_CLASS | GRUB_USB_REQTYPE_CLASS
| GRUB_USB_REQTYPE_TARGET_OTHER), | GRUB_USB_REQTYPE_TARGET_OTHER),
GRUB_USB_REQ_HUB_GET_PORT_STATUS, GRUB_USB_REQ_GET_STATUS,
0, i, sizeof (status), (char *) &status); 0, i, sizeof (status), (char *) &status);
/* Just ignore the device if the Hub does not report the /* Just ignore the device if the Hub does not report the
status. */ status. */
if (err) if (err)
continue; continue;
grub_dprintf ("usb", "Hub port %d status: 0x%02x\n", i, status);
/* If connected, reset and enable the port. */ /* If connected, reset and enable the port. */
if (status & GRUB_USB_HUB_STATUS_CONNECTED) if (status & GRUB_USB_HUB_STATUS_CONNECTED)
@ -116,21 +150,46 @@ grub_usb_add_hub (grub_usb_device_t dev)
speed = GRUB_USB_SPEED_FULL; speed = GRUB_USB_SPEED_FULL;
} }
/* A device is actually connected to this port, not enable /* A device is actually connected to this port.
the port. XXX: Why 0x03? According to some docs it * Now do reset of port. */
should be 0x0. Check the specification! */ grub_dprintf ("usb", "Reset hub port - port %d\n", i);
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
| GRUB_USB_REQTYPE_CLASS | GRUB_USB_REQTYPE_CLASS
| GRUB_USB_REQTYPE_TARGET_OTHER), | GRUB_USB_REQTYPE_TARGET_OTHER),
0x3, 0x4, i, 0, 0); GRUB_USB_REQ_SET_FEATURE,
GRUB_USB_HUB_FEATURE_PORT_RESET,
i, 0, 0);
/* If the Hub does not cooperate for this port, just skip /* If the Hub does not cooperate for this port, just skip
the port. */ the port. */
if (err) if (err)
continue; continue;
/* Wait for reset procedure done */
timeout = grub_get_time_ms () + 1000;
do
{
/* Get the port status. */
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
| GRUB_USB_REQTYPE_CLASS
| GRUB_USB_REQTYPE_TARGET_OTHER),
GRUB_USB_REQ_GET_STATUS,
0, i, sizeof (status), (char *) &status);
}
while (!err &&
!(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) &&
(grub_get_time_ms() < timeout) );
if (err || !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) )
continue;
/* Add the device and assign a device address to it. */ /* Add the device and assign a device address to it. */
grub_usb_hub_add_dev (&dev->controller, speed); grub_dprintf ("usb", "Call hub_add_dev - port %d\n", i);
next_dev = grub_usb_hub_add_dev (&dev->controller, speed);
if (! next_dev)
continue;
/* If the device is a Hub, scan it for more devices. */
if (next_dev->descdev.class == 0x09)
grub_usb_add_hub (next_dev);
} }
} }

View file

@ -23,19 +23,28 @@
#include <grub/term.h> #include <grub/term.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/gzio.h> #include <grub/gzio.h>
#include <grub/command.h> #include <grub/extcmd.h>
#include <grub/i18n.h> #include <grub/i18n.h>
static grub_err_t static const struct grub_arg_option options[] =
grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)), {
int argc, char **args) {"dos", -1, 0, N_("Accept DOS-style CR/NL line endings."), 0, 0},
{0, 0, 0, 0, 0, 0}
};
static grub_err_t
grub_cmd_cat (grub_extcmd_t cmd, int argc, char **args)
{ {
struct grub_arg_list *state = cmd->state;
int dos = 0;
grub_file_t file; grub_file_t file;
char buf[GRUB_DISK_SECTOR_SIZE]; char buf[GRUB_DISK_SECTOR_SIZE];
grub_ssize_t size; grub_ssize_t size;
int key = 0; int key = 0;
if (state[0].set)
dos = 1;
if (argc != 1) if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
@ -53,7 +62,12 @@ grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)),
unsigned char c = buf[i]; unsigned char c = buf[i];
if ((grub_isprint (c) || grub_isspace (c)) && c != '\r') if ((grub_isprint (c) || grub_isspace (c)) && c != '\r')
grub_putchar (c); grub_printf ("%c", c);
else if (dos && c == '\r' && i + 1 < size && buf[i + 1] == '\n')
{
grub_printf ("\n");
i++;
}
else else
{ {
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
@ -67,22 +81,23 @@ grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)),
; ;
} }
grub_putchar ('\n'); grub_xputs ("\n");
grub_refresh (); grub_refresh ();
grub_file_close (file); grub_file_close (file);
return 0; return 0;
} }
static grub_command_t cmd; static grub_extcmd_t cmd;
GRUB_MOD_INIT(cat) GRUB_MOD_INIT(cat)
{ {
cmd = grub_register_command_p1 ("cat", grub_cmd_cat, cmd = grub_register_extcmd ("cat", grub_cmd_cat, GRUB_COMMAND_FLAG_BOTH,
N_("FILE"), N_("Show the contents of a file.")); N_("FILE"), N_("Show the contents of a file."),
options);
} }
GRUB_MOD_FINI(cat) GRUB_MOD_FINI(cat)
{ {
grub_unregister_command (cmd); grub_unregister_extcmd (cmd);
} }

View file

@ -66,18 +66,24 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
while (unicode_last_screen_position < unicode_last_position && while (unicode_last_screen_position < unicode_last_position &&
stringwidth < ((grub_term_width (term) / 2) - 2)) stringwidth < ((grub_term_width (term) / 2) - 2))
{ {
struct grub_unicode_glyph glyph;
unicode_last_screen_position
+= grub_unicode_aglomerate_comb (unicode_last_screen_position,
unicode_last_position
- unicode_last_screen_position,
&glyph);
stringwidth stringwidth
+= grub_term_getcharwidth (term, += grub_term_getcharwidth (term, &glyph);
*unicode_last_screen_position);
unicode_last_screen_position++;
} }
grub_print_ucs4 (unicode_command_help, grub_print_ucs4 (unicode_command_help,
unicode_last_screen_position, term); unicode_last_screen_position, 0, 0, term);
if (!(cnt % 2)) if (!(cnt % 2))
grub_print_spaces (term, grub_term_width (term) / 2 grub_print_spaces (term, grub_term_width (term) / 2
- stringwidth); - stringwidth);
} }
if (cnt % 2) if (cnt % 2)
grub_printf ("\n"); grub_printf ("\n");
cnt++; cnt++;
@ -109,7 +115,7 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD)
grub_arg_show_help ((grub_extcmd_t) cmd->data); grub_arg_show_help ((grub_extcmd_t) cmd->data);
else else
grub_printf ("%s %s %s\n%s\b", _("Usage:"), cmd->name, _(cmd->summary), grub_printf ("%s %s %s\n%s\n", _("Usage:"), cmd->name, _(cmd->summary),
_(cmd->description)); _(cmd->description));
} }
} }

View file

@ -57,7 +57,7 @@ grub_ls_list_devices (int longlist)
} }
grub_device_iterate (grub_ls_print_devices); grub_device_iterate (grub_ls_print_devices);
grub_putchar ('\n'); grub_xputs ("\n");
grub_refresh (); grub_refresh ();
return 0; return 0;
@ -233,7 +233,7 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
} }
if (grub_errno == GRUB_ERR_NONE) if (grub_errno == GRUB_ERR_NONE)
grub_putchar ('\n'); grub_xputs ("\n");
grub_refresh (); grub_refresh ();
} }

View file

@ -54,7 +54,7 @@ grub_mini_cmd_cat (struct grub_command *cmd __attribute__ ((unused)),
unsigned char c = buf[i]; unsigned char c = buf[i];
if ((grub_isprint (c) || grub_isspace (c)) && c != '\r') if ((grub_isprint (c) || grub_isspace (c)) && c != '\r')
grub_putchar (c); grub_printf ("%c", c);
else else
{ {
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
@ -64,7 +64,7 @@ grub_mini_cmd_cat (struct grub_command *cmd __attribute__ ((unused)),
} }
} }
grub_putchar ('\n'); grub_xputs ("\n");
grub_refresh (); grub_refresh ();
grub_file_close (file); grub_file_close (file);
@ -312,11 +312,11 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)),
for (dep = mod->dep; dep; dep = dep->next) for (dep = mod->dep; dep; dep = dep->next)
{ {
if (dep != mod->dep) if (dep != mod->dep)
grub_putchar (','); grub_xputs (",");
grub_printf ("%s", dep->mod->name); grub_printf ("%s", dep->mod->name);
} }
grub_putchar ('\n'); grub_xputs ("\n");
} }
return 0; return 0;
@ -332,19 +332,8 @@ grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)),
return 0; return 0;
} }
/* clear */
static grub_err_t
grub_mini_cmd_clear (struct grub_command *cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char *argv[] __attribute__ ((unused)))
{
grub_cls ();
return 0;
}
static grub_command_t cmd_cat, cmd_help, cmd_root; static grub_command_t cmd_cat, cmd_help, cmd_root;
static grub_command_t cmd_dump, cmd_rmmod, cmd_lsmod, cmd_exit; static grub_command_t cmd_dump, cmd_rmmod, cmd_lsmod, cmd_exit;
static grub_command_t cmd_clear;
GRUB_MOD_INIT(minicmd) GRUB_MOD_INIT(minicmd)
{ {
@ -369,9 +358,6 @@ GRUB_MOD_INIT(minicmd)
cmd_exit = cmd_exit =
grub_register_command ("exit", grub_mini_cmd_exit, grub_register_command ("exit", grub_mini_cmd_exit,
0, N_("Exit from GRUB.")); 0, N_("Exit from GRUB."));
cmd_clear =
grub_register_command ("clear", grub_mini_cmd_clear,
0, N_("Clear the screen."));
} }
GRUB_MOD_FINI(minicmd) GRUB_MOD_FINI(minicmd)
@ -383,5 +369,4 @@ GRUB_MOD_FINI(minicmd)
grub_unregister_command (cmd_rmmod); grub_unregister_command (cmd_rmmod);
grub_unregister_command (cmd_lsmod); grub_unregister_command (cmd_lsmod);
grub_unregister_command (cmd_exit); grub_unregister_command (cmd_exit);
grub_unregister_command (cmd_clear);
} }

View file

@ -0,0 +1,92 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/err.h>
#include <grub/dl.h>
#include <grub/command.h>
#include <grub/cs5536.h>
static grub_err_t
grub_cmd_lsspd (grub_command_t cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
grub_pci_device_t dev;
grub_port_t smbbase;
int i;
grub_err_t err;
if (!grub_cs5536_find (&dev))
{
grub_printf ("No CS5536 found\n");
return GRUB_ERR_NONE;
}
grub_printf ("CS5536 at %d:%d.%d\n", grub_pci_get_bus (dev),
grub_pci_get_device (dev), grub_pci_get_function (dev));
err = grub_cs5536_init_smbus (dev, 0x7fff, &smbbase);
if (err)
return err;
grub_printf ("SMB base = 0x%x\n", smbbase);
for (i = GRUB_SMB_RAM_START_ADDR;
i < GRUB_SMB_RAM_START_ADDR + GRUB_SMB_RAM_NUM_MAX; i++)
{
struct grub_smbus_spd spd;
grub_memset (&spd, 0, sizeof (spd));
grub_printf ("Device %d\n", i);
err = grub_cs5536_read_spd (smbbase, i, &spd);
if (err)
{
grub_print_error ();
continue;
}
grub_printf ("Written SPD bytes: %d B.\n", spd.written_size);
grub_printf ("Total flash size: %d B.\n", 1 << spd.log_total_flash_size);
if (spd.memory_type == GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2)
{
char str[sizeof (spd.ddr2.part_number) + 1];
grub_printf ("Memory type: DDR2.\n");
grub_memcpy (str, spd.ddr2.part_number,
sizeof (spd.ddr2.part_number));
str[sizeof (spd.ddr2.part_number)] = 0;
grub_printf ("Part no: %s.\n", str);
}
else
grub_printf ("Memory type: Unknown.\n");
}
return GRUB_ERR_NONE;
}
static grub_command_t cmd;
GRUB_MOD_INIT(lsspd)
{
cmd = grub_register_command ("lsspd", grub_cmd_lsspd, 0,
"Print Memory information.");
}
GRUB_MOD_FINI(lsspd)
{
grub_unregister_command (cmd);
}

View file

@ -47,7 +47,7 @@ grub_getline (void)
line[i] = c; line[i] = c;
if (grub_isprint (c)) if (grub_isprint (c))
grub_putchar (c); grub_printf ("%c", c);
i++; i++;
tmp = grub_realloc (line, 1 + i + sizeof('\0')); tmp = grub_realloc (line, 1 + i + sizeof('\0'));
if (! tmp) if (! tmp)

View file

@ -30,8 +30,8 @@ struct abstract_terminal
{ {
struct abstract_terminal *next; struct abstract_terminal *next;
const char *name; const char *name;
grub_err_t (*init) (void); grub_err_t (*init) (struct abstract_terminal *term);
grub_err_t (*fini) (void); grub_err_t (*fini) (struct abstract_terminal *term);
}; };
static grub_err_t static grub_err_t
@ -123,7 +123,7 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled,
break; break;
if (term) if (term)
{ {
if (term->init && term->init () != GRUB_ERR_NONE) if (term->init && term->init (term) != GRUB_ERR_NONE)
return grub_errno; return grub_errno;
grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term)); grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
@ -147,7 +147,7 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled,
"can't remove the last terminal"); "can't remove the last terminal");
grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term)); grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
if (term->fini) if (term->fini)
term->fini (); term->fini (term);
grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term)); grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
} }
} }
@ -160,7 +160,7 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled,
break; break;
if (term) if (term)
{ {
if (term->init && term->init () != GRUB_ERR_NONE) if (term->init && term->init (term) != GRUB_ERR_NONE)
return grub_errno; return grub_errno;
grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term)); grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
@ -183,7 +183,7 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled,
"can't remove the last terminal"); "can't remove the last terminal");
grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term)); grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
if (term->fini) if (term->fini)
term->fini (); term->fini (term);
grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term)); grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
} }
} }

View file

@ -25,6 +25,7 @@
#include <grub/term.h> #include <grub/term.h>
#include <grub/command.h> #include <grub/command.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/gfxmenu_view.h>
static grub_err_t static grub_err_t
grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)), grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
@ -38,15 +39,8 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
unsigned int width; unsigned int width;
unsigned int height; unsigned int height;
int i; int i;
grub_font_t sansbig;
grub_font_t sans;
grub_font_t sanssmall;
grub_font_t fixed;
struct grub_font_glyph *glyph;
struct grub_video_render_target *text_layer; struct grub_video_render_target *text_layer;
grub_video_color_t palette[16]; grub_video_color_t palette[16];
const char *str;
int texty;
err = grub_video_set_mode ("auto", GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); err = grub_video_set_mode ("auto", GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
if (err) if (err)
@ -54,21 +48,22 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
grub_video_get_viewport (&x, &y, &width, &height); grub_video_get_viewport (&x, &y, &width, &height);
{
const char *str;
int texty;
grub_font_t sansbig;
grub_font_t sans;
grub_font_t sanssmall;
grub_font_t fixed;
struct grub_font_glyph *glyph;
grub_video_create_render_target (&text_layer, width, height, grub_video_create_render_target (&text_layer, width, height,
GRUB_VIDEO_MODE_TYPE_RGB GRUB_VIDEO_MODE_TYPE_RGB
| GRUB_VIDEO_MODE_TYPE_ALPHA); | GRUB_VIDEO_MODE_TYPE_ALPHA);
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); grub_video_set_active_render_target (text_layer);
color = grub_video_map_rgb (0, 0, 0);
grub_video_fill_rect (color, 0, 0, width, height);
color = grub_video_map_rgb (255, 0, 0);
grub_video_fill_rect (color, 0, 0, 100, 100);
color = grub_video_map_rgb (0, 255, 255); color = grub_video_map_rgb (0, 255, 255);
grub_video_fill_rect (color, 100, 100, 100, 100);
sansbig = grub_font_get ("Unknown Regular 16"); sansbig = grub_font_get ("Unknown Regular 16");
sans = grub_font_get ("Unknown Regular 16"); sans = grub_font_get ("Unknown Regular 16");
sanssmall = grub_font_get ("Unknown Regular 16"); sanssmall = grub_font_get ("Unknown Regular 16");
@ -79,13 +74,6 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
glyph = grub_font_get_glyph (fixed, '*'); glyph = grub_font_get_glyph (fixed, '*');
grub_font_draw_glyph (glyph, color, 200 ,0); grub_font_draw_glyph (glyph, color, 200 ,0);
grub_video_set_viewport (x + 150, y + 150,
width - 150 * 2, height - 150 * 2);
color = grub_video_map_rgb (77, 33, 77);
grub_video_fill_rect (color, 0, 0, width, height);
grub_video_set_active_render_target (text_layer);
color = grub_video_map_rgb (255, 255, 255); color = grub_video_map_rgb (255, 255, 255);
texty = 32; texty = 32;
@ -147,9 +135,28 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
palette[i] = color; palette[i] = color;
grub_font_draw_glyph (glyph, color, 16 + i * 16, 220); grub_font_draw_glyph (glyph, color, 16 + i * 16, 220);
} }
}
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
for (i = 0; i < 2; i++)
{
color = grub_video_map_rgb (0, 0, 0);
grub_video_fill_rect (color, 0, 0, width, height);
color = grub_video_map_rgb (255, 0, 0);
grub_video_fill_rect (color, 0, 0, 100, 100);
color = grub_video_map_rgb (0, 255, 255);
grub_video_fill_rect (color, 100, 100, 100, 100);
grub_video_set_viewport (x + 150, y + 150,
width - 150 * 2, height - 150 * 2);
color = grub_video_map_rgb (77, 33, 77);
grub_video_fill_rect (color, 0, 0, width, height);
grub_video_swap_buffers ();
}
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
{ {
color = grub_video_map_rgb (i, 33, 77); color = grub_video_map_rgb (i, 33, 77);

View file

@ -38,7 +38,8 @@ grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \
partmap/msdos.c partmap/bsdlabel.c partmap/apple.c \ partmap/msdos.c partmap/bsdlabel.c partmap/apple.c \
partmap/sun.c partmap/sunpc.c partmap/gpt.c \ partmap/sun.c partmap/sunpc.c partmap/gpt.c \
kern/fs.c kern/env.c fs/fshelp.c \ kern/fs.c kern/env.c fs/fshelp.c \
disk/raid.c disk/mdraid_linux.c disk/lvm.c grub_probe_init.c disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \
disk/mdraid_linux.c disk/lvm.c grub_probe_init.c
ifeq ($(enable_grub_fstest), yes) ifeq ($(enable_grub_fstest), yes)
bin_UTILITIES += grub-fstest bin_UTILITIES += grub-fstest
@ -69,7 +70,8 @@ grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c kern/emu/hostfs.c \
# For grub-mkfont. # For grub-mkfont.
ifeq ($(enable_grub_mkfont), yes) ifeq ($(enable_grub_mkfont), yes)
bin_UTILITIES += grub-mkfont bin_UTILITIES += grub-mkfont
grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c kern/emu/misc.c grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c \
unidata.c kern/emu/misc.c
grub_mkfont_CFLAGS = $(freetype_cflags) grub_mkfont_CFLAGS = $(freetype_cflags)
grub_mkfont_LDFLAGS = $(freetype_libs) grub_mkfont_LDFLAGS = $(freetype_libs)
endif endif
@ -95,6 +97,7 @@ grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c
kern/command.c kern/misc.c kern/env.c grub_script.tab.c \ kern/command.c kern/misc.c kern/env.c grub_script.tab.c \
grub_script.yy.c grub_script.yy.c
grub_script_check_CFLAGS = $(GNULIB_UTIL_CFLAGS) grub_script_check_CFLAGS = $(GNULIB_UTIL_CFLAGS)
grub_script_check_DEPENDENCIES = grub_script.tab.h
MOSTLYCLEANFILES += symlist.c kernel_syms.lst MOSTLYCLEANFILES += symlist.c kernel_syms.lst
DEFSYMFILES += kernel_syms.lst DEFSYMFILES += kernel_syms.lst
@ -201,10 +204,13 @@ CLEANFILES += grub-gettext_lib
%: util/grub.d/%.in config.status %: util/grub.d/%.in config.status
./config.status --file=$@:$< ./config.status --file=$@:$<
chmod +x $@ chmod +x $@
grub-mkconfig_SCRIPTS = 00_header 30_os-prober 40_custom grub-mkconfig_SCRIPTS = 00_header 30_os-prober 40_custom 41_custom
ifneq (, $(host_kernel)) ifneq (, $(host_kernel))
grub-mkconfig_SCRIPTS += 10_$(host_kernel) grub-mkconfig_SCRIPTS += 10_$(host_kernel)
endif endif
ifeq (linux, $(host_kernel))
grub-mkconfig_SCRIPTS += 20_linux_xen
endif
CLEANFILES += $(grub-mkconfig_SCRIPTS) CLEANFILES += $(grub-mkconfig_SCRIPTS)
@ -437,7 +443,7 @@ scsi_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += minicmd.mod extcmd.mod hello.mod \ pkglib_MODULES += minicmd.mod extcmd.mod hello.mod \
ls.mod cmp.mod cat.mod help.mod search.mod loopback.mod \ ls.mod cmp.mod cat.mod help.mod search.mod loopback.mod \
configfile.mod echo.mod \ configfile.mod echo.mod \
terminfo.mod test.mod blocklist.mod hexdump.mod \ test.mod blocklist.mod hexdump.mod \
read.mod sleep.mod loadenv.mod crc.mod parttool.mod \ read.mod sleep.mod loadenv.mod crc.mod parttool.mod \
msdospart.mod memrw.mod normal.mod \ msdospart.mod memrw.mod normal.mod \
gptsync.mod true.mod probe.mod password.mod \ gptsync.mod true.mod probe.mod password.mod \
@ -486,7 +492,8 @@ gfxmenu_mod_SOURCES = \
gfxmenu/gui_progress_bar.c \ gfxmenu/gui_progress_bar.c \
gfxmenu/gui_util.c \ gfxmenu/gui_util.c \
gfxmenu/gui_string_util.c \ gfxmenu/gui_string_util.c \
gfxmenu/named_colors.c gfxmenu/named_colors.c \
gfxmenu/font.c
gfxmenu_mod_CFLAGS = $(COMMON_CFLAGS) gfxmenu_mod_CFLAGS = $(COMMON_CFLAGS)
gfxmenu_mod_LDFLAGS = $(COMMON_LDFLAGS) gfxmenu_mod_LDFLAGS = $(COMMON_LDFLAGS)
@ -562,10 +569,13 @@ configfile_mod_SOURCES = commands/configfile.c
configfile_mod_CFLAGS = $(COMMON_CFLAGS) configfile_mod_CFLAGS = $(COMMON_CFLAGS)
configfile_mod_LDFLAGS = $(COMMON_LDFLAGS) configfile_mod_LDFLAGS = $(COMMON_LDFLAGS)
ifneq ($(platform), ieee1275)
# For terminfo.mod. # For terminfo.mod.
pkglib_MODULES += terminfo.mod
terminfo_mod_SOURCES = term/terminfo.c term/tparm.c terminfo_mod_SOURCES = term/terminfo.c term/tparm.c
terminfo_mod_CFLAGS = $(COMMON_CFLAGS) terminfo_mod_CFLAGS = $(COMMON_CFLAGS)
terminfo_mod_LDFLAGS = $(COMMON_LDFLAGS) terminfo_mod_LDFLAGS = $(COMMON_LDFLAGS)
endif
# For blocklist.mod. # For blocklist.mod.
blocklist_mod_SOURCES = commands/blocklist.c blocklist_mod_SOURCES = commands/blocklist.c
@ -618,12 +628,15 @@ keystatus_mod_CFLAGS = $(COMMON_CFLAGS)
keystatus_mod_LDFLAGS = $(COMMON_LDFLAGS) keystatus_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For normal.mod. # For normal.mod.
ifneq (, $(FONT_SOURCE))
normal/charset.c_DEPENDENCIES = widthspec.h
endif
normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \ normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \
normal/auth.c normal/autofs.c \ normal/auth.c normal/autofs.c \
normal/color.c normal/completion.c normal/datetime.c normal/menu.c \ normal/color.c normal/completion.c normal/datetime.c normal/menu.c \
normal/menu_entry.c normal/menu_text.c \ normal/menu_entry.c normal/menu_text.c normal/charset.c \
normal/misc.c normal/crypto.c normal/term.c normal/context.c \ normal/misc.c normal/crypto.c normal/term.c normal/context.c \
script/main.c script/script.c script/execute.c script/argv.c \ script/main.c script/script.c script/execute.c script/argv.c unidata.c \
script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c
normal_mod_CFLAGS = $(COMMON_CFLAGS) $(POSIX_CFLAGS) -Wno-error normal_mod_CFLAGS = $(COMMON_CFLAGS) $(POSIX_CFLAGS) -Wno-error
normal_mod_LDFLAGS = $(COMMON_LDFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
@ -697,7 +710,6 @@ png_mod_SOURCES = video/readers/png.c
png_mod_CFLAGS = $(COMMON_CFLAGS) png_mod_CFLAGS = $(COMMON_CFLAGS)
png_mod_LDFLAGS = $(COMMON_LDFLAGS) png_mod_LDFLAGS = $(COMMON_LDFLAGS)
# Misc. # Misc.
pkglib_MODULES += gzio.mod elf.mod pkglib_MODULES += gzio.mod elf.mod
@ -751,11 +763,6 @@ setjmp_mod_SOURCES = lib/$(target_cpu)/setjmp.S
setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS) setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS)
setjmp_mod_LDFLAGS = $(COMMON_LDFLAGS) setjmp_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += charset.mod
charset_mod_SOURCES = lib/charset.c
charset_mod_CFLAGS = $(COMMON_CFLAGS)
charset_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += regexp.mod pkglib_MODULES += regexp.mod
regexp_mod_SOURCES = gnulib/regex.c commands/regexp.c regexp_mod_SOURCES = gnulib/regex.c commands/regexp.c
regexp_mod_CFLAGS = $(COMMON_CFLAGS) $(GNULIB_CFLAGS) regexp_mod_CFLAGS = $(COMMON_CFLAGS) $(GNULIB_CFLAGS)

View file

@ -22,9 +22,10 @@ kernel_img_SOURCES = kern/i386/ieee1275/startup.S \
kern/generic/millisleep.c \ kern/generic/millisleep.c \
kern/ieee1275/ieee1275.c \ kern/ieee1275/ieee1275.c \
term/ieee1275/ofconsole.c \ term/ieee1275/ofconsole.c \
term/terminfo.c term/tparm.c \
disk/ieee1275/ofdisk.c \ disk/ieee1275/ofdisk.c \
symlist.c symlist.c
kernel_img_HEADERS += ieee1275/ieee1275.h kernel_img_HEADERS += ieee1275/ieee1275.h terminfo.h
kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic

View file

@ -78,7 +78,8 @@ grub_setup_SOURCES = gnulib/progname.c util/i386/pc/grub-setup.c \
partmap/msdos.c partmap/bsdlabel.c partmap/sunpc.c \ partmap/msdos.c partmap/bsdlabel.c partmap/sunpc.c \
partmap/gpt.c \ partmap/gpt.c \
\ \
disk/raid.c disk/mdraid_linux.c disk/lvm.c \ disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \
disk/mdraid_linux.c disk/lvm.c \
util/raid.c util/lvm.c \ util/raid.c util/lvm.c \
grub_setup_init.c grub_setup_init.c
@ -147,7 +148,7 @@ linux_mod_CFLAGS = $(COMMON_CFLAGS)
linux_mod_LDFLAGS = $(COMMON_LDFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += xnu.mod pkglib_MODULES += xnu.mod
xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/pc/xnu.c \ xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c \
loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c
xnu_mod_CFLAGS = $(COMMON_CFLAGS) xnu_mod_CFLAGS = $(COMMON_CFLAGS)
xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -13,10 +13,13 @@ boot_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_M
boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LINK_ADDR) boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LINK_ADDR)
boot_img_FORMAT = binary boot_img_FORMAT = binary
kern/i386/qemu/init.c_DEPENDENCIES = ascii.h
pkglib_PROGRAMS += kernel.img pkglib_PROGRAMS += kernel.img
kernel_img_SOURCES = kern/i386/qemu/startup.S \ kernel_img_SOURCES = kern/i386/qemu/startup.S \
kern/i386/misc.S \ kern/i386/misc.S \
kern/i386/coreboot/init.c \ kern/i386/coreboot/init.c \
kern/i386/qemu/init.c \
kern/i386/qemu/mmap.c \ kern/i386/qemu/mmap.c \
kern/i386/halt.c \ kern/i386/halt.c \
kern/main.c kern/device.c \ kern/main.c kern/device.c \
@ -29,8 +32,9 @@ kernel_img_SOURCES = kern/i386/qemu/startup.S \
kern/generic/rtc_get_time_ms.c \ kern/generic/rtc_get_time_ms.c \
kern/generic/millisleep.c \ kern/generic/millisleep.c \
kern/env.c \ kern/env.c \
term/i386/pc/vga_text.c term/i386/vga_common.c \ term/i386/pc/vga_text.c term/i386/vga_common.c bus/pci.c \
symlist.c symlist.c
kernel_img_HEADERS += pci.h
kernel_img_CFLAGS = $(COMMON_CFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR) kernel_img_CFLAGS = $(COMMON_CFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR)

View file

@ -15,6 +15,16 @@ vga_text_mod_SOURCES = term/i386/pc/vga_text.c term/i386/vga_common.c
vga_text_mod_CFLAGS = $(COMMON_CFLAGS) vga_text_mod_CFLAGS = $(COMMON_CFLAGS)
vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS) vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += video_cirrus.mod
video_cirrus_mod_SOURCES = video/cirrus.c
video_cirrus_mod_CFLAGS = $(COMMON_CFLAGS)
video_cirrus_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += video_bochs.mod
video_bochs_mod_SOURCES = video/bochs.c
video_bochs_mod_CFLAGS = $(COMMON_CFLAGS)
video_bochs_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += relocator.mod pkglib_MODULES += relocator.mod
relocator_mod_SOURCES = lib/i386/relocator.c lib/i386/relocator_asm.S lib/i386/relocator_backward.S relocator_mod_SOURCES = lib/i386/relocator.c lib/i386/relocator_asm.S lib/i386/relocator_backward.S
relocator_mod_CFLAGS = $(COMMON_CFLAGS) relocator_mod_CFLAGS = $(COMMON_CFLAGS)
@ -50,11 +60,14 @@ 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)
# On qemu it's compiled in
ifneq ($(platform), qemu)
# For pci.mod # For pci.mod
pkglib_MODULES += pci.mod pkglib_MODULES += pci.mod
pci_mod_SOURCES = bus/pci.c pci_mod_SOURCES = bus/pci.c
pci_mod_CFLAGS = $(COMMON_CFLAGS) pci_mod_CFLAGS = $(COMMON_CFLAGS)
pci_mod_LDFLAGS = $(COMMON_LDFLAGS) pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
endif
# For cs5536.mod # For cs5536.mod
pkglib_MODULES += cs5536.mod pkglib_MODULES += cs5536.mod

View file

@ -20,3 +20,9 @@ kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic
kernel_img_FORMAT = binary kernel_img_FORMAT = binary
# For serial.mod.
pkglib_MODULES += serial.mod
serial_mod_SOURCES = term/serial.c
serial_mod_CFLAGS = $(COMMON_CFLAGS)
serial_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -27,13 +27,21 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \
video/fb/fbfill.c video/fb/fbutil.c video/bitmap.c \ video/fb/fbfill.c video/fb/fbutil.c video/bitmap.c \
video/bitmap_scale.c video/sm712.c bus/pci.c bus/bonito.c \ video/bitmap_scale.c video/sm712.c bus/pci.c bus/bonito.c \
term/gfxterm.c commands/extcmd.c lib/arg.c \ term/gfxterm.c commands/extcmd.c lib/arg.c \
bus/cs5536.c \ bus/cs5536.c term/serial.c term/terminfo.c term/tparm.c \
symlist.c symlist.c
kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK
kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic
kernel_img_FORMAT = binary kernel_img_FORMAT = binary
pkglib_IMAGES += fwstart.img
fwstart_img_SOURCES = boot/$(target_cpu)/$(target_machine)/fwstart.S
fwstart_img_CFLAGS = $(COMMON_CFLAGS)
fwstart_img_ASFLAGS = $(COMMON_ASFLAGS)
fwstart_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \
-Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic
fwstart_img_FORMAT = binary
# For ata.mod. # For ata.mod.
pkglib_MODULES += ata.mod pkglib_MODULES += ata.mod
ata_mod_SOURCES = disk/ata.c ata_mod_SOURCES = disk/ata.c
@ -65,12 +73,24 @@ 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)
# For lsspd.mod
pkglib_MODULES += lsspd.mod
lsspd_mod_SOURCES = commands/mips/yeeloong/lsspd.c
lsspd_mod_CFLAGS = $(COMMON_CFLAGS)
lsspd_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += linux.mod pkglib_MODULES += linux.mod
linux_mod_SOURCES = loader/$(target_cpu)/linux.c linux_mod_SOURCES = loader/$(target_cpu)/linux.c
linux_mod_CFLAGS = $(COMMON_CFLAGS) linux_mod_CFLAGS = $(COMMON_CFLAGS)
linux_mod_ASFLAGS = $(COMMON_ASFLAGS) linux_mod_ASFLAGS = $(COMMON_ASFLAGS)
linux_mod_LDFLAGS = $(COMMON_LDFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For halt.mod.
pkglib_MODULES += halt.mod
halt_mod_SOURCES = commands/halt.c
halt_mod_CFLAGS = $(COMMON_CFLAGS)
halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For usb.mod # For usb.mod
pkglib_MODULES += usb.mod pkglib_MODULES += usb.mod
usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c

View file

@ -10,12 +10,6 @@ kernel_img_HEADERS += cpu/cache.h
sbin_SCRIPTS = sbin_SCRIPTS =
bin_SCRIPTS = bin_SCRIPTS =
# 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. # For relocator.mod.
pkglib_MODULES += relocator.mod pkglib_MODULES += relocator.mod
relocator_mod_SOURCES = lib/$(target_cpu)/relocator.c lib/$(target_cpu)/relocator_asm.S relocator_mod_SOURCES = lib/$(target_cpu)/relocator.c lib/$(target_cpu)/relocator_asm.S

View file

@ -16,7 +16,7 @@ kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \
kern/list.c kern/command.c kern/corecmd.c \ kern/list.c kern/command.c kern/corecmd.c \
kern/ieee1275/init.c \ kern/ieee1275/init.c \
kern/ieee1275/mmap.c \ kern/ieee1275/mmap.c \
term/ieee1275/ofconsole.c \ term/ieee1275/ofconsole.c term/terminfo.c term/tparm.c \
kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c \ kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c \
kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \
kern/generic/millisleep.c kern/time.c \ kern/generic/millisleep.c kern/time.c \

View file

@ -31,7 +31,8 @@ kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \
kern/sparc64/ieee1275/init.c \ kern/sparc64/ieee1275/init.c \
kern/ieee1275/mmap.c \ kern/ieee1275/mmap.c \
term/ieee1275/ofconsole.c \ term/ieee1275/ofconsole.c \
kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c \ kern/ieee1275/openfw.c term/terminfo.c term/tparm.c \
disk/ieee1275/ofdisk.c \
kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \
kern/generic/millisleep.c kern/time.c \ kern/generic/millisleep.c kern/time.c \
symlist.c kern/$(target_cpu)/cache.S symlist.c kern/$(target_cpu)/cache.S
@ -61,7 +62,8 @@ grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c \
partmap/amiga.c partmap/apple.c partmap/msdos.c \ partmap/amiga.c partmap/apple.c partmap/msdos.c \
partmap/bsdlabel.c partmap/sun.c partmap/acorn.c \ partmap/bsdlabel.c partmap/sun.c partmap/acorn.c \
\ \
disk/raid.c disk/mdraid_linux.c disk/lvm.c util/raid.c \ disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \
disk/mdraid_linux.c disk/lvm.c util/raid.c \
util/lvm.c gnulib/progname.c grub_setup_init.c util/lvm.c gnulib/progname.c grub_setup_init.c
# For grub-ofpathname. # For grub-ofpathname.

View file

@ -102,7 +102,7 @@ efi_gop_mod_CFLAGS = $(COMMON_CFLAGS)
efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS) efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += xnu.mod pkglib_MODULES += xnu.mod
xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c \ xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c \
loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c
xnu_mod_CFLAGS = $(COMMON_CFLAGS) xnu_mod_CFLAGS = $(COMMON_CFLAGS)
xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -179,15 +179,23 @@ if test "x$YACC" = x; then
AC_MSG_ERROR([bison is not found]) AC_MSG_ERROR([bison is not found])
fi fi
FONT_SOURCE=
for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do
for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/unifont; do for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/unifont; do
if test -f "$dir/unifont.$ext"; then if test -f "$dir/unifont.$ext"; then
AC_SUBST([FONT_SOURCE], [$dir/unifont.$ext]) FONT_SOURCE="$dir/unifont.$ext"
break 2 break 2
fi fi
done done
done done
if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xyeeloong ); then
AC_MSG_ERROR([qemu and yeeloong ports need unifont])
fi
AC_SUBST([FONT_SOURCE])
AC_PROG_INSTALL AC_PROG_INSTALL
AC_PROG_AWK AC_PROG_AWK
AC_PROG_LEX AC_PROG_LEX

View file

@ -24,10 +24,13 @@
#include <grub/time.h> #include <grub/time.h>
#include <grub/pci.h> #include <grub/pci.h>
#include <grub/scsi.h> #include <grub/scsi.h>
#include <grub/cs5536.h>
/* At the moment, only two IDE ports are supported. */ /* At the moment, only two IDE ports are supported. */
static const grub_port_t grub_ata_ioaddress[] = { 0x1f0, 0x170 }; static const grub_port_t grub_ata_ioaddress[] = { GRUB_ATA_CH0_PORT1,
static const grub_port_t grub_ata_ioaddress2[] = { 0x3f6, 0x376 }; GRUB_ATA_CH1_PORT1 };
static const grub_port_t grub_ata_ioaddress2[] = { GRUB_ATA_CH0_PORT2,
GRUB_ATA_CH1_PORT2 };
static struct grub_ata_device *grub_ata_devices; static struct grub_ata_device *grub_ata_devices;
@ -331,11 +334,38 @@ grub_ata_identify (struct grub_ata_device *dev)
return 0; return 0;
} }
static grub_err_t
check_device (struct grub_ata_device *dev)
{
grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
grub_ata_wait ();
/* Try to detect if the port is in use by writing to it,
waiting for a while and reading it again. If the value
was preserved, there is a device connected. */
grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);
grub_ata_wait ();
grub_uint8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS);
grub_dprintf ("ata", "sectors=0x%x\n", sec);
if (sec != 0x5A)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no device connected");
/* The above test may detect a second (slave) device
connected to a SATA controller which supports only one
(master) device. It is not safe to use the status register
READY bit to check for controller channel existence. Some
ATAPI commands (RESET, DIAGNOSTIC) may clear this bit. */
/* Use the IDENTIFY DEVICE command to query the device. */
return grub_ata_identify (dev);
}
static grub_err_t static grub_err_t
grub_ata_device_initialize (int port, int device, int addr, int addr2) grub_ata_device_initialize (int port, int device, int addr, int addr2)
{ {
struct grub_ata_device *dev; struct grub_ata_device *dev;
struct grub_ata_device **devp; struct grub_ata_device **devp;
grub_err_t err;
grub_dprintf ("ata", "detecting device %d,%d (0x%x, 0x%x)\n", grub_dprintf ("ata", "detecting device %d,%d (0x%x, 0x%x)\n",
port, device, addr, addr2); port, device, addr, addr2);
@ -351,39 +381,14 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2)
dev->ioaddress2 = addr2 + GRUB_MACHINE_PCI_IO_BASE; 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_wait ();
/* Try to detect if the port is in use by writing to it,
waiting for a while and reading it again. If the value
was preserved, there is a device connected. */
grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);
grub_ata_wait ();
grub_uint8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS);
grub_dprintf ("ata", "sectors=0x%x\n", sec);
if (sec != 0x5A)
{
grub_free(dev);
return 0;
}
/* The above test may detect a second (slave) device
connected to a SATA controller which supports only one
(master) device. It is not safe to use the status register
READY bit to check for controller channel existence. Some
ATAPI commands (RESET, DIAGNOSTIC) may clear this bit. */
/* Use the IDENTIFY DEVICE command to query the device. */
if (grub_ata_identify (dev))
{
grub_free (dev);
return 0;
}
/* Register the device. */ /* Register the device. */
for (devp = &grub_ata_devices; *devp; devp = &(*devp)->next); for (devp = &grub_ata_devices; *devp; devp = &(*devp)->next);
*devp = dev; *devp = dev;
err = check_device (dev);
if (err)
grub_print_error ();
return 0; return 0;
} }
@ -408,7 +413,7 @@ grub_ata_pciinit (grub_pci_device_t dev,
class = grub_pci_read (addr); class = grub_pci_read (addr);
/* AMD CS5536 Southbridge. */ /* AMD CS5536 Southbridge. */
if (pciid == 0x208f1022) if (pciid == GRUB_CS5536_PCIID)
{ {
cs5536 = 1; cs5536 = 1;
nports = 1; nports = 1;
@ -666,6 +671,14 @@ grub_ata_iterate (int (*hook) (const char *name))
for (dev = grub_ata_devices; dev; dev = dev->next) for (dev = grub_ata_devices; dev; dev = dev->next)
{ {
char devname[10]; char devname[10];
grub_err_t err;
err = check_device (dev);
if (err)
{
grub_errno = GRUB_ERR_NONE;
continue;
}
if (dev->atapi) if (dev->atapi)
continue; continue;
@ -684,6 +697,7 @@ static grub_err_t
grub_ata_open (const char *name, grub_disk_t disk) grub_ata_open (const char *name, grub_disk_t disk)
{ {
struct grub_ata_device *dev; struct grub_ata_device *dev;
grub_err_t err;
for (dev = grub_ata_devices; dev; dev = dev->next) for (dev = grub_ata_devices; dev; dev = dev->next)
{ {
@ -700,6 +714,11 @@ grub_ata_open (const char *name, grub_disk_t disk)
if (dev->atapi) if (dev->atapi)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk"); return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk");
err = check_device (dev);
if (err)
return err;
disk->total_sectors = dev->size; disk->total_sectors = dev->size;
disk->id = (unsigned long) dev; disk->id = (unsigned long) dev;
@ -749,20 +768,25 @@ static struct grub_disk_dev grub_atadisk_dev =
/* ATAPI code. */ /* ATAPI code. */
static int static int
grub_atapi_iterate (int (*hook) (const char *name, int luns)) grub_atapi_iterate (int (*hook) (int bus, int luns))
{ {
struct grub_ata_device *dev; struct grub_ata_device *dev;
for (dev = grub_ata_devices; dev; dev = dev->next) for (dev = grub_ata_devices; dev; dev = dev->next)
{ {
char devname[10]; grub_err_t err;
grub_snprintf (devname, sizeof (devname),
"ata%d", dev->port * 2 + dev->device); err = check_device (dev);
if (err)
{
grub_errno = GRUB_ERR_NONE;
continue;
}
if (! dev->atapi) if (! dev->atapi)
continue; continue;
if (hook (devname, 1)) if (hook (dev->port * 2 + dev->device, 1))
return 1; return 1;
} }
@ -822,46 +846,45 @@ grub_atapi_write (struct grub_scsi *scsi __attribute__((unused)),
} }
static grub_err_t static grub_err_t
grub_atapi_open (const char *name, struct grub_scsi *scsi) grub_atapi_open (int devnum, struct grub_scsi *scsi)
{ {
struct grub_ata_device *dev; struct grub_ata_device *dev;
struct grub_ata_device *devfnd = 0; struct grub_ata_device *devfnd = 0;
grub_err_t err;
for (dev = grub_ata_devices; dev; dev = dev->next) for (dev = grub_ata_devices; dev; dev = dev->next)
{ {
char devname[10]; if (dev->port * 2 + dev->device == devnum)
grub_snprintf (devname, sizeof (devname),
"ata%d", dev->port * 2 + dev->device);
if (!grub_strcmp (devname, name))
{ {
devfnd = dev; devfnd = dev;
break; break;
} }
} }
grub_dprintf ("ata", "opening ATAPI dev `%s'\n", name); grub_dprintf ("ata", "opening ATAPI dev `ata%d'\n", devnum);
if (! devfnd) if (! devfnd)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device"); return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device");
err = check_device (devfnd);
if (err)
return err;
if (! devfnd->atapi)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device");
scsi->data = devfnd; scsi->data = devfnd;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
static void
grub_atapi_close (struct grub_scsi *scsi)
{
grub_free (scsi->name);
}
static struct grub_scsi_dev grub_atapi_dev = static struct grub_scsi_dev grub_atapi_dev =
{ {
.name = "ATAPI", .name = "ata",
.id = GRUB_SCSI_SUBSYSTEM_ATAPI,
.iterate = grub_atapi_iterate, .iterate = grub_atapi_iterate,
.open = grub_atapi_open, .open = grub_atapi_open,
.close = grub_atapi_close,
.read = grub_atapi_read, .read = grub_atapi_read,
.write = grub_atapi_write .write = grub_atapi_write
}; };

View file

@ -45,6 +45,52 @@ grub_lvm_getvalue (char **p, char *str)
return grub_strtoul (*p, NULL, 10); return grub_strtoul (*p, NULL, 10);
} }
static int
grub_lvm_checkvalue (char **p, char *str, char *tmpl)
{
int tmpllen = grub_strlen (tmpl);
*p = grub_strstr (*p, str);
if (! *p)
return 0;
*p += grub_strlen (str);
if (**p != '"')
return 0;
return (grub_memcmp (*p + 1, tmpl, tmpllen) == 0 && (*p)[tmpllen + 1] == '"');
}
static int
grub_lvm_check_flag (char *p, char *str, char *flag)
{
int len_str = grub_strlen (str), len_flag = grub_strlen (flag);
while (1)
{
char *q;
p = grub_strstr (p, str);
if (! p)
return 0;
p += len_str;
if (grub_memcmp (p, " = [", sizeof (" = [") - 1) != 0)
continue;
q = p + sizeof (" = [") - 1;
while (1)
{
while (grub_isspace (*q))
q++;
if (*q != '"')
return 0;
q++;
if (grub_memcmp (q, flag, len_flag) == 0 && q[len_flag] == '"')
return 1;
while (*q != '"')
q++;
q++;
if (*q == ']')
return 0;
q++;
}
}
}
static int static int
grub_lvm_iterate (int (*hook) (const char *name)) grub_lvm_iterate (int (*hook) (const char *name))
{ {
@ -421,6 +467,7 @@ grub_lvm_scan_device (const char *name)
while (1) while (1)
{ {
int s; int s;
int skip_lv = 0;
struct grub_lvm_lv *lv; struct grub_lvm_lv *lv;
struct grub_lvm_segment *seg; struct grub_lvm_segment *seg;
@ -445,6 +492,12 @@ grub_lvm_scan_device (const char *name)
lv->size = 0; lv->size = 0;
if (!grub_lvm_check_flag (p, "status", "VISIBLE"))
{
skip_lv = 1;
goto lv_parsed;
}
lv->segment_count = grub_lvm_getvalue (&p, "segment_count = "); lv->segment_count = grub_lvm_getvalue (&p, "segment_count = ");
if (p == NULL) if (p == NULL)
goto lvs_fail; goto lvs_fail;
@ -465,6 +518,14 @@ grub_lvm_scan_device (const char *name)
seg->extent_count = grub_lvm_getvalue (&p, "extent_count = "); seg->extent_count = grub_lvm_getvalue (&p, "extent_count = ");
if (p == NULL) if (p == NULL)
goto lvs_segment_fail; goto lvs_segment_fail;
if (grub_lvm_checkvalue (&p, "type = ", "snapshot"))
{
/* Found a snapshot, give up and move on. */
skip_lv = 1;
break;
}
seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = "); seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = ");
if (p == NULL) if (p == NULL)
goto lvs_segment_fail; goto lvs_segment_fail;
@ -531,12 +592,20 @@ grub_lvm_scan_device (const char *name)
goto fail4; goto fail4;
} }
lv_parsed:
if (p != NULL) if (p != NULL)
p = grub_strchr (p, '}'); p = grub_strchr (p, '}');
if (p == NULL) if (p == NULL)
goto lvs_fail; goto lvs_fail;
p += 3; p += 3;
if (skip_lv)
{
grub_free (lv->name);
grub_free (lv);
continue;
}
lv->number = lv_count++; lv->number = lv_count++;
lv->vg = vg; lv->vg = vg;
lv->next = vg->lvs; lv->next = vg->lvs;

View file

@ -318,15 +318,24 @@ grub_scsi_iterate (int (*hook) (const char *name))
{ {
grub_scsi_dev_t p; grub_scsi_dev_t p;
auto int scsi_iterate (const char *name, int luns); auto int scsi_iterate (int bus, int luns);
int scsi_iterate (const char *name, int luns) int scsi_iterate (int bus, int luns)
{ {
int i; int i;
/* In case of a single LUN, just return `usbX'. */ /* In case of a single LUN, just return `usbX'. */
if (luns == 1) if (luns == 1)
return hook (name); {
char *sname;
int ret;
sname = grub_xasprintf ("%s%d", p->name, bus);
if (!sname)
return 1;
ret = hook (sname);
grub_free (sname);
return ret;
}
/* In case of multiple LUNs, every LUN will get a prefix to /* In case of multiple LUNs, every LUN will get a prefix to
distinguish it. */ distinguish it. */
@ -334,7 +343,7 @@ grub_scsi_iterate (int (*hook) (const char *name))
{ {
char *sname; char *sname;
int ret; int ret;
sname = grub_xasprintf ("%s%c", name, 'a' + i); sname = grub_xasprintf ("%s%d%c", p->name, bus, 'a' + i);
if (!sname) if (!sname)
return 1; return 1;
ret = hook (sname); ret = hook (sname);
@ -358,37 +367,46 @@ grub_scsi_open (const char *name, grub_disk_t disk)
grub_scsi_dev_t p; grub_scsi_dev_t p;
grub_scsi_t scsi; grub_scsi_t scsi;
grub_err_t err; grub_err_t err;
int len; int lun, bus;
int lun;
grub_uint64_t maxtime; grub_uint64_t maxtime;
const char *nameend;
nameend = name + grub_strlen (name) - 1;
/* Try to detect a LUN ('a'-'z'), otherwise just use the first
LUN. */
if (nameend >= name && *nameend >= 'a' && *nameend <= 'z')
{
lun = *nameend - 'a';
nameend--;
}
else
lun = 0;
while (nameend >= name && grub_isdigit (*nameend))
nameend--;
if (!nameend[1] || !grub_isdigit (nameend[1]))
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a SCSI disk");
bus = grub_strtoul (nameend + 1, 0, 0);
scsi = grub_malloc (sizeof (*scsi)); scsi = grub_malloc (sizeof (*scsi));
if (! scsi) if (! scsi)
return grub_errno; return grub_errno;
len = grub_strlen (name);
lun = name[len - 1] - 'a';
/* Try to detect a LUN ('a'-'z'), otherwise just use the first
LUN. */
if (lun < 0 || lun > 26)
lun = 0;
for (p = grub_scsi_dev_list; p; p = p->next) for (p = grub_scsi_dev_list; p; p = p->next)
{ {
if (p->open (name, scsi)) if (grub_strncmp (p->name, name, nameend - name) != 0)
continue; continue;
disk->id = (unsigned long) "scsi"; /* XXX */ if (p->open (bus, scsi))
continue;
disk->id = grub_make_scsi_id (scsi->dev->id, bus, lun);
disk->data = scsi; disk->data = scsi;
scsi->dev = p; scsi->dev = p;
scsi->lun = lun; scsi->lun = lun;
scsi->name = grub_strdup (name); scsi->bus = bus;
if (! scsi->name)
{
grub_free (scsi);
return grub_errno;
}
grub_dprintf ("scsi", "dev opened\n"); grub_dprintf ("scsi", "dev opened\n");
@ -476,6 +494,7 @@ grub_scsi_close (grub_disk_t disk)
grub_scsi_t scsi; grub_scsi_t scsi;
scsi = disk->data; scsi = disk->data;
if (scsi->dev->close)
scsi->dev->close (scsi); scsi->dev->close (scsi);
grub_free (scsi); grub_free (scsi);
} }

View file

@ -222,22 +222,15 @@ grub_usbms_finddevs (void)
static int static int
grub_usbms_iterate (int (*hook) (const char *name, int luns)) grub_usbms_iterate (int (*hook) (int bus, int luns))
{ {
grub_usbms_dev_t p; grub_usbms_dev_t p;
int cnt = 0; int cnt = 0;
for (p = grub_usbms_dev_list; p; p = p->next) for (p = grub_usbms_dev_list; p; p = p->next)
{ {
char *devname; if (hook (cnt, p->luns))
devname = grub_xasprintf ("usb%d", cnt);
if (hook (devname, p->luns))
{
grub_free (devname);
return 1; return 1;
}
grub_free (devname);
cnt++; cnt++;
} }
@ -312,7 +305,7 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
grub_dprintf ("usb", "buf:\n"); grub_dprintf ("usb", "buf:\n");
if (size <= 64) if (size <= 64)
for (i=0; i<size; i++) for (i=0; i<size; i++)
grub_dprintf ("usb", "0x%02x: 0x%02x\n", i, buf[i]); grub_dprintf ("usb", "0x%02" PRIxGRUB_SIZE ": 0x%02x\n", i, buf[i]);
else else
grub_dprintf ("usb", "Too much data for debug print...\n"); grub_dprintf ("usb", "Too much data for debug print...\n");
} }
@ -330,7 +323,7 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
/* Debug print of sent data. */ /* Debug print of sent data. */
if (size <= 256) if (size <= 256)
for (i=0; i<size; i++) for (i=0; i<size; i++)
grub_dprintf ("usb", "0x%02x: 0x%02x\n", i, buf[i]); grub_dprintf ("usb", "0x%02" PRIxGRUB_SIZE ": 0x%02x\n", i, buf[i]);
else else
grub_dprintf ("usb", "Too much data for debug print...\n"); grub_dprintf ("usb", "Too much data for debug print...\n");
} }
@ -398,28 +391,18 @@ grub_usbms_write (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
} }
static grub_err_t static grub_err_t
grub_usbms_open (const char *name, struct grub_scsi *scsi) grub_usbms_open (int devnum, struct grub_scsi *scsi)
{ {
grub_usbms_dev_t p; grub_usbms_dev_t p;
int devnum;
int i = 0; int i = 0;
if (grub_strncmp (name, "usb", 3))
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"not a USB Mass Storage device");
devnum = grub_strtoul (name + 3, NULL, 10);
for (p = grub_usbms_dev_list; p; p = p->next) for (p = grub_usbms_dev_list; p; p = p->next)
{ {
/* Check if this is the devnumth device. */ /* Check if this is the devnumth device. */
if (devnum == i) if (devnum == i)
{ {
scsi->data = p; scsi->data = p;
scsi->name = grub_strdup (name);
scsi->luns = p->luns; scsi->luns = p->luns;
if (! scsi->name)
return grub_errno;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@ -430,18 +413,12 @@ grub_usbms_open (const char *name, struct grub_scsi *scsi)
"not a USB Mass Storage device"); "not a USB Mass Storage device");
} }
static void
grub_usbms_close (struct grub_scsi *scsi)
{
grub_free (scsi->name);
}
static struct grub_scsi_dev grub_usbms_dev = static struct grub_scsi_dev grub_usbms_dev =
{ {
.name = "usb", .name = "usb",
.id = GRUB_SCSI_SUBSYSTEM_USBMS,
.iterate = grub_usbms_iterate, .iterate = grub_usbms_iterate,
.open = grub_usbms_open, .open = grub_usbms_open,
.close = grub_usbms_close,
.read = grub_usbms_read, .read = grub_usbms_read,
.write = grub_usbms_write .write = grub_usbms_write
}; };

View file

@ -80,7 +80,6 @@ This edition documents version @value{VERSION}.
* Network:: Downloading OS images from a network * Network:: Downloading OS images from a network
* Serial terminal:: Using GRUB via a serial line * Serial terminal:: Using GRUB via a serial line
* Vendor power-on keys:: Changing GRUB behaviour on vendor power-on keys * Vendor power-on keys:: Changing GRUB behaviour on vendor power-on keys
* Preset Menu:: Embedding a configuration file into GRUB
* Images:: GRUB image files * Images:: GRUB image files
* Filesystem:: Filesystem syntax and semantics * Filesystem:: Filesystem syntax and semantics
* Interface:: The menu and the command-line * Interface:: The menu and the command-line
@ -107,6 +106,7 @@ This edition documents version @value{VERSION}.
* Overview:: What exactly GRUB is and how to use it * Overview:: What exactly GRUB is and how to use it
* History:: From maggot to house fly * History:: From maggot to house fly
* Features:: GRUB features * Features:: GRUB features
* Changes from GRUB Legacy:: Differences from previous versions
* Role of a boot loader:: The role of a boot loader * Role of a boot loader:: The role of a boot loader
@end menu @end menu
@ -191,6 +191,74 @@ extents, and by the end of 2009 multiple major distributions were installing
it by default. it by default.
@node Changes from GRUB Legacy
@section Differences from previous versions
GRUB 2 is a rewrite of GRUB (@pxref{History}), although it shares many
characteristics with the previous version, now known as GRUB Legacy. Users
of GRUB Legacy may need some guidance to find their way around this new
version.
@itemize @bullet
@item
The configuration file has a new name (@file{grub.cfg} rather than
@file{menu.lst} or @file{grub.conf}), new syntax (@pxref{Configuration}) and
many new commands (@pxref{Commands}). Configuration cannot be copied over
directly, although most GRUB Legacy users should not find the syntax too
surprising.
@item
@file{grub.cfg} is typically automatically generated by
@command{grub-mkconfig} (@pxref{Simple configuration}). This makes it
easier to handle versioned kernel upgrades.
@item
Partition numbers in GRUB device names now start at 1, not 0 (@pxref{Naming
convention}).
@item
The configuration file is now written in something closer to a full
scripting language: variables, conditionals, and loops are available.
@item
A small amount of persistent storage is available across reboots, using the
@command{save_env} and @command{load_env} commands in GRUB and the
@command{grub-editenv} utility.
@item
GRUB 2 has more reliable ways to find its own files and those of target
kernels on multiple-disk systems, and has commands (@pxref{search}) to find
devices using file system labels or Universally Unique Identifiers (UUIDs).
@item
GRUB 2 is available for several other types of system in addition to the PC
BIOS systems supported by GRUB Legacy: PC EFI, PC coreboot, PowerPC, SPARC,
and MIPS Lemote Yeeloong are all supported.
@item
Many more file systems are supported, including but not limited to ext4,
HFS+, and NTFS.
@item
GRUB 2 can read files directly from LVM and RAID devices.
@item
A graphical terminal and a graphical menu system are available.
@item
GRUB 2's interface can be translated, including menu entry names.
@item
The image files (@pxref{Images}) that make up GRUB have been reorganised;
Stage 1, Stage 1.5, and Stage 2 are no more.
@item
GRUB 2 puts many facilities in dynamically loaded modules, allowing the core
image to be smaller, and allowing the core image to be built in more
flexible ways.
@end itemize
@node Features @node Features
@section GRUB features @section GRUB features
@ -264,10 +332,12 @@ devices, partitions, and files in a directory depending on context.
@item Support multiple filesystem types @item Support multiple filesystem types
Support multiple filesystem types transparently, plus a useful explicit Support multiple filesystem types transparently, plus a useful explicit
blocklist notation. The currently supported filesystem types are blocklist notation. The currently supported filesystem types are @dfn{Amiga
@dfn{BSD FFS}, @dfn{DOS FAT16 and FAT32}, @dfn{Minix fs}, @dfn{Linux Fast FileSystem (AFFS)}, @dfn{AtheOS fs}, @dfn{BeFS}, @dfn{cpio}, @dfn{Linux
ext2fs}, @dfn{ReiserFS}, @dfn{JFS}, @dfn{XFS}, and @dfn{VSTa ext2/ext3/ext4}, @dfn{DOS FAT12/FAT16/FAT32}, @dfn{HFS}, @dfn{HFS+},
fs}. @xref{Filesystem}, for more information. @dfn{ISO9660}, @dfn{JFS}, @dfn{Minix fs}, @dfn{nilfs2}, @dfn{NTFS},
@dfn{ReiserFS}, @dfn{Amiga Smart FileSystem (SFS)}, @dfn{tar}, @dfn{UDF},
@dfn{BSD UFS/UFS2}, and @dfn{XFS}. @xref{Filesystem}, for more information.
@item Support automatic decompression @item Support automatic decompression
Can decompress files which were compressed by @command{gzip}. This Can decompress files which were compressed by @command{gzip}. This
@ -471,6 +541,7 @@ the @dfn{boot directory}.
@menu @menu
* Installing GRUB using grub-install:: * Installing GRUB using grub-install::
* Making a GRUB bootable CD-ROM:: * Making a GRUB bootable CD-ROM::
* Device map::
@end menu @end menu
@ -615,6 +686,50 @@ to @samp{(cd)} when booted from a CD-ROM. It is only necessary to refer to
@samp{(cd)} if you want to access other drives as well. @samp{(cd)} if you want to access other drives as well.
@node Device map
@section The map between BIOS drives and OS devices
The @command{grub-mkdevicemap} program can be used to create the @dfn{device
map file}. It is often run automatically by tools such as
@command{grub-install} if the device map file does not already exist. The
file name @file{/boot/grub/device.map} is preferred.
If the device map file exists, the GRUB utilities (@command{grub-probe},
@command{grub-setup}, etc.) read it to map BIOS drives to OS devices. This
file consists of lines like this:
@example
@var{device} @var{file}
@end example
@var{device} is a drive specified in the GRUB syntax (@pxref{Device
syntax}), and @var{file} is an OS file, which is normally a device file.
Historically, the device map file was used because GRUB device names had to
be used in the configuration file, and they were derived from BIOS drive
numbers. The map between BIOS drives and OS devices cannot always be
guessed correctly: for example, GRUB will get the order wrong if you
exchange the boot sequence between IDE and SCSI in your BIOS.
Unfortunately, even OS device names are not always stable. Modern versions
of the Linux kernel may probe drives in a different order from boot to boot,
and the prefix (@file{/dev/hd*} versus @file{/dev/sd*}) may change depending
on the driver subsystem in use. As a result, the device map file required
frequent editing on some systems.
GRUB avoids this problem nowadays by using UUIDs or file system labels when
generating @file{grub.cfg}, and we advise that you do the same for any
custom menu entries you write. If the device map file does not exist, then
the GRUB utilities will assume a temporary device map on the fly. This is
often good enough, particularly in the common case of single-disk systems.
However, the device map file is not entirely obsolete yet, and there are
still some situations that require it to exist. If necessary, you may edit
the file if @command{grub-mkdevicemap} makes a mistake. You can put any
comments in the file if needed, as the GRUB utilities assume that a line is
just a comment if the first character is @samp{#}.
@node Booting @node Booting
@chapter Booting @chapter Booting
@ -729,11 +844,36 @@ Run the command @command{boot} (@pxref{boot}).
It is relatively easy to boot GNU/Linux from GRUB, because it somewhat It is relatively easy to boot GNU/Linux from GRUB, because it somewhat
resembles to boot a Multiboot-compliant OS. resembles to boot a Multiboot-compliant OS.
FIXME: this section is incomplete.
@enumerate @enumerate
@item @item
Set GRUB's root device to the same drive as GNU/Linux's. Set GRUB's root device to the same drive as GNU/Linux's. The command
@code{search --file --set /vmlinuz} or similar may help you
(@pxref{search}).
@item
Load the kernel using the command @command{linux} (@pxref{linux}):
@example
grub> @kbd{linux /vmlinuz root=/dev/sda1}
@end example
If you need to specify some kernel parameters, just append them to the
command. For example, to set @option{acpi} to @samp{off}, do this:
@example
grub> @kbd{linux /vmlinuz root=/dev/sda1 acpi=off}
@end example
See the documentation in the Linux source tree for complete information on
the available options.
@item
If you use an initrd, execute the command @command{initrd} (@pxref{initrd})
after @command{linux}:
@example
grub> @kbd{initrd /initrd}
@end example
@item @item
Finally, run the command @command{boot} (@pxref{boot}). Finally, run the command @command{boot} (@pxref{boot}).
@ -805,6 +945,8 @@ need to write the whole thing by hand.
@menu @menu
* Simple configuration:: Recommended for most users * Simple configuration:: Recommended for most users
* Shell-like scripting:: For power users and developers * Shell-like scripting:: For power users and developers
* Embedded configuration:: Embedding a configuration file into GRUB
* Themes:: Graphical menu themes
@end menu @end menu
@ -911,10 +1053,11 @@ A command to configure the serial port when using the serial console.
Command-line arguments to add to menu entries for the Linux kernel. Command-line arguments to add to menu entries for the Linux kernel.
@item GRUB_CMDLINE_LINUX_DEFAULT @item GRUB_CMDLINE_LINUX_DEFAULT
Unless @samp{GRUB_DISABLE_LINUX_RECOVERY} is set, two menu entries will be Unless @samp{GRUB_DISABLE_LINUX_RECOVERY} is set to @samp{true}, two menu
generated for each Linux kernel: one default entry and one entry for entries will be generated for each Linux kernel: one default entry and one
recovery mode. This option lists command-line arguments to add only to the entry for recovery mode. This option lists command-line arguments to add
default menu entry, after those listed in @samp{GRUB_CMDLINE_LINUX}. only to the default menu entry, after those listed in
@samp{GRUB_CMDLINE_LINUX}.
@item GRUB_CMDLINE_NETBSD @item GRUB_CMDLINE_NETBSD
@itemx GRUB_CMDLINE_NETBSD_DEFAULT @itemx GRUB_CMDLINE_NETBSD_DEFAULT
@ -929,10 +1072,22 @@ usually more reliable, but in some cases it may not be appropriate. To
disable the use of UUIDs, set this option to @samp{true}. disable the use of UUIDs, set this option to @samp{true}.
@item GRUB_DISABLE_LINUX_RECOVERY @item GRUB_DISABLE_LINUX_RECOVERY
Disable the generation of recovery mode menu entries for Linux. If this option is set to @samp{true}, disable the generation of recovery
mode menu entries for Linux.
@item GRUB_DISABLE_NETBSD_RECOVERY @item GRUB_DISABLE_NETBSD_RECOVERY
Disable the generation of recovery mode menu entries for NetBSD. If this option is set to @samp{true}, disable the generation of recovery
mode menu entries for NetBSD.
@item GRUB_VIDEO_BACKEND
If graphical video support is required, either because the @samp{gfxterm}
graphical terminal is in use or because @samp{GRUB_GFXPAYLOAD_LINUX} is set,
then @command{grub-mkconfig} will normally load all available GRUB video
drivers and use the one most appropriate for your hardware. If you need to
override this for some reason, then you can set this option.
After @command{grub-install} has been run, the available video drivers are
listed in @file{/boot/grub/video.lst}.
@item GRUB_GFXMODE @item GRUB_GFXMODE
Set the resolution used on the @samp{gfxterm} graphical terminal. Note that Set the resolution used on the @samp{gfxterm} graphical terminal. Note that
@ -973,6 +1128,11 @@ for them. Set this option to @samp{true} to disable this.
Play a tune on the speaker when GRUB starts. This is particularly useful Play a tune on the speaker when GRUB starts. This is particularly useful
for users unable to see the screen. The value of this option is passed for users unable to see the screen. The value of this option is passed
directly to @ref{play}. directly to @ref{play}.
@item GRUB_BADRAM
If this option is set, GRUB will issue a @ref{badram} command to filter
out specified regions of RAM.
@end table @end table
For more detailed customisation of @command{grub-mkconfig}'s output, you may For more detailed customisation of @command{grub-mkconfig}'s output, you may
@ -986,6 +1146,78 @@ that file, making sure to leave at least the first two lines intact.
@section Writing full configuration files directly @section Writing full configuration files directly
@node Embedded configuration
@section Embedding a configuration file into GRUB
GRUB supports embedding a configuration file directly into the core image,
so that it is loaded before entering normal mode. This is useful, for
example, when it is not straightforward to find the real configuration file,
or when you need to debug problems with loading that file.
@command{grub-install} uses this feature when it is not using BIOS disk
functions or when installing to a different disk from the one containing
@file{/boot/grub}, in which case it needs to use the @command{search}
command (@pxref{search}) to find @file{/boot/grub}.
To embed a configuration file, use the @option{-c} option to
@command{grub-mkimage}. The file is copied into the core image, so it may
reside anywhere on the file system, and may be removed after running
@command{grub-mkimage}.
After the embedded configuration file (if any) is executed, GRUB will load
the @samp{normal} module, which will then read the real configuration file
from @file{$prefix/grub.cfg}. By this point, the @code{root} variable will
also have been set to the root device name. For example, @code{prefix}
might be set to @samp{(hd0,1)/boot/grub}, and @code{root} might be set to
@samp{hd0,1}. Thus, in most cases, the embedded configuration file only
needs to set the @code{prefix} and @code{root} variables, and then drop
through to GRUB's normal processing. A typical example of this might look
like this:
@example
@group
search.fs_uuid 01234567-89ab-cdef-0123-456789abcdef root
set prefix=($root)/boot/grub
@end group
@end example
(The @samp{search_fs_uuid} module must be included in the core image for this
example to work.)
In more complex cases, it may be useful to read other configuration files
directly from the embedded configuration file. This allows such things as
reading files not called @file{grub.cfg}, or reading files from a directory
other than that where GRUB's loadable modules are installed. To do this,
include the @samp{configfile} and @samp{normal} modules in the core image,
and embed a configuration file that uses the @command{configfile} command to
load another file. The following example of this also requires the
@command{echo}, @command{search_label}, and @command{test} modules to be
included in the core image:
@example
@group
search.fs_label grub root
if [ -e /boot/grub/example/test1.cfg ]; then
set prefix=($root)/boot/grub
configfile /boot/grub/example/test1.cfg
else
if [ -e /boot/grub/example/test2.cfg ]; then
set prefix=($root)/boot/grub
configfile /boot/grub/example/test2.cfg
else
echo "Could not find an example configuration file!"
fi
fi
@end group
@end example
The embedded configuration file may not contain menu entries directly, but
may only read them from elsewhere using @command{configfile}.
@node Themes
@section Graphical menu themes
@node Network @node Network
@chapter Booting GRUB from the network @chapter Booting GRUB from the network
@ -1073,18 +1305,13 @@ minicom. Refer to a manual of your operating system, for more
information. information.
As for GRUB, the instruction to set up a serial terminal is quite As for GRUB, the instruction to set up a serial terminal is quite
simple. First of all, make sure that you haven't specified the option simple. Here is an example:
@option{--disable-serial} to the configure script when you built your
GRUB images. If you get them in binary form, probably they have serial
terminal support already.
Then, initialize your serial terminal after GRUB starts up. Here is an
example:
@example @example
@group @group
grub> @kbd{serial --unit=0 --speed=9600} grub> @kbd{serial --unit=0 --speed=9600}
grub> @kbd{terminal serial} grub> @kbd{terminal_input serial}
grub> @kbd{terminal_output serial}
@end group @end group
@end example @end example
@ -1109,16 +1336,19 @@ implements few VT100 escape sequences. If you specify this option then
GRUB provides you with an alternative menu interface, because the normal GRUB provides you with an alternative menu interface, because the normal
menu requires several fancy features of your terminal. menu requires several fancy features of your terminal.
@node Vendor power-on keys @node Vendor power-on keys
@chapter Using GRUB with vendor power-on keys @chapter Using GRUB with vendor power-on keys
Some laptop vendor provide an additional power-on button which boots another OS.
GRUB supports such buttons with GRUB_TIMEOUT_BUTTON, GRUB_DEFAULT_BUTTON, Some laptop vendors provide an additional power-on button which boots another
GRUB_HIDDEN_TIMEOUT_BUTTON and GRUB_BUTTON_CMOS_ADDRESS variables in OS. GRUB supports such buttons with the @samp{GRUB_TIMEOUT_BUTTON},
default/grub. GRUB_TIMEOUT_BUTTON, GRUB_DEFAULT_BUTTON and @samp{GRUB_DEFAULT_BUTTON}, @samp{GRUB_HIDDEN_TIMEOUT_BUTTON} and
GRUB_HIDDEN_TIMEOUT_BUTTON are used instead of corresponding variables without @samp{GRUB_BUTTON_CMOS_ADDRESS} variables in default/grub (@pxref{Simple
_BUTTON suffix when powered using special button. configuration}). @samp{GRUB_TIMEOUT_BUTTON}, @samp{GRUB_DEFAULT_BUTTON} and
GRUB_BUTTON_CMOS_ADDRESS is vendor specific and partially model-specific. @samp{GRUB_HIDDEN_TIMEOUT_BUTTON} are used instead of the corresponding
Values known to GRUB team are: variables without the @samp{_BUTTON} suffix when powered on using the special
button. @samp{GRUB_BUTTON_CMOS_ADDRESS} is vendor-specific and partially
model-specific. Values known to the GRUB team are:
@table @key @table @key
@item Dell XPS M1530 @item Dell XPS M1530
@ -1127,7 +1357,144 @@ Values known to GRUB team are:
84:1 (unconfirmed) 84:1 (unconfirmed)
@end table @end table
To take full advantage of this function install GRUB into MBR. To take full advantage of this function, install GRUB into the MBR
(@pxref{Installing GRUB using grub-install}).
@node Images
@chapter GRUB image files
@c FIXME: parts of this section are specific to PC BIOS right now.
GRUB consists of several images: a variety of bootstrap images for starting
GRUB in various ways, a kernel image, and a set of modules which are
combined with the kernel image to form a core image. Here is a short
overview of them.
@table @file
@item boot.img
On PC BIOS systems, this image is the first part of GRUB to start. It is
written to a master boot record (MBR) or to the boot sector of a partition.
Because a PC boot sector is 512 bytes, the size of this image is exactly 512
bytes.
The sole function of @file{boot.img} is to read the first sector of the core
image from a local disk and jump to it. Because of the size restriction,
@file{boot.img} cannot understand any file system structure, so
@command{grub-setup} hardcodes the location of the first sector of the core
image into @file{boot.img} when installing GRUB.
@item diskboot.img
This image is used as the first sector of the core image when booting from a
hard disk. It reads the rest of the core image into memory and starts the
kernel. Since file system handling is not yet available, it encodes the
location of the core image using a block list format.
@item cdboot.img
This image is used as the first sector of the core image when booting from a
CD-ROM drive. It performs a similar function to @file{diskboot.img}.
@item pxeboot.img
This image is used as the start of the core image when booting from the
network using PXE. @xref{Network}.
@item lnxboot.img
This image may be placed at the start of the core image in order to make
GRUB look enough like a Linux kernel that it can be booted by LILO using an
@samp{image=} section.
@item kernel.img
This image contains GRUB's basic run-time facilities: frameworks for device
and file handling, environment variables, the rescue mode command-line
parser, and so on. It is rarely used directly, but is built into all core
images.
@item core.img
This is the core image of GRUB. It is built dynamically from the kernel
image and an arbitrary list of modules by the @command{grub-mkimage}
program. Usually, it contains enough modules to access @file{/boot/grub},
and loads everything else (including menu handling, the ability to load
target operating systems, and so on) from the file system at run-time. The
modular design allows the core image to be kept small, since the areas of
disk where it must be installed are often as small as 32KB.
On PC systems using the traditional MBR partition table format, the core
image is usually installed in the "MBR gap" between the master boot record
and the first partition, or sometimes it is installed in a file system and
read directly from that. The latter is not recommended because GRUB needs
to encode the location of all the core image sectors in @file{diskboot.img},
and if the file system ever moves the core image around (as it is entitled
to do) then GRUB must be reinstalled; it also means that GRUB will not be
able to reliably find the core image if it resides on a different disk than
the one to which @file{boot.img} was installed.
On PC systems using the more recent GUID Partition Table (GPT) format, the
core image should be installed to a BIOS Boot Partition. This may be
created by GNU Parted using a command such as the following:
@example
# @kbd{parted /dev/@var{disk} set @var{partition-number} bios_grub on}
@end example
@strong{Caution:} Be very careful which partition you select! When GRUB
finds a BIOS Boot Partition during installation, it will automatically
overwrite part of it. Make sure that the partition does not contain any
other data.
@item *.mod
Everything else in GRUB resides in dynamically loadable modules. These are
often loaded automatically, or built into the core image if they are
essential, but may also be loaded manually using the @command{insmod}
command (@pxref{insmod}).
@end table
@heading For GRUB Legacy users
GRUB 2 has a different design from GRUB Legacy, and so correspondences with
the images it used cannot be exact. Nevertheless, GRUB Legacy users often
ask questions in the terms they are familiar with, and so here is a brief
guide to how GRUB 2's images relate to that.
@table @file
@item stage1
Stage 1 from GRUB Legacy was very similar to @file{boot.img} in GRUB 2, and
they serve the same function.
@item *_stage1_5
In GRUB Legacy, Stage 1.5's function was to include enough filesystem code
to allow the much larger Stage 2 to be read from an ordinary filesystem. In
this respect, its function was similar to @file{core.img} in GRUB 2.
However, @file{core.img} is much more capable than Stage 1.5 was; since it
offers a rescue shell, it is sometimes possible to recover manually in the
event that it is unable to load any other modules, for example if partition
numbers have changed. @file{core.img} is built in a more flexible way,
allowing GRUB 2 to support reading modules from advanced disk types such as
LVM and RAID.
GRUB Legacy could run with only Stage 1 and Stage 2 in some limited
configurations, while GRUB 2 requires @file{core.img} and cannot work
without it.
@item stage2
GRUB 2 has no single Stage 2 image. Instead, it loads modules from
@file{/boot/grub} at run-time.
@item stage2_eltorito
In GRUB 2, images for booting from CD-ROM drives are now constructed using
@file{cdboot.img} and @file{core.img}, making sure that the core image
contains the @samp{iso9660} module. It is usually best to use the
@command{grub-mkrescue} program for this.
@item nbgrub
There is as yet no equivalent for @file{nbgrub} in GRUB 2; it was used by
Etherboot and some other network boot loaders.
@item pxegrub
In GRUB 2, images for PXE network booting are now constructed using
@file{pxeboot.img} and @file{core.img}, making sure that the core image
contains the @samp{pxe} and @samp{pxecmd} modules. @xref{Network}.
@end table
@node Filesystem @node Filesystem
@chapter Filesystem syntax and semantics @chapter Filesystem syntax and semantics
@ -1353,19 +1720,12 @@ of entry names.
If an @key{ESC} is pressed in the editor, it aborts all the changes made If an @key{ESC} is pressed in the editor, it aborts all the changes made
to the configuration entry and returns to the main menu interface. to the configuration entry and returns to the main menu interface.
When a particular line is selected, the editor places the user in a Each line in the menu entry can be edited freely, and you can add new lines
special version of the GRUB command-line to edit that line. When the by pressing @key{RET} at the end of a line. To boot the edited entry, press
user hits @key{RET}, GRUB replaces the line in question in the boot @key{Ctrl-x}.
entry with the changes (unless it was aborted via @key{ESC},
in which case the changes are thrown away).
If you want to add a new line to the menu entry, press @key{o} if adding Although GRUB unfortunately does not support @dfn{undo}, you can do almost
a line after the current line or press @key{O} if before the current the same thing by just returning to the main menu using @key{ESC}.
line.
To delete a line, hit the key @key{d}. Although GRUB unfortunately
does not support @dfn{undo}, you can do almost the same thing by just
returning to the main menu.
@node Commands @node Commands
@ -1378,6 +1738,10 @@ the global section of the configuration file (or ``menu''); most
of them can be entered on the command-line and can be used either of them can be entered on the command-line and can be used either
anywhere in the menu or specifically in the menu entries. anywhere in the menu or specifically in the menu entries.
In rescue mode, only the @command{insmod} (@pxref{insmod}), @command{ls}
(@pxref{ls}), @command{set} (@pxref{set}), and @command{unset}
(@pxref{unset}) commands are normally available.
@menu @menu
* Menu-specific commands:: * Menu-specific commands::
* General commands:: * General commands::
@ -1510,16 +1874,23 @@ names active.
@node terminfo @node terminfo
@subsection terminfo @subsection terminfo
@deffn Command terminfo [term] @deffn Command terminfo [-a|-u|-v] [term]
Define the capabilities of your terminal by giving the name of an entry in Define the capabilities of your terminal by giving the name of an entry in
the terminfo database, which should correspond roughly to a @samp{TERM} the terminfo database, which should correspond roughly to a @samp{TERM}
environment variable in Unix. environment variable in Unix.
At the moment, only @samp{vt100} is supported in GRUB 2. If you need other The currently available terminal types are @samp{vt100}, @samp{vt100-color},
terminal types, please contact us to discuss the best way to include support @samp{ieee1275}, and @samp{dumb}. If you need other terminal types, please
for these in GRUB. contact us to discuss the best way to include support for these in GRUB.
If no option is specified, the current terminal type is printed. The @option{-a} (@option{--ascii}), @option{-u} (@option{--utf8}), and
@option{-v} (@option{--visual-utf8}) options control how non-ASCII text is
displayed. @option{-a} specifies an ASCII-only terminal; @option{-u}
specifies logically-ordered UTF-8; and @option{-v} specifies
visually-ordered UTF-8.
If no option or terminal type is specified, the current terminal type is
printed.
@end deffn @end deffn
@ -1532,12 +1903,14 @@ you forget a command, you can run the command @command{help}
@menu @menu
* acpi:: Load ACPI tables * acpi:: Load ACPI tables
* badram:: Filter out bad regions of RAM
* blocklist:: Print a block list * blocklist:: Print a block list
* boot:: Start up your operating system * boot:: Start up your operating system
* cat:: Show the contents of a file * cat:: Show the contents of a file
* chainloader:: Chain-load another boot loader * chainloader:: Chain-load another boot loader
* cmp:: Compare two files * cmp:: Compare two files
* configfile:: Load a configuration file * configfile:: Load a configuration file
* cpuid:: Check for CPU features
* crc:: Calculate CRC32 checksums * crc:: Calculate CRC32 checksums
* date:: Display or set current date and time * date:: Display or set current date and time
* drivemap:: Map a drive to another * drivemap:: Map a drive to another
@ -1547,8 +1920,12 @@ you forget a command, you can run the command @command{help}
* gptsync:: Fill an MBR based on GPT entries * gptsync:: Fill an MBR based on GPT entries
* halt:: Shut down your computer * halt:: Shut down your computer
* help:: Show help messages * help:: Show help messages
* initrd:: Load a Linux initrd
* initrd16:: Load a Linux initrd (16-bit mode)
* insmod:: Insert a module * insmod:: Insert a module
* keystatus:: Check key modifier status * keystatus:: Check key modifier status
* linux:: Load a Linux kernel
* linux16:: Load a Linux kernel (16-bit mode)
* ls:: List devices or files * ls:: List devices or files
* parttool:: Modify partition table entries * parttool:: Modify partition table entries
* password:: Set a clear-text password * password:: Set a clear-text password
@ -1584,6 +1961,27 @@ Normally, this command will replace the Root System Description Pointer
GRUB, but may be used by GRUB's EFI emulation. GRUB, but may be used by GRUB's EFI emulation.
@end deffn @end deffn
@node badram
@subsection badram
@deffn Command badram addr,mask[,addr,mask...]
Filter out bad RAM.
@end deffn
This command notifies the memory manager that specified regions of
RAM ought to be filtered out (usually, because they're damaged). This
remains in effect after a payload kernel has been loaded by GRUB, as
long as the loaded kernel obtains its memory map from GRUB. Kernels that
support this include Linux, GNU Mach, the kernel of FreeBSD and Multiboot
kernels in general.
Syntax is the same as provided by the @uref{http://www.memtest.org/,
Memtest86+ utility}: a list of address/mask pairs. Given a page-aligned
address and a base address / mask pair, if all the bits of the page-aligned
address that are enabled by the mask match with the base address, it means
this page is to be filtered. This syntax makes it easy to represent patterns
that are often result of memory damage, due to physical distribution of memory
cells.
@node blocklist @node blocklist
@subsection blocklist @subsection blocklist
@ -1606,13 +2004,19 @@ a menu entry).
@node cat @node cat
@subsection cat @subsection cat
@deffn Command cat file @deffn Command cat [@option{--dos}] file
Display the contents of the file @var{file}. This command may be useful Display the contents of the file @var{file}. This command may be useful
to remind you of your OS's root partition: to remind you of your OS's root partition:
@example @example
grub> @kbd{cat /etc/fstab} grub> @kbd{cat /etc/fstab}
@end example @end example
If the @option{--dos} option is used, then carriage return / new line pairs
will be displayed as a simple new line. Otherwise, the carriage return will
be displayed as a control character (@samp{<d>}) to make it easier to see
when boot problems are caused by a file formatted using DOS-style line
endings.
@end deffn @end deffn
@ -1655,7 +2059,22 @@ If they are completely identical, nothing will be printed.
@subsection configfile @subsection configfile
@deffn Command configfile file @deffn Command configfile file
Load @var{file} as a configuration file. Load @var{file} as a configuration file. If @var{file} defines any menu
entries, then show a menu containing them immediately.
@end deffn
@node cpuid
@subsection cpuid
@deffn Command cpuid [-l]
Check for CPU features. This command is only available on x86 systems.
With the @option{-l} option, return true if the CPU supports long mode
(64-bit).
If invoked without options, this command currently behaves as if it had been
invoked with @option{-l}. This may change in the future.
@end deffn @end deffn
@ -1813,6 +2232,30 @@ about each of the commands whose names begin with those @var{patterns}.
@end deffn @end deffn
@node initrd
@subsection initrd
@deffn Command initrd file
Load an initial ramdisk for a Linux kernel image, and set the appropriate
parameters in the Linux setup area in memory. This may only be used after
the @command{linux} command (@pxref{linux}) has been run. See also
@ref{GNU/Linux}.
@end deffn
@node initrd16
@subsection initrd16
@deffn Command initrd16 file
Load an initial ramdisk for a Linux kernel image to be booted in 16-bit
mode, and set the appropriate parameters in the Linux setup area in memory.
This may only be used after the @command{linux16} command (@pxref{linux16})
has been run. See also @ref{GNU/Linux}.
This command is only available on x86 systems.
@end deffn
@node insmod @node insmod
@subsection insmod @subsection insmod
@ -1835,6 +2278,42 @@ only if checking key modifier status is supported.
@end deffn @end deffn
@node linux
@subsection linux
@deffn Command linux file @dots{}
Load a Linux kernel image from @var{file}. The rest of the line is passed
verbatim as the @dfn{kernel command-line}. Any initrd must be reloaded
after using this command (@pxref{initrd}).
On x86 systems, the kernel will be booted using the 32-bit boot protocol.
Note that this means that the @samp{vga=} boot option will not work; if you
want to set a special video mode, you will need to use GRUB commands such as
@samp{set gfxpayload=1024x768} or @samp{set gfxpayload=keep} (to keep the
same mode as used in GRUB) instead. GRUB can automatically detect some uses
of @samp{vga=} and translate them to appropriate settings of
@samp{gfxpayload}. The @command{linux16} command (@pxref{linux16}) avoids
this restriction.
@end deffn
@node linux16
@subsection linux16
@deffn Command linux16 file @dots{}
Load a Linux kernel image from @var{file} in 16-bit mode. The rest of the
line is passed verbatim as the @dfn{kernel command-line}. Any initrd must
be reloaded after using this command (@pxref{initrd16}).
The kernel will be booted using the traditional 16-bit boot protocol. As
well as bypassing problems with @samp{vga=} described in @ref{linux}, this
permits booting some other programs that implement the Linux boot protocol
for the sake of convenience.
This command is only available on x86 systems.
@end deffn
@node ls @node ls
@subsection ls @subsection ls
@ -1947,7 +2426,7 @@ Reboot the computer.
@deffn Command search @ @deffn Command search @
[@option{--file}|@option{--label}|@option{--fs-uuid}] @ [@option{--file}|@option{--label}|@option{--fs-uuid}] @
[@option{--set} var] [@option{--no-floppy}] name [@option{--set} [var]] [@option{--no-floppy}] name
Search devices by file (@option{-f}, @option{--file}), filesystem label Search devices by file (@option{-f}, @option{--file}), filesystem label
(@option{-l}, @option{--label}), or filesystem UUID (@option{-u}, (@option{-l}, @option{--label}), or filesystem UUID (@option{-u},
@option{--fs-uuid}). @option{--fs-uuid}).
@ -2103,6 +2582,9 @@ grub-install}). When doing this, there are a few things to remember:
Drive ordering in your operating system may not be the same as the boot Drive ordering in your operating system may not be the same as the boot
drive ordering used by your firmware. Do not assume that your first hard drive ordering used by your firmware. Do not assume that your first hard
drive (e.g. @samp{/dev/sda}) is the one that your firmware will boot from. drive (e.g. @samp{/dev/sda}) is the one that your firmware will boot from.
@file{device.map} (@pxref{Device map}) can be used to override this, but it
is usually better to use UUIDs or file system labels and avoid depending on
drive ordering entirely.
@item @item
At least on BIOS systems, if you tell @command{grub-install} to install GRUB At least on BIOS systems, if you tell @command{grub-install} to install GRUB
@ -2334,7 +2816,7 @@ Once we get your report, we will try to fix the bugs.
We started the next generation of GRUB, GRUB 2. GRUB 2 includes We started the next generation of GRUB, GRUB 2. GRUB 2 includes
internationalization, dynamic module loading, real memory management, internationalization, dynamic module loading, real memory management,
multiple architecture support, a scripting language, and many other multiple architecture support, a scripting language, and many other
nice feature. If you are interested in the development of GRUB 2, take nice features. If you are interested in the development of GRUB 2, take
a look at @uref{http://www.gnu.org/software/grub/grub.html, the a look at @uref{http://www.gnu.org/software/grub/grub.html, the
homepage}. homepage}.

2
docs/man/grub-emu.h2m Normal file
View file

@ -0,0 +1,2 @@
[NAME]
grub-emu \- GRUB emulator

View file

@ -26,6 +26,8 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/video.h> #include <grub/video.h>
#include <grub/bitmap.h> #include <grub/bitmap.h>
#include <grub/charset.h>
#include <grub/unicode.h>
#include <grub/fontformat.h> #include <grub/fontformat.h>
#ifdef USE_ASCII_FAILBACK #ifdef USE_ASCII_FAILBACK
@ -133,7 +135,7 @@ ascii_glyph_lookup (grub_uint32_t code)
static int ascii_failback_initialized = 0; static int ascii_failback_initialized = 0;
if (code >= 0x80) if (code >= 0x80)
return unknown_glyph; return NULL;
if (ascii_failback_initialized == 0) if (ascii_failback_initialized == 0)
{ {
@ -148,9 +150,10 @@ ascii_glyph_lookup (grub_uint32_t code)
ascii_font_glyph[current]->offset_x = 0; ascii_font_glyph[current]->offset_x = 0;
ascii_font_glyph[current]->offset_y = -2; ascii_font_glyph[current]->offset_y = -2;
ascii_font_glyph[current]->device_width = 8; ascii_font_glyph[current]->device_width = 8;
ascii_font_glyph[current]->font = NULL;
grub_memcpy (ascii_font_glyph[current]->bitmap, grub_memcpy (ascii_font_glyph[current]->bitmap,
&ascii_bitmaps[(0x7f - current) * ASCII_BITMAP_SIZE], &ascii_bitmaps[current * ASCII_BITMAP_SIZE],
ASCII_BITMAP_SIZE); ASCII_BITMAP_SIZE);
} }
@ -160,7 +163,7 @@ ascii_glyph_lookup (grub_uint32_t code)
return ascii_font_glyph[code]; return ascii_font_glyph[code];
#else #else
(void) code; (void) code;
return unknown_glyph; return NULL;
#endif #endif
} }
@ -900,6 +903,13 @@ grub_font_get_descent (grub_font_t font)
return font->descent; return font->descent;
} }
/* FIXME: not correct for all fonts. */
int
grub_font_get_xheight (grub_font_t font)
{
return font->ascent / 2;
}
/* Get the *standard leading* of the font in pixel, which is the spacing /* Get the *standard leading* of the font in pixel, which is the spacing
between two lines of text. Specifically, it is the space between the between two lines of text. Specifically, it is the space between the
descent of one line and the ascent of the next line. This is included descent of one line and the ascent of the next line. This is included
@ -917,27 +927,6 @@ grub_font_get_height (grub_font_t font)
return font->ascent + font->descent + font->leading; return font->ascent + font->descent + font->leading;
} }
/* Get the width in pixels of the specified UTF-8 string, when rendered in
in the specified font (but falling back on other fonts for glyphs that
are missing). */
int
grub_font_get_string_width (grub_font_t font, const char *str)
{
int width;
struct grub_font_glyph *glyph;
grub_uint32_t code;
const grub_uint8_t *ptr;
for (ptr = (const grub_uint8_t *) str, width = 0;
grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0;)
{
glyph = grub_font_get_glyph_with_fallback (font, code);
width += glyph->device_width;
}
return width;
}
/* Get the glyph for FONT corresponding to the Unicode code point CODE. /* Get the glyph for FONT corresponding to the Unicode code point CODE.
Returns the ASCII glyph for the code if no other fonts are available. Returns the ASCII glyph for the code if no other fonts are available.
The glyphs are cached once loaded. */ The glyphs are cached once loaded. */
@ -1029,6 +1018,8 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code)
next = node->next; next = node->next;
glyph = grub_font_get_glyph_internal (curfont, code); glyph = grub_font_get_glyph_internal (curfont, code);
if (glyph && !font)
return glyph;
if (glyph) if (glyph)
{ {
int d; int d;
@ -1042,13 +1033,457 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code)
} }
} }
if (best_glyph)
return best_glyph; return best_glyph;
else
/* Glyph not available in any font. Return ASCII failback. */
return ascii_glyph_lookup (code);
} }
static struct grub_font_glyph *
grub_font_dup_glyph (struct grub_font_glyph *glyph)
{
static struct grub_font_glyph *ret;
ret = grub_malloc (sizeof (*ret) + (glyph->width * glyph->height + 7) / 8);
if (!ret)
return NULL;
grub_memcpy (ret, glyph, sizeof (*ret)
+ (glyph->width * glyph->height + 7) / 8);
return ret;
}
/* FIXME: suboptimal. */
static void
grub_font_blit_glyph (struct grub_font_glyph *target,
struct grub_font_glyph *src, unsigned dx, unsigned dy)
{
unsigned src_bit, tgt_bit, src_byte, tgt_byte;
unsigned i, j;
for (i = 0; i < src->height; i++)
{
src_bit = (src->width * i) % 8;
src_byte = (src->width * i) / 8;
tgt_bit = (target->width * (dy + i) + dx) % 8;
tgt_byte = (target->width * (dy + i) + dx) / 8;
for (j = 0; j < src->width; j++)
{
target->bitmap[tgt_byte] |= ((src->bitmap[src_byte] << src_bit)
& 0x80) >> tgt_bit;
src_bit++;
tgt_bit++;
if (src_bit == 8)
{
src_byte++;
src_bit = 0;
}
if (tgt_bit == 8)
{
tgt_byte++;
tgt_bit = 0;
}
}
}
}
static void
grub_font_blit_glyph_mirror (struct grub_font_glyph *target,
struct grub_font_glyph *src,
unsigned dx, unsigned dy)
{
unsigned tgt_bit, src_byte, tgt_byte;
signed src_bit;
unsigned i, j;
for (i = 0; i < src->height; i++)
{
src_bit = (src->width * i + src->width - 1) % 8;
src_byte = (src->width * i + src->width - 1) / 8;
tgt_bit = (target->width * (dy + i) + dx) % 8;
tgt_byte = (target->width * (dy + i) + dx) / 8;
for (j = 0; j < src->width; j++)
{
target->bitmap[tgt_byte] |= ((src->bitmap[src_byte] << src_bit)
& 0x80) >> tgt_bit;
src_bit--;
tgt_bit++;
if (src_bit == -1)
{
src_byte--;
src_bit = 7;
}
if (tgt_bit == 8)
{
tgt_byte++;
tgt_bit = 0;
}
}
}
}
static void
blit_comb (const struct grub_unicode_glyph *glyph_id,
struct grub_font_glyph *glyph,
struct grub_video_signed_rect *bounds_out,
struct grub_font_glyph *main_glyph,
struct grub_font_glyph **combining_glyphs, int *device_width)
{
struct grub_video_signed_rect bounds;
unsigned i;
signed above_rightx, above_righty;
signed above_leftx, above_lefty;
signed below_rightx, below_righty;
signed min_devwidth = 0;
auto void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src,
signed dx, signed dy);
void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src,
signed dx, signed dy)
{
if (glyph)
grub_font_blit_glyph (glyph, src, dx - glyph->offset_x,
(glyph->height + glyph->offset_y) + dy);
if (dx < bounds.x)
{
bounds.width += bounds.x - dx;
bounds.x = dx;
}
if (bounds.y > -src->height - dy)
{
bounds.height += bounds.y - (-src->height - dy);
bounds.y = (-src->height - dy);
}
if (dx + src->width - bounds.x >= (signed) bounds.width)
bounds.width = dx + src->width - bounds.x + 1;
if ((signed) bounds.height < src->height + (-src->height - dy) - bounds.y)
bounds.height = src->height + (-src->height - dy) - bounds.y;
}
auto void add_device_width (int val);
void add_device_width (int val)
{
if (glyph)
glyph->device_width += val;
if (device_width)
*device_width += val;
}
if (glyph)
glyph->device_width = main_glyph->device_width;
if (device_width)
*device_width = main_glyph->device_width;
bounds.x = main_glyph->offset_x;
bounds.y = main_glyph->offset_y;
bounds.width = main_glyph->width;
bounds.height = main_glyph->height;
above_rightx = main_glyph->offset_x + main_glyph->width;
above_righty = bounds.y + bounds.height;
above_leftx = main_glyph->offset_x;
above_lefty = bounds.y + bounds.height;
below_rightx = bounds.x + bounds.width;
below_righty = bounds.y;
for (i = 0; i < glyph_id->ncomb; i++)
{
grub_int16_t space = 0;
/* Center by default. */
grub_int16_t targetx;
if (!combining_glyphs[i])
continue;
targetx = (bounds.width - combining_glyphs[i]->width) / 2 + bounds.x;
/* CGJ is to avoid diacritics reordering. */
if (glyph_id->combining[i].code
== GRUB_UNICODE_COMBINING_GRAPHEME_JOINER)
continue;
switch (glyph_id->combining[i].type)
{
case GRUB_UNICODE_COMB_OVERLAY:
do_blit (combining_glyphs[i],
targetx,
(bounds.height - combining_glyphs[i]->height) / 2
- (bounds.height + bounds.y));
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT:
do_blit (combining_glyphs[i], above_rightx, -above_righty);
above_rightx += combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_ABOVE_RIGHT:
do_blit (combining_glyphs[i], above_rightx,
-(above_righty + combining_glyphs[i]->height));
above_rightx += combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_ABOVE_LEFT:
above_leftx -= combining_glyphs[i]->width;
do_blit (combining_glyphs[i], above_leftx,
-(above_lefty + combining_glyphs[i]->height));
break;
case GRUB_UNICODE_COMB_BELOW_RIGHT:
do_blit (combining_glyphs[i], below_rightx, below_righty);
below_rightx += combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_HEBREW_HOLAM:
if (glyph_id->base != GRUB_UNICODE_HEBREW_WAW)
targetx =
main_glyph->offset_x - combining_glyphs[i]->width -
(combining_glyphs[i]->width + 3) / 4;
goto above_on_main;
case GRUB_UNICODE_COMB_HEBREW_SIN_DOT:
targetx = main_glyph->offset_x + combining_glyphs[i]->width / 4;
goto above_on_main;
case GRUB_UNICODE_COMB_HEBREW_SHIN_DOT:
targetx =
main_glyph->width + main_glyph->offset_x -
combining_glyphs[i]->width;
above_on_main:
space = combining_glyphs[i]->offset_y
- grub_font_get_xheight (combining_glyphs[i]->font) - 1;
if (space <= 0)
space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8;
do_blit (combining_glyphs[i], targetx,
-(main_glyph->height + main_glyph->offset_y + space
+ combining_glyphs[i]->height));
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
/* TODO: Put dammah, fathah and alif nearer to shadda. */
case GRUB_UNICODE_COMB_SYRIAC_SUPERSCRIPT_ALAPH:
case GRUB_UNICODE_COMB_ARABIC_DAMMAH:
case GRUB_UNICODE_COMB_ARABIC_DAMMATAN:
case GRUB_UNICODE_COMB_ARABIC_FATHATAN:
case GRUB_UNICODE_COMB_ARABIC_FATHAH:
case GRUB_UNICODE_COMB_ARABIC_SUPERSCRIPT_ALIF:
case GRUB_UNICODE_COMB_ARABIC_SUKUN:
case GRUB_UNICODE_COMB_ARABIC_SHADDA:
case GRUB_UNICODE_COMB_HEBREW_RAFE:
case GRUB_UNICODE_STACK_ABOVE:
stacked_above:
space = combining_glyphs[i]->offset_y
- grub_font_get_xheight (combining_glyphs[i]->font) - 1;
if (space <= 0)
space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8;
case GRUB_UNICODE_STACK_ATTACHED_ABOVE:
do_blit (combining_glyphs[i], targetx,
-(bounds.height + bounds.y + space
+ combining_glyphs[i]->height));
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_HEBREW_SHEVA:
case GRUB_UNICODE_COMB_HEBREW_HIRIQ:
case GRUB_UNICODE_COMB_HEBREW_QAMATS:
case GRUB_UNICODE_COMB_HEBREW_TSERE:
case GRUB_UNICODE_COMB_HEBREW_SEGOL:
/* TODO: placement in final kaf and under reish. */
case GRUB_UNICODE_COMB_HEBREW_HATAF_SEGOL:
case GRUB_UNICODE_COMB_HEBREW_HATAF_PATAH:
case GRUB_UNICODE_COMB_HEBREW_HATAF_QAMATS:
case GRUB_UNICODE_COMB_HEBREW_PATAH:
case GRUB_UNICODE_COMB_HEBREW_QUBUTS:
case GRUB_UNICODE_COMB_HEBREW_METEG:
/* TODO: Put kasra and kasratan under shadda. */
case GRUB_UNICODE_COMB_ARABIC_KASRA:
case GRUB_UNICODE_COMB_ARABIC_KASRATAN:
/* I don't know how ypogegrammeni differs from subscript. */
case GRUB_UNICODE_COMB_YPOGEGRAMMENI:
case GRUB_UNICODE_STACK_BELOW:
stacked_below:
space = -(combining_glyphs[i]->offset_y
+ combining_glyphs[i]->height);
if (space <= 0)
space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8;
case GRUB_UNICODE_STACK_ATTACHED_BELOW:
do_blit (combining_glyphs[i], targetx, -(bounds.y - space));
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_MN:
switch (glyph_id->combining[i].code)
{
case GRUB_UNICODE_THAANA_ABAFILI:
case GRUB_UNICODE_THAANA_AABAAFILI:
case GRUB_UNICODE_THAANA_UBUFILI:
case GRUB_UNICODE_THAANA_OOBOOFILI:
case GRUB_UNICODE_THAANA_EBEFILI:
case GRUB_UNICODE_THAANA_EYBEYFILI:
case GRUB_UNICODE_THAANA_OBOFILI:
case GRUB_UNICODE_THAANA_OABOAFILI:
case GRUB_UNICODE_THAANA_SUKUN:
goto stacked_above;
case GRUB_UNICODE_THAANA_IBIFILI:
case GRUB_UNICODE_THAANA_EEBEEFILI:
goto stacked_below;
}
/* Fall through. */
default:
{
/* Default handling. Just draw combining character on top
of base character.
FIXME: support more unicode types correctly.
*/
do_blit (combining_glyphs[i],
main_glyph->device_width
+ combining_glyphs[i]->offset_x,
-(combining_glyphs[i]->height
+ combining_glyphs[i]->offset_y));
add_device_width (combining_glyphs[i]->device_width);
}
}
}
add_device_width ((above_rightx >
below_rightx ? above_rightx : below_rightx) -
(main_glyph->offset_x + main_glyph->width));
add_device_width (above_leftx - main_glyph->offset_x);
if (glyph && glyph->device_width < min_devwidth)
glyph->device_width = min_devwidth;
if (device_width && *device_width < min_devwidth)
*device_width = min_devwidth;
if (bounds_out)
*bounds_out = bounds;
}
static struct grub_font_glyph *
grub_font_construct_dry_run (grub_font_t hinted_font,
const struct grub_unicode_glyph *glyph_id,
struct grub_video_signed_rect *bounds,
struct grub_font_glyph ***combining_glyphs_out,
int *device_width)
{
struct grub_font_glyph *main_glyph = NULL;
struct grub_font_glyph **combining_glyphs;
grub_uint32_t desired_attributes = 0;
if (combining_glyphs_out)
*combining_glyphs_out = NULL;
if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED)
desired_attributes |= GRUB_FONT_CODE_RIGHT_JOINED;
if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED)
desired_attributes |= GRUB_FONT_CODE_LEFT_JOINED;
main_glyph = grub_font_get_glyph_with_fallback (hinted_font, glyph_id->base
| desired_attributes);
if (!main_glyph)
main_glyph = grub_font_get_glyph_with_fallback (hinted_font,
glyph_id->base);
/* Glyph not available in any font. Use ASCII fallback. */
if (!main_glyph)
main_glyph = ascii_glyph_lookup (glyph_id->base);
/* Glyph not available in any font. Return unknown glyph. */
if (!main_glyph)
return NULL;
if (device_width)
*device_width = main_glyph->device_width;
if (!glyph_id->ncomb && !glyph_id->attributes)
return main_glyph;
combining_glyphs = grub_malloc (sizeof (combining_glyphs[0])
* glyph_id->ncomb);
if (glyph_id->ncomb && !combining_glyphs)
{
grub_errno = GRUB_ERR_NONE;
return main_glyph;
}
{
unsigned i;
for (i = 0; i < glyph_id->ncomb; i++)
combining_glyphs[i]
= grub_font_get_glyph_with_fallback (main_glyph->font,
glyph_id->combining[i].code);
}
blit_comb (glyph_id, NULL, bounds, main_glyph, combining_glyphs,
device_width);
if (combining_glyphs_out)
*combining_glyphs_out = combining_glyphs;
else
grub_free (combining_glyphs);
return main_glyph;
}
int
grub_font_get_constructed_device_width (grub_font_t hinted_font,
const struct grub_unicode_glyph
*glyph_id)
{
int ret;
struct grub_font_glyph *main_glyph;
main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id, NULL,
NULL, &ret);
if (!main_glyph)
return unknown_glyph->device_width;
return ret;
}
struct grub_font_glyph *
grub_font_construct_glyph (grub_font_t hinted_font,
const struct grub_unicode_glyph *glyph_id)
{
struct grub_font_glyph *main_glyph;
struct grub_video_signed_rect bounds;
struct grub_font_glyph *glyph;
struct grub_font_glyph **combining_glyphs;
main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id,
&bounds, &combining_glyphs, NULL);
if (!main_glyph)
return grub_font_dup_glyph (unknown_glyph);
if (!combining_glyphs)
return grub_font_dup_glyph (main_glyph);
glyph =
grub_zalloc (sizeof (*glyph) + (bounds.width * bounds.height + 7) / 8);
if (!glyph)
{
grub_errno = GRUB_ERR_NONE;
return grub_font_dup_glyph (main_glyph);
}
glyph->font = main_glyph->font;
glyph->width = bounds.width;
glyph->height = bounds.height;
glyph->offset_x = bounds.x;
glyph->offset_y = bounds.y;
if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR)
grub_font_blit_glyph_mirror (glyph, main_glyph,
main_glyph->offset_x - glyph->offset_x,
(glyph->height + glyph->offset_y)
- (main_glyph->height +
main_glyph->offset_y));
else
grub_font_blit_glyph (glyph, main_glyph,
main_glyph->offset_x - glyph->offset_x,
(glyph->height + glyph->offset_y)
- (main_glyph->height + main_glyph->offset_y));
blit_comb (glyph_id, glyph, NULL, main_glyph, combining_glyphs, NULL);
return glyph;
}
/* Draw the specified glyph at (x, y). The y coordinate designates the /* Draw the specified glyph at (x, y). The y coordinate designates the
baseline of the character, while the x coordinate designates the left baseline of the character, while the x coordinate designates the left
@ -1065,8 +1500,8 @@ grub_font_draw_glyph (struct grub_font_glyph * glyph,
glyph_bitmap.mode_info.width = glyph->width; glyph_bitmap.mode_info.width = glyph->width;
glyph_bitmap.mode_info.height = glyph->height; glyph_bitmap.mode_info.height = glyph->height;
glyph_bitmap.mode_info.mode_type = glyph_bitmap.mode_info.mode_type
(1 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS) | GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP; = (1 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS) | GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP;
glyph_bitmap.mode_info.blit_format = GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED; glyph_bitmap.mode_info.blit_format = GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED;
glyph_bitmap.mode_info.bpp = 1; glyph_bitmap.mode_info.bpp = 1;
@ -1096,29 +1531,3 @@ grub_font_draw_glyph (struct grub_font_glyph * glyph,
bitmap_left, bitmap_top, bitmap_left, bitmap_top,
0, 0, glyph->width, glyph->height); 0, 0, glyph->width, glyph->height);
} }
/* Draw a UTF-8 string of text on the current video render target.
The x coordinate specifies the starting x position for the first character,
while the y coordinate specifies the baseline position.
If the string contains a character that FONT does not contain, then
a glyph from another loaded font may be used instead. */
grub_err_t
grub_font_draw_string (const char *str, grub_font_t font,
grub_video_color_t color, int left_x, int baseline_y)
{
int x;
struct grub_font_glyph *glyph;
grub_uint32_t code;
const grub_uint8_t *ptr;
for (ptr = (const grub_uint8_t *) str, x = left_x;
grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0;)
{
glyph = grub_font_get_glyph_with_fallback (font, code);
if (grub_font_draw_glyph (glyph, color, x, baseline_y) != GRUB_ERR_NONE)
return grub_errno;
x += glyph->device_width;
}
return GRUB_ERR_NONE;
}

View file

@ -929,7 +929,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
"Warning : %s has no stat block !\n", "Warning : %s has no stat block !\n",
entry_name); entry_name);
grub_free (entry_item); grub_free (entry_item);
continue; goto next;
} }
} }
if (hook (entry_name, entry_type, entry_item)) if (hook (entry_name, entry_type, entry_item))
@ -940,6 +940,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
goto found; goto found;
} }
next:
*entry_name = 0; /* Make sure next entry name (which is just *entry_name = 0; /* Make sure next entry name (which is just
before this one in disk order) stops before before this one in disk order) stops before
the current one. */ the current one. */

View file

@ -228,7 +228,7 @@ VIDEOFILES += #{video}
#{fs}: #{src} $(#{src}_DEPENDENCIES) genfslist.sh #{fs}: #{src} $(#{src}_DEPENDENCIES) genfslist.sh
set -e; \ set -e; \
$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \ $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} -DGRUB_LST_GENERATOR $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
| sh $(srcdir)/genfslist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1) | sh $(srcdir)/genfslist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
#{parttool}: #{src} $(#{src}_DEPENDENCIES) genparttoollist.sh #{parttool}: #{src} $(#{src}_DEPENDENCIES) genparttoollist.sh
@ -238,7 +238,7 @@ VIDEOFILES += #{video}
#{partmap}: #{src} $(#{src}_DEPENDENCIES) genpartmaplist.sh #{partmap}: #{src} $(#{src}_DEPENDENCIES) genpartmaplist.sh
set -e; \ set -e; \
$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \ $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} -DGRUB_LST_GENERATOR $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
| sh $(srcdir)/genpartmaplist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1) | sh $(srcdir)/genpartmaplist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
#{handler}: #{src} $(#{src}_DEPENDENCIES) genhandlerlist.sh #{handler}: #{src} $(#{src}_DEPENDENCIES) genhandlerlist.sh
@ -253,7 +253,7 @@ VIDEOFILES += #{video}
#{video}: #{src} $(#{src}_DEPENDENCIES) genvideolist.sh #{video}: #{src} $(#{src}_DEPENDENCIES) genvideolist.sh
set -e; \ set -e; \
$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \ $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} -DGRUB_LST_GENERATOR $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
| sh $(srcdir)/genvideolist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1) | sh $(srcdir)/genvideolist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
" "

109
gfxmenu/font.c Normal file
View file

@ -0,0 +1,109 @@
/* font.c - Font API and font file loader. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,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/>.
*/
#include <grub/bufio.h>
#include <grub/dl.h>
#include <grub/file.h>
#include <grub/font.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/types.h>
#include <grub/video.h>
#include <grub/bitmap.h>
#include <grub/charset.h>
#include <grub/unicode.h>
#include <grub/fontformat.h>
#include <grub/gfxmenu_view.h>
/* Draw a UTF-8 string of text on the current video render target.
The x coordinate specifies the starting x position for the first character,
while the y coordinate specifies the baseline position.
If the string contains a character that FONT does not contain, then
a glyph from another loaded font may be used instead. */
grub_err_t
grub_font_draw_string (const char *str, grub_font_t font,
grub_video_color_t color,
int left_x, int baseline_y)
{
int x;
struct grub_font_glyph *glyph;
grub_uint32_t *logical;
grub_ssize_t logical_len, visual_len;
struct grub_unicode_glyph *visual, *ptr;
logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0);
if (logical_len < 0)
return grub_errno;
visual_len = grub_bidi_logical_to_visual (logical, logical_len, &visual,
0, 0, 0);
grub_free (logical);
if (visual_len < 0)
return grub_errno;
for (ptr = visual, x = left_x; ptr < visual + visual_len; ptr++)
{
grub_err_t err;
glyph = grub_font_construct_glyph (font, ptr);
if (!glyph)
return grub_errno;
err = grub_font_draw_glyph (glyph, color, x, baseline_y);
x += glyph->device_width;
grub_free (glyph);
if (err)
return err;
}
grub_free (visual);
return GRUB_ERR_NONE;
}
/* Get the width in pixels of the specified UTF-8 string, when rendered in
in the specified font (but falling back on other fonts for glyphs that
are missing). */
int
grub_font_get_string_width (grub_font_t font, const char *str)
{
int width = 0;
grub_uint32_t *ptr;
grub_ssize_t logical_len;
grub_uint32_t *logical;
logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0);
if (logical_len < 0)
{
grub_errno = GRUB_ERR_NONE;
return 0;
}
for (ptr = logical; ptr < logical + logical_len;)
{
struct grub_unicode_glyph glyph;
ptr += grub_unicode_aglomerate_comb (ptr,
logical_len - (ptr - logical),
&glyph);
width += grub_font_get_constructed_device_width (font, &glyph);
grub_free (glyph.combining);
}
return width;
}

View file

@ -210,7 +210,7 @@ draw_scrollbar (list_impl_t self,
/* Draw the list of items. */ /* Draw the list of items. */
static void static void
draw_menu (list_impl_t self, int width, int num_shown_items) draw_menu (list_impl_t self, int num_shown_items)
{ {
if (! self->menu_box || ! self->selected_item_box) if (! self->menu_box || ! self->selected_item_box)
return; return;
@ -227,10 +227,18 @@ draw_menu (list_impl_t self, int width, int num_shown_items)
grub_gfxmenu_box_t selbox = self->selected_item_box; grub_gfxmenu_box_t selbox = self->selected_item_box;
int sel_leftpad = selbox->get_left_pad (selbox); int sel_leftpad = selbox->get_left_pad (selbox);
int item_top = boxpad; int sel_toppad = selbox->get_top_pad (selbox);
int item_left = boxpad + sel_leftpad; int item_top = sel_toppad;
int menu_index; int menu_index;
int visible_index; int visible_index;
struct grub_video_rect oviewport;
grub_video_get_viewport (&oviewport.x, &oviewport.y,
&oviewport.width, &oviewport.height);
grub_video_set_viewport (oviewport.x + boxpad,
oviewport.y + boxpad,
oviewport.width - 2 * boxpad,
oviewport.height - 2 * boxpad);
for (visible_index = 0, menu_index = self->first_shown_index; for (visible_index = 0, menu_index = self->first_shown_index;
visible_index < num_shown_items && menu_index < self->view->menu->size; visible_index < num_shown_items && menu_index < self->view->menu->size;
@ -240,16 +248,16 @@ draw_menu (list_impl_t self, int width, int num_shown_items)
if (is_selected) if (is_selected)
{ {
int sel_toppad = selbox->get_top_pad (selbox); selbox->set_content_size (selbox, oviewport.width - 2 * boxpad - 2,
selbox->set_content_size (selbox, (width - 2 * boxpad), item_height); item_height - 1);
selbox->draw (selbox, item_left - sel_leftpad, selbox->draw (selbox, 0,
item_top - sel_toppad); item_top - sel_toppad);
} }
struct grub_video_bitmap *icon; struct grub_video_bitmap *icon;
if ((icon = get_item_icon (self, menu_index)) != 0) if ((icon = get_item_icon (self, menu_index)) != 0)
grub_video_blit_bitmap (icon, GRUB_VIDEO_BLIT_BLEND, grub_video_blit_bitmap (icon, GRUB_VIDEO_BLIT_BLEND,
item_left, sel_leftpad,
item_top + (item_height - self->icon_height) / 2, item_top + (item_height - self->icon_height) / 2,
0, 0, self->icon_width, self->icon_height); 0, 0, self->icon_width, self->icon_height);
@ -266,12 +274,16 @@ draw_menu (list_impl_t self, int width, int num_shown_items)
grub_font_draw_string (item_title, grub_font_draw_string (item_title,
font, font,
grub_gui_map_color (text_color), grub_gui_map_color (text_color),
item_left + self->icon_width + icon_text_space, sel_leftpad + self->icon_width + icon_text_space,
(item_top + (item_height - (ascent + descent)) (item_top + (item_height - (ascent + descent))
/ 2 + ascent)); / 2 + ascent));
item_top += item_height + item_vspace; item_top += item_height + item_vspace;
} }
grub_video_set_viewport (oviewport.x,
oviewport.y,
oviewport.width,
oviewport.height);
} }
static void static void
@ -313,7 +325,7 @@ list_paint (void *vself, const grub_video_rect_t *region)
box->draw (box, 0, 0); box->draw (box, 0, 0);
grub_gui_set_viewport (&content_rect, &vpsave2); grub_gui_set_viewport (&content_rect, &vpsave2);
draw_menu (self, content_rect.width, num_shown_items); draw_menu (self, num_shown_items);
grub_gui_restore_viewport (&vpsave2); grub_gui_restore_viewport (&vpsave2);
if (drawing_scrollbar) if (drawing_scrollbar)
@ -322,7 +334,7 @@ list_paint (void *vself, const grub_video_rect_t *region)
0, self->view->menu->size, 0, self->view->menu->size,
self->bounds.width - box_right_pad self->bounds.width - box_right_pad
+ self->scrollbar_width, + self->scrollbar_width,
box_top_pad + self->item_padding, box_top_pad,
self->bounds.height - box_top_pad - box_bottom_pad); self->bounds.height - box_top_pad - box_bottom_pad);
} }
@ -376,6 +388,9 @@ list_get_minimal_size (void *vself, unsigned *width, unsigned *height)
int box_bottom_pad = box->get_bottom_pad (box); int box_bottom_pad = box->get_bottom_pad (box);
unsigned width_s; unsigned width_s;
grub_gfxmenu_box_t selbox = self->selected_item_box;
int sel_toppad = selbox->get_top_pad (selbox);
*width = grub_font_get_string_width (self->item_font, "Typical OS"); *width = grub_font_get_string_width (self->item_font, "Typical OS");
width_s = grub_font_get_string_width (self->selected_item_font, width_s = grub_font_get_string_width (self->selected_item_font,
"Typical OS"); "Typical OS");
@ -388,7 +403,7 @@ list_get_minimal_size (void *vself, unsigned *width, unsigned *height)
*height = (item_height * num_items *height = (item_height * num_items
+ item_vspace * (num_items - 1) + item_vspace * (num_items - 1)
+ 2 * boxpad + 2 * boxpad
+ box_top_pad + box_bottom_pad); + box_top_pad + box_bottom_pad + sel_toppad);
} }
else else
{ {

View file

@ -32,6 +32,12 @@ typedef enum
GRUB_ATA_LBA48 GRUB_ATA_LBA48
} grub_ata_addressing_t; } grub_ata_addressing_t;
#define GRUB_ATA_CH0_PORT1 0x1f0
#define GRUB_ATA_CH1_PORT1 0x170
#define GRUB_ATA_CH0_PORT2 0x3f6
#define GRUB_ATA_CH1_PORT2 0x376
#define GRUB_ATA_REG_DATA 0 #define GRUB_ATA_REG_DATA 0
#define GRUB_ATA_REG_ERROR 1 #define GRUB_ATA_REG_ERROR 1
#define GRUB_ATA_REG_FEATURES 1 #define GRUB_ATA_REG_FEATURES 1

View file

@ -117,5 +117,11 @@ grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize);
int grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg, int grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
grub_uint32_t **last_position); grub_uint32_t **last_position);
void
grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size,
grub_uint8_t *dest, grub_size_t destsize);
grub_size_t grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
const grub_uint8_t *src, grub_size_t srcsize,
const grub_uint8_t **srcend);
#endif #endif

View file

@ -22,6 +22,7 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/video.h> #include <grub/video.h>
#include <grub/file.h> #include <grub/file.h>
#include <grub/unicode.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,
@ -69,6 +70,11 @@ struct grub_font_glyph
grub_uint8_t bitmap[0]; grub_uint8_t bitmap[0];
}; };
/* Part of code field which is really used as such. */
#define GRUB_FONT_CODE_CHAR_MASK 0x001fffff
#define GRUB_FONT_CODE_RIGHT_JOINED 0x80000000
#define GRUB_FONT_CODE_LEFT_JOINED 0x40000000
/* Initialize the font loader. /* Initialize the font loader.
Must be called before any fonts are loaded or used. */ Must be called before any fonts are loaded or used. */
void grub_font_loader_init (void); void grub_font_loader_init (void);
@ -97,8 +103,7 @@ int EXPORT_FUNC (grub_font_get_leading) (grub_font_t font);
int EXPORT_FUNC (grub_font_get_height) (grub_font_t font); int EXPORT_FUNC (grub_font_get_height) (grub_font_t font);
int EXPORT_FUNC (grub_font_get_string_width) (grub_font_t font, int EXPORT_FUNC (grub_font_get_xheight) (grub_font_t font);
const char *str);
struct grub_font_glyph *EXPORT_FUNC (grub_font_get_glyph) (grub_font_t font, struct grub_font_glyph *EXPORT_FUNC (grub_font_get_glyph) (grub_font_t font,
grub_uint32_t code); grub_uint32_t code);
@ -110,9 +115,11 @@ grub_err_t EXPORT_FUNC (grub_font_draw_glyph) (struct grub_font_glyph *glyph,
grub_video_color_t color, grub_video_color_t color,
int left_x, int baseline_y); int left_x, int baseline_y);
grub_err_t EXPORT_FUNC (grub_font_draw_string) (const char *str, int
grub_font_t font, EXPORT_FUNC (grub_font_get_constructed_device_width) (grub_font_t hinted_font,
grub_video_color_t color, const struct grub_unicode_glyph *glyph_id);
int left_x, int baseline_y); struct grub_font_glyph *
EXPORT_FUNC (grub_font_construct_glyph) (grub_font_t hinted_font,
const struct grub_unicode_glyph *glyph_id);
#endif /* ! GRUB_FONT_HEADER */ #endif /* ! GRUB_FONT_HEADER */

View file

@ -91,11 +91,13 @@ typedef int (*grub_fs_autoload_hook_t) (void);
extern grub_fs_autoload_hook_t EXPORT_VAR(grub_fs_autoload_hook); extern grub_fs_autoload_hook_t EXPORT_VAR(grub_fs_autoload_hook);
extern grub_fs_t EXPORT_VAR (grub_fs_list); extern grub_fs_t EXPORT_VAR (grub_fs_list);
#ifndef GRUB_LST_GENERATOR
static inline void static inline void
grub_fs_register (grub_fs_t fs) grub_fs_register (grub_fs_t fs)
{ {
grub_list_push (GRUB_AS_LIST_P (&grub_fs_list), GRUB_AS_LIST (fs)); grub_list_push (GRUB_AS_LIST_P (&grub_fs_list), GRUB_AS_LIST (fs));
} }
#endif
static inline void static inline void
grub_fs_unregister (grub_fs_t fs) grub_fs_unregister (grub_fs_t fs)

View file

@ -62,6 +62,14 @@ grub_gfxmenu_print_timeout (int timeout, void *data);
void void
grub_gfxmenu_set_chosen_entry (int entry, void *data); grub_gfxmenu_set_chosen_entry (int entry, void *data);
grub_err_t grub_font_draw_string (const char *str,
grub_font_t font,
grub_video_color_t color,
int left_x, int baseline_y);
int grub_font_get_string_width (grub_font_t font,
const char *str);
/* Implementation details -- this should not be used outside of the /* Implementation details -- this should not be used outside of the
view itself. */ view itself. */

View file

@ -40,12 +40,15 @@
#include <grub/i386/vga_common.h> #include <grub/i386/vga_common.h>
/* These are global to share code between C and asm. */ /* These are global to share code between C and asm. */
int grub_console_checkkey (void); int grub_console_checkkey (struct grub_term_input *term);
int grub_console_getkey (void); int grub_console_getkey (struct grub_term_input *term);
grub_uint16_t grub_console_getxy (void); grub_uint16_t grub_console_getxy (struct grub_term_output *term);
void grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y); void grub_console_gotoxy (struct grub_term_output *term,
void grub_console_cls (void); grub_uint8_t x, grub_uint8_t y);
void grub_console_setcursor (int on); void grub_console_cls (struct grub_term_output *term);
void grub_console_setcursor (struct grub_term_output *term, int on);
void grub_console_putchar (struct grub_term_output *term,
const struct grub_unicode_glyph *c);
/* Initialize the console system. */ /* Initialize the console system. */
void grub_console_init (void); void grub_console_init (void);

View file

@ -34,6 +34,8 @@ extern grub_int32_t grub_kernel_image_size;
/* The total size of module images following the kernel. */ /* The total size of module images following the kernel. */
extern grub_int32_t grub_total_module_size; extern grub_int32_t grub_total_module_size;
void grub_qemu_init_cirrus (void);
#endif /* ! ASM_FILE */ #endif /* ! ASM_FILE */
#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ #endif /* ! GRUB_KERNEL_MACHINE_HEADER */

View file

@ -25,16 +25,8 @@
extern grub_uint8_t grub_console_cur_color; extern grub_uint8_t grub_console_cur_color;
void grub_console_putchar (grub_uint32_t c); grub_uint16_t grub_console_getwh (struct grub_term_output *term);
grub_ssize_t grub_console_getcharwidth (grub_uint32_t c); void grub_console_setcolorstate (struct grub_term_output *term,
grub_uint16_t grub_console_getwh (void); grub_term_color_state state);
void grub_console_setcolorstate (grub_term_color_state state);
void grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color);
void grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color);
/* Implemented in both kern/i386/pc/startup.S and vga_text.c; this symbol
is not exported, so there's no collision, but vga_common.c expects this
prototype to be the same. */
void grub_console_real_putchar (int c);
#endif /* ! GRUB_VGA_COMMON_CPU_HEADER */ #endif /* ! GRUB_VGA_COMMON_CPU_HEADER */

View file

@ -114,8 +114,6 @@ extern grub_uint32_t grub_xnu_stack;
extern grub_uint32_t grub_xnu_arg1; extern grub_uint32_t grub_xnu_arg1;
extern char grub_xnu_cmdline[1024]; extern char grub_xnu_cmdline[1024];
grub_err_t grub_xnu_boot (void); grub_err_t grub_xnu_boot (void);
grub_err_t grub_xnu_set_video (struct grub_xnu_boot_params *bootparams_relloc); grub_err_t grub_cpu_xnu_fill_devicetree (void);
grub_err_t
grub_cpu_xnu_fill_devicetree (void);
extern grub_uint32_t grub_xnu_heap_will_be_at; extern grub_uint32_t grub_xnu_heap_will_be_at;
#endif #endif

View file

@ -22,7 +22,8 @@
#include <grub/symbol.h> #include <grub/symbol.h>
/* Initialize the console system. */ /* Initialize the console system. */
void grub_console_init (void); void grub_console_init_early (void);
void grub_console_init_lately (void);
/* Finish the console system. */ /* Finish the console system. */
void grub_console_fini (void); void grub_console_fini (void);

View file

@ -0,0 +1,90 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/>.
*/
#ifndef GRUB_LOONGSON_CPU_HEADER
#define GRUB_LOONGSON_CPU_HEADER 1
#ifdef ASM_FILE
#define GRUB_CPU_REGISTER_WRAP(x) x
#else
#define GRUB_CPU_REGISTER_WRAP(x) #x
#endif
#define GRUB_CPU_LOONGSON_FLASH_START 0xbfc00000
#define GRUB_CPU_LOONGSON_FLASH_TLB_REFILL 0xbfc00200
#define GRUB_CPU_LOONGSON_FLASH_CACHE_ERROR 0xbfc00300
#define GRUB_CPU_LOONGSON_FLASH_OTHER_EXCEPTION 0xbfc00380
#define GRUB_CPU_LOONGSON_DDR2_BASE 0xaffffe00
#define GRUB_CPU_LOONGSON_DDR2_REG1_HI_8BANKS 0x00000001
#define GRUB_CPU_LOONGSON_DDR2_REG_SIZE 0x8
#define GRUB_CPU_LOONGSON_DDR2_REG_STEP 0x10
#define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG GRUB_CPU_REGISTER_WRAP($16)
#define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_ILINESIZE 0x10
#define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_DLINESIZE 0x8
#define GRUB_CPU_LOONGSON_COP0_CACHE_DSIZE_SHIFT 6
#define GRUB_CPU_LOONGSON_COP0_CACHE_ISIZE_SHIFT 9
#define GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK 0x7
#define GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET 12
#define GRUB_CPU_LOONGSON_COP0_I_INDEX_INVALIDATE 0
#define GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE 9
#define GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE 11
#define GRUB_CPU_LOONGSON_COP0_I_INDEX_BIT_OFFSET 5
#define GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET 5
#define GRUB_CPU_LOONGSON_COP0_S_INDEX_BIT_OFFSET 5
#define GRUB_CPU_LOONGSON_CACHE_ACCELERATED 7
#define GRUB_CPU_LOONGSON_CACHE_UNCACHED 2
#define GRUB_CPU_LOONGSON_CACHE_CACHED 3
#define GRUB_CPU_LOONGSON_CACHE_TYPE_MASK 7
#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_SMALL 4
#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG 5
#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_SMALL 16
#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_BIG 32
#define GRUB_CPU_LOONGSON_I_CACHE_LOG_WAYS 2
#define GRUB_CPU_LOONGSON_D_CACHE_LOG_WAYS 2
#define GRUB_CPU_LOONGSON_S_CACHE_LOG_WAYS 2
/* FIXME: determine dynamically. */
#define GRUB_CPU_LOONGSON_SECONDARY_CACHE_LOG_SIZE 19
#define GRUB_CPU_LOONGSON_COP0_BADVADDR GRUB_CPU_REGISTER_WRAP($8)
#define GRUB_CPU_LOONGSON_COP0_TIMER_COUNT GRUB_CPU_REGISTER_WRAP($9)
#define GRUB_CPU_LOONGSON_COP0_CAUSE GRUB_CPU_REGISTER_WRAP($13)
#define GRUB_CPU_LOONGSON_COP0_EPC GRUB_CPU_REGISTER_WRAP($14)
#define GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO GRUB_CPU_REGISTER_WRAP($28)
#define GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI GRUB_CPU_REGISTER_WRAP($29)
#define GRUB_CPU_LOONGSON_LIOCFG 0xbfe00108
#define GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET 2
#define GRUB_CPU_LOONGSON_ROM_DELAY_MASK 0x1f
#define GRUB_CPU_LOONGSON_CORECFG 0xbfe00180
#define GRUB_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE 0x100
#define GRUB_CPU_LOONGSON_CORECFG_BUFFER_CPU 0x200
#define GRUB_CPU_LOONGSON_PCI_HIT1_SEL_LO 0xbfe00150
#define GRUB_CPU_LOONGSON_PCI_HIT1_SEL_HI 0xbfe00154
#define GRUB_CPU_LOONGSON_GPIOCFG 0xbfe00120
#define GRUB_CPU_LOONGSON_SHUTDOWN_GPIO 1
#endif

View file

@ -0,0 +1,41 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/>.
*/
#ifndef GRUB_EC_MACHINE_HEADER
#define GRUB_EC_MACHINE_HEADER 1
#define GRUB_MACHINE_EC_MAGIC_PORT1 0x381
#define GRUB_MACHINE_EC_MAGIC_PORT2 0x382
#define GRUB_MACHINE_EC_DATA_PORT 0x383
#define GRUB_MACHINE_EC_MAGIC_VAL1 0xf4
#define GRUB_MACHINE_EC_MAGIC_VAL2 0xec
#define GRUB_MACHINE_EC_COMMAND_REBOOT 1
static inline void
grub_write_ec (grub_uint8_t value)
{
grub_outb (GRUB_MACHINE_EC_MAGIC_VAL1,
GRUB_MACHINE_PCI_IO_BASE + GRUB_MACHINE_EC_MAGIC_PORT1);
grub_outb (GRUB_MACHINE_EC_MAGIC_VAL2,
GRUB_MACHINE_PCI_IO_BASE + GRUB_MACHINE_EC_MAGIC_PORT2);
grub_outb (value, GRUB_MACHINE_PCI_IO_BASE + GRUB_MACHINE_EC_DATA_PORT);
}
#endif

View file

@ -19,6 +19,12 @@
#ifndef GRUB_MACHINE_SERIAL_HEADER #ifndef GRUB_MACHINE_SERIAL_HEADER
#define GRUB_MACHINE_SERIAL_HEADER 1 #define GRUB_MACHINE_SERIAL_HEADER 1
#define GRUB_MACHINE_SERIAL_PORTS { 0xbff003f8 } #define GRUB_MACHINE_SERIAL_DIVISOR_115200 2
#define GRUB_MACHINE_SERIAL_PORT 0xbff003f8
#ifndef ASM_FILE
#define GRUB_MACHINE_SERIAL_PORTS { GRUB_MACHINE_SERIAL_PORT }
#else
#endif
#endif #endif

View file

@ -237,7 +237,19 @@ void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n);
grub_size_t EXPORT_FUNC(grub_strlen) (const char *s); grub_size_t EXPORT_FUNC(grub_strlen) (const char *s);
int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
int EXPORT_FUNC(grub_puts) (const char *s);
extern void (*EXPORT_VAR (grub_xputs)) (const char *str);
static inline int
grub_puts (const char *s)
{
const char nl[2] = "\n";
grub_xputs (s);
grub_xputs (nl);
return 1; /* Cannot fail. */
}
int EXPORT_FUNC(grub_puts_) (const char *s); int EXPORT_FUNC(grub_puts_) (const char *s);
void EXPORT_FUNC(grub_real_dprintf) (const char *file, void EXPORT_FUNC(grub_real_dprintf) (const char *file,
const int line, const int line,
@ -253,11 +265,6 @@ char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...)
char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args); char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args);
void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn)); void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn));
void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn)); void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn));
grub_size_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest,
grub_size_t destsize,
const grub_uint8_t *src,
grub_size_t srcsize,
const grub_uint8_t **srcend);
grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
grub_uint32_t d, grub_uint32_t *r); grub_uint32_t d, grub_uint32_t *r);
@ -307,14 +314,14 @@ grub_div_roundup (unsigned int x, unsigned int y)
} }
/* Reboot the machine. */ /* Reboot the machine. */
void EXPORT_FUNC (grub_reboot) (void); void EXPORT_FUNC (grub_reboot) (void) __attribute__ ((noreturn));
#ifdef GRUB_MACHINE_PCBIOS #ifdef GRUB_MACHINE_PCBIOS
/* Halt the system, using APM if possible. If NO_APM is true, don't /* Halt the system, using APM if possible. If NO_APM is true, don't
* use APM even if it is available. */ * use APM even if it is available. */
void EXPORT_FUNC (grub_halt) (int no_apm); void EXPORT_FUNC (grub_halt) (int no_apm) __attribute__ ((noreturn));
#else #else
void EXPORT_FUNC (grub_halt) (void); void EXPORT_FUNC (grub_halt) (void) __attribute__ ((noreturn));
#endif #endif
#endif /* ! GRUB_MISC_HEADER */ #endif /* ! GRUB_MISC_HEADER */

View file

@ -77,8 +77,10 @@ void grub_parse_color_name_pair (grub_uint8_t *ret, const char *name);
/* Defined in `menu_text.c'. */ /* Defined in `menu_text.c'. */
void grub_wait_after_message (void); void grub_wait_after_message (void);
void grub_print_ucs4 (const grub_uint32_t * str, void
grub_print_ucs4 (const grub_uint32_t * str,
const grub_uint32_t * last_position, const grub_uint32_t * last_position,
int margin_left, int margin_right,
struct grub_term_output *term); struct grub_term_output *term);
grub_ssize_t grub_getstringwidth (grub_uint32_t * str, grub_ssize_t grub_getstringwidth (grub_uint32_t * str,
const grub_uint32_t * last_position, const grub_uint32_t * last_position,
@ -110,7 +112,9 @@ void read_terminal_list (const char *prefix);
void grub_set_more (int onoff); void grub_set_more (int onoff);
int grub_normal_get_line_counter (void); int grub_normal_get_char_counter (void);
void grub_install_newline_hook (void); void grub_normal_reset_more (void);
void grub_xputs_normal (const char *str);
#endif /* ! GRUB_NORMAL_HEADER */ #endif /* ! GRUB_NORMAL_HEADER */

View file

@ -83,7 +83,7 @@ struct grub_parser
}; };
typedef struct grub_parser *grub_parser_t; typedef struct grub_parser *grub_parser_t;
grub_err_t EXPORT_FUNC(grub_parser_execute) (char *source); grub_err_t grub_parser_execute (char *source);
grub_err_t grub_err_t
grub_rescue_parse_line (char *line, grub_reader_getline_t getline); grub_rescue_parse_line (char *line, grub_reader_getline_t getline);

View file

@ -77,12 +77,14 @@ char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition);
extern grub_partition_map_t EXPORT_VAR(grub_partition_map_list); extern grub_partition_map_t EXPORT_VAR(grub_partition_map_list);
#ifndef GRUB_LST_GENERATOR
static inline void static inline void
grub_partition_map_register (grub_partition_map_t partmap) grub_partition_map_register (grub_partition_map_t partmap)
{ {
grub_list_push (GRUB_AS_LIST_P (&grub_partition_map_list), grub_list_push (GRUB_AS_LIST_P (&grub_partition_map_list),
GRUB_AS_LIST (partmap)); GRUB_AS_LIST (partmap));
} }
#endif
static inline void static inline void
grub_partition_map_unregister (grub_partition_map_t partmap) grub_partition_map_unregister (grub_partition_map_t partmap)

View file

@ -1,28 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,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 GRUB_CONSOLE_MACHINE_HEADER
#define GRUB_CONSOLE_MACHINE_HEADER 1
/* Initialize the console system. */
void grub_console_init (void);
/* Finish the console system. */
void grub_console_fini (void);
#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */

View file

@ -26,16 +26,35 @@ void grub_scsi_dev_unregister (grub_scsi_dev_t dev);
struct grub_scsi; struct grub_scsi;
enum
{
GRUB_SCSI_SUBSYSTEM_USBMS,
GRUB_SCSI_SUBSYSTEM_ATAPI
};
#define GRUB_SCSI_ID_SUBSYSTEM_SHIFT 24
#define GRUB_SCSI_ID_BUS_SHIFT 8
#define GRUB_SCSI_ID_LUN_SHIFT 0
static inline grub_uint32_t
grub_make_scsi_id (int subsystem, int bus, int lun)
{
return (subsystem << GRUB_SCSI_ID_SUBSYSTEM_SHIFT)
| (bus << GRUB_SCSI_ID_BUS_SHIFT) | (lun << GRUB_SCSI_ID_BUS_SHIFT);
}
struct grub_scsi_dev struct grub_scsi_dev
{ {
/* The device name. */ /* The device name. */
const char *name; const char *name;
grub_uint8_t id;
/* Call HOOK with each device name, until HOOK returns non-zero. */ /* Call HOOK with each device name, until HOOK returns non-zero. */
int (*iterate) (int (*hook) (const char *name, int luns)); int (*iterate) (int (*hook) (int bus, int luns));
/* Open the device named NAME, and set up SCSI. */ /* Open the device named NAME, and set up SCSI. */
grub_err_t (*open) (const char *name, struct grub_scsi *scsi); grub_err_t (*open) (int bus, struct grub_scsi *scsi);
/* Close the scsi device SCSI. */ /* Close the scsi device SCSI. */
void (*close) (struct grub_scsi *scsi); void (*close) (struct grub_scsi *scsi);
@ -56,15 +75,14 @@ struct grub_scsi_dev
struct grub_scsi struct grub_scsi
{ {
/* The scsi device name. */
char *name;
/* The underlying scsi device. */ /* The underlying scsi device. */
grub_scsi_dev_t dev; grub_scsi_dev_t dev;
/* Type of SCSI device. XXX: Make enum. */ /* Type of SCSI device. XXX: Make enum. */
grub_uint8_t devtype; grub_uint8_t devtype;
int bus;
/* Number of LUNs. */ /* Number of LUNs. */
int luns; int luns;

View file

@ -59,9 +59,15 @@
#define UART_DLAB 0x80 #define UART_DLAB 0x80
/* Enable the FIFO. */ /* Enable the FIFO. */
#define UART_ENABLE_FIFO 0xC7 #define UART_ENABLE_FIFO_TRIGGER14 0xC7
/* Enable the FIFO. */
#define UART_ENABLE_FIFO_TRIGGER1 0x07
/* Turn on DTR, RTS, and OUT2. */ /* Turn on DTR, RTS, and OUT2. */
#define UART_ENABLE_MODEM 0x0B #define UART_ENABLE_DTRRTS 0x03
/* Turn on DTR, RTS, and OUT2. */
#define UART_ENABLE_OUT2 0x08
#endif /* ! GRUB_SERIAL_MACHINE_HEADER */ #endif /* ! GRUB_SERIAL_MACHINE_HEADER */

View file

@ -1,28 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,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 GRUB_CONSOLE_MACHINE_HEADER
#define GRUB_CONSOLE_MACHINE_HEADER 1
/* Initialize the console system. */
void grub_console_init (void);
/* Finish the console system. */
void grub_console_fini (void);
#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */

View file

@ -38,6 +38,7 @@
#include <grub/err.h> #include <grub/err.h>
#include <grub/symbol.h> #include <grub/symbol.h>
#include <grub/types.h> #include <grub/types.h>
#include <grub/unicode.h>
#include <grub/list.h> #include <grub/list.h>
/* These are used to represent the various color states we use. */ /* These are used to represent the various color states we use. */
@ -68,6 +69,20 @@ grub_term_color_state;
#define GRUB_TERM_NO_EDIT (1 << 1) #define GRUB_TERM_NO_EDIT (1 << 1)
/* Set when the terminal cannot do fancy things. */ /* Set when the terminal cannot do fancy things. */
#define GRUB_TERM_DUMB (1 << 2) #define GRUB_TERM_DUMB (1 << 2)
/* Which encoding does terminal expect stream to be. */
#define GRUB_TERM_CODE_TYPE_SHIFT 3
#define GRUB_TERM_CODE_TYPE_MASK (7 << GRUB_TERM_CODE_TYPE_SHIFT)
/* Only ASCII characters accepted. */
#define GRUB_TERM_CODE_TYPE_ASCII (0 << GRUB_TERM_CODE_TYPE_SHIFT)
/* Expects CP-437 characters (ASCII + pseudographics). */
#define GRUB_TERM_CODE_TYPE_CP437 (1 << GRUB_TERM_CODE_TYPE_SHIFT)
/* UTF-8 stream in logical order. Usually used for terminals
which just forward the stream to another computer. */
#define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (2 << GRUB_TERM_CODE_TYPE_SHIFT)
/* UTF-8 in visual order. Like UTF-8 logical but for buggy endpoints. */
#define GRUB_TERM_CODE_TYPE_UTF8_VISUAL (3 << GRUB_TERM_CODE_TYPE_SHIFT)
/* Glyph description in visual order. */
#define GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS (4 << GRUB_TERM_CODE_TYPE_SHIFT)
/* Bitmasks for modifier keys returned by grub_getkeystatus. */ /* Bitmasks for modifier keys returned by grub_getkeystatus. */
@ -75,20 +90,6 @@ grub_term_color_state;
#define GRUB_TERM_STATUS_CTRL (1 << 1) #define GRUB_TERM_STATUS_CTRL (1 << 1)
#define GRUB_TERM_STATUS_ALT (1 << 2) #define GRUB_TERM_STATUS_ALT (1 << 2)
/* Unicode characters for fancy graphics. */
#define GRUB_TERM_DISP_LEFT 0x2190
#define GRUB_TERM_DISP_UP 0x2191
#define GRUB_TERM_DISP_RIGHT 0x2192
#define GRUB_TERM_DISP_DOWN 0x2193
#define GRUB_TERM_DISP_HLINE 0x2501
#define GRUB_TERM_DISP_VLINE 0x2503
#define GRUB_TERM_DISP_UL 0x250F
#define GRUB_TERM_DISP_UR 0x2513
#define GRUB_TERM_DISP_LL 0x2517
#define GRUB_TERM_DISP_LR 0x251B
/* Menu-related geometrical constants. */ /* Menu-related geometrical constants. */
/* The number of lines of "GRUB version..." at the top. */ /* The number of lines of "GRUB version..." at the top. */
@ -122,19 +123,21 @@ struct grub_term_input
const char *name; const char *name;
/* Initialize the terminal. */ /* Initialize the terminal. */
grub_err_t (*init) (void); grub_err_t (*init) (struct grub_term_input *term);
/* Clean up the terminal. */ /* Clean up the terminal. */
grub_err_t (*fini) (void); grub_err_t (*fini) (struct grub_term_input *term);
/* Check if any input character is available. */ /* Check if any input character is available. */
int (*checkkey) (void); int (*checkkey) (struct grub_term_input *term);
/* Get a character. */ /* Get a character. */
int (*getkey) (void); int (*getkey) (struct grub_term_input *term);
/* Get keyboard modifier status. */ /* Get keyboard modifier status. */
int (*getkeystatus) (void); int (*getkeystatus) (struct grub_term_input *term);
void *data;
}; };
typedef struct grub_term_input *grub_term_input_t; typedef struct grub_term_input *grub_term_input_t;
@ -147,52 +150,58 @@ struct grub_term_output
const char *name; const char *name;
/* Initialize the terminal. */ /* Initialize the terminal. */
grub_err_t (*init) (void); grub_err_t (*init) (struct grub_term_output *term);
/* Clean up the terminal. */ /* Clean up the terminal. */
grub_err_t (*fini) (void); grub_err_t (*fini) (struct grub_term_output *term);
/* Put a character. C is encoded in Unicode. */ /* Put a character. C is encoded in Unicode. */
void (*putchar) (grub_uint32_t c); void (*putchar) (struct grub_term_output *term,
const struct grub_unicode_glyph *c);
/* Get the number of columns occupied by a given character C. C is /* Get the number of columns occupied by a given character C. C is
encoded in Unicode. */ encoded in Unicode. */
grub_ssize_t (*getcharwidth) (grub_uint32_t c); grub_ssize_t (*getcharwidth) (struct grub_term_output *term,
const struct grub_unicode_glyph *c);
/* Get the screen size. The return value is ((Width << 8) | Height). */ /* Get the screen size. The return value is ((Width << 8) | Height). */
grub_uint16_t (*getwh) (void); grub_uint16_t (*getwh) (struct grub_term_output *term);
/* Get the cursor position. The return value is ((X << 8) | Y). */ /* Get the cursor position. The return value is ((X << 8) | Y). */
grub_uint16_t (*getxy) (void); grub_uint16_t (*getxy) (struct grub_term_output *term);
/* Go to the position (X, Y). */ /* Go to the position (X, Y). */
void (*gotoxy) (grub_uint8_t x, grub_uint8_t y); void (*gotoxy) (struct grub_term_output *term,
grub_uint8_t x, grub_uint8_t y);
/* Clear the screen. */ /* Clear the screen. */
void (*cls) (void); void (*cls) (struct grub_term_output *term);
/* Set the current color to be used */ /* Set the current color to be used */
void (*setcolorstate) (grub_term_color_state state); void (*setcolorstate) (struct grub_term_output *term,
grub_term_color_state state);
/* Set the normal color and the highlight color. The format of each
color is VGA's. */
void (*setcolor) (grub_uint8_t normal_color, grub_uint8_t highlight_color);
/* Get the normal color and the highlight color. The format of each
color is VGA's. */
void (*getcolor) (grub_uint8_t *normal_color, grub_uint8_t *highlight_color);
/* Turn on/off the cursor. */ /* Turn on/off the cursor. */
void (*setcursor) (int on); void (*setcursor) (struct grub_term_output *term, int on);
/* Update the screen. */ /* Update the screen. */
void (*refresh) (void); void (*refresh) (struct grub_term_output *term);
/* The feature flags defined above. */ /* The feature flags defined above. */
grub_uint32_t flags; grub_uint32_t flags;
/* Current color state. */
grub_uint8_t normal_color;
grub_uint8_t highlight_color;
void *data;
}; };
typedef struct grub_term_output *grub_term_output_t; typedef struct grub_term_output *grub_term_output_t;
#define GRUB_TERM_DEFAULT_NORMAL_COLOR 0x07
#define GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR 0x70
#define GRUB_TERM_DEFAULT_STANDARD_COLOR 0x07
extern struct grub_term_output *EXPORT_VAR(grub_term_outputs_disabled); extern struct grub_term_output *EXPORT_VAR(grub_term_outputs_disabled);
extern struct grub_term_input *EXPORT_VAR(grub_term_inputs_disabled); extern struct grub_term_input *EXPORT_VAR(grub_term_inputs_disabled);
extern struct grub_term_output *EXPORT_VAR(grub_term_outputs); extern struct grub_term_output *EXPORT_VAR(grub_term_outputs);
@ -208,11 +217,19 @@ grub_term_register_input (const char *name __attribute__ ((unused)),
else else
{ {
/* If this is the first terminal, enable automatically. */ /* If this is the first terminal, enable automatically. */
if (! term->init || term->init () == GRUB_ERR_NONE) if (! term->init || term->init (term) == GRUB_ERR_NONE)
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term)); grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term));
} }
} }
static inline void
grub_term_register_input_active (const char *name __attribute__ ((unused)),
grub_term_input_t term)
{
if (! term->init || term->init (term) == GRUB_ERR_NONE)
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term));
}
static inline void static inline void
grub_term_register_output (const char *name __attribute__ ((unused)), grub_term_register_output (const char *name __attribute__ ((unused)),
grub_term_output_t term) grub_term_output_t term)
@ -223,12 +240,21 @@ grub_term_register_output (const char *name __attribute__ ((unused)),
else else
{ {
/* If this is the first terminal, enable automatically. */ /* If this is the first terminal, enable automatically. */
if (! term->init || term->init () == GRUB_ERR_NONE) if (! term->init || term->init (term) == GRUB_ERR_NONE)
grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
GRUB_AS_LIST (term)); GRUB_AS_LIST (term));
} }
} }
static inline void
grub_term_register_output_active (const char *name __attribute__ ((unused)),
grub_term_output_t term)
{
if (! term->init || term->init (term) == GRUB_ERR_NONE)
grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
GRUB_AS_LIST (term));
}
static inline void static inline void
grub_term_unregister_input (grub_term_input_t term) grub_term_unregister_input (grub_term_input_t term)
{ {
@ -250,14 +276,11 @@ grub_term_unregister_output (grub_term_output_t term)
#define FOR_ACTIVE_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs)) #define FOR_ACTIVE_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs))
#define FOR_DISABLED_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs_disabled)) #define FOR_DISABLED_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs_disabled))
void EXPORT_FUNC(grub_putchar) (int c); void grub_putcode (grub_uint32_t code, struct grub_term_output *term);
void EXPORT_FUNC(grub_putcode) (grub_uint32_t code,
struct grub_term_output *term);
int EXPORT_FUNC(grub_getkey) (void); int EXPORT_FUNC(grub_getkey) (void);
int EXPORT_FUNC(grub_checkkey) (void); int EXPORT_FUNC(grub_checkkey) (void);
int EXPORT_FUNC(grub_getkeystatus) (void); int EXPORT_FUNC(grub_getkeystatus) (void);
void EXPORT_FUNC(grub_cls) (void); void grub_cls (void);
void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state);
void EXPORT_FUNC(grub_refresh) (void); void EXPORT_FUNC(grub_refresh) (void);
void grub_puts_terminal (const char *str, struct grub_term_output *term); void grub_puts_terminal (const char *str, struct grub_term_output *term);
grub_uint16_t *grub_term_save_pos (void); grub_uint16_t *grub_term_save_pos (void);
@ -265,12 +288,12 @@ void grub_term_restore_pos (grub_uint16_t *pos);
static inline unsigned grub_term_width (struct grub_term_output *term) static inline unsigned grub_term_width (struct grub_term_output *term)
{ {
return ((term->getwh()&0xFF00)>>8); return ((term->getwh(term)&0xFF00)>>8);
} }
static inline unsigned grub_term_height (struct grub_term_output *term) static inline unsigned grub_term_height (struct grub_term_output *term)
{ {
return (term->getwh()&0xFF); return (term->getwh(term)&0xFF);
} }
/* The width of the border. */ /* The width of the border. */
@ -314,20 +337,20 @@ grub_term_cursor_x (struct grub_term_output *term)
static inline grub_uint16_t static inline grub_uint16_t
grub_term_getxy (struct grub_term_output *term) grub_term_getxy (struct grub_term_output *term)
{ {
return term->getxy (); return term->getxy (term);
} }
static inline void static inline void
grub_term_refresh (struct grub_term_output *term) grub_term_refresh (struct grub_term_output *term)
{ {
if (term->refresh) if (term->refresh)
term->refresh (); term->refresh (term);
} }
static inline void static inline void
grub_term_gotoxy (struct grub_term_output *term, grub_uint8_t x, grub_uint8_t y) grub_term_gotoxy (struct grub_term_output *term, grub_uint8_t x, grub_uint8_t y)
{ {
term->gotoxy (x, y); term->gotoxy (term, x, y);
} }
static inline void static inline void
@ -335,17 +358,26 @@ grub_term_setcolorstate (struct grub_term_output *term,
grub_term_color_state state) grub_term_color_state state)
{ {
if (term->setcolorstate) if (term->setcolorstate)
term->setcolorstate (state); term->setcolorstate (term, state);
} }
/* Set the normal color and the highlight color. The format of each static inline void
grub_setcolorstate (grub_term_color_state state)
{
struct grub_term_output *term;
FOR_ACTIVE_TERM_OUTPUTS(term)
grub_term_setcolorstate (term, state);
}
/* Set the normal color and the highlight color. The format of each
color is VGA's. */ color is VGA's. */
static inline void static inline void
grub_term_setcolor (struct grub_term_output *term, grub_term_setcolor (struct grub_term_output *term,
grub_uint8_t normal_color, grub_uint8_t highlight_color) grub_uint8_t normal_color, grub_uint8_t highlight_color)
{ {
if (term->setcolor) term->normal_color = normal_color;
term->setcolor (normal_color, highlight_color); term->highlight_color = highlight_color;
} }
/* Turn on/off the cursor. */ /* Turn on/off the cursor. */
@ -353,14 +385,14 @@ static inline void
grub_term_setcursor (struct grub_term_output *term, int on) grub_term_setcursor (struct grub_term_output *term, int on)
{ {
if (term->setcursor) if (term->setcursor)
term->setcursor (on); term->setcursor (term, on);
} }
static inline void static inline void
grub_term_cls (struct grub_term_output *term) grub_term_cls (struct grub_term_output *term)
{ {
if (term->cls) if (term->cls)
(term->cls) (); (term->cls) (term);
else else
{ {
grub_putcode ('\n', term); grub_putcode ('\n', term);
@ -368,11 +400,36 @@ grub_term_cls (struct grub_term_output *term)
} }
} }
#ifdef HAVE_UNIFONT_WIDTHSPEC
grub_ssize_t
grub_unicode_estimate_width (const struct grub_unicode_glyph *c);
#else
static inline grub_ssize_t static inline grub_ssize_t
grub_term_getcharwidth (struct grub_term_output *term, grub_uint32_t c) grub_unicode_estimate_width (const struct grub_unicode_glyph *c __attribute__ ((unused)))
{
if (grub_unicode_get_comb_type (c->base))
return 0;
return 1;
}
#endif
static inline grub_ssize_t
grub_term_getcharwidth (struct grub_term_output *term,
const struct grub_unicode_glyph *c)
{ {
if (term->getcharwidth) if (term->getcharwidth)
return term->getcharwidth (c); return term->getcharwidth (term, c);
else if (((term->flags & GRUB_TERM_CODE_TYPE_MASK)
== GRUB_TERM_CODE_TYPE_UTF8_LOGICAL)
|| ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
== GRUB_TERM_CODE_TYPE_UTF8_VISUAL)
|| ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
== GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS))
return grub_unicode_estimate_width (c);
else else
return 1; return 1;
} }
@ -381,17 +438,10 @@ static inline void
grub_term_getcolor (struct grub_term_output *term, grub_term_getcolor (struct grub_term_output *term,
grub_uint8_t *normal_color, grub_uint8_t *highlight_color) grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
{ {
if (term->getcolor) *normal_color = term->normal_color;
term->getcolor (normal_color, highlight_color); *highlight_color = term->highlight_color;
else
{
*normal_color = 0x07;
*highlight_color = 0x07;
}
} }
extern void (*EXPORT_VAR (grub_newline_hook)) (void);
struct grub_term_autoload struct grub_term_autoload
{ {
struct grub_term_autoload *next; struct grub_term_autoload *next;

View file

@ -23,15 +23,55 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/term.h> #include <grub/term.h>
char *grub_terminfo_get_current (void); char *EXPORT_FUNC(grub_terminfo_get_current) (struct grub_term_output *term);
grub_err_t grub_terminfo_set_current (const char *); grub_err_t EXPORT_FUNC(grub_terminfo_set_current) (struct grub_term_output *term,
const char *);
void grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y, #define GRUB_TERMINFO_READKEY_MAX_LEN 4
grub_term_output_t oterm); struct grub_terminfo_input_state
void grub_terminfo_cls (grub_term_output_t oterm); {
void grub_terminfo_reverse_video_on (grub_term_output_t oterm); int input_buf[GRUB_TERMINFO_READKEY_MAX_LEN];
void grub_terminfo_reverse_video_off (grub_term_output_t oterm); int npending;
void grub_terminfo_cursor_on (grub_term_output_t oterm); int (*readkey) (void);
void grub_terminfo_cursor_off (grub_term_output_t oterm); };
struct grub_terminfo_output_state
{
struct grub_term_output *next;
char *name;
char *gotoxy;
char *cls;
char *reverse_video_on;
char *reverse_video_off;
char *cursor_on;
char *cursor_off;
char *setcolor;
unsigned int xpos, ypos;
void (*put) (const int c);
};
void EXPORT_FUNC(grub_terminfo_gotoxy) (grub_term_output_t term,
grub_uint8_t x, grub_uint8_t y);
void EXPORT_FUNC(grub_terminfo_cls) (grub_term_output_t term);
grub_uint16_t EXPORT_FUNC (grub_terminfo_getxy) (struct grub_term_output *term);
void EXPORT_FUNC (grub_terminfo_setcursor) (struct grub_term_output *term,
const int on);
void EXPORT_FUNC (grub_terminfo_setcolorstate) (struct grub_term_output *term,
const grub_term_color_state state);
int EXPORT_FUNC (grub_terminfo_checkkey) (struct grub_term_input *term);
grub_err_t EXPORT_FUNC (grub_terminfo_input_init) (struct grub_term_input *term);
int EXPORT_FUNC (grub_terminfo_getkey) (struct grub_term_input *term);
void EXPORT_FUNC (grub_terminfo_putchar) (struct grub_term_output *term,
const struct grub_unicode_glyph *c);
grub_err_t EXPORT_FUNC (grub_terminfo_output_register) (struct grub_term_output *term,
const char *type);
grub_err_t EXPORT_FUNC (grub_terminfo_output_unregister) (struct grub_term_output *term);
#endif /* ! GRUB_TERMINFO_HEADER */ #endif /* ! GRUB_TERMINFO_HEADER */

View file

@ -60,7 +60,7 @@
typedef signed char grub_int8_t; typedef signed char grub_int8_t;
typedef short grub_int16_t; typedef short grub_int16_t;
typedef int grub_int32_t; typedef int grub_int32_t;
#if GRUB_CPU_SIZEOF_VOID_P == 8 #if GRUB_CPU_SIZEOF_LONG == 8
typedef long grub_int64_t; typedef long grub_int64_t;
#else #else
typedef long long grub_int64_t; typedef long long grub_int64_t;
@ -69,7 +69,7 @@ typedef long long grub_int64_t;
typedef unsigned char grub_uint8_t; typedef unsigned char grub_uint8_t;
typedef unsigned short grub_uint16_t; typedef unsigned short grub_uint16_t;
typedef unsigned grub_uint32_t; typedef unsigned grub_uint32_t;
#if GRUB_CPU_SIZEOF_VOID_P == 8 #if GRUB_CPU_SIZEOF_LONG == 8
typedef unsigned long grub_uint64_t; typedef unsigned long grub_uint64_t;
#else #else
typedef unsigned long long grub_uint64_t; typedef unsigned long long grub_uint64_t;
@ -92,13 +92,21 @@ typedef grub_int32_t grub_target_ssize_t;
typedef grub_uint64_t grub_addr_t; typedef grub_uint64_t grub_addr_t;
typedef grub_uint64_t grub_size_t; typedef grub_uint64_t grub_size_t;
typedef grub_int64_t grub_ssize_t; typedef grub_int64_t grub_ssize_t;
# if GRUB_CPU_SIZEOF_LONG == 8
# define PRIxGRUB_SIZE "lx"
# else
# define PRIxGRUB_SIZE "llx"
# endif
#else #else
typedef grub_uint32_t grub_addr_t; typedef grub_uint32_t grub_addr_t;
typedef grub_uint32_t grub_size_t; typedef grub_uint32_t grub_size_t;
typedef grub_int32_t grub_ssize_t; typedef grub_int32_t grub_ssize_t;
# define PRIxGRUB_SIZE "x"
#endif #endif
#if GRUB_CPU_SIZEOF_VOID_P == 8 #if GRUB_CPU_SIZEOF_LONG == 8
# define GRUB_ULONG_MAX 18446744073709551615UL # define GRUB_ULONG_MAX 18446744073709551615UL
# define GRUB_LONG_MAX 9223372036854775807L # define GRUB_LONG_MAX 9223372036854775807L
# define GRUB_LONG_MIN (-9223372036854775807L - 1) # define GRUB_LONG_MIN (-9223372036854775807L - 1)

272
include/grub/unicode.h Normal file
View file

@ -0,0 +1,272 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/>.
*/
#ifndef GRUB_BIDI_HEADER
#define GRUB_BIDI_HEADER 1
#include <grub/types.h>
#include <grub/mm.h>
#include <grub/misc.h>
struct grub_unicode_bidi_pair
{
grub_uint32_t key;
grub_uint32_t replace;
};
struct grub_unicode_compact_range
{
grub_uint32_t start:21;
grub_uint32_t end:21;
grub_uint8_t bidi_type:5;
grub_uint8_t comb_type;
grub_uint8_t bidi_mirror:1;
grub_uint8_t join_type:3;
} __attribute__ ((packed));
/* Old-style Arabic shaping. Used for "visual UTF-8" and
in grub-mkfont to find variant glyphs in absence of GPOS tables. */
struct grub_unicode_arabic_shape
{
grub_uint32_t code;
grub_uint32_t isolated;
grub_uint32_t right_linked;
grub_uint32_t both_linked;
grub_uint32_t left_linked;
};
extern struct grub_unicode_arabic_shape grub_unicode_arabic_shapes[];
enum grub_bidi_type
{
GRUB_BIDI_TYPE_L = 0,
GRUB_BIDI_TYPE_LRE,
GRUB_BIDI_TYPE_LRO,
GRUB_BIDI_TYPE_R,
GRUB_BIDI_TYPE_AL,
GRUB_BIDI_TYPE_RLE,
GRUB_BIDI_TYPE_RLO,
GRUB_BIDI_TYPE_PDF,
GRUB_BIDI_TYPE_EN,
GRUB_BIDI_TYPE_ES,
GRUB_BIDI_TYPE_ET,
GRUB_BIDI_TYPE_AN,
GRUB_BIDI_TYPE_CS,
GRUB_BIDI_TYPE_NSM,
GRUB_BIDI_TYPE_BN,
GRUB_BIDI_TYPE_B,
GRUB_BIDI_TYPE_S,
GRUB_BIDI_TYPE_WS,
GRUB_BIDI_TYPE_ON
};
enum grub_join_type
{
GRUB_JOIN_TYPE_NONJOINING = 0,
GRUB_JOIN_TYPE_LEFT = 1,
GRUB_JOIN_TYPE_RIGHT = 2,
GRUB_JOIN_TYPE_DUAL = 3,
GRUB_JOIN_TYPE_CAUSING = 4,
GRUB_JOIN_TYPE_TRANSPARENT = 5
};
enum grub_comb_type
{
GRUB_UNICODE_COMB_NONE = 0,
GRUB_UNICODE_COMB_OVERLAY = 1,
GRUB_UNICODE_COMB_HEBREW_SHEVA = 10,
GRUB_UNICODE_COMB_HEBREW_HATAF_SEGOL = 11,
GRUB_UNICODE_COMB_HEBREW_HATAF_PATAH = 12,
GRUB_UNICODE_COMB_HEBREW_HATAF_QAMATS = 13,
GRUB_UNICODE_COMB_HEBREW_HIRIQ = 14,
GRUB_UNICODE_COMB_HEBREW_TSERE = 15,
GRUB_UNICODE_COMB_HEBREW_SEGOL = 16,
GRUB_UNICODE_COMB_HEBREW_PATAH = 17,
GRUB_UNICODE_COMB_HEBREW_QAMATS = 18,
GRUB_UNICODE_COMB_HEBREW_HOLAM = 19,
GRUB_UNICODE_COMB_HEBREW_QUBUTS = 20,
GRUB_UNICODE_COMB_HEBREW_DAGESH = 21,
GRUB_UNICODE_COMB_HEBREW_METEG = 22,
GRUB_UNICODE_COMB_HEBREW_RAFE = 23,
GRUB_UNICODE_COMB_HEBREW_SHIN_DOT = 24,
GRUB_UNICODE_COMB_HEBREW_SIN_DOT = 25,
GRUB_UNICODE_COMB_HEBREW_VARIKA = 26,
GRUB_UNICODE_COMB_ARABIC_FATHATAN = 27,
GRUB_UNICODE_COMB_ARABIC_DAMMATAN = 28,
GRUB_UNICODE_COMB_ARABIC_KASRATAN = 29,
GRUB_UNICODE_COMB_ARABIC_FATHAH = 30,
GRUB_UNICODE_COMB_ARABIC_DAMMAH = 31,
GRUB_UNICODE_COMB_ARABIC_KASRA = 32,
GRUB_UNICODE_COMB_ARABIC_SHADDA = 33,
GRUB_UNICODE_COMB_ARABIC_SUKUN = 34,
GRUB_UNICODE_COMB_ARABIC_SUPERSCRIPT_ALIF = 35,
GRUB_UNICODE_COMB_SYRIAC_SUPERSCRIPT_ALAPH = 36,
GRUB_UNICODE_STACK_ATTACHED_BELOW = 202,
GRUB_UNICODE_STACK_ATTACHED_ABOVE = 214,
GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT = 216,
GRUB_UNICODE_STACK_BELOW = 220,
GRUB_UNICODE_COMB_BELOW_RIGHT = 222,
GRUB_UNICODE_COMB_ABOVE_LEFT = 228,
GRUB_UNICODE_STACK_ABOVE = 230,
GRUB_UNICODE_COMB_ABOVE_RIGHT = 232,
GRUB_UNICODE_COMB_YPOGEGRAMMENI = 240,
/* If combining nature is indicated only by class and
not "combining type". */
GRUB_UNICODE_COMB_ME = 253,
GRUB_UNICODE_COMB_MC = 254,
GRUB_UNICODE_COMB_MN = 255,
};
/* This structure describes a glyph as opposed to character. */
struct grub_unicode_glyph
{
grub_uint32_t base;
grub_uint16_t variant:9;
grub_uint8_t attributes:5;
grub_size_t ncomb;
struct grub_unicode_combining {
grub_uint32_t code;
enum grub_comb_type type;
} *combining;
/* Hint by unicode subsystem how wide this character usually is.
Real width is determined by font. Set only in UTF-8 stream. */
int estimated_width;
};
#define GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR 0x1
#define GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT 1
#define GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED 0x2
#define GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED \
(GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED \
<< GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT)
/* Set iff the corresponding joining flags come from ZWJ or ZWNJ. */
#define GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT 0x8
#define GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT \
(GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT \
<< GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT)
#define GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN \
(GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED \
| GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED \
| GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT \
| GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT)
enum
{
GRUB_UNICODE_COMBINING_GRAPHEME_JOINER = 0x034f,
GRUB_UNICODE_HEBREW_WAW = 0x05d5,
GRUB_UNICODE_ARABIC_START = 0x0600,
GRUB_UNICODE_ARABIC_END = 0x0700,
GRUB_UNICODE_THAANA_ABAFILI = 0x07a6,
GRUB_UNICODE_THAANA_AABAAFILI = 0x07a7,
GRUB_UNICODE_THAANA_IBIFILI = 0x07a8,
GRUB_UNICODE_THAANA_EEBEEFILI = 0x07a9,
GRUB_UNICODE_THAANA_UBUFILI = 0x07aa,
GRUB_UNICODE_THAANA_OOBOOFILI = 0x07ab,
GRUB_UNICODE_THAANA_EBEFILI = 0x07ac,
GRUB_UNICODE_THAANA_EYBEYFILI = 0x07ad,
GRUB_UNICODE_THAANA_OBOFILI = 0x07ae,
GRUB_UNICODE_THAANA_OABOAFILI = 0x07af,
GRUB_UNICODE_THAANA_SUKUN = 0x07b0,
GRUB_UNICODE_ZWNJ = 0x200c,
GRUB_UNICODE_ZWJ = 0x200d,
GRUB_UNICODE_LEFTARROW = 0x2190,
GRUB_UNICODE_UPARROW = 0x2191,
GRUB_UNICODE_RIGHTARROW = 0x2192,
GRUB_UNICODE_DOWNARROW = 0x2193,
GRUB_UNICODE_LIGHT_HLINE = 0x2500,
GRUB_UNICODE_HLINE = 0x2501,
GRUB_UNICODE_LIGHT_VLINE = 0x2502,
GRUB_UNICODE_VLINE = 0x2503,
GRUB_UNICODE_LIGHT_CORNER_UL = 0x250c,
GRUB_UNICODE_CORNER_UL = 0x250f,
GRUB_UNICODE_LIGHT_CORNER_UR = 0x2510,
GRUB_UNICODE_CORNER_UR = 0x2513,
GRUB_UNICODE_LIGHT_CORNER_LL = 0x2514,
GRUB_UNICODE_CORNER_LL = 0x2517,
GRUB_UNICODE_LIGHT_CORNER_LR = 0x2518,
GRUB_UNICODE_CORNER_LR = 0x251b,
GRUB_UNICODE_BLACK_UP_TRIANGLE = 0x25b2,
GRUB_UNICODE_BLACK_RIGHT_TRIANGLE = 0x25ba,
GRUB_UNICODE_BLACK_DOWN_TRIANGLE = 0x25bc,
GRUB_UNICODE_BLACK_LEFT_TRIANGLE = 0x25c4,
GRUB_UNICODE_VARIATION_SELECTOR_1 = 0xfe00,
GRUB_UNICODE_VARIATION_SELECTOR_16 = 0xfe0f,
GRUB_UNICODE_VARIATION_SELECTOR_17 = 0xe0100,
GRUB_UNICODE_VARIATION_SELECTOR_256 = 0xe01ef
};
extern struct grub_unicode_compact_range grub_unicode_compact[];
extern struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[];
#define GRUB_UNICODE_MAX_CACHED_CHAR 0x20000
/* Unicode mandates an arbitrary limit. */
#define GRUB_BIDI_MAX_EXPLICIT_LEVEL 61
grub_ssize_t
grub_bidi_logical_to_visual (const grub_uint32_t *logical,
grub_size_t logical_len,
struct grub_unicode_glyph **visual_out,
grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual),
grub_size_t max_width,
grub_size_t start_width);
enum grub_comb_type
grub_unicode_get_comb_type (grub_uint32_t c);
grub_size_t
grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
struct grub_unicode_glyph *out);
static inline struct grub_unicode_glyph *
grub_unicode_glyph_dup (const struct grub_unicode_glyph *in)
{
struct grub_unicode_glyph *out = grub_malloc (sizeof (*out));
if (!out)
return NULL;
grub_memcpy (out, in, sizeof (*in));
if (in->combining)
{
out->combining = grub_malloc (in->ncomb * sizeof (*in));
if (!out->combining)
{
grub_free (out);
return NULL;
}
grub_memcpy (out->combining, in->combining, in->ncomb * sizeof (*in));
}
return out;
}
static inline struct grub_unicode_glyph *
grub_unicode_glyph_from_code (grub_uint32_t code)
{
struct grub_unicode_glyph *ret;
ret = grub_zalloc (sizeof (*ret));
if (!ret)
return NULL;
ret->base = code;
return ret;
}
grub_uint32_t
grub_unicode_mirror_code (grub_uint32_t in);
grub_uint32_t
grub_unicode_shape_code (grub_uint32_t in, grub_uint8_t attr);
#endif

View file

@ -87,15 +87,17 @@ typedef struct grub_usb_transfer *grub_usb_transfer_t;
#define GRUB_USB_REQ_SET_INTERFACE 0x0B #define GRUB_USB_REQ_SET_INTERFACE 0x0B
#define GRUB_USB_REQ_SYNC_FRAME 0x0C #define GRUB_USB_REQ_SYNC_FRAME 0x0C
#define GRUB_USB_REQ_HUB_GET_PORT_STATUS 0x00
#define GRUB_USB_FEATURE_ENDP_HALT 0x00 #define GRUB_USB_FEATURE_ENDP_HALT 0x00
#define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x01 #define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x01
#define GRUB_USB_FEATURE_TEST_MODE 0x02 #define GRUB_USB_FEATURE_TEST_MODE 0x02
#define GRUB_USB_HUB_FEATURE_PORT_RESET 0x04
#define GRUB_USB_HUB_FEATURE_PORT_POWER 0x08
#define GRUB_USB_HUB_STATUS_CONNECTED (1 << 0) #define GRUB_USB_HUB_STATUS_CONNECTED (1 << 0)
#define GRUB_USB_HUB_STATUS_LOWSPEED (1 << 9) #define GRUB_USB_HUB_STATUS_LOWSPEED (1 << 9)
#define GRUB_USB_HUB_STATUS_HIGHSPEED (1 << 10) #define GRUB_USB_HUB_STATUS_HIGHSPEED (1 << 10)
#define GRUB_USB_HUB_STATUS_C_PORT_RESET (1 << 20)
struct grub_usb_packet_setup struct grub_usb_packet_setup
{ {

195
include/grub/vga.h Normal file
View file

@ -0,0 +1,195 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/>.
*/
#ifndef GRUB_VGA_HEADER
#define GRUB_VGA_HEADER 1
enum
{
GRUB_VGA_IO_ARX = 0x3c0,
GRUB_VGA_IO_SR_INDEX = 0x3c4,
GRUB_VGA_IO_SR_DATA = 0x3c5,
GRUB_VGA_IO_PIXEL_MASK = 0x3c6,
GRUB_VGA_IO_PALLETTE_READ_INDEX = 0x3c7,
GRUB_VGA_IO_PALLETTE_WRITE_INDEX = 0x3c8,
GRUB_VGA_IO_PALLETTE_DATA = 0x3c9,
GRUB_VGA_IO_GR_INDEX = 0x3ce,
GRUB_VGA_IO_GR_DATA = 0x3cf,
GRUB_VGA_IO_CR_INDEX = 0x3d4,
GRUB_VGA_IO_CR_DATA = 0x3d5,
GRUB_VGA_IO_INPUT_STATUS1_REGISTER = 0x3da
};
#define GRUB_VGA_IO_INPUT_STATUS1_VERTR_BIT 0x08
enum
{
GRUB_VGA_CR_WIDTH = 0x01,
GRUB_VGA_CR_OVERFLOW = 0x07,
GRUB_VGA_CR_CELL_HEIGHT = 0x09,
GRUB_VGA_CR_CURSOR_START = 0x0a,
GRUB_VGA_CR_CURSOR_END = 0x0b,
GRUB_VGA_CR_START_ADDR_HIGH_REGISTER = 0x0c,
GRUB_VGA_CR_START_ADDR_LOW_REGISTER = 0x0d,
GRUB_VGA_CR_CURSOR_ADDR_HIGH = 0x0e,
GRUB_VGA_CR_CURSOR_ADDR_LOW = 0x0f,
GRUB_VGA_CR_VSYNC_END = 0x11,
GRUB_VGA_CR_HEIGHT = 0x12,
GRUB_VGA_CR_PITCH = 0x13,
GRUB_VGA_CR_MODE = 0x17,
GRUB_VGA_CR_LINE_COMPARE = 0x18,
};
#define GRUB_VGA_CR_WIDTH_DIVISOR 8
#define GRUB_VGA_CR_OVERFLOW_HEIGHT1_SHIFT 7
#define GRUB_VGA_CR_OVERFLOW_HEIGHT1_MASK 0x02
#define GRUB_VGA_CR_OVERFLOW_HEIGHT2_SHIFT 3
#define GRUB_VGA_CR_OVERFLOW_HEIGHT2_MASK 0xc0
#define GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_SHIFT 4
#define GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_MASK 0x10
#define GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_MASK 0x40
#define GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT 3
enum
{
GRUB_VGA_CR_CURSOR_START_DISABLE = (1 << 5)
};
#define GRUB_VGA_CR_PITCH_DIVISOR 8
enum
{
GRUB_VGA_CR_MODE_NO_CGA = 0x01,
GRUB_VGA_CR_MODE_NO_HERCULES = 0x02,
GRUB_VGA_CR_MODE_BYTE_MODE = 0x40,
GRUB_VGA_CR_MODE_TIMING_ENABLE = 0x80
};
enum
{
GRUB_VGA_SR_CLOCKING_MODE = 1,
GRUB_VGA_SR_MAP_MASK_REGISTER = 2,
GRUB_VGA_SR_MEMORY_MODE = 4,
};
enum
{
GRUB_VGA_SR_CLOCKING_MODE_8_DOT_CLOCK = 1
};
enum
{
GRUB_VGA_SR_MEMORY_MODE_NORMAL = 0,
GRUB_VGA_SR_MEMORY_MODE_CHAIN4 = 8
};
enum
{
GRUB_VGA_GR_DATA_ROTATE = 3,
GRUB_VGA_GR_READ_MAP_REGISTER = 4,
GRUB_VGA_GR_MODE = 5,
GRUB_VGA_GR_GR6 = 6,
GRUB_VGA_GR_BITMASK = 8,
GRUB_VGA_GR_MAX
};
enum
{
GRUB_VGA_TEXT_TEXT_PLANE = 0,
GRUB_VGA_TEXT_ATTR_PLANE = 1,
GRUB_VGA_TEXT_FONT_PLANE = 2
};
enum
{
GRUB_VGA_GR_GR6_GRAPHICS_MODE = 1,
GRUB_VGA_GR_GR6_MMAP_CGA = (3 << 2)
};
enum
{
GRUB_VGA_GR_MODE_READ_MODE1 = 0x08,
GRUB_VGA_GR_MODE_ODD_EVEN = 0x10,
GRUB_VGA_GR_MODE_256_COLOR = 0x40
};
static inline void
grub_vga_gr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_GR_INDEX);
grub_outb (val, GRUB_VGA_IO_GR_DATA);
}
static inline grub_uint8_t
grub_vga_gr_read (grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_GR_INDEX);
return grub_inb (GRUB_VGA_IO_GR_DATA);
}
static inline void
grub_vga_cr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_CR_INDEX);
grub_outb (val, GRUB_VGA_IO_CR_DATA);
}
static inline grub_uint8_t
grub_vga_cr_read (grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_CR_INDEX);
return grub_inb (GRUB_VGA_IO_CR_DATA);
}
static inline void
grub_vga_sr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_SR_INDEX);
grub_outb (val, GRUB_VGA_IO_SR_DATA);
}
static inline grub_uint8_t
grub_vga_sr_read (grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_SR_INDEX);
return grub_inb (GRUB_VGA_IO_SR_DATA);
}
static inline void
grub_vga_palette_read (grub_uint8_t addr, grub_uint8_t *r, grub_uint8_t *g,
grub_uint8_t *b)
{
grub_outb (addr, GRUB_VGA_IO_PALLETTE_READ_INDEX);
*r = grub_inb (GRUB_VGA_IO_PALLETTE_DATA);
*g = grub_inb (GRUB_VGA_IO_PALLETTE_DATA);
*b = grub_inb (GRUB_VGA_IO_PALLETTE_DATA);
}
static inline void
grub_vga_palette_write (grub_uint8_t addr, grub_uint8_t r, grub_uint8_t g,
grub_uint8_t b)
{
grub_outb (addr, GRUB_VGA_IO_PALLETTE_WRITE_INDEX);
grub_outb (r, GRUB_VGA_IO_PALLETTE_DATA);
grub_outb (g, GRUB_VGA_IO_PALLETTE_DATA);
grub_outb (b, GRUB_VGA_IO_PALLETTE_DATA);
}
#endif

View file

@ -168,6 +168,15 @@ struct grub_video_rect
}; };
typedef struct grub_video_rect grub_video_rect_t; typedef struct grub_video_rect grub_video_rect_t;
struct grub_video_signed_rect
{
signed x;
signed y;
unsigned width;
unsigned height;
};
typedef struct grub_video_signed_rect grub_video_signed_rect_t;
struct grub_video_palette_data struct grub_video_palette_data
{ {
grub_uint8_t r; /* Red color value (0-255). */ grub_uint8_t r; /* Red color value (0-255). */
@ -183,9 +192,21 @@ typedef enum grub_video_driver_id
GRUB_VIDEO_DRIVER_EFI_UGA, GRUB_VIDEO_DRIVER_EFI_UGA,
GRUB_VIDEO_DRIVER_EFI_GOP, GRUB_VIDEO_DRIVER_EFI_GOP,
GRUB_VIDEO_DRIVER_SM712, GRUB_VIDEO_DRIVER_SM712,
GRUB_VIDEO_DRIVER_VGA GRUB_VIDEO_DRIVER_VGA,
GRUB_VIDEO_DRIVER_CIRRUS,
GRUB_VIDEO_DRIVER_BOCHS,
GRUB_VIDEO_DRIVER_SDL
} grub_video_driver_id_t; } grub_video_driver_id_t;
typedef enum grub_video_adapter_prio
{
GRUB_VIDEO_ADAPTER_PRIO_FALLBACK = 60,
GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE_DIRTY = 70,
GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE = 80,
GRUB_VIDEO_ADAPTER_PRIO_NATIVE = 100
} grub_video_adapter_prio_t;
struct grub_video_adapter struct grub_video_adapter
{ {
/* The next video adapter. */ /* The next video adapter. */
@ -195,6 +216,8 @@ struct grub_video_adapter
const char *name; const char *name;
grub_video_driver_id_t id; grub_video_driver_id_t id;
grub_video_adapter_prio_t prio;
/* Initialize the video adapter. */ /* Initialize the video adapter. */
grub_err_t (*init) (void); grub_err_t (*init) (void);
@ -264,13 +287,18 @@ typedef struct grub_video_adapter *grub_video_adapter_t;
extern grub_video_adapter_t EXPORT_VAR(grub_video_adapter_list); extern grub_video_adapter_t EXPORT_VAR(grub_video_adapter_list);
#ifndef GRUB_LST_GENERATOR
/* Register video driver. */ /* Register video driver. */
static inline void static inline void
grub_video_register (grub_video_adapter_t adapter) grub_video_register (grub_video_adapter_t adapter)
{ {
grub_list_push (GRUB_AS_LIST_P (&grub_video_adapter_list), grub_video_adapter_t *p;
GRUB_AS_LIST (adapter)); for (p = &grub_video_adapter_list; *p && (*p)->prio > adapter->prio;
p = &((*p)->next));
adapter->next = *p;
*p = adapter;
} }
#endif
/* Unregister video driver. */ /* Unregister video driver. */
static inline void static inline void

View file

@ -119,11 +119,18 @@ typedef grub_err_t
(*grub_video_fb_doublebuf_update_screen_t) (struct grub_video_fbrender_target *front, (*grub_video_fb_doublebuf_update_screen_t) (struct grub_video_fbrender_target *front,
struct grub_video_fbrender_target *back); struct grub_video_fbrender_target *back);
typedef grub_err_t (*grub_video_fb_set_page_t) (int page);
grub_err_t grub_err_t
grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **front, grub_video_fb_setup (unsigned int mode_type, unsigned int mode_mask,
struct grub_video_fbrender_target **back, struct grub_video_mode_info *mode_info,
grub_video_fb_doublebuf_update_screen_t *update_screen, volatile void *page0_ptr,
struct grub_video_mode_info mode_info, grub_video_fb_set_page_t set_page_in,
void *framebuf); volatile void *page1_ptr);
grub_err_t
grub_video_fb_swap_buffers (void);
grub_err_t
grub_video_fb_get_info_and_fini (struct grub_video_mode_info *mode_info,
void **framebuf);
#endif /* ! GRUB_VIDEO_FB_HEADER */ #endif /* ! GRUB_VIDEO_FB_HEADER */

View file

@ -122,7 +122,7 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
if (argc < 1) if (argc < 1)
{ {
grub_device_iterate (grub_mini_print_devices); grub_device_iterate (grub_mini_print_devices);
grub_putchar ('\n'); grub_xputs ("\n");
grub_refresh (); grub_refresh ();
} }
else else
@ -161,7 +161,7 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
else if (fs) else if (fs)
{ {
(fs->dir) (dev, path, grub_mini_print_files); (fs->dir) (dev, path, grub_mini_print_files);
grub_putchar ('\n'); grub_xputs ("\n");
grub_refresh (); grub_refresh ();
} }

View file

@ -170,6 +170,7 @@ grub_reboot (void)
grub_efi_fini (); grub_efi_fini ();
efi_call_4 (grub_efi_system_table->runtime_services->reset_system, efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL); GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL);
for (;;) ;
} }
#endif #endif
@ -179,6 +180,7 @@ grub_halt (void)
grub_efi_fini (); grub_efi_fini ();
efi_call_4 (grub_efi_system_table->runtime_services->reset_system, efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
GRUB_EFI_RESET_SHUTDOWN, GRUB_EFI_SUCCESS, 0, NULL); GRUB_EFI_RESET_SHUTDOWN, GRUB_EFI_SUCCESS, 0, NULL);
for (;;) ;
} }
int int

View file

@ -36,6 +36,9 @@ grub_efi_init (void)
/* Initialize the memory management system. */ /* Initialize the memory management system. */
grub_efi_mm_init (); grub_efi_mm_init ();
efi_call_4 (grub_efi_system_table->boot_services->set_watchdog_timer,
0, 0, 0, NULL);
grub_efidisk_init (); grub_efidisk_init ();
} }

View file

@ -346,6 +346,7 @@ grub_efi_mm_init (void)
grub_efi_uintn_t desc_size; grub_efi_uintn_t desc_size;
grub_efi_uint64_t total_pages; grub_efi_uint64_t total_pages;
grub_efi_uint64_t required_pages; grub_efi_uint64_t required_pages;
int mm_status;
/* First of all, allocate pages to maintain allocations. */ /* First of all, allocate pages to maintain allocations. */
allocated_pages allocated_pages
@ -361,16 +362,32 @@ grub_efi_mm_init (void)
if (! memory_map) if (! memory_map)
grub_fatal ("cannot allocate memory"); grub_fatal ("cannot allocate memory");
filtered_memory_map = NEXT_MEMORY_DESCRIPTOR (memory_map, MEMORY_MAP_SIZE);
/* Obtain descriptors for available memory. */ /* Obtain descriptors for available memory. */
map_size = MEMORY_MAP_SIZE; map_size = MEMORY_MAP_SIZE;
if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0) mm_status = grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0);
if (mm_status == 0)
{
grub_efi_free_pages
((grub_efi_physical_address_t) ((grub_addr_t) memory_map),
2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
memory_map = grub_efi_allocate_pages (0, 2 * BYTES_TO_PAGES (map_size));
if (! memory_map)
grub_fatal ("cannot allocate memory");
mm_status = grub_efi_get_memory_map (&map_size, memory_map, 0,
&desc_size, 0);
}
if (mm_status < 0)
grub_fatal ("cannot get memory map"); grub_fatal ("cannot get memory map");
memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size); memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size);
filtered_memory_map = memory_map_end;
filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map, filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map,
desc_size, memory_map_end); desc_size, memory_map_end);

View file

@ -43,9 +43,7 @@ static int grub_console_attr = A_NORMAL;
grub_uint8_t grub_console_cur_color = 7; grub_uint8_t grub_console_cur_color = 7;
static grub_uint8_t grub_console_standard_color = 0x7; static const grub_uint8_t grub_console_standard_color = 0x7;
static grub_uint8_t grub_console_normal_color = 0x7;
static grub_uint8_t grub_console_highlight_color = 0x70;
#define NUM_COLORS 8 #define NUM_COLORS 8
@ -64,60 +62,15 @@ static grub_uint8_t color_map[NUM_COLORS] =
static int use_color; static int use_color;
static void static void
grub_ncurses_putchar (grub_uint32_t c) grub_ncurses_putchar (struct grub_term_output *term __attribute__ ((unused)),
const struct grub_unicode_glyph *c)
{ {
/* Better than nothing. */ addch (c->base | grub_console_attr);
switch (c)
{
case GRUB_TERM_DISP_LEFT:
c = '<';
break;
case GRUB_TERM_DISP_UP:
c = '^';
break;
case GRUB_TERM_DISP_RIGHT:
c = '>';
break;
case GRUB_TERM_DISP_DOWN:
c = 'v';
break;
case GRUB_TERM_DISP_HLINE:
c = '-';
break;
case GRUB_TERM_DISP_VLINE:
c = '|';
break;
case GRUB_TERM_DISP_UL:
case GRUB_TERM_DISP_UR:
case GRUB_TERM_DISP_LL:
case GRUB_TERM_DISP_LR:
c = '+';
break;
default:
/* ncurses does not support Unicode. */
if (c > 0x7f)
c = '?';
break;
}
addch (c | grub_console_attr);
}
static grub_ssize_t
grub_ncurses_getcharwidth (grub_uint32_t code __attribute__ ((unused)))
{
return 1;
} }
static void static void
grub_ncurses_setcolorstate (grub_term_color_state state) grub_ncurses_setcolorstate (struct grub_term_output *term,
grub_term_color_state state)
{ {
switch (state) switch (state)
{ {
@ -126,11 +79,11 @@ grub_ncurses_setcolorstate (grub_term_color_state state)
grub_console_attr = A_NORMAL; grub_console_attr = A_NORMAL;
break; break;
case GRUB_TERM_COLOR_NORMAL: case GRUB_TERM_COLOR_NORMAL:
grub_console_cur_color = grub_console_normal_color; grub_console_cur_color = term->normal_color;
grub_console_attr = A_NORMAL; grub_console_attr = A_NORMAL;
break; break;
case GRUB_TERM_COLOR_HIGHLIGHT: case GRUB_TERM_COLOR_HIGHLIGHT:
grub_console_cur_color = grub_console_highlight_color; grub_console_cur_color = term->highlight_color;
grub_console_attr = A_STANDOUT; grub_console_attr = A_STANDOUT;
break; break;
default: default:
@ -149,25 +102,10 @@ grub_ncurses_setcolorstate (grub_term_color_state state)
} }
} }
/* XXX: This function is never called. */
static void
grub_ncurses_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
{
grub_console_normal_color = normal_color;
grub_console_highlight_color = highlight_color;
}
static void
grub_ncurses_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
{
*normal_color = grub_console_normal_color;
*highlight_color = grub_console_highlight_color;
}
static int saved_char = ERR; static int saved_char = ERR;
static int static int
grub_ncurses_checkkey (void) grub_ncurses_checkkey (struct grub_term_input *term __attribute__ ((unused)))
{ {
int c; int c;
@ -189,7 +127,7 @@ grub_ncurses_checkkey (void)
} }
static int static int
grub_ncurses_getkey (void) grub_ncurses_getkey (struct grub_term_input *term __attribute__ ((unused)))
{ {
int c; int c;
@ -208,19 +146,19 @@ grub_ncurses_getkey (void)
switch (c) switch (c)
{ {
case KEY_LEFT: case KEY_LEFT:
c = 2; c = GRUB_TERM_LEFT;
break; break;
case KEY_RIGHT: case KEY_RIGHT:
c = 6; c = GRUB_TERM_RIGHT;
break; break;
case KEY_UP: case KEY_UP:
c = 16; c = GRUB_TERM_UP;
break; break;
case KEY_DOWN: case KEY_DOWN:
c = 14; c = GRUB_TERM_DOWN;
break; break;
case KEY_IC: case KEY_IC:
@ -228,30 +166,30 @@ grub_ncurses_getkey (void)
break; break;
case KEY_DC: case KEY_DC:
c = 4; c = GRUB_TERM_DC;
break; break;
case KEY_BACKSPACE: case KEY_BACKSPACE:
/* XXX: For some reason ncurses on xterm does not return /* XXX: For some reason ncurses on xterm does not return
KEY_BACKSPACE. */ KEY_BACKSPACE. */
case 127: case 127:
c = 8; c = GRUB_TERM_BACKSPACE;
break; break;
case KEY_HOME: case KEY_HOME:
c = 1; c = GRUB_TERM_HOME;
break; break;
case KEY_END: case KEY_END:
c = 5; c = GRUB_TERM_END;
break; break;
case KEY_NPAGE: case KEY_NPAGE:
c = 3; c = GRUB_TERM_NPAGE;
break; break;
case KEY_PPAGE: case KEY_PPAGE:
c = 7; c = GRUB_TERM_PPAGE;
break; break;
} }
@ -259,7 +197,7 @@ grub_ncurses_getkey (void)
} }
static grub_uint16_t static grub_uint16_t
grub_ncurses_getxy (void) grub_ncurses_getxy (struct grub_term_output *term __attribute__ ((unused)))
{ {
int x; int x;
int y; int y;
@ -270,7 +208,7 @@ grub_ncurses_getxy (void)
} }
static grub_uint16_t static grub_uint16_t
grub_ncurses_getwh (void) grub_ncurses_getwh (struct grub_term_output *term __attribute__ ((unused)))
{ {
int x; int x;
int y; int y;
@ -281,32 +219,34 @@ grub_ncurses_getwh (void)
} }
static void static void
grub_ncurses_gotoxy (grub_uint8_t x, grub_uint8_t y) grub_ncurses_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
grub_uint8_t x, grub_uint8_t y)
{ {
move (y, x); move (y, x);
} }
static void static void
grub_ncurses_cls (void) grub_ncurses_cls (struct grub_term_output *term __attribute__ ((unused)))
{ {
clear (); clear ();
refresh (); refresh ();
} }
static void static void
grub_ncurses_setcursor (int on) grub_ncurses_setcursor (struct grub_term_output *term __attribute__ ((unused)),
int on)
{ {
curs_set (on ? 1 : 0); curs_set (on ? 1 : 0);
} }
static void static void
grub_ncurses_refresh (void) grub_ncurses_refresh (struct grub_term_output *term __attribute__ ((unused)))
{ {
refresh (); refresh ();
} }
static grub_err_t static grub_err_t
grub_ncurses_init (void) grub_ncurses_init (struct grub_term_output *term __attribute__ ((unused)))
{ {
initscr (); initscr ();
raw (); raw ();
@ -338,7 +278,7 @@ grub_ncurses_init (void)
} }
static grub_err_t static grub_err_t
grub_ncurses_fini (void) grub_ncurses_fini (struct grub_term_output *term __attribute__ ((unused)))
{ {
endwin (); endwin ();
return 0; return 0;
@ -358,16 +298,14 @@ static struct grub_term_output grub_ncurses_term_output =
.init = grub_ncurses_init, .init = grub_ncurses_init,
.fini = grub_ncurses_fini, .fini = grub_ncurses_fini,
.putchar = grub_ncurses_putchar, .putchar = grub_ncurses_putchar,
.getcharwidth = grub_ncurses_getcharwidth,
.getxy = grub_ncurses_getxy, .getxy = grub_ncurses_getxy,
.getwh = grub_ncurses_getwh, .getwh = grub_ncurses_getwh,
.gotoxy = grub_ncurses_gotoxy, .gotoxy = grub_ncurses_gotoxy,
.cls = grub_ncurses_cls, .cls = grub_ncurses_cls,
.setcolorstate = grub_ncurses_setcolorstate, .setcolorstate = grub_ncurses_setcolorstate,
.setcolor = grub_ncurses_setcolor,
.getcolor = grub_ncurses_getcolor,
.setcursor = grub_ncurses_setcursor, .setcursor = grub_ncurses_setcursor,
.refresh = grub_ncurses_refresh .refresh = grub_ncurses_refresh,
.flags = GRUB_TERM_CODE_TYPE_ASCII
}; };
void void
@ -380,5 +318,5 @@ grub_console_init (void)
void void
grub_console_fini (void) grub_console_fini (void)
{ {
grub_ncurses_fini (); grub_ncurses_fini (&grub_ncurses_term_output);
} }

View file

@ -33,6 +33,7 @@
#include <hurd.h> #include <hurd.h>
#include <hurd/lookup.h> #include <hurd/lookup.h>
#include <hurd/fs.h> #include <hurd/fs.h>
#include <sys/mman.h>
#endif #endif
#include <grub/mm.h> #include <grub/mm.h>

View file

@ -992,6 +992,11 @@ grub_util_biosdisk_fini (void)
grub_disk_dev_unregister (&grub_util_biosdisk_dev); grub_disk_dev_unregister (&grub_util_biosdisk_dev);
} }
/*
* Note: we do not use the new partition naming scheme as dos_part does not
* necessarily correspond to an msdos partition. See e.g. the FreeBSD code
* in function grub_util_biosdisk_get_grub_dev.
*/
static char * static char *
make_device_name (int drive, int dos_part, int bsd_part) make_device_name (int drive, int dos_part, int bsd_part)
{ {
@ -1255,7 +1260,7 @@ devmapper_out:
for (p = path + 5; *p; ++p) for (p = path + 5; *p; ++p)
if (grub_isdigit(*p)) if (grub_isdigit(*p))
{ {
p = strchr (p, 's'); p = strpbrk (p, "sp");
if (p) if (p)
*p = '\0'; *p = '\0';
break; break;
@ -1400,11 +1405,9 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
For NetBSD, proceed as for Linux, except that the start sector is For NetBSD, proceed as for Linux, except that the start sector is
obtained from the disk label. */ obtained from the disk label. */
{ {
char *name; char *name, *partname;
grub_disk_t disk; grub_disk_t disk;
grub_disk_addr_t start; grub_disk_addr_t start;
int dos_part = -1;
int bsd_part = -1;
auto int find_partition (grub_disk_t dsk, auto int find_partition (grub_disk_t dsk,
const grub_partition_t partition); const grub_partition_t partition);
@ -1419,17 +1422,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
if (start == part_start) if (start == part_start)
{ {
if (partition->parent) partname = grub_partition_get_name (partition);
{
dos_part = partition->parent->number;
bsd_part = partition->number;
}
else
{
dos_part = partition->number;
bsd_part = -1;
}
return 1; return 1;
} }
@ -1465,6 +1458,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
if (! disk) if (! disk)
return 0; return 0;
partname = NULL;
grub_partition_iterate (disk, find_partition); grub_partition_iterate (disk, find_partition);
if (grub_errno != GRUB_ERR_NONE) if (grub_errno != GRUB_ERR_NONE)
{ {
@ -1472,7 +1466,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
return 0; return 0;
} }
if (dos_part < 0) if (partname == NULL)
{ {
grub_disk_close (disk); grub_disk_close (disk);
grub_error (GRUB_ERR_BAD_DEVICE, grub_error (GRUB_ERR_BAD_DEVICE,
@ -1480,7 +1474,9 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
return 0; return 0;
} }
return make_device_name (drive, dos_part, bsd_part); name = grub_xasprintf ("%s,%s", disk->name, partname);
free (partname);
return name;
} }
#elif defined(__GNU__) #elif defined(__GNU__)
@ -1511,7 +1507,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
} }
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
/* FreeBSD uses "/dev/[a-z]+[0-9]+(s[0-9]+[a-z]?)?". */ /* FreeBSD uses "/dev/[a-z]+[0-9]+([sp][0-9]+[a-z]?)?". */
{ {
int dos_part = -1; int dos_part = -1;
int bsd_part = -1; int bsd_part = -1;
@ -1525,7 +1521,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
for (p = os_dev + 5; *p; ++p) for (p = os_dev + 5; *p; ++p)
if (grub_isdigit(*p)) if (grub_isdigit(*p))
{ {
p = strchr (p, 's'); p = strpbrk (p, "sp"); /* msdos or apple (or ... ?) partition map */
if (p) if (p)
{ {
p++; p++;

View file

@ -71,6 +71,9 @@ grub_exit (void)
void void
grub_machine_init (void) grub_machine_init (void)
{ {
#ifdef GRUB_MACHINE_QEMU
grub_qemu_init_cirrus ();
#endif
/* Initialize the console as early as possible. */ /* Initialize the console as early as possible. */
grub_vga_text_init (); grub_vga_text_init ();

View file

@ -83,6 +83,14 @@ make_install_device (void)
grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ")%s", grub_prefix); grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ")%s", grub_prefix);
grub_strcpy (grub_prefix, dev); grub_strcpy (grub_prefix, dev);
} }
else if (grub_prefix[1] == ',' || grub_prefix[1] == ')')
{
/* We have a prefix, but still need to fill in the boot drive. */
grub_snprintf (dev, sizeof (dev),
"(%cd%u%s", (grub_boot_drive & 0x80) ? 'h' : 'f',
grub_boot_drive & 0x7f, grub_prefix + 1);
grub_strcpy (grub_prefix, dev);
}
return grub_prefix; return grub_prefix;
} }

View file

@ -1063,7 +1063,7 @@ xsmap:
/* /*
* void grub_console_real_putchar (int c) * void grub_console_putchar (const struct grub_unicode_glyph *c)
* *
* Put the character C on the console. Because GRUB wants to write a * Put the character C on the console. Because GRUB wants to write a
* character with an attribute, this implementation is a bit tricky. * character with an attribute, this implementation is a bit tricky.
@ -1076,8 +1076,9 @@ xsmap:
* get the height of the screen, and the TELETYPE OUTPUT BIOS call doesn't * get the height of the screen, and the TELETYPE OUTPUT BIOS call doesn't
* support setting a background attribute. * support setting a background attribute.
*/ */
FUNCTION(grub_console_real_putchar) FUNCTION(grub_console_putchar)
movl %eax, %edx /* Retrieve the base character. */
movl 0(%edx), %edx
pusha pusha
movb EXT_C(grub_console_cur_color), %bl movb EXT_C(grub_console_cur_color), %bl
@ -1328,8 +1329,8 @@ FUNCTION(grub_console_gotoxy)
pushl %ebp pushl %ebp
pushl %ebx /* save EBX */ pushl %ebx /* save EBX */
movb %dl, %dh /* %dh = y */ movb %cl, %dh /* %dh = y */
movb %al, %dl /* %dl = x */ /* %dl = x */
call prot_to_real call prot_to_real
.code16 .code16
@ -1405,7 +1406,7 @@ FUNCTION(grub_console_setcursor)
pushl %ebx pushl %ebx
/* push ON */ /* push ON */
pushl %eax pushl %edx
/* check if the standard cursor shape has already been saved */ /* check if the standard cursor shape has already been saved */
movw console_cursor_shape, %ax movw console_cursor_shape, %ax

152
kern/i386/qemu/init.c Normal file
View file

@ -0,0 +1,152 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/pci.h>
#include <grub/machine/kernel.h>
#include <grub/misc.h>
#include <grub/vga.h>
static struct {grub_uint8_t r, g, b, a; } colors[] =
{
// {R, G, B, A}
{0x00, 0x00, 0x00, 0xFF}, // 0 = black
{0x00, 0x00, 0xA8, 0xFF}, // 1 = blue
{0x00, 0xA8, 0x00, 0xFF}, // 2 = green
{0x00, 0xA8, 0xA8, 0xFF}, // 3 = cyan
{0xA8, 0x00, 0x00, 0xFF}, // 4 = red
{0xA8, 0x00, 0xA8, 0xFF}, // 5 = magenta
{0xA8, 0x54, 0x00, 0xFF}, // 6 = brown
{0xA8, 0xA8, 0xA8, 0xFF}, // 7 = light gray
{0x54, 0x54, 0x54, 0xFF}, // 8 = dark gray
{0x54, 0x54, 0xFE, 0xFF}, // 9 = bright blue
{0x54, 0xFE, 0x54, 0xFF}, // 10 = bright green
{0x54, 0xFE, 0xFE, 0xFF}, // 11 = bright cyan
{0xFE, 0x54, 0x54, 0xFF}, // 12 = bright red
{0xFE, 0x54, 0xFE, 0xFF}, // 13 = bright magenta
{0xFE, 0xFE, 0x54, 0xFF}, // 14 = yellow
{0xFE, 0xFE, 0xFE, 0xFF} // 15 = white
};
#include <ascii.h>
static void
load_font (void)
{
unsigned i;
grub_vga_gr_write (0 << 2, GRUB_VGA_GR_GR6);
grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_NORMAL, GRUB_VGA_SR_MEMORY_MODE);
grub_vga_sr_write (1 << GRUB_VGA_TEXT_FONT_PLANE,
GRUB_VGA_SR_MAP_MASK_REGISTER);
grub_vga_gr_write (0, GRUB_VGA_GR_DATA_ROTATE);
grub_vga_gr_write (0, GRUB_VGA_GR_MODE);
grub_vga_gr_write (0xff, GRUB_VGA_GR_BITMASK);
for (i = 0; i < 128; i++)
grub_memcpy ((void *) (0xa0000 + 32 * i), ascii_bitmaps + 16 * i, 16);
}
static void
load_palette (void)
{
unsigned i;
for (i = 0; i < 16; i++)
{
grub_outb (i, GRUB_VGA_IO_ARX);
grub_outb (i, GRUB_VGA_IO_ARX);
}
for (i = 0; i < ARRAY_SIZE (colors); i++)
grub_vga_palette_write (i, colors[i].r, colors[i].g, colors[i].b);
}
void
grub_qemu_init_cirrus (void)
{
auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid);
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, GRUB_PCI_REG_CLASS);
class = grub_pci_read (addr);
if (((class >> 16) & 0xffff) != 0x0300)
return 0;
/* FIXME: chooose addresses dynamically. */
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
grub_pci_write (addr, 0xf0000000 | GRUB_PCI_ADDR_MEM_PREFETCH
| GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32);
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1);
grub_pci_write (addr, 0xf2000000
| GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32);
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
grub_pci_write (addr, GRUB_PCI_COMMAND_MEM_ENABLED
| GRUB_PCI_COMMAND_IO_ENABLED);
return 1;
}
grub_pci_iterate (find_card);
grub_outb (1, 0x3c2);
load_font ();
grub_vga_gr_write (GRUB_VGA_GR_GR6_MMAP_CGA, GRUB_VGA_GR_GR6);
grub_vga_gr_write (GRUB_VGA_GR_MODE_ODD_EVEN, GRUB_VGA_GR_MODE);
grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_NORMAL, GRUB_VGA_SR_MEMORY_MODE);
grub_vga_sr_write ((1 << GRUB_VGA_TEXT_TEXT_PLANE)
| (1 << GRUB_VGA_TEXT_ATTR_PLANE),
GRUB_VGA_SR_MAP_MASK_REGISTER);
grub_vga_cr_write (15, GRUB_VGA_CR_CELL_HEIGHT);
grub_vga_cr_write (79, GRUB_VGA_CR_WIDTH);
grub_vga_cr_write (40, GRUB_VGA_CR_PITCH);
int vert = 25 * 16;
grub_vga_cr_write (vert & 0xff, GRUB_VGA_CR_HEIGHT);
grub_vga_cr_write (((vert >> GRUB_VGA_CR_OVERFLOW_HEIGHT1_SHIFT)
& GRUB_VGA_CR_OVERFLOW_HEIGHT1_MASK)
| ((vert >> GRUB_VGA_CR_OVERFLOW_HEIGHT2_SHIFT)
& GRUB_VGA_CR_OVERFLOW_HEIGHT2_MASK),
GRUB_VGA_CR_OVERFLOW);
load_palette ();
grub_outb (0x10, 0x3c0);
grub_outb (0, 0x3c1);
grub_outb (0x14, 0x3c0);
grub_outb (0, 0x3c1);
grub_vga_sr_write (GRUB_VGA_SR_CLOCKING_MODE_8_DOT_CLOCK,
GRUB_VGA_SR_CLOCKING_MODE);
grub_vga_cr_write (14, GRUB_VGA_CR_CURSOR_START);
grub_vga_cr_write (15, GRUB_VGA_CR_CURSOR_END);
grub_outb (0x20, 0x3c0);
}

View file

@ -27,21 +27,37 @@
#define QEMU_CMOS_MEMSIZE_HIGH 0x35 #define QEMU_CMOS_MEMSIZE_HIGH 0x35
#define QEMU_CMOS_MEMSIZE_LOW 0x34 #define QEMU_CMOS_MEMSIZE_LOW 0x34
#define QEMU_CMOS_MEMSIZE2_HIGH 0x31
#define QEMU_CMOS_MEMSIZE2_LOW 0x30
#define min(a,b) ((a) > (b) ? (b) : (a)) #define min(a,b) ((a) > (b) ? (b) : (a))
extern char _start[]; extern char _start[];
extern char _end[]; extern char _end[];
grub_size_t grub_lower_mem, grub_upper_mem; static grub_uint64_t mem_size, above_4g;
grub_uint64_t mem_size;
void void
grub_machine_mmap_init () grub_machine_mmap_init ()
{ {
mem_size = grub_cmos_read (QEMU_CMOS_MEMSIZE_HIGH) << 24 | grub_cmos_read (QEMU_CMOS_MEMSIZE_LOW) << 16; mem_size = ((grub_uint64_t) grub_cmos_read (QEMU_CMOS_MEMSIZE_HIGH)) << 24
| ((grub_uint64_t) grub_cmos_read (QEMU_CMOS_MEMSIZE_LOW)) << 16;
if (mem_size > 0)
{
/* Don't ask... */ /* Don't ask... */
mem_size += (16 * 1024 * 1024); mem_size += (16 * 1024 * 1024);
}
else
{
mem_size
= ((((grub_uint64_t) grub_cmos_read (QEMU_CMOS_MEMSIZE2_HIGH)) << 18)
| ((grub_uint64_t) (grub_cmos_read (QEMU_CMOS_MEMSIZE2_LOW)) << 10))
+ 1024 * 1024;
}
above_4g = (((grub_uint64_t) grub_cmos_read (0x5b)) << 16)
| (((grub_uint64_t) grub_cmos_read (0x5c)) << 24)
| (((grub_uint64_t) grub_cmos_read (0x5d)) << 32);
} }
grub_err_t grub_err_t
@ -57,6 +73,12 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin
GRUB_MACHINE_MEMORY_RESERVED)) GRUB_MACHINE_MEMORY_RESERVED))
return 1; return 1;
/* Everything else is free. */
if (hook (0x100000,
min (mem_size, (grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE) - 0x100000,
GRUB_MACHINE_MEMORY_AVAILABLE))
return 1;
/* Protect boot.img, which contains the gdt. It is mapped at the top of memory /* Protect boot.img, which contains the gdt. It is mapped at the top of memory
(it is also mapped below 0x100000, but we already reserved that area). */ (it is also mapped below 0x100000, but we already reserved that area). */
if (hook ((grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE, if (hook ((grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE,
@ -64,9 +86,7 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin
GRUB_MACHINE_MEMORY_RESERVED)) GRUB_MACHINE_MEMORY_RESERVED))
return 1; return 1;
/* Everything else is free. */ if (above_4g != 0 && hook (0x100000000ULL, above_4g,
if (hook (0x100000,
min (mem_size, (grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE) - 0x100000,
GRUB_MACHINE_MEMORY_AVAILABLE)) GRUB_MACHINE_MEMORY_AVAILABLE))
return 1; return 1;

View file

@ -28,7 +28,7 @@
#include <grub/env.h> #include <grub/env.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/time.h> #include <grub/time.h>
#include <grub/machine/console.h> #include <grub/ieee1275/console.h>
#include <grub/ieee1275/ofdisk.h> #include <grub/ieee1275/ofdisk.h>
#include <grub/ieee1275/ieee1275.h> #include <grub/ieee1275/ieee1275.h>
#include <grub/offsets.h> #include <grub/offsets.h>
@ -224,11 +224,12 @@ grub_machine_init (void)
grub_ieee1275_init (); grub_ieee1275_init ();
grub_console_init (); grub_console_init_early ();
#ifdef __i386__ #ifdef __i386__
grub_get_extended_memory (); grub_get_extended_memory ();
#endif #endif
grub_claim_heap (); grub_claim_heap ();
grub_console_init_lately ();
grub_ofdisk_init (); grub_ofdisk_init ();
/* Process commandline. */ /* Process commandline. */

View file

@ -420,6 +420,7 @@ void
grub_reboot (void) grub_reboot (void)
{ {
grub_ieee1275_interpret ("reset-all", 0); grub_ieee1275_interpret ("reset-all", 0);
for (;;) ;
} }
#endif #endif
@ -431,4 +432,5 @@ grub_halt (void)
grub_ieee1275_interpret ("shut-down", 0); grub_ieee1275_interpret ("shut-down", 0);
grub_ieee1275_interpret ("power-off", 0); grub_ieee1275_interpret ("power-off", 0);
grub_ieee1275_interpret ("poweroff", 0); grub_ieee1275_interpret ("poweroff", 0);
for (;;) ;
} }

View file

@ -49,7 +49,14 @@ codestart:
/* Parse arguments. Has to be done before relocation. /* Parse arguments. Has to be done before relocation.
So need to do it in asm. */ So need to do it in asm. */
#ifdef GRUB_MACHINE_MIPS_YEELOONG #ifdef GRUB_MACHINE_MIPS_YEELOONG
move $s2, $zero
move $s3, $zero
move $s4, $zero
move $s5, $zero
/* $a2 has the environment. */ /* $a2 has the environment. */
addiu $t0, $a2, 1
beq $t0, $zero, argdone
move $t0, $a2 move $t0, $a2
argcont: argcont:
lw $t1, 0($t0) lw $t1, 0($t0)

View file

@ -26,6 +26,10 @@
#include <grub/time.h> #include <grub/time.h>
#include <grub/machine/kernel.h> #include <grub/machine/kernel.h>
#include <grub/machine/memory.h> #include <grub/machine/memory.h>
#include <grub/mips/loongson.h>
#include <grub/cs5536.h>
#include <grub/term.h>
#include <grub/machine/ec.h>
extern void grub_video_sm712_init (void); extern void grub_video_sm712_init (void);
extern void grub_video_init (void); extern void grub_video_init (void);
@ -33,6 +37,8 @@ extern void grub_bitmap_init (void);
extern void grub_font_init (void); extern void grub_font_init (void);
extern void grub_gfxterm_init (void); extern void grub_gfxterm_init (void);
extern void grub_at_keyboard_init (void); extern void grub_at_keyboard_init (void);
extern void grub_serial_init (void);
extern void grub_terminfo_init (void);
/* FIXME: use interrupt to count high. */ /* FIXME: use interrupt to count high. */
grub_uint64_t grub_uint64_t
@ -42,7 +48,7 @@ grub_get_rtc (void)
static grub_uint32_t last = 0; static grub_uint32_t last = 0;
grub_uint32_t low; grub_uint32_t low;
asm volatile ("mfc0 %0, $9": "=r" (low)); asm volatile ("mfc0 %0, " GRUB_CPU_LOONGSON_COP0_TIMER_COUNT : "=r" (low));
if (low < last) if (low < last)
high++; high++;
last = low; last = low;
@ -62,25 +68,147 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
static void
init_pci (void)
{
auto int NESTED_FUNC_ATTR set_card (grub_pci_device_t dev, grub_pci_id_t pciid);
int NESTED_FUNC_ATTR set_card (grub_pci_device_t dev, grub_pci_id_t pciid)
{
grub_pci_address_t addr;
/* FIXME: autoscan for BARs and devices. */
switch (pciid)
{
case GRUB_YEELOONG_OHCI_PCIID:
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
grub_pci_write (addr, 0x5025000);
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE
| GRUB_PCI_COMMAND_PARITY_ERROR
| GRUB_PCI_COMMAND_BUS_MASTER
| GRUB_PCI_COMMAND_MEM_ENABLED);
addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS);
grub_pci_write_word (addr, 0x0200 | GRUB_PCI_STATUS_CAPABILITIES);
break;
case GRUB_YEELOONG_EHCI_PCIID:
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
grub_pci_write (addr, 0x5026000);
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE
| GRUB_PCI_COMMAND_PARITY_ERROR
| GRUB_PCI_COMMAND_BUS_MASTER
| GRUB_PCI_COMMAND_MEM_ENABLED);
addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS);
grub_pci_write_word (addr, (1 << GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT)
| GRUB_PCI_STATUS_CAPABILITIES);
break;
}
return 0;
}
*((volatile grub_uint32_t *) GRUB_CPU_LOONGSON_PCI_HIT1_SEL_LO) = 0x8000000c;
*((volatile grub_uint32_t *) GRUB_CPU_LOONGSON_PCI_HIT1_SEL_HI) = 0xffffffff;
/* Setup PCI controller. */
*((volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER
+ GRUB_PCI_REG_COMMAND))
= GRUB_PCI_COMMAND_PARITY_ERROR | GRUB_PCI_COMMAND_BUS_MASTER
| GRUB_PCI_COMMAND_MEM_ENABLED;
*((volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER
+ GRUB_PCI_REG_STATUS))
= (1 << GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT)
| GRUB_PCI_STATUS_FAST_B2B_CAPABLE | GRUB_PCI_STATUS_66MHZ_CAPABLE
| GRUB_PCI_STATUS_CAPABILITIES;
*((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER
+ GRUB_PCI_REG_CACHELINE)) = 0xff;
*((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER
+ GRUB_PCI_REG_ADDRESS_REG0))
= 0x80000000 | GRUB_PCI_ADDR_MEM_TYPE_64 | GRUB_PCI_ADDR_MEM_PREFETCH;
*((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER
+ GRUB_PCI_REG_ADDRESS_REG1)) = 0;
grub_pci_iterate (set_card);
}
void void
grub_machine_init (void) grub_machine_init (void)
{ {
grub_addr_t modend; grub_addr_t modend;
/* FIXME: measure this. */
if (grub_arch_busclock == 0)
{
grub_arch_busclock = 66000000;
grub_arch_cpuclock = 797000000;
}
grub_install_get_time_ms (grub_rtc_get_time_ms);
if (grub_arch_memsize == 0)
{
grub_port_t smbbase;
grub_err_t err;
grub_pci_device_t dev;
struct grub_smbus_spd spd;
unsigned totalmem;
int i;
if (!grub_cs5536_find (&dev))
grub_fatal ("No CS5536 found\n");
err = grub_cs5536_init_smbus (dev, 0x7ff, &smbbase);
if (err)
grub_fatal ("Couldn't init SMBus: %s\n", grub_errmsg);
/* Yeeloong has only one memory slot. */
err = grub_cs5536_read_spd (smbbase, GRUB_SMB_RAM_START_ADDR, &spd);
if (err)
grub_fatal ("Couldn't read SPD: %s\n", grub_errmsg);
for (i = 5; i < 13; i++)
if (spd.ddr2.rank_capacity & (1 << (i & 7)))
break;
/* Something is wrong. */
if (i == 13)
totalmem = 256;
else
totalmem = ((spd.ddr2.num_of_ranks
& GRUB_SMBUS_SPD_MEMORY_NUM_OF_RANKS_MASK) + 1) << (i + 2);
if (totalmem >= 256)
{
grub_arch_memsize = 256;
grub_arch_highmemsize = totalmem - 256;
}
else
{
grub_arch_memsize = (totalmem >> 20);
grub_arch_highmemsize = 0;
}
grub_cs5536_init_geode (dev);
init_pci ();
}
modend = grub_modules_get_end (); modend = grub_modules_get_end ();
grub_mm_init_region ((void *) modend, (grub_arch_memsize << 20) grub_mm_init_region ((void *) modend, (grub_arch_memsize << 20)
- (modend - GRUB_ARCH_LOWMEMVSTART)); - (modend - GRUB_ARCH_LOWMEMVSTART));
/* FIXME: use upper memory as well. */ /* 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 /* Initialize output terminal (can't be done earlier, as gfxterm
relies on a working heap. */ relies on a working heap. */
grub_video_sm712_init ();
grub_video_init (); grub_video_init ();
grub_video_sm712_init ();
grub_bitmap_init (); grub_bitmap_init ();
grub_font_init (); grub_font_init ();
grub_gfxterm_init (); grub_gfxterm_init ();
grub_at_keyboard_init (); grub_at_keyboard_init ();
grub_terminfo_init ();
grub_serial_init ();
} }
void void
@ -89,20 +217,29 @@ grub_machine_fini (void)
} }
void void
grub_exit (void) grub_halt (void)
{ {
grub_outb (grub_inb (GRUB_CPU_LOONGSON_GPIOCFG)
& ~GRUB_CPU_LOONGSON_SHUTDOWN_GPIO, GRUB_CPU_LOONGSON_GPIOCFG);
grub_printf ("Shutdown failed\n");
grub_refresh ();
while (1); while (1);
} }
void void
grub_halt (void) grub_exit (void)
{ {
while (1); grub_halt ();
} }
void void
grub_reboot (void) grub_reboot (void)
{ {
grub_write_ec (GRUB_MACHINE_EC_COMMAND_REBOOT);
grub_printf ("Reboot failed\n");
grub_refresh ();
while (1); while (1);
} }

View file

@ -142,19 +142,6 @@ grub_printf_ (const char *fmt, ...)
return ret; return ret;
} }
int
grub_puts (const char *s)
{
while (*s)
{
grub_putchar (*s);
s++;
}
grub_putchar ('\n');
return 1; /* Cannot fail. */
}
int int
grub_puts_ (const char *s) grub_puts_ (const char *s)
{ {
@ -200,13 +187,37 @@ grub_real_dprintf (const char *file, const int line, const char *condition,
} }
} }
#define PREALLOC_SIZE 255
int int
grub_vprintf (const char *fmt, va_list args) grub_vprintf (const char *fmt, va_list args)
{ {
int ret; grub_size_t s;
static char buf[PREALLOC_SIZE + 1];
char *curbuf = buf;
ret = grub_vsnprintf_real (0, 0, fmt, args); s = grub_vsnprintf_real (buf, PREALLOC_SIZE, fmt, args);
return ret; if (s > PREALLOC_SIZE)
{
curbuf = grub_malloc (s + 1);
if (!curbuf)
{
grub_errno = GRUB_ERR_NONE;
buf[PREALLOC_SIZE - 3] = '.';
buf[PREALLOC_SIZE - 2] = '.';
buf[PREALLOC_SIZE - 1] = '.';
buf[PREALLOC_SIZE] = 0;
}
else
s = grub_vsnprintf_real (curbuf, s, fmt, args);
}
grub_xputs (curbuf);
if (curbuf != buf)
grub_free (curbuf);
return s;
} }
int int
@ -648,14 +659,9 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list ar
auto void write_fill (const char ch, int n); auto void write_fill (const char ch, int n);
void write_char (unsigned char ch) void write_char (unsigned char ch)
{
if (str)
{ {
if (count < max_len) if (count < max_len)
*str++ = ch; *str++ = ch;
}
else
grub_putchar (ch);
count++; count++;
} }
@ -872,7 +878,6 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list ar
} }
} }
if (str)
*str = '\0'; *str = '\0';
return count; return count;
@ -906,8 +911,6 @@ grub_snprintf (char *str, grub_size_t n, const char *fmt, ...)
return ret; return ret;
} }
#define PREALLOC_SIZE 255
char * char *
grub_xvasprintf (const char *fmt, va_list ap) grub_xvasprintf (const char *fmt, va_list ap)
{ {
@ -942,100 +945,6 @@ grub_xasprintf (const char *fmt, ...)
return ret; return ret;
} }
/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string.
Return the number of characters converted. DEST must be able to hold
at least DESTSIZE characters.
If SRCEND is not NULL, then *SRCEND is set to the next byte after the
last byte used in SRC. */
grub_size_t
grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
const grub_uint8_t *src, grub_size_t srcsize,
const grub_uint8_t **srcend)
{
grub_uint32_t *p = dest;
int count = 0;
grub_uint32_t code = 0;
if (srcend)
*srcend = src;
while (srcsize && destsize)
{
grub_uint32_t c = *src++;
if (srcsize != (grub_size_t)-1)
srcsize--;
if (count)
{
if ((c & 0xc0) != 0x80)
{
/* invalid */
code = '?';
/* Character c may be valid, don't eat it. */
src--;
if (srcsize != (grub_size_t)-1)
srcsize++;
count = 0;
}
else
{
code <<= 6;
code |= (c & 0x3f);
count--;
}
}
else
{
if (c == 0)
break;
if ((c & 0x80) == 0x00)
code = c;
else if ((c & 0xe0) == 0xc0)
{
count = 1;
code = c & 0x1f;
}
else if ((c & 0xf0) == 0xe0)
{
count = 2;
code = c & 0x0f;
}
else if ((c & 0xf8) == 0xf0)
{
count = 3;
code = c & 0x07;
}
else if ((c & 0xfc) == 0xf8)
{
count = 4;
code = c & 0x03;
}
else if ((c & 0xfe) == 0xfc)
{
count = 5;
code = c & 0x01;
}
else
{
/* invalid */
code = '?';
count = 0;
}
}
if (count == 0)
{
*p++ = code;
destsize--;
}
}
if (srcend)
*srcend = src;
return p - dest;
}
/* Abort GRUB. This function does not return. */ /* Abort GRUB. This function does not return. */
void void
grub_abort (void) grub_abort (void)

View file

@ -34,6 +34,7 @@ grub_rescue_read_line (char **line, int cont)
{ {
int c; int c;
int pos = 0; int pos = 0;
char str[4];
grub_printf ((cont) ? "> " : "grub rescue> "); grub_printf ((cont) ? "> " : "grub rescue> ");
grub_memset (linebuf, 0, GRUB_RESCUE_BUF_SIZE); grub_memset (linebuf, 0, GRUB_RESCUE_BUF_SIZE);
@ -44,24 +45,28 @@ grub_rescue_read_line (char **line, int cont)
{ {
if (pos < GRUB_RESCUE_BUF_SIZE - 1) if (pos < GRUB_RESCUE_BUF_SIZE - 1)
{ {
str[0] = c;
str[1] = 0;
linebuf[pos++] = c; linebuf[pos++] = c;
grub_putchar (c); grub_xputs (str);
} }
} }
else if (c == '\b') else if (c == '\b')
{ {
if (pos > 0) if (pos > 0)
{ {
str[0] = c;
str[1] = ' ';
str[2] = c;
str[3] = 0;
linebuf[--pos] = 0; linebuf[--pos] = 0;
grub_putchar (c); grub_xputs (str);
grub_putchar (' ');
grub_putchar (c);
} }
} }
grub_refresh (); grub_refresh ();
} }
grub_putchar ('\n'); grub_xputs ("\n");
grub_refresh (); grub_refresh ();
*line = grub_strdup (linebuf); *line = grub_strdup (linebuf);

View file

@ -24,7 +24,7 @@
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/time.h> #include <grub/time.h>
#include <grub/machine/boot.h> #include <grub/machine/boot.h>
#include <grub/machine/console.h> #include <grub/ieee1275/console.h>
#include <grub/machine/kernel.h> #include <grub/machine/kernel.h>
#include <grub/machine/time.h> #include <grub/machine/time.h>
#include <grub/ieee1275/ofdisk.h> #include <grub/ieee1275/ofdisk.h>
@ -155,8 +155,9 @@ void
grub_machine_init (void) grub_machine_init (void)
{ {
grub_ieee1275_init (); grub_ieee1275_init ();
grub_console_init (); grub_console_init_early ();
grub_heap_init (); grub_heap_init ();
grub_console_init_lately ();
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0); grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
grub_ofdisk_init (); grub_ofdisk_init ();

View file

@ -28,53 +28,54 @@ struct grub_term_input *grub_term_inputs_disabled;
struct grub_term_output *grub_term_outputs; struct grub_term_output *grub_term_outputs;
struct grub_term_input *grub_term_inputs; struct grub_term_input *grub_term_inputs;
void (*grub_newline_hook) (void) = NULL;
/* Put a Unicode character. */ /* Put a Unicode character. */
void static void
grub_putcode (grub_uint32_t code, struct grub_term_output *term) grub_putcode_dumb (grub_uint32_t code,
struct grub_term_output *term)
{ {
struct grub_unicode_glyph c =
{
.base = code,
.variant = 0,
.attributes = 0,
.ncomb = 0,
.combining = 0,
.estimated_width = 1
};
if (code == '\t' && term->getxy) if (code == '\t' && term->getxy)
{ {
int n; int n;
n = 8 - ((term->getxy () >> 8) & 7); n = 8 - ((term->getxy (term) >> 8) & 7);
while (n--) while (n--)
grub_putcode (' ', term); grub_putcode_dumb (' ', term);
return; return;
} }
(term->putchar) (code); (term->putchar) (term, &c);
if (code == '\n') if (code == '\n')
(term->putchar) ('\r'); grub_putcode_dumb ('\r', term);
} }
/* Put a character. C is one byte of a UTF-8 stream. static void
This function gathers bytes until a valid Unicode character is found. */ grub_xputs_dumb (const char *str)
void
grub_putchar (int c)
{ {
static grub_size_t size = 0; for (; *str; str++)
static grub_uint8_t buf[6];
grub_uint8_t *rest;
grub_uint32_t code;
buf[size++] = c;
while (grub_utf8_to_ucs4 (&code, 1, buf, size, (const grub_uint8_t **) &rest)
!= 0)
{ {
struct grub_term_output *term; grub_term_output_t term;
size -= rest - buf; grub_uint32_t code = *str;
grub_memmove (buf, rest, size); if (code > 0x7f)
code = '?';
FOR_ACTIVE_TERM_OUTPUTS(term) FOR_ACTIVE_TERM_OUTPUTS(term)
grub_putcode (code, term); grub_putcode_dumb (code, term);
if (code == '\n' && grub_newline_hook)
grub_newline_hook ();
} }
} }
void (*grub_xputs) (const char *str) = grub_xputs_dumb;
int int
grub_getkey (void) grub_getkey (void)
{ {
@ -86,9 +87,9 @@ grub_getkey (void)
{ {
FOR_ACTIVE_TERM_INPUTS(term) FOR_ACTIVE_TERM_INPUTS(term)
{ {
int key = term->checkkey (); int key = term->checkkey (term);
if (key != -1) if (key != -1)
return term->getkey (); return term->getkey (term);
} }
grub_cpu_idle (); grub_cpu_idle ();
@ -102,7 +103,7 @@ grub_checkkey (void)
FOR_ACTIVE_TERM_INPUTS(term) FOR_ACTIVE_TERM_INPUTS(term)
{ {
int key = term->checkkey (); int key = term->checkkey (term);
if (key != -1) if (key != -1)
return key; return key;
} }
@ -119,38 +120,12 @@ grub_getkeystatus (void)
FOR_ACTIVE_TERM_INPUTS(term) FOR_ACTIVE_TERM_INPUTS(term)
{ {
if (term->getkeystatus) if (term->getkeystatus)
status |= term->getkeystatus (); status |= term->getkeystatus (term);
} }
return status; return status;
} }
void
grub_cls (void)
{
struct grub_term_output *term;
FOR_ACTIVE_TERM_OUTPUTS(term)
{
if ((term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
{
grub_putcode ('\n', term);
grub_term_refresh (term);
}
else
(term->cls) ();
}
}
void
grub_setcolorstate (grub_term_color_state state)
{
struct grub_term_output *term;
FOR_ACTIVE_TERM_OUTPUTS(term)
grub_term_setcolorstate (term, state);
}
void void
grub_refresh (void) grub_refresh (void)
{ {

View file

@ -144,21 +144,8 @@ grub_arg_show_help (grub_extcmd_t cmd)
} }
} }
const char *doc = _(opt->doc); /* FIXME: add spacing back. */
for (;;) grub_xputs (_(opt->doc));
{
while (spacing-- > 0)
grub_putchar (' ');
while (*doc && *doc != '\n')
grub_putchar (*doc++);
grub_putchar ('\n');
if (! *doc)
break;
doc++;
spacing = 4 + 20;
}
switch (opt->shortarg) switch (opt->shortarg)
{ {

View file

@ -1,269 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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/>.
*/
/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
bytes (if SRCSIZE is -1, it is ignored) in length to a UTF-16 string.
Return the number of characters converted. DEST must be able to hold
at least DESTSIZE characters. If an invalid sequence is found, return -1.
If SRCEND is not NULL, then *SRCEND is set to the next byte after the
last byte used in SRC. */
#include <grub/charset.h>
#include <grub/mm.h>
#include <grub/misc.h>
grub_ssize_t
grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
const grub_uint8_t *src, grub_size_t srcsize,
const grub_uint8_t **srcend)
{
grub_uint16_t *p = dest;
int count = 0;
grub_uint32_t code = 0;
if (srcend)
*srcend = src;
while (srcsize && destsize)
{
grub_uint32_t c = *src++;
if (srcsize != (grub_size_t)-1)
srcsize--;
if (count)
{
if ((c & GRUB_UINT8_2_LEADINGBITS) != GRUB_UINT8_1_LEADINGBIT)
{
/* invalid */
return -1;
}
else
{
code <<= 6;
code |= (c & GRUB_UINT8_6_TRAILINGBITS);
count--;
}
}
else
{
if (c == 0)
break;
if ((c & GRUB_UINT8_1_LEADINGBIT) == 0)
code = c;
else if ((c & GRUB_UINT8_3_LEADINGBITS) == GRUB_UINT8_2_LEADINGBITS)
{
count = 1;
code = c & GRUB_UINT8_5_TRAILINGBITS;
}
else if ((c & GRUB_UINT8_4_LEADINGBITS) == GRUB_UINT8_3_LEADINGBITS)
{
count = 2;
code = c & GRUB_UINT8_4_TRAILINGBITS;
}
else if ((c & GRUB_UINT8_5_LEADINGBITS) == GRUB_UINT8_4_LEADINGBITS)
{
count = 3;
code = c & GRUB_UINT8_3_TRAILINGBITS;
}
else if ((c & GRUB_UINT8_6_LEADINGBITS) == GRUB_UINT8_5_LEADINGBITS)
{
count = 4;
code = c & GRUB_UINT8_2_TRAILINGBITS;
}
else if ((c & GRUB_UINT8_7_LEADINGBITS) == GRUB_UINT8_6_LEADINGBITS)
{
count = 5;
code = c & GRUB_UINT8_1_TRAILINGBIT;
}
else
return -1;
}
if (count == 0)
{
if (destsize < 2 && code >= GRUB_UCS2_LIMIT)
break;
if (code >= GRUB_UCS2_LIMIT)
{
*p++ = GRUB_UTF16_UPPER_SURROGATE (code);
*p++ = GRUB_UTF16_LOWER_SURROGATE (code);
destsize -= 2;
}
else
{
*p++ = code;
destsize--;
}
}
}
if (srcend)
*srcend = src;
return p - dest;
}
/* Convert UCS-4 to UTF-8. */
char *
grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size)
{
grub_size_t remaining;
grub_uint32_t *ptr;
grub_size_t cnt = 0;
grub_uint8_t *ret, *dest;
remaining = size;
ptr = src;
while (remaining--)
{
grub_uint32_t code = *ptr++;
if (code <= 0x007F)
cnt++;
else if (code <= 0x07FF)
cnt += 2;
else if ((code >= 0xDC00 && code <= 0xDFFF)
|| (code >= 0xD800 && code <= 0xDBFF))
/* No surrogates in UCS-4... */
cnt++;
else
cnt += 3;
}
cnt++;
ret = grub_malloc (cnt);
if (!ret)
return 0;
dest = ret;
remaining = size;
ptr = src;
while (remaining--)
{
grub_uint32_t code = *ptr++;
if (code <= 0x007F)
*dest++ = code;
else if (code <= 0x07FF)
{
*dest++ = (code >> 6) | 0xC0;
*dest++ = (code & 0x3F) | 0x80;
}
else if ((code >= 0xDC00 && code <= 0xDFFF)
|| (code >= 0xD800 && code <= 0xDBFF))
{
/* No surrogates in UCS-4... */
*dest++ = '?';
}
else
{
*dest++ = (code >> 12) | 0xE0;
*dest++ = ((code >> 6) & 0x3F) | 0x80;
*dest++ = (code & 0x3F) | 0x80;
}
}
*dest = 0;
return (char *) ret;
}
int
grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize)
{
grub_uint32_t code = 0;
int count = 0;
while (srcsize)
{
grub_uint32_t c = *src++;
if (srcsize != (grub_size_t)-1)
srcsize--;
if (count)
{
if ((c & 0xc0) != 0x80)
{
/* invalid */
return 0;
}
else
{
code <<= 6;
code |= (c & 0x3f);
count--;
}
}
else
{
if (c == 0)
break;
if ((c & 0x80) == 0x00)
code = c;
else if ((c & 0xe0) == 0xc0)
{
count = 1;
code = c & 0x1f;
}
else if ((c & 0xf0) == 0xe0)
{
count = 2;
code = c & 0x0f;
}
else if ((c & 0xf8) == 0xf0)
{
count = 3;
code = c & 0x07;
}
else if ((c & 0xfc) == 0xf8)
{
count = 4;
code = c & 0x03;
}
else if ((c & 0xfe) == 0xfc)
{
count = 5;
code = c & 0x01;
}
else
return 0;
}
}
return 1;
}
int
grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
grub_uint32_t **last_position)
{
grub_size_t msg_len = grub_strlen (msg);
*unicode_msg = grub_malloc (grub_strlen (msg) * sizeof (grub_uint32_t));
if (!*unicode_msg)
{
grub_printf ("utf8_to_ucs4 ERROR1: %s", msg);
return -1;
}
msg_len = grub_utf8_to_ucs4 (*unicode_msg, msg_len,
(grub_uint8_t *) msg, -1, 0);
*last_position = *unicode_msg + msg_len;
return msg_len;
}

View file

@ -445,7 +445,7 @@ grub_password_get (char buf[], unsigned buf_size)
grub_memset (buf + cur_len, 0, buf_size - cur_len); grub_memset (buf + cur_len, 0, buf_size - cur_len);
grub_putchar ('\n'); grub_xputs ("\n");
grub_refresh (); grub_refresh ();
return (key != '\e'); return (key != '\e');

View file

@ -29,10 +29,11 @@
#include <grub/cpu/linux.h> #include <grub/cpu/linux.h>
#include <grub/efi/api.h> #include <grub/efi/api.h>
#include <grub/efi/efi.h> #include <grub/efi/efi.h>
#include <grub/efi/uga_draw.h>
#include <grub/pci.h>
#include <grub/command.h> #include <grub/command.h>
#include <grub/memory.h> #include <grub/memory.h>
#include <grub/env.h>
#include <grub/video.h>
#include <grub/time.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#define GRUB_LINUX_CL_OFFSET 0x1000 #define GRUB_LINUX_CL_OFFSET 0x1000
@ -286,6 +287,67 @@ grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num,
} }
} }
static grub_err_t
grub_linux_setup_video (struct linux_kernel_params *params)
{
struct grub_video_mode_info mode_info;
void *framebuffer;
grub_err_t err;
err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
if (err)
return err;
params->lfb_width = mode_info.width;
params->lfb_height = mode_info.height;
params->lfb_depth = mode_info.bpp;
params->lfb_line_len = mode_info.pitch;
params->lfb_base = (grub_size_t) framebuffer;
params->lfb_size = ALIGN_UP (params->lfb_line_len * params->lfb_height,
65536);
params->red_mask_size = mode_info.red_mask_size;
params->red_field_pos = mode_info.red_field_pos;
params->green_mask_size = mode_info.green_mask_size;
params->green_field_pos = mode_info.green_field_pos;
params->blue_mask_size = mode_info.blue_mask_size;
params->blue_field_pos = mode_info.blue_field_pos;
params->reserved_mask_size = mode_info.reserved_mask_size;
params->reserved_field_pos = mode_info.reserved_field_pos;
params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
#ifdef GRUB_MACHINE_PCBIOS
/* VESA packed modes may come with zeroed mask sizes, which need
to be set here according to DAC Palette width. If we don't,
this results in Linux displaying a black screen. */
if (mode_info.bpp <= 8)
{
struct grub_vbe_info_block controller_info;
int status;
int width = 8;
status = grub_vbe_bios_get_controller_info (&controller_info);
if (status == GRUB_VBE_STATUS_OK &&
(controller_info.capabilities & GRUB_VBE_CAPABILITY_DACWIDTH))
status = grub_vbe_bios_set_dac_palette_width (&width);
if (status != GRUB_VBE_STATUS_OK)
/* 6 is default after mode reset. */
width = 6;
params->red_mask_size = params->green_mask_size
= params->blue_mask_size = width;
params->reserved_mask_size = 0;
}
#endif
return 0;
}
#ifdef __x86_64__ #ifdef __x86_64__
extern grub_uint8_t grub_linux_trampoline_start[]; extern grub_uint8_t grub_linux_trampoline_start[];
extern grub_uint8_t grub_linux_trampoline_end[]; extern grub_uint8_t grub_linux_trampoline_end[];
@ -300,6 +362,9 @@ grub_linux_boot (void)
grub_efi_uintn_t desc_size; grub_efi_uintn_t desc_size;
grub_efi_uint32_t desc_version; grub_efi_uint32_t desc_version;
int e820_num; int e820_num;
const char *modevar;
char *tmp;
grub_err_t err;
params = real_mode_mem; params = real_mode_mem;
@ -353,6 +418,35 @@ grub_linux_boot (void)
grub_mmap_iterate (hook); grub_mmap_iterate (hook);
params->mmap_size = e820_num; params->mmap_size = e820_num;
grub_dprintf ("linux", "Trampoline at %p. code32=%x, real_mode_mem=%p\n",
((char *) prot_mode_mem + (prot_mode_pages << 12)),
(unsigned) params->code32_start, real_mode_mem);
modevar = grub_env_get ("gfxpayload");
/* Now all graphical modes are acceptable.
May change in future if we have modes without framebuffer. */
if (modevar && *modevar != 0)
{
tmp = grub_xasprintf ("%s;auto", modevar);
if (! tmp)
return grub_errno;
err = grub_video_set_mode (tmp, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
grub_free (tmp);
}
else
err = grub_video_set_mode ("auto", GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
if (!err)
err = grub_linux_setup_video (params);
if (err)
{
grub_print_error ();
grub_printf ("Booting however\n");
grub_errno = GRUB_ERR_NONE;
}
mmap_size = find_mmap_size (); mmap_size = find_mmap_size ();
if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key, if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
&desc_size, &desc_version) <= 0) &desc_size, &desc_version) <= 0)
@ -425,174 +519,6 @@ grub_linux_unload (void)
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID;
#define RGB_MASK 0xffffff
#define RGB_MAGIC 0x121314
#define LINE_MIN 800
#define LINE_MAX 4096
#define FBTEST_STEP (0x10000 >> 2)
#define FBTEST_COUNT 8
static int
find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
{
grub_uint32_t *base = (grub_uint32_t *) (grub_target_addr_t) *fb_base;
int i;
for (i = 0; i < FBTEST_COUNT; i++, base += FBTEST_STEP)
{
if ((*base & RGB_MASK) == RGB_MAGIC)
{
int j;
for (j = LINE_MIN; j <= LINE_MAX; j++)
{
if ((base[j] & RGB_MASK) == RGB_MAGIC)
{
*fb_base = (grub_uint32_t) (grub_target_addr_t) base;
*line_len = j << 2;
return 1;
}
}
break;
}
}
return 0;
}
static int
find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len)
{
int found = 0;
auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
grub_pci_id_t pciid);
int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
grub_pci_id_t pciid)
{
grub_pci_address_t addr;
addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
if (grub_pci_read (addr) >> 24 == 0x3)
{
int i;
grub_printf ("Display controller: %d:%d.%d\nDevice id: %x\n",
grub_pci_get_bus (dev), grub_pci_get_device (dev),
grub_pci_get_function (dev), pciid);
addr += 8;
for (i = 0; i < 6; i++, addr += 4)
{
grub_uint32_t old_bar1, old_bar2, type;
grub_uint64_t base64;
old_bar1 = grub_pci_read (addr);
if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO))
continue;
type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK;
if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
{
if (i == 5)
break;
old_bar2 = grub_pci_read (addr + 4);
}
else
old_bar2 = 0;
base64 = old_bar2;
base64 <<= 32;
base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK);
grub_printf ("%s(%d): 0x%llx\n",
((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ?
"VMEM" : "MMIO"), i,
(unsigned long long) base64);
if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found))
{
*fb_base = base64;
if (find_line_len (fb_base, line_len))
found++;
}
if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
{
i++;
addr += 4;
}
}
}
return found;
}
grub_pci_iterate (find_card);
return found;
}
static int
grub_linux_setup_video (struct linux_kernel_params *params)
{
grub_efi_uga_draw_protocol_t *c;
grub_uint32_t width, height, depth, rate, pixel, fb_base, line_len;
int ret;
c = grub_efi_locate_protocol (&uga_draw_guid, 0);
if (! c)
return 1;
if (efi_call_5 (c->get_mode, c, &width, &height, &depth, &rate))
return 1;
grub_printf ("Video mode: %ux%u-%u@%u\n", width, height, depth, rate);
grub_efi_set_text_mode (0);
pixel = RGB_MAGIC;
efi_call_10 (c->blt, c, (struct grub_efi_uga_pixel *) &pixel,
GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0);
ret = find_framebuf (&fb_base, &line_len);
grub_efi_set_text_mode (1);
if (! ret)
{
grub_printf ("Can\'t find frame buffer address\n");
return 1;
}
grub_printf ("Frame buffer base: 0x%x\n", fb_base);
grub_printf ("Video line length: %d\n", line_len);
params->lfb_width = width;
params->lfb_height = height;
params->lfb_depth = depth;
params->lfb_line_len = line_len;
params->lfb_base = fb_base;
params->lfb_size = ALIGN_UP (line_len * params->lfb_height, 65536);
params->red_mask_size = 8;
params->red_field_pos = 16;
params->green_mask_size = 8;
params->green_field_pos = 8;
params->blue_mask_size = 8;
params->blue_field_pos = 0;
params->reserved_mask_size = 8;
params->reserved_field_pos = 24;
params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA;
params->vid_mode = 0x338; /* 1024x768x32 */
return 0;
}
static grub_err_t static grub_err_t
grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[]) int argc, char *argv[])
@ -806,11 +732,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE); grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
/* XXX there is no way to know if the kernel really supports EFI. */ /* XXX there is no way to know if the kernel really supports EFI. */
grub_printf (" [Linux-bzImage, setup=0x%x, size=0x%x]\n", grub_dprintf ("linux", "bzImage, setup=0x%x, size=0x%x\n",
(unsigned) real_size, (unsigned) prot_size); (unsigned) real_size, (unsigned) prot_size);
grub_linux_setup_video (params);
/* Detect explicitly specified memory size, if any. */ /* Detect explicitly specified memory size, if any. */
linux_mem_size = 0; linux_mem_size = 0;
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++)
@ -876,7 +800,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
if (grub_errno == GRUB_ERR_NONE) if (grub_errno == GRUB_ERR_NONE)
{ {
grub_loader_set (grub_linux_boot, grub_linux_unload, 1); grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
loaded = 1; loaded = 1;
} }
@ -989,7 +913,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
goto fail; goto fail;
} }
grub_printf (" [Initrd, addr=0x%x, size=0x%x]\n", grub_dprintf ("linux", "Initrd, addr=0x%x, size=0x%x\n",
(unsigned) addr, (unsigned) size); (unsigned) addr, (unsigned) size);
lh->ramdisk_image = addr; lh->ramdisk_image = addr;

View file

@ -1,178 +0,0 @@
/*
* 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/env.h>
#include <grub/xnu.h>
#include <grub/cpu/xnu.h>
#include <grub/efi/api.h>
#include <grub/efi/efi.h>
#include <grub/efi/uga_draw.h>
#include <grub/pci.h>
#include <grub/misc.h>
/* Setup video for xnu. Big parts are copied from linux.c. */
static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID;
#define RGB_MASK 0xffffff
#define RGB_MAGIC 0x121314
#define LINE_MIN 800
#define LINE_MAX 4096
#define FBTEST_STEP (0x10000 >> 2)
#define FBTEST_COUNT 8
static int
find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
{
grub_uint32_t *base = (grub_uint32_t *) (grub_target_addr_t) *fb_base;
int i;
for (i = 0; i < FBTEST_COUNT; i++, base += FBTEST_STEP)
{
if ((*base & RGB_MASK) == RGB_MAGIC)
{
int j;
for (j = LINE_MIN; j <= LINE_MAX; j++)
{
if ((base[j] & RGB_MASK) == RGB_MAGIC)
{
*fb_base = (grub_uint32_t) (grub_target_addr_t) base;
*line_len = j << 2;
return 1;
}
}
break;
}
}
return 0;
}
static int
find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len)
{
int found = 0;
auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
grub_pci_id_t pciid);
int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
grub_pci_id_t pciid)
{
grub_pci_address_t addr;
addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
if (grub_pci_read (addr) >> 24 == 0x3)
{
int i;
grub_printf ("Display controller: %d:%d.%d\nDevice id: %x\n",
grub_pci_get_bus (dev), grub_pci_get_device (dev),
grub_pci_get_function (dev), pciid);
addr += 8;
for (i = 0; i < 6; i++, addr += 4)
{
grub_uint32_t old_bar1, old_bar2, type;
grub_uint64_t base64;
old_bar1 = grub_pci_read (addr);
if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO))
continue;
type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK;
if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
{
if (i == 5)
break;
old_bar2 = grub_pci_read (addr + 4);
}
else
old_bar2 = 0;
base64 = old_bar2;
base64 <<= 32;
base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK);
grub_printf ("%s(%d): 0x%llx\n",
((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ?
"VMEM" : "MMIO"), i,
(unsigned long long) base64);
if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found))
{
*fb_base = base64;
if (find_line_len (fb_base, line_len))
found++;
}
if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
{
i++;
addr += 4;
}
}
}
return found;
}
grub_pci_iterate (find_card);
return found;
}
grub_err_t
grub_xnu_set_video (struct grub_xnu_boot_params *params)
{
grub_efi_uga_draw_protocol_t *c;
grub_uint32_t width, height, depth, rate, pixel, fb_base, line_len;
int ret;
c = grub_efi_locate_protocol (&uga_draw_guid, 0);
if (! c)
return grub_error (GRUB_ERR_IO, "couldn't find UGADraw");
if (efi_call_5 (c->get_mode, c, &width, &height, &depth, &rate))
return grub_error (GRUB_ERR_IO, "couldn't retrieve video mode");
grub_printf ("Video mode: %ux%u-%u@%u\n", width, height, depth, rate);
grub_efi_set_text_mode (0);
pixel = RGB_MAGIC;
efi_call_10 (c->blt, c, (struct grub_efi_uga_pixel *) &pixel,
GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0);
ret = find_framebuf (&fb_base, &line_len);
grub_efi_set_text_mode (1);
if (! ret)
return grub_error (GRUB_ERR_IO, "can\'t find frame buffer address");
grub_printf ("Frame buffer base: 0x%x\n", fb_base);
grub_printf ("Video line length: %d\n", line_len);
params->lfb_width = width;
params->lfb_height = height;
params->lfb_depth = depth;
params->lfb_line_len = line_len;
params->lfb_mode = GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
params->lfb_base = fb_base;
return GRUB_ERR_NONE;
}

View file

@ -205,7 +205,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
real_size = setup_sects << GRUB_DISK_SECTOR_BITS; real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE; prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
grub_printf (" [Linux-%s, setup=0x%x, size=0x%x]\n", grub_dprintf ("linux", "Linux-%s, setup=0x%x, size=0x%x\n",
"bzImage", real_size, prot_size); "bzImage", real_size, prot_size);
grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE); grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);

View file

@ -295,8 +295,8 @@ retrieve_video_parameters (struct multiboot_info *mbi,
else else
{ {
mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB; mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB;
mbi->framebuffer_red_field_position = mode_info.green_field_pos; mbi->framebuffer_red_field_position = mode_info.red_field_pos;
mbi->framebuffer_red_mask_size = mode_info.green_mask_size; mbi->framebuffer_red_mask_size = mode_info.red_mask_size;
mbi->framebuffer_green_field_position = mode_info.green_field_pos; mbi->framebuffer_green_field_position = mode_info.green_field_pos;
mbi->framebuffer_green_mask_size = mode_info.green_mask_size; mbi->framebuffer_green_mask_size = mode_info.green_mask_size;
mbi->framebuffer_blue_field_position = mode_info.blue_field_pos; mbi->framebuffer_blue_field_position = mode_info.blue_field_pos;

View file

@ -182,8 +182,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail; goto fail;
} }
grub_printf (" [Linux-%s, setup=0x%x, size=0x%x]\n", grub_dprintf ("linux", "Linux-%s, setup=0x%x, size=0x%x\n",
grub_linux_is_bzimage ? "bzImage" : "zImage", real_size, prot_size); grub_linux_is_bzimage ? "bzImage" : "zImage",
real_size, prot_size);
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++)
if (grub_memcmp (argv[i], "vga=", 4) == 0) if (grub_memcmp (argv[i], "vga=", 4) == 0)

View file

@ -1,123 +0,0 @@
/*
* 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/env.h>
#include <grub/misc.h>
#include <grub/xnu.h>
#include <grub/mm.h>
#include <grub/cpu/xnu.h>
#include <grub/video_fb.h>
#include <grub/bitmap_scale.h>
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define DEFAULT_VIDEO_MODE "auto"
/* Setup video for xnu. */
grub_err_t
grub_xnu_set_video (struct grub_xnu_boot_params *params)
{
struct grub_video_mode_info mode_info;
int ret;
char *tmp;
const char *modevar;
void *framebuffer;
grub_err_t err;
struct grub_video_bitmap *bitmap = NULL;
modevar = grub_env_get ("gfxpayload");
/* Consider only graphical 32-bit deep modes. */
if (! modevar || *modevar == 0)
err = grub_video_set_mode (DEFAULT_VIDEO_MODE,
GRUB_VIDEO_MODE_TYPE_PURE_TEXT
| GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
else
{
tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar);
if (! tmp)
return grub_errno;
err = grub_video_set_mode (tmp,
GRUB_VIDEO_MODE_TYPE_PURE_TEXT
| GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
grub_free (tmp);
}
if (err)
return err;
ret = grub_video_get_info (&mode_info);
if (ret)
return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
if (grub_xnu_bitmap)
{
if (grub_xnu_bitmap_mode == GRUB_XNU_BITMAP_STRETCH)
err = grub_video_bitmap_create_scaled (&bitmap,
mode_info.width,
mode_info.height,
grub_xnu_bitmap,
GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
else
bitmap = grub_xnu_bitmap;
}
if (bitmap)
{
int x, y;
x = mode_info.width - bitmap->mode_info.width;
x /= 2;
y = mode_info.height - bitmap->mode_info.height;
y /= 2;
err = grub_video_blit_bitmap (bitmap,
GRUB_VIDEO_BLIT_REPLACE,
x > 0 ? x : 0,
y > 0 ? y : 0,
x < 0 ? -x : 0,
y < 0 ? -y : 0,
min (bitmap->mode_info.width,
mode_info.width),
min (bitmap->mode_info.height,
mode_info.height));
}
if (err)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
bitmap = 0;
}
ret = grub_video_get_info_and_fini (&mode_info, &framebuffer);
if (ret)
return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
params->lfb_width = mode_info.width;
params->lfb_height = mode_info.height;
params->lfb_depth = mode_info.bpp;
params->lfb_line_len = mode_info.pitch;
params->lfb_base = PTR_TO_UINT32 (framebuffer);
params->lfb_mode = bitmap ? GRUB_XNU_VIDEO_SPLASH
: GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
return GRUB_ERR_NONE;
}

View file

@ -33,6 +33,12 @@
#include <grub/command.h> #include <grub/command.h>
#include <grub/gzio.h> #include <grub/gzio.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/bitmap_scale.h>
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define DEFAULT_VIDEO_MODE "auto"
char grub_xnu_cmdline[1024]; char grub_xnu_cmdline[1024];
grub_uint32_t grub_xnu_heap_will_be_at; grub_uint32_t grub_xnu_heap_will_be_at;
@ -838,6 +844,98 @@ grub_xnu_boot_resume (void)
state); state);
} }
/* Setup video for xnu. */
static grub_err_t
grub_xnu_set_video (struct grub_xnu_boot_params *params)
{
struct grub_video_mode_info mode_info;
int ret;
char *tmp;
const char *modevar;
void *framebuffer;
grub_err_t err;
struct grub_video_bitmap *bitmap = NULL;
modevar = grub_env_get ("gfxpayload");
/* Consider only graphical 32-bit deep modes. */
if (! modevar || *modevar == 0)
err = grub_video_set_mode (DEFAULT_VIDEO_MODE,
GRUB_VIDEO_MODE_TYPE_PURE_TEXT
| GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
else
{
tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar);
if (! tmp)
return grub_errno;
err = grub_video_set_mode (tmp,
GRUB_VIDEO_MODE_TYPE_PURE_TEXT
| GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
grub_free (tmp);
}
if (err)
return err;
ret = grub_video_get_info (&mode_info);
if (ret)
return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
if (grub_xnu_bitmap)
{
if (grub_xnu_bitmap_mode == GRUB_XNU_BITMAP_STRETCH)
err = grub_video_bitmap_create_scaled (&bitmap,
mode_info.width,
mode_info.height,
grub_xnu_bitmap,
GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
else
bitmap = grub_xnu_bitmap;
}
if (bitmap)
{
int x, y;
x = mode_info.width - bitmap->mode_info.width;
x /= 2;
y = mode_info.height - bitmap->mode_info.height;
y /= 2;
err = grub_video_blit_bitmap (bitmap,
GRUB_VIDEO_BLIT_REPLACE,
x > 0 ? x : 0,
y > 0 ? y : 0,
x < 0 ? -x : 0,
y < 0 ? -y : 0,
min (bitmap->mode_info.width,
mode_info.width),
min (bitmap->mode_info.height,
mode_info.height));
}
if (err)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
bitmap = 0;
}
ret = grub_video_get_info_and_fini (&mode_info, &framebuffer);
if (ret)
return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
params->lfb_width = mode_info.width;
params->lfb_height = mode_info.height;
params->lfb_depth = mode_info.bpp;
params->lfb_line_len = mode_info.pitch;
params->lfb_base = PTR_TO_UINT32 (framebuffer);
params->lfb_mode = bitmap ? GRUB_XNU_VIDEO_SPLASH
: GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
return GRUB_ERR_NONE;
}
/* Boot xnu. */ /* Boot xnu. */
grub_err_t grub_err_t
grub_xnu_boot (void) grub_xnu_boot (void)

View file

@ -136,8 +136,14 @@ grub_multiboot_boot (void)
grub_multiboot_alloc_mbi = mbi_size; grub_multiboot_alloc_mbi = mbi_size;
} }
#ifdef GRUB_USE_MULTIBOOT2
state.MULTIBOOT_MBI_REGISTER = ALIGN_UP (grub_multiboot_payload_dest
+ grub_multiboot_pure_size,
MULTIBOOT_TAG_ALIGN);
#else
state.MULTIBOOT_MBI_REGISTER = grub_multiboot_payload_dest state.MULTIBOOT_MBI_REGISTER = grub_multiboot_payload_dest
+ grub_multiboot_pure_size; + grub_multiboot_pure_size;
#endif
err = grub_multiboot_make_mbi (grub_multiboot_payload_orig, err = grub_multiboot_make_mbi (grub_multiboot_payload_orig,
grub_multiboot_payload_dest, grub_multiboot_payload_dest,
grub_multiboot_pure_size, mbi_size); grub_multiboot_pure_size, mbi_size);

Some files were not shown because too many files have changed in this diff Show more