change the format of drive info in the Multiboot Specification, implement some of the new features.
This commit is contained in:
parent
636299cc50
commit
11236082ea
9 changed files with 277 additions and 89 deletions
28
ChangeLog
28
ChangeLog
|
@ -1,3 +1,31 @@
|
|||
2000-10-16 OKUJI Yoshinori <okuji@gnu.org>
|
||||
|
||||
Some of the new Multiboot features are supported. APM support
|
||||
and VESA support are not strictly defined or implemented yet.
|
||||
|
||||
* docs/multiboot.texi (Top): Increase the version number.
|
||||
(Boot information format): Changed the drive information format,
|
||||
because it was not straightforward.
|
||||
|
||||
* grub/asmstub.c (io_map): New variable.
|
||||
(track_int13): New function.
|
||||
(get_rom_config_table): Likewise.
|
||||
* stage2/stage2.c (cmain): Set CONFIG_ENTRIES to MBI.DRIVES_ADDR
|
||||
+ MBI.DRIVES.LENGTH instead of MBI.MMAP_ADDR + MBI.MMAP_LENGTH.
|
||||
* stage2/common.c (init_bios_info) [!STAGE1_5]: Added support
|
||||
for drive info, ROM config table, and boot loader name features
|
||||
of the Multiboot Specification.
|
||||
* stage2/mb_info.h (drive_info): New structure.
|
||||
(MB_DI_CHS_MODE): New macro.
|
||||
(MB_DI_LBA_MODE): Likewise.
|
||||
(multiboot_info): Added drives_length, drives_addr,
|
||||
config_table, and boot_loader_name.
|
||||
(MB_INFO_DRIVE_INFO): New macro.
|
||||
(MB_INFO_CONFIG_TABLE): Likewise.
|
||||
(MB_INFO_BOOT_LOADER_NAME): Likewise.
|
||||
* stage2/asm.S (get_rom_config_table): New function.
|
||||
* stage2/shared.h (get_rom_config_table): Declared.
|
||||
|
||||
2000-10-16 OKUJI Yoshinori <okuji@gnu.org>
|
||||
|
||||
* util/grub-install.in (convert): Check only if the file exists,
|
||||
|
|
|
@ -22,8 +22,11 @@ instead of the root directory.
|
|||
use FILE as the grub shell.
|
||||
.TP
|
||||
\fB\-\-force\-lba\fR
|
||||
Force GRUB to use LBA mode even for a buggy
|
||||
force GRUB to use LBA mode even for a buggy
|
||||
BIOS.
|
||||
.TP
|
||||
\fB\-\-recheck\fR
|
||||
probe a device map even if it already exists.
|
||||
.PP
|
||||
INSTALL_DEVICE can be a GRUB device name or a system device filename.
|
||||
.PP
|
||||
|
|
|
@ -71,7 +71,7 @@ into another language, under the above conditions for modified versions.
|
|||
@top Multiboot Specification
|
||||
|
||||
This file documents Multiboot Specification, the proposal for the boot
|
||||
sequence standard. This edition documents version 0.6.90.
|
||||
sequence standard. This edition documents version 0.6.91.
|
||||
@end ifnottex
|
||||
|
||||
|
||||
|
@ -567,7 +567,7 @@ follows:
|
|||
44 | mmap_length | (present if flags[6] is set)
|
||||
48 | mmap_addr | (present if flags[6] is set)
|
||||
+-------------------+
|
||||
52 | drives_count | (present if flags[7] is set)
|
||||
52 | drives_length | (present if flags[7] is set)
|
||||
56 | drives_addr | (present if flags[7] is set)
|
||||
+-------------------+
|
||||
60 | config_table | (present if flags[8] is set)
|
||||
|
@ -765,29 +765,33 @@ be available for normal use.
|
|||
|
||||
If bit 7 in the @samp{flags} is set, then the @samp{drives_*} fields
|
||||
are valid, and indicate the address of the physical address of the first
|
||||
drive structure and the number of drive structures. @samp{drives_addr}
|
||||
is the address, and @samp{drives_count} is the
|
||||
number. @samp{drives_count} may be zero. Each drive structure is
|
||||
formatted as follows:
|
||||
drive structure and the size of drive structures. @samp{drives_addr}
|
||||
is the address, and @samp{drives_length} is the total size of drive
|
||||
structures. Note that @samp{drives_length} may be zero. Each drive
|
||||
structure is formatted as follows:
|
||||
|
||||
@example
|
||||
@group
|
||||
+-------------------+
|
||||
0 | drive_number |
|
||||
0 | size |
|
||||
+-------------------+
|
||||
1 | drive_mode |
|
||||
4 | drive_number |
|
||||
+-------------------+
|
||||
2 | drive_cylinders |
|
||||
4 | drive_heads |
|
||||
5 | drive_sectors |
|
||||
5 | drive_mode |
|
||||
+-------------------+
|
||||
6 | drive_ports |
|
||||
6 | drive_cylinders |
|
||||
8 | drive_heads |
|
||||
9 | drive_sectors |
|
||||
+-------------------+
|
||||
10 | reserved (0) |
|
||||
10 - xx | drive_ports |
|
||||
+-------------------+
|
||||
@end group
|
||||
@end example
|
||||
|
||||
The @samp{size} field specifies the size of this structure. The size
|
||||
varies, depending on the number of ports. Note that the size may not be
|
||||
equal to (10 + 2 * the number of ports), because of an alignment.
|
||||
|
||||
The @samp{drive_number} field contains the BIOS drive number. The
|
||||
@samp{drive_mode} field represents the access mode used by the boot
|
||||
loader. Currently, the following modes are defined:
|
||||
|
@ -807,15 +811,11 @@ cylinders. @samp{drive_heads} contains the number of the
|
|||
heads. @samp{drive_sectors} contains the number of the sectors per
|
||||
track.
|
||||
|
||||
The @samp{drive_ports} field contains the physical address of the array
|
||||
of the I/O ports used for the drive in the @sc{bios} code. The array
|
||||
consists of zero or more unsigned two-bytes integers, and is terminated
|
||||
with zero. Note that the array may contain any number of I/O ports that
|
||||
are not related to the drive actually (such as @sc{dma} controller's
|
||||
ports).
|
||||
|
||||
The last field @samp{reserved} is reserved for future use, and must be
|
||||
zero. The size is four bytes.
|
||||
The @samp{drive_ports} field contains the array of the I/O ports used
|
||||
for the drive in the @sc{bios} code. The array consists of zero or more
|
||||
unsigned two-bytes integers, and is terminated with zero. Note that the
|
||||
array may contain any number of I/O ports that are not related to the
|
||||
drive actually (such as @sc{dma} controller's ports).
|
||||
|
||||
If bit 8 in the @samp{flags} is set, then the @samp{config_table} field
|
||||
is valid, and indicates the address of the @sc{rom} configuration table
|
||||
|
|
|
@ -71,6 +71,7 @@ int saved_entryno = 0;
|
|||
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];
|
||||
|
||||
/* Emulation requirements. */
|
||||
char *grub_scratch_mem = 0;
|
||||
|
@ -423,6 +424,19 @@ get_mmap_entry (struct mmar_desc *desc, int cont)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Track the int13 handler. */
|
||||
void
|
||||
track_int13 (int drive)
|
||||
{
|
||||
/* Nothing to do in the simulator. */
|
||||
}
|
||||
|
||||
/* Get the ROM configuration table. */
|
||||
unsigned long
|
||||
get_rom_config_table (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* low-level timing info */
|
||||
int
|
||||
|
|
44
stage2/asm.S
44
stage2/asm.S
|
@ -1596,6 +1596,50 @@ xsmap:
|
|||
pop %ebp
|
||||
ret
|
||||
|
||||
/*
|
||||
* get_rom_config_table()
|
||||
*
|
||||
* Get the linear address of a ROM configuration table. Return zero,
|
||||
* if fails.
|
||||
*/
|
||||
|
||||
ENTRY(get_rom_config_table)
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
|
||||
/* zero %ebx for simplicity */
|
||||
xorl %ebx, %ebx
|
||||
|
||||
call EXT_C(prot_to_real)
|
||||
.code16
|
||||
|
||||
movw $0xc0, %ax
|
||||
int $0x15
|
||||
|
||||
jc no_rom_table
|
||||
testb %ah, %ah
|
||||
jnz no_rom_table
|
||||
|
||||
movw %es, %dx
|
||||
jmp found_rom_table
|
||||
|
||||
no_rom_table:
|
||||
xorw %dx, %dx
|
||||
xorw %bx, %bx
|
||||
|
||||
found_rom_table:
|
||||
DATA32 call EXT_C(real_to_prot)
|
||||
.code32
|
||||
|
||||
/* compute the linear address */
|
||||
movw %dx, %ax
|
||||
shll $4, %eax
|
||||
addl %ebx, %eax
|
||||
|
||||
popl %ebx
|
||||
popl %ebp
|
||||
ret
|
||||
|
||||
/*
|
||||
* gateA20(int linear)
|
||||
*
|
||||
|
|
|
@ -158,6 +158,7 @@ init_bios_info (void)
|
|||
{
|
||||
#ifndef STAGE1_5
|
||||
unsigned long cont, memtmp, addr;
|
||||
int drive;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -260,11 +261,60 @@ init_bios_info (void)
|
|||
|
||||
saved_mem_upper = mbi.mem_upper;
|
||||
|
||||
/* Get the drive info. */
|
||||
/* FIXME: This should be postponed until a Multiboot kernel actually
|
||||
requires it, because this could slow down the start-up
|
||||
unreasonably. */
|
||||
mbi.drives_length = 0;
|
||||
mbi.drives_addr = addr;
|
||||
|
||||
/* For now, GRUB doesn't probe floppies, since it is trivial to map
|
||||
floppy drives to BIOS drives. */
|
||||
for (drive = 0x80; drive < 0x88; drive++)
|
||||
{
|
||||
struct geometry geom;
|
||||
struct drive_info *info = (struct drive_info *) addr;
|
||||
unsigned short *port;
|
||||
|
||||
/* Get the geometry. This ensures that the drive is present. */
|
||||
if (get_diskinfo (drive, &geom))
|
||||
break;
|
||||
|
||||
/* Clean out the I/O map. */
|
||||
grub_memset ((char *) io_map, 0,
|
||||
IO_MAP_SIZE * sizeof (unsigned short));
|
||||
/* Track the int13 handler. */
|
||||
track_int13 (drive);
|
||||
|
||||
/* Set the information. */
|
||||
info->drive_number = drive;
|
||||
info->drive_mode = ((geom.flags & BIOSDISK_FLAG_LBA_EXTENSION)
|
||||
? MB_DI_LBA_MODE : MB_DI_CHS_MODE);
|
||||
info->drive_cylinders = geom.cylinders;
|
||||
info->drive_heads = geom.heads;
|
||||
info->drive_sectors = geom.sectors;
|
||||
|
||||
addr += sizeof (struct drive_info);
|
||||
for (port = io_map; *port; port++, addr += sizeof (unsigned short))
|
||||
*((unsigned short *) addr) = *port;
|
||||
|
||||
info->size = addr - (unsigned long) info;
|
||||
mbi.drives_length += info->size;
|
||||
}
|
||||
|
||||
/* Get the ROM configuration table by INT 15, AH=C0h. */
|
||||
mbi.config_table = get_rom_config_table ();
|
||||
|
||||
/* Set the boot loader name. */
|
||||
mbi.boot_loader_name = (unsigned long) "GNU GRUB " VERSION;
|
||||
|
||||
/*
|
||||
* Initialize other Multiboot Info flags.
|
||||
*/
|
||||
|
||||
mbi.flags = MB_INFO_MEMORY | MB_INFO_CMDLINE | MB_INFO_BOOTDEV;
|
||||
mbi.flags = (MB_INFO_MEMORY | MB_INFO_CMDLINE | MB_INFO_BOOTDEV
|
||||
| MB_INFO_DRIVE_INFO | MB_INFO_CONFIG_TABLE
|
||||
| MB_INFO_BOOT_LOADER_NAME);
|
||||
|
||||
#endif /* STAGE1_5 */
|
||||
|
||||
|
|
173
stage2/mb_info.h
173
stage2/mb_info.h
|
@ -23,17 +23,17 @@
|
|||
*/
|
||||
|
||||
struct mod_list
|
||||
{
|
||||
/* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
|
||||
unsigned long mod_start;
|
||||
unsigned long mod_end;
|
||||
|
||||
/* Module command line */
|
||||
unsigned long cmdline;
|
||||
|
||||
/* padding to take it to 16 bytes (must be zero) */
|
||||
unsigned long pad;
|
||||
};
|
||||
{
|
||||
/* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
|
||||
unsigned long mod_start;
|
||||
unsigned long mod_end;
|
||||
|
||||
/* Module command line */
|
||||
unsigned long cmdline;
|
||||
|
||||
/* padding to take it to 16 bytes (must be zero) */
|
||||
unsigned long pad;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
|
@ -44,19 +44,45 @@ struct mod_list
|
|||
*/
|
||||
|
||||
struct AddrRangeDesc
|
||||
{
|
||||
unsigned long size;
|
||||
unsigned long long BaseAddr;
|
||||
unsigned long long Length;
|
||||
unsigned long Type;
|
||||
|
||||
/* unspecified optional padding... */
|
||||
};
|
||||
{
|
||||
unsigned long size;
|
||||
unsigned long long BaseAddr;
|
||||
unsigned long long Length;
|
||||
unsigned long Type;
|
||||
|
||||
/* unspecified optional padding... */
|
||||
};
|
||||
|
||||
/* usable memory "Type", all others are reserved. */
|
||||
#define MB_ARD_MEMORY 1
|
||||
|
||||
|
||||
/* Drive Info structure. */
|
||||
struct drive_info
|
||||
{
|
||||
/* The size of this structure. */
|
||||
unsigned long size;
|
||||
|
||||
/* The BIOS drive number. */
|
||||
unsigned char drive_number;
|
||||
|
||||
/* The access mode (see below). */
|
||||
unsigned char drive_mode;
|
||||
|
||||
/* The BIOS geometry. */
|
||||
unsigned short drive_cylinders;
|
||||
unsigned char drive_heads;
|
||||
unsigned char drive_sectors;
|
||||
|
||||
/* The array of I/O ports used for the drive. */
|
||||
unsigned short drive_ports[0];
|
||||
};
|
||||
|
||||
/* Drive Mode. */
|
||||
#define MB_DI_CHS_MODE 0
|
||||
#define MB_DI_LBA_MODE 1
|
||||
|
||||
|
||||
/*
|
||||
* MultiBoot Info description
|
||||
*
|
||||
|
@ -65,52 +91,62 @@ struct AddrRangeDesc
|
|||
*/
|
||||
|
||||
struct multiboot_info
|
||||
{
|
||||
/* MultiBoot info version number */
|
||||
unsigned long flags;
|
||||
|
||||
/* Available memory from BIOS */
|
||||
unsigned long mem_lower;
|
||||
unsigned long mem_upper;
|
||||
|
||||
/* "root" partition */
|
||||
unsigned long boot_device;
|
||||
|
||||
/* Kernel command line */
|
||||
unsigned long cmdline;
|
||||
|
||||
/* Boot-Module list */
|
||||
unsigned long mods_count;
|
||||
unsigned long mods_addr;
|
||||
|
||||
union
|
||||
{
|
||||
/* MultiBoot info version number */
|
||||
unsigned long flags;
|
||||
|
||||
/* Available memory from BIOS */
|
||||
unsigned long mem_lower;
|
||||
unsigned long mem_upper;
|
||||
|
||||
/* "root" partition */
|
||||
unsigned long boot_device;
|
||||
|
||||
/* Kernel command line */
|
||||
unsigned long cmdline;
|
||||
|
||||
/* Boot-Module list */
|
||||
unsigned long mods_count;
|
||||
unsigned long mods_addr;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/* (a.out) Kernel symbol table info */
|
||||
unsigned long tabsize;
|
||||
unsigned long strsize;
|
||||
unsigned long addr;
|
||||
unsigned long pad;
|
||||
}
|
||||
a;
|
||||
|
||||
struct
|
||||
{
|
||||
/* (ELF) Kernel section header table */
|
||||
unsigned long num;
|
||||
unsigned long size;
|
||||
unsigned long addr;
|
||||
unsigned long shndx;
|
||||
}
|
||||
e;
|
||||
}
|
||||
syms;
|
||||
|
||||
/* Memory Mapping buffer */
|
||||
unsigned long mmap_length;
|
||||
unsigned long mmap_addr;
|
||||
};
|
||||
struct
|
||||
{
|
||||
/* (a.out) Kernel symbol table info */
|
||||
unsigned long tabsize;
|
||||
unsigned long strsize;
|
||||
unsigned long addr;
|
||||
unsigned long pad;
|
||||
}
|
||||
a;
|
||||
|
||||
struct
|
||||
{
|
||||
/* (ELF) Kernel section header table */
|
||||
unsigned long num;
|
||||
unsigned long size;
|
||||
unsigned long addr;
|
||||
unsigned long shndx;
|
||||
}
|
||||
e;
|
||||
}
|
||||
syms;
|
||||
|
||||
/* Memory Mapping buffer */
|
||||
unsigned long mmap_length;
|
||||
unsigned long mmap_addr;
|
||||
|
||||
/* Drive Info buffer */
|
||||
unsigned long drives_length;
|
||||
unsigned long drives_addr;
|
||||
|
||||
/* ROM configuration table */
|
||||
unsigned long config_table;
|
||||
|
||||
/* Boot Loader Name */
|
||||
unsigned long boot_loader_name;
|
||||
};
|
||||
|
||||
/*
|
||||
* Flags to be set in the 'flags' parameter above
|
||||
|
@ -135,6 +171,15 @@ struct multiboot_info
|
|||
/* is there a full memory map? */
|
||||
#define MB_INFO_MEM_MAP 0x40
|
||||
|
||||
/* Is there drive info? */
|
||||
#define MB_INFO_DRIVE_INFO 0x80
|
||||
|
||||
/* Is there a config table? */
|
||||
#define MB_INFO_CONFIG_TABLE 0x100
|
||||
|
||||
/* Is there a boot loader name? */
|
||||
#define MB_INFO_BOOT_LOADER_NAME 0x200
|
||||
|
||||
/*
|
||||
* The following value must be present in the EAX register.
|
||||
*/
|
||||
|
|
|
@ -643,6 +643,10 @@ int get_eisamemsize (void);
|
|||
map). */
|
||||
int get_mmap_entry (struct mmar_desc *desc, int cont);
|
||||
|
||||
/* Get the linear address of a ROM configuration table. Return zero,
|
||||
if fails. */
|
||||
unsigned long get_rom_config_table (void);
|
||||
|
||||
/* Return the data area immediately following our code. */
|
||||
int get_code_end (void);
|
||||
|
||||
|
|
|
@ -797,7 +797,7 @@ cmain (void)
|
|||
config_len = 0;
|
||||
menu_len = 0;
|
||||
num_entries = 0;
|
||||
config_entries = (char *) (mbi.mmap_addr + mbi.mmap_length);
|
||||
config_entries = (char *) mbi.drives_addr + mbi.drives_length;
|
||||
menu_entries = (char *) MENU_BUF;
|
||||
init_config ();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue