add apm support.

This commit is contained in:
okuji 2000-10-19 21:10:42 +00:00
parent 13a32db008
commit 1f2d29244a
11 changed files with 237 additions and 6 deletions

View file

@ -1,3 +1,25 @@
2000-10-20 OKUJI Yoshinori <okuji@gnu.org>
APM BIOS table support is added, based on a patch by Matt Yourst
<yourst@mit.edu>.
* docs/multiboot.texi (Boot information format): Added the
definition of APM table format.
* stage2/mb_info.h (apm_info): New structure.
(multiboot_info): Added a new element, apm_table.
(MB_INFO_APM_TABLE): New macro.
* stage2/asm.S (apm_bios_info): New variable.
Include "apm.S".
* stage2/apm.S: New file.
* stage2/common.c (init_bios_info) [!STAGE1_5]: Added APM BIOS
table support.
* stage2/shared.h (apm_bios_info): Declared.
(get_apm_info): Likewise.
* stage2/Makefile.am (EXTRA_DIST): Added apm.S.
* grub/asmstub.c (apm_bios_info): New variable.
(get_apm_info): New function.
2000-10-19 OKUJI Yoshinori <okuji@gnu.org>
Segregate functions which are copyrighted differently.

1
THANKS
View file

@ -36,6 +36,7 @@ Klaus Reichl <klaus.reichl@alcatel.at>
Kunihiro Ishiguro <kunihiro@zebra.org>
M. Meiarashi <mes@st.rim.or.jp>
Mark Lundeberg <aa026@pgfn.bc.ca>
Matt Yourst <yourst@mit.edu>
Matthias Kretschmer <m.kretschmer@bsdger.org>
Michael Hohmuth <hohmuth@innocent.com>
Mike Meyer <mwm@mired.org>

View file

@ -574,7 +574,7 @@ follows:
+-------------------+
64 | boot_loader_name | (present if flags[9] is set)
+-------------------+
68 - ?? | apm_table | (present if flags[10] is set)
68 | apm_table | (present if flags[10] is set)
+-------------------+
?? - ?? | graphics_table | (present if flags[11] is set)
+-------------------+
@ -823,11 +823,41 @@ returned by the @dfn{GET CONFIGURATION} @sc{bios} call. If the @sc{bios}
call fails, then the size of the table must be @emph{zero}.
If bit 9 in the @samp{flags} is set, the @samp{boot_loader_name} field
is valid, and contains the physical address of the name of the boot
is valid, and contains the physical address of the name of a boot
loader booting the kernel. The name is a normal C-style zero-terminated
string.
@c I haven't defined the apm_table field yet. - okuji
If bit 10 in the @samp{flags} is set, the @samp{apm_table} field is
valid, and contains the physical address of an @sc{apm} table defined as
below:
@example
@group
+----------------------+
0 | version |
2 | cseg |
4 | offset |
8 | cseg_16 |
10 | dseg |
12 | flags |
14 | cseg_len |
16 | cseg_16_len |
18 | dseg_len |
+----------------------+
@end group
@end example
The fields @samp{version}, @samp{cseg}, @samp{offset}, @samp{cseg_16},
@samp{dseg}, @samp{flags}, @samp{cseg_len}, @samp{cseg_16_len},
@samp{dseg_len} indicate the version number, the protected mode 32-bit
code segment, the offset of the entry point, the protected mode 16-bit
code segment, the protected mode 16-bit data segment, the flags, the
length of the protected mode 32-bit code segment, the length of the
protected mode 16-bit code segment, and the length of the protected mode
16-bit data segment, respectively. Only the field @samp{offset} is 4
bytes, and the others are 2 bytes. See
@uref{http://www.microsoft.com/hwdev/busbios/amp_12.htm, Advanced Power
Management (APM) BIOS Interface Specification}, for more information.
If bit 11 in the @samp{flags} is set, video mode information is
available in the mode table. This should only be done if the kernel has

View file

@ -72,6 +72,7 @@ char version_string[] = VERSION;
char config_file[128] = "/boot/grub/menu.lst"; /* FIXME: arbitrary */
unsigned long linux_text_len = 0;
unsigned short io_map[IO_MAP_SIZE];
struct apm_info apm_bios_info;
/* Emulation requirements. */
char *grub_scratch_mem = 0;
@ -438,6 +439,13 @@ get_rom_config_table (void)
return 0;
}
/* Get APM BIOS information. */
void
get_apm_info (void)
{
/* Nothing to do in the simulator. */
}
/* low-level timing info */
int
getrtsecs (void)

View file

@ -7,7 +7,7 @@ noinst_HEADERS = apic.h defs.h dir.h disk_inode.h disk_inode_ffs.h \
fat.h filesys.h freebsd.h fs.h i386-elf.h imgact_aout.h \
mb_header.h mb_info.h md5.h pc_slice.h serial.h shared.h \
smp-imps.h nbi.h
EXTRA_DIST = setjmp.S $(noinst_SCRIPTS)
EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS)
# For <stage1.h>.
INCLUDES = -I$(top_srcdir)/stage1

View file

@ -96,7 +96,7 @@ noinst_HEADERS = apic.h defs.h dir.h disk_inode.h disk_inode_ffs.h \
mb_header.h mb_info.h md5.h pc_slice.h serial.h shared.h \
smp-imps.h nbi.h
EXTRA_DIST = setjmp.S $(noinst_SCRIPTS)
EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS)
# For <stage1.h>.
INCLUDES = -I$(top_srcdir)/stage1

127
stage2/apm.S Normal file
View file

@ -0,0 +1,127 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2000 Free Software Foundation, Inc.
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* This is stolen from arch/i386/boot/setup.S in Linux 2.2.17 */
/*
! setup.S Copyright (C) 1991, 1992 Linus Torvalds
*/
ENTRY(get_apm_info)
pushl %ebp
pushl %ebx
pushl %edi
pushl %esi
call EXT_C(prot_to_real)
.code16
/* APM BIOS installation check */
movw $0x5300, %ax
xorw %bx, %bx
int $0x15
/* error -> no APM BIOS */
jc done_apm_bios
/* check for "PM" signature */
cmpw $0x504d, %bx
/* no signature -> no APM BIOS */
jne done_apm_bios
/* Is 32 bit supported? */
andw $0x0002, %cx
/* no ... */
je done_apm_bios
/* Disconnect first just in case */
movw $0x5304, %ax
xorw %bx, %bx
/* ignore return code */
int $0x15
/* 32 bit connect */
movw $0x5303, %ax
xorl %ebx, %ebx
/* paranoia */
xorw %cx, %cx
xorw %dx, %dx
xorl %esi, %esi
xorw %di, %di
int $0x15
/* error */
jc no_32_apm_bios
/* BIOS code segment */
movw %ax, ABS(EXT_C(apm_bios_info)) + 2
/* BIOS entry point offset */
movl %ebx, ABS(EXT_C(apm_bios_info)) + 4
/* BIOS 16 bit code segment */
movw %cx, ABS(EXT_C(apm_bios_info)) + 8
/* BIOS data segment */
movw %dx, ABS(EXT_C(apm_bios_info)) + 10
/* BIOS code segment length */
movl %esi, ABS(EXT_C(apm_bios_info)) + 14
/* BIOS data segment length */
movw %di, ABS(EXT_C(apm_bios_info)) + 18
/*
* Redo the installation check as the 32 bit connect
* modifies the flags returned on some BIOSs
*/
/* APM BIOS installation check */
movw $0x5300, %ax
xorw %bx, %bx
/* paranoia */
xorw %cx, %cx
int $0x15
/* error -> should not happen, tidy up */
jc apm_disconnect
/* check for "PM" signature */
cmpw $0x504d, %bx
/* no signature -> should not happen, tidy up */
jne apm_disconnect
/* record the APM BIOS version */
movw %ax, ABS(EXT_C(apm_bios_info))
/* and flags */
movw %cx, ABS(EXT_C(apm_bios_info)) + 12
jmp done_apm_bios
apm_disconnect:
/* Disconnect */
movw $0x5304, %ax
xorw %bx, %bx
/* ignore return code */
int $0x15
jmp done_apm_bios
no_32_apm_bios:
/* remove 32 bit support bit */
andw $0xfffd, ABS(EXT_C(apm_bios_info)) + 12
done_apm_bios:
DATA32 call EXT_C(prot_to_real)
.code32
popl %esi
popl %edi
popl %ebx
popl %ebp
ret

View file

@ -1324,6 +1324,7 @@ probe_values:
/* Source files are splitted, as they have different copyrights. */
#include "setjmp.S"
#include "apm.S"
/*
* console_putchar(c)
@ -2106,6 +2107,16 @@ offset:
segment:
.word 0
VARIABLE(apm_bios_info)
.word 0 /* version */
.word 0 /* cseg */
.long 0 /* offset */
.word 0 /* cseg_16 */
.word 0 /* dseg_16 */
.word 0 /* cseg_len */
.word 0 /* cseg_16_len */
.word 0 /* dseg_16_len */
/*
* This is the Global Descriptor Table
*

View file

@ -308,6 +308,11 @@ init_bios_info (void)
/* Set the boot loader name. */
mbi.boot_loader_name = (unsigned long) "GNU GRUB " VERSION;
/* Get the APM BIOS table. */
get_apm_info ();
if (apm_bios_info.version)
mbi.apm_table = (unsigned long) &apm_bios_info;
/*
* Initialize other Multiboot Info flags.
*/
@ -316,6 +321,9 @@ init_bios_info (void)
| MB_INFO_DRIVE_INFO | MB_INFO_CONFIG_TABLE
| MB_INFO_BOOT_LOADER_NAME);
if (apm_bios_info.version)
mbi.flags |= MB_INFO_APM_TABLE;
#endif /* STAGE1_5 */
#ifdef SUPPORT_DISKLESS

View file

@ -83,6 +83,20 @@ struct drive_info
#define MB_DI_LBA_MODE 1
/* APM BIOS info. */
struct apm_info
{
unsigned short version;
unsigned short cseg;
unsigned long offset;
unsigned short cseg_16;
unsigned short dseg_16;
unsigned short cseg_len;
unsigned short cseg_16_len;
unsigned short dseg_16_len;
};
/*
* MultiBoot Info description
*
@ -146,6 +160,9 @@ struct multiboot_info
/* Boot Loader Name */
unsigned long boot_loader_name;
/* APM table */
unsigned long apm_table;
};
/*
@ -180,6 +197,9 @@ struct multiboot_info
/* Is there a boot loader name? */
#define MB_INFO_BOOT_LOADER_NAME 0x200
/* Is there a APM table? */
#define MB_INFO_APM_TABLE 0x400
/*
* The following value must be present in the EAX register.
*/

View file

@ -466,6 +466,7 @@ typedef enum
extern unsigned long install_partition;
extern unsigned long boot_drive;
extern unsigned long install_second_sector;
extern struct apm_info apm_bios_info;
extern unsigned long boot_part_addr;
extern unsigned long boot_part_offset;
extern int saved_entryno;
@ -658,6 +659,9 @@ int get_mmap_entry (struct mmar_desc *desc, int cont);
if fails. */
unsigned long get_rom_config_table (void);
/* Get APM BIOS information. */
void get_apm_info (void);
/* Return the data area immediately following our code. */
int get_code_end (void);